2000-04-10 07:09:42 +04:00
/*
Unix SMB / Netbios implementation .
Version 3.0
lpq parsing routines
Copyright ( C ) Andrew Tridgell 2000
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 2 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*/
# include "includes.h"
extern int DEBUGLEVEL ;
static char * Months [ 13 ] = { " Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " ,
" Jul " , " Aug " , " Sep " , " Oct " , " Nov " , " Dec " , " Err " } ;
/*******************************************************************
process time fields
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static time_t EntryTime ( fstring tok [ ] , int ptr , int count , int minimum )
{
time_t jobtime , jobtime1 ;
jobtime = time ( NULL ) ; /* default case: take current time */
if ( count > = minimum ) {
struct tm * t ;
int i , day , hour , min , sec ;
char * c ;
for ( i = 0 ; i < 13 ; i + + ) if ( ! strncmp ( tok [ ptr ] , Months [ i ] , 3 ) ) break ; /* Find month */
if ( i < 12 ) {
t = localtime ( & jobtime ) ;
day = atoi ( tok [ ptr + 1 ] ) ;
c = ( char * ) ( tok [ ptr + 2 ] ) ;
* ( c + 2 ) = 0 ;
hour = atoi ( c ) ;
* ( c + 5 ) = 0 ;
min = atoi ( c + 3 ) ;
if ( * ( c + 6 ) ! = 0 ) sec = atoi ( c + 6 ) ;
else sec = 0 ;
if ( ( t - > tm_mon < i ) | |
( ( t - > tm_mon = = i ) & &
( ( t - > tm_mday < day ) | |
( ( t - > tm_mday = = day ) & &
( t - > tm_hour * 60 + t - > tm_min < hour * 60 + min ) ) ) ) )
t - > tm_year - - ; /* last year's print job */
t - > tm_mon = i ;
t - > tm_mday = day ;
t - > tm_hour = hour ;
t - > tm_min = min ;
t - > tm_sec = sec ;
jobtime1 = mktime ( t ) ;
if ( jobtime1 ! = ( time_t ) - 1 )
jobtime = jobtime1 ;
}
}
return jobtime ;
}
/****************************************************************************
parse a lpq line
here is an example of lpq output under bsd
Warning : no daemon present
Rank Owner Job Files Total Size
1 st tridge 148 README 8096 bytes
here is an example of lpq output under osf / 1
Warning : no daemon present
Rank Pri Owner Job Files Total Size
1 st 0 tridge 148 README 8096 bytes
< allan @ umich . edu > June 30 , 1998.
Modified to handle file names with spaces , like the parse_lpq_lprng code
further below .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_bsd ( char * line , print_queue_struct * buf , BOOL first )
{
# ifdef OSF1
# define RANKTOK 0
# define PRIOTOK 1
# define USERTOK 2
# define JOBTOK 3
# define FILETOK 4
# define TOTALTOK (count - 2)
# define NTOK 6
# define MAXTOK 128
# else /* OSF1 */
# define RANKTOK 0
# define USERTOK 1
# define JOBTOK 2
# define FILETOK 3
# define TOTALTOK (count - 2)
# define NTOK 5
# define MAXTOK 128
# endif /* OSF1 */
char * tok [ MAXTOK ] ;
int count = 0 ;
pstring line2 ;
pstrcpy ( line2 , line ) ;
# ifdef OSF1
{
size_t length ;
length = strlen ( line2 ) ;
if ( line2 [ length - 3 ] = = ' : ' )
return ( False ) ;
}
# endif /* OSF1 */
tok [ 0 ] = strtok ( line2 , " \t " ) ;
count + + ;
while ( ( ( tok [ count ] = strtok ( NULL , " \t " ) ) ! = NULL ) & & ( count < MAXTOK ) ) {
count + + ;
}
/* we must get at least NTOK tokens */
if ( count < NTOK )
return ( False ) ;
/* the Job and Total columns must be integer */
if ( ! isdigit ( ( int ) * tok [ JOBTOK ] ) | | ! isdigit ( ( int ) * tok [ TOTALTOK ] ) ) return ( False ) ;
buf - > job = atoi ( tok [ JOBTOK ] ) ;
buf - > size = atoi ( tok [ TOTALTOK ] ) ;
buf - > status = strequal ( tok [ RANKTOK ] , " active " ) ? LPQ_PRINTING : LPQ_QUEUED ;
buf - > time = time ( NULL ) ;
StrnCpy ( buf - > user , tok [ USERTOK ] , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , tok [ FILETOK ] , sizeof ( buf - > file ) - 1 ) ;
if ( ( FILETOK + 1 ) ! = TOTALTOK ) {
int bufsize ;
int i ;
bufsize = sizeof ( buf - > file ) - strlen ( buf - > file ) - 1 ;
for ( i = ( FILETOK + 1 ) ; i < TOTALTOK ; i + + ) {
safe_strcat ( buf - > file , " " , bufsize ) ;
safe_strcat ( buf - > file , tok [ i ] , bufsize - 1 ) ;
bufsize = sizeof ( buf - > file ) - strlen ( buf - > file ) - 1 ;
if ( bufsize < = 0 ) {
break ;
}
}
/* Ensure null termination. */
buf - > file [ sizeof ( buf - > file ) - 1 ] = ' \0 ' ;
}
# ifdef PRIOTOK
buf - > priority = atoi ( tok [ PRIOTOK ] ) ;
# else
buf - > priority = 1 ;
# endif
return ( True ) ;
}
/*
< magnus @ hum . auc . dk >
LPRng_time modifies the current date by inserting the hour and minute from
the lpq output . The lpq time looks like " 23:15:07 "
< allan @ umich . edu > June 30 , 1998.
Modified to work with the re - written parse_lpq_lprng routine .
*/
static time_t LPRng_time ( char * time_string )
{
time_t jobtime ;
struct tm * t ;
jobtime = time ( NULL ) ; /* default case: take current time */
t = localtime ( & jobtime ) ;
t - > tm_hour = atoi ( time_string ) ;
t - > tm_min = atoi ( time_string + 3 ) ;
t - > tm_sec = atoi ( time_string + 6 ) ;
jobtime = mktime ( t ) ;
return jobtime ;
}
/****************************************************************************
parse a lprng lpq line
< allan @ umich . edu > June 30 , 1998.
Re - wrote this to handle file names with spaces , multiple file names on one
lpq line , etc ;
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_lprng ( char * line , print_queue_struct * buf , BOOL first )
{
# define LPRNG_RANKTOK 0
# define LPRNG_USERTOK 1
# define LPRNG_PRIOTOK 2
# define LPRNG_JOBTOK 3
# define LPRNG_FILETOK 4
# define LPRNG_TOTALTOK (num_tok - 2)
# define LPRNG_TIMETOK (num_tok - 1)
# define LPRNG_NTOK 7
# define LPRNG_MAXTOK 128 /* PFMA just to keep us from running away. */
2000-10-26 01:28:15 +04:00
fstring tokarr [ LPRNG_MAXTOK ] ;
2000-04-10 07:09:42 +04:00
char * cptr ;
int num_tok = 0 ;
pstring line2 ;
pstrcpy ( line2 , line ) ;
2000-10-26 01:28:15 +04:00
cptr = line2 ;
while ( next_token ( & cptr , tokarr [ num_tok ] , " \t " , sizeof ( fstring ) ) & & ( num_tok < LPRNG_MAXTOK ) )
2000-04-10 07:09:42 +04:00
num_tok + + ;
/* We must get at least LPRNG_NTOK tokens. */
if ( num_tok < LPRNG_NTOK ) {
return ( False ) ;
}
if ( ! isdigit ( ( int ) * tokarr [ LPRNG_JOBTOK ] ) | | ! isdigit ( ( int ) * tokarr [ LPRNG_TOTALTOK ] ) ) {
return ( False ) ;
}
buf - > job = atoi ( tokarr [ LPRNG_JOBTOK ] ) ;
buf - > size = atoi ( tokarr [ LPRNG_TOTALTOK ] ) ;
if ( strequal ( tokarr [ LPRNG_RANKTOK ] , " active " ) ) {
buf - > status = LPQ_PRINTING ;
} else if ( isdigit ( ( int ) * tokarr [ LPRNG_RANKTOK ] ) ) {
buf - > status = LPQ_QUEUED ;
} else {
buf - > status = LPQ_PAUSED ;
}
buf - > priority = * tokarr [ LPRNG_PRIOTOK ] - ' A ' ;
buf - > time = LPRng_time ( tokarr [ LPRNG_TIMETOK ] ) ;
StrnCpy ( buf - > user , tokarr [ LPRNG_USERTOK ] , sizeof ( buf - > user ) - 1 ) ;
/* The '@hostname' prevents windows from displaying the printing icon
* for the current user on the taskbar . Plop in a null .
*/
if ( ( cptr = strchr ( buf - > user , ' @ ' ) ) ! = NULL ) {
* cptr = ' \0 ' ;
}
StrnCpy ( buf - > file , tokarr [ LPRNG_FILETOK ] , sizeof ( buf - > file ) - 1 ) ;
if ( ( LPRNG_FILETOK + 1 ) ! = LPRNG_TOTALTOK ) {
int bufsize ;
int i ;
bufsize = sizeof ( buf - > file ) - strlen ( buf - > file ) - 1 ;
for ( i = ( LPRNG_FILETOK + 1 ) ; i < LPRNG_TOTALTOK ; i + + ) {
safe_strcat ( buf - > file , " " , bufsize ) ;
safe_strcat ( buf - > file , tokarr [ i ] , bufsize - 1 ) ;
bufsize = sizeof ( buf - > file ) - strlen ( buf - > file ) - 1 ;
if ( bufsize < = 0 ) {
break ;
}
}
/* Ensure null termination. */
buf - > file [ sizeof ( buf - > file ) - 1 ] = ' \0 ' ;
}
return ( True ) ;
}
/*******************************************************************
parse lpq on an aix system
Queue Dev Status Job Files User PP % Blks Cp Rnk
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
lazer lazer READY
lazer lazer RUNNING 537 6297 doc . A kvintus @ IE 0 10 2445 1 1
QUEUED 538 C . ps root @ IEDVB 124 1 2
QUEUED 539 E . ps root @ IEDVB 28 1 3
QUEUED 540 L . ps root @ IEDVB 172 1 4
QUEUED 541 P . ps root @ IEDVB 22 1 5
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_aix ( char * line , print_queue_struct * buf , BOOL first )
{
fstring tok [ 11 ] ;
int count = 0 ;
/* handle the case of "(standard input)" as a filename */
pstring_sub ( line , " standard input " , " STDIN " ) ;
all_string_sub ( line , " ( " , " \" " , 0 ) ;
all_string_sub ( line , " ) " , " \" " , 0 ) ;
for ( count = 0 ;
count < 10 & &
next_token ( & line , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ;
count + + ) ;
/* we must get 6 tokens */
if ( count < 10 )
{
if ( ( count = = 7 ) & & ( ( strcmp ( tok [ 0 ] , " QUEUED " ) = = 0 ) | | ( strcmp ( tok [ 0 ] , " HELD " ) = = 0 ) ) )
{
/* the 2nd and 5th columns must be integer */
if ( ! isdigit ( ( int ) * tok [ 1 ] ) | | ! isdigit ( ( int ) * tok [ 4 ] ) ) return ( False ) ;
buf - > size = atoi ( tok [ 4 ] ) * 1024 ;
/* if the fname contains a space then use STDIN */
if ( strchr ( tok [ 2 ] , ' ' ) )
fstrcpy ( tok [ 2 ] , " STDIN " ) ;
/* only take the last part of the filename */
{
fstring tmp ;
char * p = strrchr ( tok [ 2 ] , ' / ' ) ;
if ( p )
{
fstrcpy ( tmp , p + 1 ) ;
fstrcpy ( tok [ 2 ] , tmp ) ;
}
}
buf - > job = atoi ( tok [ 1 ] ) ;
buf - > status = strequal ( tok [ 0 ] , " HELD " ) ? LPQ_PAUSED : LPQ_QUEUED ;
buf - > priority = 0 ;
buf - > time = time ( NULL ) ;
StrnCpy ( buf - > user , tok [ 3 ] , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , tok [ 2 ] , sizeof ( buf - > file ) - 1 ) ;
}
else
{
DEBUG ( 6 , ( " parse_lpq_aix count=%d \n " , count ) ) ;
return ( False ) ;
}
}
else
{
/* the 4th and 9th columns must be integer */
if ( ! isdigit ( ( int ) * tok [ 3 ] ) | | ! isdigit ( ( int ) * tok [ 8 ] ) ) return ( False ) ;
buf - > size = atoi ( tok [ 8 ] ) * 1024 ;
/* if the fname contains a space then use STDIN */
if ( strchr ( tok [ 4 ] , ' ' ) )
fstrcpy ( tok [ 4 ] , " STDIN " ) ;
/* only take the last part of the filename */
{
fstring tmp ;
char * p = strrchr ( tok [ 4 ] , ' / ' ) ;
if ( p )
{
fstrcpy ( tmp , p + 1 ) ;
fstrcpy ( tok [ 4 ] , tmp ) ;
}
}
buf - > job = atoi ( tok [ 3 ] ) ;
buf - > status = strequal ( tok [ 2 ] , " RUNNING " ) ? LPQ_PRINTING : LPQ_QUEUED ;
buf - > priority = 0 ;
buf - > time = time ( NULL ) ;
StrnCpy ( buf - > user , tok [ 5 ] , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , tok [ 4 ] , sizeof ( buf - > file ) - 1 ) ;
}
return ( True ) ;
}
/****************************************************************************
parse a lpq line
here is an example of lpq output under hpux ; note there ' s no space after - o !
$ > lpstat - oljplus
ljplus - 2153 user priority 0 Jan 19 08 : 14 on ljplus
util . c 125697 bytes
server . c 110712 bytes
ljplus - 2154 user priority 0 Jan 19 08 : 14 from client
( standard input ) 7551 bytes
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_hpux ( char * line , print_queue_struct * buf , BOOL first )
{
/* must read two lines to process, therefore keep some values static */
static BOOL header_line_ok = False , base_prio_reset = False ;
static fstring jobuser ;
static int jobid ;
static int jobprio ;
static time_t jobtime ;
static int jobstat = LPQ_QUEUED ;
/* to store minimum priority to print, lpstat command should be invoked
with - p option first , to work */
static int base_prio ;
int count ;
char htab = ' \011 ' ;
fstring tok [ 12 ] ;
/* If a line begins with a horizontal TAB, it is a subline type */
if ( line [ 0 ] = = htab ) { /* subline */
/* check if it contains the base priority */
if ( ! strncmp ( line , " \t fence priority : " , 18 ) ) {
base_prio = atoi ( & line [ 18 ] ) ;
DEBUG ( 4 , ( " fence priority set at %d \n " , base_prio ) ) ;
}
if ( ! header_line_ok ) return ( False ) ; /* incorrect header line */
/* handle the case of "(standard input)" as a filename */
pstring_sub ( line , " standard input " , " STDIN " ) ;
all_string_sub ( line , " ( " , " \" " , 0 ) ;
all_string_sub ( line , " ) " , " \" " , 0 ) ;
for ( count = 0 ; count < 2 & & next_token ( & line , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
/* we must get 2 tokens */
if ( count < 2 ) return ( False ) ;
/* the 2nd column must be integer */
if ( ! isdigit ( ( int ) * tok [ 1 ] ) ) return ( False ) ;
/* if the fname contains a space then use STDIN */
if ( strchr ( tok [ 0 ] , ' ' ) )
fstrcpy ( tok [ 0 ] , " STDIN " ) ;
buf - > size = atoi ( tok [ 1 ] ) ;
StrnCpy ( buf - > file , tok [ 0 ] , sizeof ( buf - > file ) - 1 ) ;
/* fill things from header line */
buf - > time = jobtime ;
buf - > job = jobid ;
buf - > status = jobstat ;
buf - > priority = jobprio ;
StrnCpy ( buf - > user , jobuser , sizeof ( buf - > user ) - 1 ) ;
return ( True ) ;
}
else { /* header line */
header_line_ok = False ; /* reset it */
if ( first ) {
if ( ! base_prio_reset ) {
base_prio = 0 ; /* reset it */
base_prio_reset = True ;
}
}
else if ( base_prio ) base_prio_reset = False ;
/* handle the dash in the job id */
pstring_sub ( line , " - " , " " ) ;
for ( count = 0 ; count < 12 & & next_token ( & line , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
/* we must get 8 tokens */
if ( count < 8 ) return ( False ) ;
/* first token must be printer name (cannot check ?) */
/* the 2nd, 5th & 7th column must be integer */
if ( ! isdigit ( ( int ) * tok [ 1 ] ) | | ! isdigit ( ( int ) * tok [ 4 ] ) | | ! isdigit ( ( int ) * tok [ 6 ] ) ) return ( False ) ;
jobid = atoi ( tok [ 1 ] ) ;
StrnCpy ( jobuser , tok [ 2 ] , sizeof ( buf - > user ) - 1 ) ;
jobprio = atoi ( tok [ 4 ] ) ;
/* process time */
jobtime = EntryTime ( tok , 5 , count , 8 ) ;
if ( jobprio < base_prio ) {
jobstat = LPQ_PAUSED ;
DEBUG ( 4 , ( " job %d is paused: prio %d < %d; jobstat=%d \n " , jobid , jobprio , base_prio , jobstat ) ) ;
}
else {
jobstat = LPQ_QUEUED ;
if ( ( count > 8 ) & & ( ( ( strequal ( tok [ 8 ] , " on " ) ) | |
( ( strequal ( tok [ 8 ] , " from " ) ) & &
( ( count > 10 ) & & ( strequal ( tok [ 10 ] , " on " ) ) ) ) ) ) )
jobstat = LPQ_PRINTING ;
}
header_line_ok = True ; /* information is correct */
return ( False ) ; /* need subline info to include into queuelist */
}
}
/****************************************************************************
parse a lpstat line
here is an example of " lpstat -o dcslw " output under sysv
dcslw - 896 tridge 4712 Dec 20 10 : 30 : 30 on dcslw
dcslw - 897 tridge 4712 Dec 20 10 : 30 : 30 being held
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_sysv ( char * line , print_queue_struct * buf , BOOL first )
{
fstring tok [ 9 ] ;
int count = 0 ;
char * p ;
/*
* Handle the dash in the job id , but make sure that we skip over
* the printer name in case we have a dash in that .
* Patch from Dom . Mitchell @ palmerharvey . co . uk .
*/
/*
* Move to the first space .
*/
for ( p = line ; ! isspace ( * p ) & & * p ; p + + )
;
/*
* Back up until the last ' - ' character or
* start of line .
*/
for ( ; ( p > = line ) & & ( * p ! = ' - ' ) ; p - - )
;
if ( ( p > = line ) & & ( * p = = ' - ' ) )
* p = ' ' ;
for ( count = 0 ; count < 9 & & next_token ( & line , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + )
;
/* we must get 7 tokens */
if ( count < 7 )
return ( False ) ;
/* the 2nd and 4th, 6th columns must be integer */
if ( ! isdigit ( ( int ) * tok [ 1 ] ) | | ! isdigit ( ( int ) * tok [ 3 ] ) )
return ( False ) ;
if ( ! isdigit ( ( int ) * tok [ 5 ] ) )
return ( False ) ;
/* if the user contains a ! then trim the first part of it */
if ( ( p = strchr ( tok [ 2 ] , ' ! ' ) ) ) {
fstring tmp ;
fstrcpy ( tmp , p + 1 ) ;
fstrcpy ( tok [ 2 ] , tmp ) ;
}
buf - > job = atoi ( tok [ 1 ] ) ;
buf - > size = atoi ( tok [ 3 ] ) ;
if ( count > 7 & & strequal ( tok [ 7 ] , " on " ) )
buf - > status = LPQ_PRINTING ;
else if ( count > 8 & & strequal ( tok [ 7 ] , " being " ) & & strequal ( tok [ 8 ] , " held " ) )
buf - > status = LPQ_PAUSED ;
else
buf - > status = LPQ_QUEUED ;
buf - > priority = 0 ;
buf - > time = EntryTime ( tok , 4 , count , 7 ) ;
StrnCpy ( buf - > user , tok [ 2 ] , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , tok [ 2 ] , sizeof ( buf - > file ) - 1 ) ;
return ( True ) ;
}
/****************************************************************************
parse a lpq line
here is an example of lpq output under qnx
Spooler : / qnx / spooler , on node 1
Printer : txt ( ready )
0000 : root [ job # 1 ] active 1146 bytes / etc / profile
0001 : root [ job # 2 ] ready 2378 bytes / etc / install
0002 : root [ job # 3 ] ready 1146 bytes - - standard input - -
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_qnx ( char * line , print_queue_struct * buf , BOOL first )
{
fstring tok [ 7 ] ;
int count = 0 ;
DEBUG ( 4 , ( " antes [%s] \n " , line ) ) ;
/* handle the case of "-- standard input --" as a filename */
pstring_sub ( line , " standard input " , " STDIN " ) ;
DEBUG ( 4 , ( " despues [%s] \n " , line ) ) ;
all_string_sub ( line , " -- " , " \" " , 0 ) ;
all_string_sub ( line , " -- " , " \" " , 0 ) ;
DEBUG ( 4 , ( " despues 1 [%s] \n " , line ) ) ;
pstring_sub ( line , " [job # " , " " ) ;
pstring_sub ( line , " ] " , " " ) ;
DEBUG ( 4 , ( " despues 2 [%s] \n " , line ) ) ;
for ( count = 0 ; count < 7 & & next_token ( & line , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
/* we must get 7 tokens */
if ( count < 7 )
return ( False ) ;
/* the 3rd and 5th columns must be integer */
if ( ! isdigit ( ( int ) * tok [ 2 ] ) | | ! isdigit ( ( int ) * tok [ 4 ] ) ) return ( False ) ;
/* only take the last part of the filename */
{
fstring tmp ;
char * p = strrchr ( tok [ 6 ] , ' / ' ) ;
if ( p )
{
fstrcpy ( tmp , p + 1 ) ;
fstrcpy ( tok [ 6 ] , tmp ) ;
}
}
buf - > job = atoi ( tok [ 2 ] ) ;
buf - > size = atoi ( tok [ 4 ] ) ;
buf - > status = strequal ( tok [ 3 ] , " active " ) ? LPQ_PRINTING : LPQ_QUEUED ;
buf - > priority = 0 ;
buf - > time = time ( NULL ) ;
StrnCpy ( buf - > user , tok [ 1 ] , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , tok [ 6 ] , sizeof ( buf - > file ) - 1 ) ;
return ( True ) ;
}
/****************************************************************************
parse a lpq line for the plp printing system
Bertrand Wallrich < Bertrand . Wallrich @ loria . fr >
redone by tridge . Here is a sample queue :
Local Printer ' lp2 ' ( fjall ) :
Printing ( started at Jun 15 13 : 33 : 58 , attempt 1 ) .
Rank Owner Pr Opt Job Host Files Size Date
active tridge X - 6 fjall / etc / hosts 739 Jun 15 13 : 33
3 rd tridge X - 7 fjall / etc / hosts 739 Jun 15 13 : 33
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_plp ( char * line , print_queue_struct * buf , BOOL first )
{
fstring tok [ 11 ] ;
int count = 0 ;
/* handle the case of "(standard input)" as a filename */
pstring_sub ( line , " stdin " , " STDIN " ) ;
all_string_sub ( line , " ( " , " \" " , 0 ) ;
all_string_sub ( line , " ) " , " \" " , 0 ) ;
for ( count = 0 ; count < 11 & & next_token ( & line , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
/* we must get 11 tokens */
if ( count < 11 )
return ( False ) ;
/* the first must be "active" or begin with an integer */
if ( strcmp ( tok [ 0 ] , " active " ) & & ! isdigit ( ( int ) tok [ 0 ] [ 0 ] ) )
return ( False ) ;
/* the 5th and 8th must be integer */
if ( ! isdigit ( ( int ) * tok [ 4 ] ) | | ! isdigit ( ( int ) * tok [ 7 ] ) )
return ( False ) ;
/* if the fname contains a space then use STDIN */
if ( strchr ( tok [ 6 ] , ' ' ) )
fstrcpy ( tok [ 6 ] , " STDIN " ) ;
/* only take the last part of the filename */
{
fstring tmp ;
char * p = strrchr ( tok [ 6 ] , ' / ' ) ;
if ( p )
{
fstrcpy ( tmp , p + 1 ) ;
fstrcpy ( tok [ 6 ] , tmp ) ;
}
}
buf - > job = atoi ( tok [ 4 ] ) ;
buf - > size = atoi ( tok [ 7 ] ) ;
if ( strchr ( tok [ 7 ] , ' K ' ) )
buf - > size * = 1024 ;
if ( strchr ( tok [ 7 ] , ' M ' ) )
buf - > size * = 1024 * 1024 ;
buf - > status = strequal ( tok [ 0 ] , " active " ) ? LPQ_PRINTING : LPQ_QUEUED ;
buf - > priority = 0 ;
buf - > time = time ( NULL ) ;
StrnCpy ( buf - > user , tok [ 1 ] , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , tok [ 6 ] , sizeof ( buf - > file ) - 1 ) ;
return ( True ) ;
}
/****************************************************************************
parse a qstat line
here is an example of " qstat -l -d qms " output under softq
Queue qms : 2 jobs ; daemon active ( 313 ) ; enabled ; accepting ;
job - ID submission - time pri size owner title
205980 : H 98 / 03 / 09 13 : 04 : 05 0 15733 stephenf chap1 . ps
206086 : > 98 / 03 / 12 17 : 24 : 40 0 659 chris -
206087 : 98 / 03 / 12 17 : 24 : 45 0 4876 chris -
Total : 21268 bytes in queue
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_softq ( char * line , print_queue_struct * buf , BOOL first )
{
fstring tok [ 10 ] ;
int count = 0 ;
/* mung all the ":"s to spaces*/
pstring_sub ( line , " : " , " " ) ;
for ( count = 0 ; count < 10 & & next_token ( & line , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
/* we must get 9 tokens */
if ( count < 9 )
return ( False ) ;
/* the 1st and 7th columns must be integer */
if ( ! isdigit ( ( int ) * tok [ 0 ] ) | | ! isdigit ( ( int ) * tok [ 6 ] ) ) return ( False ) ;
/* if the 2nd column is either '>' or 'H' then the 7th and 8th must be
* integer , else it ' s the 6 th and 7 th that must be
*/
if ( * tok [ 1 ] = = ' H ' | | * tok [ 1 ] = = ' > ' )
{
if ( ! isdigit ( ( int ) * tok [ 7 ] ) )
return ( False ) ;
buf - > status = * tok [ 1 ] = = ' > ' ? LPQ_PRINTING : LPQ_PAUSED ;
count = 1 ;
}
else
{
if ( ! isdigit ( ( int ) * tok [ 5 ] ) )
return ( False ) ;
buf - > status = LPQ_QUEUED ;
count = 0 ;
}
buf - > job = atoi ( tok [ 0 ] ) ;
buf - > size = atoi ( tok [ count + 6 ] ) ;
buf - > priority = atoi ( tok [ count + 5 ] ) ;
StrnCpy ( buf - > user , tok [ count + 7 ] , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , tok [ count + 8 ] , sizeof ( buf - > file ) - 1 ) ;
buf - > time = time ( NULL ) ; /* default case: take current time */
{
time_t jobtime ;
struct tm * t ;
t = localtime ( & buf - > time ) ;
t - > tm_mday = atoi ( tok [ count + 2 ] + 6 ) ;
t - > tm_mon = atoi ( tok [ count + 2 ] + 3 ) ;
switch ( * tok [ count + 2 ] )
{
case 7 : case 8 : case 9 : t - > tm_year = atoi ( tok [ count + 2 ] ) ; break ;
default : t - > tm_year = atoi ( tok [ count + 2 ] ) ; break ;
}
t - > tm_hour = atoi ( tok [ count + 3 ] ) ;
t - > tm_min = atoi ( tok [ count + 4 ] ) ;
t - > tm_sec = atoi ( tok [ count + 5 ] ) ;
jobtime = mktime ( t ) ;
if ( jobtime ! = ( time_t ) - 1 )
buf - > time = jobtime ;
}
return ( True ) ;
}
2000-10-07 04:48:27 +04:00
/*******************************************************************
parse lpq on an NT system
Windows 2000 LPD Server
Printer \ \ 10.0 .0 .2 \ NP17PCL ( Paused )
Owner Status Jobname Job - Id Size Pages Priority
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
root ( 9.99 . Printing / usr / lib / rhs / rhs - pr 3 625 0 1
root ( 9.99 . Paused / usr / lib / rhs / rhs - pr 4 625 0 1
jmcd Waiting Re : Samba Open Sour 26 32476 1 1
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_nt ( char * line , print_queue_struct * buf , BOOL first )
{
# define LPRNT_OWNSIZ 11
# define LPRNT_STATSIZ 9
# define LPRNT_JOBSIZ 19
# define LPRNT_IDSIZ 6
# define LPRNT_SIZSIZ 9
typedef struct
{
char owner [ LPRNT_OWNSIZ ] ;
char space1 ;
char status [ LPRNT_STATSIZ ] ;
char space2 ;
char jobname [ LPRNT_JOBSIZ ] ;
char space3 ;
char jobid [ LPRNT_IDSIZ ] ;
char space4 ;
char size [ LPRNT_SIZSIZ ] ;
char terminator ;
} nt_lpq_line ;
nt_lpq_line parse_line ;
# define LPRNT_PRINTING "Printing"
# define LPRNT_WAITING "Waiting"
# define LPRNT_PAUSED "Paused"
memset ( & parse_line , ' \0 ' , sizeof ( parse_line ) ) ;
strncpy ( ( char * ) & parse_line , line , sizeof ( parse_line ) - 1 ) ;
if ( strlen ( ( char * ) & parse_line ) ! = sizeof ( parse_line ) - 1 )
return ( False ) ;
/* Just want the first word in the owner field - the username */
if ( strchr ( parse_line . owner , ' ' ) )
* ( strchr ( parse_line . owner , ' ' ) ) = ' \0 ' ;
else
parse_line . space1 = ' \0 ' ;
/* Make sure we have an owner */
if ( ! strlen ( parse_line . owner ) )
return ( False ) ;
/* Make sure the status is valid */
parse_line . space2 = ' \0 ' ;
trim_string ( parse_line . status , NULL , " " ) ;
if ( ! strequal ( parse_line . status , LPRNT_PRINTING ) & &
! strequal ( parse_line . status , LPRNT_PAUSED ) & &
! strequal ( parse_line . status , LPRNT_WAITING ) )
return ( False ) ;
parse_line . space3 = ' \0 ' ;
trim_string ( parse_line . jobname , NULL , " " ) ;
buf - > job = atoi ( parse_line . jobid ) ;
buf - > priority = 0 ;
buf - > size = atoi ( parse_line . size ) ;
buf - > time = time ( NULL ) ;
StrnCpy ( buf - > user , parse_line . owner , sizeof ( buf - > user ) - 1 ) ;
StrnCpy ( buf - > file , parse_line . jobname , sizeof ( buf - > file ) - 1 ) ;
if ( strequal ( parse_line . status , LPRNT_PRINTING ) )
buf - > status = LPQ_PRINTING ;
else if ( strequal ( parse_line . status , LPRNT_PAUSED ) )
buf - > status = LPQ_PAUSED ;
else
buf - > status = LPQ_QUEUED ;
return ( True ) ;
}
/*******************************************************************
parse lpq on an OS2 system
JobID File Name Rank Size Status Comment
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
3 Control 1 68 Queued root @ psflinu
4 / etc / motd 2 11666 Queued root @ psflinu
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_os2 ( char * line , print_queue_struct * buf , BOOL first )
{
# define LPROS2_IDSIZ 5
# define LPROS2_JOBSIZ 15
# define LPROS2_SIZSIZ 8
# define LPROS2_STATSIZ 12
# define LPROS2_OWNSIZ 12
typedef struct
{
char jobid [ LPROS2_IDSIZ ] ;
char space1 [ 2 ] ;
char jobname [ LPROS2_JOBSIZ ] ;
char space2 [ 14 ] ;
char size [ LPROS2_SIZSIZ ] ;
char space3 [ 4 ] ;
char status [ LPROS2_STATSIZ ] ;
char space4 [ 4 ] ;
char owner [ LPROS2_OWNSIZ ] ;
char terminator ;
} os2_lpq_line ;
os2_lpq_line parse_line ;
# define LPROS2_PRINTING "Printing"
# define LPROS2_WAITING "Queued"
# define LPROS2_PAUSED "Paused"
memset ( & parse_line , ' \0 ' , sizeof ( parse_line ) ) ;
strncpy ( ( char * ) & parse_line , line , sizeof ( parse_line ) - 1 ) ;
if ( strlen ( ( char * ) & parse_line ) ! = sizeof ( parse_line ) - 1 )
return ( False ) ;
/* Get the jobid */
buf - > job = atoi ( parse_line . jobid ) ;
/* Get the job name */
parse_line . space2 [ 0 ] = ' \0 ' ;
trim_string ( parse_line . jobname , NULL , " " ) ;
StrnCpy ( buf - > file , parse_line . jobname , sizeof ( buf - > file ) - 1 ) ;
buf - > priority = 0 ;
buf - > size = atoi ( parse_line . size ) ;
buf - > time = time ( NULL ) ;
/* Make sure we have an owner */
if ( ! strlen ( parse_line . owner ) )
return ( False ) ;
/* Make sure we have a valid status */
parse_line . space4 [ 0 ] = ' \0 ' ;
trim_string ( parse_line . status , NULL , " " ) ;
if ( ! strequal ( parse_line . status , LPROS2_PRINTING ) & &
! strequal ( parse_line . status , LPROS2_PAUSED ) & &
! strequal ( parse_line . status , LPROS2_WAITING ) )
return ( False ) ;
StrnCpy ( buf - > user , parse_line . owner , sizeof ( buf - > user ) - 1 ) ;
if ( strequal ( parse_line . status , LPROS2_PRINTING ) )
buf - > status = LPQ_PRINTING ;
else if ( strequal ( parse_line . status , LPROS2_PAUSED ) )
buf - > status = LPQ_PAUSED ;
else
buf - > status = LPQ_QUEUED ;
return ( True ) ;
}
2000-04-10 07:09:42 +04:00
static char * stat0_strings [ ] = { " enabled " , " online " , " idle " , " no entries " , " free " , " ready " , NULL } ;
static char * stat1_strings [ ] = { " offline " , " disabled " , " down " , " off " , " waiting " , " no daemon " , NULL } ;
static char * stat2_strings [ ] = { " jam " , " paper " , " error " , " responding " , " not accepting " , " not running " , " turned off " , NULL } ;
/****************************************************************************
parse a lpq line . Choose printing style
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
BOOL parse_lpq_entry ( int snum , char * line ,
print_queue_struct * buf ,
print_status_struct * status , BOOL first )
{
BOOL ret ;
switch ( lp_printing ( snum ) )
{
case PRINT_SYSV :
ret = parse_lpq_sysv ( line , buf , first ) ;
break ;
case PRINT_AIX :
ret = parse_lpq_aix ( line , buf , first ) ;
break ;
case PRINT_HPUX :
ret = parse_lpq_hpux ( line , buf , first ) ;
break ;
case PRINT_QNX :
ret = parse_lpq_qnx ( line , buf , first ) ;
break ;
case PRINT_LPRNG :
ret = parse_lpq_lprng ( line , buf , first ) ;
break ;
case PRINT_PLP :
ret = parse_lpq_plp ( line , buf , first ) ;
break ;
case PRINT_SOFTQ :
ret = parse_lpq_softq ( line , buf , first ) ;
break ;
2000-10-07 04:48:27 +04:00
case PRINT_LPRNT :
ret = parse_lpq_nt ( line , buf , first ) ;
break ;
case PRINT_LPROS2 :
ret = parse_lpq_os2 ( line , buf , first ) ;
break ;
2000-04-10 07:09:42 +04:00
default :
ret = parse_lpq_bsd ( line , buf , first ) ;
break ;
}
/* We don't want the newline in the status message. */
{
char * p = strchr ( line , ' \n ' ) ;
if ( p ) * p = 0 ;
}
/* in the LPRNG case, we skip lines starting by a space.*/
if ( line & & ! ret & & ( lp_printing ( snum ) = = PRINT_LPRNG ) )
{
if ( line [ 0 ] = = ' ' )
return ret ;
}
if ( status & & ! ret )
{
/* a few simple checks to see if the line might be a
printer status line :
handle them so that most severe condition is shown */
int i ;
strlower ( line ) ;
switch ( status - > status ) {
case LPSTAT_OK :
for ( i = 0 ; stat0_strings [ i ] ; i + + )
if ( strstr ( line , stat0_strings [ i ] ) ) {
StrnCpy ( status - > message , line , sizeof ( status - > message ) - 1 ) ;
status - > status = LPSTAT_OK ;
return ret ;
}
case LPSTAT_STOPPED :
for ( i = 0 ; stat1_strings [ i ] ; i + + )
if ( strstr ( line , stat1_strings [ i ] ) ) {
StrnCpy ( status - > message , line , sizeof ( status - > message ) - 1 ) ;
status - > status = LPSTAT_STOPPED ;
return ret ;
}
case LPSTAT_ERROR :
for ( i = 0 ; stat2_strings [ i ] ; i + + )
if ( strstr ( line , stat2_strings [ i ] ) ) {
StrnCpy ( status - > message , line , sizeof ( status - > message ) - 1 ) ;
status - > status = LPSTAT_ERROR ;
return ret ;
}
break ;
}
}
return ( ret ) ;
}