The branch, master has been updated via 937da4d... s3-lib: Fixed a possible crash bug. via 555b175... s3-printing: Added function to update the queue. via 7e9d602... s3-printing: Rename jobs_changed functions to jobs_added. from 536d4d4... s3: Fix an uninitialized variable
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 937da4d14111e1cd32f514a9382291f12764c1c9 Author: Andreas Schneider <a...@samba.org> Date: Wed Aug 18 12:08:47 2010 +0200 s3-lib: Fixed a possible crash bug. Volker please check! commit 555b175212d5c7e5b8628d4d5e3cba4541037dbb Author: Andreas Schneider <a...@samba.org> Date: Thu Apr 29 14:00:30 2010 +0200 s3-printing: Added function to update the queue. commit 7e9d6021c91919f2e457e1e471cb253886aad9aa Author: Andreas Schneider <a...@samba.org> Date: Thu Apr 29 13:43:40 2010 +0200 s3-printing: Rename jobs_changed functions to jobs_added. ----------------------------------------------------------------------- Summary of changes: source3/include/printing.h | 2 +- source3/lib/serverid.c | 2 + source3/printing/printing.c | 256 +++++++++++++++++++++++++++++++++---------- 3 files changed, 203 insertions(+), 57 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/include/printing.h b/source3/include/printing.h index a16917f..180f6a0 100644 --- a/source3/include/printing.h +++ b/source3/include/printing.h @@ -83,7 +83,7 @@ extern struct printif iprint_printif; #ifndef PRINT_SPOOL_PREFIX #define PRINT_SPOOL_PREFIX "smbprn." #endif -#define PRINT_DATABASE_VERSION 6 +#define PRINT_DATABASE_VERSION 7 /* There can be this many printing tdb's open, plus any locked ones. */ #define MAX_PRINT_DBS_OPEN 1 diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c index 5523eca..6adad7e 100644 --- a/source3/lib/serverid.c +++ b/source3/lib/serverid.c @@ -157,6 +157,8 @@ bool serverid_register_msg_flags(const struct server_id id, bool do_reg, data->msg_flags &= ~msg_flags; } + ZERO_STRUCT(tdbdata); + status = rec->store(rec, tdbdata, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("Storing serverid.tdb record failed: %s\n", diff --git a/source3/printing/printing.c b/source3/printing/printing.c index 4240ddf..ca6139c 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -30,7 +30,7 @@ extern struct current_user current_user; extern userdom_struct current_user_info; /* Current printer interface */ -static bool remove_from_jobs_changed(const char* sharename, uint32 jobid); +static bool remove_from_jobs_added(const char* sharename, uint32 jobid); /* the printing backend revolves around a tdb database that stores the @@ -558,19 +558,97 @@ static uint32 map_to_spoolss_status(uint32 lpq_status) return 0; } +/*************************************************************************** + Append a jobid to the 'jobs changed' list. +***************************************************************************/ + +static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32_t jobid) +{ + TDB_DATA data; + uint32_t store_jobid; + + SIVAL(&store_jobid, 0, jobid); + data.dptr = (uint8 *) &store_jobid; + data.dsize = 4; + + DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); + + return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"), + data) == 0); +} + +/*************************************************************************** + Remove a jobid from the 'jobs changed' list. +***************************************************************************/ + +static bool remove_from_jobs_changed(const char* sharename, uint32_t jobid) +{ + struct tdb_print_db *pdb = get_print_db_byname(sharename); + TDB_DATA data, key; + size_t job_count, i; + bool ret = False; + bool gotlock = False; + + if (!pdb) { + return False; + } + + ZERO_STRUCT(data); + + key = string_tdb_data("INFO/jobs_changed"); + + if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) + goto out; + + gotlock = True; + + data = tdb_fetch(pdb->tdb, key); + + if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) + goto out; + + job_count = data.dsize / 4; + for (i = 0; i < job_count; i++) { + uint32 ch_jobid; + + ch_jobid = IVAL(data.dptr, i*4); + if (ch_jobid == jobid) { + if (i < job_count -1 ) + memmove(data.dptr + (i*4), data.dptr + (i*4) + 4, (job_count - i - 1)*4 ); + data.dsize -= 4; + if (tdb_store(pdb->tdb, key, data, TDB_REPLACE) == -1) + goto out; + break; + } + } + + ret = True; + out: + + if (gotlock) + 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; +} + static void pjob_store_notify(struct tevent_context *ev, struct messaging_context *msg_ctx, const char* sharename, uint32 jobid, struct printjob *old_data, - struct printjob *new_data) + struct printjob *new_data, + bool *pchanged) { - bool new_job = False; - - if (!old_data) - new_job = True; + bool new_job = false; + bool changed = false; - /* Job attributes that can't be changed. We only send - notification for these on a new job. */ + if (old_data == NULL) { + new_job = true; + } /* ACHTUNG! Due to a bug in Samba's spoolss parsing of the NOTIFY_INFO_DATA buffer, we *have* to send the job submission @@ -584,31 +662,40 @@ static void pjob_store_notify(struct tevent_context *ev, sharename, jobid, new_data->starttime); notify_job_username(ev, msg_ctx, sharename, jobid, new_data->user); - } - - if (new_job || !strequal(old_data->jobname, new_data->jobname)) notify_job_name(ev, msg_ctx, 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(ev, msg_ctx, - sharename, jobid, new_data->jobname); - - if (new_job || old_data->status != new_data->status) notify_job_status(ev, msg_ctx, - sharename, jobid, - map_to_spoolss_status(new_data->status)); - - if (new_job || old_data->size != new_data->size) + sharename, jobid, map_to_spoolss_status(new_data->status)); notify_job_total_bytes(ev, msg_ctx, sharename, jobid, new_data->size); - - if (new_job || old_data->page_count != new_data->page_count) notify_job_total_pages(ev, msg_ctx, sharename, jobid, new_data->page_count); + } else { + if (!strequal(old_data->jobname, new_data->jobname)) { + notify_job_name(ev, msg_ctx, sharename, + jobid, new_data->jobname); + changed = true; + } + + if (old_data->status != new_data->status) { + notify_job_status(ev, msg_ctx, + sharename, jobid, + map_to_spoolss_status(new_data->status)); + } + + if (old_data->size != new_data->size) { + notify_job_total_bytes(ev, msg_ctx, + sharename, jobid, new_data->size); + } + + if (old_data->page_count != new_data->page_count) { + notify_job_total_pages(ev, msg_ctx, + sharename, jobid, + new_data->page_count); + } + } + + *pchanged = changed; } /**************************************************************************** @@ -678,11 +765,10 @@ static bool pjob_store(struct tevent_context *ev, ret = (tdb_store(pdb->tdb, print_key(jobid, &tmp), new_data, TDB_REPLACE) == 0); - release_print_db(pdb); - /* Send notify updates for what has changed */ if ( ret ) { + bool changed = false; struct printjob old_pjob; if ( old_data.dsize ) @@ -692,17 +778,25 @@ static bool pjob_store(struct tevent_context *ev, pjob_store_notify(server_event_context(), msg_ctx, sharename, jobid, &old_pjob, - pjob); + pjob, + &changed); talloc_free(old_pjob.devmode); + + if (changed) { + add_to_jobs_changed(pdb, jobid); + } } + } else { /* new job */ pjob_store_notify(server_event_context(), msg_ctx, - sharename, jobid, NULL, pjob); + sharename, jobid, NULL, pjob, + &changed); } } + release_print_db(pdb); done: SAFE_FREE( old_data.dptr ); SAFE_FREE( buf ); @@ -747,7 +841,7 @@ static void pjob_delete(struct tevent_context *ev, /* Remove from printing.tdb */ tdb_delete(pdb->tdb, print_key(jobid, &tmp)); - remove_from_jobs_changed(sharename, jobid); + remove_from_jobs_added(sharename, jobid); release_print_db( pdb ); rap_jobid_delete(sharename, jobid); } @@ -1117,13 +1211,13 @@ 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) +static TDB_DATA get_jobs_added_data(struct tdb_print_db *pdb) { TDB_DATA data; ZERO_STRUCT(data); - data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); + data = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); if (data.dptr == NULL || data.dsize == 0 || (data.dsize % 4 != 0)) { SAFE_FREE(data.dptr); ZERO_STRUCT(data); @@ -1132,7 +1226,7 @@ static TDB_DATA get_jobs_changed_data(struct tdb_print_db *pdb) return data; } -static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid) +static void check_job_added(const char *sharename, TDB_DATA data, uint32 jobid) { unsigned int i; unsigned int job_count = data.dsize / 4; @@ -1142,7 +1236,7 @@ static void check_job_changed(const char *sharename, TDB_DATA data, uint32 jobid ch_jobid = IVAL(data.dptr, i*4); if (ch_jobid == jobid) - remove_from_jobs_changed(sharename, jobid); + remove_from_jobs_added(sharename, jobid); } } @@ -1274,7 +1368,7 @@ static void print_queue_update_internal( struct tevent_context *ev, fill in any system job numbers as we go */ - jcdata = get_jobs_changed_data(pdb); + jcdata = get_jobs_added_data(pdb); for (i=0; i<qcount; i++) { uint32 jobid = print_parse_jobid(queue[i].fs_file); @@ -1306,7 +1400,7 @@ static void print_queue_update_internal( struct tevent_context *ev, pjob_store(ev, msg_ctx, sharename, jobid, pjob); - check_job_changed(sharename, jcdata, jobid); + check_job_added(sharename, jcdata, jobid); } SAFE_FREE(jcdata.dptr); @@ -2013,10 +2107,10 @@ bool print_job_get_name(TALLOC_CTX *mem_ctx, const char *sharename, uint32_t job /*************************************************************************** - Remove a jobid from the 'jobs changed' list. + Remove a jobid from the 'jobs added' list. ***************************************************************************/ -static bool remove_from_jobs_changed(const char* sharename, uint32 jobid) +static bool remove_from_jobs_added(const char* sharename, uint32 jobid) { struct tdb_print_db *pdb = get_print_db_byname(sharename); TDB_DATA data, key; @@ -2030,7 +2124,7 @@ static bool remove_from_jobs_changed(const char* sharename, uint32 jobid) ZERO_STRUCT(data); - key = string_tdb_data("INFO/jobs_changed"); + key = string_tdb_data("INFO/jobs_added"); if (tdb_chainlock_with_timeout(pdb->tdb, key, 5) == -1) goto out; @@ -2065,9 +2159,9 @@ static bool remove_from_jobs_changed(const char* sharename, uint32 jobid) SAFE_FREE(data.dptr); release_print_db(pdb); if (ret) - DEBUG(10,("remove_from_jobs_changed: removed jobid %u\n", (unsigned int)jobid )); + DEBUG(10,("remove_from_jobs_added: removed jobid %u\n", (unsigned int)jobid )); else - DEBUG(10,("remove_from_jobs_changed: Failed to remove jobid %u\n", (unsigned int)jobid )); + DEBUG(10,("remove_from_jobs_added: Failed to remove jobid %u\n", (unsigned int)jobid )); return ret; } @@ -2131,7 +2225,7 @@ static bool print_job_delete1(struct tevent_context *ev, } } - remove_from_jobs_changed( sharename, jobid ); + remove_from_jobs_added( sharename, jobid ); return (result == 0); } @@ -2534,10 +2628,10 @@ static WERROR allocate_print_jobid(struct tdb_print_db *pdb, int snum, } /*************************************************************************** - Append a jobid to the 'jobs changed' list. + Append a jobid to the 'jobs added' list. ***************************************************************************/ -static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) +static bool add_to_jobs_added(struct tdb_print_db *pdb, uint32 jobid) { TDB_DATA data; uint32 store_jobid; @@ -2546,9 +2640,9 @@ static bool add_to_jobs_changed(struct tdb_print_db *pdb, uint32 jobid) data.dptr = (uint8 *)&store_jobid; data.dsize = 4; - DEBUG(10,("add_to_jobs_changed: Added jobid %u\n", (unsigned int)jobid )); + DEBUG(10,("add_to_jobs_added: Added jobid %u\n", (unsigned int)jobid )); - return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_changed"), + return (tdb_append(pdb->tdb, string_tdb_data("INFO/jobs_added"), data) == 0); } @@ -2755,8 +2849,8 @@ WERROR print_job_start(struct auth_serversupplied_info *server_info, pjob_store(server_event_context(), msg_ctx, sharename, jobid, &pjob); - /* Update the 'jobs changed' entry used by print_queue_status. */ - add_to_jobs_changed(pdb, jobid); + /* Update the 'jobs added' entry used by print_queue_status. */ + add_to_jobs_added(pdb, jobid); /* Ensure we keep a rough count of the number of total jobs... */ tdb_change_int32_atomic(pdb->tdb, "INFO/total_jobs", &njobs, 1); @@ -2913,10 +3007,11 @@ static bool get_stored_queue_info(struct messaging_context *msg_ctx, struct tdb_print_db *pdb, int snum, int *pcount, print_queue_struct **ppqueue) { - TDB_DATA data, cgdata; + TDB_DATA data, cgdata, jcdata; print_queue_struct *queue = NULL; uint32 qcount = 0; uint32 extra_count = 0; + uint32_t changed_count = 0; int total_count = 0; size_t len = 0; uint32 i; @@ -2940,11 +3035,16 @@ static bool get_stored_queue_info(struct messaging_context *msg_ctx, if (data.dptr && data.dsize >= sizeof(qcount)) len += tdb_unpack(data.dptr + len, data.dsize - len, "d", &qcount); - /* Get the changed jobs list. */ - cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); + /* Get the added jobs list. */ + cgdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_added")); if (cgdata.dptr != NULL && (cgdata.dsize % 4 == 0)) extra_count = cgdata.dsize/4; + /* Get the changed jobs list. */ + jcdata = tdb_fetch(pdb->tdb, string_tdb_data("INFO/jobs_changed")); + if (jcdata.dptr != NULL && (jcdata.dsize % 4 == 0)) + changed_count = jcdata.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. */ @@ -2977,17 +3077,17 @@ static bool get_stored_queue_info(struct messaging_context *msg_ctx, total_count = qcount; - /* Add in the changed jobids. */ + /* Add new jobids to the queue. */ for( i = 0; i < extra_count; i++) { uint32 jobid; struct printjob *pjob; jobid = IVAL(cgdata.dptr, i*4); - DEBUG(5,("get_stored_queue_info: changed job = %u\n", (unsigned int)jobid)); + DEBUG(5,("get_stored_queue_info: added job = %u\n", (unsigned int)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(sharename, jobid); + DEBUG(5,("get_stored_queue_info: failed to find added job = %u\n", (unsigned int)jobid)); + remove_from_jobs_added(sharename, jobid); continue; } @@ -3002,6 +3102,50 @@ static bool get_stored_queue_info(struct messaging_context *msg_ctx, total_count++; } + /* Update the changed jobids. */ + for (i = 0; i < changed_count; i++) { + uint32_t jobid = IVAL(jcdata.dptr, i * 4); + uint32_t j; + bool found = false; + + for (j = 0; j < total_count; j++) { + if (queue[j].job == jobid) { + found = true; + break; + } + } + + if (found) { + struct printjob *pjob; + + DEBUG(5,("get_stored_queue_info: changed job: %u\n", + (unsigned int) jobid)); + + pjob = print_job_find(sharename, jobid); + if (pjob == NULL) { + DEBUG(5,("get_stored_queue_info: failed to find " + "changed job = %u\n", + (unsigned int) jobid)); + remove_from_jobs_changed(sharename, jobid); + continue; + } + + queue[j].job = jobid; + queue[j].size = pjob->size; + queue[j].page_count = pjob->page_count; + queue[j].status = pjob->status; + queue[j].priority = 1; + queue[j].time = pjob->starttime; + fstrcpy(queue[j].fs_user, pjob->user); + fstrcpy(queue[j].fs_file, pjob->jobname); + + DEBUG(5,("get_stored_queue_info: updated queue[%u], jobid: %u, jobname: %s\n", + (unsigned int) j, (unsigned int) jobid, pjob->jobname)); + } + + remove_from_jobs_changed(sharename, jobid); + } + /* Sort the queue by submission time otherwise they are displayed in hash order. */ -- Samba Shared Repository