[print notify fixes from APP_HEAD]
authorGerald Carter <jerry@samba.org>
Tue, 26 Nov 2002 00:01:56 +0000 (00:01 +0000)
committerGerald Carter <jerry@samba.org>
Tue, 26 Nov 2002 00:01:56 +0000 (00:01 +0000)
 * fixing change notify on print server handle
 * adding change notify support into smbcontrol for sending comment
   changes, etc...

All part of CR 1159/1160

source/Makefile.in
source/include/printing.h
source/printing/notify.c
source/printing/printing.c
source/printing/printing_db.c [new file with mode: 0644]
source/utils/smbcontrol.c

index 8ec552e367c7474fa79cd198365f8947aea3e34b..d42379472ff207577334c3069f26d71bf2dd2fc4 100644 (file)
@@ -288,7 +288,8 @@ PRINTING_OBJ = printing/pcap.o printing/print_svid.o \
                                printing/print_cups.o printing/print_generic.o \
                                printing/lpq_parse.o printing/load.o
 
-PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o printing/notify.o
+PRINTBACKEND_OBJ = printing/printing.o printing/nt_printing.o printing/notify.o \
+               printing/printing_db.o
 
 MSDFS_OBJ = msdfs/msdfs.o 
 
@@ -330,7 +331,8 @@ STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
              $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(POPT_LIB_OBJ)
 
 SMBCONTROL_OBJ = utils/smbcontrol.o $(LOCKING_OBJ) $(PARAM_OBJ) \
-             $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
+       $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) printing/notify.o \
+       printing/printing_db.o
 
 SMBTREE_OBJ = utils/smbtree.o $(LOCKING_OBJ) $(PARAM_OBJ) \
              $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ) $(LIBSMB_OBJ) 
@@ -706,7 +708,7 @@ bin/smbstatus: $(STATUS_OBJ) @BUILD_POPT@ bin/.dummy
 
 bin/smbcontrol: $(SMBCONTROL_OBJ) bin/.dummy
        @echo Linking $@
-       @$(CC) $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(LDFLAGS) $(LIBS)
+       @$(CC) -DUSING_SMBCONTROL $(FLAGS) -o $@ $(SMBCONTROL_OBJ) $(LDFLAGS) $(LIBS)
 
 bin/smbtree: $(SMBTREE_OBJ) bin/.dummy
        @echo Linking $@
index 38ff7eac36695628f15358c904df907794b5d0ff..1d658a07681e2330d70d1faf0d45ca72aaa8cf3b 100644 (file)
@@ -74,4 +74,20 @@ extern struct printif        cups_printif;
 #define PRINT_SPOOL_PREFIX "smbprn."
 #define PRINT_DATABASE_VERSION 5
 
+/* There can be this many printing tdb's open, plus any locked ones. */
+#define MAX_PRINT_DBS_OPEN 1
+
+struct tdb_print_db {
+       struct tdb_print_db *next, *prev;
+       TDB_CONTEXT *tdb;
+       int ref_count;
+       fstring printer_name;
+};
+
+/* 
+ * Used for print notify
+ */
+
+#define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST"
+
 #endif /* PRINTING_H_ */
index a4111831d9c9401dc9f79f6b0b01176cd7e27104..f55dbff47e8b0fff7da0098aa961e4399161b820 100644 (file)
@@ -31,6 +31,18 @@ static struct notify_queue {
        size_t buflen;
 } *notify_queue_head = NULL;
 
+/****************************************************************************
+ Turn a queue name into a snum.
+****************************************************************************/
+
+int print_queue_snum(const char *qname)
+{
+       int snum = lp_servicenumber(qname);
+       if (snum == -1 || !lp_print_ok(snum))
+               return -1;
+       return snum;
+}
+
 /*******************************************************************
  Used to decide if we need a short select timeout.
 *******************************************************************/
@@ -362,3 +374,78 @@ void notify_printer_location(int snum, char *location)
                printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
                snum, strlen(location) + 1, location);
 }
+
+void notify_printer_byname( char *printername, uint32 change, char *value )
+{
+       int snum = print_queue_snum(printername);
+       int type = PRINTER_NOTIFY_TYPE;
+       
+       if ( snum == -1 )
+               return;
+               
+       send_notify_field_buffer( printername, type, change, snum, strlen(value), value );
+} 
+
+
+/****************************************************************************
+ Return a malloced list of pid_t's that are interested in getting update
+ messages on this print queue. Used in printing/notify to send the messages.
+****************************************************************************/
+
+BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list)
+{
+       struct tdb_print_db *pdb = NULL;
+       TDB_CONTEXT *tdb = NULL;
+       TDB_DATA data;
+       BOOL ret = True;
+       size_t i, num_pids, offset;
+       pid_t *pid_list;
+
+       *p_num_pids = 0;
+       *pp_pid_list = NULL;
+
+       pdb = get_print_db_byname(printername);
+       if (!pdb)
+               return False;
+       tdb = pdb->tdb;
+
+       if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
+               DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
+                                       printername));
+               if (pdb)
+                       release_print_db(pdb);
+               return False;
+       }
+
+       data = get_printer_notify_pid_list( tdb, printername, True );
+
+       if (!data.dptr) {
+               ret = True;
+               goto done;
+       }
+
+       num_pids = data.dsize / 8;
+
+       if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) {
+               ret = False;
+               goto done;
+       }
+
+       for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++)
+               pid_list[i] = (pid_t)IVAL(data.dptr, offset);
+
+       *pp_pid_list = pid_list;
+       *p_num_pids = num_pids;
+
+       ret = True;
+
+  done:
+
+       tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
+       if (pdb)
+               release_print_db(pdb);
+       SAFE_FREE(data.dptr);
+       return ret;
+}
+
+
index a8f90972557ed37cc5b262c3c781bdc3b69e53ca..a6b5e5cb834d0f38da11fe2d5c7e1eca88396d32 100644 (file)
@@ -136,135 +136,6 @@ static pid_t local_pid;
 
 static int get_queue_status(int, print_status_struct *);
 
-/* There can be this many printing tdb's open, plus any locked ones. */
-#define MAX_PRINT_DBS_OPEN 1
-
-struct tdb_print_db {
-       struct tdb_print_db *next, *prev;
-       TDB_CONTEXT *tdb;
-       int ref_count;
-       fstring printer_name;
-};
-
-static struct tdb_print_db *print_db_head;
-
-/****************************************************************************
-  Function to find or create the printer specific job tdb given a printername.
-  Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
-****************************************************************************/
-
-static struct tdb_print_db *get_print_db_byname(const char *printername)
-{
-       struct tdb_print_db *p = NULL, *last_entry = NULL;
-       int num_open = 0;
-       pstring printdb_path;
-       BOOL done_become_root = False;
-
-       for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
-               /* Ensure the list terminates... JRA. */
-               SMB_ASSERT(p->next != print_db_head);
-
-               if (p->tdb && strequal(p->printer_name, printername)) {
-                       DLIST_PROMOTE(print_db_head, p);
-                       p->ref_count++;
-                       return p;
-               }
-               num_open++;
-               last_entry = p;
-       }
-
-       /* Not found. */
-       if (num_open >= MAX_PRINT_DBS_OPEN) {
-               /* Try and recycle the last entry. */
-               DLIST_PROMOTE(print_db_head, last_entry);
-
-               for (p = print_db_head; p; p = p->next) {
-                       if (p->ref_count)
-                               continue;
-                       if (p->tdb) {
-                               if (tdb_close(print_db_head->tdb)) {
-                                       DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
-                                                               print_db_head->printer_name ));
-                                       return NULL;
-                               }
-                       }
-                       p->tdb = NULL;
-                       p->ref_count = 0;
-                       memset(p->printer_name, '\0', sizeof(p->printer_name));
-                       break;
-               }
-               if (p) {
-                       DLIST_PROMOTE(print_db_head, p);
-                       p = print_db_head;
-               }
-       }
-       
-       if (!p) {
-               /* Create one. */
-               p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
-               if (!p) {
-                       DEBUG(0,("get_print_db: malloc fail !\n"));
-                       return NULL;
-               }
-               ZERO_STRUCTP(p);
-               DLIST_ADD(print_db_head, p);
-       }
-
-       pstrcpy(printdb_path, lock_path("printing/"));
-       pstrcat(printdb_path, printername);
-       pstrcat(printdb_path, ".tdb");
-
-       if (geteuid() != 0) {
-               become_root();
-               done_become_root = True;
-       }
-
-       p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
-
-       if (done_become_root)
-               unbecome_root();
-
-       if (!p->tdb) {
-               DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
-                                       printdb_path ));
-               DLIST_REMOVE(print_db_head, p);
-               SAFE_FREE(p);
-               return NULL;
-       }
-       fstrcpy(p->printer_name, printername);
-       p->ref_count++;
-       return p;
-}
-
-/***************************************************************************
- Remove a reference count.
-****************************************************************************/
-
-static void release_print_db( struct tdb_print_db *pdb)
-{
-       pdb->ref_count--;
-       SMB_ASSERT(pdb->ref_count >= 0);
-}
-
-/***************************************************************************
- Close all open print db entries.
-****************************************************************************/
-
-static void close_all_print_db(void)
-{
-       struct tdb_print_db *p = NULL, *next_p = NULL;
-
-       for (p = print_db_head; p; p = next_p) {
-               next_p = p->next;
-
-               if (p->tdb)
-                       tdb_close(p->tdb);
-               DLIST_REMOVE(print_db_head, p);
-               ZERO_STRUCTP(p);
-               SAFE_FREE(p);
-       }
-}
-
 /****************************************************************************
  Initialise the printing backend. Called once at startup before the fork().
 ****************************************************************************/
@@ -1046,134 +917,6 @@ static void print_queue_update(int snum)
        release_print_db(pdb);
 }
 
-/****************************************************************************
- Fetch and clean the pid_t record list for all pids interested in notify
- messages. data needs freeing on exit.
-****************************************************************************/
-
-#define NOTIFY_PID_LIST_KEY "NOTIFY_PID_LIST"
-#define PRINT_SERVER_ENTRY_NAME "___PRINT_SERVER_ENTRY___"
-
-static TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
-{
-       TDB_DATA data;
-       size_t i;
-
-       ZERO_STRUCT(data);
-
-       data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY );
-
-       if (!data.dptr) {
-               ZERO_STRUCT(data);
-               return data;
-       }
-
-       if (data.dsize % 8) {
-               DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
-               tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY );
-               SAFE_FREE(data.dptr);
-               ZERO_STRUCT(data);
-               return data;
-       }
-
-       if (!cleanlist)
-               return data;
-
-       /*
-        * Weed out all dead entries.
-        */
-
-       for( i = 0; i < data.dsize; i += 8) {
-               pid_t pid = (pid_t)IVAL(data.dptr, i);
-
-               if (pid == sys_getpid())
-                       continue;
-
-               /* 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))) {
-
-                       /* Refcount == zero is a logic error and should never happen. */
-                       if (IVAL(data.dptr, i + 4) == 0) {
-                               DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
-                                                       (unsigned int)pid, printer_name ));
-                       }
-
-                       if (data.dsize - i > 8)
-                               memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
-                       data.dsize -= 8;
-               }
-       }
-
-       return data;
-}
-
-/****************************************************************************
- Return a malloced list of pid_t's that are interested in getting update
- messages on this print queue. Used in printing/notify to send the messages.
-****************************************************************************/
-
-BOOL print_notify_pid_list(const char *printername, TALLOC_CTX *mem_ctx, size_t *p_num_pids, pid_t **pp_pid_list)
-{
-       struct tdb_print_db *pdb = NULL;
-       TDB_CONTEXT *tdb = NULL;
-       TDB_DATA data;
-       BOOL ret = True;
-       size_t i, num_pids, offset;
-       pid_t *pid_list;
-
-       *p_num_pids = 0;
-       *pp_pid_list = NULL;
-
-       if (strequal(printername, PRINT_SERVER_ENTRY_NAME)) {
-               pdb = NULL;
-               tdb = conn_tdb_ctx();
-       } else {
-               pdb = get_print_db_byname(printername);
-               if (!pdb)
-                       return False;
-               tdb = pdb->tdb;
-       }
-
-       if (tdb_read_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
-               DEBUG(0,("print_notify_pid_list: Failed to lock printer %s database\n",
-                                       printername));
-               if (pdb)
-                       release_print_db(pdb);
-               return False;
-       }
-
-       data = get_printer_notify_pid_list( tdb, printername, True );
-
-       if (!data.dptr) {
-               ret = True;
-               goto done;
-       }
-
-       num_pids = data.dsize / 8;
-
-       if ((pid_list = (pid_t *)talloc(mem_ctx, sizeof(pid_t) * num_pids)) == NULL) {
-               ret = False;
-               goto done;
-       }
-
-       for( i = 0, offset = 0; offset < data.dsize; offset += 8, i++)
-               pid_list[i] = (pid_t)IVAL(data.dptr, offset);
-
-       *pp_pid_list = pid_list;
-       *p_num_pids = num_pids;
-
-       ret = True;
-
-  done:
-
-       tdb_read_unlock_bystring(tdb, NOTIFY_PID_LIST_KEY);
-       if (pdb)
-               release_print_db(pdb);
-       SAFE_FREE(data.dptr);
-       return ret;
-}
-
 /****************************************************************************
  Create/Update an entry in the print tdb that will allow us to send notify
  updates only to interested smbd's. 
@@ -1189,16 +932,29 @@ BOOL print_notify_register_pid(int snum)
        BOOL ret = False;
        size_t i;
 
-       if (snum != -1) {
+       /* if (snum == -1), then the change notify request was
+          on a print server handle and we need to register on
+          all print queus */
+          
+       if (snum == -1) 
+       {
+               int num_services = lp_numservices();
+               int idx;
+               
+               for ( idx=0; idx<num_services; idx++ ) {
+                       if (lp_snum_ok(idx) && lp_print_ok(idx) )
+                               print_notify_register_pid(idx);
+               }
+               
+               return True;
+       }
+       else /* register for a specific printer */
+       {
                printername = lp_const_servicename(snum);
                pdb = get_print_db_byname(printername);
                if (!pdb)
                        return False;
                tdb = pdb->tdb;
-       } else {
-               printername = PRINT_SERVER_ENTRY_NAME;
-               pdb = NULL;
-               tdb = conn_tdb_ctx();
        }
 
        if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
@@ -1267,16 +1023,28 @@ BOOL print_notify_deregister_pid(int snum)
        size_t i;
        BOOL ret = False;
 
-       if (snum != -1) {
+       /* if ( snum == -1 ), we are deregister a print server handle
+          which means to deregister on all print queues */
+          
+       if (snum == -1) 
+       {
+               int num_services = lp_numservices();
+               int idx;
+               
+               for ( idx=0; idx<num_services; idx++ ) {
+                       if ( lp_snum_ok(idx) && lp_print_ok(idx) )
+                               print_notify_deregister_pid(idx);
+               }
+               
+               return True;
+       }
+       else /* deregister a specific printer */
+       {
                printername = lp_const_servicename(snum);
                pdb = get_print_db_byname(printername);
                if (!pdb)
                        return False;
                tdb = pdb->tdb;
-       } else {
-               printername = PRINT_SERVER_ENTRY_NAME;
-               pdb = NULL;
-               tdb = conn_tdb_ctx();
        }
 
        if (tdb_lock_bystring(tdb, NOTIFY_PID_LIST_KEY, 10) == -1) {
@@ -2197,18 +1965,6 @@ int print_queue_status(int snum,
        return tstruct.qcount;
 }
 
-/****************************************************************************
- Turn a queue name into a snum.
-****************************************************************************/
-
-int print_queue_snum(const char *qname)
-{
-       int snum = lp_servicenumber(qname);
-       if (snum == -1 || !lp_print_ok(snum))
-               return -1;
-       return snum;
-}
-
 /****************************************************************************
  Pause a queue.
 ****************************************************************************/
diff --git a/source/printing/printing_db.c b/source/printing/printing_db.c
new file mode 100644 (file)
index 0000000..ec33dae
--- /dev/null
@@ -0,0 +1,204 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0
+   printing backend routines
+   Copyright (C) Andrew Tridgell 1992-2000
+   Copyright (C) Jeremy Allison 2002
+   
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "printing.h"
+
+static struct tdb_print_db *print_db_head;
+
+/****************************************************************************
+  Function to find or create the printer specific job tdb given a printername.
+  Limits the number of tdb's open to MAX_PRINT_DBS_OPEN.
+****************************************************************************/
+
+struct tdb_print_db *get_print_db_byname(const char *printername)
+{
+       struct tdb_print_db *p = NULL, *last_entry = NULL;
+       int num_open = 0;
+       pstring printdb_path;
+       BOOL done_become_root = False;
+
+       for (p = print_db_head, last_entry = print_db_head; p; p = p->next) {
+               /* Ensure the list terminates... JRA. */
+               SMB_ASSERT(p->next != print_db_head);
+
+               if (p->tdb && strequal(p->printer_name, printername)) {
+                       DLIST_PROMOTE(print_db_head, p);
+                       p->ref_count++;
+                       return p;
+               }
+               num_open++;
+               last_entry = p;
+       }
+
+       /* Not found. */
+       if (num_open >= MAX_PRINT_DBS_OPEN) {
+               /* Try and recycle the last entry. */
+               DLIST_PROMOTE(print_db_head, last_entry);
+
+               for (p = print_db_head; p; p = p->next) {
+                       if (p->ref_count)
+                               continue;
+                       if (p->tdb) {
+                               if (tdb_close(print_db_head->tdb)) {
+                                       DEBUG(0,("get_print_db: Failed to close tdb for printer %s\n",
+                                                               print_db_head->printer_name ));
+                                       return NULL;
+                               }
+                       }
+                       p->tdb = NULL;
+                       p->ref_count = 0;
+                       memset(p->printer_name, '\0', sizeof(p->printer_name));
+                       break;
+               }
+               if (p) {
+                       DLIST_PROMOTE(print_db_head, p);
+                       p = print_db_head;
+               }
+       }
+       
+       if (!p) {
+               /* Create one. */
+               p = (struct tdb_print_db *)malloc(sizeof(struct tdb_print_db));
+               if (!p) {
+                       DEBUG(0,("get_print_db: malloc fail !\n"));
+                       return NULL;
+               }
+               ZERO_STRUCTP(p);
+               DLIST_ADD(print_db_head, p);
+       }
+
+       pstrcpy(printdb_path, lock_path("printing/"));
+       pstrcat(printdb_path, printername);
+       pstrcat(printdb_path, ".tdb");
+
+       if (geteuid() != 0) {
+               become_root();
+               done_become_root = True;
+       }
+
+       p->tdb = tdb_open_log(printdb_path, 0, TDB_DEFAULT, O_RDWR|O_CREAT, 0600);
+
+       if (done_become_root)
+               unbecome_root();
+
+       if (!p->tdb) {
+               DEBUG(0,("get_print_db: Failed to open printer backend database %s.\n",
+                                       printdb_path ));
+               DLIST_REMOVE(print_db_head, p);
+               SAFE_FREE(p);
+               return NULL;
+       }
+       fstrcpy(p->printer_name, printername);
+       p->ref_count++;
+       return p;
+}
+
+/***************************************************************************
+ Remove a reference count.
+****************************************************************************/
+
+void release_print_db( struct tdb_print_db *pdb)
+{
+       pdb->ref_count--;
+       SMB_ASSERT(pdb->ref_count >= 0);
+}
+
+/***************************************************************************
+ Close all open print db entries.
+****************************************************************************/
+
+void close_all_print_db(void)
+{
+       struct tdb_print_db *p = NULL, *next_p = NULL;
+
+       for (p = print_db_head; p; p = next_p) {
+               next_p = p->next;
+
+               if (p->tdb)
+                       tdb_close(p->tdb);
+               DLIST_REMOVE(print_db_head, p);
+               ZERO_STRUCTP(p);
+               SAFE_FREE(p);
+       }
+}
+
+
+/****************************************************************************
+ Fetch and clean the pid_t record list for all pids interested in notify
+ messages. data needs freeing on exit.
+****************************************************************************/
+
+TDB_DATA get_printer_notify_pid_list(TDB_CONTEXT *tdb, const char *printer_name, BOOL cleanlist)
+{
+       TDB_DATA data;
+       size_t i;
+
+       ZERO_STRUCT(data);
+
+       data = tdb_fetch_by_string( tdb, NOTIFY_PID_LIST_KEY );
+
+       if (!data.dptr) {
+               ZERO_STRUCT(data);
+               return data;
+       }
+
+       if (data.dsize % 8) {
+               DEBUG(0,("get_printer_notify_pid_list: Size of record for printer %s not a multiple of 8 !\n", printer_name ));
+               tdb_delete_by_string(tdb, NOTIFY_PID_LIST_KEY );
+               SAFE_FREE(data.dptr);
+               ZERO_STRUCT(data);
+               return data;
+       }
+
+       if (!cleanlist)
+               return data;
+
+       /*
+        * Weed out all dead entries.
+        */
+
+       for( i = 0; i < data.dsize; i += 8) {
+               pid_t pid = (pid_t)IVAL(data.dptr, i);
+
+               if (pid == sys_getpid())
+                       continue;
+
+               /* 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))) {
+
+                       /* Refcount == zero is a logic error and should never happen. */
+                       if (IVAL(data.dptr, i + 4) == 0) {
+                               DEBUG(0,("get_printer_notify_pid_list: Refcount == 0 for pid = %u printer %s !\n",
+                                                       (unsigned int)pid, printer_name ));
+                       }
+
+                       if (data.dsize - i > 8)
+                               memmove( &data.dptr[i], &data.dptr[i+8], data.dsize - i - 8);
+                       data.dsize -= 8;
+               }
+       }
+
+       return data;
+}
+
+
index 034de91ce0167452052f4a9e36c3baa83c15c872..933cabdb4b93a702a3fc54647ccd38de5a364f9a 100644 (file)
@@ -42,7 +42,7 @@ static struct {
        {"dmalloc-mark", MSG_REQ_DMALLOC_MARK },
        {"dmalloc-log-changed", MSG_REQ_DMALLOC_LOG_CHANGED },
        {"shutdown", MSG_SHUTDOWN },
-       {"change_id", MSG_PRINTER_DRVUPGRADE},
+       {"drvupgrade", MSG_PRINTER_DRVUPGRADE},
        {NULL, -1}
 };
 
@@ -50,6 +50,12 @@ time_t timeout_start;
 
 #define MAX_WAIT       10
 
+/* we need these because we link to printing*.o */
+
+void become_root(void) {}
+void unbecome_root(void) {}
+
+
 static void usage(BOOL doexit)
 {
        int i;
@@ -250,6 +256,7 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
        int i, n, v;
        int mtype;
        BOOL retval=False;
+       BOOL check_notify_msgs = False;
 
        mtype = parse_type(msg_name);
        if (mtype == -1) {
@@ -360,9 +367,7 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
                break;
 
                /* Send a notification message to a printer */
-               /* NB. None of these currently work due to changes in the printing notify mechanisms. */
 
-#if 0
        case MSG_PRINTER_NOTIFY2: {
                char *cmd;
 
@@ -380,6 +385,8 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
 
                cmd = params[0];
 
+               check_notify_msgs = True;
+
                /* Pause a print queue */
 
                if (strequal(cmd, "queuepause")) {
@@ -421,6 +428,7 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
                        notify_job_status_byname(
                                params[1], jobid, JOB_STATUS_PAUSED, 
                                SPOOLSS_NOTIFY_MSG_UNIX_JOBID);
+                       break;
                }
 
                /* Resume a print job */
@@ -438,6 +446,7 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
                        notify_job_status_byname(
                                params[1], jobid, JOB_STATUS_QUEUED,
                                SPOOLSS_NOTIFY_MSG_UNIX_JOBID);
+                       break;
                }
 
                /* Delete a print job */
@@ -461,10 +470,40 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
                                JOB_STATUS_DELETED,
                                SPOOLSS_NOTIFY_MSG_UNIX_JOBID);
                }
-
+               
+               /* printer change notify */
+               
+               if (strequal(cmd, "printer")) {
+                       int attribute = -1;
+                       
+                       if (!params[1] || !params[2] || !params[3]) {
+                               fprintf(stderr, "printer command requires an and attribute name and value!\n");
+                               fprintf(stderr, "supported attributes:\n");
+                               fprintf(stderr, "\tcomment:\n");
+                               fprintf(stderr, "\tport:\n");
+                               fprintf(stderr, "\tdriver:\n");
+                               return False;
+                       }
+                       if ( strequal(params[2], "comment") )
+                               attribute = PRINTER_NOTIFY_COMMENT;
+                       else if ( strequal(params[2], "port") )
+                               attribute = PRINTER_NOTIFY_PORT_NAME;
+                       else if ( strequal(params[2], "driver") )
+                               attribute = PRINTER_NOTIFY_DRIVER_NAME;
+                       
+                       if ( attribute == -1 ) {
+                               fprintf(stderr, "bad attribute!\n");
+                               return False;
+                       }
+                       
+                       notify_printer_byname( params[1], attribute, params[3]);
+                       
+                       break;
+               }
+               
                break;
          }
-#endif
+
 
        case MSG_SMB_FORCE_TDIS:
                if (!strequal(dest, "smbd")) {
@@ -563,6 +602,11 @@ static BOOL do_command(char *dest, char *msg_name, int iparams, char **params)
                break;
        }
 
+       /* check if we have any pending print notify messages */
+
+       if ( check_notify_msgs )
+               print_notify_send_messages();
+               
        return (True);
 }