summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2001-02-23 03:59:37 +0000
committerJeremy Allison <jra@samba.org>2001-02-23 03:59:37 +0000
commited77fca1990f96dba6fe9204e551056395c6ed29 (patch)
tree955f1e173e91fbccb9a7325567373fe708640fac
parent7bab8111d2b1668495b8e0411fa1de6b174aacdc (diff)
downloadsamba-ed77fca1990f96dba6fe9204e551056395c6ed29.tar.gz
samba-ed77fca1990f96dba6fe9204e551056395c6ed29.tar.bz2
samba-ed77fca1990f96dba6fe9204e551056395c6ed29.zip
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)
-rwxr-xr-xsource3/include/rpc_spoolss.h14
-rw-r--r--source3/include/smb.h5
-rw-r--r--source3/printing/printing.c100
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c36
-rw-r--r--source3/smbd/lanman.c26
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,