summaryrefslogtreecommitdiff
path: root/source4/printing
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2004-05-24 17:41:47 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:56:12 -0500
commit7fb1be73734915e027f86aca9ba62b86c56ca787 (patch)
treeb66be4fc8eedb1ed5c20bbc29493e3a6353bcfff /source4/printing
parentf1a8a690fcd9e8824dade9278e83902a6229b092 (diff)
downloadsamba-7fb1be73734915e027f86aca9ba62b86c56ca787.tar.gz
samba-7fb1be73734915e027f86aca9ba62b86c56ca787.tar.bz2
samba-7fb1be73734915e027f86aca9ba62b86c56ca787.zip
r853: remove a real big bunch of unused code
I really think that this is needed to get a better overview of what is currently used Also this stuff is really out of date so if we really ever need some of this stuff back, a 'svn copy' from the SAMBA_3_0 branch should be no big problem... metze (This used to be commit 972598d511c64f29bdc849fe58c9c82fbcf6a4a2)
Diffstat (limited to 'source4/printing')
-rw-r--r--source4/printing/config.m416
-rw-r--r--source4/printing/load.c73
-rw-r--r--source4/printing/lpq_parse.c1099
-rw-r--r--source4/printing/notify.c526
-rw-r--r--source4/printing/pcap.c413
-rw-r--r--source4/printing/print_cups.c1293
-rw-r--r--source4/printing/print_generic.c245
-rw-r--r--source4/printing/print_svid.c144
-rw-r--r--source4/printing/printfsp.c120
-rw-r--r--source4/printing/printing.c2128
-rw-r--r--source4/printing/printing_db.c204
11 files changed, 0 insertions, 6261 deletions
diff --git a/source4/printing/config.m4 b/source4/printing/config.m4
deleted file mode 100644
index ad5e4844e5..0000000000
--- a/source4/printing/config.m4
+++ /dev/null
@@ -1,16 +0,0 @@
-############################################
-# for cups support we need libcups, and a handful of header files
-
-AC_ARG_ENABLE(cups,
-[ --enable-cups Turn on CUPS support (default=auto)])
-
-if test x$enable_cups != xno; then
- AC_PATH_PROG(CUPS_CONFIG, cups-config)
-
- if test "x$CUPS_CONFIG" != x; then
- AC_DEFINE(HAVE_CUPS,1,[Whether we have CUPS])
- CFLAGS="$CFLAGS `$CUPS_CONFIG --cflags`"
- LDFLAGS="$LDFLAGS `$CUPS_CONFIG --ldflags`"
- PRINTLIBS="$PRINTLIBS `$CUPS_CONFIG --libs`"
- fi
-fi
diff --git a/source4/printing/load.c b/source4/printing/load.c
deleted file mode 100644
index cd90cbb6f3..0000000000
--- a/source4/printing/load.c
+++ /dev/null
@@ -1,73 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- load printer lists
- Copyright (C) Andrew Tridgell 1992-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 02139, USA.
-*/
-
-#include "includes.h"
-
-
-/***************************************************************************
-auto-load printer services
-***************************************************************************/
-void add_all_printers(void)
-{
- int printers = lp_servicenumber(PRINTERS_NAME);
-
- if (printers < 0) return;
-
- pcap_printer_fn(lp_add_one_printer);
-}
-
-/***************************************************************************
-auto-load some homes and printer services
-***************************************************************************/
-static void add_auto_printers(void)
-{
- const char *p;
- int printers;
- char *str = strdup(lp_auto_services());
-
- if (!str) return;
-
- printers = lp_servicenumber(PRINTERS_NAME);
-
- if (printers < 0) {
- SAFE_FREE(str);
- return;
- }
-
- for (p=strtok(str,LIST_SEP);p;p=strtok(NULL,LIST_SEP)) {
- if (lp_servicenumber(p) >= 0) continue;
-
- if (pcap_printername_ok(p,NULL)) {
- lp_add_printer(p,printers);
- }
- }
-
- SAFE_FREE(str);
-}
-
-/***************************************************************************
-load automatic printer services
-***************************************************************************/
-void load_printers(void)
-{
- add_auto_printers();
- if (lp_load_printers())
- add_all_printers();
-}
diff --git a/source4/printing/lpq_parse.c b/source4/printing/lpq_parse.c
deleted file mode 100644
index 4b91b8ac9a..0000000000
--- a/source4/printing/lpq_parse.c
+++ /dev/null
@@ -1,1099 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- 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 02139, USA.
-*/
-
-#include "includes.h"
-
-static const char *Months[13] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec", "Err"};
-
-
-/*******************************************************************
-process time fields
-********************************************************************/
-static time_t EntryTime(fstring tok[], int ptr, int count, int minimum)
-{
- time_t jobtime,jobtime1;
-
- jobtime = time(NULL); /* default case: take current time */
- if (count >= minimum) {
- struct tm *t;
- int i, day, hour, min, sec;
- char *c;
-
- for (i=0; i<13; i++) if (!strncmp(tok[ptr], Months[i],3)) break; /* Find month */
- if (i<12) {
- t = localtime(&jobtime);
- day = atoi(tok[ptr+1]);
- c=(char *)(tok[ptr+2]);
- *(c+2)=0;
- hour = atoi(c);
- *(c+5)=0;
- min = atoi(c+3);
- if(*(c+6) != 0)sec = atoi(c+6);
- else sec=0;
-
- if ((t->tm_mon < i)||
- ((t->tm_mon == i)&&
- ((t->tm_mday < day)||
- ((t->tm_mday == day)&&
- (t->tm_hour*60+t->tm_min < hour*60+min)))))
- t->tm_year--; /* last year's print job */
-
- t->tm_mon = i;
- t->tm_mday = day;
- t->tm_hour = hour;
- t->tm_min = min;
- t->tm_sec = sec;
- jobtime1 = mktime(t);
- if (jobtime1 != (time_t)-1)
- jobtime = jobtime1;
- }
- }
- return jobtime;
-}
-
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under bsd
-
-Warning: no daemon present
-Rank Owner Job Files Total Size
-1st 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
-1st 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 */
-
- /* FIXME: Use next_token rather than strtok! */
- tok[0] = strtok(line2," \t");
- count++;
-
- while (((tok[count] = strtok(NULL," \t")) != NULL) && (count < MAXTOK)) {
- count++;
- }
-
- /* we must get at least NTOK tokens */
- if (count < NTOK)
- return(False);
-
- /* the Job and Total columns must be integer */
- if (!isdigit((int)*tok[JOBTOK]) || !isdigit((int)*tok[TOTALTOK])) return(False);
-
- buf->job = atoi(tok[JOBTOK]);
- buf->size = atoi(tok[TOTALTOK]);
- buf->status = strequal(tok[RANKTOK],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[USERTOK],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[FILETOK],sizeof(buf->fs_file)-1);
-
- if ((FILETOK + 1) != TOTALTOK) {
- int i;
-
- for (i = (FILETOK + 1); i < TOTALTOK; i++) {
- /* 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]);
- }
- /* Ensure null termination. */
- fstrterminate(buf->fs_file);
- }
-
-#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.
-
-<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"
-
-*/
-static time_t LPRng_time(char *time_string)
-{
- time_t jobtime;
- struct tm t;
-
- jobtime = time(NULL); /* default case: take current time */
- t = *localtime(&jobtime);
-
- 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;
-}
-
-
-/****************************************************************************
- 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. */
-
- fstring tokarr[LPRNG_MAXTOK];
- const char *cptr;
- char *ptr;
- int num_tok = 0;
-
- cptr = line;
- while(next_token( &cptr, tokarr[num_tok], " \t", sizeof(fstring)) && (num_tok < LPRNG_MAXTOK))
- num_tok++;
-
- /* We must get at least LPRNG_NTOK tokens. */
- if (num_tok < LPRNG_NTOK) {
- return(False);
- }
-
- if (!isdigit((int)*tokarr[LPRNG_JOBTOK]) || !isdigit((int)*tokarr[LPRNG_TOTALTOK])) {
- return(False);
- }
-
- buf->job = atoi(tokarr[LPRNG_JOBTOK]);
- buf->size = atoi(tokarr[LPRNG_TOTALTOK]);
-
- if (strequal(tokarr[LPRNG_RANKTOK],"active")) {
- buf->status = LPQ_PRINTING;
- } else if (strequal(tokarr[LPRNG_RANKTOK],"done")) {
- buf->status = LPQ_PRINTED;
- } else if (isdigit((int)*tokarr[LPRNG_RANKTOK])) {
- buf->status = LPQ_QUEUED;
- } else {
- buf->status = LPQ_PAUSED;
- }
-
- buf->priority = *tokarr[LPRNG_PRIOTOK] -'A';
-
- buf->time = LPRng_time(tokarr[LPRNG_TIMETOK]);
-
- StrnCpy(buf->fs_user,tokarr[LPRNG_USERTOK],sizeof(buf->fs_user)-1);
-
- /* The '@hostname' prevents windows from displaying the printing icon
- * for the current user on the taskbar. Plop in a null.
- */
-
- if ((ptr = strchr_m(buf->fs_user,'@')) != NULL) {
- *ptr = '\0';
- }
-
- StrnCpy(buf->fs_file,tokarr[LPRNG_FILETOK],sizeof(buf->fs_file)-1);
-
- if ((LPRNG_FILETOK + 1) != LPRNG_TOTALTOK) {
- int i;
-
- for (i = (LPRNG_FILETOK + 1); i < LPRNG_TOTALTOK; i++) {
- /* 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]);
- }
- /* Ensure null termination. */
- fstrterminate(buf->fs_file);
- }
-
- 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 6297doc.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;
- const char *cline = line;
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"standard input","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0;
- count<10 &&
- next_token(&cline,tok[count],NULL, sizeof(tok[count]));
- count++) ;
-
- /* we must get 6 tokens */
- if (count < 10)
- {
- if ((count == 7) && ((strcmp(tok[0],"QUEUED") == 0) || (strcmp(tok[0],"HELD") == 0)))
- {
- /* the 2nd and 5th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4])) return(False);
- buf->size = atoi(tok[4]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[2],' '))
- fstrcpy(tok[2],"STDIN");
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[2],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[2],tmp);
- }
- }
-
-
- buf->job = atoi(tok[1]);
- buf->status = strequal(tok[0],"HELD")?LPQ_PAUSED:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[3],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1);
- }
- else
- {
- DEBUG(6,("parse_lpq_aix count=%d\n", count));
- return(False);
- }
- }
- else
- {
- /* the 4th and 9th columns must be integer */
- if (!isdigit((int)*tok[3]) || !isdigit((int)*tok[8])) return(False);
- buf->size = atoi(tok[8]) * 1024;
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[4],' '))
- fstrcpy(tok[4],"STDIN");
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[4],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[4],tmp);
- }
- }
-
-
- buf->job = atoi(tok[3]);
- buf->status = strequal(tok[2],"RUNNING")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[5],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[4],sizeof(buf->fs_file)-1);
- }
-
-
- return(True);
-}
-
-
-/****************************************************************************
-parse a lpq line
-here is an example of lpq output under hpux; note there's no space after -o !
-$> lpstat -oljplus
-ljplus-2153 user priority 0 Jan 19 08:14 on ljplus
- util.c 125697 bytes
- server.c 110712 bytes
-ljplus-2154 user priority 0 Jan 19 08:14 from client
- (standard input) 7551 bytes
-****************************************************************************/
-static BOOL parse_lpq_hpux(char *line, print_queue_struct *buf, BOOL first)
-{
- /* must read two lines to process, therefore keep some values static */
- static BOOL header_line_ok=False, base_prio_reset=False;
- static fstring jobuser;
- static int jobid;
- static int jobprio;
- static time_t jobtime;
- static int jobstat=LPQ_QUEUED;
- /* to store minimum priority to print, lpstat command should be invoked
- with -p option first, to work */
- static int base_prio;
- int count;
- char htab = '\011';
- const char *cline = line;
- 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,"\tfence 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 */
- string_sub(line,"standard input","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0; count<2 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
- /* we must get 2 tokens */
- if (count < 2) return(False);
-
- /* the 2nd column must be integer */
- if (!isdigit((int)*tok[1])) return(False);
-
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[0],' '))
- fstrcpy(tok[0],"STDIN");
-
- buf->size = atoi(tok[1]);
- StrnCpy(buf->fs_file,tok[0],sizeof(buf->fs_file)-1);
-
- /* fill things from header line */
- buf->time = jobtime;
- buf->job = jobid;
- buf->status = jobstat;
- buf->priority = jobprio;
- StrnCpy(buf->fs_user,jobuser,sizeof(buf->fs_user)-1);
-
- return(True);
- }
- else { /* header line */
- header_line_ok=False; /* reset it */
- if (first) {
- if (!base_prio_reset) {
- base_prio=0; /* reset it */
- base_prio_reset=True;
- }
- }
- else if (base_prio) base_prio_reset=False;
-
- /* handle the dash in the job id */
- string_sub(line,"-"," ",0);
-
- for (count=0; count<12 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 8 tokens */
- if (count < 8) return(False);
-
- /* first token must be printer name (cannot check ?) */
- /* the 2nd, 5th & 7th column must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[4]) || !isdigit((int)*tok[6])) return(False);
- jobid = atoi(tok[1]);
- StrnCpy(jobuser,tok[2],sizeof(buf->fs_user)-1);
- jobprio = atoi(tok[4]);
-
- /* process time */
- jobtime=EntryTime(tok, 5, count, 8);
- if (jobprio < base_prio) {
- jobstat = LPQ_PAUSED;
- DEBUG (4, ("job %d is paused: prio %d < %d; jobstat=%d\n", jobid, jobprio, base_prio, jobstat));
- }
- else {
- jobstat = LPQ_QUEUED;
- if ((count >8) && (((strequal(tok[8],"on")) ||
- ((strequal(tok[8],"from")) &&
- ((count > 10)&&(strequal(tok[10],"on")))))))
- jobstat = LPQ_PRINTING;
- }
-
- header_line_ok=True; /* information is correct */
- return(False); /* need subline info to include into queuelist */
- }
-}
-
-
-/****************************************************************************
-parse a lpstat line
-
-here is an example of "lpstat -o dcslw" output under sysv
-
-dcslw-896 tridge 4712 Dec 20 10:30:30 on dcslw
-dcslw-897 tridge 4712 Dec 20 10:30:30 being held
-
-****************************************************************************/
-static BOOL parse_lpq_sysv(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[9];
- int count=0;
- char *p;
- const char *cline = line;
-
- /*
- * Handle the dash in the job id, but make sure that we skip over
- * the printer name in case we have a dash in that.
- * Patch from Dom.Mitchell@palmerharvey.co.uk.
- */
-
- /*
- * Move to the first space.
- */
- for (p = line ; !isspace(*p) && *p; p++)
- ;
-
- /*
- * Back up until the last '-' character or
- * start of line.
- */
- for (; (p >= line) && (*p != '-'); p--)
- ;
-
- if((p >= line) && (*p == '-'))
- *p = ' ';
-
- for (count=0; count<9 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++)
- ;
-
- /* we must get 7 tokens */
- if (count < 7)
- return(False);
-
- /* the 2nd and 4th, 6th columns must be integer */
- if (!isdigit((int)*tok[1]) || !isdigit((int)*tok[3]))
- return(False);
- if (!isdigit((int)*tok[5]))
- return(False);
-
- /* if the user contains a ! then trim the first part of it */
- if ((p=strchr_m(tok[2],'!'))) {
- fstring tmp;
- fstrcpy(tmp,p+1);
- fstrcpy(tok[2],tmp);
- }
-
- buf->job = atoi(tok[1]);
- buf->size = atoi(tok[3]);
- if (count > 7 && strequal(tok[7],"on"))
- buf->status = LPQ_PRINTING;
- else if (count > 8 && strequal(tok[7],"being") && strequal(tok[8],"held"))
- buf->status = LPQ_PAUSED;
- else
- buf->status = LPQ_QUEUED;
- buf->priority = 0;
- buf->time = EntryTime(tok, 4, count, 7);
- StrnCpy(buf->fs_user,tok[2],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[2],sizeof(buf->fs_file)-1);
- return(True);
-}
-
-/****************************************************************************
-parse a lpq line
-
-here is an example of lpq output under qnx
-Spooler: /qnx/spooler, on node 1
-Printer: txt (ready)
-0000: root [job #1 ] active 1146 bytes /etc/profile
-0001: root [job #2 ] ready 2378 bytes /etc/install
-0002: root [job #3 ] ready 1146 bytes -- standard input --
-****************************************************************************/
-static BOOL parse_lpq_qnx(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[7];
- int count=0;
- const char *cline;
-
- DEBUG(4,("antes [%s]\n", line));
-
- /* handle the case of "-- standard input --" as a filename */
- string_sub(line,"standard input","STDIN",0);
- DEBUG(4,("despues [%s]\n", line));
- all_string_sub(line,"-- ","\"",0);
- all_string_sub(line," --","\"",0);
- DEBUG(4,("despues 1 [%s]\n", line));
-
- string_sub(line,"[job #","",0);
- string_sub(line,"]","",0);
- DEBUG(4,("despues 2 [%s]\n", line));
-
- for (count=0; count<7 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 7 tokens */
- if (count < 7)
- return(False);
-
- /* the 3rd and 5th columns must be integer */
- if (!isdigit((int)*tok[2]) || !isdigit((int)*tok[4])) return(False);
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[6],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[6],tmp);
- }
- }
-
-
- buf->job = atoi(tok[2]);
- buf->size = atoi(tok[4]);
- buf->status = strequal(tok[3],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1);
- return(True);
-}
-
-
-/****************************************************************************
- parse a lpq line for the plp printing system
- Bertrand Wallrich <Bertrand.Wallrich@loria.fr>
-
-redone by tridge. Here is a sample queue:
-
-Local Printer 'lp2' (fjall):
- Printing (started at Jun 15 13:33:58, attempt 1).
- Rank Owner Pr Opt Job Host Files Size Date
- active tridge X - 6 fjall /etc/hosts 739 Jun 15 13:33
- 3rd 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;
- const char *cline = line;
-
- /* handle the case of "(standard input)" as a filename */
- string_sub(line,"stdin","STDIN",0);
- all_string_sub(line,"(","\"",0);
- all_string_sub(line,")","\"",0);
-
- for (count=0; count<11 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 11 tokens */
- if (count < 11)
- return(False);
-
- /* the first must be "active" or begin with an integer */
- if (strcmp(tok[0],"active") && !isdigit((int)tok[0][0]))
- return(False);
-
- /* the 5th and 8th must be integer */
- if (!isdigit((int)*tok[4]) || !isdigit((int)*tok[7]))
- return(False);
-
- /* if the fname contains a space then use STDIN */
- if (strchr_m(tok[6],' '))
- fstrcpy(tok[6],"STDIN");
-
- /* only take the last part of the filename */
- {
- fstring tmp;
- char *p = strrchr_m(tok[6],'/');
- if (p)
- {
- fstrcpy(tmp,p+1);
- fstrcpy(tok[6],tmp);
- }
- }
-
-
- buf->job = atoi(tok[4]);
-
- buf->size = atoi(tok[7]);
- if (strchr_m(tok[7],'K'))
- buf->size *= 1024;
- if (strchr_m(tok[7],'M'))
- buf->size *= 1024*1024;
-
- buf->status = strequal(tok[0],"active")?LPQ_PRINTING:LPQ_QUEUED;
- buf->priority = 0;
- buf->time = time(NULL);
- StrnCpy(buf->fs_user,tok[1],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[6],sizeof(buf->fs_file)-1);
- return(True);
-}
-
-/****************************************************************************
-parse a qstat line
-
-here is an example of "qstat -l -d qms" output under softq
-
-Queue qms: 2 jobs; daemon active (313); enabled; accepting;
- job-ID submission-time pri size owner title
-205980: H 98/03/09 13:04:05 0 15733 stephenf chap1.ps
-206086:> 98/03/12 17:24:40 0 659 chris -
-206087: 98/03/12 17:24:45 0 4876 chris -
-Total: 21268 bytes in queue
-
-
-****************************************************************************/
-static BOOL parse_lpq_softq(char *line,print_queue_struct *buf,BOOL first)
-{
- fstring tok[10];
- int count=0;
- const char *cline = line;
-
- /* mung all the ":"s to spaces*/
- string_sub(line,":"," ",0);
-
- for (count=0; count<10 && next_token(&cline,tok[count],NULL,sizeof(tok[count])); count++) ;
-
- /* we must get 9 tokens */
- if (count < 9)
- return(False);
-
- /* the 1st and 7th columns must be integer */
- if (!isdigit((int)*tok[0]) || !isdigit((int)*tok[6])) return(False);
- /* if the 2nd column is either '>' or 'H' then the 7th and 8th must be
- * integer, else it's the 6th and 7th that must be
- */
- if (*tok[1] == 'H' || *tok[1] == '>')
- {
- if (!isdigit((int)*tok[7]))
- return(False);
- buf->status = *tok[1] == '>' ? LPQ_PRINTING : LPQ_PAUSED;
- count = 1;
- }
- else
- {
- if (!isdigit((int)*tok[5]))
- return(False);
- buf->status = LPQ_QUEUED;
- count = 0;
- }
-
-
- buf->job = atoi(tok[0]);
- buf->size = atoi(tok[count+6]);
- buf->priority = atoi(tok[count+5]);
- StrnCpy(buf->fs_user,tok[count+7],sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file,tok[count+8],sizeof(buf->fs_file)-1);
- buf->time = time(NULL); /* default case: take current time */
- {
- time_t jobtime;
- struct tm *t;
-
- t = localtime(&buf->time);
- t->tm_mday = atoi(tok[count+2]+6);
- t->tm_mon = atoi(tok[count+2]+3);
- switch (*tok[count+2])
- {
- case 7: case 8: case 9: t->tm_year = atoi(tok[count+2]); break;
- default: t->tm_year = atoi(tok[count+2]); break;
- }
-
- t->tm_hour = atoi(tok[count+3]);
- t->tm_min = atoi(tok[count+4]);
- t->tm_sec = atoi(tok[count+5]);
- jobtime = mktime(t);
- if (jobtime != (time_t)-1)
- buf->time = jobtime;
- }
-
- return(True);
-}
-
-/*******************************************************************
-parse lpq on an NT system
-
- Windows 2000 LPD Server
- Printer \\10.0.0.2\NP17PCL (Paused)
-
-Owner Status Jobname Job-Id Size Pages Priority
-----------------------------------------------------------------------------
-root (9.99. Printing /usr/lib/rhs/rhs-pr 3 625 0 1
-root (9.99. Paused /usr/lib/rhs/rhs-pr 4 625 0 1
-jmcd Waiting Re: Samba Open Sour 26 32476 1 1
-
-********************************************************************/
-static BOOL parse_lpq_nt(char *line,print_queue_struct *buf,BOOL first)
-{
-#define LPRNT_OWNSIZ 11
-#define LPRNT_STATSIZ 9
-#define LPRNT_JOBSIZ 19
-#define LPRNT_IDSIZ 6
-#define LPRNT_SIZSIZ 9
- typedef struct
- {
- char owner[LPRNT_OWNSIZ];
- char space1;
- char status[LPRNT_STATSIZ];
- char space2;
- char jobname[LPRNT_JOBSIZ];
- char space3;
- char jobid[LPRNT_IDSIZ];
- char space4;
- char size[LPRNT_SIZSIZ];
- char terminator;
- } nt_lpq_line;
-
- nt_lpq_line parse_line;
-#define LPRNT_PRINTING "Printing"
-#define LPRNT_WAITING "Waiting"
-#define LPRNT_PAUSED "Paused"
-
- memset(&parse_line, '\0', sizeof(parse_line));
- strncpy((char *) &parse_line, line, sizeof(parse_line) -1);
-
- if (strlen((char *) &parse_line) != sizeof(parse_line) - 1)
- return(False);
-
- /* Just want the first word in the owner field - the username */
- if (strchr_m(parse_line.owner, ' '))
- *(strchr_m(parse_line.owner, ' ')) = '\0';
- else
- parse_line.space1 = '\0';
-
- /* Make sure we have an owner */
- if (!strlen(parse_line.owner))
- return(False);
-
- /* Make sure the status is valid */
- parse_line.space2 = '\0';
- trim_string(parse_line.status, NULL, " ");
- if (!strequal(parse_line.status, LPRNT_PRINTING) &&
- !strequal(parse_line.status, LPRNT_PAUSED) &&
- !strequal(parse_line.status, LPRNT_WAITING))
- return(False);
-
- parse_line.space3 = '\0';
- trim_string(parse_line.jobname, NULL, " ");
-
- buf->job = atoi(parse_line.jobid);
- buf->priority = 0;
- buf->size = atoi(parse_line.size);
- buf->time = time(NULL);
- StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1);
- StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1);
- if (strequal(parse_line.status, LPRNT_PRINTING))
- buf->status = LPQ_PRINTING;
- else if (strequal(parse_line.status, LPRNT_PAUSED))
- buf->status = LPQ_PAUSED;
- else
- buf->status = LPQ_QUEUED;
-
- return(True);
-}
-
-/*******************************************************************
-parse lpq on an OS2 system
-
-JobID File Name Rank Size Status Comment
------ --------------- ------ -------- ------------ ------------
- 3 Control 1 68 Queued root@psflinu
- 4 /etc/motd 2 11666 Queued root@psflinu
-
-********************************************************************/
-static BOOL parse_lpq_os2(char *line,print_queue_struct *buf,BOOL first)
-{
-#define LPROS2_IDSIZ 5
-#define LPROS2_JOBSIZ 15
-#define LPROS2_SIZSIZ 8
-#define LPROS2_STATSIZ 12
-#define LPROS2_OWNSIZ 12
- typedef struct
- {
- char jobid[LPROS2_IDSIZ];
- char space1[2];
- char jobname[LPROS2_JOBSIZ];
- char space2[14];
- char size[LPROS2_SIZSIZ];
- char space3[4];
- char status[LPROS2_STATSIZ];
- char space4[4];
- char owner[LPROS2_OWNSIZ];
- char terminator;
- } os2_lpq_line;
-
- os2_lpq_line parse_line;
-#define LPROS2_PRINTING "Printing"
-#define LPROS2_WAITING "Queued"
-#define LPROS2_PAUSED "Paused"
-
- memset(&parse_line, '\0', sizeof(parse_line));
- strncpy((char *) &parse_line, line, sizeof(parse_line) -1);
-
- if (strlen((char *) &parse_line) != sizeof(parse_line) - 1)
- return(False);
-
- /* Get the jobid */
- buf->job = atoi(parse_line.jobid);
-
- /* Get the job name */
- parse_line.space2[0] = '\0';
- trim_string(parse_line.jobname, NULL, " ");
- StrnCpy(buf->fs_file, parse_line.jobname, sizeof(buf->fs_file)-1);
-
- buf->priority = 0;
- buf->size = atoi(parse_line.size);
- buf->time = time(NULL);
-
- /* Make sure we have an owner */
- if (!strlen(parse_line.owner))
- return(False);
-
- /* Make sure we have a valid status */
- parse_line.space4[0] = '\0';
- trim_string(parse_line.status, NULL, " ");
- if (!strequal(parse_line.status, LPROS2_PRINTING) &&
- !strequal(parse_line.status, LPROS2_PAUSED) &&
- !strequal(parse_line.status, LPROS2_WAITING))
- return(False);
-
- StrnCpy(buf->fs_user, parse_line.owner, sizeof(buf->fs_user)-1);
- if (strequal(parse_line.status, LPROS2_PRINTING))
- buf->status = LPQ_PRINTING;
- else if (strequal(parse_line.status, LPROS2_PAUSED))
- buf->status = LPQ_PAUSED;
- else
- buf->status = LPQ_QUEUED;
-
- return(True);
-}
-
-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 };
-
-#ifdef DEVELOPER
-
-/****************************************************************************
-parse a vlp line
-****************************************************************************/
-static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
-{
- int toknum = 0;
- fstring tok;
- const char *cline = line;
-
- /* First line is printer status */
-
- if (!isdigit(line[0])) return False;
-
- /* Parse a print job entry */
-
- while(next_token(&cline, tok, NULL, sizeof(fstring))) {
- 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:
- fstrcpy(buf->fs_user, tok);
- break;
- case 5:
- fstrcpy(buf->fs_file, tok);
- break;
- }
- toknum++;
- }
-
- return True;
-}
-
-#endif /* DEVELOPER */
-
-/****************************************************************************
-parse a lpq line. Choose printing style
-****************************************************************************/
-
-BOOL parse_lpq_entry(int snum,char *line,
- print_queue_struct *buf,
- print_status_struct *status,BOOL first)
-{
- BOOL ret;
-
- switch (lp_printing(snum))
- {
- case PRINT_SYSV:
- ret = parse_lpq_sysv(line,buf,first);
- break;
- case PRINT_AIX:
- ret = parse_lpq_aix(line,buf,first);
- break;
- case PRINT_HPUX:
- ret = parse_lpq_hpux(line,buf,first);
- break;
- case PRINT_QNX:
- ret = parse_lpq_qnx(line,buf,first);
- break;
- case PRINT_LPRNG:
- ret = parse_lpq_lprng(line,buf,first);
- break;
- case PRINT_PLP:
- ret = parse_lpq_plp(line,buf,first);
- break;
- case PRINT_SOFTQ:
- ret = parse_lpq_softq(line,buf,first);
- break;
- case PRINT_LPRNT:
- ret = parse_lpq_nt(line,buf,first);
- break;
- case PRINT_LPROS2:
- ret = parse_lpq_os2(line,buf,first);
- break;
-#ifdef DEVELOPER
- case PRINT_VLP:
- case PRINT_TEST:
- ret = parse_lpq_vlp(line,buf,first);
- break;
-#endif /* DEVELOPER */
- default:
- ret = parse_lpq_bsd(line,buf,first);
- break;
- }
-
- /* We don't want the newline in the status message. */
- {
- char *p = strchr_m(line,'\n');
- if (p) *p = 0;
- }
-
- /* in the LPRNG case, we skip lines starting by a space.*/
- if (line && !ret && (lp_printing(snum)==PRINT_LPRNG) )
- {
- if (line[0]==' ')
- return ret;
- }
-
-
- if (status && !ret)
- {
- /* a few simple checks to see if the line might be a
- printer status line:
- handle them so that most severe condition is shown */
- int i;
- strlower(line);
-
- switch (status->status) {
- case LPSTAT_OK:
- for (i=0; stat0_strings[i]; i++)
- if (strstr(line,stat0_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_OK;
- return ret;
- }
- case LPSTAT_STOPPED:
- for (i=0; stat1_strings[i]; i++)
- if (strstr(line,stat1_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_STOPPED;
- return ret;
- }
- case LPSTAT_ERROR:
- for (i=0; stat2_strings[i]; i++)
- if (strstr(line,stat2_strings[i])) {
- StrnCpy(status->message,line,sizeof(status->message)-1);
- status->status=LPSTAT_ERROR;
- return ret;
- }
- break;
- }
- }
-
- return(ret);
-}
diff --git a/source4/printing/notify.c b/source4/printing/notify.c
deleted file mode 100644
index a745e9e308..0000000000
--- a/source4/printing/notify.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 2.2
- printing backend routines
- Copyright (C) Tim Potter, 2002
- Copyright (C) Gerald Carter, 2002
-
- 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 02139, USA.
-*/
-
-#include "printing.h"
-
-static TALLOC_CTX *send_ctx;
-
-static BOOL create_send_ctx(void)
-{
- if (!send_ctx)
- send_ctx = talloc_init("print notify queue");
-
- if (!send_ctx)
- return False;
-
- return True;
-}
-
-/****************************************************************************
- Turn a queue name into a snum.
-****************************************************************************/
-
-int print_queue_snum(const char *qname)
-{
- int snum = lp_servicenumber(qname);
- if (snum == -1 || !lp_print_ok(snum))
- return -1;
- return snum;
-}
-
-/*******************************************************************
- Used to decide if we need a short select timeout.
-*******************************************************************/
-
-BOOL print_notify_messages_pending(void)
-{
- return (notify_queue_head != NULL);
-}
-
-/*******************************************************************
- Flatten data into a message.
-*******************************************************************/
-
-static BOOL flatten_message(struct notify_queue *q)
-{
- struct spoolss_notify_msg *msg = q->msg;
- char *buf = NULL;
- size_t buflen = 0, len;
-
-again:
- len = 0;
-
- /* Pack header */
-
- len += tdb_pack(buf + len, buflen - len, "f", msg->printer);
-
- len += tdb_pack(buf + len, buflen - len, "ddddd",
- msg->type, msg->field, msg->id, msg->len, msg->flags);
-
- /* Pack data */
-
- if (msg->len == 0)
- len += tdb_pack(buf + len, buflen - len, "dd",
- msg->notify.value[0], msg->notify.value[1]);
- else
- len += tdb_pack(buf + len, buflen - len, "B",
- msg->len, msg->notify.data);
-
- if (buflen != len) {
- buf = talloc_realloc(send_ctx, buf, len);
- if (!buf)
- return False;
- buflen = len;
- goto again;
- }
-
- q->buf = buf;
- q->buflen = buflen;
-
- return True;
-}
-
-/*******************************************************************
- Send the batched messages - on a per-printer basis.
-*******************************************************************/
-
-static void print_notify_send_messages_to_printer(const char *printer, unsigned int timeout)
-{
- char *buf;
- struct notify_queue *pq, *pq_next;
- size_t msg_count = 0, offset = 0;
- size_t num_pids = 0;
- size_t i;
- pid_t *pid_list = NULL;
-
- /* Count the space needed to send the messages. */
- for (pq = notify_queue_head; pq; pq = pq->next) {
- if (strequal(printer, pq->msg->printer)) {
- if (!flatten_message(pq)) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_destroy_pool(send_ctx);
- return;
- }
- offset += (pq->buflen + 4);
- msg_count++;
- }
- }
- offset += 4; /* For count. */
-
- buf = talloc(send_ctx, offset);
- if (!buf) {
- DEBUG(0,("print_notify_send_messages: Out of memory\n"));
- talloc_destroy_pool(send_ctx);
- return;
- }
-
- offset = 0;
- SIVAL(buf,offset,msg_count);
- offset += 4;
- for (pq = notify_queue_head; pq; pq = pq_next) {
- pq_next = pq->next;
-
- if (strequal(printer, pq->msg->printer)) {
- SIVAL(buf,offset,pq->buflen);
- offset += 4;
- memcpy(buf + offset, pq->buf, pq->buflen);
- offset += pq->buflen;
-
- /* Remove from list. */
- DLIST_REMOVE(notify_queue_head, pq);
- }
- }
-
- DEBUG(5, ("print_notify_send_messages_to_printer: sending %d print notify message%s to printer %s\n",
- msg_count, msg_count != 1 ? "s" : "", printer));
-
- /*
- * Get the list of PID's to send to.
- */
-
- if (!print_notify_pid_list(printer, send_ctx, &num_pids, &pid_list))
- return;
-
- for (i = 0; i < num_pids; i++)
- message_send_pid_with_timeout(pid_list[i], MSG_PRINTER_NOTIFY2, buf, offset, True, timeout);
-}
-
-/*******************************************************************
- Actually send the batched messages.
-*******************************************************************/
-
-void print_notify_send_messages(unsigned int timeout)
-{
- if (!print_notify_messages_pending())
- return;
-
- if (!create_send_ctx())
- return;
-
- while (print_notify_messages_pending())
- print_notify_send_messages_to_printer(notify_queue_head->msg->printer, timeout);
-
- talloc_destroy_pool(send_ctx);
-}
-
-/**********************************************************************
- deep copy a SPOOLSS_NOTIFY_MSG structure using a TALLOC_CTX
- *********************************************************************/
-
-static BOOL copy_notify2_msg( SPOOLSS_NOTIFY_MSG *to, SPOOLSS_NOTIFY_MSG *from )
-{
-
- if ( !to || !from )
- return False;
-
- memcpy( to, from, sizeof(SPOOLSS_NOTIFY_MSG) );
-
- if ( from->len ) {
- to->notify.data = talloc_memdup(send_ctx, from->notify.data, from->len );
- if ( !to->notify.data ) {
- DEBUG(0,("copy_notify2_msg: talloc_memdup() of size [%d] failed!\n", from->len ));
- return False;
- }
- }
-
-
- return True;
-}
-
-/*******************************************************************
- Batch up print notify messages.
-*******************************************************************/
-
-static void send_spoolss_notify2_msg(SPOOLSS_NOTIFY_MSG *msg)
-{
- struct notify_queue *pnqueue;
-
- /*
- * Ensure we only have one message unique to each name/type/field/id/flags
- * tuple. There is no point in sending multiple messages that match
- * as they will just cause flickering updates in the client.
- */
-
- for (tmp_ptr = notify_queue_head; tmp_ptr; tmp_ptr = tmp_ptr->next) {
- if (tmp_ptr->msg->type == msg->type &&
- tmp_ptr->msg->field == msg->field &&
- tmp_ptr->msg->id == msg->id &&
- tmp_ptr->msg->flags == msg->flags &&
- strequal(tmp_ptr->msg->printer, msg->printer)) {
-
- DEBUG(5, ("send_spoolss_notify2_msg: replacing message 0x%02x/0x%02x for printer %s \
-in notify_queue\n", msg->type, msg->field, msg->printer));
-
- tmp_ptr->msg = msg;
- return;
- }
- }
-
- /* Store the message on the pending queue. */
-
- pnqueue = talloc(send_ctx, sizeof(*pnqueue));
- if (!pnqueue) {
- DEBUG(0,("send_spoolss_notify2_msg: Out of memory.\n"));
- return;
- }
-
- /* allocate a new msg structure and copy the fields */
-
- if ( !(pnqueue->msg = (SPOOLSS_NOTIFY_MSG*)talloc(send_ctx, sizeof(SPOOLSS_NOTIFY_MSG))) ) {
- DEBUG(0,("send_spoolss_notify2_msg: talloc() of size [%d] failed!\n",
- sizeof(SPOOLSS_NOTIFY_MSG)));
- return;
- }
- copy_notify2_msg(pnqueue->msg, msg);
- pnqueue->buf = NULL;
- pnqueue->buflen = 0;
-
- DEBUG(5, ("send_spoolss_notify2_msg: appending message 0x%02x/0x%02x for printer %s \
-to notify_queue_head\n", msg->type, msg->field, msg->printer));
-
- /*
- * Note we add to the end of the list to ensure
- * the messages are sent in the order they were received. JRA.
- */
-
- DLIST_ADD_END(notify_queue_head, pnqueue, struct notify_queue *);
-}
-
-static void send_notify_field_values(const char *printer_name, uint32 type,
- uint32 field, uint32 id, uint32 value1,
- uint32 value2, uint32 flags)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = (struct spoolss_notify_msg *)talloc(send_ctx, sizeof(struct spoolss_notify_msg));
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, printer_name);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->notify.value[0] = value1;
- msg->notify.value[1] = value2;
- msg->flags = flags;
-
- send_spoolss_notify2_msg(msg);
-}
-
-static void send_notify_field_buffer(const char *printer_name, uint32 type,
- uint32 field, uint32 id, uint32 len,
- char *buffer)
-{
- struct spoolss_notify_msg *msg;
-
- if (lp_disable_spoolss())
- return;
-
- if (!create_send_ctx())
- return;
-
- msg = (struct spoolss_notify_msg *)talloc(send_ctx, sizeof(struct spoolss_notify_msg));
- if (!msg)
- return;
-
- ZERO_STRUCTP(msg);
-
- fstrcpy(msg->printer, printer_name);
- msg->type = type;
- msg->field = field;
- msg->id = id;
- msg->len = len;
- msg->notify.data = buffer;
-
- send_spoolss_notify2_msg(msg);
-}
-
-/* Send a message that the printer status has changed */
-
-void notify_printer_status_byname(const char *printer_name, uint32 status)
-{
- /* Printer status stored in value1 */
-
- send_notify_field_values(printer_name, PRINTER_NOTIFY_TYPE,
- PRINTER_NOTIFY_STATUS, 0,
- status, 0, 0);
-}
-
-void notify_printer_status(int snum, uint32 status)
-{
- const char *printer_name = SERVICE(snum);
-
- if (printer_name)
- notify_printer_status_byname(printer_name, status);
-}
-
-void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 status,
- uint32 flags)
-{
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_STATUS, jobid,
- status, 0, flags);
-}
-
-void notify_job_status(int snum, uint32 jobid, uint32 status)
-{
- const char *printer_name = SERVICE(snum);
-
- notify_job_status_byname(printer_name, jobid, status, 0);
-}
-
-void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
-{
- const char *printer_name = SERVICE(snum);
-
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_TOTAL_BYTES, jobid,
- size, 0, 0);
-}
-
-void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
-{
- const char *printer_name = SERVICE(snum);
-
- /* Job id stored in id field, status in value1 */
-
- send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
- JOB_NOTIFY_TOTAL_PAGES, jobid,
- pages, 0, 0);
-}
-
-void notify_job_username(int snum, uint32 jobid, char *name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_name(int snum, uint32 jobid, char *name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
- jobid, strlen(name) + 1, name);
-}
-
-void notify_job_submitted(int snum, uint32 jobid, time_t submitted)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED,
- jobid, sizeof(submitted), (char *)&submitted);
-}
-
-void notify_printer_driver(int snum, char *driver_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,
- snum, strlen(driver_name) + 1, driver_name);
-}
-
-void notify_printer_comment(int snum, char *comment)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,
- snum, strlen(comment) + 1, comment);
-}
-
-void notify_printer_sharename(int snum, char *share_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
- snum, strlen(share_name) + 1, share_name);
-}
-
-void notify_printer_port(int snum, char *port_name)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,
- snum, strlen(port_name) + 1, port_name);
-}
-
-void notify_printer_location(int snum, char *location)
-{
- const char *printer_name = SERVICE(snum);
-
- send_notify_field_buffer(
- printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
- snum, strlen(location) + 1, location);
-}
-
-void notify_printer_byname( char *printername, uint32 change, char *value )
-{
- int snum = print_queue_snum(printername);
- int type = PRINTER_NOTIFY_TYPE;
-
- if ( snum == -1 )
- return;
-
- send_notify_field_buffer( printername, type, change, snum, strlen(value)+1, value );
-}
-
-
-/****************************************************************************
- Return a malloced list of pid_t's that are interested in getting update
- messages on this print queue. Used in printing/notify to send the messages.
-****************************************************************************/
-
-BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list)
-{
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- TDB_DATA data;
- BOOL ret = True;
- size_t i, num_pids, offset;
- pid_t *pid_list;
-
- *p_num_pids = 0;
- *pp_pid_list = NULL;
-
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
-
- if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- if (!data.dptr) {
- ret = True;
- goto done;
- }
-
- num_pids = data.dsize / 8;
-
- if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) {
- ret = False;
- goto done;
- }
-
- for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++)
- pid_list[i] = (pid_t)IVAL(data.dptr, offset);
-
- *pp_pid_list = pid_list;
- *p_num_pids = num_pids;
-
- ret = True;
-
- done:
-
- tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
diff --git a/source4/printing/pcap.c b/source4/printing/pcap.c
deleted file mode 100644
index c399c3c6cc..0000000000
--- a/source4/printing/pcap.c
+++ /dev/null
@@ -1,413 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- printcap parsing
- Copyright (C) Karl Auer 1993-1998
-
- Re-working by Martin Kiff, 1994
-
- Re-written again by Andrew Tridgell
-
- Modified for SVID support by Norm Jacobs, 1997
-
- Modified for CUPS support by Michael Sweet, 1999
-
- 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 02139, USA.
-*/
-
-/*
- * Parse printcap file.
- *
- * This module does exactly one thing - it looks into the printcap file
- * and tells callers if a specified string appears as a printer name.
- *
- * The way this module looks at the printcap file is very simplistic.
- * Only the local printcap file is inspected (no searching of NIS
- * databases etc).
- *
- * There are assumed to be one or more printer names per record, held
- * as a set of sub-fields separated by vertical bar symbols ('|') in the
- * first field of the record. The field separator is assumed to be a colon
- * ':' and the record separator a newline.
- *
- * Lines ending with a backspace '\' are assumed to flag that the following
- * line is a continuation line so that a set of lines can be read as one
- * printcap entry.
- *
- * A line stating with a hash '#' is assumed to be a comment and is ignored
- * Comments are discarded before the record is strung together from the
- * set of continuation lines.
- *
- * Opening a pipe for "lpc status" and reading that would probably
- * be pretty effective. Code to do this already exists in the freely
- * distributable PCNFS server code.
- *
- * Modified to call SVID/XPG4 support if printcap name is set to "lpstat"
- * in smb.conf under Solaris.
- *
- * Modified to call CUPS support if printcap name is set to "cups"
- * in smb.conf.
- */
-
-#include "includes.h"
-
-#ifdef AIX
-/* ******************************************
- Extend for AIX system and qconfig file
- from 'boulard@univ-rennes1.fr
- ****************************************** */
-static int strlocate(char *xpLine,char *xpS)
-{
- int iS,iL,iRet;
- char *p;
- iS = strlen(xpS);
- iL = strlen(xpLine);
-
- iRet = 0;
- p = xpLine;
- while (iL >= iS)
- {
- if (strncmp(p,xpS,iS) == 0) {iRet =1;break;};
- p++;
- iL--;
- }
- /*DEBUG(3,(" strlocate %s in line '%s',ret=%d\n",xpS,xpLine,iRet));*/
-
- return(iRet);
-}
-
-
-/* ******************************************************************* */
-/* * Scan qconfig and search all virtual printer (device printer) * */
-/* ******************************************************************* */
-static void ScanQconfig_fn(char *psz,void (*fn)(char *, char *))
-{
- int iEtat;
- XFILE *pfile;
- char *line,*p;
- pstring name,comment;
- line = NULL;
- *name = 0;
- *comment = 0;
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- return;
- }
-
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* locate an entry */
- if (*line == '\t' || *line == ' ') continue;
- if ((p=strchr_m(line,':')))
- {
- *p = '\0';
- p = strtok(line,":");
- if (strcmp(p,"bsh")!=0)
- {
- pstrcpy(name,p);
- iEtat = 1;
- continue;
- }
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- fn(name,comment);
- iEtat = 0;
- continue;
- }
- break;
- }
- }
- x_fclose(pfile);
-}
-
-/* Scan qconfig file and locate de printername */
-
-static BOOL ScanQconfig(char *psz,char *pszPrintername)
-{
- int iLg,iEtat;
- XFILE *pfile;
- char *pName;
- char *line;
-
- pName = NULL;
- line = NULL;
- if ((pszPrintername!= NULL) && ((iLg = strlen(pszPrintername)) > 0))
- pName = malloc(iLg+10);
- if (pName == NULL)
- {
- DEBUG(0,(" Unable to allocate memory for printer %s\n",pszPrintername));
- return(False);
- }
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open qconfig file %s for read!\n", psz));
- SAFE_FREE(pName);
- return(False);
- }
- slprintf(pName, iLg + 9, "%s:",pszPrintername);
- iLg = strlen(pName);
- /*DEBUG(3,( " Looking for entry %s\n",pName));*/
- iEtat = 0;
- /* scan qconfig file for searching <printername>: */
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '*' || *line == 0)
- continue;
- switch (iEtat)
- {
- case 0: /* scanning entry */
- if (strncmp(line,pName,iLg) == 0)
- {
- iEtat = 1;
- continue;
- }
- break;
- case 1: /* scanning device stanza */
- if (*line == '*' || *line == 0) continue;
- if (*line != '\t' && *line != ' ')
- {
- /* name is found without stanza device */
- /* probably a good printer ??? */
- free (line);
- SAFE_FREE(pName);
- fclose(pfile);
- return(True);
- }
-
- if (strlocate(line,"backend"))
- {
- /* it's a device, not a virtual printer*/
- iEtat = 0;
- }
- else if (strlocate(line,"device"))
- {
- /* it's a good virtual printer */
- free (line);
- SAFE_FREE(pName);
- fclose(pfile);
- return(True);
- }
- break;
- }
- }
- free (pName);
- x_fclose(pfile);
- return(False);
-}
-#endif /* AIX */
-
-
-/***************************************************************************
-Scan printcap file pszPrintcapname for a printer called pszPrintername.
-Return True if found, else False. Returns False on error, too, after logging
-the error at level 0. For generality, the printcap name may be passed - if
-passed as NULL, the configuration will be queried for the name.
-***************************************************************************/
-BOOL pcap_printername_ok(const char *pszPrintername, const char *pszPrintcapname)
-{
- char *line=NULL;
- const char *psz;
- char *p,*q;
- XFILE *pfile;
-
- if (pszPrintername == NULL || pszPrintername[0] == '\0')
- {
- DEBUG(0,( "Attempt to locate null printername! Internal error?\n"));
- return(False);
- }
-
- /* only go looking if no printcap name supplied */
- if ((psz = pszPrintcapname) == NULL || psz[0] == '\0')
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return(False);
- }
-
-#ifdef HAVE_CUPS
- if (strequal(psz, "cups"))
- return (cups_printername_ok(pszPrintername));
-#endif /* HAVE_CUPS */
-
-#ifdef SYSV
- if (strequal(psz, "lpstat"))
- return (sysv_printername_ok(pszPrintername));
-#endif
-
-#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- return(ScanQconfig(psz,pszPrintername));
-#endif
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return(False);
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
-
- /* now just check if the name is in the list */
- /* NOTE: I avoid strtok as the fn calling this one may be using it */
- for (p=line; p; p=q)
- {
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- if (strequal(p,pszPrintername))
- {
- SAFE_FREE(line);
- x_fclose(pfile);
- return(True);
- }
- p = q;
- }
- }
-
- x_fclose(pfile);
- return(False);
-}
-
-
-/***************************************************************************
-run a function on each printer name in the printcap file. The function is
-passed the primary name and the comment (if possible). Note the fn() takes
-strings in DOS codepage. This means the xxx_printer_fn() calls must be fixed
-to return DOS codepage. FIXME !! JRA.
-***************************************************************************/
-void pcap_printer_fn(void (*fn)(char *, char *))
-{
- pstring name,comment;
- char *line;
- char *psz;
- char *p,*q;
- XFILE *pfile;
-
- /* only go looking if no printcap name supplied */
- if (((psz = lp_printcapname()) == NULL) || (psz[0] == '\0'))
- {
- DEBUG(0,( "No printcap file name configured!\n"));
- return;
- }
-
-#ifdef HAVE_CUPS
- if (strequal(psz, "cups")) {
- cups_printer_fn(fn);
- return;
- }
-#endif /* HAVE_CUPS */
-
-#ifdef SYSV
- if (strequal(psz, "lpstat")) {
- sysv_printer_fn(fn);
- return;
- }
-#endif
-
-#ifdef AIX
- if (strlocate(psz,"/qconfig"))
- {
- ScanQconfig_fn(psz,fn);
- return;
- }
-#endif
-
- if ((pfile = x_fopen(psz, O_RDONLY, 0)) == NULL)
- {
- DEBUG(0,( "Unable to open printcap file %s for read!\n", psz));
- return;
- }
-
- for (;(line = fgets_slash(NULL,sizeof(pstring),pfile)); safe_free(line))
- {
- if (*line == '#' || *line == 0)
- continue;
-
- /* now we have a real printer line - cut it off at the first : */
- p = strchr_m(line,':');
- if (p) *p = 0;
-
- /* now find the most likely printer name and comment
- this is pure guesswork, but it's better than nothing */
- *name = 0;
- *comment = 0;
- for (p=line; p; p=q)
- {
- BOOL has_punctuation;
- if ((q = strchr_m(p,'|'))) *q++ = 0;
-
- has_punctuation = (strchr_m(p,' ') || strchr_m(p,'\t') || strchr_m(p,'(') || strchr_m(p,')'));
-
- if (strlen(p)>strlen(comment) && has_punctuation)
- {
- StrnCpy(comment,p,sizeof(comment)-1);
- continue;
- }
-
- if (strlen(p) <= MAXPRINTERLEN && strlen(p)>strlen(name) && !has_punctuation)
- {
- if (!*comment) pstrcpy(comment,name);
- pstrcpy(name,p);
- continue;
- }
-
- if (!strchr_m(comment,' ') &&
- strlen(p) > strlen(comment))
- {
- StrnCpy(comment,p,sizeof(comment)-1);
- continue;
- }
- }
-
- comment[60] = 0;
- name[MAXPRINTERLEN] = 0;
-
- if (*name)
- fn(name,comment);
- }
- x_fclose(pfile);
-}
diff --git a/source4/printing/print_cups.c b/source4/printing/print_cups.c
deleted file mode 100644
index 7cf21c966e..0000000000
--- a/source4/printing/print_cups.c
+++ /dev/null
@@ -1,1293 +0,0 @@
-/*
- * Support code for the Common UNIX Printing System ("CUPS")
- *
- * Copyright 1999-2003 by Michael R Sweet.
- *
- * 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 02139, USA.
- */
-
-#include "printing.h"
-
-#ifdef HAVE_CUPS
-#include <cups/cups.h>
-#include <cups/language.h>
-
-
-/*
- * CUPS printing interface definitions...
- */
-
-static int cups_job_delete(int snum, struct printjob *pjob);
-static int cups_job_pause(int snum, struct printjob *pjob);
-static int cups_job_resume(int snum, struct printjob *pjob);
-static int cups_job_submit(int snum, struct printjob *pjob);
-static int cups_queue_get(int snum, print_queue_struct **q,
- print_status_struct *status);
-static int cups_queue_pause(int snum);
-static int cups_queue_resume(int snum);
-
-
-struct printif cups_printif =
- {
- cups_queue_get,
- cups_queue_pause,
- cups_queue_resume,
- cups_job_delete,
- cups_job_pause,
- cups_job_resume,
- cups_job_submit,
- };
-
-/*
- * 'cups_passwd_cb()' - The CUPS password callback...
- */
-
-static const char * /* O - Password or NULL */
-cups_passwd_cb(const char *prompt) /* I - Prompt */
-{
- /*
- * Always return NULL to indicate that no password is available...
- */
-
- return (NULL);
-}
-
-
-/*
- * 'cups_printer_fn()' - Call a function for every printer known to the
- * system.
- */
-
-void cups_printer_fn(void (*fn)(char *, char *))
-{
- /* I - Function to call */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
- char *name, /* printer-name attribute */
- *make_model, /* printer-make-and-model attribute */
- *info; /* printer-info attribute */
- static const char *requested[] =/* Requested attributes */
- {
- "printer-name",
- "printer-make-and-model",
- "printer-info"
- };
-
-
- DEBUG(5,("cups_printer_fn(%p)\n", fn));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return;
- }
-
- /*
- * Build a CUPS_GET_PRINTERS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- */
-
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_PRINTERS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(requested) / sizeof(requested[0])),
- NULL, requested);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(cupsLastError())));
- httpClose(http);
- return;
- }
-
- for (attr = response->attrs; attr != NULL;)
- {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- name = NULL;
- make_model = NULL;
- info = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-info") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- info = attr->values[0].string.text;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (name == NULL)
- break;
-
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
- }
-
- ippDelete(response);
-
-
- /*
- * Build a CUPS_GET_CLASSES request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- */
-
- request = ippNew();
-
- request->request.op.operation_id = CUPS_GET_CLASSES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(requested) / sizeof(requested[0])),
- NULL, requested);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get printer list - %s\n",
- ippErrorString(cupsLastError())));
- httpClose(http);
- return;
- }
-
- for (attr = response->attrs; attr != NULL;)
- {
- /*
- * Skip leading attributes until we hit a printer...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Pull the needed attributes from this printer...
- */
-
- name = NULL;
- make_model = NULL;
- info = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
- {
- if (strcmp(attr->name, "printer-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-make-and-model") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- make_model = attr->values[0].string.text;
-
- if (strcmp(attr->name, "printer-info") == 0 &&
- attr->value_tag == IPP_TAG_TEXT)
- info = attr->values[0].string.text;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (name == NULL)
- break;
-
- if (info == NULL || !info[0])
- (*fn)(name, make_model);
- else
- (*fn)(name, info);
-
-
- }
-
- ippDelete(response);
-
- /*
- * Close the connection to the server...
- */
-
- httpClose(http);
-}
-
-
-/*
- * 'cups_printername_ok()' - Provide the equivalent of pcap_printername_ok()
- * for CUPS.
- * O - 1 if printer name OK
- * I - Name of printer
- */
-int cups_printername_ok(const char *name)
-{
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_printername_ok(\"%s\")\n", name));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(3,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (0);
- }
-
- /*
- * Build an IPP_GET_PRINTER_ATTRS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes", NULL, "printer-uri");
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", name);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(cupsLastError())));
- httpClose(http);
- return (0);
- }
-
- httpClose(http);
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(3,("Unable to get printer status for %s - %s\n", name,
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- return (0);
- }
- else
- {
- ippDelete(response);
- return (1);
- }
-}
-
-
-/*
- * 'cups_job_delete()' - Delete a job.
- */
-
-static int
-cups_job_delete(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_delete(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_CANCEL_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_CANCEL_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to cancel job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_job_pause()' - Pause a job.
- */
-
-static int
-cups_job_pause(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_HOLD_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_HOLD_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to hold job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_job_resume()' - Resume a paused job.
- */
-
-static int
-cups_job_resume(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_RELEASE_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * job-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_RELEASE_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/jobs/%d", pjob->sysjob);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob,
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_job_submit()' - Submit a job for printing.
- */
-
-static int
-cups_job_submit(int snum, struct printjob *pjob)
-{
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_PRINT_JOB request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- * [document-data]
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_PRINT_JOB;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, pjob->user);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "job-originating-host-name", NULL,
- get_remote_machine_name());
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL,
- pjob->jobname);
-
- /*
- * Do the request and get back a response...
- */
-
- slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum));
-
- ret = 1;
- if ((response = cupsDoFileRequest(http, request, uri,
- pjob->filename)) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to print file to `%s' - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- if ( ret == 0 )
- unlink(pjob->filename);
- /* else print_job_end will do it for us */
-
- return (ret);
-}
-
-
-/*
- * 'cups_queue_get()' - Get all the jobs in the print queue.
- */
-
-static int
-cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
-{
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- ipp_attribute_t *attr; /* Current attribute */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- int qcount, /* Number of active queue entries */
- qalloc; /* Number of queue entries allocated */
- print_queue_struct *queue, /* Queue entries */
- *temp; /* Temporary pointer for queue */
- const char *user_name, /* job-originating-user-name attribute */
- *job_name; /* job-name attribute */
- int job_id; /* job-id attribute */
- int job_k_octets; /* job-k-octets attribute */
- time_t job_time; /* time-at-creation attribute */
- ipp_jstate_t job_status; /* job-status attribute */
- int job_priority; /* job-priority attribute */
- static const char *jattrs[] = /* Requested job attributes */
- {
- "job-id",
- "job-k-octets",
- "job-name",
- "job-originating-user-name",
- "job-priority",
- "job-state",
- "time-at-creation",
- };
- static const char *pattrs[] = /* Requested printer attributes */
- {
- "printer-state",
- "printer-state-message"
- };
-
-
- DEBUG(5,("cups_queue_get(%d, %p, %p)\n", snum, q, status));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (0);
- }
-
- /*
- * Generate the printer URI...
- */
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- /*
- * Build an IPP_GET_JOBS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_JOBS;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(jattrs) / sizeof(jattrs[0])),
- NULL, jattrs);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(cupsLastError())));
- httpClose(http);
- return (0);
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(0,("Unable to get jobs for %s - %s\n", uri,
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- httpClose(http);
-
- return (0);
- }
-
- /*
- * Process the jobs...
- */
-
- qcount = 0;
- qalloc = 0;
- queue = NULL;
-
- for (attr = response->attrs; attr != NULL; attr = attr->next)
- {
- /*
- * Skip leading attributes until we hit a job...
- */
-
- while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
- attr = attr->next;
-
- if (attr == NULL)
- break;
-
- /*
- * Allocate memory as needed...
- */
- if (qcount >= qalloc)
- {
- qalloc += 16;
-
- temp = Realloc(queue, sizeof(print_queue_struct) * qalloc);
-
- if (temp == NULL)
- {
- DEBUG(0,("cups_queue_get: Not enough memory!"));
- ippDelete(response);
- httpClose(http);
-
- SAFE_FREE(queue);
- return (0);
- }
-
- queue = temp;
- }
-
- temp = queue + qcount;
- memset(temp, 0, sizeof(print_queue_struct));
-
- /*
- * Pull the needed attributes from this job...
- */
-
- job_id = 0;
- job_priority = 50;
- job_status = IPP_JOB_PENDING;
- job_time = 0;
- job_k_octets = 0;
- user_name = NULL;
- job_name = NULL;
-
- while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
- {
- if (attr->name == NULL)
- {
- attr = attr->next;
- break;
- }
-
- if (strcmp(attr->name, "job-id") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_id = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-k-octets") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_k_octets = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-priority") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_priority = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-state") == 0 &&
- attr->value_tag == IPP_TAG_ENUM)
- job_status = (ipp_jstate_t)(attr->values[0].integer);
-
- if (strcmp(attr->name, "time-at-creation") == 0 &&
- attr->value_tag == IPP_TAG_INTEGER)
- job_time = attr->values[0].integer;
-
- if (strcmp(attr->name, "job-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- job_name = attr->values[0].string.text;
-
- if (strcmp(attr->name, "job-originating-user-name") == 0 &&
- attr->value_tag == IPP_TAG_NAME)
- user_name = attr->values[0].string.text;
-
- attr = attr->next;
- }
-
- /*
- * See if we have everything needed...
- */
-
- if (user_name == NULL || job_name == NULL || job_id == 0)
- {
- if (attr == NULL)
- break;
- else
- continue;
- }
-
- temp->job = job_id;
- temp->size = job_k_octets * 1024;
- temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED :
- job_status == IPP_JOB_STOPPED ? LPQ_PAUSED :
- job_status == IPP_JOB_HELD ? LPQ_PAUSED :
- LPQ_PRINTING;
- temp->priority = job_priority;
- temp->time = job_time;
- strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1);
- strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1);
-
- qcount ++;
-
- if (attr == NULL)
- break;
- }
-
- ippDelete(response);
-
- /*
- * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
- * following attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * requested-attributes
- * printer-uri
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
- "requested-attributes",
- (sizeof(pattrs) / sizeof(pattrs[0])),
- NULL, pattrs);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
- "printer-uri", NULL, uri);
-
- /*
- * Do the request and get back a response...
- */
-
- if ((response = cupsDoRequest(http, request, "/")) == NULL)
- {
- DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- httpClose(http);
- *q = queue;
- return (qcount);
- }
-
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- {
- DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
- ippErrorString(response->request.status.status_code)));
- ippDelete(response);
- httpClose(http);
- *q = queue;
- return (qcount);
- }
-
- /*
- * Get the current printer status and convert it to the SAMBA values.
- */
-
- if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
- {
- if (attr->values[0].integer == IPP_PRINTER_STOPPED)
- status->status = LPSTAT_STOPPED;
- else
- status->status = LPSTAT_OK;
- }
-
- if ((attr = ippFindAttribute(response, "printer-state-message",
- IPP_TAG_TEXT)) != NULL)
- fstrcpy(status->message, attr->values[0].string.text);
-
- ippDelete(response);
-
- /*
- * Return the job queue...
- */
-
- httpClose(http);
-
- *q = queue;
- return (qcount);
-}
-
-
-/*
- * 'cups_queue_pause()' - Pause a print queue.
- */
-
-static int
-cups_queue_pause(int snum)
-{
- extern userdom_struct current_user_info;
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_queue_pause(%d)\n", snum));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_PAUSE_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_PAUSE_PRINTER;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, current_user_info.unix_name);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to pause printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-/*
- * 'cups_queue_resume()' - Restart a print queue.
- */
-
-static int
-cups_queue_resume(int snum)
-{
- extern userdom_struct current_user_info;
- int ret; /* Return value */
- http_t *http; /* HTTP connection to server */
- ipp_t *request, /* IPP Request */
- *response; /* IPP Response */
- cups_lang_t *language; /* Default language */
- char uri[HTTP_MAX_URI]; /* printer-uri attribute */
-
-
- DEBUG(5,("cups_queue_resume(%d)\n", snum));
-
- /*
- * Make sure we don't ask for passwords...
- */
-
- cupsSetPasswordCB(cups_passwd_cb);
-
- /*
- * Try to connect to the server...
- */
-
- if ((http = httpConnect(cupsServer(), ippPort())) == NULL)
- {
- DEBUG(0,("Unable to connect to CUPS server %s - %s\n",
- cupsServer(), strerror(errno)));
- return (1);
- }
-
- /*
- * Build an IPP_RESUME_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name
- */
-
- request = ippNew();
-
- request->request.op.operation_id = IPP_RESUME_PRINTER;
- request->request.op.request_id = 1;
-
- language = cupsLangDefault();
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, cupsLangEncoding(language));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, language->language);
-
- slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
- PRINTERNAME(snum));
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
-
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
- NULL, current_user_info.unix_name);
-
- /*
- * Do the request and get back a response...
- */
-
- ret = 1;
-
- if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
- {
- if (response->request.status.status_code >= IPP_OK_CONFLICT)
- DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
- else
- ret = 0;
-
- ippDelete(response);
- }
- else
- DEBUG(0,("Unable to resume printer %s - %s\n", PRINTERNAME(snum),
- ippErrorString(cupsLastError())));
-
- httpClose(http);
-
- return (ret);
-}
-
-
-#else
- /* this keeps fussy compilers happy */
- void print_cups_dummy(void) {}
-#endif /* HAVE_CUPS */
diff --git a/source4/printing/print_generic.c b/source4/printing/print_generic.c
deleted file mode 100644
index aae2844ded..0000000000
--- a/source4/printing/print_generic.c
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- printing command routines
- Copyright (C) Andrew Tridgell 1992-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 02139, USA.
-*/
-
-#include "printing.h"
-
-
-/*
- * Generic printing interface definitions...
- */
-
-static int generic_job_delete(int snum, struct printjob *pjob);
-static int generic_job_pause(int snum, struct printjob *pjob);
-static int generic_job_resume(int snum, struct printjob *pjob);
-static int generic_job_submit(int snum, struct printjob *pjob);
-static int generic_queue_get(int snum, print_queue_struct **q,
- print_status_struct *status);
-static int generic_queue_pause(int snum);
-static int generic_queue_resume(int snum);
-
-
-struct printif generic_printif =
- {
- generic_queue_get,
- generic_queue_pause,
- generic_queue_resume,
- generic_job_delete,
- generic_job_pause,
- generic_job_resume,
- generic_job_submit,
- };
-
-/****************************************************************************
-run a given print command
-a null terminated list of value/substitute pairs is provided
-for local substitution strings
-****************************************************************************/
-static int print_run_command(int snum,char *command, int *outfd, ...)
-{
-
- pstring syscmd;
- char *arg;
- int ret;
- va_list ap;
- va_start(ap, outfd);
-
- if (!command || !*command) return -1;
-
- if (!VALID_SNUM(snum)) {
- DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
- return -1;
- }
-
- pstrcpy(syscmd, command);
-
- while ((arg = va_arg(ap, char *))) {
- char *value = va_arg(ap,char *);
- pstring_sub(syscmd, arg, value);
- }
- va_end(ap);
-
- pstring_sub(syscmd, "%p", PRINTERNAME(snum));
- standard_sub_snum(snum,syscmd,sizeof(syscmd));
-
- ret = smbrun(syscmd,outfd);
-
- DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
-
- return ret;
-}
-
-
-/****************************************************************************
-delete a print job
-****************************************************************************/
-static int generic_job_delete(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to delete the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(
- snum,
- lp_lprmcommand(snum), NULL,
- "%j", jobstr,
- "%T", timestring(pjob->starttime),
- NULL);
-}
-
-/****************************************************************************
-pause a job
-****************************************************************************/
-static int generic_job_pause(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to pause the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum,
- lp_lppausecommand(snum), NULL,
- "%j", jobstr,
- NULL);
-}
-
-/****************************************************************************
-resume a job
-****************************************************************************/
-static int generic_job_resume(int snum, struct printjob *pjob)
-{
- fstring jobstr;
-
- /* need to pause the spooled entry */
- slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum,
- lp_lpresumecommand(snum), NULL,
- "%j", jobstr,
- NULL);
-}
-
-/****************************************************************************
- Submit a file for printing - called from print_job_end()
-****************************************************************************/
-
-static int generic_job_submit(int snum, struct printjob *pjob)
-{
- int ret;
- pstring current_directory;
- pstring print_directory;
- char *wd, *p;
- pstring jobname;
- fstring job_page_count, job_size;
-
- /* we print from the directory path to give the best chance of
- parsing the lpq output */
- wd = sys_getwd(current_directory);
- if (!wd)
- return 0;
-
- pstrcpy(print_directory, pjob->filename);
- p = strrchr_m(print_directory,'/');
- if (!p)
- return 0;
- *p++ = 0;
-
- if (chdir(print_directory) != 0)
- return 0;
-
- pstrcpy(jobname, pjob->jobname);
- pstring_sub(jobname, "'", "_");
- slprintf(job_page_count, sizeof(job_page_count)-1, "%d", pjob->page_count);
- slprintf(job_size, sizeof(job_size)-1, "%d", pjob->size);
-
- /* send it to the system spooler */
- ret = print_run_command(snum,
- lp_printcommand(snum), NULL,
- "%s", p,
- "%J", jobname,
- "%f", p,
- "%z", job_size,
- "%c", job_page_count,
- NULL);
-
- chdir(wd);
-
- return ret;
-}
-
-
-/****************************************************************************
-get the current list of queued jobs
-****************************************************************************/
-static int generic_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
-{
- char **qlines;
- int fd;
- int numlines, i, qcount;
- print_queue_struct *queue = NULL;
- fstring printer_name;
-
- fstrcpy(printer_name, lp_servicename(snum));
-
- print_run_command(snum, lp_lpqcommand(snum), &fd, NULL);
-
- if (fd == -1) {
- DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
- printer_name ));
- return 0;
- }
-
- numlines = 0;
- qlines = fd_lines_load(fd, &numlines);
- close(fd);
-
- /* turn the lpq output into a series of job structures */
- qcount = 0;
- ZERO_STRUCTP(status);
- if (numlines)
- queue = (print_queue_struct *)malloc(sizeof(print_queue_struct)*(numlines+1));
-
- if (queue) {
- for (i=0; i<numlines; i++) {
- /* parse the line */
- if (parse_lpq_entry(snum,qlines[i],
- &queue[qcount],status,qcount==0)) {
- qcount++;
- }
- }
- }
- file_lines_free(qlines);
-
- *q = queue;
- return qcount;
-}
-
-/****************************************************************************
- pause a queue
-****************************************************************************/
-static int generic_queue_pause(int snum)
-{
- return print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL);
-}
-
-/****************************************************************************
- resume a queue
-****************************************************************************/
-static int generic_queue_resume(int snum)
-{
- return print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL);
-}
diff --git a/source4/printing/print_svid.c b/source4/printing/print_svid.c
deleted file mode 100644
index 07b157bcd9..0000000000
--- a/source4/printing/print_svid.c
+++ /dev/null
@@ -1,144 +0,0 @@
-/*
- * Copyright (C) 1997-1998 by Norm Jacobs, Colorado Springs, Colorado, USA
- * Copyright (C) 1997-1998 by Sun Microsystem, Inc.
- * All Rights Reserved
- *
- * 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 02139, USA.
- */
-
-/*
- * This module implements support for gathering and comparing available
- * printer information on a SVID or XPG4 compliant system. It does this
- * through the use of the SVID/XPG4 command "lpstat(1)".
- *
- * The expectations is that execution of the command "lpstat -v" will
- * generate responses in the form of:
- *
- * device for serial: /dev/term/b
- * system for fax: server
- * system for color: server (as printer chroma)
- */
-
-
-#include "includes.h"
-
-#ifdef SYSV
-
-typedef struct printer {
- char *name;
- struct printer *next;
-} printer_t;
-static printer_t *printers = NULL;
-
-static void populate_printers(void)
-{
- char **lines;
- int i;
-
- lines = file_lines_pload("/usr/bin/lpstat -v", NULL);
- if (!lines) return;
-
- for (i=0;lines[i];i++) {
- printer_t *ptmp;
- char *name, *tmp;
- char *buf = lines[i];
-
- /* eat "system/device for " */
- if (((tmp = strchr_m(buf, ' ')) == NULL) ||
- ((tmp = strchr_m(++tmp, ' ')) == NULL))
- continue;
-
- /*
- * In case we're only at the "for ".
- */
-
- if(!strncmp("for ",++tmp,4)) {
- tmp=strchr_m(tmp, ' ');
- tmp++;
- }
-
- /* Eat whitespace. */
-
- while(*tmp == ' ')
- ++tmp;
-
- /*
- * On HPUX there is an extra line that can be ignored.
- * d.thibadeau 2001/08/09
- */
- if(!strncmp("remote to",tmp,9))
- continue;
-
- name = tmp;
-
- /* truncate the ": ..." */
- if ((tmp = strchr_m(name, ':')) != NULL)
- *tmp = '\0';
-
- /* add it to the cache */
- if ((ptmp = malloc(sizeof (*ptmp))) != NULL) {
- ZERO_STRUCTP(ptmp);
- if((ptmp->name = strdup(name)) == NULL)
- DEBUG(0,("populate_printers: malloc fail in strdup !\n"));
- ptmp->next = printers;
- printers = ptmp;
- } else {
- DEBUG(0,("populate_printers: malloc fail for ptmp\n"));
- }
- }
-
- file_lines_free(lines);
-}
-
-
-/*
- * provide the equivalent of pcap_printer_fn() for SVID/XPG4 conforming
- * systems. It was unclear why pcap_printer_fn() was tossing names longer
- * than 8 characters. I suspect that its a protocol limit, but amazingly
- * names longer than 8 characters appear to work with my test
- * clients (Win95/NT).
- */
-void sysv_printer_fn(void (*fn)(char *, char *))
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- (fn)(tmp->name, "");
-}
-
-
-/*
- * provide the equivalent of pcap_printername_ok() for SVID/XPG4 conforming
- * systems.
- */
-int sysv_printername_ok(const char *name)
-{
- printer_t *tmp;
-
- if (printers == NULL)
- populate_printers();
- for (tmp = printers; tmp != NULL; tmp = tmp->next)
- if (strcmp(tmp->name, name) == 0)
- return (True);
- return (False);
-}
-
-#else
-/* this keeps fussy compilers happy */
- void print_svid_dummy(void);
- void print_svid_dummy(void) {}
-#endif
diff --git a/source4/printing/printfsp.c b/source4/printing/printfsp.c
deleted file mode 100644
index 5d230f8be4..0000000000
--- a/source4/printing/printfsp.c
+++ /dev/null
@@ -1,120 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- printing backend routines for smbd - using files_struct rather
- than only snum
- Copyright (C) Andrew Tridgell 1992-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 02139, USA.
-*/
-
-#include "includes.h"
-
-/***************************************************************************
-open a print file and setup a fsp for it. This is a wrapper around
-print_job_start().
-***************************************************************************/
-
-files_struct *print_fsp_open(struct tcon_context *conn, char *fname)
-{
- int jobid;
- SMB_STRUCT_STAT sbuf;
- extern struct current_user current_user;
- files_struct *fsp = file_new(conn);
- fstring name;
-
- if(!fsp)
- return NULL;
-
- fstrcpy( name, "Remote Downlevel Document");
- if (fname) {
- char *p = strrchr(fname, '/');
- fstrcat(name, " ");
- if (!p)
- p = fname;
- fstrcat(name, p);
- }
-
- jobid = print_job_start(&current_user, SNUM(conn), name, NULL);
- if (jobid == -1) {
- file_free(fsp);
- return NULL;
- }
-
- /* Convert to RAP id. */
- fsp->rap_print_jobid = pjobid_to_rap(SNUM(conn), jobid);
- if (fsp->rap_print_jobid == 0) {
- /* We need to delete the entry in the tdb. */
- pjob_delete(SNUM(conn), jobid);
- file_free(fsp);
- return NULL;
- }
-
- /* setup a full fsp */
- fsp->fd = print_job_fd(SNUM(conn),jobid);
- GetTimeOfDay(&fsp->open_time);
- fsp->vuid = current_user.vuid;
- fsp->size = 0;
- fsp->pos = -1;
- fsp->can_lock = True;
- fsp->can_read = False;
- fsp->can_write = True;
- fsp->share_mode = 0;
- fsp->print_file = True;
- fsp->modified = False;
- fsp->oplock_type = NO_OPLOCK;
- fsp->sent_oplock_break = NO_BREAK_SENT;
- fsp->is_directory = False;
- fsp->directory_delete_on_close = False;
- string_set(&fsp->fsp_name,print_job_fname(SNUM(conn),jobid));
- fsp->wbmpx_ptr = NULL;
- fsp->wcp = NULL;
- conn->vfs_ops.fstat(fsp,fsp->fd, &sbuf);
- fsp->mode = sbuf.st_mode;
- fsp->inode = sbuf.st_ino;
- fsp->dev = sbuf.st_dev;
-
- conn->num_files_open++;
-
- return fsp;
-}
-
-/****************************************************************************
-print a file - called on closing the file
-****************************************************************************/
-void print_fsp_end(files_struct *fsp, BOOL normal_close)
-{
- uint32 jobid;
- int snum;
-
- if (fsp->share_mode == FILE_DELETE_ON_CLOSE) {
- /*
- * Truncate the job. print_job_end will take
- * care of deleting it for us. JRA.
- */
- sys_ftruncate(fsp->fd, 0);
- }
-
- if (fsp->fsp_name) {
- string_free(&fsp->fsp_name);
- }
-
- if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) {
- DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n",
- (unsigned int)fsp->rap_print_jobid ));
- return;
- }
-
- print_job_end(SNUM(fsp->conn),jobid, normal_close);
-}
diff --git a/source4/printing/printing.c b/source4/printing/printing.c
deleted file mode 100644
index e4d9e5f785..0000000000
--- a/source4/printing/printing.c
+++ /dev/null
@@ -1,2128 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 2002
-
- 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 02139, USA.
-*/
-
-#include "printing.h"
-
-/* Current printer interface */
-static struct printif *current_printif = &generic_printif;
-
-/*
- the printing backend revolves around a tdb database that stores the
- SMB view of the print queue
-
- The key for this database is a jobid - a internally generated number that
- uniquely identifies a print job
-
- reading the print queue involves two steps:
- - possibly running lpq and updating the internal database from that
- - reading entries from the database
-
- jobids are assigned when a job starts spooling.
-*/
-
-/***************************************************************************
- Nightmare. LANMAN jobid's are 16 bit numbers..... We must map them to 32
- bit RPC jobids.... JRA.
-***************************************************************************/
-
-static TDB_CONTEXT *rap_tdb;
-static uint16 next_rap_jobid;
-
-uint16 pjobid_to_rap(int snum, uint32 jobid)
-{
- uint16 rap_jobid;
- TDB_DATA data, key;
- char jinfo[8];
-
- DEBUG(10,("pjobid_to_rap: called.\n"));
-
- if (!rap_tdb) {
- /* Create the in-memory tdb. */
- rap_tdb = tdb_open_log(NULL, 0, TDB_INTERNAL, (O_RDWR|O_CREAT), 0644);
- if (!rap_tdb)
- return 0;
- }
-
- SIVAL(&jinfo,0,(int32)snum);
- SIVAL(&jinfo,4,jobid);
-
- key.dptr = (char *)&jinfo;
- key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
- if (data.dptr && data.dsize == sizeof(uint16)) {
- memcpy(&rap_jobid, data.dptr, sizeof(uint16));
- SAFE_FREE(data.dptr);
- DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid,
- (unsigned int)rap_jobid));
- return rap_jobid;
- }
- SAFE_FREE(data.dptr);
- /* Not found - create and store mapping. */
- rap_jobid = ++next_rap_jobid;
- if (rap_jobid == 0)
- rap_jobid = ++next_rap_jobid;
- data.dptr = (char *)&rap_jobid;
- data.dsize = sizeof(rap_jobid);
- tdb_store(rap_tdb, key, data, TDB_REPLACE);
- tdb_store(rap_tdb, data, key, TDB_REPLACE);
-
- DEBUG(10,("pjobid_to_rap: created jobid %u maps to RAP jobid %u\n",
- (unsigned int)jobid,
- (unsigned int)rap_jobid));
- return rap_jobid;
-}
-
-BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
-{
- TDB_DATA data, key;
-
- DEBUG(10,("rap_to_pjobid called.\n"));
-
- if (!rap_tdb)
- return False;
-
- key.dptr = (char *)&rap_jobid;
- key.dsize = sizeof(rap_jobid);
- data = tdb_fetch(rap_tdb, key);
- if (data.dptr && data.dsize == 8) {
- *psnum = IVAL(data.dptr,0);
- *pjobid = IVAL(data.dptr,4);
- DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
- (unsigned int)*pjobid,
- (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return True;
- }
-
- DEBUG(10,("rap_to_pjobid: Failed to lookup RAP jobid %u\n",
- (unsigned int)rap_jobid));
- SAFE_FREE(data.dptr);
- return False;
-}
-
-static void rap_jobid_delete(int snum, uint32 jobid)
-{
- TDB_DATA key, data;
- uint16 rap_jobid;
- char jinfo[8];
-
- DEBUG(10,("rap_jobid_delete: called.\n"));
-
- if (!rap_tdb)
- return;
-
- SIVAL(&jinfo,0,(int32)snum);
- SIVAL(&jinfo,4,jobid);
-
- key.dptr = (char *)&jinfo;
- key.dsize = sizeof(jinfo);
- data = tdb_fetch(rap_tdb, key);
- if (!data.dptr || (data.dsize != sizeof(uint16))) {
- DEBUG(10,("rap_jobid_delete: cannot find jobid %u\n",
- (unsigned int)jobid ));
- SAFE_FREE(data.dptr);
- return;
- }
-
- DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
- (unsigned int)jobid ));
-
- memcpy(&rap_jobid, data.dptr, sizeof(uint16));
- SAFE_FREE(data.dptr);
- data.dptr = (char *)&rap_jobid;
- data.dsize = sizeof(rap_jobid);
- tdb_delete(rap_tdb, key);
- tdb_delete(rap_tdb, data);
-}
-
-static pid_t local_pid;
-
-static int get_queue_status(int, print_status_struct *);
-
-/****************************************************************************
- Initialise the printing backend. Called once at startup before the fork().
-****************************************************************************/
-
-BOOL print_backend_init(void)
-{
- const char *sversion = "INFO/version";
- pstring printing_path;
- int services = lp_numservices();
- int snum;
-
- if (local_pid == sys_getpid())
- return True;
-
- unlink(lock_path("printing.tdb"));
- pstrcpy(printing_path,lock_path("printing"));
- mkdir(printing_path,0755);
-
- local_pid = sys_getpid();
-
- /* handle a Samba upgrade */
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
-
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (!pdb)
- continue;
- if (tdb_lock_bystring(pdb->tdb, sversion, 0) == -1) {
- DEBUG(0,("print_backend_init: Failed to open printer %s database\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
- return False;
- }
- if (tdb_fetch_int32(pdb->tdb, sversion) != PRINT_DATABASE_VERSION) {
- tdb_traverse(pdb->tdb, tdb_traverse_delete_fn, NULL);
- tdb_store_int32(pdb->tdb, sversion, PRINT_DATABASE_VERSION);
- }
- tdb_unlock_bystring(pdb->tdb, sversion);
- release_print_db(pdb);
- }
-
- close_all_print_db(); /* Don't leave any open. */
-
- /* select the appropriate printing interface... */
-#ifdef HAVE_CUPS
- if (strcmp(lp_printcapname(), "cups") == 0)
- current_printif = &cups_printif;
-#endif /* HAVE_CUPS */
-
- /* do NT print initialization... */
- return nt_printing_init();
-}
-
-/****************************************************************************
- Shut down printing backend. Called once at shutdown to close the tdb.
-****************************************************************************/
-
-void printing_end(void)
-{
- close_all_print_db(); /* Don't leave any open. */
-}
-
-/****************************************************************************
- Useful function to generate a tdb key.
-****************************************************************************/
-
-static TDB_DATA print_key(uint32 jobid)
-{
- static uint32 j;
- TDB_DATA ret;
-
- j = jobid;
- ret.dptr = (void *)&j;
- ret.dsize = sizeof(j);
- return ret;
-}
-
-/***********************************************************************
- unpack a pjob from a tdb buffer
-***********************************************************************/
-
-int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
-{
- int len = 0;
- int used;
-
- if ( !buf || !pjob )
- return -1;
-
- len += tdb_unpack(buf+len, buflen-len, "dddddddddffff",
- &pjob->pid,
- &pjob->sysjob,
- &pjob->fd,
- &pjob->starttime,
- &pjob->status,
- &pjob->size,
- &pjob->page_count,
- &pjob->spooled,
- &pjob->smbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- if ( len == -1 )
- return -1;
-
- if ( (used = unpack_devicemode(&pjob->nt_devmode, buf+len, buflen-len)) == -1 )
- return -1;
-
- len += used;
-
- return len;
-
-}
-
-/****************************************************************************
- Useful function to find a print job in the database.
-****************************************************************************/
-
-static struct printjob *print_job_find(int snum, uint32 jobid)
-{
- static struct printjob pjob;
- TDB_DATA ret;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
-
-
- if (!pdb)
- return NULL;
-
- ret = tdb_fetch(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
-
- if (!ret.dptr)
- return NULL;
-
- if ( pjob.nt_devmode )
- free_nt_devicemode( &pjob.nt_devmode );
-
- ZERO_STRUCT( pjob );
-
- if ( unpack_pjob( ret.dptr, ret.dsize, &pjob ) == -1 ) {
- SAFE_FREE(ret.dptr);
- return NULL;
- }
-
- SAFE_FREE(ret.dptr);
- return &pjob;
-}
-
-/* Convert a unix jobid to a smb jobid */
-
-static uint32 sysjob_to_jobid_value;
-
-static int unixjob_traverse_fn(TDB_CONTEXT *the_tdb, TDB_DATA key,
- TDB_DATA data, void *state)
-{
- struct printjob *pjob;
- int *sysjob = (int *)state;
-
- if (!data.dptr || data.dsize == 0)
- return 0;
-
- pjob = (struct printjob *)data.dptr;
- if (key.dsize != sizeof(uint32))
- return 0;
-
- if (*sysjob == pjob->sysjob) {
- uint32 *jobid = (uint32 *)key.dptr;
-
- sysjob_to_jobid_value = *jobid;
- return 1;
- }
-
- return 0;
-}
-
-/****************************************************************************
- This is a *horribly expensive call as we have to iterate through all the
- current printer tdb's. Don't do this often ! JRA.
-****************************************************************************/
-
-uint32 sysjob_to_jobid(int unix_jobid)
-{
- int services = lp_numservices();
- int snum;
-
- sysjob_to_jobid_value = (uint32)-1;
-
- for (snum = 0; snum < services; snum++) {
- struct tdb_print_db *pdb;
- if (!lp_print_ok(snum))
- continue;
- pdb = get_print_db_byname(lp_const_servicename(snum));
- if (pdb)
- tdb_traverse(pdb->tdb, unixjob_traverse_fn, &unix_jobid);
- release_print_db(pdb);
- if (sysjob_to_jobid_value != (uint32)-1)
- return sysjob_to_jobid_value;
- }
- return (uint32)-1;
-}
-
-/****************************************************************************
- Send notifications based on what has changed after a pjob_store.
-****************************************************************************/
-
-static struct {
- uint32 lpq_status;
- uint32 spoolss_status;
-} lpq_to_spoolss_status_map[] = {
- { LPQ_QUEUED, JOB_STATUS_QUEUED },
- { LPQ_PAUSED, JOB_STATUS_PAUSED },
- { LPQ_SPOOLING, JOB_STATUS_SPOOLING },
- { LPQ_PRINTING, JOB_STATUS_PRINTING },
- { LPQ_DELETING, JOB_STATUS_DELETING },
- { LPQ_OFFLINE, JOB_STATUS_OFFLINE },
- { LPQ_PAPEROUT, JOB_STATUS_PAPEROUT },
- { LPQ_PRINTED, JOB_STATUS_PRINTED },
- { LPQ_DELETED, JOB_STATUS_DELETED },
- { LPQ_BLOCKED, JOB_STATUS_BLOCKED },
- { LPQ_USER_INTERVENTION, JOB_STATUS_USER_INTERVENTION },
- { -1, 0 }
-};
-
-/* Convert a lpq status value stored in printing.tdb into the
- appropriate win32 API constant. */
-
-static uint32 map_to_spoolss_status(uint32 lpq_status)
-{
- int i = 0;
-
- while (lpq_to_spoolss_status_map[i].lpq_status != -1) {
- if (lpq_to_spoolss_status_map[i].lpq_status == lpq_status)
- return lpq_to_spoolss_status_map[i].spoolss_status;
- i++;
- }
-
- return 0;
-}
-
-static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
- struct printjob *new_data)
-{
- BOOL new_job = False;
-
- if (!old_data)
- new_job = True;
-
- /* Notify the job name first */
-
- if (new_job || !strequal(old_data->jobname, new_data->jobname))
- notify_job_name(snum, jobid, new_data->jobname);
-
- /* Job attributes that can't be changed. We only send
- notification for these on a new job. */
-
- if (new_job) {
- notify_job_submitted(snum, jobid, new_data->starttime);
- notify_job_username(snum, jobid, new_data->user);
- }
-
- /* Job attributes of a new job or attributes that can be
- modified. */
-
- if (new_job || old_data->status != new_data->status)
- notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
-
- if (new_job || old_data->size != new_data->size)
- notify_job_total_bytes(snum, jobid, new_data->size);
-
- if (new_job || old_data->page_count != new_data->page_count)
- notify_job_total_pages(snum, jobid, new_data->page_count);
-}
-
-/****************************************************************************
- Store a job structure back to the database.
-****************************************************************************/
-
-static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
-{
- TDB_DATA old_data, new_data;
- BOOL ret = False;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
- char *buf = NULL;
- int len, newlen, buflen;
-
-
- if (!pdb)
- return False;
-
- /* Get old data */
-
- old_data = tdb_fetch(pdb->tdb, print_key(jobid));
-
- /* Doh! Now we have to pack/unpack data since the NT_DEVICEMODE was added */
-
- newlen = 0;
-
- do {
- len = 0;
- buflen = newlen;
- len += tdb_pack(buf+len, buflen-len, "dddddddddffff",
- pjob->pid,
- pjob->sysjob,
- pjob->fd,
- pjob->starttime,
- pjob->status,
- pjob->size,
- pjob->page_count,
- pjob->spooled,
- pjob->smbjob,
- pjob->filename,
- pjob->jobname,
- pjob->user,
- pjob->queuename);
-
- len += pack_devicemode(pjob->nt_devmode, buf+len, buflen-len);
-
- if (buflen != len) {
- char *tb;
-
- tb = (char *)Realloc(buf, len);
- if (!tb) {
- DEBUG(0,("pjob_store: failed to enlarge buffer!\n"));
- goto done;
- }
- else
- buf = tb;
- newlen = len;
- }
- } while ( buflen != len );
-
-
- /* Store new data */
-
- new_data.dptr = buf;
- new_data.dsize = len;
- ret = (tdb_store(pdb->tdb, print_key(jobid), new_data, TDB_REPLACE) == 0);
-
- release_print_db(pdb);
-
- /* Send notify updates for what has changed */
-
- if ( ret && (old_data.dsize == 0 || old_data.dsize == sizeof(*pjob)) )
- pjob_store_notify( snum, jobid, (struct printjob *)old_data.dptr, pjob );
-
-done:
- SAFE_FREE( old_data.dptr );
- SAFE_FREE( buf );
-
- return ret;
-}
-
-/****************************************************************************
- Remove a job structure from the database.
-****************************************************************************/
-
-void pjob_delete(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- uint32 job_status = 0;
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
-
- if (!pdb)
- return;
-
- if (!pjob) {
- DEBUG(5, ("pjob_delete(): we were asked to delete nonexistent job %u\n",
- (unsigned int)jobid));
- release_print_db(pdb);
- return;
- }
-
- /* Send a notification that a job has been deleted */
-
- job_status = map_to_spoolss_status(pjob->status);
-
- /* We must cycle through JOB_STATUS_DELETING and
- JOB_STATUS_DELETED for the port monitor to delete the job
- properly. */
-
- job_status |= JOB_STATUS_DELETING;
- notify_job_status(snum, jobid, job_status);
-
- job_status |= JOB_STATUS_DELETED;
- notify_job_status(snum, jobid, job_status);
-
- /* Remove from printing.tdb */
-
- tdb_delete(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
- rap_jobid_delete(snum, jobid);
-}
-
-/****************************************************************************
- Parse a file name from the system spooler to generate a jobid.
-****************************************************************************/
-
-static uint32 print_parse_jobid(char *fname)
-{
- int jobid;
-
- if (strncmp(fname,PRINT_SPOOL_PREFIX,strlen(PRINT_SPOOL_PREFIX)) != 0)
- return (uint32)-1;
- fname += strlen(PRINT_SPOOL_PREFIX);
-
- jobid = atoi(fname);
- if (jobid <= 0)
- return (uint32)-1;
-
- return (uint32)jobid;
-}
-
-/****************************************************************************
- List a unix job in the print database.
-****************************************************************************/
-
-static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
-{
- struct printjob pj, *old_pj;
-
- if (jobid == (uint32)-1)
- jobid = q->job + UNIX_JOB_START;
-
- /* Preserve the timestamp on an existing unix print job */
-
- old_pj = print_job_find(snum, jobid);
-
- ZERO_STRUCT(pj);
-
- pj.pid = (pid_t)-1;
- pj.sysjob = q->job;
- pj.fd = -1;
- pj.starttime = old_pj ? old_pj->starttime : q->time;
- pj.status = q->status;
- pj.size = q->size;
- pj.spooled = True;
- pj.smbjob = (old_pj != NULL ? True : False);
- fstrcpy(pj.filename, old_pj ? old_pj->filename : "");
- if (jobid < UNIX_JOB_START)
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : "Remote Downlevel Document");
- else
- fstrcpy(pj.jobname, old_pj ? old_pj->jobname : q->fs_file);
- fstrcpy(pj.user, old_pj ? old_pj->user : q->fs_user);
- fstrcpy(pj.queuename, old_pj ? old_pj->queuename : lp_const_servicename(snum));
-
- pjob_store(snum, jobid, &pj);
-}
-
-
-struct traverse_struct {
- print_queue_struct *queue;
- int qcount, snum, maxcount, total_jobs;
- time_t lpq_time;
-};
-
-/****************************************************************************
- Utility fn to delete any jobs that are no longer active.
-****************************************************************************/
-
-static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct traverse_struct *ts = (struct traverse_struct *)state;
- struct printjob pjob;
- uint32 jobid;
- int i;
-
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- memcpy(&jobid, key.dptr, sizeof(jobid));
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
- return 0;
- free_nt_devicemode( &pjob.nt_devmode );
-
-
- if (ts->snum != lp_servicenumber(pjob.queuename)) {
- /* this isn't for the queue we are looking at - this cannot happen with the split tdb's. JRA */
- return 0;
- }
-
- if (!pjob.smbjob) {
- /* remove a unix job if it isn't in the system queue any more */
-
- for (i=0;i<ts->qcount;i++) {
- uint32 u_jobid = (ts->queue[i].job + UNIX_JOB_START);
- if (jobid == u_jobid)
- break;
- }
- if (i == ts->qcount)
- pjob_delete(ts->snum, jobid);
- else
- ts->total_jobs++;
- return 0;
- }
-
- /* maybe it hasn't been spooled yet */
- if (!pjob.spooled) {
- /* if a job is not spooled and the process doesn't
- exist then kill it. This cleans up after smbd
- deaths */
- if (!process_exists(pjob.pid))
- pjob_delete(ts->snum, jobid);
- else
- ts->total_jobs++;
- return 0;
- }
-
- for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
- if (jobid == curr_jobid)
- break;
- }
-
- /* The job isn't in the system queue - we have to assume it has
- completed, so delete the database entry. */
-
- if (i == ts->qcount) {
-
- /* A race can occur between the time a job is spooled and
- when it appears in the lpq output. This happens when
- the job is added to printing.tdb when another smbd
- running print_queue_update() has completed a lpq and
- is currently traversing the printing tdb and deleting jobs.
- Don't delete the job if it was submitted after the lpq_time. */
-
- if (pjob.starttime < ts->lpq_time)
- pjob_delete(ts->snum, jobid);
- else
- ts->total_jobs++;
- }
- else
- ts->total_jobs++;
-
- return 0;
-}
-
-/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static void print_cache_flush(int snum)
-{
- fstring key;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return;
- slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
- tdb_store_int32(pdb->tdb, key, -1);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Check if someone already thinks they are doing the update.
-****************************************************************************/
-
-static pid_t get_updating_pid(fstring printer_name)
-{
- fstring keystr;
- TDB_DATA data, key;
- pid_t updating_pid;
- struct tdb_print_db *pdb = get_print_db_byname(printer_name);
-
- if (!pdb)
- return (pid_t)-1;
- slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
-
- data = tdb_fetch(pdb->tdb, key);
- release_print_db(pdb);
- if (!data.dptr || data.dsize != sizeof(pid_t)) {
- SAFE_FREE(data.dptr);
- return (pid_t)-1;
- }
-
- memcpy(&updating_pid, data.dptr, sizeof(pid_t));
- SAFE_FREE(data.dptr);
-
- if (process_exists(updating_pid))
- return updating_pid;
-
- return (pid_t)-1;
-}
-
-/****************************************************************************
- Set the fact that we're doing the update, or have finished doing the update
- in the tdb.
-****************************************************************************/
-
-static void set_updating_pid(const fstring printer_name, BOOL delete)
-{
- fstring keystr;
- TDB_DATA key;
- TDB_DATA data;
- pid_t updating_pid = sys_getpid();
- struct tdb_print_db *pdb = get_print_db_byname(printer_name);
-
- if (!pdb)
- return;
-
- slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
-
- if (delete) {
- tdb_delete(pdb->tdb, key);
- release_print_db(pdb);
- return;
- }
-
- data.dptr = (void *)&updating_pid;
- data.dsize = sizeof(pid_t);
-
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Update the internal database from the system print queue for a queue.
-****************************************************************************/
-
-static void print_queue_update(int snum)
-{
- int i, qcount;
- print_queue_struct *queue = NULL;
- print_status_struct status;
- print_status_struct old_status;
- struct printjob *pjob;
- struct traverse_struct tstruct;
- fstring keystr, printer_name, cachestr;
- TDB_DATA data, key;
- struct tdb_print_db *pdb;
-
- fstrcpy(printer_name, lp_const_servicename(snum));
- pdb = get_print_db_byname(printer_name);
- if (!pdb)
- return;
-
- /*
- * Check to see if someone else is doing this update.
- * This is essentially a mutex on the update.
- */
-
- if (get_updating_pid(printer_name) != -1) {
- release_print_db(pdb);
- return;
- }
-
- /* Lock the queue for the database update */
-
- slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name);
- /* Only wait 10 seconds for this. */
- if (tdb_lock_bystring(pdb->tdb, keystr, 10) == -1) {
- DEBUG(0,("print_queue_update: Failed to lock printer %s database\n", printer_name));
- release_print_db(pdb);
- return;
- }
-
- /*
- * Ensure that no one else got in here.
- * If the updating pid is still -1 then we are
- * the winner.
- */
-
- if (get_updating_pid(printer_name) != -1) {
- /*
- * Someone else is doing the update, exit.
- */
- tdb_unlock_bystring(pdb->tdb, keystr);
- release_print_db(pdb);
- return;
- }
-
- /*
- * We're going to do the update ourselves.
- */
-
- /* Tell others we're doing the update. */
- set_updating_pid(printer_name, False);
-
- /*
- * Allow others to enter and notice we're doing
- * the update.
- */
-
- tdb_unlock_bystring(pdb->tdb, keystr);
-
- /*
- * Update the cache time FIRST ! Stops others even
- * attempting to get the lock and doing this
- * if the lpq takes a long time.
- */
-
- slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", printer_name);
- tdb_store_int32(pdb->tdb, cachestr, (int)time(NULL));
-
- /* get the current queue using the appropriate interface */
- ZERO_STRUCT(status);
-
- qcount = (*(current_printif->queue_get))(snum, &queue, &status);
-
- DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
- "s" : "", printer_name));
-
- /*
- any job in the internal database that is marked as spooled
- and doesn't exist in the system queue is considered finished
- and removed from the database
-
- any job in the system database but not in the internal database
- is added as a unix job
-
- fill in any system job numbers as we go
- */
- for (i=0; i<qcount; i++) {
- uint32 jobid = print_parse_jobid(queue[i].fs_file);
-
- if (jobid == (uint32)-1) {
- /* assume its a unix print job */
- print_unix_job(snum, &queue[i], jobid);
- continue;
- }
-
- /* we have an active SMB print job - update its status */
- pjob = print_job_find(snum, jobid);
- if (!pjob) {
- /* err, somethings wrong. Probably smbd was restarted
- with jobs in the queue. All we can do is treat them
- like unix jobs. Pity. */
- print_unix_job(snum, &queue[i], jobid);
- continue;
- }
-
- pjob->sysjob = queue[i].job;
- pjob->status = queue[i].status;
-
- pjob_store(snum, jobid, pjob);
- }
-
- /* now delete any queued entries that don't appear in the
- system queue */
- tstruct.queue = queue;
- tstruct.qcount = qcount;
- tstruct.snum = snum;
- tstruct.total_jobs = 0;
- tstruct.lpq_time = time(NULL);
-
- tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
-
- SAFE_FREE(tstruct.queue);
-
- DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
- printer_name, tstruct.total_jobs ));
-
- tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
-
- get_queue_status(snum, &old_status);
- if (old_status.qcount != qcount)
- DEBUG(10,("print_queue_update: queue status change %d jobs -> %d jobs for printer %s\n",
- old_status.qcount, qcount, printer_name ));
-
- /* store the new queue status structure */
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
-
- status.qcount = qcount;
- data.dptr = (void *)&status;
- data.dsize = sizeof(status);
- tdb_store(pdb->tdb, key, data, TDB_REPLACE);
-
- /*
- * Update the cache time again. We want to do this call
- * as little as possible...
- */
-
- slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
- tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
-
- /* Delete our pid from the db. */
- set_updating_pid(printer_name, True);
- release_print_db(pdb);
-}
-
-/****************************************************************************
- Create/Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
-****************************************************************************/
-
-BOOL print_notify_register_pid(int snum)
-{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- BOOL ret = False;
- size_t i;
-
- /* if (snum == -1), then the change notify request was
- on a print server handle and we need to register on
- all print queus */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if (lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_register_pid(idx);
- }
-
- return True;
- }
- else /* register for a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock printer %s\n",
- printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Add ourselves and increase the refcount. */
-
- for (i = 0; i < data.dsize; i += 8) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 new_refcount = IVAL(data.dptr, i+4) + 1;
- SIVAL(data.dptr, i+4, new_refcount);
- break;
- }
- }
-
- if (i == data.dsize) {
- /* We weren't in the list. Realloc. */
- data.dptr = Realloc(data.dptr, data.dsize + 8);
- if (!data.dptr) {
- DEBUG(0,("print_notify_register_pid: Relloc fail for printer %s\n",
- printername));
- goto done;
- }
- data.dsize += 8;
- SIVAL(data.dptr,data.dsize - 8,mypid);
- SIVAL(data.dptr,data.dsize - 4,1); /* Refcount. */
- }
-
- /* Store back the record. */
- if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/****************************************************************************
- Update an entry in the print tdb that will allow us to send notify
- updates only to interested smbd's.
-****************************************************************************/
-
-BOOL print_notify_deregister_pid(int snum)
-{
- TDB_DATA data;
- struct tdb_print_db *pdb = NULL;
- TDB_CONTEXT *tdb = NULL;
- const char *printername;
- uint32 mypid = (uint32)sys_getpid();
- size_t i;
- BOOL ret = False;
-
- /* if ( snum == -1 ), we are deregister a print server handle
- which means to deregister on all print queues */
-
- if (snum == -1)
- {
- int num_services = lp_numservices();
- int idx;
-
- for ( idx=0; idx<num_services; idx++ ) {
- if ( lp_snum_ok(idx) && lp_print_ok(idx) )
- print_notify_deregister_pid(idx);
- }
-
- return True;
- }
- else /* deregister a specific printer */
- {
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
- if (!pdb)
- return False;
- tdb = pdb->tdb;
- }
-
- if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to lock \
-printer %s database\n", printername));
- if (pdb)
- release_print_db(pdb);
- return False;
- }
-
- data = get_printer_notify_pid_list( tdb, printername, True );
-
- /* Reduce refcount. Remove ourselves if zero. */
-
- for (i = 0; i < data.dsize; ) {
- if (IVAL(data.dptr,i) == mypid) {
- uint32 refcount = IVAL(data.dptr, i+4);
-
- refcount--;
-
- if (refcount == 0) {
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- continue;
- }
- SIVAL(data.dptr, i+4, refcount);
- }
-
- i += 8;
- }
-
- if (data.dsize == 0)
- SAFE_FREE(data.dptr);
-
- /* Store back the record. */
- if (tdb_store_by_string(tdb, NOTIFY_PID_LIST_KEY, data, TDB_REPLACE) == -1) {
- DEBUG(0,("print_notify_register_pid: Failed to update pid \
-list for printer %s\n", printername));
- goto done;
- }
-
- ret = True;
-
- done:
-
- tdb_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
- if (pdb)
- release_print_db(pdb);
- SAFE_FREE(data.dptr);
- return ret;
-}
-
-/****************************************************************************
- Check if a jobid is valid. It is valid if it exists in the database.
-****************************************************************************/
-
-BOOL print_job_exists(int snum, uint32 jobid)
-{
- struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
- BOOL ret;
-
- if (!pdb)
- return False;
- ret = tdb_exists(pdb->tdb, print_key(jobid));
- release_print_db(pdb);
- return ret;
-}
-
-/****************************************************************************
- Give the fd used for a jobid.
-****************************************************************************/
-
-int print_job_fd(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob)
- return -1;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != local_pid)
- return -1;
- return pjob->fd;
-}
-
-/****************************************************************************
- Give the filename used for a jobid.
- Only valid for the process doing the spooling and when the job
- has not been spooled.
-****************************************************************************/
-
-char *print_job_fname(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob || pjob->spooled || pjob->pid != local_pid)
- return NULL;
- return pjob->filename;
-}
-
-
-/****************************************************************************
- Give the filename used for a jobid.
- Only valid for the process doing the spooling and when the job
- has not been spooled.
-****************************************************************************/
-
-NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
-
- if ( !pjob )
- return NULL;
-
- return pjob->nt_devmode;
-}
-
-/****************************************************************************
- Set the place in the queue for a job.
-****************************************************************************/
-
-BOOL print_job_set_place(int snum, uint32 jobid, int place)
-{
- DEBUG(2,("print_job_set_place not implemented yet\n"));
- return False;
-}
-
-/****************************************************************************
- Set the name of a job. Only possible for owner.
-****************************************************************************/
-
-BOOL print_job_set_name(int snum, uint32 jobid, char *name)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob || pjob->pid != local_pid)
- return False;
-
- fstrcpy(pjob->jobname, name);
- return pjob_store(snum, jobid, pjob);
-}
-
-/****************************************************************************
- Delete a print job - don't update queue.
-****************************************************************************/
-
-static BOOL print_job_delete1(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int result = 0;
-
- if (!pjob)
- return False;
-
- /*
- * If already deleting just return.
- */
-
- if (pjob->status == LPQ_DELETING)
- return True;
-
- /* Hrm - we need to be able to cope with deleting a job before it
- has reached the spooler. */
-
- if (pjob->sysjob == -1) {
- DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
- }
-
- /* Set the tdb entry to be deleting. */
-
- pjob->status = LPQ_DELETING;
- pjob_store(snum, jobid, pjob);
-
- if (pjob->spooled && pjob->sysjob != -1)
- result = (*(current_printif->job_delete))(snum, pjob);
-
- /* Delete the tdb entry if the delete suceeded or the job hasn't
- been spooled. */
-
- if (result == 0)
- pjob_delete(snum, jobid);
-
- return (result == 0);
-}
-
-/****************************************************************************
- Return true if the current user owns the print job.
-****************************************************************************/
-
-static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- user_struct *vuser;
-
- if (!pjob || !user)
- return False;
-
- if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- return strequal(pjob->user, vuser->user.smb_name);
- } else {
- return strequal(pjob->user, uidtoname(user->uid));
- }
-}
-
-/****************************************************************************
- Delete a print job.
-****************************************************************************/
-
-BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
-{
- BOOL owner, deleted;
- char *fname;
-
- *errcode = WERR_OK;
-
- owner = is_owner(user, snum, jobid);
-
- /* Check access against security descriptor or whether the user
- owns their job. */
-
- if (!owner &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("delete denied by security descriptor\n"));
- *errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
- return False;
- }
-
- /*
- * get the spooled filename of the print job
- * if this works, then the file has not been spooled
- * to the underlying print system. Just delete the
- * spool file & return.
- */
-
- if ( (fname = print_job_fname( snum, jobid )) != NULL )
- {
- /* remove the spool file */
- DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
- if ( unlink( fname ) == -1 ) {
- *errcode = map_werror_from_unix(errno);
- return False;
- }
-
- return True;
- }
-
- if (!print_job_delete1(snum, jobid)) {
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- /* force update the database and say the delete failed if the
- job still exists */
-
- print_queue_update(snum);
-
- deleted = !print_job_exists(snum, jobid);
- if ( !deleted )
- *errcode = WERR_ACCESS_DENIED;
-
- return deleted;
-}
-
-/****************************************************************************
- Pause a job.
-****************************************************************************/
-
-BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret = -1;
-
- if (!pjob || !user)
- return False;
-
- if (!pjob->spooled || pjob->sysjob == -1)
- return False;
-
- if (!is_owner(user, snum, jobid) &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("pause denied by security descriptor\n"));
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
-
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- /* need to pause the spooled entry */
- ret = (*(current_printif->job_pause))(snum, pjob);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(snum);
-
- /* Send a printer notify message */
-
- notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
-
- /* how do we tell if this succeeded? */
-
- return True;
-}
-
-/****************************************************************************
- Resume a job.
-****************************************************************************/
-
-BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret;
-
- if (!pjob || !user)
- return False;
-
- if (!pjob->spooled || pjob->sysjob == -1)
- return False;
-
- if (!is_owner(user, snum, jobid) &&
- !print_access_check(user, snum, JOB_ACCESS_ADMINISTER)) {
- DEBUG(3, ("resume denied by security descriptor\n"));
- *errcode = WERR_ACCESS_DENIED;
-
- /* BEGIN_ADMIN_LOG */
- sys_adminlog( LOG_ERR,
- "Permission denied-- user not allowed to delete, \
-pause, or resume print job. User name: %s. Printer name: %s.",
- uidtoname(user->uid), PRINTERNAME(snum) );
- /* END_ADMIN_LOG */
- return False;
- }
-
- ret = (*(current_printif->job_resume))(snum, pjob);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(snum);
-
- /* Send a printer notify message */
-
- notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
-
- return True;
-}
-
-/****************************************************************************
- Write to a print file.
-****************************************************************************/
-
-int print_job_write(int snum, uint32 jobid, const char *buf, int size)
-{
- int return_code;
- struct printjob *pjob = print_job_find(snum, jobid);
-
- if (!pjob)
- return -1;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != local_pid)
- return -1;
-
- return_code = write(pjob->fd, buf, size);
- if (return_code>0) {
- pjob->size += size;
- pjob_store(snum, jobid, pjob);
- }
- return return_code;
-}
-
-/****************************************************************************
- Check if the print queue has been updated recently enough.
-****************************************************************************/
-
-static BOOL print_cache_expired(int snum)
-{
- fstring key;
- time_t last_qscan_time, time_now = time(NULL);
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return False;
-
- slprintf(key, sizeof(key), "CACHE/%s", printername);
- last_qscan_time = (time_t)tdb_fetch_int32(pdb->tdb, key);
-
- /*
- * Invalidate the queue for 3 reasons.
- * (1). last queue scan time == -1.
- * (2). Current time - last queue scan time > allowed cache time.
- * (3). last queue scan time > current time + MAX_CACHE_VALID_TIME (1 hour by default).
- * This last test picks up machines for which the clock has been moved
- * forward, an lpq scan done and then the clock moved back. Otherwise
- * that last lpq scan would stay around for a loooong loooong time... :-). JRA.
- */
-
- if (last_qscan_time == ((time_t)-1) || (time_now - last_qscan_time) >= lp_lpqcachetime() ||
- last_qscan_time > (time_now + MAX_CACHE_VALID_TIME)) {
- DEBUG(3, ("print cache expired for queue %s \
-(last_qscan_time = %d, time now = %d, qcachetime = %d)\n", printername,
- (int)last_qscan_time, (int)time_now, (int)lp_lpqcachetime() ));
- release_print_db(pdb);
- return True;
- }
- release_print_db(pdb);
- return False;
-}
-
-/****************************************************************************
- Get the queue status - do not update if db is out of date.
-****************************************************************************/
-
-static int get_queue_status(int snum, print_status_struct *status)
-{
- fstring keystr;
- TDB_DATA data, key;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- int len;
-
- if (!pdb)
- return 0;
-
- if (status) {
- ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
- if (data.dptr) {
- if (data.dsize == sizeof(print_status_struct))
- memcpy(status, data.dptr, sizeof(print_status_struct));
- SAFE_FREE(data.dptr);
- }
- }
- len = tdb_fetch_int32(pdb->tdb, "INFO/total_jobs");
- release_print_db(pdb);
- return (len == -1 ? 0 : len);
-}
-
-/****************************************************************************
- Determine the number of jobs in a queue.
-****************************************************************************/
-
-int print_queue_length(int snum, print_status_struct *pstatus)
-{
- print_status_struct status;
- int len;
-
- /* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- /* also fetch the queue status */
- memset(&status, 0, sizeof(status));
- len = get_queue_status(snum, &status);
-
- if (pstatus)
- *pstatus = status;
-
- return len;
-}
-
-/***************************************************************************
- Allocate a jobid. Hold the lock for as short a time as possible.
-***************************************************************************/
-
-static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *printername, uint32 *pjobid)
-{
- int i;
- uint32 jobid;
-
- *pjobid = (uint32)-1;
-
- for (i = 0; i < 3; i++) {
- /* Lock the database - only wait 20 seconds. */
- if (tdb_lock_bystring(pdb->tdb, "INFO/nextjob", 20) == -1) {
- DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", printername ));
- return False;
- }
-
- if (!tdb_fetch_uint32(pdb->tdb, "INFO/nextjob", &jobid)) {
- if (tdb_error(pdb->tdb) != TDB_ERR_NOEXIST) {
- DEBUG(0, ("allocate_print_jobid: failed to fetch INFO/nextjob for print queue %s\n",
- printername ));
- return False;
- }
- jobid = 0;
- }
-
- jobid = NEXT_JOBID(jobid);
-
- if (tdb_store_int32(pdb->tdb, "INFO/nextjob", jobid)==-1) {
- DEBUG(3, ("allocate_print_jobid: failed to store INFO/nextjob.\n"));
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
- return False;
- }
-
- /* We've finished with the INFO/nextjob lock. */
- tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
-
- if (!print_job_exists(snum, jobid))
- break;
- }
-
- if (i > 2) {
- DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
- printername ));
- /* Probably full... */
- errno = ENOSPC;
- return False;
- }
-
- /* Store a dummy placeholder. */
- {
- TDB_DATA dum;
- dum.dptr = NULL;
- dum.dsize = 0;
- if (tdb_store(pdb->tdb, print_key(jobid), dum, TDB_INSERT) == -1) {
- DEBUG(3, ("allocate_print_jobid: jobid (%d) failed to store placeholder.\n",
- jobid ));
- return False;
- }
- }
-
- *pjobid = jobid;
- return True;
-}
-
-/***************************************************************************
- Start spooling a job - return the jobid.
-***************************************************************************/
-
-uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DEVICEMODE *nt_devmode )
-{
- uint32 jobid;
- char *path;
- struct printjob pjob;
- user_struct *vuser;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
- int njobs;
-
- errno = 0;
-
- if (!pdb)
- return (uint32)-1;
-
- if (!print_access_check(user, snum, PRINTER_ACCESS_USE)) {
- DEBUG(3, ("print_job_start: job start denied by security descriptor\n"));
- release_print_db(pdb);
- return (uint32)-1;
- }
-
- if (!print_time_access_check(snum)) {
- DEBUG(3, ("print_job_start: job start denied by time check\n"));
- release_print_db(pdb);
- return (uint32)-1;
- }
-
- path = lp_pathname(snum);
-
- /* see if we have sufficient disk space */
- if (lp_minprintspace(snum)) {
- SMB_BIG_UINT dspace, dsize;
- if (sys_fsusage(path, &dspace, &dsize) == 0 &&
- dspace < 2*(SMB_BIG_UINT)lp_minprintspace(snum)) {
- DEBUG(3, ("print_job_start: disk space check failed.\n"));
- release_print_db(pdb);
- errno = ENOSPC;
- return (uint32)-1;
- }
- }
-
- /* for autoloaded printers, check that the printcap entry still exists */
- if (lp_autoloaded(snum) && !pcap_printername_ok(lp_const_servicename(snum), NULL)) {
- DEBUG(3, ("print_job_start: printer name %s check failed.\n", lp_const_servicename(snum) ));
- release_print_db(pdb);
- errno = ENOENT;
- return (uint32)-1;
- }
-
- /* Insure the maximum queue size is not violated */
- if ((njobs = print_queue_length(snum,NULL)) > lp_maxprintjobs(snum)) {
- DEBUG(3, ("print_job_start: Queue %s number of jobs (%d) larger than max printjobs per queue (%d).\n",
- printername, njobs, lp_maxprintjobs(snum) ));
- release_print_db(pdb);
- errno = ENOSPC;
- return (uint32)-1;
- }
-
- DEBUG(10,("print_job_start: Queue %s number of jobs (%d), max printjobs = %d\n",
- printername, njobs, lp_maxprintjobs(snum) ));
-
- if (!allocate_print_jobid(pdb, snum, printername, &jobid))
- goto fail;
-
- /* create the database entry */
-
- ZERO_STRUCT(pjob);
-
- pjob.pid = local_pid;
- pjob.sysjob = -1;
- pjob.fd = -1;
- pjob.starttime = time(NULL);
- pjob.status = LPQ_SPOOLING;
- pjob.size = 0;
- pjob.spooled = False;
- pjob.smbjob = True;
- pjob.nt_devmode = nt_devmode;
-
- fstrcpy(pjob.jobname, jobname);
-
- if ((vuser = get_valid_user_struct(user->vuid)) != NULL) {
- fstrcpy(pjob.user, vuser->user.smb_name);
- } else {
- fstrcpy(pjob.user, uidtoname(user->uid));
- }
-
- fstrcpy(pjob.queuename, lp_const_servicename(snum));
-
- /* we have a job entry - now create the spool file */
- slprintf(pjob.filename, sizeof(pjob.filename)-1, "%s/%s%.8u.XXXXXX",
- path, PRINT_SPOOL_PREFIX, (unsigned int)jobid);
- pjob.fd = smb_mkstemp(pjob.filename);
-
- if (pjob.fd == -1) {
- if (errno == EACCES) {
- /* Common setup error, force a report. */
- DEBUG(0, ("print_job_start: insufficient permissions \
-to open spool file %s.\n", pjob.filename));
- } else {
- /* Normal case, report at level 3 and above. */
- DEBUG(3, ("print_job_start: can't open spool file %s,\n", pjob.filename));
- DEBUGADD(3, ("errno = %d (%s).\n", errno, strerror(errno)));
- }
- goto fail;
- }
-
- pjob_store(snum, jobid, &pjob);
-
- /* Ensure we keep a rough count of the number of total jobs... */
- tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1);
-
- release_print_db(pdb);
-
- return jobid;
-
- fail:
- if (jobid != -1)
- pjob_delete(snum, jobid);
-
- release_print_db(pdb);
-
- DEBUG(3, ("print_job_start: returning fail. Error = %s\n", strerror(errno) ));
- return (uint32)-1;
-}
-
-/****************************************************************************
- Update the number of pages spooled to jobid
-****************************************************************************/
-
-void print_job_endpage(int snum, uint32 jobid)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- if (!pjob)
- return;
- /* don't allow another process to get this info - it is meaningless */
- if (pjob->pid != local_pid)
- return;
-
- pjob->page_count++;
- pjob_store(snum, jobid, pjob);
-}
-
-/****************************************************************************
- Print a file - called on closing the file. This spools the job.
- If normal close is false then we're tearing down the jobs - treat as an
- error.
-****************************************************************************/
-
-BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
-{
- struct printjob *pjob = print_job_find(snum, jobid);
- int ret;
- SMB_STRUCT_STAT sbuf;
-
- if (!pjob)
- return False;
-
- if (pjob->spooled || pjob->pid != local_pid)
- return False;
-
- if (normal_close && (sys_fstat(pjob->fd, &sbuf) == 0)) {
- pjob->size = sbuf.st_size;
- close(pjob->fd);
- pjob->fd = -1;
- } else {
-
- /*
- * Not a normal close or we couldn't stat the job file,
- * so something has gone wrong. Cleanup.
- */
- close(pjob->fd);
- pjob->fd = -1;
- DEBUG(3,("print_job_end: failed to stat file for jobid %d\n", jobid ));
- goto fail;
- }
-
- /* Technically, this is not quite right. If the printer has a separator
- * page turned on, the NT spooler prints the separator page even if the
- * print job is 0 bytes. 010215 JRR */
- if (pjob->size == 0 || pjob->status == LPQ_DELETING) {
- /* don't bother spooling empty files or something being deleted. */
- DEBUG(5,("print_job_end: canceling spool of %s (%s)\n",
- pjob->filename, pjob->size ? "deleted" : "zero length" ));
- unlink(pjob->filename);
- pjob_delete(snum, jobid);
- return True;
- }
-
- ret = (*(current_printif->job_submit))(snum, pjob);
-
- if (ret)
- goto fail;
-
- /* The print job has been sucessfully handed over to the back-end */
-
- pjob->spooled = True;
- pjob->status = LPQ_QUEUED;
- pjob_store(snum, jobid, pjob);
-
- /* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- return True;
-
-fail:
-
- /* The print job was not succesfully started. Cleanup */
- /* Still need to add proper error return propagation! 010122:JRR */
- unlink(pjob->filename);
- pjob_delete(snum, jobid);
- return False;
-}
-
-/****************************************************************************
- Utility fn to enumerate the print queue.
-****************************************************************************/
-
-static int traverse_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct traverse_struct *ts = (struct traverse_struct *)state;
- struct printjob pjob;
- int i;
- uint32 jobid;
-
- /* sanity checks */
-
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- memcpy(&jobid, key.dptr, sizeof(jobid));
-
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
- return 0;
- free_nt_devicemode( &pjob.nt_devmode );
-
- /* maybe it isn't for this queue */
- if (ts->snum != lp_servicenumber(pjob.queuename))
- return 0;
-
- if (ts->qcount >= ts->maxcount)
- return 0;
-
- i = ts->qcount;
-
- ts->queue[i].job = jobid;
- ts->queue[i].size = pjob.size;
- ts->queue[i].page_count = pjob.page_count;
- ts->queue[i].status = pjob.status;
- ts->queue[i].priority = 1;
- ts->queue[i].time = pjob.starttime;
- fstrcpy(ts->queue[i].fs_user, pjob.user);
- fstrcpy(ts->queue[i].fs_file, pjob.jobname);
-
- ts->qcount++;
-
- return 0;
-}
-
-struct traverse_count_struct {
- int snum, count;
-};
-
-/****************************************************************************
- Utility fn to count the number of entries in the print queue.
-****************************************************************************/
-
-static int traverse_count_fn_queue(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void *state)
-{
- struct traverse_count_struct *ts = (struct traverse_count_struct *)state;
- struct printjob pjob;
- uint32 jobid;
-
- /* sanity checks */
-
- if ( key.dsize != sizeof(jobid) )
- return 0;
-
- memcpy(&jobid, key.dptr, sizeof(jobid));
-
- if ( unpack_pjob( data.dptr, data.dsize, &pjob ) == -1 )
- return 0;
-
- free_nt_devicemode( &pjob.nt_devmode );
-
- /* maybe it isn't for this queue - this cannot happen with the tdb/printer code. JRA */
- if (ts->snum != lp_servicenumber(pjob.queuename))
- return 0;
-
- ts->count++;
-
- return 0;
-}
-
-/****************************************************************************
- Sort print jobs by submittal time.
-****************************************************************************/
-
-static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
-{
- /* Silly cases */
-
- if (!j1 && !j2)
- return 0;
- if (!j1)
- return -1;
- if (!j2)
- return 1;
-
- /* Sort on job start time */
-
- if (j1->time == j2->time)
- return 0;
- return (j1->time > j2->time) ? 1 : -1;
-}
-
-/****************************************************************************
- Get a printer queue listing.
- set queue = NULL and status = NULL if you just want to update the cache
-****************************************************************************/
-
-int print_queue_status(int snum,
- print_queue_struct **queue,
- print_status_struct *status)
-{
- struct traverse_struct tstruct;
- struct traverse_count_struct tsc;
- fstring keystr;
- TDB_DATA data, key;
- const char *printername;
- struct tdb_print_db *pdb;
-
- /* make sure the database is up to date */
-
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- /* return if we are done */
-
- if ( !queue || !status )
- return 0;
-
- *queue = NULL;
- printername = lp_const_servicename(snum);
- pdb = get_print_db_byname(printername);
-
- if (!pdb)
- return 0;
-
- /*
- * Fetch the queue status. We must do this first, as there may
- * be no jobs in the queue.
- */
- ZERO_STRUCTP(status);
- slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
- key.dptr = keystr;
- key.dsize = strlen(keystr);
- data = tdb_fetch(pdb->tdb, key);
- if (data.dptr) {
- if (data.dsize == sizeof(*status)) {
- memcpy(status, data.dptr, sizeof(*status));
- }
- SAFE_FREE(data.dptr);
- }
-
- /*
- * Now, fetch the print queue information. We first count the number
- * of entries, and then only retrieve the queue if necessary.
- */
- tsc.count = 0;
- tsc.snum = snum;
-
- tdb_traverse(pdb->tdb, traverse_count_fn_queue, (void *)&tsc);
-
- if (tsc.count == 0) {
- release_print_db(pdb);
- return 0;
- }
-
- /* Allocate the queue size. */
- if ((tstruct.queue = (print_queue_struct *)
- malloc(sizeof(print_queue_struct)*tsc.count)) == NULL) {
- release_print_db(pdb);
- return 0;
- }
-
- /*
- * Fill in the queue.
- * We need maxcount as the queue size may have changed between
- * the two calls to tdb_traverse.
- */
- tstruct.qcount = 0;
- tstruct.maxcount = tsc.count;
- tstruct.snum = snum;
-
- tdb_traverse(pdb->tdb, traverse_fn_queue, (void *)&tstruct);
- release_print_db(pdb);
-
- /* Sort the queue by submission time otherwise they are displayed
- in hash order. */
-
- qsort(tstruct.queue, tstruct.qcount, sizeof(print_queue_struct),
- QSORT_CAST printjob_comp);
-
- *queue = tstruct.queue;
- return tstruct.qcount;
-}
-
-/****************************************************************************
- Pause a queue.
-****************************************************************************/
-
-BOOL print_queue_pause(struct current_user *user, int snum, WERROR *errcode)
-{
- int ret;
-
- if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- ret = (*(current_printif->queue_pause))(snum);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* force update the database */
- print_cache_flush(snum);
-
- /* Send a printer notify message */
-
- notify_printer_status(snum, PRINTER_STATUS_PAUSED);
-
- return True;
-}
-
-/****************************************************************************
- Resume a queue.
-****************************************************************************/
-
-BOOL print_queue_resume(struct current_user *user, int snum, WERROR *errcode)
-{
- int ret;
-
- if (!print_access_check(user, snum, PRINTER_ACCESS_ADMINISTER)) {
- *errcode = WERR_ACCESS_DENIED;
- return False;
- }
-
- ret = (*(current_printif->queue_resume))(snum);
-
- if (ret != 0) {
- *errcode = WERR_INVALID_PARAM;
- return False;
- }
-
- /* make sure the database is up to date */
- if (print_cache_expired(snum))
- print_queue_update(snum);
-
- /* Send a printer notify message */
-
- notify_printer_status(snum, PRINTER_STATUS_OK);
-
- return True;
-}
-
-/****************************************************************************
- Purge a queue - implemented by deleting all jobs that we can delete.
-****************************************************************************/
-
-BOOL print_queue_purge(struct current_user *user, int snum, WERROR *errcode)
-{
- print_queue_struct *queue;
- print_status_struct status;
- int njobs, i;
- BOOL can_job_admin;
-
- /* Force and update so the count is accurate (i.e. not a cached count) */
- print_queue_update(snum);
-
- can_job_admin = print_access_check(user, snum, JOB_ACCESS_ADMINISTER);
- njobs = print_queue_status(snum, &queue, &status);
-
- for (i=0;i<njobs;i++) {
- BOOL owner = is_owner(user, snum, queue[i].job);
-
- if (owner || can_job_admin) {
- print_job_delete1(snum, queue[i].job);
- }
- }
-
- SAFE_FREE(queue);
-
- return True;
-}
diff --git a/source4/printing/printing_db.c b/source4/printing/printing_db.c
deleted file mode 100644
index 0aa8dfafa5..0000000000
--- a/source4/printing/printing_db.c
+++ /dev/null
@@ -1,204 +0,0 @@
-/*
- Unix SMB/Netbios implementation.
- Version 3.0
- printing backend routines
- Copyright (C) Andrew Tridgell 1992-2000
- Copyright (C) Jeremy Allison 2002
-
- 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 02139, USA.
-*/
-
-#include "printing.h"
-
-static struct tdb_print_db *print_db_head;
-
-/****************************************************************************
- Function to find or create the printer specific job tdb given a printername.
- Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
-****************************************************************************/
-
-struct tdb_print_db *get_print_db_byname(const char *printername)
-{
- struct tdb_print_db *p = NULL, *last_entry = NULL;
- int num_open = 0;
- pstring printdb_path;
- BOOL done_become_root = False;
-
- for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
- /* Ensure the list terminates... JRA. */
- SMB_ASSERT(p->next != print_db_head);
-
- if (p->tdb && strequal(p->printer_name, printername)) {
- DLIST_PROMOTE(print_db_head, p);
- p->ref_count++;
- return p;
- }
- num_open++;
- last_entry = p;
- }
-
- /* Not found. */
- if (num_open >= MAX_PRINT_DBS_OPEN) {
- /* Try and recycle the last entry. */
- DLIST_PROMOTE(print_db_head, last_entry);
-
- for (p = print_db_head; p; p = p->next) {
- if (p->ref_count)
- continue;
- if (p->tdb) {
- if (tdb_close(print_db_head->tdb)) {
- DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
- print_db_head->printer_name ));
- return NULL;
- }
- }
- p->tdb = NULL;
- p->ref_count = 0;
- memset(p->printer_name, '\0', sizeof(p->printer_name));
- break;
- }
- if (p) {
- DLIST_PROMOTE(print_db_head, p);
- p = print_db_head;
- }
- }
-
- if (!p) {
- /* Create one. */
- p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
- if (!p) {
- DEBUG(0,("get_print_db: malloc fail !\n"));
- return NULL;
- }
- ZERO_STRUCTP(p);
- DLIST_ADD(print_db_head, p);
- }
-
- pstrcpy(printdb_path, lock_path("printing/"));
- pstrcat(printdb_path, printername);
- pstrcat(printdb_path, ".tdb");
-
- if (geteuid() != 0) {
- become_root();
- done_become_root = True;
- }
-
- p->tdb = tdb_open_log(printdb_path, 5000, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-
- if (done_become_root)
- unbecome_root();
-
- if (!p->tdb) {
- DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
- printdb_path ));
- DLIST_REMOVE(print_db_head, p);
- SAFE_FREE(p);
- return NULL;
- }
- fstrcpy(p->printer_name, printername);
- p->ref_count++;
- return p;
-}
-
-/***************************************************************************
- Remove a reference count.
-****************************************************************************/
-
-void release_print_db( struct tdb_print_db *pdb)
-{
- pdb->ref_count--;
- SMB_ASSERT(pdb->ref_count >= 0);
-}
-
-/***************************************************************************
- Close all open print db entries.
-****************************************************************************/
-
-void close_all_print_db(void)
-{
- struct tdb_print_db *p = NULL, *next_p = NULL;
-
- for (p = print_db_head; p; p = next_p) {
- next_p = p->next;
-
- if (p->tdb)
- tdb_close(p->tdb);
- DLIST_REMOVE(print_db_head, p);
- ZERO_STRUCTP(p);
- SAFE_FREE(p);
- }
-}
-
-
-/****************************************************************************
- Fetch and clean the pid_t record list for all pids interested in notify
- messages. data needs freeing on exit.
-****************************************************************************/
-
-TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
-{
- TDB_DATA data;
- size_t i;
-
- ZERO_STRUCT(data);
-
- data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY );
-
- if (!data.dptr) {
- ZERO_STRUCT(data);
- return data;
- }
-
- if (data.dsize % 8) {
- DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
- tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY );
- SAFE_FREE(data.dptr);
- ZERO_STRUCT(data);
- return data;
- }
-
- if (!cleanlist)
- return data;
-
- /*
- * Weed out all dead entries.
- */
-
- for( i = 0; i < data.dsize; i += 8) {
- pid_t pid = (pid_t)IVAL(data.dptr, i);
-
- if (pid == sys_getpid())
- continue;
-
- /* Entry is dead if process doesn't exist or refcount is zero. */
-
- while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {
-
- /* Refcount == zero is a logic error and should never happen. */
- if (IVAL(data.dptr, i + 4) == 0) {
- DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
- (unsigned int)pid, printer_name ));
- }
-
- if (data.dsize - i > 8)
- memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
- data.dsize -= 8;
- }
- }
-
- return data;
-}
-
-