summaryrefslogtreecommitdiff
path: root/source3/printing/printing.c
diff options
context:
space:
mode:
Diffstat (limited to 'source3/printing/printing.c')
-rw-r--r--source3/printing/printing.c94
1 files changed, 84 insertions, 10 deletions
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index b6c4969761..39fb48ae17 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -24,6 +24,7 @@
/* Current printer interface */
static struct printif *current_printif = &generic_printif;
+static BOOL remove_from_jobs_changed(int snum, uint32 jobid);
/*
the printing backend revolves around a tdb database that stores the
@@ -663,9 +664,11 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
if (jobid == u_jobid)
break;
}
- if (i == ts->qcount)
+ if (i == ts->qcount) {
+ DEBUG(10,("traverse_fn_delete: pjob %u deleted due to !smbjob\n",
+ (unsigned int)jobid ));
pjob_delete(ts->snum, jobid);
- else
+ } else
ts->total_jobs++;
return 0;
}
@@ -675,9 +678,11 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
/* if a job is not spooled and the process doesn't
exist then kill it. This cleans up after smbd
deaths */
- if (!process_exists(pjob.pid))
+ 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);
- else
+ } else
ts->total_jobs++;
return 0;
}
@@ -700,9 +705,13 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
is currently traversing the printing tdb and deleting jobs.
Don't delete the job if it was submitted after the lpq_time. */
- if (pjob.starttime < ts->lpq_time)
+ if (pjob.starttime < ts->lpq_time) {
+ DEBUG(10,("traverse_fn_delete: pjob %u deleted due to pjob.starttime (%u) < ts->lpq_time (%u)\n",
+ (unsigned int)jobid,
+ (unsigned int)pjob.starttime,
+ (unsigned int)ts->lpq_time ));
pjob_delete(ts->snum, jobid);
- else
+ } else
ts->total_jobs++;
}
else
@@ -872,6 +881,37 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
return;
}
+static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb)
+{
+ TDB_DATA data, key;
+
+ key.dptr = "INFO/jobs_changed";
+ key.dsize = strlen(key.dptr);
+ ZERO_STRUCT(data);
+
+ data = tdb_fetch(pdb->tdb, key);
+ if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) {
+ SAFE_FREE(data.dptr);
+ ZERO_STRUCT(data);
+ }
+
+ return data;
+}
+
+static void check_job_changed(int snum, TDB_DATA data, uint32 jobid)
+{
+ unsigned int i;
+ unsigned int job_count = data.dsize / 4;
+
+ for (i = 0; i < job_count; i++) {
+ uint32 ch_jobid;
+
+ memcpy(&ch_jobid, data.dptr + (i*4), 4);
+ if (ch_jobid == jobid)
+ remove_from_jobs_changed(snum, jobid);
+ }
+}
+
/****************************************************************************
Update the internal database from the system print queue for a queue.
****************************************************************************/
@@ -886,6 +926,7 @@ static void print_queue_update(int snum)
struct traverse_struct tstruct;
fstring keystr, printer_name, cachestr;
TDB_DATA data, key;
+ TDB_DATA jcdata;
struct tdb_print_db *pdb;
fstrcpy(printer_name, lp_const_servicename(snum));
@@ -975,6 +1016,9 @@ static void print_queue_update(int snum)
fill in any system job numbers as we go
*/
+
+ jcdata = get_jobs_changed_data(pdb);
+
for (i=0; i<qcount; i++) {
uint32 jobid = print_parse_jobid(queue[i].fs_file);
@@ -996,10 +1040,12 @@ static void print_queue_update(int snum)
pjob->sysjob = queue[i].job;
pjob->status = queue[i].status;
-
pjob_store(snum, jobid, pjob);
+ check_job_changed(snum, jcdata, jobid);
}
+ SAFE_FREE(jcdata.dptr);
+
/* now delete any queued entries that don't appear in the
system queue */
tstruct.queue = queue;
@@ -1364,6 +1410,10 @@ static BOOL remove_from_jobs_changed(int snum, uint32 jobid)
tdb_chainunlock(pdb->tdb, key);
SAFE_FREE(data.dptr);
release_print_db(pdb);
+ if (ret)
+ DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid ));
+ else
+ DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid ));
return ret;
}
@@ -1406,8 +1456,18 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
/* Delete the tdb entry if the delete suceeded or the job hasn't
been spooled. */
- if (result == 0)
+ if (result == 0) {
+ const char *printername = lp_const_servicename(snum);
+ struct tdb_print_db *pdb = get_print_db_byname(printername);
+ int njobs = 1;
+
+ if (!pdb)
+ return False;
pjob_delete(snum, 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);
+ }
return (result == 0);
}
@@ -1790,6 +1850,8 @@ static BOOL add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid)
data.dptr = (char *)&jobid;
data.dsize = 4;
+ DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid ));
+
return (tdb_append(pdb->tdb, key, data) == 0);
}
@@ -1998,7 +2060,6 @@ BOOL print_job_end(int snum, uint32 jobid, BOOL normal_close)
pjob->spooled = True;
pjob->status = LPQ_QUEUED;
pjob_store(snum, jobid, pjob);
- remove_from_jobs_changed(snum, jobid);
/* make sure the database is up to date */
if (print_cache_expired(snum))
@@ -2031,6 +2092,10 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
int max_reported_jobs = lp_max_reported_jobs(snum);
BOOL ret = False;
+ /* make sure the database is up to date */
+ if (print_cache_expired(snum))
+ print_queue_update(snum);
+
*pcount = 0;
*ppqueue = NULL;
@@ -2055,6 +2120,8 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0))
extra_count = cgdata.dsize/4;
+ DEBUG(5,("get_stored_queue_info: qcount = %u, extra_count = %u\n", (unsigned int)qcount, (unsigned int)extra_count));
+
/* Allocate the queue size. */
if (qcount == 0 && extra_count == 0)
goto out;
@@ -2091,9 +2158,13 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
struct printjob *pjob;
memcpy(&jobid, &cgdata.dptr[i*4], 4);
+ DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid));
pjob = print_job_find(snum, jobid);
- if (!pjob)
+ if (!pjob) {
+ DEBUG(5,("get_stored_queue_info: failed to find changed job = %u\n", (unsigned int)jobid));
+ remove_from_jobs_changed(snum, jobid);
continue;
+ }
queue[total_count].job = jobid;
queue[total_count].size = pjob->size;
@@ -2102,6 +2173,7 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
queue[total_count].priority = 1;
fstrcpy(queue[total_count].fs_user, pjob->user);
fstrcpy(queue[total_count].fs_file, pjob->jobname);
+ total_count++;
}
/* Sort the queue by submission time otherwise they are displayed
@@ -2109,6 +2181,8 @@ static BOOL get_stored_queue_info(struct tdb_print_db *pdb, int snum, int *pcoun
qsort(queue, total_count, sizeof(print_queue_struct), QSORT_CAST(printjob_comp));
+ DEBUG(5,("get_stored_queue_info: total_count = %u\n", (unsigned int)total_count));
+
if (max_reported_jobs && total_count > max_reported_jobs)
total_count = max_reported_jobs;