2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 2000
6 Copyright (C) 2002 by Martin Pool
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 static char *Months
[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
27 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
30 /*******************************************************************
32 ********************************************************************/
33 static time_t EntryTime(fstring tok
[], int ptr
, int count
, int minimum
)
35 time_t jobtime
,jobtime1
;
37 jobtime
= time(NULL
); /* default case: take current time */
38 if (count
>= minimum
) {
40 int i
, day
, hour
, min
, sec
;
43 for (i
=0; i
<13; i
++) if (!strncmp(tok
[ptr
], Months
[i
],3)) break; /* Find month */
45 t
= localtime(&jobtime
);
46 day
= atoi(tok
[ptr
+1]);
47 c
=(char *)(tok
[ptr
+2]);
52 if(*(c
+6) != 0)sec
= atoi(c
+6);
58 ((t
->tm_mday
== day
)&&
59 (t
->tm_hour
*60+t
->tm_min
< hour
*60+min
)))))
60 t
->tm_year
--; /* last year's print job */
68 if (jobtime1
!= (time_t)-1)
76 /****************************************************************************
79 here is an example of lpq output under bsd
81 Warning: no daemon present
82 Rank Owner Job Files Total Size
83 1st tridge 148 README 8096 bytes
85 here is an example of lpq output under osf/1
87 Warning: no daemon present
88 Rank Pri Owner Job Files Total Size
89 1st 0 tridge 148 README 8096 bytes
92 <allan@umich.edu> June 30, 1998.
93 Modified to handle file names with spaces, like the parse_lpq_lprng code
95 ****************************************************************************/
96 static BOOL
parse_lpq_bsd(char *line
,print_queue_struct
*buf
,BOOL first
)
104 #define TOTALTOK (count - 2)
112 #define TOTALTOK (count - 2)
126 length
= strlen(line2
);
127 if (line2
[length
-3] == ':')
132 tok
[0] = strtok(line2
," \t");
135 while (((tok
[count
] = strtok(NULL
," \t")) != NULL
) && (count
< MAXTOK
)) {
139 /* we must get at least NTOK tokens */
143 /* the Job and Total columns must be integer */
144 if (!isdigit((int)*tok
[JOBTOK
]) || !isdigit((int)*tok
[TOTALTOK
])) return(False
);
146 buf
->job
= atoi(tok
[JOBTOK
]);
147 buf
->size
= atoi(tok
[TOTALTOK
]);
148 buf
->status
= strequal(tok
[RANKTOK
],"active")?LPQ_PRINTING
:LPQ_QUEUED
;
149 buf
->time
= time(NULL
);
150 fstrcpy(buf
->fs_user
,tok
[USERTOK
]);
151 fstrcpy(buf
->fs_file
,tok
[FILETOK
]);
153 if ((FILETOK
+ 1) != TOTALTOK
) {
156 for (i
= (FILETOK
+ 1); i
< TOTALTOK
; i
++) {
157 /* FIXME: Using fstrcat rather than other means is a bit
158 * inefficient; this might be a problem for enormous queues with
160 fstrcat(buf
->fs_file
, " ");
161 fstrcat(buf
->fs_file
, tok
[i
]);
163 /* Ensure null termination. */
164 fstrterminate(buf
->fs_file
);
168 buf
->priority
= atoi(tok
[PRIOTOK
]);
177 LPRng_time modifies the current date by inserting the hour and minute from
178 the lpq output. The lpq time looks like "23:15:07"
180 <allan@umich.edu> June 30, 1998.
181 Modified to work with the re-written parse_lpq_lprng routine.
183 <J.P.M.v.Itegem@tue.nl> Dec 17,1999
184 Modified to work with lprng 3.16
185 With lprng 3.16 The lpq time looks like
188 "1999-12-16-23:15:07"
189 "1999-12-16-23:15:07.100"
192 static time_t LPRng_time(char *time_string
)
197 jobtime
= time(NULL
); /* default case: take current time */
198 t
= *localtime(&jobtime
);
200 if ( atoi(time_string
) < 24 ){
201 t
.tm_hour
= atoi(time_string
);
202 t
.tm_min
= atoi(time_string
+3);
203 t
.tm_sec
= atoi(time_string
+6);
205 t
.tm_year
= atoi(time_string
)-1900;
206 t
.tm_mon
= atoi(time_string
+5)-1;
207 t
.tm_mday
= atoi(time_string
+8);
208 t
.tm_hour
= atoi(time_string
+11);
209 t
.tm_min
= atoi(time_string
+14);
210 t
.tm_sec
= atoi(time_string
+17);
212 jobtime
= mktime(&t
);
218 /****************************************************************************
219 parse a lprng lpq line
220 <allan@umich.edu> June 30, 1998.
221 Re-wrote this to handle file names with spaces, multiple file names on one
223 ****************************************************************************/
224 static BOOL
parse_lpq_lprng(char *line
,print_queue_struct
*buf
,BOOL first
)
226 #define LPRNG_RANKTOK 0
227 #define LPRNG_USERTOK 1
228 #define LPRNG_PRIOTOK 2
229 #define LPRNG_JOBTOK 3
230 #define LPRNG_FILETOK 4
231 #define LPRNG_TOTALTOK (num_tok - 2)
232 #define LPRNG_TIMETOK (num_tok - 1)
234 #define LPRNG_MAXTOK 128 /* PFMA just to keep us from running away. */
236 fstring tokarr
[LPRNG_MAXTOK
];
243 while(next_token( &cptr
, tokarr
[num_tok
], " \t", sizeof(fstring
)) && (num_tok
< LPRNG_MAXTOK
))
246 /* We must get at least LPRNG_NTOK tokens. */
247 if (num_tok
< LPRNG_NTOK
) {
251 if (!isdigit((int)*tokarr
[LPRNG_JOBTOK
]) || !isdigit((int)*tokarr
[LPRNG_TOTALTOK
])) {
255 buf
->job
= atoi(tokarr
[LPRNG_JOBTOK
]);
256 buf
->size
= atoi(tokarr
[LPRNG_TOTALTOK
]);
258 if (strequal(tokarr
[LPRNG_RANKTOK
],"active")) {
259 buf
->status
= LPQ_PRINTING
;
260 } else if (strequal(tokarr
[LPRNG_RANKTOK
],"done")) {
261 buf
->status
= LPQ_PRINTED
;
262 } else if (isdigit((int)*tokarr
[LPRNG_RANKTOK
])) {
263 buf
->status
= LPQ_QUEUED
;
265 buf
->status
= LPQ_PAUSED
;
268 buf
->priority
= *tokarr
[LPRNG_PRIOTOK
] -'A';
270 buf
->time
= LPRng_time(tokarr
[LPRNG_TIMETOK
]);
272 fstrcpy(buf
->fs_user
,tokarr
[LPRNG_USERTOK
]);
274 /* The '@hostname' prevents windows from displaying the printing icon
275 * for the current user on the taskbar. Plop in a null.
278 if ((cptr
= strchr(buf
->fs_user
,'@')) != NULL
) {
282 fstrcpy(buf
->fs_file
,tokarr
[LPRNG_FILETOK
]);
284 if ((LPRNG_FILETOK
+ 1) != LPRNG_TOTALTOK
) {
287 for (i
= (LPRNG_FILETOK
+ 1); i
< LPRNG_TOTALTOK
; i
++) {
288 /* FIXME: Using fstrcat rather than other means is a bit
289 * inefficient; this might be a problem for enormous queues with
291 fstrcat(buf
->fs_file
, " ");
292 fstrcat(buf
->fs_file
, tokarr
[i
]);
294 /* Ensure null termination. */
295 fstrterminate(buf
->fs_file
);
303 /*******************************************************************
304 parse lpq on an aix system
306 Queue Dev Status Job Files User PP % Blks Cp Rnk
307 ------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
309 lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1
310 QUEUED 538 C.ps root@IEDVB 124 1 2
311 QUEUED 539 E.ps root@IEDVB 28 1 3
312 QUEUED 540 L.ps root@IEDVB 172 1 4
313 QUEUED 541 P.ps root@IEDVB 22 1 5
314 ********************************************************************/
315 static BOOL
parse_lpq_aix(char *line
,print_queue_struct
*buf
,BOOL first
)
320 /* handle the case of "(standard input)" as a filename */
321 pstring_sub(line
,"standard input","STDIN");
322 all_string_sub(line
,"(","\"",0);
323 all_string_sub(line
,")","\"",0);
327 next_token(&line
,tok
[count
],NULL
, sizeof(tok
[count
]));
330 /* we must get 6 tokens */
333 if ((count
== 7) && ((strcmp(tok
[0],"QUEUED") == 0) || (strcmp(tok
[0],"HELD") == 0)))
335 /* the 2nd and 5th columns must be integer */
336 if (!isdigit((int)*tok
[1]) || !isdigit((int)*tok
[4])) return(False
);
337 buf
->size
= atoi(tok
[4]) * 1024;
338 /* if the fname contains a space then use STDIN */
339 if (strchr(tok
[2],' '))
340 fstrcpy(tok
[2],"STDIN");
342 /* only take the last part of the filename */
345 char *p
= strrchr(tok
[2],'/');
354 buf
->job
= atoi(tok
[1]);
355 buf
->status
= strequal(tok
[0],"HELD")?LPQ_PAUSED
:LPQ_QUEUED
;
357 buf
->time
= time(NULL
);
358 fstrcpy(buf
->fs_user
, tok
[3]);
359 fstrcpy(buf
->fs_file
, tok
[2]);
363 DEBUG(6,("parse_lpq_aix count=%d\n", count
));
369 /* the 4th and 9th columns must be integer */
370 if (!isdigit((int)*tok
[3]) || !isdigit((int)*tok
[8])) return(False
);
371 buf
->size
= atoi(tok
[8]) * 1024;
372 /* if the fname contains a space then use STDIN */
373 if (strchr(tok
[4],' '))
374 fstrcpy(tok
[4],"STDIN");
376 /* only take the last part of the filename */
379 char *p
= strrchr(tok
[4],'/');
388 buf
->job
= atoi(tok
[3]);
389 buf
->status
= strequal(tok
[2],"RUNNING")?LPQ_PRINTING
:LPQ_QUEUED
;
391 buf
->time
= time(NULL
);
392 fstrcpy(buf
->fs_user
, tok
[5]);
393 fstrcpy(buf
->fs_file
, tok
[4]);
401 /****************************************************************************
403 here is an example of lpq output under hpux; note there's no space after -o !
405 ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
407 server.c 110712 bytes
408 ljplus-2154 user priority 0 Jan 19 08:14 from client
409 (standard input) 7551 bytes
410 ****************************************************************************/
411 static BOOL
parse_lpq_hpux(char * line
, print_queue_struct
*buf
, BOOL first
)
413 /* must read two lines to process, therefore keep some values static */
414 static BOOL header_line_ok
=False
, base_prio_reset
=False
;
415 static fstring jobuser
;
418 static time_t jobtime
;
419 static int jobstat
=LPQ_QUEUED
;
420 /* to store minimum priority to print, lpstat command should be invoked
421 with -p option first, to work */
422 static int base_prio
;
428 /* If a line begins with a horizontal TAB, it is a subline type */
430 if (line
[0] == htab
) { /* subline */
431 /* check if it contains the base priority */
432 if (!strncmp(line
,"\tfence priority : ",18)) {
433 base_prio
=atoi(&line
[18]);
434 DEBUG(4, ("fence priority set at %d\n", base_prio
));
436 if (!header_line_ok
) return (False
); /* incorrect header line */
437 /* handle the case of "(standard input)" as a filename */
438 pstring_sub(line
,"standard input","STDIN");
439 all_string_sub(line
,"(","\"",0);
440 all_string_sub(line
,")","\"",0);
442 for (count
=0; count
<2 && next_token(&line
,tok
[count
],NULL
,sizeof(tok
[count
])); count
++) ;
443 /* we must get 2 tokens */
444 if (count
< 2) return(False
);
446 /* the 2nd column must be integer */
447 if (!isdigit((int)*tok
[1])) return(False
);
449 /* if the fname contains a space then use STDIN */
450 if (strchr(tok
[0],' '))
451 fstrcpy(tok
[0],"STDIN");
453 buf
->size
= atoi(tok
[1]);
454 fstrcpy(buf
->fs_file
,tok
[0]);
456 /* fill things from header line */
459 buf
->status
= jobstat
;
460 buf
->priority
= jobprio
;
461 fstrcpy(buf
->fs_user
, jobuser
);
465 else { /* header line */
466 header_line_ok
=False
; /* reset it */
468 if (!base_prio_reset
) {
469 base_prio
=0; /* reset it */
470 base_prio_reset
=True
;
473 else if (base_prio
) base_prio_reset
=False
;
475 /* handle the dash in the job id */
476 pstring_sub(line
,"-"," ");
478 for (count
=0; count
<12 && next_token(&line
,tok
[count
],NULL
,sizeof(tok
[count
])); count
++) ;
480 /* we must get 8 tokens */
481 if (count
< 8) return(False
);
483 /* first token must be printer name (cannot check ?) */
484 /* the 2nd, 5th & 7th column must be integer */
485 if (!isdigit((int)*tok
[1]) || !isdigit((int)*tok
[4]) || !isdigit((int)*tok
[6])) return(False
);
486 jobid
= atoi(tok
[1]);
487 fstrcpy(jobuser
, tok
[2]);
488 jobprio
= atoi(tok
[4]);
491 jobtime
=EntryTime(tok
, 5, count
, 8);
492 if (jobprio
< base_prio
) {
493 jobstat
= LPQ_PAUSED
;
494 DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid
, jobprio
, base_prio
, jobstat
));
497 jobstat
= LPQ_QUEUED
;
498 if ((count
>8) && (((strequal(tok
[8],"on")) ||
499 ((strequal(tok
[8],"from")) &&
500 ((count
> 10)&&(strequal(tok
[10],"on")))))))
501 jobstat
= LPQ_PRINTING
;
504 header_line_ok
=True
; /* information is correct */
505 return(False
); /* need subline info to include into queuelist */
510 /****************************************************************************
513 here is an example of "lpstat -o dcslw" output under sysv
515 dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
516 dcslw-897 tridge 4712 Dec 20 10:30:30 being held
518 ****************************************************************************/
519 static BOOL
parse_lpq_sysv(char *line
,print_queue_struct
*buf
,BOOL first
)
526 * Handle the dash in the job id, but make sure that we skip over
527 * the printer name in case we have a dash in that.
528 * Patch from Dom.Mitchell@palmerharvey.co.uk.
532 * Move to the first space.
534 for (p
= line
; !isspace(*p
) && *p
; p
++)
538 * Back up until the last '-' character or
541 for (; (p
>= line
) && (*p
!= '-'); p
--)
544 if((p
>= line
) && (*p
== '-'))
547 for (count
=0; count
<9 && next_token(&line
,tok
[count
],NULL
,sizeof(tok
[count
])); count
++)
550 /* we must get 7 tokens */
554 /* the 2nd and 4th, 6th columns must be integer */
555 if (!isdigit((int)*tok
[1]) || !isdigit((int)*tok
[3]))
557 if (!isdigit((int)*tok
[5]))
560 /* if the user contains a ! then trim the first part of it */
561 if ((p
=strchr(tok
[2],'!'))) {
567 buf
->job
= atoi(tok
[1]);
568 buf
->size
= atoi(tok
[3]);
569 if (count
> 7 && strequal(tok
[7],"on"))
570 buf
->status
= LPQ_PRINTING
;
571 else if (count
> 8 && strequal(tok
[7],"being") && strequal(tok
[8],"held"))
572 buf
->status
= LPQ_PAUSED
;
574 buf
->status
= LPQ_QUEUED
;
576 buf
->time
= EntryTime(tok
, 4, count
, 7);
577 fstrcpy(buf
->fs_user
, tok
[2]);
578 fstrcpy(buf
->fs_file
, tok
[2]);
582 /****************************************************************************
585 here is an example of lpq output under qnx
586 Spooler: /qnx/spooler, on node 1
588 0000: root [job #1 ] active 1146 bytes /etc/profile
589 0001: root [job #2 ] ready 2378 bytes /etc/install
590 0002: root [job #3 ] ready 1146 bytes -- standard input --
591 ****************************************************************************/
592 static BOOL
parse_lpq_qnx(char *line
,print_queue_struct
*buf
,BOOL first
)
597 DEBUG(4,("antes [%s]\n", line
));
599 /* handle the case of "-- standard input --" as a filename */
600 pstring_sub(line
,"standard input","STDIN");
601 DEBUG(4,("despues [%s]\n", line
));
602 all_string_sub(line
,"-- ","\"",0);
603 all_string_sub(line
," --","\"",0);
604 DEBUG(4,("despues 1 [%s]\n", line
));
606 pstring_sub(line
,"[job #","");
607 pstring_sub(line
,"]","");
608 DEBUG(4,("despues 2 [%s]\n", line
));
612 for (count
=0; count
<7 && next_token(&line
,tok
[count
],NULL
,sizeof(tok
[count
])); count
++) ;
614 /* we must get 7 tokens */
618 /* the 3rd and 5th columns must be integer */
619 if (!isdigit((int)*tok
[2]) || !isdigit((int)*tok
[4])) return(False
);
621 /* only take the last part of the filename */
624 char *p
= strrchr(tok
[6],'/');
633 buf
->job
= atoi(tok
[2]);
634 buf
->size
= atoi(tok
[4]);
635 buf
->status
= strequal(tok
[3],"active")?LPQ_PRINTING
:LPQ_QUEUED
;
637 buf
->time
= time(NULL
);
638 fstrcpy(buf
->fs_user
,tok
[1]);
639 fstrcpy(buf
->fs_file
,tok
[6]);
644 /****************************************************************************
645 parse a lpq line for the plp printing system
646 Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
648 redone by tridge. Here is a sample queue:
650 Local Printer 'lp2' (fjall):
651 Printing (started at Jun 15 13:33:58, attempt 1).
652 Rank Owner Pr Opt Job Host Files Size Date
653 active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
654 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33
656 ****************************************************************************/
657 static BOOL
parse_lpq_plp(char *line
,print_queue_struct
*buf
,BOOL first
)
662 /* handle the case of "(standard input)" as a filename */
663 pstring_sub(line
,"stdin","STDIN");
664 all_string_sub(line
,"(","\"",0);
665 all_string_sub(line
,")","\"",0);
667 for (count
=0; count
<11 && next_token(&line
,tok
[count
],NULL
,sizeof(tok
[count
])); count
++) ;
669 /* we must get 11 tokens */
673 /* the first must be "active" or begin with an integer */
674 if (strcmp(tok
[0],"active") && !isdigit((int)tok
[0][0]))
677 /* the 5th and 8th must be integer */
678 if (!isdigit((int)*tok
[4]) || !isdigit((int)*tok
[7]))
681 /* if the fname contains a space then use STDIN */
682 if (strchr(tok
[6],' '))
683 fstrcpy(tok
[6],"STDIN");
685 /* only take the last part of the filename */
688 char *p
= strrchr(tok
[6],'/');
697 buf
->job
= atoi(tok
[4]);
699 buf
->size
= atoi(tok
[7]);
700 if (strchr(tok
[7],'K'))
702 if (strchr(tok
[7],'M'))
703 buf
->size
*= 1024*1024;
705 buf
->status
= strequal(tok
[0],"active")?LPQ_PRINTING
:LPQ_QUEUED
;
707 buf
->time
= time(NULL
);
708 fstrcpy(buf
->fs_user
,tok
[1]);
709 fstrcpy(buf
->fs_file
,tok
[6]);
713 /****************************************************************************
716 here is an example of "qstat -l -d qms" output under softq
718 Queue qms: 2 jobs; daemon active (313); enabled; accepting;
719 job-ID submission-time pri size owner title
720 205980: H 98/03/09 13:04:05 0 15733 stephenf chap1.ps
721 206086:> 98/03/12 17:24:40 0 659 chris -
722 206087: 98/03/12 17:24:45 0 4876 chris -
723 Total: 21268 bytes in queue
726 ****************************************************************************/
727 static BOOL
parse_lpq_softq(char *line
,print_queue_struct
*buf
,BOOL first
)
732 /* mung all the ":"s to spaces*/
733 pstring_sub(line
,":"," ");
735 for (count
=0; count
<10 && next_token(&line
,tok
[count
],NULL
,sizeof(tok
[count
])); count
++) ;
737 /* we must get 9 tokens */
741 /* the 1st and 7th columns must be integer */
742 if (!isdigit((int)*tok
[0]) || !isdigit((int)*tok
[6])) return(False
);
743 /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be
744 * integer, else it's the 6th and 7th that must be
746 if (*tok
[1] == 'H' || *tok
[1] == '>')
748 if (!isdigit((int)*tok
[7]))
750 buf
->status
= *tok
[1] == '>' ? LPQ_PRINTING
: LPQ_PAUSED
;
755 if (!isdigit((int)*tok
[5]))
757 buf
->status
= LPQ_QUEUED
;
762 buf
->job
= atoi(tok
[0]);
763 buf
->size
= atoi(tok
[count
+6]);
764 buf
->priority
= atoi(tok
[count
+5]);
765 fstrcpy(buf
->fs_user
,tok
[count
+7]);
766 fstrcpy(buf
->fs_file
,tok
[count
+8]);
767 buf
->time
= time(NULL
); /* default case: take current time */
772 t
= localtime(&buf
->time
);
773 t
->tm_mday
= atoi(tok
[count
+2]+6);
774 t
->tm_mon
= atoi(tok
[count
+2]+3);
775 switch (*tok
[count
+2])
777 case 7: case 8: case 9: t
->tm_year
= atoi(tok
[count
+2]); break;
778 default: t
->tm_year
= atoi(tok
[count
+2]); break;
781 t
->tm_hour
= atoi(tok
[count
+3]);
782 t
->tm_min
= atoi(tok
[count
+4]);
783 t
->tm_sec
= atoi(tok
[count
+5]);
785 if (jobtime
!= (time_t)-1)
792 /*******************************************************************
793 parse lpq on an NT system
795 Windows 2000 LPD Server
796 Printer \\10.0.0.2\NP17PCL (Paused)
798 Owner Status Jobname Job-Id Size Pages Priority
799 ----------------------------------------------------------------------------
800 root (9.99. Printing /usr/lib/rhs/rhs-pr 3 625 0 1
801 root (9.99. Paused /usr/lib/rhs/rhs-pr 4 625 0 1
802 jmcd Waiting Re: Samba Open Sour 26 32476 1 1
804 ********************************************************************/
805 static BOOL
parse_lpq_nt(char *line
,print_queue_struct
*buf
,BOOL first
)
807 #define LPRNT_OWNSIZ 11
808 #define LPRNT_STATSIZ 9
809 #define LPRNT_JOBSIZ 19
810 #define LPRNT_IDSIZ 6
811 #define LPRNT_SIZSIZ 9
814 char owner
[LPRNT_OWNSIZ
];
816 char status
[LPRNT_STATSIZ
];
818 char jobname
[LPRNT_JOBSIZ
];
820 char jobid
[LPRNT_IDSIZ
];
822 char size
[LPRNT_SIZSIZ
];
826 nt_lpq_line parse_line
;
827 #define LPRNT_PRINTING "Printing"
828 #define LPRNT_WAITING "Waiting"
829 #define LPRNT_PAUSED "Paused"
831 memset(&parse_line
, '\0', sizeof(parse_line
));
832 strncpy((char *) &parse_line
, line
, sizeof(parse_line
) -1);
834 if (strlen((char *) &parse_line
) != sizeof(parse_line
) - 1)
837 /* Just want the first word in the owner field - the username */
838 if (strchr(parse_line
.owner
, ' '))
839 *(strchr(parse_line
.owner
, ' ')) = '\0';
841 parse_line
.space1
= '\0';
843 /* Make sure we have an owner */
844 if (!strlen(parse_line
.owner
))
847 /* Make sure the status is valid */
848 parse_line
.space2
= '\0';
849 trim_string(parse_line
.status
, NULL
, " ");
850 if (!strequal(parse_line
.status
, LPRNT_PRINTING
) &&
851 !strequal(parse_line
.status
, LPRNT_PAUSED
) &&
852 !strequal(parse_line
.status
, LPRNT_WAITING
))
855 parse_line
.space3
= '\0';
856 trim_string(parse_line
.jobname
, NULL
, " ");
858 buf
->job
= atoi(parse_line
.jobid
);
860 buf
->size
= atoi(parse_line
.size
);
861 buf
->time
= time(NULL
);
862 fstrcpy(buf
->fs_user
, parse_line
.owner
);
863 fstrcpy(buf
->fs_file
, parse_line
.jobname
);
864 if (strequal(parse_line
.status
, LPRNT_PRINTING
))
865 buf
->status
= LPQ_PRINTING
;
866 else if (strequal(parse_line
.status
, LPRNT_PAUSED
))
867 buf
->status
= LPQ_PAUSED
;
869 buf
->status
= LPQ_QUEUED
;
874 /*******************************************************************
875 parse lpq on an OS2 system
877 JobID File Name Rank Size Status Comment
878 ----- --------------- ------ -------- ------------ ------------
879 3 Control 1 68 Queued root@psflinu
880 4 /etc/motd 2 11666 Queued root@psflinu
882 ********************************************************************/
883 static BOOL
parse_lpq_os2(char *line
,print_queue_struct
*buf
,BOOL first
)
885 #define LPROS2_IDSIZ 5
886 #define LPROS2_JOBSIZ 15
887 #define LPROS2_SIZSIZ 8
888 #define LPROS2_STATSIZ 12
889 #define LPROS2_OWNSIZ 12
892 char jobid
[LPROS2_IDSIZ
];
894 char jobname
[LPROS2_JOBSIZ
];
896 char size
[LPROS2_SIZSIZ
];
898 char status
[LPROS2_STATSIZ
];
900 char owner
[LPROS2_OWNSIZ
];
904 os2_lpq_line parse_line
;
905 #define LPROS2_PRINTING "Printing"
906 #define LPROS2_WAITING "Queued"
907 #define LPROS2_PAUSED "Paused"
909 memset(&parse_line
, '\0', sizeof(parse_line
));
910 strncpy((char *) &parse_line
, line
, sizeof(parse_line
) -1);
912 if (strlen((char *) &parse_line
) != sizeof(parse_line
) - 1)
916 buf
->job
= atoi(parse_line
.jobid
);
918 /* Get the job name */
919 parse_line
.space2
[0] = '\0';
920 trim_string(parse_line
.jobname
, NULL
, " ");
921 fstrcpy(buf
->fs_file
, parse_line
.jobname
);
924 buf
->size
= atoi(parse_line
.size
);
925 buf
->time
= time(NULL
);
927 /* Make sure we have an owner */
928 if (!strlen(parse_line
.owner
))
931 /* Make sure we have a valid status */
932 parse_line
.space4
[0] = '\0';
933 trim_string(parse_line
.status
, NULL
, " ");
934 if (!strequal(parse_line
.status
, LPROS2_PRINTING
) &&
935 !strequal(parse_line
.status
, LPROS2_PAUSED
) &&
936 !strequal(parse_line
.status
, LPROS2_WAITING
))
939 fstrcpy(buf
->fs_user
, parse_line
.owner
);
940 if (strequal(parse_line
.status
, LPROS2_PRINTING
))
941 buf
->status
= LPQ_PRINTING
;
942 else if (strequal(parse_line
.status
, LPROS2_PAUSED
))
943 buf
->status
= LPQ_PAUSED
;
945 buf
->status
= LPQ_QUEUED
;
950 static char *stat0_strings
[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL
};
951 static char *stat1_strings
[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL
};
952 static char *stat2_strings
[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL
};
956 /****************************************************************************
958 ****************************************************************************/
959 static BOOL
parse_lpq_vlp(char *line
,print_queue_struct
*buf
,BOOL first
)
964 /* First line is printer status */
966 if (!isdigit(line
[0])) return False
;
968 /* Parse a print job entry */
970 while(next_token(&line
, tok
, NULL
, sizeof(fstring
))) {
973 buf
->job
= atoi(tok
);
976 buf
->size
= atoi(tok
);
979 buf
->status
= atoi(tok
);
982 buf
->time
= atoi(tok
);
985 fstrcpy(buf
->fs_user
, tok
);
988 fstrcpy(buf
->fs_file
, tok
);
997 #endif /* DEVELOPER */
999 /****************************************************************************
1000 parse a lpq line. Choose printing style
1001 ****************************************************************************/
1002 BOOL
parse_lpq_entry(int snum
,char *line
,
1003 print_queue_struct
*buf
,
1004 print_status_struct
*status
,BOOL first
)
1008 switch (lp_printing(snum
))
1011 ret
= parse_lpq_sysv(line
,buf
,first
);
1014 ret
= parse_lpq_aix(line
,buf
,first
);
1017 ret
= parse_lpq_hpux(line
,buf
,first
);
1020 ret
= parse_lpq_qnx(line
,buf
,first
);
1023 ret
= parse_lpq_lprng(line
,buf
,first
);
1026 ret
= parse_lpq_plp(line
,buf
,first
);
1029 ret
= parse_lpq_softq(line
,buf
,first
);
1032 ret
= parse_lpq_nt(line
,buf
,first
);
1035 ret
= parse_lpq_os2(line
,buf
,first
);
1040 ret
= parse_lpq_vlp(line
,buf
,first
);
1042 #endif /* DEVELOPER */
1044 ret
= parse_lpq_bsd(line
,buf
,first
);
1048 /* We don't want the newline in the status message. */
1050 char *p
= strchr(line
,'\n');
1054 /* in the LPRNG case, we skip lines starting by a space.*/
1055 if (line
&& !ret
&& (lp_printing(snum
)==PRINT_LPRNG
) )
1064 /* a few simple checks to see if the line might be a
1065 printer status line:
1066 handle them so that most severe condition is shown */
1070 switch (status
->status
) {
1072 for (i
=0; stat0_strings
[i
]; i
++)
1073 if (strstr(line
,stat0_strings
[i
])) {
1074 StrnCpy(status
->message
,line
,sizeof(status
->message
)-1);
1075 status
->status
=LPSTAT_OK
;
1078 case LPSTAT_STOPPED
:
1079 for (i
=0; stat1_strings
[i
]; i
++)
1080 if (strstr(line
,stat1_strings
[i
])) {
1081 StrnCpy(status
->message
,line
,sizeof(status
->message
)-1);
1082 status
->status
=LPSTAT_STOPPED
;
1086 for (i
=0; stat2_strings
[i
]; i
++)
1087 if (strstr(line
,stat2_strings
[i
])) {
1088 StrnCpy(status
->message
,line
,sizeof(status
->message
)-1);
1089 status
->status
=LPSTAT_ERROR
;