2000-04-10 07:09:42 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
2000-04-10 07:09:42 +04:00
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"
2003-01-03 11:28:12 +03:00
static const char * Months [ 13 ] = { " Jan " , " Feb " , " Mar " , " Apr " , " May " , " Jun " ,
2000-04-10 07:09:42 +04:00
" 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 */
2002-02-27 02:22:02 +03:00
/* FIXME: Use next_token rather than strtok! */
2000-04-10 07:09:42 +04:00
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 ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , tok [ USERTOK ] ) ;
fstrcpy ( buf - > fs_file , tok [ FILETOK ] ) ;
2000-04-10 07:09:42 +04:00
if ( ( FILETOK + 1 ) ! = TOTALTOK ) {
int i ;
for ( i = ( FILETOK + 1 ) ; i < TOTALTOK ; i + + ) {
2002-04-22 22:48:45 +04:00
/* FIXME: Using fstrcat rather than other means is a bit
* inefficient ; this might be a problem for enormous queues with
* many fields . */
fstrcat ( buf - > fs_file , " " ) ;
fstrcat ( buf - > fs_file , tok [ i ] ) ;
2000-04-10 07:09:42 +04:00
}
/* Ensure null termination. */
2002-04-22 22:48:45 +04:00
fstrterminate ( buf - > fs_file ) ;
2000-04-10 07:09:42 +04:00
}
# 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 .
2001-03-27 07:16:05 +04:00
< J . P . M . v . Itegem @ tue . nl > Dec 17 , 1999
Modified to work with lprng 3.16
With lprng 3.16 The lpq time looks like
" 23:15:07 "
" 23:15:07.100 "
" 1999-12-16-23:15:07 "
" 1999-12-16-23:15:07.100 "
2000-04-10 07:09:42 +04:00
*/
static time_t LPRng_time ( char * time_string )
{
2001-03-27 07:16:05 +04:00
time_t jobtime ;
struct tm t ;
jobtime = time ( NULL ) ; /* default case: take current time */
t = * localtime ( & jobtime ) ;
if ( atoi ( time_string ) < 24 ) {
t . tm_hour = atoi ( time_string ) ;
t . tm_min = atoi ( time_string + 3 ) ;
t . tm_sec = atoi ( time_string + 6 ) ;
} else {
t . tm_year = atoi ( time_string ) - 1900 ;
t . tm_mon = atoi ( time_string + 5 ) - 1 ;
t . tm_mday = atoi ( time_string + 8 ) ;
t . tm_hour = atoi ( time_string + 11 ) ;
t . tm_min = atoi ( time_string + 14 ) ;
t . tm_sec = atoi ( time_string + 17 ) ;
}
jobtime = mktime ( & t ) ;
return jobtime ;
2000-04-10 07:09:42 +04:00
}
/****************************************************************************
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 ] ;
2002-11-13 02:20:50 +03:00
const char * cptr ;
char * ptr ;
2000-04-10 07:09:42 +04:00
int num_tok = 0 ;
2002-11-13 02:20:50 +03:00
cptr = line ;
2000-10-26 01:28:15 +04:00
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 ;
2002-07-15 14:35:28 +04:00
} else if ( strequal ( tokarr [ LPRNG_RANKTOK ] , " done " ) ) {
buf - > status = LPQ_PRINTED ;
2000-04-10 07:09:42 +04:00
} 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 ] ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , tokarr [ LPRNG_USERTOK ] ) ;
2000-04-10 07:09:42 +04:00
/* The '@hostname' prevents windows from displaying the printing icon
* for the current user on the taskbar . Plop in a null .
*/
2002-11-13 02:20:50 +03:00
if ( ( ptr = strchr_m ( buf - > fs_user , ' @ ' ) ) ! = NULL ) {
* ptr = ' \0 ' ;
2000-04-10 07:09:42 +04:00
}
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_file , tokarr [ LPRNG_FILETOK ] ) ;
2000-04-10 07:09:42 +04:00
if ( ( LPRNG_FILETOK + 1 ) ! = LPRNG_TOTALTOK ) {
int i ;
for ( i = ( LPRNG_FILETOK + 1 ) ; i < LPRNG_TOTALTOK ; i + + ) {
2002-04-22 22:48:45 +04:00
/* FIXME: Using fstrcat rather than other means is a bit
* inefficient ; this might be a problem for enormous queues with
* many fields . */
fstrcat ( buf - > fs_file , " " ) ;
fstrcat ( buf - > fs_file , tokarr [ i ] ) ;
2000-04-10 07:09:42 +04:00
}
/* Ensure null termination. */
2002-04-22 22:48:45 +04:00
fstrterminate ( buf - > fs_file ) ;
2000-04-10 07:09:42 +04:00
}
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 ;
2002-11-13 02:20:50 +03:00
const char * cline = line ;
2000-04-10 07:09:42 +04:00
/* handle the case of "(standard input)" as a filename */
2002-07-15 14:35:28 +04:00
string_sub ( line , " standard input " , " STDIN " , 0 ) ;
2000-04-10 07:09:42 +04:00
all_string_sub ( line , " ( " , " \" " , 0 ) ;
all_string_sub ( line , " ) " , " \" " , 0 ) ;
for ( count = 0 ;
count < 10 & &
2002-11-13 02:20:50 +03:00
next_token ( & cline , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ;
2000-04-10 07:09:42 +04:00
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 */
2001-07-04 11:36:09 +04:00
if ( strchr_m ( tok [ 2 ] , ' ' ) )
2000-04-10 07:09:42 +04:00
fstrcpy ( tok [ 2 ] , " STDIN " ) ;
/* only take the last part of the filename */
{
fstring tmp ;
2001-07-04 11:36:09 +04:00
char * p = strrchr_m ( tok [ 2 ] , ' / ' ) ;
2000-04-10 07:09:42 +04:00
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 ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , tok [ 3 ] ) ;
fstrcpy ( buf - > fs_file , tok [ 2 ] ) ;
2000-04-10 07:09:42 +04:00
}
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 */
2001-07-04 11:36:09 +04:00
if ( strchr_m ( tok [ 4 ] , ' ' ) )
2000-04-10 07:09:42 +04:00
fstrcpy ( tok [ 4 ] , " STDIN " ) ;
/* only take the last part of the filename */
{
fstring tmp ;
2001-07-04 11:36:09 +04:00
char * p = strrchr_m ( tok [ 4 ] , ' / ' ) ;
2000-04-10 07:09:42 +04:00
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 ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , tok [ 5 ] ) ;
fstrcpy ( buf - > fs_file , tok [ 4 ] ) ;
2000-04-10 07:09:42 +04:00
}
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
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-13 02:20:50 +03:00
static BOOL parse_lpq_hpux ( char * line , print_queue_struct * buf , BOOL first )
2000-04-10 07:09:42 +04:00
{
/* 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 ' ;
2002-11-13 02:20:50 +03:00
const char * cline = line ;
2000-04-10 07:09:42 +04:00
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 */
2002-07-15 14:35:28 +04:00
string_sub ( line , " standard input " , " STDIN " , 0 ) ;
2000-04-10 07:09:42 +04:00
all_string_sub ( line , " ( " , " \" " , 0 ) ;
all_string_sub ( line , " ) " , " \" " , 0 ) ;
2002-11-13 02:20:50 +03:00
for ( count = 0 ; count < 2 & & next_token ( & cline , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
2000-04-10 07:09:42 +04:00
/* 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 */
2001-07-04 11:36:09 +04:00
if ( strchr_m ( tok [ 0 ] , ' ' ) )
2000-04-10 07:09:42 +04:00
fstrcpy ( tok [ 0 ] , " STDIN " ) ;
buf - > size = atoi ( tok [ 1 ] ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_file , tok [ 0 ] ) ;
2000-04-10 07:09:42 +04:00
/* fill things from header line */
buf - > time = jobtime ;
buf - > job = jobid ;
buf - > status = jobstat ;
buf - > priority = jobprio ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , jobuser ) ;
2000-04-10 07:09:42 +04:00
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 */
2002-07-15 14:35:28 +04:00
string_sub ( line , " - " , " " , 0 ) ;
2000-04-10 07:09:42 +04:00
2002-11-13 02:20:50 +03:00
for ( count = 0 ; count < 12 & & next_token ( & cline , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
2000-04-10 07:09:42 +04:00
/* 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 ] ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( jobuser , tok [ 2 ] ) ;
2000-04-10 07:09:42 +04:00
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 ;
2002-11-13 02:20:50 +03:00
const char * cline = line ;
2000-04-10 07:09:42 +04:00
/*
* 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 = ' ' ;
2002-11-13 02:20:50 +03:00
for ( count = 0 ; count < 9 & & next_token ( & cline , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + )
2000-04-10 07:09:42 +04:00
;
/* 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 */
2001-07-04 11:36:09 +04:00
if ( ( p = strchr_m ( tok [ 2 ] , ' ! ' ) ) ) {
2000-04-10 07:09:42 +04:00
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 ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , tok [ 2 ] ) ;
fstrcpy ( buf - > fs_file , tok [ 2 ] ) ;
2000-04-10 07:09:42 +04:00
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 ;
2003-03-05 03:54:47 +03:00
const char * cline = line ;
2000-04-10 07:09:42 +04:00
DEBUG ( 4 , ( " antes [%s] \n " , line ) ) ;
/* handle the case of "-- standard input --" as a filename */
2002-07-15 14:35:28 +04:00
string_sub ( line , " standard input " , " STDIN " , 0 ) ;
2000-04-10 07:09:42 +04:00
DEBUG ( 4 , ( " despues [%s] \n " , line ) ) ;
all_string_sub ( line , " -- " , " \" " , 0 ) ;
all_string_sub ( line , " -- " , " \" " , 0 ) ;
DEBUG ( 4 , ( " despues 1 [%s] \n " , line ) ) ;
2002-07-15 14:35:28 +04:00
string_sub ( line , " [job # " , " " , 0 ) ;
string_sub ( line , " ] " , " " , 0 ) ;
2000-04-10 07:09:42 +04:00
DEBUG ( 4 , ( " despues 2 [%s] \n " , line ) ) ;
2002-11-13 02:20:50 +03:00
for ( count = 0 ; count < 7 & & next_token ( & cline , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
2000-04-10 07:09:42 +04:00
/* 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 ;
2001-07-04 11:36:09 +04:00
char * p = strrchr_m ( tok [ 6 ] , ' / ' ) ;
2000-04-10 07:09:42 +04:00
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 ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , tok [ 1 ] ) ;
fstrcpy ( buf - > fs_file , tok [ 6 ] ) ;
2000-04-10 07:09:42 +04:00
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 ;
2002-11-13 02:20:50 +03:00
const char * cline = line ;
2000-04-10 07:09:42 +04:00
/* handle the case of "(standard input)" as a filename */
2002-07-15 14:35:28 +04:00
string_sub ( line , " stdin " , " STDIN " , 0 ) ;
2000-04-10 07:09:42 +04:00
all_string_sub ( line , " ( " , " \" " , 0 ) ;
all_string_sub ( line , " ) " , " \" " , 0 ) ;
2002-11-13 02:20:50 +03:00
for ( count = 0 ; count < 11 & & next_token ( & cline , tok [ count ] , NULL , sizeof ( tok [ count ] ) ) ; count + + ) ;
2000-04-10 07:09:42 +04:00
/* 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 */
2001-07-04 11:36:09 +04:00
if ( strchr_m ( tok [ 6 ] , ' ' ) )
2000-04-10 07:09:42 +04:00
fstrcpy ( tok [ 6 ] , " STDIN " ) ;
/* only take the last part of the filename */
{
fstring tmp ;
2001-07-04 11:36:09 +04:00
char * p = strrchr_m ( tok [ 6 ] , ' / ' ) ;
2000-04-10 07:09:42 +04:00
if ( p )
{
fstrcpy ( tmp , p + 1 ) ;
fstrcpy ( tok [ 6 ] , tmp ) ;
}
}
buf - > job = atoi ( tok [ 4 ] ) ;
buf - > size = atoi ( tok [ 7 ] ) ;
2001-07-04 11:36:09 +04:00
if ( strchr_m ( tok [ 7 ] , ' K ' ) )
2000-04-10 07:09:42 +04:00
buf - > size * = 1024 ;
2001-07-04 11:36:09 +04:00
if ( strchr_m ( tok [ 7 ] , ' M ' ) )
2000-04-10 07:09:42 +04:00
buf - > size * = 1024 * 1024 ;
buf - > status = strequal ( tok [ 0 ] , " active " ) ? LPQ_PRINTING : LPQ_QUEUED ;
buf - > priority = 0 ;
buf - > time = time ( NULL ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , tok [ 1 ] ) ;
fstrcpy ( buf - > fs_file , tok [ 6 ] ) ;
2000-04-10 07:09:42 +04:00
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 */
2001-07-04 11:36:09 +04:00
if ( strchr_m ( parse_line . owner , ' ' ) )
* ( strchr_m ( parse_line . owner , ' ' ) ) = ' \0 ' ;
2000-10-07 04:48:27 +04:00
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 ' ;
2003-09-05 23:59:55 +04:00
trim_char ( parse_line . status , ' \0 ' , ' ' ) ;
2000-10-07 04:48:27 +04:00
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 ' ;
2003-09-05 23:59:55 +04:00
trim_char ( parse_line . jobname , ' \0 ' , ' ' ) ;
2000-10-07 04:48:27 +04:00
buf - > job = atoi ( parse_line . jobid ) ;
buf - > priority = 0 ;
buf - > size = atoi ( parse_line . size ) ;
buf - > time = time ( NULL ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , parse_line . owner ) ;
fstrcpy ( buf - > fs_file , parse_line . jobname ) ;
2000-10-07 04:48:27 +04:00
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 ' ;
2003-09-05 23:59:55 +04:00
trim_char ( parse_line . jobname , ' \0 ' , ' ' ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_file , parse_line . jobname ) ;
2000-10-07 04:48:27 +04:00
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 ' ;
2003-09-05 23:59:55 +04:00
trim_char ( parse_line . status , ' \0 ' , ' ' ) ;
2000-10-07 04:48:27 +04:00
if ( ! strequal ( parse_line . status , LPROS2_PRINTING ) & &
! strequal ( parse_line . status , LPROS2_PAUSED ) & &
! strequal ( parse_line . status , LPROS2_WAITING ) )
return ( False ) ;
2003-04-23 17:27:35 +04:00
fstrcpy ( buf - > fs_user , parse_line . owner ) ;
2000-10-07 04:48:27 +04:00
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
2003-01-03 11:28:12 +03:00
static const char * stat0_strings [ ] = { " enabled " , " online " , " idle " , " no entries " , " free " , " ready " , NULL } ;
static const char * stat1_strings [ ] = { " offline " , " disabled " , " down " , " off " , " waiting " , " no daemon " , NULL } ;
static const char * stat2_strings [ ] = { " jam " , " paper " , " error " , " responding " , " not accepting " , " not running " , " turned off " , NULL } ;
2000-04-10 07:09:42 +04:00
2000-11-14 18:26:53 +03:00
# ifdef DEVELOPER
/****************************************************************************
parse a vlp line
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static BOOL parse_lpq_vlp ( char * line , print_queue_struct * buf , BOOL first )
{
int toknum = 0 ;
fstring tok ;
2002-11-13 02:20:50 +03:00
const char * cline = line ;
2000-11-14 18:26:53 +03:00
/* First line is printer status */
if ( ! isdigit ( line [ 0 ] ) ) return False ;
/* Parse a print job entry */
2002-11-13 02:20:50 +03:00
while ( next_token ( & cline , tok , NULL , sizeof ( fstring ) ) ) {
2000-11-14 18:26:53 +03:00
switch ( toknum ) {
case 0 :
buf - > job = atoi ( tok ) ;
break ;
case 1 :
buf - > size = atoi ( tok ) ;
break ;
case 2 :
buf - > status = atoi ( tok ) ;
break ;
case 3 :
buf - > time = atoi ( tok ) ;
break ;
case 4 :
2002-03-15 11:14:10 +03:00
fstrcpy ( buf - > fs_user , tok ) ;
2000-11-14 18:26:53 +03:00
break ;
case 5 :
2002-03-15 11:14:10 +03:00
fstrcpy ( buf - > fs_file , tok ) ;
2000-11-14 18:26:53 +03:00
break ;
}
toknum + + ;
}
return True ;
}
# endif /* DEVELOPER */
2000-04-10 07:09:42 +04:00
/****************************************************************************
parse a lpq line . Choose printing style
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-11-13 02:20:50 +03:00
2004-10-19 21:05:01 +04:00
BOOL parse_lpq_entry ( enum printing_types printing_type , char * line ,
2000-04-10 07:09:42 +04:00
print_queue_struct * buf ,
print_status_struct * status , BOOL first )
{
BOOL ret ;
2004-10-19 21:05:01 +04:00
switch ( printing_type )
2000-04-10 07:09:42 +04:00
{
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 ;
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-11-14 18:26:53 +03:00
# ifdef DEVELOPER
case PRINT_VLP :
case PRINT_TEST :
ret = parse_lpq_vlp ( line , buf , first ) ;
break ;
# endif /* DEVELOPER */
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. */
{
2001-07-04 11:36:09 +04:00
char * p = strchr_m ( line , ' \n ' ) ;
2000-04-10 07:09:42 +04:00
if ( p ) * p = 0 ;
}
/* in the LPRNG case, we skip lines starting by a space.*/
2006-03-08 04:18:18 +03:00
if ( ! ret & & ( printing_type = = PRINT_LPRNG ) )
2000-04-10 07:09:42 +04:00
{
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 ;
2003-07-03 23:11:31 +04:00
strlower_m ( line ) ;
2000-04-10 07:09:42 +04:00
switch ( status - > status ) {
case LPSTAT_OK :
for ( i = 0 ; stat0_strings [ i ] ; i + + )
2004-03-09 03:17:14 +03:00
if ( strstr_m ( line , stat0_strings [ i ] ) ) {
2003-04-23 17:27:35 +04:00
fstrcpy ( status - > message , line ) ;
status - > status = LPSTAT_OK ;
return ret ;
2000-04-10 07:09:42 +04:00
}
case LPSTAT_STOPPED :
for ( i = 0 ; stat1_strings [ i ] ; i + + )
2004-03-09 03:17:14 +03:00
if ( strstr_m ( line , stat1_strings [ i ] ) ) {
2003-04-23 17:27:35 +04:00
fstrcpy ( status - > message , line ) ;
status - > status = LPSTAT_STOPPED ;
return ret ;
2000-04-10 07:09:42 +04:00
}
case LPSTAT_ERROR :
for ( i = 0 ; stat2_strings [ i ] ; i + + )
2004-03-09 03:17:14 +03:00
if ( strstr_m ( line , stat2_strings [ i ] ) ) {
2003-04-23 17:27:35 +04:00
fstrcpy ( status - > message , line ) ;
status - > status = LPSTAT_ERROR ;
return ret ;
2000-04-10 07:09:42 +04:00
}
break ;
}
}
return ( ret ) ;
}