From 8a91379a00cade86a0b448c6a7c4e949cc58185c Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 16 Apr 2000 06:20:43 +0000 Subject: JF and Jeremy - please have a look at what I did to the spoolss code. It now uses the new printing backend. ------------ The following series of commits are for the new tdb based printing backend. This completely replaces our old printing backend. Major changes include: - all print ops are now done in printing/*.c rather than scattered all over the place - system job ids are decoupled from SMB job ids - the lpq parsers don't need to be nearly so smart, they only need to parse the filename, the status and system job id - we can store lots more info about a job, including the full job name - the queue cache control is much better I also added a new utility routine file_lines_load() that loads a text file and parses it into lines. This is used in out lpq parsing and I also want to use it to replace all of our fgets() based code in other places. (This used to be commit 2df82862c061cca5644f5f69146c97302ccb42d5) --- source3/rpc_server/srv_spoolss_nt.c | 242 +++++++++--------------------------- 1 file changed, 59 insertions(+), 183 deletions(-) diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 3f9e98caa3..54564b6c7d 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -46,11 +46,7 @@ typedef struct _Printer{ BOOL open; BOOL document_started; BOOL page_started; - uint32 current_jobid; - uint32 document_fd; - uint32 document_lastwritten; - pstring document_name; - pstring job_name; + int jobid; /* jobid in printing backend */ POLICY_HND printer_hnd; BOOL printer_type; union { @@ -183,11 +179,9 @@ static BOOL close_printer_handle(POLICY_HND *hnd) ****************************************************************************/ static BOOL get_printer_snum(const POLICY_HND *hnd, int *number) { - int snum; Printer_entry *Printer = find_printer_index_by_hnd(hnd); - int n_services=lp_numservices(); - if (!OPEN_HANDLE(Printer)) { + if (!OPEN_HANDLE(Printer)) { DEBUG(3,("Error getting printer - take a nap quickly !\n")); return False; } @@ -195,22 +189,8 @@ static BOOL get_printer_snum(const POLICY_HND *hnd, int *number) switch (Printer->printer_type) { case PRINTER_HANDLE_IS_PRINTER: DEBUG(4,("short name:%s\n", Printer->dev.printername)); - for (snum=0;snumdev.printername ) ) - && ( !strncasecmp(lp_servicename(snum), - Printer->dev.printername, - strlen( lp_servicename(snum) ))) ) { - DEBUG(4,("Printer found: %s[%x]\n",lp_servicename(snum),snum)); - *number=snum; - return True; - break; - } - } - } - return False; - break; + *number = print_queue_snum(Printer->dev.printername); + return (*number != -1); case PRINTER_HANDLE_IS_PRINTSERVER: return False; break; @@ -338,7 +318,7 @@ static BOOL set_printer_hnd_printername(POLICY_HND *hnd, char *printername) for (snum=0;snumnotify_data.value[0]=(uint32) status.status; safe_free(q); } @@ -1065,7 +1045,7 @@ static void spoolss_notify_cjobs(int snum, SPOOL_NOTIFY_INFO_DATA *data, print_q print_status_struct status; memset(&status, 0, sizeof(status)); - data->notify_data.value[0]=get_printqueue(snum, NULL, &q, &status); + data->notify_data.value[0] = print_queue_status(snum, &q, &status); safe_free(q); } @@ -1499,7 +1479,7 @@ static uint32 printer_notify_info(const POLICY_HND *hnd, SPOOL_NOTIFY_INFO *info case JOB_NOTIFY_TYPE: memset(&status, 0, sizeof(status)); - count=get_printqueue(snum, NULL, &queue, &status); + count = print_queue_status(snum, &queue, &status); for (j=0; jdoc_info_1; - - pstring fname; - pstring tempname; - pstring datatype; - int fd = -1; int snum; + pstring jobname; + fstring datatype; Printer_entry *Printer = find_printer_index_by_hnd(handle); if (!OPEN_HANDLE(Printer)) @@ -2701,24 +2678,18 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, return ERROR_INVALID_HANDLE; } - /* Create a temporary file in the printer spool directory - * and open it - */ - - slprintf(tempname,sizeof(tempname)-1, "%s/smb_print.XXXXXX",lp_pathname(snum)); - pstrcpy(fname, (char *)mktemp(tempname)); - - fd=open(fname, O_WRONLY|O_CREAT|O_TRUNC|O_EXCL, S_IRUSR|S_IWUSR ); - DEBUG(4,("Temp spool file created: [%s]\n", fname)); - - Printer->current_jobid=fd; - pstrcpy(Printer->document_name, fname); + unistr2_to_ascii(jobname, &info_1->docname, sizeof(jobname)); - unistr2_to_ascii(Printer->job_name, &info_1->docname, sizeof(Printer->job_name)); + Printer->jobid = print_job_start(snum, jobname); + + /* need to map error codes properly - for now give out of + memory as I don't know the correct codes (tridge) */ + if (Printer->jobid == -1) { + return ERROR_NOT_ENOUGH_MEMORY; + } - Printer->document_fd=fd; Printer->document_started=True; - (*jobid) = Printer->current_jobid; + (*jobid) = Printer->jobid; return 0x0; } @@ -2730,16 +2701,8 @@ uint32 _spoolss_startdocprinter( const POLICY_HND *handle, uint32 level, ********************************************************************/ uint32 _spoolss_enddocprinter(const POLICY_HND *handle) { - int snum; - pstring filename; - pstring filename1; - pstring job_name; - pstring syscmd; - char *tstr; Printer_entry *Printer=find_printer_index_by_hnd(handle); - *syscmd=0; - if (!OPEN_HANDLE(Printer)) { DEBUG(3,("Error in enddocprinter handle\n")); @@ -2747,65 +2710,8 @@ uint32 _spoolss_enddocprinter(const POLICY_HND *handle) } Printer->document_started=False; - close(Printer->document_fd); - DEBUG(4,("Temp spool file closed, printing now ...\n")); - - pstrcpy(filename1, Printer->document_name); - pstrcpy(job_name, Printer->job_name); - - if (!get_printer_snum(handle,&snum)) - { - return ERROR_INVALID_HANDLE; - } - - /* copy the command into the buffer for extensive meddling. */ - StrnCpy(syscmd, lp_printcommand(snum), sizeof(pstring) - 1); - - /* look for "%s" in the string. If there is no %s, we cannot print. */ - if (!strstr(syscmd, "%s") && !strstr(syscmd, "%f")) - { - DEBUG(2,("WARNING! No placeholder for the filename in the print command for service %s!\n", SERVICE(snum))); - } - - if (strstr(syscmd,"%s")) - { - pstrcpy(filename,filename1); - pstring_sub(syscmd, "%s", filename); - } - - pstring_sub(syscmd, "%f", filename1); - - /* Does the service have a printername? If not, make a fake and empty - * printer name. That way a %p is treated sanely if no printer - * name was specified to replace it. This eventuality is logged. - */ - - tstr = lp_printername(snum); - if (tstr == NULL || tstr[0] == '\0') { - DEBUG(3,( "No printer name - using %s.\n", SERVICE(snum))); - tstr = SERVICE(snum); - } - - pstring_sub(syscmd, "%p", tstr); - - /* If the lpr command support the 'Job' option replace here */ - pstring_sub(syscmd, "%j", job_name); - - if ( *syscmd != '\0') { - int ret = smbrun(syscmd, NULL, False); - DEBUG(3,("Running the command `%s' gave %d\n", syscmd, ret)); - if (ret < 0) { - lpq_reset(snum); - return ERROR_ACCESS_DENIED; - } - } - else { - DEBUG(0,("Null print command?\n")); - lpq_reset(snum); - return ERROR_ACCESS_DENIED; - } - - lpq_reset(snum); + print_job_end(Printer->jobid); + /* error codes unhandled so far ... */ return 0x0; } @@ -2817,7 +2723,6 @@ uint32 _spoolss_writeprinter( const POLICY_HND *handle, const uint8 *buffer, uint32 *buffer_written) { - int fd; Printer_entry *Printer = find_printer_index_by_hnd(handle); if (!OPEN_HANDLE(Printer)) @@ -2826,9 +2731,7 @@ uint32 _spoolss_writeprinter( const POLICY_HND *handle, return ERROR_INVALID_HANDLE; } - fd = Printer->document_fd; - (*buffer_written) = write(fd, buffer, buffer_size); - Printer->document_lastwritten = (*buffer_written); + (*buffer_written) = print_job_write(Printer->jobid, buffer, buffer_size); return 0x0; } @@ -2850,27 +2753,22 @@ static uint32 control_printer(const POLICY_HND *handle, uint32 command) return ERROR_INVALID_HANDLE; switch (command) { - case PRINTER_CONTROL_PAUSE: - /* pause the printer here */ - status_printqueue(NULL, snum, LPSTAT_STOPPED); - return 0x0; - break; - case PRINTER_CONTROL_RESUME: - case PRINTER_CONTROL_UNPAUSE: - /* UN-pause the printer here */ - status_printqueue(NULL, snum, LPSTAT_OK); - return 0x0; - break; - case PRINTER_CONTROL_PURGE: - /* - * It's not handled by samba - * we need a smb.conf param to do - * lprm -P%p - on BSD - * lprm -P%p all on LPRNG - * I don't know on SysV - * we could do it by looping in the job's list... - */ - break; + case PRINTER_CONTROL_PAUSE: + if (print_queue_pause(snum)) { + return 0; + } + break; + case PRINTER_CONTROL_RESUME: + case PRINTER_CONTROL_UNPAUSE: + if (print_queue_resume(snum)) { + return 0; + } + break; + case PRINTER_CONTROL_PURGE: + if (print_queue_purge(snum)) { + return 0; + } + break; } return ERROR_INVALID_FUNCTION; @@ -3201,7 +3099,7 @@ uint32 _spoolss_enumjobs( POLICY_HND *handle, uint32 firstjob, uint32 numofjobs, if (!get_printer_snum(handle, &snum)) return ERROR_INVALID_HANDLE; - *returned = get_printqueue(snum, NULL, &queue, &prt_status); + *returned = print_queue_status(snum, &queue, &prt_status); DEBUGADD(4,("count:[%d], status:[%d], [%s]\n", *returned, prt_status.status, prt_status.message)); switch (level) { @@ -3237,11 +3135,7 @@ uint32 _spoolss_setjob( const POLICY_HND *handle, { int snum; - print_queue_struct *queue=NULL; print_status_struct prt_status; - int i=0; - BOOL found=False; - int count; memset(&prt_status, 0, sizeof(prt_status)); @@ -3249,44 +3143,26 @@ uint32 _spoolss_setjob( const POLICY_HND *handle, return ERROR_INVALID_HANDLE; } - count=get_printqueue(snum, NULL, &queue, &prt_status); - - while ( (i