2 Unix SMB/Netbios implementation.
5 Copyright (C) Andrew Tridgell 1992-1998
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;
25 static BOOL * lpq_cache_reset=NULL;
27 static int check_lpq_cache(int snum) {
28 static int lpq_caches=0;
30 if (lpq_caches <= snum) {
32 p = (BOOL *) Realloc(lpq_cache_reset,(snum+1)*sizeof(BOOL));
41 void lpq_reset(int snum)
43 if (check_lpq_cache(snum) > snum) lpq_cache_reset[snum]=True;
47 /****************************************************************************
48 Build the print command in the supplied buffer. This means getting the
49 print command for the service and inserting the printer name and the
50 print file name. Return NULL on error, else the passed buffer pointer.
51 ****************************************************************************/
52 static char *build_print_command(connection_struct *conn,
54 char *syscmd, char *filename1)
56 int snum = SNUM(conn);
60 /* get the print command for the service. */
62 if (!syscmd || !tstr) {
63 DEBUG(0,("No print command for service `%s'\n",
68 /* copy the command into the buffer for extensive meddling. */
69 StrnCpy(syscmd, tstr, sizeof(pstring) - 1);
71 /* look for "%s" in the string. If there is no %s, we cannot print. */
72 if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) {
73 DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum)));
76 if (strstr(syscmd,"%s")) {
77 pstrcpy(filename,filename1);
79 string_sub(syscmd, "%s", filename);
82 string_sub(syscmd, "%f", filename1);
84 /* Does the service have a printername? If not, make a fake
86 /* printer name. That way a %p is treated sanely if no printer */
87 /* name was specified to replace it. This eventuality is logged. */
88 tstr = PRINTERNAME(snum);
89 if (tstr == NULL || tstr[0] == '\0') {
90 DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum)));
94 string_sub(syscmd, "%p", tstr);
96 standard_sub(conn,syscmd);
102 /****************************************************************************
103 print a file - called on closing the file
104 ****************************************************************************/
105 void print_file(connection_struct *conn, files_struct *file)
108 int snum = SNUM(conn);
113 if (file_size(file->fsp_name) <= 0) {
114 DEBUG(3,("Discarding null print job %s\n",file->fsp_name));
115 dos_unlink(file->fsp_name);
119 tempstr = build_print_command(conn,
121 syscmd, file->fsp_name);
122 if (tempstr != NULL) {
123 int ret = smbrun(syscmd,NULL,False);
124 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
126 DEBUG(0,("Null print command?\n"));
132 static char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
133 "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
136 /*******************************************************************
138 ********************************************************************/
139 static time_t EntryTime(fstring tok[], int ptr, int count, int minimum)
141 time_t jobtime,jobtime1;
143 jobtime = time(NULL); /* default case: take current time */
144 if (count >= minimum) {
146 int i, day, hour, min, sec;
149 for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */
151 t = localtime(&jobtime);
152 day = atoi(tok[ptr+1]);
153 c=(char *)(tok[ptr+2]);
158 if(*(c+6) != 0)sec = atoi(c+6);
161 if ((t->tm_mon < i)||
163 ((t->tm_mday < day)||
164 ((t->tm_mday == day)&&
165 (t->tm_hour*60+t->tm_min < hour*60+min)))))
166 t->tm_year--; /* last year's print job */
173 jobtime1 = mktime(t);
174 if (jobtime1 != (time_t)-1)
182 /****************************************************************************
185 here is an example of lpq output under bsd
187 Warning: no daemon present
188 Rank Owner Job Files Total Size
189 1st tridge 148 README 8096 bytes
191 here is an example of lpq output under osf/1
193 Warning: no daemon present
194 Rank Pri Owner Job Files Total Size
195 1st 0 tridge 148 README 8096 bytes
198 <allan@umich.edu> June 30, 1998.
199 Modified to handle file names with spaces, like the parse_lpq_lprng code
201 ****************************************************************************/
202 static BOOL parse_lpq_bsd(char *line,print_queue_struct *buf,BOOL first)
210 #define TOTALTOK (count - 2)
218 #define TOTALTOK (count - 2)
232 length = strlen(line2);
233 if (line2[length-3] == ':')
238 tok[0] = strtok(line2," \t");
241 while (((tok[count] = strtok(NULL," \t")) != NULL) && (count < MAXTOK)) {
245 /* we must get at least NTOK tokens */
249 /* the Job and Total columns must be integer */
250 if (!isdigit(*tok[JOBTOK]) || !isdigit(*tok[TOTALTOK])) return(False);
252 buf->job = atoi(tok[JOBTOK]);
253 buf->size = atoi(tok[TOTALTOK]);
254 buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
255 buf->time = time(NULL);
256 StrnCpy(buf->user,tok[USERTOK],sizeof(buf->user)-1);
257 StrnCpy(buf->file,tok[FILETOK],sizeof(buf->file)-1);
259 if ((FILETOK + 1) != TOTALTOK) {
263 bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
265 for (i = (FILETOK + 1); i < TOTALTOK; i++) {
266 strncat(buf->file," ",bufsize);
267 strncat(buf->file,tok[i],bufsize - 1);
268 bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
276 buf->priority = atoi(tok[PRIOTOK]);
285 LPRng_time modifies the current date by inserting the hour and minute from
286 the lpq output. The lpq time looks like "23:15:07"
288 <allan@umich.edu> June 30, 1998.
289 Modified to work with the re-written parse_lpq_lprng routine.
291 static time_t LPRng_time(char *time_string)
296 jobtime = time(NULL); /* default case: take current time */
297 t = localtime(&jobtime);
298 t->tm_hour = atoi(time_string);
299 t->tm_min = atoi(time_string+3);
300 t->tm_sec = atoi(time_string+6);
307 /****************************************************************************
308 parse a lprng lpq line
309 <allan@umich.edu> June 30, 1998.
310 Re-wrote this to handle file names with spaces, multiple file names on one
312 ****************************************************************************/
313 static BOOL parse_lpq_lprng(char *line,print_queue_struct *buf,BOOL first)
315 #define LPRNG_RANKTOK 0
316 #define LPRNG_USERTOK 1
317 #define LPRNG_PRIOTOK 2
318 #define LPRNG_JOBTOK 3
319 #define LPRNG_FILETOK 4
320 #define LPRNG_TOTALTOK (num_tok - 2)
321 #define LPRNG_TIMETOK (num_tok - 1)
323 #define LPRNG_MAXTOK 128 /* PFMA just to keep us from running away. */
325 char *tokarr[LPRNG_MAXTOK];
331 tokarr[0] = strtok(line2," \t");
333 while (((tokarr[num_tok] = strtok(NULL," \t")) != NULL)
334 && (num_tok < LPRNG_MAXTOK)) {
338 /* We must get at least LPRNG_NTOK tokens. */
339 if (num_tok < LPRNG_NTOK) {
343 if (!isdigit(*tokarr[LPRNG_JOBTOK]) || !isdigit(*tokarr[LPRNG_TOTALTOK])) {
347 buf->job = atoi(tokarr[LPRNG_JOBTOK]);
348 buf->size = atoi(tokarr[LPRNG_TOTALTOK]);
350 if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
351 buf->status = LPQ_PRINTING;
352 } else if (isdigit(*tokarr[LPRNG_RANKTOK])) {
353 buf->status = LPQ_QUEUED;
355 buf->status = LPQ_PAUSED;
358 buf->priority = *tokarr[LPRNG_PRIOTOK] -'A';
360 buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]);
362 StrnCpy(buf->user,tokarr[LPRNG_USERTOK],sizeof(buf->user)-1);
364 /* The '@hostname' prevents windows from displaying the printing icon
365 * for the current user on the taskbar. Plop in a null.
368 if ((cptr = strchr(buf->user,'@')) != NULL) {
372 StrnCpy(buf->file,tokarr[LPRNG_FILETOK],sizeof(buf->file)-1);
374 if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) {
378 bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
380 for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) {
381 strncat(buf->file," ",bufsize);
382 strncat(buf->file,tokarr[i],bufsize - 1);
383 bufsize = sizeof(buf->file) - strlen(buf->file) - 1;
395 /*******************************************************************
396 parse lpq on an aix system
398 Queue Dev Status Job Files User PP % Blks Cp Rnk
399 ------- ----- --------- --- ------------------ ---------- ---- -- ----- --- ---
401 lazer lazer RUNNING 537 6297doc.A kvintus@IE 0 10 2445 1 1
402 QUEUED 538 C.ps root@IEDVB 124 1 2
403 QUEUED 539 E.ps root@IEDVB 28 1 3
404 QUEUED 540 L.ps root@IEDVB 172 1 4
405 QUEUED 541 P.ps root@IEDVB 22 1 5
406 ********************************************************************/
407 static BOOL parse_lpq_aix(char *line,print_queue_struct *buf,BOOL first)
412 /* handle the case of "(standard input)" as a filename */
413 string_sub(line,"standard input","STDIN");
414 all_string_sub(line,"(","\"");
415 all_string_sub(line,")","\"");
419 next_token(&line,tok[count],NULL, sizeof(tok[count]));
422 /* we must get 6 tokens */
425 if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0)))
427 /* the 2nd and 5th columns must be integer */
428 if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) return(False);
429 buf->size = atoi(tok[4]) * 1024;
430 /* if the fname contains a space then use STDIN */
431 if (strchr(tok[2],' '))
432 fstrcpy(tok[2],"STDIN");
434 /* only take the last part of the filename */
437 char *p = strrchr(tok[2],'/');
446 buf->job = atoi(tok[1]);
447 buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED;
449 buf->time = time(NULL);
450 StrnCpy(buf->user,tok[3],sizeof(buf->user)-1);
451 StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
455 DEBUG(6,("parse_lpq_aix count=%d\n", count));
461 /* the 4th and 9th columns must be integer */
462 if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) return(False);
463 buf->size = atoi(tok[8]) * 1024;
464 /* if the fname contains a space then use STDIN */
465 if (strchr(tok[4],' '))
466 fstrcpy(tok[4],"STDIN");
468 /* only take the last part of the filename */
471 char *p = strrchr(tok[4],'/');
480 buf->job = atoi(tok[3]);
481 buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
483 buf->time = time(NULL);
484 StrnCpy(buf->user,tok[5],sizeof(buf->user)-1);
485 StrnCpy(buf->file,tok[4],sizeof(buf->file)-1);
493 /****************************************************************************
495 here is an example of lpq output under hpux; note there's no space after -o !
497 ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
499 server.c 110712 bytes
500 ljplus-2154 user priority 0 Jan 19 08:14 from client
501 (standard input) 7551 bytes
502 ****************************************************************************/
503 static BOOL parse_lpq_hpux(char * line, print_queue_struct *buf, BOOL first)
505 /* must read two lines to process, therefore keep some values static */
506 static BOOL header_line_ok=False, base_prio_reset=False;
507 static fstring jobuser;
510 static time_t jobtime;
511 static int jobstat=LPQ_QUEUED;
512 /* to store minimum priority to print, lpstat command should be invoked
513 with -p option first, to work */
514 static int base_prio;
520 /* If a line begins with a horizontal TAB, it is a subline type */
522 if (line[0] == htab) { /* subline */
523 /* check if it contains the base priority */
524 if (!strncmp(line,"\tfence priority : ",18)) {
525 base_prio=atoi(&line[18]);
526 DEBUG(4, ("fence priority set at %d\n", base_prio));
528 if (!header_line_ok) return (False); /* incorrect header line */
529 /* handle the case of "(standard input)" as a filename */
530 string_sub(line,"standard input","STDIN");
531 all_string_sub(line,"(","\"");
532 all_string_sub(line,")","\"");
534 for (count=0; count<2 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
535 /* we must get 2 tokens */
536 if (count < 2) return(False);
538 /* the 2nd column must be integer */
539 if (!isdigit((int)*tok[1])) return(False);
541 /* if the fname contains a space then use STDIN */
542 if (strchr(tok[0],' '))
543 fstrcpy(tok[0],"STDIN");
545 buf->size = atoi(tok[1]);
546 StrnCpy(buf->file,tok[0],sizeof(buf->file)-1);
548 /* fill things from header line */
551 buf->status = jobstat;
552 buf->priority = jobprio;
553 StrnCpy(buf->user,jobuser,sizeof(buf->user)-1);
557 else { /* header line */
558 header_line_ok=False; /* reset it */
560 if (!base_prio_reset) {
561 base_prio=0; /* reset it */
562 base_prio_reset=True;
565 else if (base_prio) base_prio_reset=False;
567 /* handle the dash in the job id */
568 string_sub(line,"-"," ");
570 for (count=0; count<12 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
572 /* we must get 8 tokens */
573 if (count < 8) return(False);
575 /* first token must be printer name (cannot check ?) */
576 /* the 2nd, 5th & 7th column must be integer */
577 if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False);
578 jobid = atoi(tok[1]);
579 StrnCpy(jobuser,tok[2],sizeof(buf->user)-1);
580 jobprio = atoi(tok[4]);
583 jobtime=EntryTime(tok, 5, count, 8);
584 if (jobprio < base_prio) {
585 jobstat = LPQ_PAUSED;
586 DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat));
589 jobstat = LPQ_QUEUED;
590 if ((count >8) && (((strequal(tok[8],"on")) ||
591 ((strequal(tok[8],"from")) &&
592 ((count > 10)&&(strequal(tok[10],"on")))))))
593 jobstat = LPQ_PRINTING;
596 header_line_ok=True; /* information is correct */
597 return(False); /* need subline info to include into queuelist */
602 /****************************************************************************
605 here is an example of "lpstat -o dcslw" output under sysv
607 dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
608 dcslw-897 tridge 4712 Dec 20 10:30:30 being held
610 ****************************************************************************/
611 static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
617 /* handle the dash in the job id */
618 string_sub(line,"-"," ");
620 for (count=0; count<9 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
622 /* we must get 7 tokens */
626 /* the 2nd and 4th, 6th columns must be integer */
627 if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3])) return(False);
628 if (!isdigit((int)*tok[5])) return(False);
630 /* if the user contains a ! then trim the first part of it */
631 if ((p=strchr(tok[2],'!')))
639 buf->job = atoi(tok[1]);
640 buf->size = atoi(tok[3]);
641 if (count > 7 && strequal(tok[7],"on"))
642 buf->status = LPQ_PRINTING;
643 else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held"))
644 buf->status = LPQ_PAUSED;
646 buf->status = LPQ_QUEUED;
648 buf->time = EntryTime(tok, 4, count, 7);
649 StrnCpy(buf->user,tok[2],sizeof(buf->user)-1);
650 StrnCpy(buf->file,tok[2],sizeof(buf->file)-1);
654 /****************************************************************************
657 here is an example of lpq output under qnx
658 Spooler: /qnx/spooler, on node 1
660 0000: root [job #1 ] active 1146 bytes /etc/profile
661 0001: root [job #2 ] ready 2378 bytes /etc/install
662 0002: root [job #3 ] ready 1146 bytes -- standard input --
663 ****************************************************************************/
664 static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
669 DEBUG(4,("antes [%s]\n", line));
671 /* handle the case of "-- standard input --" as a filename */
672 string_sub(line,"standard input","STDIN");
673 DEBUG(4,("despues [%s]\n", line));
674 all_string_sub(line,"-- ","\"");
675 all_string_sub(line," --","\"");
676 DEBUG(4,("despues 1 [%s]\n", line));
678 string_sub(line,"[job #","");
679 string_sub(line,"]","");
680 DEBUG(4,("despues 2 [%s]\n", line));
684 for (count=0; count<7 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
686 /* we must get 7 tokens */
690 /* the 3rd and 5th columns must be integer */
691 if (!isdigit((int)*tok[2]) || !isdigit((int)*tok[4])) return(False);
693 /* only take the last part of the filename */
696 char *p = strrchr(tok[6],'/');
705 buf->job = atoi(tok[2]);
706 buf->size = atoi(tok[4]);
707 buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
709 buf->time = time(NULL);
710 StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
711 StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
716 /****************************************************************************
717 parse a lpq line for the plp printing system
718 Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
720 redone by tridge. Here is a sample queue:
722 Local Printer 'lp2' (fjall):
723 Printing (started at Jun 15 13:33:58, attempt 1).
724 Rank Owner Pr Opt Job Host Files Size Date
725 active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
726 3rd tridge X - 7 fjall /etc/hosts 739 Jun 15 13:33
728 ****************************************************************************/
729 static BOOL parse_lpq_plp(char *line,print_queue_struct *buf,BOOL first)
734 /* handle the case of "(standard input)" as a filename */
735 string_sub(line,"stdin","STDIN");
736 all_string_sub(line,"(","\"");
737 all_string_sub(line,")","\"");
739 for (count=0; count<11 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
741 /* we must get 11 tokens */
745 /* the first must be "active" or begin with an integer */
746 if (strcmp(tok[0],"active") && !isdigit((int)tok[0][0]))
749 /* the 5th and 8th must be integer */
750 if (!isdigit((int)*tok[4]) || !isdigit((int)*tok[7]))
753 /* if the fname contains a space then use STDIN */
754 if (strchr(tok[6],' '))
755 fstrcpy(tok[6],"STDIN");
757 /* only take the last part of the filename */
760 char *p = strrchr(tok[6],'/');
769 buf->job = atoi(tok[4]);
771 buf->size = atoi(tok[7]);
772 if (strchr(tok[7],'K'))
774 if (strchr(tok[7],'M'))
775 buf->size *= 1024*1024;
777 buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
779 buf->time = time(NULL);
780 StrnCpy(buf->user,tok[1],sizeof(buf->user)-1);
781 StrnCpy(buf->file,tok[6],sizeof(buf->file)-1);
785 /****************************************************************************
788 here is an example of "qstat -l -d qms" output under softq
790 Queue qms: 2 jobs; daemon active (313); enabled; accepting;
791 job-ID submission-time pri size owner title
792 205980: H 98/03/09 13:04:05 0 15733 stephenf chap1.ps
793 206086:> 98/03/12 17:24:40 0 659 chris -
794 206087: 98/03/12 17:24:45 0 4876 chris -
795 Total: 21268 bytes in queue
798 ****************************************************************************/
799 static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
804 /* mung all the ":"s to spaces*/
805 string_sub(line,":"," ");
807 for (count=0; count<10 && next_token(&line,tok[count],NULL,sizeof(tok[count])); count++) ;
809 /* we must get 9 tokens */
813 /* the 1st and 7th columns must be integer */
814 if (!isdigit((int)*tok[0]) || !isdigit((int)*tok[6])) return(False);
815 /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be
816 * integer, else it's the 6th and 7th that must be
818 if (*tok[1] == 'H' || *tok[1] == '>')
820 if (!isdigit((int)*tok[7]))
822 buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED;
827 if (!isdigit((int)*tok[5]))
829 buf->status = LPQ_QUEUED;
834 buf->job = atoi(tok[0]);
835 buf->size = atoi(tok[count+6]);
836 buf->priority = atoi(tok[count+5]);
837 StrnCpy(buf->user,tok[count+7],sizeof(buf->user)-1);
838 StrnCpy(buf->file,tok[count+8],sizeof(buf->file)-1);
839 buf->time = time(NULL); /* default case: take current time */
844 t = localtime(&buf->time);
845 t->tm_mday = atoi(tok[count+2]+6);
846 t->tm_mon = atoi(tok[count+2]+3);
847 switch (*tok[count+2])
849 case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]) + 1900; break;
850 default: t->tm_year = atoi(tok[count+2]) + 2000; break;
853 t->tm_hour = atoi(tok[count+3]);
854 t->tm_min = atoi(tok[count+4]);
855 t->tm_sec = atoi(tok[count+5]);
857 if (jobtime != (time_t)-1)
865 char *stat0_strings[] = { "enabled", "online", "idle", "no entries", "free", "ready", NULL };
866 char *stat1_strings[] = { "offline", "disabled", "down", "off", "waiting", "no daemon", NULL };
867 char *stat2_strings[] = { "jam", "paper", "error", "responding", "not accepting", "not running", "turned off", NULL };
869 /****************************************************************************
870 parse a lpq line. Choose printing style
871 ****************************************************************************/
872 static BOOL parse_lpq_entry(int snum,char *line,
873 print_queue_struct *buf,
874 print_status_struct *status,BOOL first)
878 switch (lp_printing(snum))
881 ret = parse_lpq_sysv(line,buf,first);
884 ret = parse_lpq_aix(line,buf,first);
887 ret = parse_lpq_hpux(line,buf,first);
890 ret = parse_lpq_qnx(line,buf,first);
893 ret = parse_lpq_lprng(line,buf,first);
896 ret = parse_lpq_plp(line,buf,first);
899 ret = parse_lpq_softq(line,buf,first);
902 ret = parse_lpq_bsd(line,buf,first);
906 #ifdef LPQ_GUEST_TO_USER
908 extern pstring sesssetup_user;
909 /* change guest entries to the current logged in user to make
910 them appear deletable to windows */
911 if (sesssetup_user[0] && strequal(buf->user,lp_guestaccount(snum)))
912 pstrcpy(buf->user,sesssetup_user);
916 /* We don't want the newline in the status message. */
918 char *p = strchr(line,'\n');
924 /* a few simple checks to see if the line might be a
926 handle them so that most severe condition is shown */
930 switch (status->status) {
932 for (i=0; stat0_strings[i]; i++)
933 if (strstr(line,stat0_strings[i])) {
934 StrnCpy(status->message,line,sizeof(status->message)-1);
935 status->status=LPSTAT_OK;
939 for (i=0; stat1_strings[i]; i++)
940 if (strstr(line,stat1_strings[i])) {
941 StrnCpy(status->message,line,sizeof(status->message)-1);
942 status->status=LPSTAT_STOPPED;
946 for (i=0; stat2_strings[i]; i++)
947 if (strstr(line,stat2_strings[i])) {
948 StrnCpy(status->message,line,sizeof(status->message)-1);
949 status->status=LPSTAT_ERROR;
959 /****************************************************************************
961 ****************************************************************************/
962 int get_printqueue(int snum,
963 connection_struct *conn,print_queue_struct **queue,
964 print_status_struct *status)
966 char *lpq_command = lp_lpqcommand(snum);
967 char *printername = PRINTERNAME(snum);
973 SMB_STRUCT_STAT sbuf;
975 int cachetime = lp_lpqcachetime();
978 check_lpq_cache(snum);
980 if (!printername || !*printername) {
981 DEBUG(6,("xx replacing printer name with service (snum=(%s,%d))\n",
982 lp_servicename(snum),snum));
983 printername = lp_servicename(snum);
986 if (!lpq_command || !(*lpq_command)) {
987 DEBUG(5,("No lpq command\n"));
991 pstrcpy(syscmd,lpq_command);
992 string_sub(syscmd,"%p",printername);
994 standard_sub(conn,syscmd);
996 slprintf(outfile,sizeof(outfile)-1, "%s/lpq.%08x",tmpdir(),str_checksum(syscmd));
998 if (!lpq_cache_reset[snum] && cachetime && !sys_stat(outfile,&sbuf)) {
999 if (time(NULL) - sbuf.st_mtime < cachetime) {
1000 DEBUG(3,("Using cached lpq output\n"));
1006 ret = smbrun(syscmd,outfile,True);
1007 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
1010 lpq_cache_reset[snum] = False;
1012 f = sys_fopen(outfile,"r");
1018 fstrcpy(status->message,"");
1019 status->status = LPSTAT_OK;
1022 while (fgets(line,sizeof(pstring),f)) {
1023 DEBUG(6,("QUEUE2: %s\n",line));
1025 *queue = Realloc(*queue,sizeof(print_queue_struct)*(count+1));
1031 bzero((char *)&(*queue)[count],sizeof(**queue));
1034 if (!parse_lpq_entry(snum,line,
1035 &(*queue)[count],status,count==0))
1046 /* we only expect this to succeed on trapdoor systems,
1047 on normal systems the file is owned by root */
1048 chmod(outfile,0666);
1054 /****************************************************************************
1055 delete a printer queue entry
1056 ****************************************************************************/
1057 void del_printqueue(connection_struct *conn,int snum,int jobid)
1059 char *lprm_command = lp_lprmcommand(snum);
1060 char *printername = PRINTERNAME(snum);
1065 if (!printername || !*printername)
1067 DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
1068 lp_servicename(snum),snum));
1069 printername = lp_servicename(snum);
1072 if (!lprm_command || !(*lprm_command))
1074 DEBUG(5,("No lprm command\n"));
1078 slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
1080 pstrcpy(syscmd,lprm_command);
1081 string_sub(syscmd,"%p",printername);
1082 string_sub(syscmd,"%j",jobstr);
1083 standard_sub(conn,syscmd);
1085 ret = smbrun(syscmd,NULL,False);
1086 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
1087 lpq_reset(snum); /* queue has changed */
1090 /****************************************************************************
1091 change status of a printer queue entry
1092 ****************************************************************************/
1093 void status_printjob(connection_struct *conn,int snum,int jobid,int status)
1095 char *lpstatus_command =
1096 (status==LPQ_PAUSED?lp_lppausecommand(snum):lp_lpresumecommand(snum));
1097 char *printername = PRINTERNAME(snum);
1102 if (!printername || !*printername)
1104 DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
1105 lp_servicename(snum),snum));
1106 printername = lp_servicename(snum);
1109 if (!lpstatus_command || !(*lpstatus_command))
1111 DEBUG(5,("No lpstatus command to %s job\n",
1112 (status==LPQ_PAUSED?"pause":"resume")));
1116 slprintf(jobstr,sizeof(jobstr)-1,"%d",jobid);
1118 pstrcpy(syscmd,lpstatus_command);
1119 string_sub(syscmd,"%p",printername);
1120 string_sub(syscmd,"%j",jobstr);
1121 standard_sub(conn,syscmd);
1123 ret = smbrun(syscmd,NULL,False);
1124 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
1125 lpq_reset(snum); /* queue has changed */
1130 /****************************************************************************
1131 we encode print job numbers over the wire so that when we get them back we can
1132 tell not only what print job they are but also what service it belongs to,
1133 this is to overcome the problem that windows clients tend to send the wrong
1134 service number when doing print queue manipulation!
1135 ****************************************************************************/
1136 int printjob_encode(int snum, int job)
1138 return ((snum&0xFF)<<8) | (job & 0xFF);
1141 /****************************************************************************
1142 and now decode them again ...
1143 ****************************************************************************/
1144 void printjob_decode(int jobid, int *snum, int *job)
1146 (*snum) = (jobid >> 8) & 0xFF;
1147 (*job) = jobid & 0xFF;
1150 /****************************************************************************
1151 Change status of a printer queue
1152 ****************************************************************************/
1154 void status_printqueue(connection_struct *conn,int snum,int status)
1156 char *queuestatus_command = (status==LPSTAT_STOPPED ?
1157 lp_queuepausecommand(snum):lp_queueresumecommand(snum));
1158 char *printername = PRINTERNAME(snum);
1162 if (!printername || !*printername) {
1163 DEBUG(6,("replacing printer name with service (snum=(%s,%d))\n",
1164 lp_servicename(snum),snum));
1165 printername = lp_servicename(snum);
1168 if (!queuestatus_command || !(*queuestatus_command)) {
1169 DEBUG(5,("No queuestatus command to %s job\n",
1170 (status==LPSTAT_STOPPED?"pause":"resume")));
1174 pstrcpy(syscmd,queuestatus_command);
1175 string_sub(syscmd,"%p",printername);
1176 standard_sub(conn,syscmd);
1178 ret = smbrun(syscmd,NULL,False);
1179 DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
1180 lpq_reset(snum); /* queue has changed */
1185 /***************************************************************************
1186 auto-load printer services
1187 ***************************************************************************/
1188 static void add_all_printers(void)
1190 int printers = lp_servicenumber(PRINTERS_NAME);
1192 if (printers < 0) return;
1194 pcap_printer_fn(lp_add_one_printer);
1197 /***************************************************************************
1198 auto-load some homes and printer services
1199 ***************************************************************************/
1200 static void add_auto_printers(void)
1204 char *str = lp_auto_services();
1208 printers = lp_servicenumber(PRINTERS_NAME);
1210 if (printers < 0) return;
1212 for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
1213 if (lp_servicenumber(p) >= 0) continue;
1215 if (pcap_printername_ok(p,NULL)) {
1216 lp_add_printer(p,printers);
1221 /***************************************************************************
1222 load automatic printer services
1223 ***************************************************************************/
1224 void load_printers(void)
1226 add_auto_printers();
1227 if (lp_load_printers())