summaryrefslogtreecommitdiff
path: root/source3/rpc_server
diff options
context:
space:
mode:
authorJean-François Micouleau <jfm@samba.org>2000-09-25 21:05:18 +0000
committerJean-François Micouleau <jfm@samba.org>2000-09-25 21:05:18 +0000
commit233bc000209cf5759e0e49ad83da70b280d51dae (patch)
treeb86d40660677f230e89d385efe397472c8f2c5c7 /source3/rpc_server
parentd31a72f7390339ec2bb0f3af5da014d635ce09dd (diff)
downloadsamba-233bc000209cf5759e0e49ad83da70b280d51dae.tar.gz
samba-233bc000209cf5759e0e49ad83da70b280d51dae.tar.bz2
samba-233bc000209cf5759e0e49ad83da70b280d51dae.zip
printer notify code.
It only sends notifies to one client. The broadcasting notify code will code soon. J.F. (This used to be commit 4c63c9185887c64e57d901e82a4a16a83522c898)
Diffstat (limited to 'source3/rpc_server')
-rw-r--r--source3/rpc_server/srv_spoolss_nt.c150
1 files changed, 144 insertions, 6 deletions
diff --git a/source3/rpc_server/srv_spoolss_nt.c b/source3/rpc_server/srv_spoolss_nt.c
index ca1b20522b..2a25f615d8 100644
--- a/source3/rpc_server/srv_spoolss_nt.c
+++ b/source3/rpc_server/srv_spoolss_nt.c
@@ -60,6 +60,8 @@ typedef struct _Printer{
fstring localmachine;
uint32 printerlocal;
SPOOL_NOTIFY_OPTION *option;
+ POLICY_HND client_hnd;
+ uint32 client_connected;
} notify;
struct {
fstring machine;
@@ -78,6 +80,8 @@ typedef struct _counter_printer_0 {
static ubi_dlList Printer_list;
static ubi_dlList counter_list;
+static struct cli_state cli;
+static uint32 smb_connections=0;
#define OPEN_HANDLE(pnum) ((pnum!=NULL) && (pnum->open!=False) && (IVAL(pnum->printer_hnd.data,16)==(uint32)sys_getpid()))
#define OUR_HANDLE(pnum) ((pnum==NULL)?"NULL":(IVAL(pnum->data,16)==sys_getpid()?"OURS":"OTHER"))
@@ -170,6 +174,30 @@ static void clear_handle(POLICY_HND *hnd)
ZERO_STRUCTP(hnd);
}
+/***************************************************************************
+ Disconnect from the client
+****************************************************************************/
+static BOOL srv_spoolss_replycloseprinter(POLICY_HND *handle)
+{
+ uint32 status;
+
+ /* weird if the test succeds !!! */
+ if (smb_connections==0) {
+ DEBUG(0,("srv_spoolss_replycloseprinter:Trying to close non-existant notify backchannel !\n"));
+ return False;
+ }
+
+ if(!cli_spoolss_reply_close_printer(&cli, handle, &status))
+ return False;
+
+ /* if it's the last connection, deconnect the IPC$ share */
+ if (smb_connections==1)
+ if(!spoolss_disconnect_from_client(&cli))
+ return False;
+
+ smb_connections--;
+}
+
/****************************************************************************
close printer index by handle
****************************************************************************/
@@ -182,6 +210,10 @@ static BOOL close_printer_handle(POLICY_HND *hnd)
return False;
}
+ if (Printer->notify.client_connected==True)
+ if(!srv_spoolss_replycloseprinter(&Printer->notify.client_hnd))
+ return ERROR_INVALID_HANDLE;
+
Printer->open=False;
Printer->notify.flags=0;
Printer->notify.options=0;
@@ -189,7 +221,8 @@ static BOOL close_printer_handle(POLICY_HND *hnd)
Printer->notify.printerlocal=0;
safe_free(Printer->notify.option);
Printer->notify.option=NULL;
-
+ Printer->notify.client_connected=False;
+
clear_handle(hnd);
ubi_dlRemThis(&Printer_list, Printer);
@@ -540,6 +573,57 @@ static BOOL alloc_buffer_size(NEW_BUFFER *buffer, uint32 buffer_size)
return True;
}
+/***************************************************************************
+ receive the notify message
+****************************************************************************/
+static BOOL srv_spoolss_receive_message(char *printer)
+{
+ uint32 status;
+ Printer_entry *find_printer;
+
+ find_printer = (Printer_entry *)ubi_dlFirst(&Printer_list);
+
+ /* Iterate the printer list. */
+ for(; find_printer; find_printer = (Printer_entry *)ubi_dlNext(find_printer)) {
+
+ /*
+ * if the entry is the given printer or if it's a printerserver
+ * we send the message
+ */
+
+ if (find_printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
+ if (strcmp(find_printer->dev.handlename, printer))
+ continue;
+
+ if (find_printer->notify.client_connected==True)
+ if( !cli_spoolss_reply_rrpcn(&cli, &find_printer->notify.client_hnd, PRINTER_CHANGE_ALL, 0x0, &status))
+ return False;
+
+ }
+}
+
+/***************************************************************************
+ send a notify event
+****************************************************************************/
+static BOOL srv_spoolss_sendnotify(POLICY_HND *handle)
+{
+ fstring printer;
+
+ Printer_entry *Printer=find_printer_index_by_hnd(handle);
+
+ if (!OPEN_HANDLE(Printer)) {
+ DEBUG(0,("srv_spoolss_sendnotify: Invalid handle (%s).\n", OUR_HANDLE(handle)));
+ return False;
+ }
+
+ if (Printer->printer_type==PRINTER_HANDLE_IS_PRINTER)
+ fstrcpy(printer, Printer->dev.handlename);
+ else
+ fstrcpy(printer, "");
+
+ srv_spoolss_receive_message(printer);
+}
+
/********************************************************************
* spoolss_open_printer
*
@@ -695,6 +779,8 @@ uint32 _spoolss_deleteprinter(POLICY_HND *handle)
if (!delete_printer_handle(handle))
return ERROR_INVALID_HANDLE;
+
+ srv_spoolss_sendnotify(handle);
return NT_STATUS_NO_PROBLEMO;
}
@@ -896,6 +982,27 @@ uint32 _spoolss_getprinterdata(POLICY_HND *handle, UNISTR2 *valuename,
return NT_STATUS_NO_PROBLEMO;
}
+/***************************************************************************
+ connect to the client
+****************************************************************************/
+static BOOL srv_spoolss_replyopenprinter(char *printer, uint32 localprinter, uint32 type, POLICY_HND *handle)
+{
+ uint32 status;
+
+ /*
+ * If it's the first connection, contact the client
+ * and connect to the IPC$ share anonumously
+ */
+ if (smb_connections==0)
+ if(!spoolss_connect_to_client(&cli, printer+2)) /* the +2 is to strip the leading 2 backslashs */
+ return False;
+
+ smb_connections++;
+
+ if(!cli_spoolss_reply_open_printer(&cli, printer, localprinter, type, &status, handle))
+ return False;
+}
+
/********************************************************************
* _spoolss_rffpcnex
* ReplyFindFirstPrinterChangeNotifyEx
@@ -926,6 +1033,12 @@ uint32 _spoolss_rffpcnex(POLICY_HND *handle, uint32 flags, uint32 options,
Printer->notify.option=option;
unistr2_to_ascii(Printer->notify.localmachine, localmachine, sizeof(Printer->notify.localmachine)-1);
+ /* connect to the client machine and send a ReplyOpenPrinter */
+ if(srv_spoolss_replyopenprinter(Printer->notify.localmachine,
+ Printer->notify.printerlocal, 1,
+ &Printer->notify.client_hnd))
+ Printer->notify.client_connected=True;
+
return NT_STATUS_NO_PROBLEMO;
}
@@ -3112,6 +3225,7 @@ uint32 _spoolss_startdocprinter(POLICY_HND *handle, uint32 level,
Printer->document_started=True;
(*jobid) = Printer->jobid;
+ srv_spoolss_sendnotify(handle);
return 0x0;
}
@@ -3133,6 +3247,8 @@ uint32 _spoolss_enddocprinter(POLICY_HND *handle)
print_job_end(Printer->jobid);
/* error codes unhandled so far ... */
+ srv_spoolss_sendnotify(handle);
+
return 0x0;
}
@@ -3182,17 +3298,20 @@ static uint32 control_printer(POLICY_HND *handle, uint32 command,
switch (command) {
case PRINTER_CONTROL_PAUSE:
if (print_queue_pause(&user, snum, &errcode)) {
+ srv_spoolss_sendnotify(handle);
return 0;
}
break;
case PRINTER_CONTROL_RESUME:
case PRINTER_CONTROL_UNPAUSE:
if (print_queue_resume(&user, snum, &errcode)) {
+ srv_spoolss_sendnotify(handle);
return 0;
}
break;
case PRINTER_CONTROL_PURGE:
if (print_queue_purge(&user, snum, &errcode)) {
+ srv_spoolss_sendnotify(handle);
return 0;
}
break;
@@ -3449,6 +3568,8 @@ static uint32 update_printer(POLICY_HND *handle, uint32 level,
done:
free_a_printer(&printer, 2);
+ srv_spoolss_sendnotify(handle);
+
return result;
}
@@ -3495,7 +3616,11 @@ uint32 _spoolss_fcpn(POLICY_HND *handle)
DEBUG(0,("_spoolss_fcpn: Invalid handle (%s)\n", OUR_HANDLE(handle)));
return ERROR_INVALID_HANDLE;
}
-
+
+ if (Printer->notify.client_connected==True)
+ if(!srv_spoolss_replycloseprinter(&Printer->notify.client_hnd))
+ return ERROR_INVALID_HANDLE;
+
Printer->notify.flags=0;
Printer->notify.options=0;
Printer->notify.localmachine[0]='\0';
@@ -3504,7 +3629,8 @@ uint32 _spoolss_fcpn(POLICY_HND *handle)
safe_free(Printer->notify.option->ctr.type);
safe_free(Printer->notify.option);
Printer->notify.option=NULL;
-
+ Printer->notify.client_connected=False;
+
return NT_STATUS_NO_PROBLEMO;
}
@@ -3779,13 +3905,22 @@ uint32 _spoolss_setjob( POLICY_HND *handle,
switch (command) {
case JOB_CONTROL_CANCEL:
case JOB_CONTROL_DELETE:
- if (print_job_delete(&user, jobid)) return 0x0;
+ if (print_job_delete(&user, jobid)) {
+ srv_spoolss_sendnotify(handle);
+ return 0x0;
+ }
break;
case JOB_CONTROL_PAUSE:
- if (print_job_pause(&user, jobid)) return 0x0;
+ if (print_job_pause(&user, jobid)) {
+ srv_spoolss_sendnotify(handle);
+ return 0x0;
+ }
break;
case JOB_CONTROL_RESUME:
- if (print_job_resume(&user, jobid)) return 0x0;
+ if (print_job_resume(&user, jobid)) {
+ srv_spoolss_sendnotify(handle);
+ return 0x0;
+ }
break;
default:
return ERROR_INVALID_LEVEL;
@@ -4512,6 +4647,9 @@ static uint32 spoolss_addprinterex_level_2( const UNISTR2 *uni_srv_name,
}
free_a_printer(&printer,2);
+
+ srv_spoolss_sendnotify(handle);
+
return NT_STATUS_NO_PROBLEMO;
}