diff options
| -rw-r--r-- | source3/Makefile.in | 8 | ||||
| -rw-r--r-- | source3/include/printing.h | 16 | ||||
| -rw-r--r-- | source3/printing/notify.c | 87 | ||||
| -rw-r--r-- | source3/printing/printing.c | 314 | ||||
| -rw-r--r-- | source3/printing/printing_db.c | 204 | ||||
| -rw-r--r-- | source3/utils/smbcontrol.c | 54 | 
6 files changed, 396 insertions, 287 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 8ec552e367..d42379472f 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -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 $@ diff --git a/source3/include/printing.h b/source3/include/printing.h index 38ff7eac36..1d658a0768 100644 --- a/source3/include/printing.h +++ b/source3/include/printing.h @@ -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_ */ diff --git a/source3/printing/notify.c b/source3/printing/notify.c index a4111831d9..f55dbff47e 100644 --- a/source3/printing/notify.c +++ b/source3/printing/notify.c @@ -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; +} + + diff --git a/source3/printing/printing.c b/source3/printing/printing.c index a8f9097255..a6b5e5cb83 100644 --- a/source3/printing/printing.c +++ b/source3/printing/printing.c @@ -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().  ****************************************************************************/ @@ -1047,134 +918,6 @@ static void print_queue_update(int snum)  }  /**************************************************************************** - 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) { @@ -2198,18 +1966,6 @@ int print_queue_status(int snum,  }  /**************************************************************************** - 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/source3/printing/printing_db.c b/source3/printing/printing_db.c new file mode 100644 index 0000000000..ec33daea1a --- /dev/null +++ b/source3/printing/printing_db.c @@ -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; +} + + diff --git a/source3/utils/smbcontrol.c b/source3/utils/smbcontrol.c index 034de91ce0..933cabdb4b 100644 --- a/source3/utils/smbcontrol.c +++ b/source3/utils/smbcontrol.c @@ -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);  }  | 
