Marco Ivaldi pointed me to some unsafe code in ParseJob.c. I do not have a sun machine (well, not currently operational anyway), so the code is not tested. But seriously, this is some horrible code. This local parser for sun needs to be rewritten!
1432 lines
36 KiB
C
1432 lines
36 KiB
C
/*
|
|
* CDE - Common Desktop Environment
|
|
*
|
|
* Copyright (c) 1993-2012, The Open Group. All rights reserved.
|
|
*
|
|
* These libraries and programs are free software; you can
|
|
* redistribute them and/or modify them under the terms of the GNU
|
|
* Lesser General Public License as published by the Free Software
|
|
* Foundation; either version 2 of the License, or (at your option)
|
|
* any later version.
|
|
*
|
|
* These libraries and programs are distributed in the hope that
|
|
* they will be useful, but WITHOUT ANY WARRANTY; without even the
|
|
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
|
|
* PURPOSE. See the GNU Lesser General Public License for more
|
|
* details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with these libraries and programs; if not, write
|
|
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
|
|
* Floor, Boston, MA 02110-1301 USA
|
|
*/
|
|
/* $TOG: ParseJobs.C /main/12 1998/08/03 16:30:29 mgreess $ */
|
|
/* *
|
|
* (c) Copyright 1993, 1994 Hewlett-Packard Company *
|
|
* (c) Copyright 1993, 1994 International Business Machines Corp. *
|
|
* (c) Copyright 1993, 1994 Sun Microsystems, Inc. *
|
|
* (c) Copyright 1993, 1994 Novell, Inc. *
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#if defined(_AIX)
|
|
/*
|
|
* XXXXX - AIX hack alert!!! This is needed for an AIX defect
|
|
* in the definition of inet_addr in <arpa/inet.h>
|
|
*/
|
|
extern "C" in_addr_t inet_addr(const char *);
|
|
#endif
|
|
#include <arpa/inet.h>
|
|
#include <netdb.h>
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <signal.h>
|
|
#include <unistd.h>
|
|
#include <string.h>
|
|
#include <dirent.h>
|
|
#include <time.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <X11/Intrinsic.h>
|
|
|
|
#include <string>
|
|
|
|
#include "dtprintinfomsg.h"
|
|
|
|
#ifdef NO_REGCOMP
|
|
#include <ctype.h>
|
|
#if defined(SVR4) || defined(SYSV)
|
|
#include <libgen.h>
|
|
#endif
|
|
#else
|
|
#include <regex.h>
|
|
#endif
|
|
|
|
#if defined(aix)
|
|
extern "C" { int rresvport(int *); }
|
|
#endif
|
|
|
|
#ifdef hpux
|
|
#define SETEUID(id) setresuid(getuid(), (uid_t)id, (uid_t)0);
|
|
#else
|
|
#if defined(aix)
|
|
extern "C" { extern int seteuid(uid_t); }
|
|
#endif
|
|
#define SETEUID(id) seteuid((uid_t)id)
|
|
#endif
|
|
|
|
#include "ParseJobs.h"
|
|
#include "Invoke.h"
|
|
|
|
static int G_AIX_LOCAL = 0;
|
|
|
|
int RemotePrintJobs(char *server, char *printer, char **job_list, int *n_jobs)
|
|
{
|
|
*n_jobs = 0;
|
|
*job_list = NULL;
|
|
|
|
// hookup to Server
|
|
int sockfd;
|
|
if ((sockfd = ConnectToPrintServer(server, 15)) == -1)
|
|
return 0;
|
|
|
|
char *output = NULL;
|
|
int rc = 0;
|
|
if (SendPrintJobStatusReguest(sockfd, printer))
|
|
{
|
|
int len = 512;
|
|
int ctr = 1;
|
|
int n;
|
|
output = (char *)malloc(512);
|
|
char *out1 = output;
|
|
char *out2 = out1 + 511;
|
|
|
|
while (1)
|
|
{
|
|
if ((n = read(sockfd, out1, len)) == len)
|
|
{
|
|
len = 512;
|
|
ctr++;
|
|
output = (char *)realloc(output, (ctr * 512));
|
|
out1 = output + ((ctr - 1) * 512);
|
|
out2 = out1 + 511;
|
|
}
|
|
else if (n > 0)
|
|
{
|
|
out1 += n;
|
|
len = out2 - out1 + 1;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
*out1 = 0;
|
|
close(sockfd);
|
|
rc = 1;
|
|
}
|
|
if (output)
|
|
{
|
|
if (*output)
|
|
rc = ParseRemotePrintJobs(printer, output, job_list, n_jobs);
|
|
free(output);
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
int ParseRemotePrintJobs(char *printer, char *jobs, char **job_list,
|
|
int *n_jobs)
|
|
{
|
|
*n_jobs = 0;
|
|
*job_list = NULL;
|
|
|
|
int rc = 0;
|
|
if (jobs && *jobs)
|
|
{
|
|
switch (DetermineOutput(jobs))
|
|
{
|
|
case AIX_V2_OUTPUT:
|
|
rc = ParseAIXv2PrintJobs(printer, jobs, job_list, n_jobs);
|
|
break;
|
|
case AIX_V3_OUTPUT:
|
|
rc = ParseAIXv3PrintJobs(printer, jobs, job_list, n_jobs);
|
|
break;
|
|
case BSD_OUTPUT:
|
|
rc = ParseBSDPrintJobs(printer, jobs, job_list, n_jobs);
|
|
break;
|
|
default:
|
|
case UNKNOWN_OUTPUT:
|
|
rc = 1;
|
|
break;
|
|
}
|
|
}
|
|
return rc;
|
|
}
|
|
|
|
static void connect_timeout(int not_used)
|
|
{
|
|
not_used = 0;
|
|
}
|
|
|
|
// Create a connection to the remote printer server.
|
|
int ConnectToPrintServer(const char *rhost, int timeout)
|
|
{
|
|
struct hostent *hp;
|
|
struct servent *sp;
|
|
struct sockaddr_in sin;
|
|
int s, lport = IPPORT_RESERVED - 1;
|
|
|
|
// Get the host address and port number to connect to.
|
|
if (!(hp = gethostbyname(rhost)))
|
|
{
|
|
unsigned long tmpaddr = inet_addr(rhost);
|
|
hp = gethostbyaddr((char *)&tmpaddr, sizeof(tmpaddr), AF_INET);
|
|
}
|
|
if (hp == NULL)
|
|
return -1;
|
|
if (!(sp = getservbyname("printer", "tcp")))
|
|
return -1;
|
|
|
|
memset((char *)&sin, 0, sizeof(sin));
|
|
memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
|
|
sin.sin_family = hp->h_addrtype;
|
|
sin.sin_port = sp->s_port;
|
|
|
|
// run as user's UID, but with privileges from root
|
|
SETEUID(0);
|
|
|
|
// Try connecting to the server from a privileged port.
|
|
/* FIXME: Test for the presence of rresvport and provide a substitute
|
|
* if necessary. Linux C library support:
|
|
* dietlibc: no rresvport, defines __dietlibc__
|
|
* musl: no rresvport
|
|
* uclibc: rresvport, defines __GLIBC__
|
|
*/
|
|
#if !defined(__linux__) || defined(__GLIBC__)
|
|
s = rresvport(&lport);
|
|
#endif
|
|
|
|
signal(SIGALRM, connect_timeout);
|
|
if (timeout > 0)
|
|
alarm(timeout);
|
|
else
|
|
alarm(15);
|
|
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0)
|
|
{
|
|
close(s);
|
|
s = -1;
|
|
}
|
|
alarm(0);
|
|
SETEUID(getuid());
|
|
return s;
|
|
}
|
|
|
|
int SendPrintJobStatusReguest(int sockfd, const char *printer)
|
|
{
|
|
char *buf = new char[100];
|
|
int size;
|
|
|
|
sprintf(buf, "%c%s \n", '\4', printer);
|
|
|
|
size=strlen(buf);
|
|
size = write(sockfd, buf, size);
|
|
if (write(sockfd, buf, size) != size)
|
|
{
|
|
close(sockfd);
|
|
delete [] buf;
|
|
return 0;
|
|
}
|
|
delete [] buf;
|
|
return 1;
|
|
}
|
|
|
|
JobOutputType DetermineOutput(char *output)
|
|
{
|
|
char *s, *s1;
|
|
int i;
|
|
static int first_time = 1;
|
|
#ifdef NO_REGCOMP
|
|
static char *aixv2_pattern;
|
|
static char *aixv3_pattern;
|
|
static char *bsd_pattern;
|
|
/*
|
|
* Due to bug in regcmp/regex (bug id 1191772), change to C locale for
|
|
* this parsing work. And change back at end of procedure. This workaround
|
|
* appears to be ok since the print service output parsed here is in a
|
|
* "C locale" 8-bit form for inter-machine networking.
|
|
*/
|
|
setlocale(LC_ALL, "C");
|
|
|
|
if (first_time)
|
|
{
|
|
aixv2_pattern = regcmp("dev.*arg.*status.*request", (char *)NULL);
|
|
aixv3_pattern = regcmp("Queue.*Dev.*Status.*Job", (char *)NULL);
|
|
bsd_pattern = regcmp(":.*\\[.*\\]", (char *)NULL);
|
|
first_time = 0;
|
|
}
|
|
#else
|
|
static regex_t aixv2_pattern;
|
|
static regex_t aixv3_pattern;
|
|
static regex_t bsd_pattern;
|
|
|
|
if (first_time)
|
|
{
|
|
regcomp(&aixv2_pattern, "dev.*arg.*status.*request", REG_NOSUB);
|
|
regcomp(&aixv3_pattern, "Queue.*Dev.*Status.*Job", REG_NOSUB);
|
|
regcomp(&bsd_pattern, ":.*\\[.*\\]", REG_NOSUB);
|
|
first_time = 0;
|
|
}
|
|
#endif
|
|
|
|
s = output;
|
|
if (s1 = strchr(s, '\n'))
|
|
s1++;
|
|
i = 0;
|
|
while (i < 10 && s && *s)
|
|
{
|
|
#ifdef NO_REGCOMP
|
|
if (regex(bsd_pattern, s)) {
|
|
setlocale(LC_ALL, "");
|
|
return BSD_OUTPUT;
|
|
}
|
|
if (regex(aixv3_pattern, s)) {
|
|
setlocale(LC_ALL, "");
|
|
return AIX_V3_OUTPUT;
|
|
}
|
|
if (regex(aixv2_pattern, s)) {
|
|
setlocale(LC_ALL, "");
|
|
return AIX_V2_OUTPUT;
|
|
}
|
|
#else
|
|
if (!regexec(&bsd_pattern, s, (size_t)0, NULL, 0))
|
|
return BSD_OUTPUT;
|
|
if (!regexec(&aixv3_pattern, s, (size_t)0, NULL, 0))
|
|
return AIX_V3_OUTPUT;
|
|
if (!regexec(&aixv2_pattern, s, (size_t)0, NULL, 0))
|
|
return AIX_V2_OUTPUT;
|
|
#endif
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
s1++;
|
|
i++;
|
|
}
|
|
#ifdef NO_REGCOMP
|
|
setlocale(LC_ALL, "");
|
|
#endif
|
|
return UNKNOWN_OUTPUT;
|
|
}
|
|
|
|
///////////////////////////// LOCAL PARSERS /////////////////////////////////
|
|
|
|
#ifdef aix
|
|
void LocalPrintJobs(char *printer, char **job_list, int *n_jobs)
|
|
{
|
|
char *output;
|
|
char *cmd = new char[60];
|
|
|
|
sprintf(cmd, "LANG=C enq -LP%s", printer);
|
|
Invoke *_thread = new Invoke(cmd, &output);
|
|
|
|
// run as user's UID, but with privileges from root
|
|
SETEUID(0);
|
|
G_AIX_LOCAL = 1;
|
|
ParseAIXv3PrintJobs(printer, output, job_list, n_jobs);
|
|
G_AIX_LOCAL = 0;
|
|
SETEUID(getuid());
|
|
|
|
delete [] cmd;
|
|
delete output;
|
|
delete _thread;
|
|
}
|
|
#endif
|
|
|
|
#if defined(sun)
|
|
|
|
// JET - this *really* needs to be re-written for sun
|
|
|
|
// I tried to mitigate some of the more stupider code segments in
|
|
// check_dir() for example, but... It's a C++ file, yet someone who
|
|
// does not appear to know C++ very well wrote this crap in... C, sort
|
|
// of.
|
|
|
|
#warning "This SUN local parser code is unsafe, please re-write"
|
|
|
|
// SUN LOCAL PARSER, actually this gets the local information from the file
|
|
// system, it should have the good performance since no processes (lpstat)
|
|
// are needed.
|
|
|
|
typedef struct
|
|
{
|
|
int immediate;
|
|
long secs;
|
|
char *line;
|
|
} StatusLineStruct, *StatusLine, **StatusLineList;
|
|
|
|
#define TMP_DIR "/var/spool/lp/tmp"
|
|
#define REQ_DIR "/var/spool/lp/requests/%s/"
|
|
#define SPOOL_DIR "/var/spool/lp/tmp/%s/"
|
|
|
|
static void check_dir(char *printer, char *tmp_dir, StatusLineList *job_list,
|
|
int *n_jobs, int prev_n_jobs);
|
|
static int SortJobs(const void *, const void *);
|
|
|
|
void LocalPrintJobs(char *printer, char **return_job_list, int *return_n_jobs)
|
|
{
|
|
DIR *lp_tmp_dir;
|
|
struct dirent *dir_struct;
|
|
struct stat statbuff;
|
|
int n_jobs = 0;
|
|
int i;
|
|
char oldpwd[300];
|
|
int current_size;
|
|
int len;
|
|
|
|
static char *job_list1 = NULL;
|
|
static int prev_buf_size = 0;
|
|
static StatusLineList job_list = NULL;
|
|
static int prev_n_jobs = 0;
|
|
|
|
if (prev_buf_size == 0)
|
|
{
|
|
prev_buf_size = BUFSIZ;
|
|
job_list1 = (char *)malloc(prev_buf_size);
|
|
}
|
|
|
|
current_size = 0;
|
|
*job_list1 = '\0';
|
|
*return_n_jobs = 0;
|
|
|
|
// run as user's UID, but with privileges from root
|
|
SETEUID(0);
|
|
|
|
getcwd(oldpwd, 300);
|
|
if (getenv("TMP_DIR"))
|
|
chdir(getenv("TMP_DIR"));
|
|
else
|
|
chdir(TMP_DIR);
|
|
if (!(lp_tmp_dir = opendir(".")))
|
|
{
|
|
*return_job_list = NULL;
|
|
*return_n_jobs = 0;
|
|
chdir(oldpwd);
|
|
SETEUID(getuid());
|
|
return;
|
|
}
|
|
|
|
dir_struct = readdir(lp_tmp_dir);
|
|
for ( ; dir_struct ; dir_struct = readdir(lp_tmp_dir))
|
|
{
|
|
if (*dir_struct->d_name == '.')
|
|
continue;
|
|
if (stat(dir_struct->d_name, &statbuff) >= 0 &&
|
|
statbuff.st_mode & S_IFDIR)
|
|
{
|
|
chdir(dir_struct->d_name);
|
|
check_dir(printer, dir_struct->d_name, &job_list, &n_jobs,
|
|
prev_n_jobs);
|
|
chdir("..");
|
|
}
|
|
}
|
|
closedir(lp_tmp_dir);
|
|
prev_n_jobs = prev_n_jobs > n_jobs ? prev_n_jobs : n_jobs;
|
|
qsort(job_list, n_jobs, sizeof(StatusLineList), SortJobs);
|
|
for (i = 0; i < n_jobs; i++)
|
|
{
|
|
len = strlen(job_list[i]->line);
|
|
if (prev_buf_size < (current_size + len + 1))
|
|
job_list1 = (char *) realloc(job_list1, (current_size + len + 1) *
|
|
sizeof(char *));
|
|
memcpy(job_list1 + current_size, job_list[i]->line, len);
|
|
current_size += len;
|
|
}
|
|
*(job_list1 + current_size) = '\0';
|
|
prev_buf_size = prev_buf_size > current_size ? prev_buf_size : current_size;
|
|
*return_job_list = job_list1;
|
|
*return_n_jobs = n_jobs;
|
|
chdir(oldpwd);
|
|
SETEUID(getuid());
|
|
}
|
|
|
|
// JET - this whole function is atrocious and should be re-written in C++
|
|
static void check_dir(char *printer, char *tmp_dir, StatusLineList *job_list,
|
|
int *n_jobs, int prev_n_jobs)
|
|
{
|
|
DIR *lp_tmp_dir;
|
|
struct dirent *dir_struct;
|
|
char buf[256];
|
|
int req_len;
|
|
int spool_len;
|
|
int line_ct;
|
|
char *line;
|
|
char date_str[100];
|
|
char owner[100];
|
|
char job_size[100];
|
|
FILE *req, *job;
|
|
time_t secs;
|
|
int found;
|
|
int immediate;
|
|
char *s;
|
|
char title[200];
|
|
char *jobname;
|
|
StatusLineList j_list;
|
|
|
|
char *filename = new char[200];
|
|
char *filename1 = new char[200];
|
|
char *request = new char[300];
|
|
char *spool_dir = new char[300];
|
|
|
|
if (getenv("REQ_DIR"))
|
|
snprintf(request, sizeof(request), "%s/%s", getenv("REQ_DIR"), tmp_dir);
|
|
else
|
|
sprintf(request, sizeof(request), "%s", REQ_DIR, tmp_dir);
|
|
req_len = strlen(request);
|
|
snprintf(spool_dir, sizeof(spool_dir), "%s/%s", SPOOL_DIR, tmp_dir);
|
|
spool_len = strlen(spool_dir);
|
|
|
|
if (!(lp_tmp_dir = opendir(".")))
|
|
{
|
|
delete [] filename;
|
|
delete [] filename1;
|
|
delete [] request;
|
|
delete [] spool_dir;
|
|
return;
|
|
}
|
|
|
|
dir_struct = readdir(lp_tmp_dir);
|
|
for ( ; dir_struct ; dir_struct = readdir(lp_tmp_dir))
|
|
{
|
|
int len = strlen(dir_struct->d_name);
|
|
if (len < 3)
|
|
continue;
|
|
if (strcmp(dir_struct->d_name + len - 2, "-0"))
|
|
continue;
|
|
|
|
// *(request + req_len) = '\0';
|
|
// strcat(request + req_len, dir_struct->d_name);
|
|
std:string file_req(request);
|
|
file_req.append(dir_struct->d_name);
|
|
|
|
if (!(req = fopen(file_req.c_str(), "r")))
|
|
continue;
|
|
if (!(job = fopen(dir_struct->d_name, "r")))
|
|
{
|
|
fclose(req);
|
|
continue;
|
|
}
|
|
found = 1;
|
|
immediate = 0;
|
|
title[0] = '\0';
|
|
filename[0] = '\0';
|
|
filename1[0] = '\0';
|
|
date_str[0] = '\0';
|
|
owner[0] = '\0';
|
|
job_size[0] = '\0';
|
|
while (found && fgets(buf, 100, job))
|
|
{
|
|
line = strtok(buf, "\n");
|
|
switch (*line)
|
|
{
|
|
case 'H':
|
|
if (!strcmp("immediate", line + 2))
|
|
immediate = 1;
|
|
break;
|
|
case 'D':
|
|
if (strcmp(printer, line + 2))
|
|
found = 0;
|
|
break;
|
|
case 'F':
|
|
{
|
|
// *(spool_dir + spool_len) = '\0';
|
|
// strncat(spool_dir, dir_struct->d_name, len - 1);
|
|
// strcat(spool_dir, "1");
|
|
std::string spool_chk(spool_dir);
|
|
spool_chk.append(dir_struct->d_name);
|
|
spool_chk.append("1");
|
|
if (strcmp(spool_chk.c_str(), line + 2))
|
|
snprintf(filename1, sizeof(filename1), "%s", line + 2);
|
|
else
|
|
*filename1 = '\0';
|
|
}
|
|
break;
|
|
case 'O':
|
|
if (s = strrchr(line, ':'))
|
|
*s = '\0';
|
|
if (s = strrchr(line, '\''))
|
|
{
|
|
s++;
|
|
for ( ; *s == ' '; s++)
|
|
;
|
|
}
|
|
strcpy(filename, s);
|
|
if (*s == '\0')
|
|
{
|
|
if (s = strstr(line, "-T"))
|
|
{
|
|
int i = 0;
|
|
s += 2;
|
|
while (1)
|
|
{
|
|
if (*s == ' ')
|
|
{
|
|
if (i == 0)
|
|
{
|
|
i++;
|
|
break;
|
|
}
|
|
else
|
|
{
|
|
i--;
|
|
if (filename[i] != '\\')
|
|
{
|
|
i++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
filename[i++] = *s;
|
|
s++;
|
|
}
|
|
filename[i] = '\0';
|
|
}
|
|
}
|
|
break;
|
|
case 'T':
|
|
if (s = strstr(line, "\\n"))
|
|
*s = '\0';
|
|
strcpy(title, line + 2);
|
|
break;
|
|
}
|
|
}
|
|
if (found)
|
|
{
|
|
line_ct = 1;
|
|
while (line_ct)
|
|
{
|
|
fgets(buf, 100, req);
|
|
line = strtok(buf, "\n");
|
|
switch (line_ct)
|
|
{
|
|
case 3:
|
|
if (s = strchr(line, '!'))
|
|
{
|
|
*s = '\0';
|
|
s++;
|
|
strcpy(owner, s);
|
|
strcat(owner, "@");
|
|
strcat(owner, line);
|
|
if (s = strchr(owner, '.'))
|
|
*s = '\0';
|
|
}
|
|
else
|
|
strcpy(owner, line);
|
|
break;
|
|
case 5: strcpy(job_size, line); break;
|
|
case 6:
|
|
secs = (time_t)atoi(line);
|
|
strftime(date_str, 100, "%b %e|%T", localtime(&secs));
|
|
line_ct = -1;
|
|
break;
|
|
}
|
|
line_ct++;
|
|
}
|
|
if (s = strstr(dir_struct->d_name, "-0"))
|
|
*s = '\0';
|
|
if (*filename)
|
|
jobname = filename;
|
|
else if (*filename1)
|
|
jobname = filename1;
|
|
else if (*title)
|
|
jobname = title;
|
|
else
|
|
{
|
|
sprintf(filename, "%s-%s", printer, dir_struct->d_name);
|
|
jobname = filename;
|
|
}
|
|
if (*n_jobs >= prev_n_jobs)
|
|
{
|
|
if (*n_jobs == 0)
|
|
*job_list = (StatusLineList) malloc(sizeof(StatusLine));
|
|
else
|
|
*job_list = (StatusLineList) realloc(*job_list, (*n_jobs + 1) *
|
|
sizeof(StatusLine));
|
|
j_list = *job_list;
|
|
j_list[*n_jobs] = (StatusLine) malloc(sizeof(StatusLineStruct));
|
|
len = 7 + strlen(printer) + strlen(jobname) + strlen(date_str) +
|
|
strlen(dir_struct->d_name) + strlen(owner) + strlen(job_size);
|
|
j_list[*n_jobs]->line = (char *) malloc(len);
|
|
}
|
|
else
|
|
{
|
|
j_list = *job_list;
|
|
len = 7 + strlen(printer) + strlen(jobname) + strlen(date_str) +
|
|
strlen(dir_struct->d_name) + strlen(owner) + strlen(job_size);
|
|
j_list[*n_jobs]->line = (char *)realloc(j_list[*n_jobs]->line, len);
|
|
}
|
|
sprintf(j_list[*n_jobs]->line, "%s|%s|%s|%s|%s|%s\n", printer,
|
|
jobname, dir_struct->d_name, owner, date_str, job_size);
|
|
j_list[*n_jobs]->secs = (long) secs;
|
|
j_list[*n_jobs]->immediate = immediate;
|
|
(*n_jobs)++;
|
|
}
|
|
fclose(req);
|
|
fclose(job);
|
|
}
|
|
closedir(lp_tmp_dir);
|
|
delete [] filename;
|
|
delete [] filename1;
|
|
delete [] request;
|
|
delete [] spool_dir;
|
|
}
|
|
|
|
static int SortJobs(const void *_first, const void *_second)
|
|
{
|
|
StatusLineList first = (StatusLineList)_first;
|
|
StatusLineList second = (StatusLineList)_second;
|
|
|
|
if ((**first).immediate && !(**second).immediate)
|
|
return -1;
|
|
if (!(**first).immediate && (**second).immediate)
|
|
return 1;
|
|
if ((**first).immediate)
|
|
return (int)((**second).secs - (**first).secs);
|
|
else
|
|
return (int)((**first).secs - (**second).secs);
|
|
}
|
|
|
|
#endif // SUN LOCAL PARSER
|
|
|
|
#ifdef hpux
|
|
|
|
/* HP LOCAL PARSER - have to parse the following
|
|
|
|
Need to parse the following 2 forms of output:
|
|
|
|
coseps-28 guest priority 0 Aug 9 12:54 on coseps
|
|
test.ps 31160 bytes
|
|
|
|
OR
|
|
|
|
coseps-29 guest priority 0 Aug 9 12:56 on hostname
|
|
(standard input) 31160 bytes
|
|
*/
|
|
|
|
void LocalPrintJobs(char *printer, char **return_job_list, int *return_n_jobs)
|
|
{
|
|
char *buf = new char[300];
|
|
char *s, *s1, *c;
|
|
char *qname;
|
|
char *jname;
|
|
char *jnumber;
|
|
char *owner;
|
|
char *month;
|
|
char *day;
|
|
char *stime;
|
|
char *jsize;
|
|
char *hostname;
|
|
int current_size;
|
|
int len;
|
|
char *output;
|
|
|
|
static char *job_list = NULL;
|
|
static int prev_buf_size = 0;
|
|
|
|
sprintf(buf, "LANG=C lpstat -i -o%s", printer);
|
|
Invoke *_thread = new Invoke(buf, &output);
|
|
|
|
if (prev_buf_size == 0)
|
|
{
|
|
prev_buf_size = BUFSIZ;
|
|
job_list = (char *)malloc(prev_buf_size);
|
|
}
|
|
|
|
current_size = 0;
|
|
*job_list = '\0';
|
|
*return_n_jobs = 0;
|
|
s = output;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
while (s && *s)
|
|
{
|
|
qname = strtok(s, "-");
|
|
jnumber = strtok(NULL, " ");
|
|
owner = strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
month = strtok(NULL, " ");
|
|
day = strtok(NULL, " ");
|
|
stime = strtok(NULL, " \n");
|
|
strtok(NULL, " ");
|
|
hostname = strtok(NULL, " \n");
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
for (jname = s; *jname == '\t' || *jname == ' '; jname++)
|
|
;
|
|
jsize = strrchr(s, ' ');
|
|
*jsize = '\0';
|
|
jsize = strrchr(s, ' ') + 1;
|
|
for (c = jsize - 1; *c == ' '; c--)
|
|
;
|
|
*(c + 1) = '\0';
|
|
if (hostname && strcmp(qname, hostname))
|
|
sprintf(buf, "%s|%s|%s|%s@%s|%s %s|%s|%s\n", qname, jname, jnumber,
|
|
owner, hostname, month, day, stime, jsize);
|
|
else
|
|
sprintf(buf, "%s|%s|%s|%s|%s %s|%s|%s\n", qname, jname, jnumber,
|
|
owner, month, day, stime, jsize);
|
|
|
|
len = strlen(buf);
|
|
if (prev_buf_size < (current_size + len + 1))
|
|
job_list = (char *) realloc(job_list, (current_size + len + 1) *
|
|
sizeof(char *));
|
|
memcpy(job_list + current_size, buf, len);
|
|
current_size += len;
|
|
(*return_n_jobs)++;
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
}
|
|
*(job_list + current_size) = '\0';
|
|
prev_buf_size = prev_buf_size > current_size ? prev_buf_size : current_size;
|
|
*return_job_list = job_list;
|
|
delete [] buf;
|
|
delete output;
|
|
delete _thread;
|
|
}
|
|
#endif // HP LOCAL PARSER
|
|
|
|
#if defined(__linux__) || defined(CSRG_BASED)
|
|
|
|
//Linux local parser
|
|
|
|
#define NEXT_OUTPUT_LINE(line,rest) \
|
|
do \
|
|
{ \
|
|
line = rest; \
|
|
if (line && (rest = strchr(line, '\n'))) \
|
|
*rest++ = '\0'; \
|
|
} while (NULL != line && 0 == *line);
|
|
|
|
void LocalPrintJobs(char *printer, char **return_job_list, int *return_n_jobs)
|
|
{
|
|
char *buf = new char[1000];
|
|
char *s, *s1, *c;
|
|
char *qname = NULL;
|
|
char *jname;
|
|
char *jnumber;
|
|
char *owner;
|
|
char *month;
|
|
char *day;
|
|
char *date;
|
|
char *year;
|
|
char *network;
|
|
char *output;
|
|
char *stime;
|
|
char *jsize;
|
|
char *hostname;
|
|
int current_size;
|
|
int len;
|
|
int has_pri = 0;
|
|
|
|
static char *job_list = NULL;
|
|
static int prev_buf_size = 0;
|
|
|
|
#if defined(__linux__) || defined(__OpenBSD__) || defined(__NetBSD__)
|
|
snprintf(buf, 1000, "LANG=C lpq -P%s", printer);
|
|
#elif defined(__FreeBSD__)
|
|
snprintf(buf, 1000, "LANG=C /usr/local/bin/lpq -P%s", printer);
|
|
#endif
|
|
|
|
Invoke *_thread = new Invoke(buf, &output);
|
|
|
|
if (prev_buf_size == 0)
|
|
{
|
|
prev_buf_size = BUFSIZ;
|
|
job_list = (char*) malloc(prev_buf_size);
|
|
}
|
|
|
|
current_size = 0;
|
|
*job_list = '\0';
|
|
*return_n_jobs = 0;
|
|
|
|
s1 = output;
|
|
NEXT_OUTPUT_LINE(s,s1);
|
|
|
|
//
|
|
// Parse the optional "Requests on" line of output to verify printer name.
|
|
// "Requests on ansel:"
|
|
//
|
|
{
|
|
char *opt_requests_on_line = "Requests on ";
|
|
if (0 == strncmp(s, opt_requests_on_line, strlen(opt_requests_on_line)))
|
|
{
|
|
char *requests = strtok(s, " ");
|
|
char *on = strtok(NULL, " ");
|
|
|
|
qname = strtok(NULL, " :\n");
|
|
if (0 != strncmp(qname, printer, strlen(qname)))
|
|
fprintf(
|
|
stderr,
|
|
"Found the wrong printer: looking for '%s'; found '%s'\n",
|
|
printer, qname);
|
|
|
|
NEXT_OUTPUT_LINE(s,s1);
|
|
}
|
|
}
|
|
|
|
//
|
|
// Parse the host/date line of output to collect host, date, and time.
|
|
// "Fri Oct 4 09:08:48 1996: "
|
|
//
|
|
{
|
|
hostname = strtok(s, ":");
|
|
day = strtok(NULL, " ");
|
|
month = strtok(NULL, " ");
|
|
date = strtok(NULL, " ");
|
|
stime = strtok(NULL, " ");
|
|
year = strtok(NULL, " \n");
|
|
}
|
|
|
|
NEXT_OUTPUT_LINE(s,s1);
|
|
|
|
//
|
|
// If this is the "no entries" line, we're done. Return.
|
|
// "no entries"
|
|
//
|
|
{
|
|
char *no_entries_line = "no entries";
|
|
if (0 == strncmp(s, no_entries_line, strlen(no_entries_line)))
|
|
{
|
|
*return_job_list = job_list;
|
|
free(output);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Parse the optional printer status line.
|
|
// "federal is ready and printing via dev"
|
|
//
|
|
{
|
|
char *buffer = new char[128];
|
|
char *opt_status_line = buffer;
|
|
|
|
sprintf(buffer, "%s is ready and printing via ", printer);
|
|
if (0 == strncmp(s, opt_status_line, strlen(opt_status_line)))
|
|
{
|
|
qname = strtok(s, " \t");
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
network = strtok(s, " \n");
|
|
|
|
NEXT_OUTPUT_LINE(s,s1);
|
|
}
|
|
|
|
delete [] buffer;
|
|
}
|
|
|
|
//
|
|
// Parse the legend line.
|
|
// "Rank Owner Job Files Total Size"
|
|
// or
|
|
// "Rank Pri Owner Job Files Total Size"
|
|
//
|
|
{
|
|
char *tmp;
|
|
|
|
tmp = strtok(s, " ");
|
|
if (strcmp(tmp, "Rank"))
|
|
fprintf(stderr, "Unexpected legend column: %s != Rank\n", tmp);
|
|
|
|
tmp = strtok(NULL, " ");
|
|
if (0 == strcmp(tmp, "Pri"))
|
|
{
|
|
has_pri = TRUE;
|
|
tmp = strtok(NULL, " ");
|
|
}
|
|
if (strcmp(tmp, "Owner"))
|
|
fprintf(stderr, "Unexpected legend column: %s != Owner\n", tmp);
|
|
|
|
tmp = strtok(NULL, " ");
|
|
if (strcmp(tmp, "Job"))
|
|
fprintf(stderr, "Unexpected legend column: %s != Job\n", tmp);
|
|
|
|
tmp = strtok(NULL, " ");
|
|
if (strcmp(tmp, "Files"))
|
|
fprintf(stderr, "Unexpected legend column: %s != Files\n", tmp);
|
|
|
|
tmp = strtok(NULL, " ");
|
|
if (strcmp(tmp, "Total"))
|
|
fprintf(stderr, "Unexpected legend column: %s != Total\n", tmp);
|
|
|
|
tmp = strtok(NULL, " \n");
|
|
if (strcmp(tmp, "Size"))
|
|
fprintf(stderr, "Unexpected legend column: %s != Size\n", tmp);
|
|
}
|
|
|
|
|
|
NEXT_OUTPUT_LINE(s,s1);
|
|
|
|
//
|
|
// Parse the job lines.
|
|
// "active mgreess 65 (standard input) 13482 bytes"
|
|
// or
|
|
// "1st 0 mgreess 7 ParseJobs.C 33367 bytes"
|
|
//
|
|
while (s && *s)
|
|
{
|
|
strtok(s, " \t");
|
|
if (has_pri)
|
|
strtok(NULL, " ");
|
|
owner = strtok(NULL, " ");
|
|
jnumber = strtok(NULL, " ");
|
|
jname = strtok(NULL," ");
|
|
jsize = strtok(NULL," ");
|
|
|
|
if (NULL == owner || NULL == jnumber || NULL == jname || NULL == jsize)
|
|
{
|
|
NEXT_OUTPUT_LINE(s,s1);
|
|
continue;
|
|
}
|
|
|
|
if (NULL == qname)
|
|
qname = printer;
|
|
|
|
if (hostname && strcmp(qname, hostname))
|
|
sprintf(buf, "%s|%s|%s|%s@%s|%s %s|%s|%s\n", qname, jname, jnumber,
|
|
owner, hostname, month, date, stime, jsize);
|
|
else
|
|
sprintf(buf, "%s|%s|%s|%s|%s %s|%s|%s\n", qname, jname, jnumber,
|
|
owner, month, date, stime, jsize);
|
|
|
|
printf("qname, jname, jnumber, owner, ");
|
|
printf("hostname, month, date, stime, jsize\n");
|
|
printf("%s\n", buf);
|
|
|
|
len = strlen(buf);
|
|
if (prev_buf_size < (current_size + len + 1))
|
|
job_list =
|
|
(char*) realloc(job_list, (current_size + len + 1) * sizeof(char*));
|
|
memcpy(job_list + current_size, buf, len);
|
|
current_size += len;
|
|
(*return_n_jobs)++;
|
|
|
|
NEXT_OUTPUT_LINE(s,s1);
|
|
}
|
|
|
|
*(job_list + current_size) = '\0';
|
|
prev_buf_size = prev_buf_size > current_size ? prev_buf_size : current_size;
|
|
*return_job_list = job_list;
|
|
free(output);
|
|
delete [] buf;
|
|
}
|
|
#endif // Linux local parser
|
|
|
|
|
|
/* BSD PARSER - have to parse the following
|
|
|
|
BSD, HP, and SUN output
|
|
Warning: test1 is down: b906ps3 is ready and printing
|
|
Warning: no daemon present
|
|
|
|
root: 1st [job 006b906ps3.austin.ibm.com]
|
|
/etc/motd 421 bytes
|
|
root: 2nd [job 006b906ps3.austin.ibm.com]
|
|
<File name not available> 421 bytes
|
|
*/
|
|
|
|
int ParseBSDPrintJobs(char *printer, char *jobs,
|
|
char **return_job_list, int *return_n_jobs)
|
|
{
|
|
char *s, *s1;
|
|
char *jname;
|
|
char jnumber[9];
|
|
char *owner;
|
|
char *sdate;
|
|
char *stime;
|
|
char *jsize;
|
|
char *hostname;
|
|
int current_size;
|
|
int len;
|
|
char *buf = new char[300];
|
|
static char *job_list = NULL;
|
|
static int prev_buf_size = 0;
|
|
static int first_time = 1;
|
|
int rc = 1;
|
|
|
|
#ifdef NO_REGCOMP
|
|
static char *bsd_pattern;
|
|
/*
|
|
* Due to bug in regcmp/regex (bug id 1191772), change to C locale for
|
|
* this parsing work. And change back at end of procedure. This workaround
|
|
* appears to be ok since the print service output parsed here is in a
|
|
* "C locale" 8-bit form for inter-machine networking.
|
|
*/
|
|
setlocale(LC_ALL, "C");
|
|
|
|
if (first_time)
|
|
{
|
|
bsd_pattern = regcmp(":.*\\[.*\\]", (char *)NULL);
|
|
first_time = 0;
|
|
}
|
|
#else
|
|
static regex_t bsd_pattern;
|
|
|
|
if (first_time)
|
|
{
|
|
regcomp(&bsd_pattern, ":.*\\[.*\\]", REG_NOSUB);
|
|
first_time = 0;
|
|
}
|
|
#endif
|
|
|
|
if (prev_buf_size == 0)
|
|
{
|
|
prev_buf_size = BUFSIZ;
|
|
job_list = (char *)malloc(prev_buf_size);
|
|
}
|
|
|
|
current_size = 0;
|
|
*job_list = '\0';
|
|
*return_n_jobs = 0;
|
|
sdate = MESSAGE(NotAvailableL);
|
|
stime = sdate;
|
|
|
|
s = strtok(jobs, "\n");
|
|
while (s)
|
|
{
|
|
#ifdef NO_REGCOMP
|
|
if (regex(bsd_pattern, s))
|
|
#else
|
|
if (!regexec(&bsd_pattern, s, (size_t)0, NULL, 0))
|
|
#endif
|
|
{
|
|
owner = s;
|
|
s = strchr(s, ':');
|
|
*s++ = '\0';
|
|
s = strchr(s, '[');
|
|
s1 = jnumber;
|
|
for (s = strchr(s, ' ') + 1; isdigit((int)*s); s++)
|
|
*s1++ = *s;
|
|
*s1++ = '\0';
|
|
for (s1 = s; *s1 == ' '; s1++)
|
|
;
|
|
hostname = s1;
|
|
if (s = strchr(hostname, '.'))
|
|
*s = '\0';
|
|
else
|
|
*(strchr(hostname, ']')) = '\0';
|
|
|
|
s = strtok(NULL, "\n");
|
|
for (s1 = s; *s1 == ' ' || *s1 == '\t'; s1++)
|
|
;
|
|
jname = s1;
|
|
s1 = strrchr(s, ' ');
|
|
*s1-- = '\0';
|
|
s1 = strrchr(s, ' ');
|
|
jsize = s1 + 1;
|
|
for ( ; *s1 == ' '; s1--)
|
|
;
|
|
*(s1 + 1) = '\0';
|
|
sprintf(buf, "%s|%s|%s|%s@%s|%s|%s|%s\n", printer, jname, jnumber,
|
|
owner, hostname, sdate, stime, jsize);
|
|
len = strlen(buf);
|
|
if (prev_buf_size < (current_size + len + 1))
|
|
job_list = (char *) realloc(job_list, (current_size + len + 1) *
|
|
sizeof(char *));
|
|
memcpy(job_list + current_size, buf, len);
|
|
current_size += len;
|
|
(*return_n_jobs)++;
|
|
}
|
|
else
|
|
{
|
|
if (strstr(s, "down"))
|
|
rc = 0;
|
|
}
|
|
s = strtok(NULL, "\n");
|
|
}
|
|
*(job_list + current_size) = '\0';
|
|
prev_buf_size = prev_buf_size > current_size ? prev_buf_size : current_size;
|
|
*return_job_list = job_list;
|
|
|
|
#ifdef NO_REGCOMP
|
|
setlocale(LC_ALL, "");
|
|
#endif
|
|
|
|
delete [] buf;
|
|
return rc;
|
|
}
|
|
|
|
/* AIX version 3 and 4 PARSER - have to parse the following
|
|
|
|
Queue Dev Status Job Name From To
|
|
Submitted Rnk Pri Blks Cp PP %
|
|
------- ----- --------- --------- --- --- ----- --- ---- --
|
|
bsh bshde RUNNING 956 STDIN.14937 root root
|
|
08/02/94 09:55:44 1 15 1 1 0 0
|
|
/var/spool/qdaemon/tOlkCSM
|
|
|
|
OR
|
|
|
|
Queue Dev Status Job Name From To
|
|
Submitted Rnk Pri Blks Cp PP %
|
|
------- ----- --------- --------- --- --- ----- --- ---- --
|
|
john1 lp0 DOWN
|
|
QUEUED 957 STDIN.14952 root root
|
|
08/02/94 10:17:53 1 15 1 1
|
|
/var/spool/qdaemon/tOmgCrx
|
|
|
|
|
|
Also need to parse filenames that are titles: Example, "My Report" below.
|
|
|
|
QUEUED 957 My Report root root
|
|
08/02/94 10:17:53 1 15 1 1
|
|
/var/spool/qdaemon/tOmgCrx
|
|
|
|
*/
|
|
|
|
int ParseAIXv3PrintJobs(char *_printer, char *jobs,
|
|
char **return_job_list, int *return_n_jobs)
|
|
{
|
|
char *buf = new char[300];
|
|
struct stat statbuff;
|
|
char *s, *s1, *c;
|
|
char *jname;
|
|
char *jnumber;
|
|
char *owner;
|
|
char *sdate;
|
|
char *stime;
|
|
char *jsize;
|
|
char *dollar1;
|
|
int current_size;
|
|
int len;
|
|
char printer[60];
|
|
int rc = 1;
|
|
|
|
static char *job_list = NULL;
|
|
static int prev_buf_size = 0;
|
|
|
|
snprintf(printer, sizeof(printer), "%s", _printer);
|
|
if (s = strchr(printer, ':'))
|
|
*s = '\0';
|
|
|
|
if (prev_buf_size == 0)
|
|
{
|
|
prev_buf_size = BUFSIZ;
|
|
job_list = (char *)malloc(prev_buf_size);
|
|
}
|
|
|
|
current_size = 0;
|
|
*job_list = '\0';
|
|
*return_n_jobs = 0;
|
|
|
|
s = jobs;
|
|
s1 = strchr(s, '\n');
|
|
s = s1 + 1;
|
|
s1 = strchr(s, '\n');
|
|
s = s1 + 1;
|
|
s1 = strchr(s, '\n');
|
|
s = s1 + 1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
if (strstr(s, "DOWN"))
|
|
rc = 0;
|
|
while (s && *s)
|
|
{
|
|
dollar1 = strtok(s, " ");
|
|
if (!strncmp(dollar1, printer, strlen(dollar1)))
|
|
{
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
}
|
|
jnumber = strtok(NULL, " ");
|
|
if (!(jnumber && *jnumber))
|
|
{
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
continue;
|
|
}
|
|
jname = strtok(NULL, "\n");
|
|
if (!(jname && *jname))
|
|
{
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
continue;
|
|
}
|
|
for (c = jname + strlen(jname) - 1; *c == ' '; c--)
|
|
;
|
|
for ( ; *c != ' '; c--)
|
|
;
|
|
for ( ; *c == ' '; c--)
|
|
;
|
|
*(c + 1) = '\0';
|
|
for ( ; *c != ' '; c--)
|
|
;
|
|
owner = c + 1;
|
|
for ( ; *c == ' '; c--)
|
|
;
|
|
*(c + 1) = '\0';
|
|
for (c = jname; *c == ' '; c++)
|
|
;
|
|
jname = c;
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
sdate = strtok(s, " ");
|
|
stime = strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
jsize = strtok(NULL, " ");
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
c = strtok(s, " \n");
|
|
if (strstr(c, jname))
|
|
jname = c;
|
|
if (!G_AIX_LOCAL)
|
|
statbuff.st_size = atoi(jsize) * 512;
|
|
else if (stat(c, &statbuff) < 0)
|
|
statbuff.st_size = atoi(jsize) * 512;
|
|
strtok(owner, ".");
|
|
sprintf(buf, "%s|%s|%s|%s|%s|%s|%d\n", printer, jname, jnumber,
|
|
owner, sdate, stime, (int)statbuff.st_size);
|
|
len = strlen(buf);
|
|
if (prev_buf_size < (current_size + len + 1))
|
|
job_list = (char *) realloc(job_list, (current_size + len + 1) *
|
|
sizeof(char *));
|
|
memcpy(job_list + current_size, buf, len);
|
|
current_size += len;
|
|
(*return_n_jobs)++;
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
}
|
|
*(job_list + current_size) = '\0';
|
|
prev_buf_size = prev_buf_size > current_size ? prev_buf_size : current_size;
|
|
*return_job_list = job_list;
|
|
delete [] buf;
|
|
return rc;
|
|
}
|
|
|
|
/* AIX version 2 PARSER - have to parse the following
|
|
|
|
dev arg status request pp output % done
|
|
--- ---------- ---------- -------------------- --------- ------
|
|
bp0 b906ps5 READY
|
|
bp1 s906ps5 READY
|
|
bp2 lp0 READY
|
|
ts1 t1 OFF
|
|
ts2 t2 OFF
|
|
|
|
queue user request blks cops pri time to
|
|
----- ----------------- -------------------- ---- ---- --- ----- --------
|
|
ts1 root /etc/motd 2 1 15 15:57 root
|
|
ts1 root@warpspeed /etc/rc.afs 3 1 15 16:03 root@war
|
|
ts2 root /.profile 1 1 15 16:05 root
|
|
ts2 root /.profile 1 1 15 16:06 root
|
|
ts2 root@warpspeed /etc/rc.afs 3 1 15 16:07 root@war
|
|
|
|
*/
|
|
|
|
int ParseAIXv2PrintJobs(char *printer, char *jobs,
|
|
char **return_job_list, int *return_n_jobs)
|
|
{
|
|
char *buf = new char[300];
|
|
char *s, *s1, *c;
|
|
char *jname;
|
|
char *jnumber;
|
|
char *owner;
|
|
char *sdate;
|
|
char *stime;
|
|
char *jsize;
|
|
char *device;
|
|
char *tmp;
|
|
int current_size;
|
|
int len;
|
|
int rc = 1;
|
|
|
|
static char *job_list = NULL;
|
|
static int prev_buf_size = 0;
|
|
|
|
if (prev_buf_size == 0)
|
|
{
|
|
prev_buf_size = BUFSIZ;
|
|
job_list = (char *)malloc(prev_buf_size);
|
|
}
|
|
|
|
current_size = 0;
|
|
*job_list = '\0';
|
|
*return_n_jobs = 0;
|
|
sdate = MESSAGE(NotAvailableL);
|
|
jnumber = sdate;
|
|
|
|
s = jobs;
|
|
s1 = strchr(s, '\n');
|
|
s = s1 + 1;
|
|
s1 = strchr(s, '\n');
|
|
s = s1 + 1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
while (s)
|
|
{
|
|
device = strtok(s, " ");
|
|
tmp = strtok(NULL, " ");
|
|
c = strtok(NULL, " ");
|
|
if (!strcmp(tmp, printer))
|
|
{
|
|
if (strstr(c, "OFF"))
|
|
rc = 0;
|
|
break;
|
|
}
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
}
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
while (s)
|
|
{
|
|
tmp = strtok(s, " ");
|
|
if (!tmp || strcmp(tmp, device))
|
|
{
|
|
s = s1;
|
|
if (s1)
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
continue;
|
|
}
|
|
owner = strtok(NULL, " ");
|
|
jname = strtok(NULL, " ");
|
|
jsize = strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
strtok(NULL, " ");
|
|
stime = strtok(NULL, " ");
|
|
if (c = strchr(owner, '.'))
|
|
*c = '\0';
|
|
sprintf(buf, "%s|%s|%s|%s|%s|%s|%d\n", printer, jname, jnumber,
|
|
owner, sdate, stime, atoi(jsize) * 512);
|
|
len = strlen(buf);
|
|
if (prev_buf_size < (current_size + len + 1))
|
|
job_list = (char *) realloc(job_list, (current_size + len + 1) *
|
|
sizeof(char *));
|
|
memcpy(job_list + current_size, buf, len);
|
|
current_size += len;
|
|
(*return_n_jobs)++;
|
|
s = s1;
|
|
if (s1 = strchr(s, '\n'))
|
|
*s1++ = '\0';
|
|
}
|
|
*(job_list + current_size) = '\0';
|
|
prev_buf_size = prev_buf_size > current_size ? prev_buf_size : current_size;
|
|
*return_job_list = job_list;
|
|
delete [] buf;
|
|
return rc;
|
|
}
|