From ed77fca1990f96dba6fe9204e551056395c6ed29 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 23 Feb 2001 03:59:37 +0000 Subject: include/rpc_spoolss.h: Added JOB_STATUS_XXX defines. include/smb.h: Added LPQ_xx enums to correspond with the NT JOB_STATUS_XXX. We need these to be different as we're storing LPQ_xx enums in the tdb already. rpc_server/srv_spoolss_nt.c: Don't need to return status strings as we're now returning status codes. smbd/lanman.c: Change the RAP status codes to have "RAP" in the name. printing/printing.c: Keep track of the status of a job. Allow a job to be deleted from one smbd when being submitted by another. Made logic in mutex clearer. Jeremy. (This used to be commit 71029da7dd74eb91dd6953752bdf238f319d985d) --- source3/include/rpc_spoolss.h | 14 +++++ source3/include/smb.h | 5 +- source3/printing/printing.c | 100 ++++++++++++++++++------------------ source3/rpc_server/srv_spoolss_nt.c | 36 +++++++++++-- source3/smbd/lanman.c | 26 +++++----- 5 files changed, 112 insertions(+), 69 deletions(-) diff --git a/source3/include/rpc_spoolss.h b/source3/include/rpc_spoolss.h index 94d5985688..82719b6bc9 100755 --- a/source3/include/rpc_spoolss.h +++ b/source3/include/rpc_spoolss.h @@ -154,6 +154,20 @@ #define PRINTER_ACCESS_USE 0x00000008 #define JOB_ACCESS_ADMINISTER 0x00000010 +/* JOB status codes. */ + +#define JOB_STATUS_PAUSED 0x001 +#define JOB_STATUS_ERROR 0x002 +#define JOB_STATUS_DELETING 0x004 +#define JOB_STATUS_SPOOLING 0x008 +#define JOB_STATUS_PRINTING 0x010 +#define JOB_STATUS_OFFLINE 0x020 +#define JOB_STATUS_PAPEROUT 0x040 +#define JOB_STATUS_PRINTED 0x080 +#define JOB_STATUS_DELETED 0x100 +#define JOB_STATUS_BLOCKED 0x200 +#define JOB_STATUS_USER_INTERVENTION 0x400 + /* ACE masks for the various print permissions */ #define PRINTER_ACE_FULL_CONTROL GENERIC_ALL_ACCESS diff --git a/source3/include/smb.h b/source3/include/smb.h index 7df338510d..15fb7beada 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -594,7 +594,10 @@ typedef struct { fstring domain; /* domain that the client specified */ } userdom_struct; -enum {LPQ_QUEUED,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING}; +/* Extra fields above "LPQ_PRINTING" are used to map extra NT status codes. */ + +enum {LPQ_QUEUED=0,LPQ_PAUSED,LPQ_SPOOLING,LPQ_PRINTING,LPQ_ERROR,LPQ_DELETING, + LPQ_OFFLINE,LPQ_PAPEROUT,LPQ_PRINTED,LPQ_DELETED,LPQ_BLOCKED,LPQ_USER_INTERVENTION}; typedef struct _print_queue_struct { diff --git a/source3/printing/printing.c b/source3/printing/printing.c index b0b0482cd3..e771e93600 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -402,58 +402,50 @@ static void print_queue_update(int snum) * This is essentially a mutex on the update. */ - if (get_updating_pid(printer_name) == -1) { - /* Lock the queue for the database update */ + if (get_updating_pid(printer_name) != -1) + return; - slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); - tdb_lock_bystring(tdb, keystr); + /* Lock the queue for the database update */ - /* - * Ensure that no one else got in here. - * If the updating pid is still -1 then we are - * the winner. - */ + slprintf(keystr, sizeof(keystr) - 1, "LOCK/%s", printer_name); + tdb_lock_bystring(tdb, keystr); - if (get_updating_pid(printer_name) != -1) { - /* - * Someone else is doing the update, exit. - */ - tdb_unlock_bystring(tdb, keystr); - 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) { /* - * We're going to do the update ourselves. + * Someone else is doing the update, exit. */ + tdb_unlock_bystring(tdb, keystr); + return; + } - /* Tell others we're doing the update. */ - set_updating_pid(printer_name, False); + /* + * We're going to do the update ourselves. + */ - /* - * Allow others to enter and notice we're doing - * the update. - */ + /* Tell others we're doing the update. */ + set_updating_pid(printer_name, False); - tdb_unlock_bystring(tdb, keystr); + /* + * Allow others to enter and notice we're doing + * the update. + */ - /* - * Update the cache time FIRST ! Stops others even - * attempting to get the lock and doing this - * if the lpq takes a long time. - */ + tdb_unlock_bystring(tdb, keystr); - slprintf(cachestr, sizeof(cachestr), "CACHE/%s", printer_name); - tdb_store_int(tdb, cachestr, (int)time(NULL)); + /* + * Update the cache time FIRST ! Stops others even + * attempting to get the lock and doing this + * if the lpq takes a long time. + */ - } - else - { - /* - * Someone else is already doing the update, defer to - * them. - */ - return; - } + slprintf(cachestr, sizeof(cachestr), "CACHE/%s", printer_name); + tdb_store_int(tdb, cachestr, (int)time(NULL)); slprintf(tmp_file, sizeof(tmp_file), "%s/smblpq.%d", path, local_pid); @@ -645,6 +637,13 @@ static BOOL print_job_delete1(int jobid) if (!pjob) return False; + /* + * If already deleting just return. + */ + + if (pjob->status == LPQ_DELETING) + return True; + snum = print_job_snum(jobid); /* Hrm - we need to be able to cope with deleting a job before it @@ -655,6 +654,11 @@ static BOOL print_job_delete1(int jobid) jobid)); } + /* Set the tdb entry to be deleting. */ + + pjob->status = LPQ_DELETING; + print_job_store(jobid, pjob); + if (pjob->spooled && pjob->sysjob != -1) { fstring jobstr; @@ -668,13 +672,6 @@ static BOOL print_job_delete1(int jobid) NULL); } - /* Delete the tdb entry if the delete suceeded or the job hasn't - been spooled. */ - - if (result == 0) { - tdb_delete(tdb, print_key(jobid)); - } - return (result == 0); } @@ -979,7 +976,7 @@ int print_job_start(struct current_user *user, int snum, char *jobname) pjob.sysjob = -1; pjob.fd = -1; pjob.starttime = time(NULL); - pjob.status = LPQ_QUEUED; + pjob.status = LPQ_SPOOLING; pjob.size = 0; pjob.spooled = False; pjob.smbjob = True; @@ -1093,8 +1090,10 @@ BOOL print_job_end(int jobid, BOOL normal_close) /* Technically, this is not quit right. If the printer has a separator * page turned on, the NT spooler prints the separator page even if the * print job is 0 bytes. 010215 JRR */ - if (pjob->size == 0) { - /* don't bother spooling empty files */ + if (pjob->size == 0 || pjob->status == LPQ_DELETING) { + /* don't bother spooling empty files or something being deleted. */ + DEBUG(5,("print_job_end: canceling spool of %s (%s)\n", + pjob->filename, pjob->size ? "deleted" : "zero length" )); unlink(pjob->filename); tdb_delete(tdb, print_key(jobid)); return True; @@ -1130,6 +1129,7 @@ BOOL print_job_end(int jobid, BOOL normal_close) /* The print job has been sucessfully handed over to the back-end */ pjob->spooled = True; + pjob->status = LPQ_QUEUED; print_job_store(jobid, pjob); /* make sure the database is up to date */ diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c index 05fbbca0f3..d5f0703e03 100644 --- a/source3/rpc_server/srv_spoolss_nt.c +++ b/source3/rpc_server/srv_spoolss_nt.c @@ -45,7 +45,7 @@ typedef struct _Printer{ BOOL open; BOOL document_started; BOOL page_started; - int jobid; /* jobid in printing backend */ + int jobid; /* jobid in printing backend */ POLICY_HND printer_hnd; BOOL printer_type; union { @@ -90,12 +90,30 @@ static uint32 smb_connections=0; static int nt_printj_status(int v) { switch (v) { - case LPQ_PAUSED: - return PRINTER_STATUS_PAUSED; case LPQ_QUEUED: + return 0; + case LPQ_PAUSED: + return JOB_STATUS_PAUSED; case LPQ_SPOOLING: + return JOB_STATUS_SPOOLING; case LPQ_PRINTING: - return 0; + return JOB_STATUS_PRINTING; + case LPQ_ERROR: + return JOB_STATUS_ERROR; + case LPQ_DELETING: + return JOB_STATUS_DELETING; + case LPQ_OFFLINE: + return JOB_STATUS_OFFLINE; + case LPQ_PAPEROUT: + return JOB_STATUS_PAPEROUT; + case LPQ_PRINTED: + return JOB_STATUS_PRINTED; + case LPQ_DELETED: + return JOB_STATUS_DELETED; + case LPQ_BLOCKED: + return JOB_STATUS_BLOCKED; + case LPQ_USER_INTERVENTION: + return JOB_STATUS_USER_INTERVENTION; } return 0; } @@ -1785,10 +1803,17 @@ static void spoolss_notify_job_status_string(int snum, NT_PRINTER_INFO_LEVEL *printer, TALLOC_CTX *mem_ctx) { - char *p = "unknown"; + /* + * Now we're returning job status codes we just return a "" here. JRA. + */ + + char *p = ""; pstring temp; uint32 len; +#if 0 /* NO LONGER NEEDED - JRA. 02/22/2001 */ + p = "unknown"; + switch (queue->status) { case LPQ_QUEUED: p = "Queued"; @@ -1803,6 +1828,7 @@ static void spoolss_notify_job_status_string(int snum, p = "Printing"; break; } +#endif /* NO LONGER NEEDED. */ len = (uint32)dos_PutUniCode(temp, p, sizeof(temp) - 2, True); diff --git a/source3/smbd/lanman.c b/source3/smbd/lanman.c index 7dba0c06f3..c29f0df434 100644 --- a/source3/smbd/lanman.c +++ b/source3/smbd/lanman.c @@ -413,14 +413,14 @@ static int check_printq_info(struct pack_desc* desc, } -#define JOB_STATUS_QUEUED 0 -#define JOB_STATUS_PAUSED 1 -#define JOB_STATUS_SPOOLING 2 -#define JOB_STATUS_PRINTING 3 -#define JOB_STATUS_PRINTED 4 +#define RAP_JOB_STATUS_QUEUED 0 +#define RAP_JOB_STATUS_PAUSED 1 +#define RAP_JOB_STATUS_SPOOLING 2 +#define RAP_JOB_STATUS_PRINTING 3 +#define RAP_JOB_STATUS_PRINTED 4 -#define QUEUE_STATUS_PAUSED 1 -#define QUEUE_STATUS_ERROR 2 +#define RAP_QUEUE_STATUS_PAUSED 1 +#define RAP_QUEUE_STATUS_ERROR 2 /* turn a print job status into a on the wire status */ @@ -428,13 +428,13 @@ static int printj_status(int v) { switch (v) { case LPQ_QUEUED: - return JOB_STATUS_QUEUED; + return RAP_JOB_STATUS_QUEUED; case LPQ_PAUSED: - return JOB_STATUS_PAUSED; + return RAP_JOB_STATUS_PAUSED; case LPQ_SPOOLING: - return JOB_STATUS_SPOOLING; + return RAP_JOB_STATUS_SPOOLING; case LPQ_PRINTING: - return JOB_STATUS_PRINTING; + return RAP_JOB_STATUS_PRINTING; } return 0; } @@ -447,9 +447,9 @@ static int printq_status(int v) case LPQ_QUEUED: return 0; case LPQ_PAUSED: - return QUEUE_STATUS_PAUSED; + return RAP_QUEUE_STATUS_PAUSED; } - return QUEUE_STATUS_ERROR; + return RAP_QUEUE_STATUS_ERROR; } static void fill_printjob_info(connection_struct *conn, int snum, int uLevel, -- cgit