diff options
-rw-r--r-- | source/include/printing.h | 8 | ||||
-rw-r--r-- | source/printing/lpq_parse.c | 6 | ||||
-rw-r--r-- | source/printing/notify.c | 85 | ||||
-rw-r--r-- | source/printing/print_cups.c | 55 | ||||
-rw-r--r-- | source/printing/print_generic.c | 89 | ||||
-rw-r--r-- | source/printing/printfsp.c | 12 | ||||
-rw-r--r-- | source/printing/printing.c | 512 | ||||
-rw-r--r-- | source/smbd/fileio.c | 4 |
8 files changed, 425 insertions, 346 deletions
diff --git a/source/include/printing.h b/source/include/printing.h index bf7c61b251e..fd1e7e43e4e 100644 --- a/source/include/printing.h +++ b/source/include/printing.h @@ -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); diff --git a/source/printing/lpq_parse.c b/source/printing/lpq_parse.c index b7e41964f1b..68c06ade41f 100644 --- a/source/printing/lpq_parse.c +++ b/source/printing/lpq_parse.c @@ -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; diff --git a/source/printing/notify.c b/source/printing/notify.c index 10b5f745287..77326bee3e4 100644 --- a/source/printing/notify.c +++ b/source/printing/notify.c @@ -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); } diff --git a/source/printing/print_cups.c b/source/printing/print_cups.c index 3097811fac2..ad01a68c8e6 100644 --- a/source/printing/print_cups.c +++ b/source/printing/print_cups.c @@ -27,31 +27,6 @@ /* - * 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 */ diff --git a/source/printing/print_generic.c b/source/printing/print_generic.c index 9e0ea85bb9a..d6074704b3f 100644 --- a/source/printing/print_generic.c +++ b/source/printing/print_generic.c @@ -22,37 +22,12 @@ #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, +}; + diff --git a/source/printing/printfsp.c b/source/printing/printfsp.c index 0b6d4fdbe1c..7c5de468701 100644 --- a/source/printing/printfsp.c +++ b/source/printing/printfsp.c @@ -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; diff --git a/source/printing/printing.c b/source/printing/printing.c index 60adcc4d7f0..1e897c962a6 100644 --- a/source/printing/printing.c +++ b/source/printing/printing.c @@ -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); diff --git a/source/smbd/fileio.c b/source/smbd/fileio.c index c2fb6e34566..b9fe1ad1cfc 100644 --- a/source/smbd/fileio.c +++ b/source/smbd/fileio.c @@ -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; |