From 071af8f007efc20c23959d140a87cc09363aae83 Mon Sep 17 00:00:00 2001
From: Gerald Carter <jerry@samba.org>
Date: Sat, 11 Jan 2003 02:38:36 +0000
Subject: [merge] make sure to update print queue cache during
 timeout_processing() to send notify events; CR 1491 (This used to be commit
 f8a915b14d63e4fdb99235053eeb896ef9492068)

---
 source3/printing/printing.c             | 21 ++++++++++----
 source3/rpc_client/cli_spoolss_notify.c |  2 ++
 source3/rpc_server/srv_spoolss_nt.c     | 49 +++++++++++++++++++++++++++------
 source3/smbd/process.c                  |  4 +++
 4 files changed, 61 insertions(+), 15 deletions(-)

diff --git a/source3/printing/printing.c b/source3/printing/printing.c
index be42664b56..a770e7a09a 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);
+	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;
 
-	/* make sure the database is up to date */
-	if (print_cache_expired(snum))
-		print_queue_update(snum);
-
 	/*
 	 * 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..a289de78de 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;
+				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;
+				if ( job_notify_table[msg->field].fn )
 				job_notify_table[msg->field].fn(msg, &data[data_len], mem_ctx);
-
 				break;
 
 			default:
@@ -1228,6 +1229,32 @@ void do_drv_upgrade_printer(int msg_type, pid_t src, void *buf, size_t len)
 	/* all done */	
 }
 
+/********************************************************************
+ 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(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
@@ -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.
-- 
cgit