patch based on volker's initial work in trunk that fixes the queu update problem...
authorjerry <jerry@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Tue, 19 Oct 2004 17:05:01 +0000 (17:05 +0000)
committerjerry <jerry@0c0555d6-39d7-0310-84fc-f1cc0bd64818>
Tue, 19 Oct 2004 17:05:01 +0000 (17:05 +0000)
git-svn-id: svn+ssh://svn.samba.org/data/svn/samba/branches/SAMBA_3_0@3067 0c0555d6-39d7-0310-84fc-f1cc0bd64818

source/include/printing.h
source/printing/lpq_parse.c
source/printing/notify.c
source/printing/print_cups.c
source/printing/print_generic.c
source/printing/printfsp.c
source/printing/printing.c
source/smbd/fileio.c

index bf7c61b251ee4b47b4510860d1e605b8690aff86..fd1e7e43e4e89f6fa77ec77473656fa60a8fa202 100644 (file)
@@ -47,7 +47,13 @@ struct printjob {
 /* Information for print interfaces */
 struct printif
 {
-  int (*queue_get)(int snum, print_queue_struct **q,
+  /* value of the 'printing' option for this service */
+  enum printing_types type;
+
+  int (*queue_get)(const char *printer_name,
+                   enum printing_types printing_type,
+                   char *lpq_command,
+                   print_queue_struct **q,
                    print_status_struct *status);
   int (*queue_pause)(int snum);
   int (*queue_resume)(int snum);
index b7e41964f1b7e8854ceea437a49a1bf2f13a9d5e..68c06ade41f0240df99dbb055d992d9182f5539b 100644 (file)
@@ -921,13 +921,13 @@ static BOOL parse_lpq_vlp(char *line,print_queue_struct *buf,BOOL first)
 parse a lpq line. Choose printing style
 ****************************************************************************/
 
-BOOL parse_lpq_entry(int snum,char *line,
+BOOL parse_lpq_entry(enum printing_types printing_type,char *line,
                     print_queue_struct *buf,
                     print_status_struct *status,BOOL first)
 {
   BOOL ret;
 
-  switch (lp_printing(snum))
+  switch (printing_type)
     {
     case PRINT_SYSV:
       ret = parse_lpq_sysv(line,buf,first);
@@ -971,7 +971,7 @@ BOOL parse_lpq_entry(int snum,char *line,
   }
 
   /* in the LPRNG case, we skip lines starting by a space.*/
-  if (line && !ret && (lp_printing(snum)==PRINT_LPRNG) )
+  if (line && !ret && (printing_type==PRINT_LPRNG) )
   {
        if (line[0]==' ')
                return ret;
index 10b5f74528784e516ed418542101f8cbfee98ab6..77326bee3e42d3b4f9f63096a03b533e2e016049 100644 (file)
@@ -297,7 +297,7 @@ to notify_queue_head\n", msg->type, msg->field, msg->printer));
        num_messages++;
 }
 
-static void send_notify_field_values(const char *printer_name, uint32 type,
+static void send_notify_field_values(const char *sharename, uint32 type,
                                     uint32 field, uint32 id, uint32 value1, 
                                     uint32 value2, uint32 flags)
 {
@@ -315,7 +315,7 @@ static void send_notify_field_values(const char *printer_name, uint32 type,
 
        ZERO_STRUCTP(msg);
 
-       fstrcpy(msg->printer, printer_name);
+       fstrcpy(msg->printer, sharename);
        msg->type = type;
        msg->field = field;
        msg->id = id;
@@ -326,7 +326,7 @@ static void send_notify_field_values(const char *printer_name, uint32 type,
        send_spoolss_notify2_msg(msg);
 }
 
-static void send_notify_field_buffer(const char *printer_name, uint32 type,
+static void send_notify_field_buffer(const char *sharename, uint32 type,
                                     uint32 field, uint32 id, uint32 len,
                                     char *buffer)
 {
@@ -344,7 +344,7 @@ static void send_notify_field_buffer(const char *printer_name, uint32 type,
 
        ZERO_STRUCTP(msg);
 
-       fstrcpy(msg->printer, printer_name);
+       fstrcpy(msg->printer, sharename);
        msg->type = type;
        msg->field = field;
        msg->id = id;
@@ -356,140 +356,131 @@ static void send_notify_field_buffer(const char *printer_name, uint32 type,
 
 /* Send a message that the printer status has changed */
 
-void notify_printer_status_byname(const char *printer_name, uint32 status)
+void notify_printer_status_byname(const char *sharename, uint32 status)
 {
        /* Printer status stored in value1 */
 
-       send_notify_field_values(printer_name, PRINTER_NOTIFY_TYPE, 
+       send_notify_field_values(sharename, PRINTER_NOTIFY_TYPE, 
                                 PRINTER_NOTIFY_STATUS, 0, 
                                 status, 0, 0);
 }
 
 void notify_printer_status(int snum, uint32 status)
 {
-       const char *printer_name = SERVICE(snum); 
+       const char *sharename = SERVICE(snum); 
 
-       if (printer_name)
-               notify_printer_status_byname(printer_name, status);
+       if (sharename)
+               notify_printer_status_byname(sharename, status);
 }
 
-void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 status,
+void notify_job_status_byname(const char *sharename, uint32 jobid, uint32 status,
                              uint32 flags)
 {
        /* Job id stored in id field, status in value1 */
 
-       send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
+       send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
                                 JOB_NOTIFY_STATUS, jobid,
                                 status, 0, flags);
 }
 
-void notify_job_status(int snum, uint32 jobid, uint32 status)
+void notify_job_status(const char *sharename, uint32 jobid, uint32 status)
 {
-       const char *printer_name = SERVICE(snum);
-
-       notify_job_status_byname(printer_name, jobid, status, 0);
+       notify_job_status_byname(sharename, jobid, status, 0);
 }
 
-void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
+void notify_job_total_bytes(const char *sharename, 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,
+       send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
                                 JOB_NOTIFY_TOTAL_BYTES, jobid,
                                 size, 0, 0);
 }
 
-void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
+void notify_job_total_pages(const char *sharename, 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,
+       send_notify_field_values(sharename, JOB_NOTIFY_TYPE,
                                 JOB_NOTIFY_TOTAL_PAGES, jobid,
                                 pages, 0, 0);
 }
 
-void notify_job_username(int snum, uint32 jobid, char *name)
+void notify_job_username(const char *sharename, uint32 jobid, char *name)
 {
-       const char *printer_name = SERVICE(snum);
-
        send_notify_field_buffer(
-               printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
+               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
                jobid, strlen(name) + 1, name);
 }
 
-void notify_job_name(int snum, uint32 jobid, char *name)
+void notify_job_name(const char *sharename, uint32 jobid, char *name)
 {
-       const char *printer_name = SERVICE(snum);
-
        send_notify_field_buffer(
-               printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
+               sharename, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
                jobid, strlen(name) + 1, name);
 }
 
-void notify_job_submitted(int snum, uint32 jobid, time_t submitted)
+void notify_job_submitted(const char *sharename, uint32 jobid,
+                         time_t submitted)
 {
-       const char *printer_name = SERVICE(snum);
-
        send_notify_field_buffer(
-               printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED,
+               sharename, 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);
+       const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,
+               sharename, 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);
+       const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,
+               sharename, 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);
+       const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
                snum, strlen(share_name) + 1, share_name);
 }
 
 void notify_printer_printername(int snum, char *printername)
 {
-       const char *printer_name = SERVICE(snum);
+       const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PRINTER_NAME,
                snum, strlen(printername) + 1, printername);
 }
 
 void notify_printer_port(int snum, char *port_name)
 {
-       const char *printer_name = SERVICE(snum);
+       const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,
+               sharename, 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);
+       const char *sharename = SERVICE(snum);
 
        send_notify_field_buffer(
-               printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
+               sharename, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
                snum, strlen(location) + 1, location);
 }
 
index 3097811fac2ce9e3f27397b8f4434bf63e627c39..ad01a68c8e6bc431ba18a5cbc12c6ac5303d1d28 100644 (file)
 #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...
  */
@@ -811,7 +786,11 @@ cups_job_submit(int snum, struct printjob *pjob)
  */
 
 static int
-cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
+cups_queue_get(const char *printer_name,
+               enum printing_types printing_type,
+               char *lpq_command,
+               print_queue_struct **q, 
+               print_status_struct *status)
 {
        http_t          *http;          /* HTTP connection to server */
        ipp_t           *request,       /* IPP Request */
@@ -847,7 +826,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
                        };
 
 
-       DEBUG(5,("cups_queue_get(%d, %p, %p)\n", snum, q, status));
+       DEBUG(5,("cups_queue_get(%s, %p, %p)\n", printer_name, q, status));
 
        /*
         * Make sure we don't ask for passwords...
@@ -870,8 +849,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
         * Generate the printer URI...
        */
 
-       slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s",
-                PRINTERNAME(snum));
+       slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", printer_name);
 
        /*
        * Build an IPP_GET_JOBS request, which requires the following
@@ -1090,7 +1068,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
 
        if ((response = cupsDoRequest(http, request, "/")) == NULL)
        {
-               DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
+               DEBUG(0,("Unable to get printer status for %s - %s\n", printer_name,
                         ippErrorString(cupsLastError())));
                httpClose(http);
                *q = queue;
@@ -1099,7 +1077,7 @@ cups_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
 
        if (response->request.status.status_code >= IPP_OK_CONFLICT)
        {
-               DEBUG(0,("Unable to get printer status for %s - %s\n", PRINTERNAME(snum),
+               DEBUG(0,("Unable to get printer status for %s - %s\n", printer_name,
                         ippErrorString(response->request.status.status_code)));
                ippDelete(response);
                httpClose(http);
@@ -1319,6 +1297,21 @@ cups_queue_resume(int snum)
        return (ret);
 }
 
+/*******************************************************************
+ * CUPS printing interface definitions...
+ ******************************************************************/
+
+struct printif cups_printif =
+{
+       PRINT_CUPS,
+       cups_queue_get,
+       cups_queue_pause,
+       cups_queue_resume,
+       cups_job_delete,
+       cups_job_pause,
+       cups_job_resume,
+       cups_job_submit,
+};
 
 #else
  /* this keeps fussy compilers happy */
index 9e0ea85bb9adcb6b0ad46e1ccd844649a9943fe0..d6074704b3fe960f39e42e95a4d0674c30268da0 100644 (file)
 #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, ...)
+static int print_run_command(int snum, const char* printername, BOOL do_sub, char *command, int *outfd, ...)
 {
 
        pstring syscmd;
@@ -61,12 +36,13 @@ static int print_run_command(int snum,char *command, int *outfd, ...)
        va_list ap;
        va_start(ap, outfd);
 
-       if (!command || !*command) return -1;
+       /* check for a valid system printername and valid command to run */
 
-       if (!VALID_SNUM(snum)) {
-               DEBUG(0,("Invalid snum %d for command %s\n", snum, command));
+       if ( !printername || !*printername ) 
+               return -1;
+
+       if (!command || !*command) 
                return -1;
-       }
 
        pstrcpy(syscmd, command);
 
@@ -76,9 +52,11 @@ static int print_run_command(int snum,char *command, int *outfd, ...)
        }
        va_end(ap);
   
-       pstring_sub(syscmd, "%p", PRINTERNAME(snum));
-       standard_sub_snum(snum,syscmd,sizeof(syscmd));
+       pstring_sub( syscmd, "%p", printername );
 
+       if ( do_sub && snum != -1 )
+               standard_sub_snum(snum,syscmd,sizeof(syscmd));
+               
        ret = smbrun(syscmd,outfd);
 
        DEBUG(3,("Running the command `%s' gave %d\n",syscmd,ret));
@@ -96,8 +74,7 @@ static int generic_job_delete(int snum, struct printjob *pjob)
 
        /* need to delete the spooled entry */
        slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
-       return print_run_command(
-                  snum, 
+       return print_run_command(snum, PRINTERNAME(snum), True,
                   lp_lprmcommand(snum), NULL,
                   "%j", jobstr,
                   "%T", http_timestring(pjob->starttime),
@@ -113,7 +90,7 @@ static int generic_job_pause(int snum, struct printjob *pjob)
        
        /* need to pause the spooled entry */
        slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
-       return print_run_command(snum, 
+       return print_run_command(snum, PRINTERNAME(snum), True,
                                 lp_lppausecommand(snum), NULL,
                                 "%j", jobstr,
                                 NULL);
@@ -128,7 +105,7 @@ static int generic_job_resume(int snum, struct printjob *pjob)
        
        /* need to pause the spooled entry */
        slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
-       return print_run_command(snum, 
+       return print_run_command(snum, PRINTERNAME(snum), True,
                                 lp_lpresumecommand(snum), NULL,
                                 "%j", jobstr,
                                 NULL);
@@ -168,7 +145,7 @@ static int generic_job_submit(int snum, struct printjob *pjob)
        slprintf(job_size, sizeof(job_size)-1, "%lu", (unsigned long)pjob->size);
 
        /* send it to the system spooler */
-       ret = print_run_command(snum, 
+       ret = print_run_command(snum, PRINTERNAME(snum), True,
                        lp_printcommand(snum), NULL,
                        "%s", p,
                        "%J", jobname,
@@ -186,17 +163,22 @@ static int generic_job_submit(int snum, struct printjob *pjob)
 /****************************************************************************
 get the current list of queued jobs
 ****************************************************************************/
-static int generic_queue_get(int snum, print_queue_struct **q, print_status_struct *status)
+static int generic_queue_get(const char *printer_name, 
+                             enum printing_types printing_type,
+                             char *lpq_command,
+                             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);
+       /* never do substitution when running the 'lpq command' since we can't
+          get it rigt when using the background update daemon.  Make the caller 
+          do it before passing off the command string to us here. */
+
+       print_run_command(-1, printer_name, False, lpq_command, &fd, NULL);
 
        if (fd == -1) {
                DEBUG(5,("generic_queue_get: Can't read print queue status for printer %s\n",
@@ -218,7 +200,7 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru
                memset(queue, '\0', sizeof(print_queue_struct)*(numlines+1));
                for (i=0; i<numlines; i++) {
                        /* parse the line */
-                       if (parse_lpq_entry(snum,qlines[i],
+                       if (parse_lpq_entry(printing_type,qlines[i],
                                            &queue[qcount],status,qcount==0)) {
                                qcount++;
                        }
@@ -235,7 +217,7 @@ static int generic_queue_get(int snum, print_queue_struct **q, print_status_stru
 ****************************************************************************/
 static int generic_queue_pause(int snum)
 {
-       return print_run_command(snum, lp_queuepausecommand(snum), NULL, NULL);
+       return print_run_command(snum, PRINTERNAME(snum), True, lp_queuepausecommand(snum), NULL, NULL);
 }
 
 /****************************************************************************
@@ -243,5 +225,22 @@ static int generic_queue_pause(int snum)
 ****************************************************************************/
 static int generic_queue_resume(int snum)
 {
-       return print_run_command(snum, lp_queueresumecommand(snum), NULL, NULL);
+       return print_run_command(snum, PRINTERNAME(snum), True, lp_queueresumecommand(snum), NULL, NULL);
 }
+
+/****************************************************************************
+ * Generic printing interface definitions...
+ ***************************************************************************/
+
+struct printif generic_printif =
+{
+       DEFAULT_PRINTING,
+       generic_queue_get,
+       generic_queue_pause,
+       generic_queue_resume,
+       generic_job_delete,
+       generic_job_pause,
+       generic_job_resume,
+       generic_job_submit,
+};
+
index 0b6d4fdbe1cef6bbf645f21846c6cafc4e6afe90..7c5de468701ce217b44fca62421c908adfa241d1 100644 (file)
@@ -53,16 +53,16 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
        }
 
        /* Convert to RAP id. */
-       fsp->rap_print_jobid = pjobid_to_rap(SNUM(conn), jobid);
+       fsp->rap_print_jobid = pjobid_to_rap(lp_const_servicename(SNUM(conn)), jobid);
        if (fsp->rap_print_jobid == 0) {
                /* We need to delete the entry in the tdb. */
-               pjob_delete(SNUM(conn), jobid);
+               pjob_delete(lp_const_servicename(SNUM(conn)), jobid);
                file_free(fsp);
                return NULL;
        }
 
        /* setup a full fsp */
-       fsp->fd = print_job_fd(SNUM(conn),jobid);
+       fsp->fd = print_job_fd(lp_const_servicename(SNUM(conn)),jobid);
        GetTimeOfDay(&fsp->open_time);
        fsp->vuid = current_user.vuid;
        fsp->size = 0;
@@ -77,7 +77,7 @@ files_struct *print_fsp_open(connection_struct *conn, char *fname)
        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));
+       string_set(&fsp->fsp_name,print_job_fname(lp_const_servicename(SNUM(conn)),jobid));
        fsp->wbmpx_ptr = NULL;      
        fsp->wcp = NULL; 
        SMB_VFS_FSTAT(fsp,fsp->fd, &sbuf);
@@ -96,7 +96,7 @@ print a file - called on closing the file
 void print_fsp_end(files_struct *fsp, BOOL normal_close)
 {
        uint32 jobid;
-       int snum;
+       fstring sharename;
 
        if (fsp->share_mode == FILE_DELETE_ON_CLOSE) {
                /*
@@ -110,7 +110,7 @@ void print_fsp_end(files_struct *fsp, BOOL normal_close)
                string_free(&fsp->fsp_name);
        }
 
-       if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) {
+       if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) {
                DEBUG(3,("print_fsp_end: Unable to convert RAP jobid %u to print jobid.\n",
                        (unsigned int)fsp->rap_print_jobid ));
                return;
index 60adcc4d7f07e2f48c8d205b2e8f1e1f7131e245..1e897c962a61ac7ab10334ebff999d77c0fecb8b 100644 (file)
@@ -27,7 +27,7 @@ extern SIG_ATOMIC_T got_sig_term;
 extern SIG_ATOMIC_T reload_after_sighup;
 
 /* Current printer interface */
-static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
+static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid);
 
 /* 
    the printing backend revolves around a tdb database that stores the
@@ -50,12 +50,16 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
 
 static TDB_CONTEXT *rap_tdb;
 static uint16 next_rap_jobid;
+struct rap_jobid_key {
+       fstring sharename;
+       uint32  jobid;
+};
 
-uint16 pjobid_to_rap(int snum, uint32 jobid)
+uint16 pjobid_to_rap(const char* sharename, uint32 jobid)
 {
        uint16 rap_jobid;
        TDB_DATA data, key;
-       char jinfo[8];
+       struct rap_jobid_key jinfo;
 
        DEBUG(10,("pjobid_to_rap: called.\n"));
 
@@ -66,18 +70,18 @@ uint16 pjobid_to_rap(int snum, uint32 jobid)
                        return 0;
        }
 
-       SIVAL(&jinfo,0,(int32)snum);
-       SIVAL(&jinfo,4,jobid);
-
-       key.dptr = (char *)&jinfo;
+       ZERO_STRUCT( jinfo );
+       fstrcpy( jinfo.sharename, sharename );
+       jinfo.jobid = jobid;
+       key.dptr = (char*)&jinfo;
        key.dsize = sizeof(jinfo);
+
        data = tdb_fetch(rap_tdb, key);
        if (data.dptr && data.dsize == sizeof(uint16)) {
                rap_jobid = SVAL(data.dptr, 0);
                SAFE_FREE(data.dptr);
                DEBUG(10,("pjobid_to_rap: jobid %u maps to RAP jobid %u\n",
-                               (unsigned int)jobid,
-                               (unsigned int)rap_jobid));
+                       (unsigned int)jobid, (unsigned int)rap_jobid));
                return rap_jobid;
        }
        SAFE_FREE(data.dptr);
@@ -91,12 +95,11 @@ uint16 pjobid_to_rap(int snum, uint32 jobid)
        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));
+               (unsigned int)jobid, (unsigned int)rap_jobid));
        return rap_jobid;
 }
 
-BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
+BOOL rap_to_pjobid(uint16 rap_jobid, fstring sharename, uint32 *pjobid)
 {
        TDB_DATA data, key;
 
@@ -108,48 +111,50 @@ BOOL rap_to_pjobid(uint16 rap_jobid, int *psnum, uint32 *pjobid)
        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);
+       if ( data.dptr && data.dsize == sizeof(struct rap_jobid_key) ) 
+       {
+               struct rap_jobid_key *jinfo = (struct rap_jobid_key*)data.dptr;
+               fstrcpy( sharename, jinfo->sharename );
+               *pjobid = jinfo->jobid;
                DEBUG(10,("rap_to_pjobid: jobid %u maps to RAP jobid %u\n",
-                               (unsigned int)*pjobid,
-                               (unsigned int)rap_jobid));
+                       (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));
+               (unsigned int)rap_jobid));
        SAFE_FREE(data.dptr);
        return False;
 }
 
-static void rap_jobid_delete(int snum, uint32 jobid)
+static void rap_jobid_delete(const char* sharename, uint32 jobid)
 {
        TDB_DATA key, data;
        uint16 rap_jobid;
-       char jinfo[8];
+       struct rap_jobid_key jinfo;
 
        DEBUG(10,("rap_jobid_delete: called.\n"));
 
        if (!rap_tdb)
                return;
 
-       SIVAL(&jinfo,0,(int32)snum);
-       SIVAL(&jinfo,4,jobid);
-
-       key.dptr = (char *)&jinfo;
+       ZERO_STRUCT( jinfo );
+       fstrcpy( jinfo.sharename, sharename );
+       jinfo.jobid = 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 ));
+                       (unsigned int)jobid ));
                SAFE_FREE(data.dptr);
                return;
        }
 
        DEBUG(10,("rap_jobid_delete: deleting jobid %u\n",
-                               (unsigned int)jobid ));
+               (unsigned int)jobid ));
 
        rap_jobid = SVAL(data.dptr, 0);
        SAFE_FREE(data.dptr);
@@ -159,7 +164,7 @@ static void rap_jobid_delete(int snum, uint32 jobid)
        tdb_delete(rap_tdb, data);
 }
 
-static int get_queue_status(int, print_status_struct *);
+static int get_queue_status(const char* sharename, print_status_struct *);
 
 /****************************************************************************
  Initialise the printing backend. Called once at startup before the fork().
@@ -223,19 +228,27 @@ void printing_end(void)
  when asked for (and only when supported)
 ****************************************************************************/
 
-static struct printif *get_printer_fns( int snum )
+static struct printif *get_printer_fns_from_type( enum printing_types type )
 {
        struct printif *printer_fns = &generic_printif;
 
 #ifdef HAVE_CUPS
-       if ( lp_printing(snum) == PRINT_CUPS ) {
+       if ( type == PRINT_CUPS ) {
                printer_fns = &cups_printif;
        }
 #endif /* HAVE_CUPS */
+
+       printer_fns->type = type;
        
        return printer_fns;
 }
 
+static struct printif *get_printer_fns( int snum )
+{
+       return get_printer_fns_from_type( lp_printing(snum) );
+}
+
+
 /****************************************************************************
  Useful function to generate a tdb key.
 ****************************************************************************/
@@ -306,11 +319,11 @@ int unpack_pjob( char* buf, int buflen, struct printjob *pjob )
  Useful function to find a print job in the database.
 ****************************************************************************/
 
-static struct printjob *print_job_find(int snum, uint32 jobid)
+static struct printjob *print_job_find(const char *sharename, uint32 jobid)
 {
        static struct printjob  pjob;
        TDB_DATA                ret;
-       struct tdb_print_db     *pdb = get_print_db_byname(lp_const_servicename(snum));
+       struct tdb_print_db     *pdb = get_print_db_byname(sharename);
        
 
        if (!pdb)
@@ -427,7 +440,7 @@ static uint32 map_to_spoolss_status(uint32 lpq_status)
        return 0;
 }
 
-static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
+static void pjob_store_notify(const char* sharename, uint32 jobid, struct printjob *old_data,
                              struct printjob *new_data)
 {
        BOOL new_job = False;
@@ -446,38 +459,38 @@ static void pjob_store_notify(int snum, uint32 jobid, struct printjob *old_data,
           --jerry (i'll feel dirty for this) */
  
        if (new_job) {
-               notify_job_submitted(snum, jobid, new_data->starttime);
-               notify_job_username(snum, jobid, new_data->user);
+               notify_job_submitted(sharename, jobid, new_data->starttime);
+               notify_job_username(sharename, jobid, new_data->user);
        }
 
        if (new_job || !strequal(old_data->jobname, new_data->jobname))
-               notify_job_name(snum, jobid, new_data->jobname);
+               notify_job_name(sharename, jobid, new_data->jobname);
 
        /* Job attributes of a new job or attributes that can be
           modified. */
 
        if (new_job || !strequal(old_data->jobname, new_data->jobname))
-               notify_job_name(snum, jobid, new_data->jobname);
+               notify_job_name(sharename, jobid, new_data->jobname);
 
        if (new_job || old_data->status != new_data->status)
-               notify_job_status(snum, jobid, map_to_spoolss_status(new_data->status));
+               notify_job_status(sharename, 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);
+               notify_job_total_bytes(sharename, 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);
+               notify_job_total_pages(sharename, jobid, new_data->page_count);
 }
 
 /****************************************************************************
  Store a job structure back to the database.
 ****************************************************************************/
 
-static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
+static BOOL pjob_store(const char* sharename, 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));
+       struct tdb_print_db     *pdb = get_print_db_byname(sharename);
        char                    *buf = NULL;
        int                     len, newlen, buflen;
        
@@ -545,13 +558,13 @@ static BOOL pjob_store(int snum, uint32 jobid, struct printjob *pjob)
                {
                        if ( unpack_pjob( old_data.dptr, old_data.dsize, &old_pjob ) != -1 )
                        {
-                               pjob_store_notify( snum, jobid, &old_pjob , pjob );
+                               pjob_store_notify( sharename, jobid, &old_pjob , pjob );
                                free_nt_devicemode( &old_pjob.nt_devmode );
                        }
                }
                else {
                        /* new job */
-                       pjob_store_notify( snum, jobid, NULL, pjob );
+                       pjob_store_notify( sharename, jobid, NULL, pjob );
                }
        }
 
@@ -566,15 +579,19 @@ done:
  Remove a job structure from the database.
 ****************************************************************************/
 
-void pjob_delete(int snum, uint32 jobid)
+void pjob_delete(const char* sharename, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       struct printjob *pjob;
        uint32 job_status = 0;
-       struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
+       struct tdb_print_db *pdb;
+
+       pdb = get_print_db_byname( sharename );
 
        if (!pdb)
                return;
 
+       pjob = print_job_find( sharename, jobid );
+
        if (!pjob) {
                DEBUG(5, ("pjob_delete: we were asked to delete nonexistent job %u\n",
                                        (unsigned int)jobid));
@@ -587,14 +604,14 @@ void pjob_delete(int snum, uint32 jobid)
            properly. */
        
        job_status = JOB_STATUS_DELETING|JOB_STATUS_DELETED;
-       notify_job_status(snum, jobid, job_status);
+       notify_job_status(sharename, jobid, job_status);
        
        /* Remove from printing.tdb */
 
        tdb_delete(pdb->tdb, print_key(jobid));
-       remove_from_jobs_changed(snum, jobid);
-       release_print_db(pdb);
-       rap_jobid_delete(snum, jobid);
+       remove_from_jobs_changed(sharename, jobid);
+       release_print_db( pdb );
+       rap_jobid_delete(sharename, jobid);
 }
 
 /****************************************************************************
@@ -620,7 +637,7 @@ static uint32 print_parse_jobid(char *fname)
  List a unix job in the print database.
 ****************************************************************************/
 
-static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
+static void print_unix_job(const char *sharename, print_queue_struct *q, uint32 jobid)
 {
        struct printjob pj, *old_pj;
 
@@ -629,7 +646,7 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
 
        /* Preserve the timestamp on an existing unix print job */
 
-       old_pj = print_job_find(snum, jobid);
+       old_pj = print_job_find(sharename, jobid);
 
        ZERO_STRUCT(pj);
 
@@ -649,15 +666,16 @@ static void print_unix_job(int snum, print_queue_struct *q, uint32 jobid)
                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));
+       fstrcpy(pj.queuename, old_pj ? old_pj->queuename : sharename );
 
-       pjob_store(snum, jobid, &pj);
+       pjob_store(sharename, jobid, &pj);
 }
 
 
 struct traverse_struct {
        print_queue_struct *queue;
        int qcount, snum, maxcount, total_jobs;
+       const char *sharename;
        time_t lpq_time;
 };
 
@@ -681,11 +699,6 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
        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 */
 
@@ -697,7 +710,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                if (i == ts->qcount) {
                        DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
                                                (unsigned int)jobid ));
-                       pjob_delete(ts->snum, jobid);
+                       pjob_delete(ts->sharename, jobid);
                        return 0;
                } 
 
@@ -713,7 +726,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                if (!process_exists(pjob.pid)) {
                        DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !process_exists (%u)\n",
                                                (unsigned int)jobid, (unsigned int)pjob.pid ));
-                       pjob_delete(ts->snum, jobid);
+                       pjob_delete(ts->sharename, jobid);
                } else
                        ts->total_jobs++;
                return 0;
@@ -746,7 +759,7 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
                                                (unsigned int)jobid,
                                                (unsigned int)pjob.starttime,
                                                (unsigned int)ts->lpq_time ));
-                       pjob_delete(ts->snum, jobid);
+                       pjob_delete(ts->sharename, jobid);
                } else
                        ts->total_jobs++;
                return 0;
@@ -776,12 +789,12 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
 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);
+       const char *sharename = lp_const_servicename(snum);
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
 
        if (!pdb)
                return;
-       slprintf(key, sizeof(key)-1, "CACHE/%s", printername);
+       slprintf(key, sizeof(key)-1, "CACHE/%s", sharename);
        tdb_store_int32(pdb->tdb, key, -1);
        release_print_db(pdb);
 }
@@ -790,16 +803,16 @@ static void print_cache_flush(int snum)
  Check if someone already thinks they are doing the update.
 ****************************************************************************/
 
-static pid_t get_updating_pid(fstring printer_name)
+static pid_t get_updating_pid(fstring sharename)
 {
        fstring keystr;
        TDB_DATA data, key;
        pid_t updating_pid;
-       struct tdb_print_db *pdb = get_print_db_byname(printer_name);
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
 
        if (!pdb)
                return (pid_t)-1;
-       slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
+       slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
        key.dptr = keystr;
        key.dsize = strlen(keystr);
 
@@ -824,7 +837,7 @@ static pid_t get_updating_pid(fstring printer_name)
  in the tdb.
 ****************************************************************************/
 
-static void set_updating_pid(const fstring printer_name, BOOL delete)
+static void set_updating_pid(const fstring sharename, BOOL delete)
 {
        fstring keystr;
        TDB_DATA key;
@@ -832,12 +845,12 @@ static void set_updating_pid(const fstring printer_name, BOOL delete)
        pid_t updating_pid = sys_getpid();
        uint8 buffer[4];
        
-       struct tdb_print_db *pdb = get_print_db_byname(printer_name);
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
 
        if (!pdb)
                return;
 
-       slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", printer_name);
+       slprintf(keystr, sizeof(keystr)-1, "UPDATING/%s", sharename);
        key.dptr = keystr;
        key.dsize = strlen(keystr);
 
@@ -951,7 +964,7 @@ static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
        return data;
 }
 
-static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
+static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid)
 {
        unsigned int i;
        unsigned int job_count = data.dsize / 4;
@@ -961,15 +974,23 @@ static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
 
                ch_jobid = IVAL(data.dptr, i*4);
                if (ch_jobid == jobid)
-                       remove_from_jobs_changed(snum, jobid);
+                       remove_from_jobs_changed(sharename, jobid);
        }
 }
 
+struct print_queue_update_context {
+       fstring sharename;
+       enum printing_types printing_type;
+       pstring lpqcommand;
+};
+
 /****************************************************************************
- Update the internal database from the system print queue for a queue.
+ main work for updating the lpq cahe for a printer queue
 ****************************************************************************/
 
-static void print_queue_update_internal(int snum)
+static void print_queue_update_internal( const char *sharename, 
+                                         struct printif *current_printif,
+                                         char *lpq_command )
 {
        int i, qcount;
        print_queue_struct *queue = NULL;
@@ -977,88 +998,35 @@ static void print_queue_update_internal(int snum)
        print_status_struct old_status;
        struct printjob *pjob;
        struct traverse_struct tstruct;
-       fstring keystr, printer_name, cachestr;
        TDB_DATA data, key;
        TDB_DATA jcdata;
-       struct tdb_print_db *pdb;
-       struct printif *current_printif = get_printer_fns( snum );
-
-       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);
-
+       fstring keystr, cachestr;
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
+       
        /*
         * 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);
+       slprintf(cachestr, sizeof(cachestr)-1, "CACHE/%s", sharename);
        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);
+       qcount = (*(current_printif->queue_get))(sharename, 
+               current_printif->type, 
+               lpq_command, &queue, &status);
 
        DEBUG(3, ("%d job%s in queue for %s\n", qcount, (qcount != 1) ?
-               "s" : "", printer_name));
+               "s" : "", sharename));
 
        /* Sort the queue by submission time otherwise they are displayed
           in hash order. */
 
        qsort(queue, qcount, sizeof(print_queue_struct),
-             QSORT_CAST(printjob_comp));
+               QSORT_CAST(printjob_comp));
 
        /*
          any job in the internal database that is marked as spooled
@@ -1078,24 +1046,24 @@ static void print_queue_update_internal(int snum)
 
                if (jobid == (uint32)-1) {
                        /* assume its a unix print job */
-                       print_unix_job(snum, &queue[i], jobid);
+                       print_unix_job(sharename, &queue[i], jobid);
                        continue;
                }
 
                /* we have an active SMB print job - update its status */
-               pjob = print_job_find(snum, jobid);
+               pjob = print_job_find(sharename, 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);
+                       print_unix_job(sharename, &queue[i], jobid);
                        continue;
                }
 
                pjob->sysjob = queue[i].job;
                pjob->status = queue[i].status;
-               pjob_store(snum, jobid, pjob);
-               check_job_changed(snum, jcdata, jobid);
+               pjob_store(sharename, jobid, pjob);
+               check_job_changed(sharename, jcdata, jobid);
        }
 
        SAFE_FREE(jcdata.dptr);
@@ -1104,9 +1072,10 @@ static void print_queue_update_internal(int snum)
            system queue */
        tstruct.queue = queue;
        tstruct.qcount = qcount;
-       tstruct.snum = snum;
+       tstruct.snum = -1;
        tstruct.total_jobs = 0;
        tstruct.lpq_time = time(NULL);
+       tstruct.sharename = sharename;
 
        tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
 
@@ -1116,17 +1085,17 @@ static void print_queue_update_internal(int snum)
        SAFE_FREE(tstruct.queue);
 
        DEBUG(10,("print_queue_update: printer %s INFO/total_jobs = %d\n",
-                               printer_name, tstruct.total_jobs ));
+                               sharename, tstruct.total_jobs ));
 
        tdb_store_int32(pdb->tdb, "INFO/total_jobs", tstruct.total_jobs);
 
-       get_queue_status(snum, &old_status);
+       get_queue_status(sharename, &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 ));
+                                       old_status.qcount, qcount, sharename));
 
        /* store the new queue status structure */
-       slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printer_name);
+       slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
        key.dptr = keystr;
        key.dsize = strlen(keystr);
 
@@ -1140,11 +1109,90 @@ static void print_queue_update_internal(int snum)
         * as little as possible...
         */
 
-       slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", printer_name);
+       slprintf(keystr, sizeof(keystr)-1, "CACHE/%s", sharename);
        tdb_store_int32(pdb->tdb, keystr, (int32)time(NULL));
 
+}
+
+/****************************************************************************
+ Update the internal database from the system print queue for a queue.
+ obtain a lock on the print queue before proceeding (needed when mutiple
+ smbd processes maytry to update the lpq cache concurrently).
+****************************************************************************/
+
+static void print_queue_update_with_lock(int snum)
+{
+       fstring sharename, keystr;
+       pstring lpq_command;
+       struct tdb_print_db *pdb;
+       struct printif *current_printif = get_printer_fns( snum );
+
+       fstrcpy(sharename, lp_const_servicename(snum));
+       pdb = get_print_db_byname(sharename);
+       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(sharename) != -1) {
+               release_print_db(pdb);
+               return;
+       }
+
+       /* Lock the queue for the database update */
+
+       slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", sharename);
+       /* 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", sharename));
+               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(sharename) != -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(sharename, False);
+
+       /*
+        * Allow others to enter and notice we're doing
+        * the update.
+        */
+
+       tdb_unlock_bystring(pdb->tdb, keystr);
+
+       /* do the main work now */
+       /* have to substitute any variables here since 
+           print_queue_get_internal() will not */
+       
+       pstrcpy( lpq_command, lp_lpqcommand(snum) );
+       pstring_sub( lpq_command, "%p", PRINTERNAME(snum) );
+       standard_sub_snum( snum, lpq_command, sizeof(lpq_command) );
+       
+       print_queue_update_internal( sharename, current_printif, lpq_command );
+       
        /* Delete our pid from the db. */
-       set_updating_pid(printer_name, True);
+       set_updating_pid(sharename, True);
        release_print_db(pdb);
 }
 
@@ -1153,9 +1201,17 @@ this is the receive function of the background lpq updater
 ****************************************************************************/
 static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t len)
 {
-       int snum;
-       snum=*((int *)buf);
-       print_queue_update_internal(snum);
+       struct print_queue_update_context *ctx;
+
+       if (len != sizeof(struct print_queue_update_context)) {
+               DEBUG(1, ("Got invalid print queue update message\n"));
+               return;
+       }
+
+       ctx = (struct print_queue_update_context*)buf;
+       print_queue_update_internal(ctx->sharename, 
+               get_printer_fns_from_type(ctx->printing_type),
+               ctx->lpqcommand );
 }
 
 static pid_t background_lpq_updater_pid = -1;
@@ -1207,6 +1263,10 @@ void start_background_queue(void)
                        
                        DEBUG(10,("start_background_queue: background LPQ thread got a message\n"));
                        message_dispatch();
+
+                       /* process any pending print change notify messages */
+
+                       print_notify_send_messages(0);
                }
        }
 }
@@ -1216,19 +1276,28 @@ update the internal database from the system print queue for a queue
 ****************************************************************************/
 static void print_queue_update(int snum)
 {
+       struct print_queue_update_context ctx;
+
        /* 
-        * Make sure that the backgroup queueu process exists.  
+        * Make sure that the background queue process exists.  
         * Otherwise just do the update ourselves 
         */
           
        if ( background_lpq_updater_pid != -1 ) {
+               fstrcpy(ctx.sharename, lp_const_servicename(snum));
+               ctx.printing_type = lp_printing(snum);
+
+               pstrcpy(ctx.lpqcommand, lp_lpqcommand(snum));
+               pstring_sub( ctx.lpqcommand, "%p", PRINTERNAME(snum) );
+               standard_sub_snum( snum, ctx.lpqcommand, sizeof(ctx.lpqcommand) );
+       
                become_root();
                message_send_pid(background_lpq_updater_pid,
-                                MSG_PRINTER_UPDATE, &snum, sizeof(snum),
+                                MSG_PRINTER_UPDATE, &ctx, sizeof(ctx),
                                 False);
                unbecome_root();
        } else
-               print_queue_update_internal( snum );
+               print_queue_update_with_lock( snum );
 }
 
 /****************************************************************************
@@ -1416,9 +1485,9 @@ list for printer %s\n", printername));
  Check if a jobid is valid. It is valid if it exists in the database.
 ****************************************************************************/
 
-BOOL print_job_exists(int snum, uint32 jobid)
+BOOL print_job_exists(const char* sharename, uint32 jobid)
 {
-       struct tdb_print_db *pdb = get_print_db_byname(lp_const_servicename(snum));
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
        BOOL ret;
 
        if (!pdb)
@@ -1432,9 +1501,9 @@ BOOL print_job_exists(int snum, uint32 jobid)
  Give the fd used for a jobid.
 ****************************************************************************/
 
-int print_job_fd(int snum, uint32 jobid)
+int print_job_fd(const char* sharename, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       struct printjob *pjob = print_job_find(sharename, jobid);
        if (!pjob)
                return -1;
        /* don't allow another process to get this info - it is meaningless */
@@ -1449,9 +1518,9 @@ int print_job_fd(int snum, uint32 jobid)
  has not been spooled.
 ****************************************************************************/
 
-char *print_job_fname(int snum, uint32 jobid)
+char *print_job_fname(const char* sharename, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       struct printjob *pjob = print_job_find(sharename, jobid);
        if (!pjob || pjob->spooled || pjob->pid != sys_getpid())
                return NULL;
        return pjob->filename;
@@ -1464,9 +1533,9 @@ char *print_job_fname(int snum, uint32 jobid)
  has not been spooled.
 ****************************************************************************/
 
-NT_DEVICEMODE *print_job_devmode(int snum, uint32 jobid)
+NT_DEVICEMODE *print_job_devmode(const char* sharename, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       struct printjob *pjob = print_job_find(sharename, jobid);
        
        if ( !pjob )
                return NULL;
@@ -1490,22 +1559,24 @@ BOOL print_job_set_place(int snum, uint32 jobid, int place)
 
 BOOL print_job_set_name(int snum, uint32 jobid, char *name)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       const char* sharename = lp_const_servicename(snum);
+       struct printjob *pjob;
+
+       pjob = print_job_find(sharename, jobid);
        if (!pjob || pjob->pid != sys_getpid())
                return False;
 
        fstrcpy(pjob->jobname, name);
-       return pjob_store(snum, jobid, pjob);
+       return pjob_store(sharename, jobid, pjob);
 }
 
 /***************************************************************************
  Remove a jobid from the 'jobs changed' list.
 ***************************************************************************/
 
-static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
+static BOOL remove_from_jobs_changed(const char* sharename, uint32 jobid)
 {
-       const char *printername = lp_const_servicename(snum);
-       struct tdb_print_db *pdb = get_print_db_byname(printername);
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
        TDB_DATA data, key;
        size_t job_count, i;
        BOOL ret = False;
@@ -1560,10 +1631,13 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
 
 static BOOL print_job_delete1(int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       const char* sharename = lp_const_servicename(snum);
+       struct printjob *pjob = print_job_find(sharename, jobid);
        int result = 0;
        struct printif *current_printif = get_printer_fns( snum );
 
+       pjob = print_job_find(sharename, jobid);
+
        if (!pjob)
                return False;
 
@@ -1584,7 +1658,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
        /* Set the tdb entry to be deleting. */
 
        pjob->status = LPQ_DELETING;
-       pjob_store(snum, jobid, pjob);
+       pjob_store(sharename, jobid, pjob);
 
        if (pjob->spooled && pjob->sysjob != -1)
                result = (*(current_printif->job_delete))(snum, pjob);
@@ -1593,13 +1667,12 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
           been spooled. */
 
        if (result == 0) {
-               const char *printername = lp_const_servicename(snum);
-               struct tdb_print_db *pdb = get_print_db_byname(printername);
+               struct tdb_print_db *pdb = get_print_db_byname(sharename);
                int njobs = 1;
 
                if (!pdb)
                        return False;
-               pjob_delete(snum, jobid);
+               pjob_delete(sharename, jobid);
                /* 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);
@@ -1614,7 +1687,7 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
 
 static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       struct printjob *pjob = print_job_find(lp_const_servicename(snum), jobid);
        user_struct *vuser;
 
        if (!pjob || !user)
@@ -1633,6 +1706,7 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
 
 BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
 {
+       const char* sharename = lp_const_servicename( snum );
        BOOL    owner, deleted;
        char    *fname;
 
@@ -1665,7 +1739,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
         * spool file & return.
         */
         
-       if ( (fname = print_job_fname( snum, jobid )) != NULL )
+       if ( (fname = print_job_fname( sharename, jobid )) != NULL )
        {
                /* remove the spool file */
                DEBUG(10,("print_job_delete: Removing spool file [%s]\n", fname ));
@@ -1685,7 +1759,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
        print_queue_update(snum);
        
-       deleted = !print_job_exists(snum, jobid);
+       deleted = !print_job_exists(sharename, jobid);
        if ( !deleted )
                *errcode = WERR_ACCESS_DENIED;
 
@@ -1698,9 +1772,12 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
 BOOL print_job_pause(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       const char* sharename = lp_const_servicename(snum);
+       struct printjob *pjob;
        int ret = -1;
        struct printif *current_printif = get_printer_fns( snum );
+
+       pjob = print_job_find(sharename, jobid);
        
        if (!pjob || !user) 
                return False;
@@ -1736,7 +1813,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
        /* Send a printer notify message */
 
-       notify_job_status(snum, jobid, JOB_STATUS_PAUSED);
+       notify_job_status(sharename, jobid, JOB_STATUS_PAUSED);
 
        /* how do we tell if this succeeded? */
 
@@ -1749,9 +1826,12 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
 BOOL print_job_resume(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       const char *sharename = lp_const_servicename(snum);
+       struct printjob *pjob;
        int ret;
        struct printif *current_printif = get_printer_fns( snum );
+
+       pjob = print_job_find(sharename, jobid);
        
        if (!pjob || !user)
                return False;
@@ -1785,7 +1865,7 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
        /* Send a printer notify message */
 
-       notify_job_status(snum, jobid, JOB_STATUS_QUEUED);
+       notify_job_status(sharename, jobid, JOB_STATUS_QUEUED);
 
        return True;
 }
@@ -1796,8 +1876,11 @@ pause, or resume print job. User name: %s. Printer name: %s.",
 
 int print_job_write(int snum, uint32 jobid, const char *buf, int size)
 {
+       const char* sharename = lp_const_servicename(snum);
        int return_code;
-       struct printjob *pjob = print_job_find(snum, jobid);
+       struct printjob *pjob;
+
+       pjob = print_job_find(sharename, jobid);
 
        if (!pjob)
                return -1;
@@ -1808,7 +1891,7 @@ int print_job_write(int snum, uint32 jobid, const char *buf, int size)
        return_code = write(pjob->fd, buf, size);
        if (return_code>0) {
                pjob->size += size;
-               pjob_store(snum, jobid, pjob);
+               pjob_store(sharename, jobid, pjob);
        }
        return return_code;
 }
@@ -1856,12 +1939,11 @@ static BOOL print_cache_expired(int snum)
  Get the queue status - do not update if db is out of date.
 ****************************************************************************/
 
-static int get_queue_status(int snum, print_status_struct *status)
+static int get_queue_status(const char* sharename, 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);
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
        int len;
 
        if (!pdb)
@@ -1869,7 +1951,7 @@ static int get_queue_status(int snum, print_status_struct *status)
 
        if (status) {
                ZERO_STRUCTP(status);
-               slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
+               slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
                key.dptr = keystr;
                key.dsize = strlen(keystr);
                data = tdb_fetch(pdb->tdb, key);
@@ -1892,6 +1974,7 @@ static int get_queue_status(int snum, print_status_struct *status)
 
 int print_queue_length(int snum, print_status_struct *pstatus)
 {
+       const char* sharename = lp_const_servicename( snum );
        print_status_struct status;
        int len;
  
@@ -1901,7 +1984,7 @@ int print_queue_length(int snum, print_status_struct *pstatus)
  
        /* also fetch the queue status */
        memset(&status, 0, sizeof(status));
-       len = get_queue_status(snum, &status);
+       len = get_queue_status(sharename, &status);
 
        if (pstatus)
                *pstatus = status;
@@ -1913,7 +1996,7 @@ int print_queue_length(int snum, print_status_struct *pstatus)
  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)
+static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char *sharename, uint32 *pjobid)
 {
        int i;
        uint32 jobid;
@@ -1923,14 +2006,14 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char
        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 ));
+                       DEBUG(0,("allocate_print_jobid: failed to lock printing database %s\n", sharename));
                        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 ));
+                                       sharename));
                                return False;
                        }
                        jobid = 0;
@@ -1947,13 +2030,13 @@ static BOOL allocate_print_jobid(struct tdb_print_db *pdb, int snum, const char
                /* We've finished with the INFO/nextjob lock. */
                tdb_unlock_bystring(pdb->tdb, "INFO/nextjob");
                                
-               if (!print_job_exists(snum, jobid))
+               if (!print_job_exists(sharename, jobid))
                        break;
        }
 
        if (i > 2) {
                DEBUG(0, ("allocate_print_jobid: failed to allocate a print job for queue %s\n",
-                               printername ));
+                       sharename));
                /* Probably full... */
                errno = ENOSPC;
                return False;
@@ -2005,8 +2088,8 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
        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);
+       const char *sharename = lp_const_servicename(snum);
+       struct tdb_print_db *pdb = get_print_db_byname(sharename);
        int njobs;
 
        errno = 0;
@@ -2051,16 +2134,16 @@ uint32 print_job_start(struct current_user *user, int snum, char *jobname, NT_DE
        /* 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) ));
+                       sharename, 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) ));
+               sharename, njobs, lp_maxprintjobs(snum) ));
 
-       if (!allocate_print_jobid(pdb, snum, printername, &jobid))
+       if (!allocate_print_jobid(pdb, snum, sharename, &jobid))
                goto fail;
 
        /* create the database entry */
@@ -2105,7 +2188,7 @@ to open spool file %s.\n", pjob.filename));
                goto fail;
        }
 
-       pjob_store(snum, jobid, &pjob);
+       pjob_store(sharename, jobid, &pjob);
 
        /* Update the 'jobs changed' entry used by print_queue_status. */
        add_to_jobs_changed(pdb, jobid);
@@ -2119,7 +2202,7 @@ to open spool file %s.\n", pjob.filename));
 
  fail:
        if (jobid != -1)
-               pjob_delete(snum, jobid);
+               pjob_delete(sharename, jobid);
 
        release_print_db(pdb);
 
@@ -2133,7 +2216,10 @@ to open spool file %s.\n", pjob.filename));
 
 void print_job_endpage(int snum, uint32 jobid)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       const char* sharename = lp_const_servicename(snum);
+       struct printjob *pjob;
+
+       pjob = print_job_find(sharename, jobid);
        if (!pjob)
                return;
        /* don't allow another process to get this info - it is meaningless */
@@ -2141,7 +2227,7 @@ void print_job_endpage(int snum, uint32 jobid)
                return;
 
        pjob->page_count++;
-       pjob_store(snum, jobid, pjob);
+       pjob_store(sharename, jobid, pjob);
 }
 
 /****************************************************************************
@@ -2152,11 +2238,14 @@ void print_job_endpage(int snum, uint32 jobid)
 
 BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
 {
-       struct printjob *pjob = print_job_find(snum, jobid);
+       const char* sharename = lp_const_servicename(snum);
+       struct printjob *pjob;
        int ret;
        SMB_STRUCT_STAT sbuf;
        struct printif *current_printif = get_printer_fns( snum );
 
+       pjob = print_job_find(sharename, jobid);
+
        if (!pjob)
                return False;
 
@@ -2187,7 +2276,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
                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);
+               pjob_delete(sharename, jobid);
                return True;
        }
 
@@ -2202,7 +2291,7 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
        
        pjob->spooled = True;
        pjob->status = LPQ_QUEUED;
-       pjob_store(snum, jobid, pjob);
+       pjob_store(sharename, jobid, pjob);
        
        /* make sure the database is up to date */
        if (print_cache_expired(snum))
@@ -2215,7 +2304,7 @@ 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);
+       pjob_delete(sharename, jobid);
        return False;
 }
 
@@ -2234,6 +2323,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
        uint32 i;
        int max_reported_jobs = lp_max_reported_jobs(snum);
        BOOL ret = False;
+       const char* sharename = lp_servicename(snum);
 
        /* make sure the database is up to date */
        if (print_cache_expired(snum))
@@ -2300,10 +2390,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
 
                jobid = IVAL(cgdata.dptr, i*4);
                DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
-               pjob = print_job_find(snum, jobid);
+               pjob = print_job_find(lp_const_servicename(snum), jobid);
                if (!pjob) {
                        DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
-                       remove_from_jobs_changed(snum, jobid);
+                       remove_from_jobs_changed(sharename, jobid);
                        continue;
                }
 
@@ -2351,7 +2441,7 @@ int print_queue_status(int snum,
 {
        fstring keystr;
        TDB_DATA data, key;
-       const char *printername;
+       const char *sharename;
        struct tdb_print_db *pdb;
        int count = 0;
 
@@ -2365,8 +2455,8 @@ int print_queue_status(int snum,
                return 0;
 
        *ppqueue = NULL;
-       printername = lp_const_servicename(snum);
-       pdb = get_print_db_byname(printername);
+       sharename = lp_const_servicename(snum);
+       pdb = get_print_db_byname(sharename);
 
        if (!pdb)
                return 0;
@@ -2377,7 +2467,7 @@ int print_queue_status(int snum,
         */
 
        ZERO_STRUCTP(status);
-       slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", printername);
+       slprintf(keystr, sizeof(keystr)-1, "STATUS/%s", sharename);
        key.dptr = keystr;
        key.dsize = strlen(keystr);
        data = tdb_fetch(pdb->tdb, key);
index c2fb6e345665e55728d1f0f51ea0d6f17b3e46fc..b9fe1ad1cfcb7220a07f627f759d57f5452f7bf4 100644 (file)
@@ -151,10 +151,10 @@ ssize_t write_file(files_struct *fsp, char *data, SMB_OFF_T pos, size_t n)
        int write_path = -1; 
 
        if (fsp->print_file) {
-               int snum;
+               fstring sharename;
                uint32 jobid;
 
-               if (!rap_to_pjobid(fsp->rap_print_jobid, &snum, &jobid)) {
+               if (!rap_to_pjobid(fsp->rap_print_jobid, sharename, &jobid)) {
                        DEBUG(3,("write_file: Unable to map RAP jobid %u to jobid.\n",
                                                (unsigned int)fsp->rap_print_jobid ));
                        errno = EBADF;