summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/printing/printing.c23
-rw-r--r--source3/rpc_client/cli_spoolss_notify.c2
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c53
-rw-r--r--source3/smbd/process.c4
4 files changed, 64 insertions, 18 deletions
diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index be42664b56..5f2594f07a 100644
--- a/source3/printing/printing.c
+++ b/source3/printing/printing.c
@@ -1907,6 +1907,7 @@ static int printjob_comp(print_queue_struct *j1, print_queue_struct *j2)
/****************************************************************************
Get a printer queue listing.
+ set queue = NULL and status = NULL if you just want to update the cache
****************************************************************************/
int print_queue_status(int snum,
@@ -1917,18 +1918,26 @@ int print_queue_status(int snum,
struct traverse_count_struct tsc;
fstring keystr;
TDB_DATA data, key;
- const char *printername = lp_const_servicename(snum);
- struct tdb_print_db *pdb = get_print_db_byname(printername);
-
- *queue = NULL;
-
- if (!pdb)
- return 0;
+ const char *printername;
+ struct tdb_print_db *pdb;
/* make sure the database is up to date */
+
if (print_cache_expired(snum))
print_queue_update(snum);
+ /* return if we are done */
+
+ if ( !queue || !status )
+ return 0;
+
+ *queue = NULL;
+ printername = lp_const_servicename(snum);
+ pdb = get_print_db_byname(printername);
+
+ if (!pdb)
+ return 0;
+
/*
* Fetch the queue status. We must do this first, as there may
* be no jobs in the queue.
diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c
index 2843aaece1..f4eda332bb 100644
--- a/source3/rpc_client/cli_spoolss_notify.c
+++ b/source3/rpc_client/cli_spoolss_notify.c
@@ -212,6 +212,8 @@ WERROR cli_spoolss_rrpcn(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (r.unknown0 == 0x00080000)
DEBUG(8,("cli_spoolss_reply_rrpcn: I think the spooler resonded that the notification was ignored.\n"));
+ else if ( r.unknown0 != 0x0 )
+ DEBUG(8,("cli_spoolss_reply_rrpcn: unknown0 is non-zero [0x%x]\n", r.unknown0));
result = r.status;
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index 279bbb86ff..2fba89030e 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -79,8 +79,10 @@ typedef struct _Printer{
uint32 printerlocal;
SPOOL_NOTIFY_OPTION *option;
POLICY_HND client_hnd;
- uint32 client_connected;
+ BOOL client_connected;
uint32 change;
+ /* are we in a FindNextPrinterChangeNotify() call? */
+ BOOL fnpcn;
} notify;
struct {
fstring machine;
@@ -90,6 +92,7 @@ typedef struct _Printer{
/* devmode sent in the OpenPrinter() call */
NT_DEVICEMODE *nt_devmode;
+
} Printer_entry;
static Printer_entry *printers_list;
@@ -932,7 +935,7 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
SPOOL_NOTIFY_INFO_DATA *data;
uint32 data_len = 0;
uint32 id;
- int i;
+ int i, event_index;
/* Is there notification on this handle? */
@@ -955,6 +958,8 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
data = talloc( mem_ctx, msg_group->num_msgs*sizeof(SPOOL_NOTIFY_INFO_DATA) );
ZERO_STRUCTP(data);
+ event_index = 0;
+
/* build the array of change notifications */
for ( i=0; i<msg_group->num_msgs; i++ )
@@ -1005,17 +1010,13 @@ static void send_notify2_changes( SPOOLSS_NOTIFY_MSG_CTR *ctr, uint32 idx )
switch(msg->type) {
case PRINTER_NOTIFY_TYPE:
- if ( !printer_notify_table[msg->field].fn )
- goto done;
- printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
-
+ if ( printer_notify_table[msg->field].fn )
+ printer_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
break;
case JOB_NOTIFY_TYPE:
- if ( !job_notify_table[msg->field].fn )
- goto done;
- job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
-
+ if ( job_notify_table[msg->field].fn )
+ job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
break;
default:
@@ -1229,6 +1230,32 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
}
/********************************************************************
+ Update the cahce for all printq's with a registered client
+ connection
+ ********************************************************************/
+
+void update_monitored_printq_cache( void )
+{
+ Printer_entry *printer = printers_list;
+ int snum;
+
+ /* loop through all printers and update the cache where
+ client_connected == True */
+ while ( printer )
+ {
+ if ( (printer->printer_type == PRINTER_HANDLE_IS_PRINTER)
+ && printer->notify.client_connected )
+ {
+ snum = print_queue_snum_dos(printer->dev.handlename);
+ print_queue_status( snum, NULL, NULL );
+ }
+
+ printer = printer->next;
+ }
+
+ return;
+}
+/********************************************************************
Send a message to ourself about new driver being installed
so we can upgrade the information for each printer bound to this
driver
@@ -3727,6 +3754,8 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
/* We need to keep track of the change value to send back in
RRPCN replies otherwise our updates are ignored. */
+ Printer->notify.fnpcn = True;
+
if (Printer->notify.client_connected) {
DEBUG(10,("_spoolss_rfnpcnex: Saving change value in request [%x]\n", q_u->change));
Printer->notify.change = q_u->change;
@@ -3744,7 +3773,9 @@ WERROR _spoolss_rfnpcnex( pipes_struct *p, SPOOL_Q_RFNPCNEX *q_u, SPOOL_R_RFNPCN
break;
}
- done:
+ Printer->notify.fnpcn = False;
+
+done:
return result;
}
diff --git a/source3/smbd/process.c b/source3/smbd/process.c
index 06cedea573..ff84dc8e1a 100644
--- a/source3/smbd/process.c
+++ b/source3/smbd/process.c
@@ -1209,6 +1209,10 @@ machine %s in domain %s.\n", global_myname(), lp_workgroup() ));
*/
process_blocking_lock_queue(t);
+ /* update printer queue caches if necessary */
+
+ update_monitored_printq_cache();
+
/*
* Check to see if we have any change notifies
* outstanding on the queue.