2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1997
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 extern int DEBUGLEVEL
;
24 extern connection_struct Connections
[];
25 extern files_struct Files
[];
27 static BOOL
* lpq_cache_reset
=NULL
;
29 static int check_lpq_cache(int snum
) {
30 static int lpq_caches
=0;
32 if (lpq_caches
<= snum
) {
34 p
= (BOOL
*) Realloc(lpq_cache_reset
,(snum
+1)*sizeof(BOOL
));
43 void lpq_reset(int snum
)
45 if (check_lpq_cache(snum
) > snum
) lpq_cache_reset
[snum
]=True
;
49 /****************************************************************************
50 Build the print command in the supplied buffer. This means getting the
51 print command for the service and inserting the printer name and the
52 print file name. Return NULL on error, else the passed buffer pointer.
53 ****************************************************************************/
54 static char *build_print_command(int cnum
, char *command
, char *syscmd
, char *filename1
)
56 int snum
= SNUM(cnum
);
60 /* get the print command for the service. */
62 if (!syscmd
|| !tstr
) {
63 DEBUG(0,("No print command for service `%s'\n", SERVICE(snum
)));
67 /* copy the command into the buffer for extensive meddling. */
68 StrnCpy(syscmd
, tstr
, sizeof(pstring
) - 1);
70 /* look for "%s" in the string. If there is no %s, we cannot print. */
71 if (!strstr(syscmd
, "%s") && !strstr(syscmd
, "%f")) {
72 DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum
)));
75 if (strstr(syscmd
,"%s")) {
76 int iOffset
= PTR_DIFF(strstr(syscmd
, "%s"),syscmd
);
78 /* construct the full path for the filename, shouldn't be necessary unless
79 the subshell causes a "cd" to be executed.
80 Only use the full path if there isn't a / preceding the %s */
81 if (iOffset
==0 || syscmd
[iOffset
-1] != '/') {
82 StrnCpy(filename
,Connections
[cnum
].connectpath
,sizeof(filename
)-1);
83 trim_string(filename
,"","/");
85 strcat(filename
,filename1
);
88 strcpy(filename
,filename1
);
90 string_sub(syscmd
, "%s", filename
);
93 string_sub(syscmd
, "%f", filename1
);
95 /* Does the service have a printername? If not, make a fake and empty */
96 /* printer name. That way a %p is treated sanely if no printer */
97 /* name was specified to replace it. This eventuality is logged. */
98 tstr
= PRINTERNAME(snum
);
99 if (tstr
== NULL
|| tstr
[0] == '\0') {
100 DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum
)));
101 tstr
= SERVICE(snum
);
104 string_sub(syscmd
, "%p", tstr
);
106 standard_sub(cnum
,syscmd
);
112 /****************************************************************************
113 print a file - called on closing the file
114 ****************************************************************************/
115 void print_file(int fnum
)
118 int cnum
= Files
[fnum
].cnum
;
124 if (file_size(Files
[fnum
].name
) <= 0) {
125 DEBUG(3,("Discarding null print job %s\n",Files
[fnum
].name
));
126 sys_unlink(Files
[fnum
].name
);
130 tempstr
= build_print_command(cnum
, PRINTCOMMAND(snum
), syscmd
, Files
[fnum
].name
);
133 int ret
= smbrun(syscmd
,NULL
,False
);
134 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
137 DEBUG(0,("Null print command?\n"));
142 static char *Months
[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
143 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
146 /*******************************************************************
148 ********************************************************************/
149 static time_t EntryTime(string tok
[], int ptr
, int count
, int minimum
)
151 time_t jobtime
,jobtime1
;
153 jobtime
= time(NULL
); /* default case: take current time */
154 if (count
>= minimum
) {
156 int i
, day
, hour
, min
, sec
;
159 for (i
=0; i
<13; i
++) if (!strncmp(tok
[ptr
], Months
[i
],3)) break; /* Find month */
161 t
= localtime(&jobtime
);
162 day
= atoi(tok
[ptr
+1]);
163 c
=(char *)(tok
[ptr
+2]);
168 if(*(c
+6) != 0)sec
= atoi(c
+6);
171 if ((t
->tm_mon
< i
)||
173 ((t
->tm_mday
< day
)||
174 ((t
->tm_mday
== day
)&&
175 (t
->tm_hour
*60+t
->tm_min
< hour
*60+min
)))))
176 t
->tm_year
--; /* last year's print job */
183 jobtime1
= mktime(t
);
184 if (jobtime1
!= (time_t)-1)
192 /****************************************************************************
195 here is an example of lpq output under bsd
197 Warning: no daemon present
198 Rank Owner Job Files Total Size
199 1st tridge 148 README 8096 bytes
201 here is an example of lpq output under osf/1
203 Warning: no daemon present
204 Rank Pri Owner Job Files Total Size
205 1st 0 tridge 148 README 8096 bytes
206 ****************************************************************************/
207 static BOOL
parse_lpq_bsd(char *line
,print_queue_struct
*buf
,BOOL first
)
231 length
= strlen(line
);
232 if (line
[length
-3] == ':')
236 /* handle the case of "(standard input)" as a filename */
237 string_sub(line
,"standard input","STDIN");
238 string_sub(line
,"(","\"");
239 string_sub(line
,")","\"");
241 for (count
=0; count
<NTOK
&& next_token(&line
,tok
[count
],NULL
); count
++) ;
243 /* we must get NTOK tokens */
247 /* the Job and Total columns must be integer */
248 if (!isdigit(*tok
[JOBTOK
]) || !isdigit(*tok
[TOTALTOK
])) return(False
);
250 /* if the fname contains a space then use STDIN */
251 if (strchr(tok
[FILETOK
],' '))
252 strcpy(tok
[FILETOK
],"STDIN");
254 /* only take the last part of the filename */
257 char *p
= strrchr(tok
[FILETOK
],'/');
261 strcpy(tok
[FILETOK
],tmp
);
266 buf
->job
= atoi(tok
[JOBTOK
]);
267 buf
->size
= atoi(tok
[TOTALTOK
]);
268 buf
->status
= strequal(tok
[RANKTOK
],"active")?LPQ_PRINTING
:LPQ_QUEUED
;
269 buf
->time
= time(NULL
);
270 StrnCpy(buf
->user
,tok
[USERTOK
],sizeof(buf
->user
)-1);
271 StrnCpy(buf
->file
,tok
[FILETOK
],sizeof(buf
->file
)-1);
273 buf
->priority
= atoi(tok
[PRIOTOK
]);
282 LPRng_time modifies the current date by inserting the hour and minute from
283 the lpq output. The lpq time looks like "23:15:07"
285 static time_t LPRng_time(string tok
[],int pos
)
291 jobtime
= time(NULL
); /* default case: take current time */
292 t
= localtime(&jobtime
);
293 t
->tm_hour
= atoi(tok
[pos
]);
294 StrnCpy(tmp_time
,tok
[pos
],sizeof(tmp_time
));
295 t
->tm_min
= atoi(tmp_time
+3);
296 t
->tm_sec
= atoi(tmp_time
+6);
303 /****************************************************************************
306 Most of the code is directly reused from parse_lpq_bsd()
308 here are two examples of lpq output under lprng (LPRng-2.3.0)
310 Printer: humprn@hum-fak
311 Queue: 1 printable job
312 Server: pid 4840 active, Unspooler: pid 4841 active
313 Status: job 'cfA659hum-fak', closing device at Fri Jun 21 10:10:21 1996
314 Rank Owner Class Job Files Size Time
315 active magnus@hum-fak A 659 /var/spool/smb/Notesblok-ikke-na4024 10:03:31
317 Printer: humprn@hum-fak (printing disabled)
318 Queue: 1 printable job
319 Warning: no server present
320 Status: finished operations at Fri Jun 21 10:10:32 1996
321 Rank Owner Class Job Files Size Time
322 1 magnus@hum-fak A 387 /var/spool/smb/netbudget.xls 21230 10:50:53
324 ****************************************************************************/
325 static BOOL
parse_lpq_lprng(char *line
,print_queue_struct
*buf
,BOOL first
)
327 #define LPRNG_RANKTOK 0
328 #define LPRNG_USERTOK 1
329 #define LPRNG_PRIOTOK 2
330 #define LPRNG_JOBTOK 3
331 #define LPRNG_FILETOK 4
332 #define LPRNG_TOTALTOK 5
333 #define LPRNG_TIMETOK 6
336 /****************************************************************************
337 From lpd_status.c in LPRng source.
339 12345678901234567890123456789012345678901234567890123456789012345678901234
340 " Rank Owner Class Job Files Size Time"
341 plp_snprintf( msg, sizeof(msg), "%-6s %-19s %c %03d %-32s",
342 number, line, priority, cfp->number, error );
343 plp_snprintf( msg + len, sizeof(msg)-len, "%4d",
345 plp_snprintf( msg+len, sizeof(msg)-len, " %s",
346 Time_str( 1, cfp->statb.st_ctime ) );
347 ****************************************************************************/
348 /* The following define's are to be able to adjust the values if the
349 LPRng source changes. This is from version 2.3.0. Magnus */
356 /* The JOBSIZE_W is too small for big jobs, so time is pushed to the right */
360 #define OWNER_POS RANK_POS+RANK_W+SPACE_W
361 #define CLASS_POS OWNER_POS+OWNER_W+SPACE_W
362 #define JOB_POS CLASS_POS+CLASS_W+SPACE_W
363 #define FILE_POS JOB_POS+JOB_W+SPACE_W
364 #define JOBSIZE_POS FILE_POS+FILE_W
367 string tok
[LPRNG_NTOK
];
371 Need to insert one space in front of the size, to be able to use
372 next_token() unchanged. I would have liked to be able to insert a
373 space instead, to prevent losing that one char, but perl has spoiled
374 me :-\ So I did it the easiest way.
376 HINT: Use as short a path as possible for the samba spool directory.
377 A long spool-path will just waste significant chars of the file name.
380 line
[JOBSIZE_POS
-1]=' ';
382 /* handle the case of "(stdin)" as a filename */
383 string_sub(line
,"stdin","STDIN");
384 string_sub(line
,"(","\"");
385 string_sub(line
,")","\"");
387 for (count
=0; count
<LPRNG_NTOK
&& next_token(&line
,tok
[count
],NULL
); count
++) ;
389 /* we must get LPRNG_NTOK tokens */
390 if (count
< LPRNG_NTOK
)
393 /* the Job and Total columns must be integer */
394 if (!isdigit(*tok
[LPRNG_JOBTOK
]) || !isdigit(*tok
[LPRNG_TOTALTOK
])) return(False
);
396 /* if the fname contains a space then use STDIN */
397 /* I do not understand how this would be possible. Magnus. */
398 if (strchr(tok
[LPRNG_FILETOK
],' '))
399 strcpy(tok
[LPRNG_FILETOK
],"STDIN");
401 /* only take the last part of the filename */
404 char *p
= strrchr(tok
[LPRNG_FILETOK
],'/');
408 strcpy(tok
[LPRNG_FILETOK
],tmp
);
413 buf
->job
= atoi(tok
[LPRNG_JOBTOK
]);
414 buf
->size
= atoi(tok
[LPRNG_TOTALTOK
]);
415 buf
->status
= strequal(tok
[LPRNG_RANKTOK
],"active")?LPQ_PRINTING
:LPQ_QUEUED
;
416 /* buf->time = time(NULL); */
417 buf
->time
= LPRng_time(tok
,LPRNG_TIMETOK
);
418 DEBUG(3,("Time reported for job %d is %s", buf
->job
, ctime(&buf
->time
)));
419 StrnCpy(buf
->user
,tok
[LPRNG_USERTOK
],sizeof(buf
->user
)-1);
420 StrnCpy(buf
->file
,tok
[LPRNG_FILETOK
],sizeof(buf
->file
)-1);
422 /* Here I try to map the CLASS char to a number, but the number
423 is never shown in Print Manager under NT anyway... Magnus. */
424 buf
->priority
= atoi(tok
[LPRNG_PRIOTOK
]-('A'-1));
433 /*******************************************************************
434 parse lpq on an aix system
436 Queue Dev Status Job Files User PP % Blks Cp Rnk
437 ------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
439 lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1
440 QUEUED 538 C.ps root@IEDVB 124 1 2
441 QUEUED 539 E.ps root@IEDVB 28 1 3
442 QUEUED 540 L.ps root@IEDVB 172 1 4
443 QUEUED 541 P.ps root@IEDVB 22 1 5
444 ********************************************************************/
445 static BOOL
parse_lpq_aix(char *line
,print_queue_struct
*buf
,BOOL first
)
450 /* handle the case of "(standard input)" as a filename */
451 string_sub(line
,"standard input","STDIN");
452 string_sub(line
,"(","\"");
453 string_sub(line
,")","\"");
455 for (count
=0; count
<10 && next_token(&line
,tok
[count
],NULL
); count
++) ;
457 /* we must get 6 tokens */
460 if ((count
== 7) && (strcmp(tok
[0],"QUEUED") == 0))
462 /* the 2nd and 5th columns must be integer */
463 if (!isdigit(*tok
[1]) || !isdigit(*tok
[4])) return(False
);
464 buf
->size
= atoi(tok
[4]) * 1024;
465 /* if the fname contains a space then use STDIN */
466 if (strchr(tok
[2],' '))
467 strcpy(tok
[2],"STDIN");
469 /* only take the last part of the filename */
472 char *p
= strrchr(tok
[2],'/');
481 buf
->job
= atoi(tok
[1]);
482 buf
->status
= LPQ_QUEUED
;
484 buf
->time
= time(NULL
);
485 StrnCpy(buf
->user
,tok
[3],sizeof(buf
->user
)-1);
486 StrnCpy(buf
->file
,tok
[2],sizeof(buf
->file
)-1);
490 DEBUG(6,("parse_lpq_aix count=%d\n", count
));
496 /* the 4th and 9th columns must be integer */
497 if (!isdigit(*tok
[3]) || !isdigit(*tok
[8])) return(False
);
498 buf
->size
= atoi(tok
[8]) * 1024;
499 /* if the fname contains a space then use STDIN */
500 if (strchr(tok
[4],' '))
501 strcpy(tok
[4],"STDIN");
503 /* only take the last part of the filename */
506 char *p
= strrchr(tok
[4],'/');
515 buf
->job
= atoi(tok
[3]);
516 buf
->status
= strequal(tok
[2],"RUNNING")?LPQ_PRINTING
:LPQ_QUEUED
;
518 buf
->time
= time(NULL
);
519 StrnCpy(buf
->user
,tok
[5],sizeof(buf
->user
)-1);
520 StrnCpy(buf
->file
,tok
[4],sizeof(buf
->file
)-1);
528 /****************************************************************************
530 here is an example of lpq output under hpux; note there's no space after -o !
532 ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
534 server.c 110712 bytes
535 ljplus-2154 user priority 0 Jan 19 08:14 from client
536 (standard input) 7551 bytes
537 ****************************************************************************/
538 static BOOL
parse_lpq_hpux(char * line
, print_queue_struct
*buf
, BOOL first
)
540 /* must read two lines to process, therefore keep some values static */
541 static BOOL header_line_ok
=False
, base_prio_reset
=False
;
542 static string jobuser
;
545 static time_t jobtime
;
546 static int jobstat
=LPQ_QUEUED
;
547 /* to store minimum priority to print, lpstat command should be invoked
548 with -p option first, to work */
549 static int base_prio
;
555 /* If a line begins with a horizontal TAB, it is a subline type */
557 if (line
[0] == TAB
) { /* subline */
558 /* check if it contains the base priority */
559 if (!strncmp(line
,"\tfence priority : ",18)) {
560 base_prio
=atoi(&line
[18]);
561 DEBUG(4, ("fence priority set at %d\n", base_prio
));
563 if (!header_line_ok
) return (False
); /* incorrect header line */
564 /* handle the case of "(standard input)" as a filename */
565 string_sub(line
,"standard input","STDIN");
566 string_sub(line
,"(","\"");
567 string_sub(line
,")","\"");
569 for (count
=0; count
<2 && next_token(&line
,tok
[count
],NULL
); count
++) ;
570 /* we must get 2 tokens */
571 if (count
< 2) return(False
);
573 /* the 2nd column must be integer */
574 if (!isdigit(*tok
[1])) return(False
);
576 /* if the fname contains a space then use STDIN */
577 if (strchr(tok
[0],' '))
578 strcpy(tok
[0],"STDIN");
580 buf
->size
= atoi(tok
[1]);
581 StrnCpy(buf
->file
,tok
[0],sizeof(buf
->file
)-1);
583 /* fill things from header line */
586 buf
->status
= jobstat
;
587 buf
->priority
= jobprio
;
588 StrnCpy(buf
->user
,jobuser
,sizeof(buf
->user
)-1);
592 else { /* header line */
593 header_line_ok
=False
; /* reset it */
595 if (!base_prio_reset
) {
596 base_prio
=0; /* reset it */
597 base_prio_reset
=True
;
600 else if (base_prio
) base_prio_reset
=False
;
602 /* handle the dash in the job id */
603 string_sub(line
,"-"," ");
605 for (count
=0; count
<12 && next_token(&line
,tok
[count
],NULL
); count
++) ;
607 /* we must get 8 tokens */
608 if (count
< 8) return(False
);
610 /* first token must be printer name (cannot check ?) */
611 /* the 2nd, 5th & 7th column must be integer */
612 if (!isdigit(*tok
[1]) || !isdigit(*tok
[4]) || !isdigit(*tok
[6])) return(False
);
613 jobid
= atoi(tok
[1]);
614 StrnCpy(jobuser
,tok
[2],sizeof(buf
->user
)-1);
615 jobprio
= atoi(tok
[4]);
618 jobtime
=EntryTime(tok
, 5, count
, 8);
619 if (jobprio
< base_prio
) {
620 jobstat
= LPQ_PAUSED
;
621 DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid
, jobprio
, base_prio
, jobstat
));
624 jobstat
= LPQ_QUEUED
;
625 if ((count
>8) && (((strequal(tok
[8],"on")) ||
626 ((strequal(tok
[8],"from")) &&
627 ((count
> 10)&&(strequal(tok
[10],"on")))))))
628 jobstat
= LPQ_PRINTING
;
631 header_line_ok
=True
; /* information is correct */
632 return(False
); /* need subline info to include into queuelist */
637 /****************************************************************************
640 here is an example of "lpstat -o dcslw" output under sysv
642 dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
643 dcslw-897 tridge 4712 Dec 20 10:30:30 being held
645 ****************************************************************************/
646 static BOOL
parse_lpq_sysv(char *line
,print_queue_struct
*buf
,BOOL first
)
652 /* handle the dash in the job id */
653 string_sub(line
,"-"," ");
655 for (count
=0; count
<9 && next_token(&line
,tok
[count
],NULL
); count
++) ;
657 /* we must get 7 tokens */
661 /* the 2nd and 4th, 6th columns must be integer */
662 if (!isdigit(*tok
[1]) || !isdigit(*tok
[3])) return(False
);
663 if (!isdigit(*tok
[5])) return(False
);
665 /* if the user contains a ! then trim the first part of it */
666 if ((p
=strchr(tok
[2],'!')))
674 buf
->job
= atoi(tok
[1]);
675 buf
->size
= atoi(tok
[3]);
676 if (count
> 7 && strequal(tok
[7],"on"))
677 buf
->status
= LPQ_PRINTING
;
678 else if (count
> 8 && strequal(tok
[7],"being") && strequal(tok
[8],"held"))
679 buf
->status
= LPQ_PAUSED
;
681 buf
->status
= LPQ_QUEUED
;
683 buf
->time
= EntryTime(tok
, 4, count
, 7);
684 StrnCpy(buf
->user
,tok
[2],sizeof(buf
->user
)-1);
685 StrnCpy(buf
->file
,tok
[2],sizeof(buf
->file
)-1);
689 /****************************************************************************
692 here is an example of lpq output under qnx
693 Spooler: /qnx/spooler, on node 1
695 0000: root [job #1 ] active 1146 bytes /etc/profile
696 0001: root [job #2 ] ready 2378 bytes /etc/install
697 0002: root [job #3 ] ready 1146 bytes -- standard input --
698 ****************************************************************************/
699 static BOOL
parse_lpq_qnx(char *line
,print_queue_struct
*buf
,BOOL first
)
704 DEBUG(0,("antes [%s]\n", line
));
706 /* handle the case of "-- standard input --" as a filename */
707 string_sub(line
,"standard input","STDIN");
708 DEBUG(0,("despues [%s]\n", line
));
709 string_sub(line
,"-- ","\"");
710 string_sub(line
," --","\"");
711 DEBUG(0,("despues 1 [%s]\n", line
));
713 string_sub(line
,"[job #","");
714 string_sub(line
,"]","");
715 DEBUG(0,("despues 2 [%s]\n", line
));
719 for (count
=0; count
<7 && next_token(&line
,tok
[count
],NULL
); count
++) ;
721 /* we must get 7 tokens */
725 /* the 3rd and 5th columns must be integer */
726 if (!isdigit(*tok
[2]) || !isdigit(*tok
[4])) return(False
);
728 /* only take the last part of the filename */
731 char *p
= strrchr(tok
[6],'/');
740 buf
->job
= atoi(tok
[2]);
741 buf
->size
= atoi(tok
[4]);
742 buf
->status
= strequal(tok
[3],"active")?LPQ_PRINTING
:LPQ_QUEUED
;
744 buf
->time
= time(NULL
);
745 StrnCpy(buf
->user
,tok
[1],sizeof(buf
->user
)-1);
746 StrnCpy(buf
->file
,tok
[6],sizeof(buf
->file
)-1);
751 /****************************************************************************
752 parse a lpq line for the plp printing system
753 Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
755 redone by tridge. Here is a sample queue:
757 Local Printer 'lp2' (fjall):
758 Printing (started at Jun 15 13:33:58, attempt 1).
759 Rank Owner Pr Opt Job Host Files Size Date
760 active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
761 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33
763 ****************************************************************************/
764 static BOOL
parse_lpq_plp(char *line
,print_queue_struct
*buf
,BOOL first
)
769 /* handle the case of "(standard input)" as a filename */
770 string_sub(line
,"stdin","STDIN");
771 string_sub(line
,"(","\"");
772 string_sub(line
,")","\"");
774 for (count
=0; count
<11 && next_token(&line
,tok
[count
],NULL
); count
++) ;
776 /* we must get 11 tokens */
780 /* the first must be "active" or begin with an integer */
781 if (strcmp(tok
[0],"active") && !isdigit(tok
[0][0]))
784 /* the 5th and 8th must be integer */
785 if (!isdigit(*tok
[4]) || !isdigit(*tok
[7]))
788 /* if the fname contains a space then use STDIN */
789 if (strchr(tok
[6],' '))
790 strcpy(tok
[6],"STDIN");
792 /* only take the last part of the filename */
795 char *p
= strrchr(tok
[6],'/');
804 buf
->job
= atoi(tok
[4]);
806 buf
->size
= atoi(tok
[7]);
807 if (strchr(tok
[7],'K'))
809 if (strchr(tok
[7],'M'))
810 buf
->size
*= 1024*1024;
812 buf
->status
= strequal(tok
[0],"active")?LPQ_PRINTING
:LPQ_QUEUED
;
814 buf
->time
= time(NULL
);
815 StrnCpy(buf
->user
,tok
[1],sizeof(buf
->user
)-1);
816 StrnCpy(buf
->file
,tok
[6],sizeof(buf
->file
)-1);
822 char *stat0_strings
[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL
};
823 char *stat1_strings
[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL
};
824 char *stat2_strings
[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL
};
826 /****************************************************************************
827 parse a lpq line. Choose printing style
828 ****************************************************************************/
829 static BOOL
parse_lpq_entry(int snum
,char *line
,
830 print_queue_struct
*buf
,
831 print_status_struct
*status
,BOOL first
)
835 switch (lp_printing())
838 ret
= parse_lpq_sysv(line
,buf
,first
);
841 ret
= parse_lpq_aix(line
,buf
,first
);
844 ret
= parse_lpq_hpux(line
,buf
,first
);
847 ret
= parse_lpq_qnx(line
,buf
,first
);
850 ret
= parse_lpq_lprng(line
,buf
,first
);
853 ret
= parse_lpq_plp(line
,buf
,first
);
856 ret
= parse_lpq_bsd(line
,buf
,first
);
860 #ifdef LPQ_GUEST_TO_USER
862 extern pstring sesssetup_user
;
863 /* change guest entries to the current logged in user to make
864 them appear deletable to windows */
865 if (sesssetup_user
[0] && strequal(buf
->user
,lp_guestaccount(snum
)))
866 strcpy(buf
->user
,sesssetup_user
);
870 /* We don't want the newline in the status message. */
872 char *p
= strchr(line
,'\n');
878 /* a few simple checks to see if the line might be a
880 handle them so that most severe condition is shown */
884 switch (status
->status
) {
886 for (i
=0; stat0_strings
[i
]; i
++)
887 if (strstr(line
,stat0_strings
[i
])) {
888 StrnCpy(status
->message
,line
,sizeof(status
->message
)-1);
889 status
->status
=LPSTAT_OK
;
892 for (i
=0; stat1_strings
[i
]; i
++)
893 if (strstr(line
,stat1_strings
[i
])) {
894 StrnCpy(status
->message
,line
,sizeof(status
->message
)-1);
895 status
->status
=LPSTAT_STOPPED
;
898 for (i
=0; stat2_strings
[i
]; i
++)
899 if (strstr(line
,stat2_strings
[i
])) {
900 StrnCpy(status
->message
,line
,sizeof(status
->message
)-1);
901 status
->status
=LPSTAT_ERROR
;
910 /****************************************************************************
912 ****************************************************************************/
913 int get_printqueue(int snum
,int cnum
,print_queue_struct
**queue
,
914 print_status_struct
*status
)
916 char *lpq_command
= lp_lpqcommand(snum
);
917 char *printername
= PRINTERNAME(snum
);
925 int cachetime
= lp_lpqcachetime();
928 check_lpq_cache(snum
);
930 if (!printername
|| !*printername
)
932 DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
933 lp_servicename(snum
),snum
));
934 printername
= lp_servicename(snum
);
937 if (!lpq_command
|| !(*lpq_command
))
939 DEBUG(5,("No lpq command\n"));
943 strcpy(syscmd
,lpq_command
);
944 string_sub(syscmd
,"%p",printername
);
946 standard_sub(cnum
,syscmd
);
948 sprintf(outfile
,"%s/lpq.%08x",tmpdir(),str_checksum(syscmd
));
950 if (!lpq_cache_reset
[snum
] && cachetime
&& !stat(outfile
,&sbuf
))
952 if (time(NULL
) - sbuf
.st_mtime
< cachetime
) {
953 DEBUG(3,("Using cached lpq output\n"));
959 ret
= smbrun(syscmd
,outfile
,True
);
960 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
963 lpq_cache_reset
[snum
] = False
;
965 f
= fopen(outfile
,"r");
971 strcpy(status
->message
,"");
972 status
->status
= LPSTAT_OK
;
975 while (fgets(line
,sizeof(pstring
),f
))
977 DEBUG(6,("QUEUE2: %s\n",line
));
979 *queue
= Realloc(*queue
,sizeof(print_queue_struct
)*(count
+1));
986 bzero((char *)&(*queue
)[count
],sizeof(**queue
));
989 if (!parse_lpq_entry(snum
,line
,&(*queue
)[count
],status
,count
==0))
1000 /* we only expect this to succeed on trapdoor systems, on normal systems
1001 the file is owned by root */
1002 chmod(outfile
,0666);
1008 /****************************************************************************
1009 delete a printer queue entry
1010 ****************************************************************************/
1011 void del_printqueue(int cnum
,int snum
,int jobid
)
1013 char *lprm_command
= lp_lprmcommand(snum
);
1014 char *printername
= PRINTERNAME(snum
);
1019 if (!printername
|| !*printername
)
1021 DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
1022 lp_servicename(snum
),snum
));
1023 printername
= lp_servicename(snum
);
1026 if (!lprm_command
|| !(*lprm_command
))
1028 DEBUG(5,("No lprm command\n"));
1032 sprintf(jobstr
,"%d",jobid
);
1034 strcpy(syscmd
,lprm_command
);
1035 string_sub(syscmd
,"%p",printername
);
1036 string_sub(syscmd
,"%j",jobstr
);
1037 standard_sub(cnum
,syscmd
);
1039 ret
= smbrun(syscmd
,NULL
,False
);
1040 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
1041 lpq_reset(snum
); /* queue has changed */
1044 /****************************************************************************
1045 change status of a printer queue entry
1046 ****************************************************************************/
1047 void status_printjob(int cnum
,int snum
,int jobid
,int status
)
1049 char *lpstatus_command
=
1050 (status
==LPQ_PAUSED
?lp_lppausecommand(snum
):lp_lpresumecommand(snum
));
1051 char *printername
= PRINTERNAME(snum
);
1056 if (!printername
|| !*printername
)
1058 DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
1059 lp_servicename(snum
),snum
));
1060 printername
= lp_servicename(snum
);
1063 if (!lpstatus_command
|| !(*lpstatus_command
))
1065 DEBUG(5,("No lpstatus command to %s job\n",
1066 (status
==LPQ_PAUSED
?"pause":"resume")));
1070 sprintf(jobstr
,"%d",jobid
);
1072 strcpy(syscmd
,lpstatus_command
);
1073 string_sub(syscmd
,"%p",printername
);
1074 string_sub(syscmd
,"%j",jobstr
);
1075 standard_sub(cnum
,syscmd
);
1077 ret
= smbrun(syscmd
,NULL
,False
);
1078 DEBUG(3,("Running the command `%s' gave %d\n",syscmd
,ret
));
1079 lpq_reset(snum
); /* queue has changed */