summaryrefslogtreecommitdiff
path: root/source3/printing
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2005-09-30 17:13:37 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 11:04:48 -0500
commit54abd2aa66069e6baf7769c496f46d9dba18db39 (patch)
tree9cf8e88168011797319ba9e9866749201b1eac1e /source3/printing
parent4a2cc231d22a82ed21771a72508f15d21ed63227 (diff)
downloadsamba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.gz
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.tar.bz2
samba-54abd2aa66069e6baf7769c496f46d9dba18db39.zip
r10656: BIG merge from trunk. Features not copied over
* \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3)
Diffstat (limited to 'source3/printing')
-rw-r--r--source3/printing/notify.c12
-rw-r--r--source3/printing/print_cups.c6
-rw-r--r--source3/printing/print_generic.c8
-rw-r--r--source3/printing/print_iprint.c8
-rw-r--r--source3/printing/printing.c159
-rw-r--r--source3/printing/printing_db.c2
6 files changed, 132 insertions, 63 deletions
diff --git a/source3/printing/notify.c b/source3/printing/notify.c
index e289eba1b6..e71d9e6f25 100644
--- a/source3/printing/notify.c
+++ b/source3/printing/notify.c
@@ -176,13 +176,15 @@ static void print_notify_send_messages_to_printer(const char *printer, unsigned
return;
for (i = 0; i < num_pids; i++) {
- unsigned int q_len = messages_pending_for_pid(pid_list[i]);
+ unsigned int q_len = messages_pending_for_pid(pid_to_procid(pid_list[i]));
if (q_len > 1000) {
DEBUG(5, ("print_notify_send_messages_to_printer: discarding notify to printer %s as queue length = %u\n",
printer, q_len ));
continue;
}
- message_send_pid_with_timeout(pid_list[i], MSG_PRINTER_NOTIFY2, buf, offset, True, timeout);
+ message_send_pid_with_timeout(pid_to_procid(pid_list[i]),
+ MSG_PRINTER_NOTIFY2,
+ buf, offset, True, timeout);
}
}
@@ -328,7 +330,7 @@ static void send_notify_field_values(const char *sharename, uint32 type,
static void send_notify_field_buffer(const char *sharename, uint32 type,
uint32 field, uint32 id, uint32 len,
- char *buffer)
+ const char *buffer)
{
struct spoolss_notify_msg *msg;
@@ -349,7 +351,7 @@ static void send_notify_field_buffer(const char *sharename, uint32 type,
msg->field = field;
msg->id = id;
msg->len = len;
- msg->notify.data = buffer;
+ msg->notify.data = CONST_DISCARD(char *,buffer);
send_spoolss_notify2_msg(msg);
}
@@ -484,7 +486,7 @@ void notify_printer_location(int snum, char *location)
snum, strlen(location) + 1, location);
}
-void notify_printer_byname( const char *printername, uint32 change, char *value )
+void notify_printer_byname( const char *printername, uint32 change, const char *value )
{
int snum = print_queue_snum(printername);
int type = PRINTER_NOTIFY_TYPE;
diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c
index e6064564dc..8ae896fddf 100644
--- a/source3/printing/print_cups.c
+++ b/source3/printing/print_cups.c
@@ -265,7 +265,7 @@ BOOL cups_cache_reload(void)
* 'cups_job_delete()' - Delete a job.
*/
-static int cups_job_delete(int snum, struct printjob *pjob)
+static int cups_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
{
int ret = 1; /* Return value */
http_t *http = NULL; /* HTTP connection to server */
@@ -275,7 +275,7 @@ static int cups_job_delete(int snum, struct printjob *pjob)
char uri[HTTP_MAX_URI]; /* printer-uri attribute */
- DEBUG(5,("cups_job_delete(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
+ DEBUG(5,("cups_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
/*
* Make sure we don't ask for passwords...
@@ -712,7 +712,7 @@ static int cups_queue_get(const char *sharename,
*q = NULL;
- /* HACK ALERT!!! The porblem with support the 'printer name'
+ /* HACK ALERT!!! The problem with support the 'printer name'
option is that we key the tdb off the sharename. So we will
overload the lpq_command string to pass in the printername
(which is basically what we do for non-cups printers ... using
diff --git a/source3/printing/print_generic.c b/source3/printing/print_generic.c
index 256654179e..b2484d5b43 100644
--- a/source3/printing/print_generic.c
+++ b/source3/printing/print_generic.c
@@ -27,7 +27,8 @@ run a given print command
a null terminated list of value/substitute pairs is provided
for local substitution strings
****************************************************************************/
-static int print_run_command(int snum, const char* printername, BOOL do_sub, char *command, int *outfd, ...)
+static int print_run_command(int snum, const char* printername, BOOL do_sub,
+ const char *command, int *outfd, ...)
{
pstring syscmd;
@@ -68,14 +69,13 @@ static int print_run_command(int snum, const char* printername, BOOL do_sub, cha
/****************************************************************************
delete a print job
****************************************************************************/
-static int generic_job_delete(int snum, struct printjob *pjob)
+static int generic_job_delete( const char *sharename, const char *lprm_command, struct printjob *pjob)
{
fstring jobstr;
/* need to delete the spooled entry */
slprintf(jobstr, sizeof(jobstr)-1, "%d", pjob->sysjob);
- return print_run_command(snum, PRINTERNAME(snum), True,
- lp_lprmcommand(snum), NULL,
+ return print_run_command( -1, sharename, False, lprm_command, NULL,
"%j", jobstr,
"%T", http_timestring(pjob->starttime),
NULL);
diff --git a/source3/printing/print_iprint.c b/source3/printing/print_iprint.c
index 33bbcb256a..6193dbe2ca 100644
--- a/source3/printing/print_iprint.c
+++ b/source3/printing/print_iprint.c
@@ -423,7 +423,7 @@ BOOL iprint_cache_reload(void)
* 'iprint_job_delete()' - Delete a job.
*/
-static int iprint_job_delete(int snum, struct printjob *pjob)
+static int iprint_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob)
{
int ret = 1; /* Return value */
http_t *http = NULL; /* HTTP connection to server */
@@ -434,7 +434,7 @@ static int iprint_job_delete(int snum, struct printjob *pjob)
char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */
- DEBUG(5,("iprint_job_delete(%d, %p (%d))\n", snum, pjob, pjob->sysjob));
+ DEBUG(5,("iprint_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob));
/*
* Make sure we don't ask for passwords...
@@ -476,7 +476,7 @@ static int iprint_job_delete(int snum, struct printjob *pjob)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
- slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), PRINTERNAME(snum));
+ slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), sharename);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
@@ -489,7 +489,7 @@ static int iprint_job_delete(int snum, struct printjob *pjob)
* Do the request and get back a response...
*/
- slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", PRINTERNAME(snum));
+ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", sharename);
if ((response = cupsDoRequest(http, request, httpPath)) != NULL) {
if (response->request.status.status_code >= IPP_OK_CONFLICT) {
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index 61470f1510..6e74095f71 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -691,6 +691,8 @@ struct traverse_struct {
int qcount, snum, maxcount, total_jobs;
const char *sharename;
time_t lpq_time;
+ const char *lprm_command;
+ struct printif *print_if;
};
/****************************************************************************
@@ -737,7 +739,7 @@ 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_by_pid(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->sharename, jobid);
@@ -750,9 +752,38 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
if ( pjob.smbjob ) {
for (i=0;i<ts->qcount;i++) {
- uint32 curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
- if (jobid == curr_jobid)
+ uint32 curr_jobid;
+
+ if ( pjob.status == LPQ_DELETED )
+ continue;
+
+ curr_jobid = print_parse_jobid(ts->queue[i].fs_file);
+
+ if (jobid == curr_jobid) {
+
+ /* try to clean up any jobs that need to be deleted */
+
+ if ( pjob.status == LPQ_DELETING ) {
+ int result;
+
+ result = (*(ts->print_if->job_delete))(
+ ts->sharename, ts->lprm_command, &pjob );
+
+ if ( result != 0 ) {
+ /* if we can't delete, then reset the job status */
+ pjob.status = LPQ_QUEUED;
+ pjob_store(ts->sharename, jobid, &pjob);
+ }
+ else {
+ /* if we deleted the job, the remove the tdb record */
+ pjob_delete(ts->sharename, jobid);
+ pjob.status = LPQ_DELETED;
+ }
+
+ }
+
break;
+ }
}
}
@@ -779,9 +810,10 @@ static int traverse_fn_delete(TDB_CONTEXT *t, TDB_DATA key, TDB_DATA data, void
return 0;
}
- /* Save the pjob attributes we will store. */
- /* FIXME!!! This is the only place where queue->job
+ /* Save the pjob attributes we will store.
+ FIXME!!! This is the only place where queue->job
represents the SMB jobid --jerry */
+
ts->queue[i].job = jobid;
ts->queue[i].size = pjob.size;
ts->queue[i].page_count = pjob.page_count;
@@ -840,7 +872,7 @@ static pid_t get_updating_pid(const char *sharename)
updating_pid = IVAL(data.dptr, 0);
SAFE_FREE(data.dptr);
- if (process_exists(updating_pid))
+ if (process_exists_by_pid(updating_pid))
return updating_pid;
return (pid_t)-1;
@@ -910,6 +942,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
/****************************************************************************
Store the sorted queue representation for later portmon retrieval.
+ Skip deleted jobs
****************************************************************************/
static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct *pts)
@@ -923,13 +956,17 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
if (max_reported_jobs && (max_reported_jobs < pts->qcount))
pts->qcount = max_reported_jobs;
- qcount = pts->qcount;
+ qcount = 0;
/* Work out the size. */
data.dsize = 0;
data.dsize += tdb_pack(NULL, 0, "d", qcount);
for (i = 0; i < pts->qcount; i++) {
+ if ( queue[i].status == LPQ_DELETED )
+ continue;
+
+ qcount++;
data.dsize += tdb_pack(NULL, 0, "ddddddff",
(uint32)queue[i].job,
(uint32)queue[i].size,
@@ -947,6 +984,9 @@ static void store_queue_struct(struct tdb_print_db *pdb, struct traverse_struct
len = 0;
len += tdb_pack(data.dptr + len, data.dsize - len, "d", qcount);
for (i = 0; i < pts->qcount; i++) {
+ if ( queue[i].status == LPQ_DELETED )
+ continue;
+
len += tdb_pack(data.dptr + len, data.dsize - len, "ddddddff",
(uint32)queue[i].job,
(uint32)queue[i].size,
@@ -1024,6 +1064,7 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
|| (time_now - last_qscan_time) >= lp_lpqcachetime()
|| last_qscan_time > (time_now + MAX_CACHE_VALID_TIME))
{
+ uint32 u;
time_t msg_pending_time;
DEBUG(4, ("print_cache_expired: cache expired for queue %s "
@@ -1039,8 +1080,8 @@ static BOOL print_cache_expired(const char *sharename, BOOL check_pending)
snprintf(key, sizeof(key), "MSG_PENDING/%s", sharename);
if ( check_pending
- && tdb_fetch_uint32( pdb->tdb, key, (uint32*)&msg_pending_time )
- && msg_pending_time > 0
+ && tdb_fetch_uint32( pdb->tdb, key, &u )
+ && (msg_pending_time=u) > 0
&& msg_pending_time <= time_now
&& (time_now - msg_pending_time) < 60 )
{
@@ -1063,7 +1104,7 @@ done:
static void print_queue_update_internal( const char *sharename,
struct printif *current_printif,
- char *lpq_command )
+ char *lpq_command, char *lprm_command )
{
int i, qcount;
print_queue_struct *queue = NULL;
@@ -1141,8 +1182,14 @@ static void print_queue_update_internal( const char *sharename,
}
pjob->sysjob = queue[i].job;
- pjob->status = queue[i].status;
+
+ /* don't reset the status on jobs to be deleted */
+
+ if ( pjob->status != LPQ_DELETING )
+ pjob->status = queue[i].status;
+
pjob_store(sharename, jobid, pjob);
+
check_job_changed(sharename, jcdata, jobid);
}
@@ -1156,6 +1203,8 @@ static void print_queue_update_internal( const char *sharename,
tstruct.total_jobs = 0;
tstruct.lpq_time = time(NULL);
tstruct.sharename = sharename;
+ tstruct.lprm_command = lprm_command;
+ tstruct.print_if = current_printif;
tdb_traverse(pdb->tdb, traverse_fn_delete, (void *)&tstruct);
@@ -1216,7 +1265,7 @@ static void print_queue_update_internal( const char *sharename,
static void print_queue_update_with_lock( const char *sharename,
struct printif *current_printif,
- char *lpq_command )
+ char *lpq_command, char *lprm_command )
{
fstring keystr;
struct tdb_print_db *pdb;
@@ -1283,7 +1332,8 @@ static void print_queue_update_with_lock( const char *sharename,
/* do the main work now */
- print_queue_update_internal( sharename, current_printif, lpq_command );
+ print_queue_update_internal( sharename, current_printif,
+ lpq_command, lprm_command );
/* Delete our pid from the db. */
set_updating_pid(sharename, False);
@@ -1293,17 +1343,19 @@ static void print_queue_update_with_lock( const char *sharename,
/****************************************************************************
this is the receive function of the background lpq updater
****************************************************************************/
-static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msglen)
+static void print_queue_receive(int msg_type, struct process_id src,
+ void *buf, size_t msglen)
{
fstring sharename;
- pstring lpqcommand;
+ pstring lpqcommand, lprmcommand;
int printing_type;
size_t len;
- len = tdb_unpack( buf, msglen, "fdP",
+ len = tdb_unpack( buf, msglen, "fdPP",
sharename,
&printing_type,
- lpqcommand );
+ lpqcommand,
+ lprmcommand );
if ( len == -1 ) {
DEBUG(0,("print_queue_receive: Got invalid print queue update message\n"));
@@ -1312,7 +1364,7 @@ static void print_queue_receive(int msg_type, pid_t src, void *buf, size_t msgle
print_queue_update_with_lock(sharename,
get_printer_fns_from_type(printing_type),
- lpqcommand );
+ lpqcommand, lprmcommand );
return;
}
@@ -1382,7 +1434,7 @@ static void print_queue_update(int snum, BOOL force)
{
fstring key;
fstring sharename;
- pstring lpqcommand;
+ pstring lpqcommand, lprmcommand;
char *buffer = NULL;
size_t len = 0;
size_t newlen;
@@ -1398,6 +1450,10 @@ static void print_queue_update(int snum, BOOL force)
string_sub2( lpqcommand, "%p", PRINTERNAME(snum), sizeof(lpqcommand), False, False );
standard_sub_snum( snum, lpqcommand, sizeof(lpqcommand) );
+ pstrcpy( lprmcommand, lp_lprmcommand(snum));
+ string_sub2( lprmcommand, "%p", PRINTERNAME(snum), sizeof(lprmcommand), False, False );
+ standard_sub_snum( snum, lprmcommand, sizeof(lprmcommand) );
+
/*
* Make sure that the background queue process exists.
* Otherwise just do the update ourselves
@@ -1406,7 +1462,7 @@ static void print_queue_update(int snum, BOOL force)
if ( force || background_lpq_updater_pid == -1 ) {
DEBUG(4,("print_queue_update: updating queue [%s] myself\n", sharename));
current_printif = get_printer_fns( snum );
- print_queue_update_with_lock( sharename, current_printif, lpqcommand );
+ print_queue_update_with_lock( sharename, current_printif, lpqcommand, lprmcommand );
return;
}
@@ -1415,23 +1471,26 @@ static void print_queue_update(int snum, BOOL force)
/* get the length */
- len = tdb_pack( buffer, len, "fdP",
+ len = tdb_pack( buffer, len, "fdPP",
sharename,
type,
- lpqcommand );
+ lpqcommand,
+ lprmcommand );
buffer = SMB_XMALLOC_ARRAY( char, len );
/* now pack the buffer */
- newlen = tdb_pack( buffer, len, "fdP",
+ newlen = tdb_pack( buffer, len, "fdPP",
sharename,
type,
- lpqcommand );
+ lpqcommand,
+ lprmcommand );
SMB_ASSERT( newlen == len );
DEBUG(10,("print_queue_update: Sending message -> printer = %s, "
- "type = %d, lpq command = [%s]\n", sharename, type, lpqcommand ));
+ "type = %d, lpq command = [%s] lprm command = [%s]\n",
+ sharename, type, lpqcommand, lprmcommand ));
/* here we set a msg pending record for other smbd processes
to throttle the number of duplicate print_queue_update msgs
@@ -1457,7 +1516,7 @@ static void print_queue_update(int snum, BOOL force)
/* finally send the message */
become_root();
- message_send_pid(background_lpq_updater_pid,
+ message_send_pid(pid_to_procid(background_lpq_updater_pid),
MSG_PRINTER_UPDATE, buffer, len, False);
unbecome_root();
@@ -1806,8 +1865,6 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
int result = 0;
struct printif *current_printif = get_printer_fns( snum );
- pjob = print_job_find(sharename, jobid);
-
if (!pjob)
return False;
@@ -1819,7 +1876,9 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
return True;
/* Hrm - we need to be able to cope with deleting a job before it
- has reached the spooler. */
+ has reached the spooler. Just mark it as LPQ_DELETING and
+ let the print_queue_update() code rmeove the record */
+
if (pjob->sysjob == -1) {
DEBUG(5, ("attempt to delete job %u not seen by lpr\n", (unsigned int)jobid));
@@ -1830,24 +1889,31 @@ static BOOL print_job_delete1(int snum, uint32 jobid)
pjob->status = LPQ_DELETING;
pjob_store(sharename, jobid, pjob);
- if (pjob->spooled && pjob->sysjob != -1)
- result = (*(current_printif->job_delete))(snum, pjob);
+ if (pjob->spooled && pjob->sysjob != -1)
+ {
+ result = (*(current_printif->job_delete))(
+ PRINTERNAME(snum),
+ lp_lprmcommand(snum),
+ pjob);
- /* Delete the tdb entry if the delete succeeded or the job hasn't
- been spooled. */
+ /* Delete the tdb entry if the delete succeeded or the job hasn't
+ been spooled. */
- if (result == 0) {
- struct tdb_print_db *pdb = get_print_db_byname(sharename);
- int njobs = 1;
+ if (result == 0) {
+ struct tdb_print_db *pdb = get_print_db_byname(sharename);
+ int njobs = 1;
- if (!pdb)
- return False;
- pjob_delete(sharename, 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);
+ if (!pdb)
+ return False;
+ pjob_delete(sharename, 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);
+ }
}
+ remove_from_jobs_changed( sharename, jobid );
+
return (result == 0);
}
@@ -1877,7 +1943,8 @@ static BOOL is_owner(struct current_user *user, int snum, uint32 jobid)
BOOL print_job_delete(struct current_user *user, int snum, uint32 jobid, WERROR *errcode)
{
const char* sharename = lp_const_servicename( snum );
- BOOL owner, deleted;
+ struct printjob *pjob;
+ BOOL owner;
char *fname;
*errcode = WERR_OK;
@@ -1929,11 +1996,11 @@ pause, or resume print job. User name: %s. Printer name: %s.",
print_queue_update(snum, True);
- deleted = !print_job_exists(sharename, jobid);
- if ( !deleted )
+ pjob = print_job_find(sharename, jobid);
+ if ( pjob && (pjob->status != LPQ_DELETING) )
*errcode = WERR_ACCESS_DENIED;
- return deleted;
+ return (pjob == NULL );
}
/****************************************************************************
diff --git a/source3/printing/printing_db.c b/source3/printing/printing_db.c
index b9b4b3c6b0..adea10dfa6 100644
--- a/source3/printing/printing_db.c
+++ b/source3/printing/printing_db.c
@@ -188,7 +188,7 @@ TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name,
/* Entry is dead if process doesn't exist or refcount is zero. */
- while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists(pid))) {
+ while ((i < data.dsize) && ((IVAL(data.dptr, i + 4) == 0) || !process_exists_by_pid(pid))) {
/* Refcount == zero is a logic error and should never happen. */
if (IVAL(data.dptr, i + 4) == 0) {