Sync 3.0 branch with HEAD
[jra/samba/.git] / source3 / printing / notify.c
1 /* 
2    Unix SMB/Netbios implementation.
3    Version 2.2
4    printing backend routines
5    Copyright (C) Tim Potter, 2002
6    Copyright (C) Gerald Carter,         2002
7    
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 2 of the License, or
11    (at your option) any later version.
12    
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17    
18    You should have received a copy of the GNU General Public License
19    along with this program; if not, write to the Free Software
20    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23 #include "printing.h"
24
25 /*
26  * Print notification routines
27  */
28
29 static void send_spoolss_notify2_msg(struct spoolss_notify_msg *msg)
30 {
31         char *buf = NULL;
32         int buflen = 0, len;
33         TDB_CONTEXT *tdb;
34
35         /* Let's not waste any time with this */
36
37         if (lp_disable_spoolss())
38                 return;
39
40         /* Flatten data into a message */
41
42 again:
43         len = 0;
44
45         /* Pack header */
46
47         len += tdb_pack(buf + len, buflen - len, "f", msg->printer);
48
49         len += tdb_pack(buf + len, buflen - len, "ddddd",
50                         msg->type, msg->field, msg->id, msg->len, msg->flags);
51
52         /* Pack data */
53
54         if (msg->len == 0)
55                 len += tdb_pack(buf + len, buflen - len, "dd",
56                                 msg->notify.value[0], msg->notify.value[1]);
57         else
58                 len += tdb_pack(buf + len, buflen - len, "B",
59                                 msg->len, msg->notify.data);
60
61         if (buflen != len) {
62                 buf = Realloc(buf, len);
63                 buflen = len;
64                 goto again;
65         }
66
67         /* Send message */
68
69         tdb = conn_tdb_ctx();
70
71         if (!tdb) {
72                 DEBUG(3, ("Failed to open connections database in send_spoolss_notify2_msg\n"));
73                 goto done;
74         }
75         
76         message_send_all(tdb, MSG_PRINTER_NOTIFY2, buf, buflen, False, NULL);
77
78 done:
79         SAFE_FREE(buf);
80 }
81
82 static void send_notify_field_values(const char *printer_name, uint32 type,
83                                      uint32 field, uint32 id, uint32 value1, 
84                                      uint32 value2, uint32 flags)
85 {
86         struct spoolss_notify_msg msg;
87
88         ZERO_STRUCT(msg);
89
90         fstrcpy(msg.printer, printer_name);
91         msg.type = type;
92         msg.field = field;
93         msg.id = id;
94         msg.notify.value[0] = value1;
95         msg.notify.value[1] = value2;
96         msg.flags = flags;
97
98         send_spoolss_notify2_msg(&msg);
99 }
100
101 static void send_notify_field_buffer(const char *printer_name, uint32 type,
102                                      uint32 field, uint32 id, uint32 len,
103                                      char *buffer)
104 {
105         struct spoolss_notify_msg msg;
106
107         ZERO_STRUCT(msg);
108
109         fstrcpy(msg.printer, printer_name);
110         msg.type = type;
111         msg.field = field;
112         msg.id = id;
113         msg.len = len;
114         msg.notify.data = buffer;
115
116         send_spoolss_notify2_msg(&msg);
117 }
118
119 /* Send a message that the printer status has changed */
120
121 void notify_printer_status_byname(const char *printer_name, uint32 status)
122 {
123         /* Printer status stored in value1 */
124
125         send_notify_field_values(printer_name, PRINTER_NOTIFY_TYPE, 
126                                  PRINTER_NOTIFY_STATUS, 0, 
127                                  status, 0, 0);
128 }
129
130 void notify_printer_status(int snum, uint32 status)
131 {
132         const char *printer_name = SERVICE(snum); 
133
134         if (printer_name)
135                 notify_printer_status_byname(printer_name, status);
136 }
137
138 void notify_job_status_byname(const char *printer_name, uint32 jobid, uint32 status,
139                               uint32 flags)
140 {
141         /* Job id stored in id field, status in value1 */
142
143         send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
144                                  JOB_NOTIFY_STATUS, jobid,
145                                  status, 0, flags);
146 }
147
148 void notify_job_status(int snum, uint32 jobid, uint32 status)
149 {
150         const char *printer_name = SERVICE(snum);
151
152         notify_job_status_byname(printer_name, jobid, status, 0);
153 }
154
155 void notify_job_total_bytes(int snum, uint32 jobid, uint32 size)
156 {
157         const char *printer_name = SERVICE(snum);
158
159         /* Job id stored in id field, status in value1 */
160
161         send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
162                                  JOB_NOTIFY_TOTAL_BYTES, jobid,
163                                  size, 0, 0);
164 }
165
166 void notify_job_total_pages(int snum, uint32 jobid, uint32 pages)
167 {
168         const char *printer_name = SERVICE(snum);
169
170         /* Job id stored in id field, status in value1 */
171
172         send_notify_field_values(printer_name, JOB_NOTIFY_TYPE,
173                                  JOB_NOTIFY_TOTAL_PAGES, jobid,
174                                  pages, 0, 0);
175 }
176
177 void notify_job_username(int snum, uint32 jobid, char *name)
178 {
179         const char *printer_name = SERVICE(snum);
180
181         send_notify_field_buffer(
182                 printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_USER_NAME,
183                 jobid, strlen(name) + 1, name);
184 }
185
186 void notify_job_name(int snum, uint32 jobid, char *name)
187 {
188         const char *printer_name = SERVICE(snum);
189
190         send_notify_field_buffer(
191                 printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_DOCUMENT,
192                 jobid, strlen(name) + 1, name);
193 }
194
195 void notify_job_submitted(int snum, uint32 jobid, time_t submitted)
196 {
197         const char *printer_name = SERVICE(snum);
198
199         send_notify_field_buffer(
200                 printer_name, JOB_NOTIFY_TYPE, JOB_NOTIFY_SUBMITTED,
201                 jobid, sizeof(submitted), (char *)&submitted);
202 }
203
204 void notify_printer_driver(int snum, char *driver_name)
205 {
206         const char *printer_name = SERVICE(snum);
207
208         send_notify_field_buffer(
209                 printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_DRIVER_NAME,
210                 snum, strlen(driver_name) + 1, driver_name);
211 }
212
213 void notify_printer_comment(int snum, char *comment)
214 {
215         const char *printer_name = SERVICE(snum);
216
217         send_notify_field_buffer(
218                 printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_COMMENT,
219                 snum, strlen(comment) + 1, comment);
220 }
221
222 void notify_printer_sharename(int snum, char *share_name)
223 {
224         const char *printer_name = SERVICE(snum);
225
226         send_notify_field_buffer(
227                 printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_SHARE_NAME,
228                 snum, strlen(share_name) + 1, share_name);
229 }
230
231 void notify_printer_port(int snum, char *port_name)
232 {
233         const char *printer_name = SERVICE(snum);
234
235         send_notify_field_buffer(
236                 printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_PORT_NAME,
237                 snum, strlen(port_name) + 1, port_name);
238 }
239
240 void notify_printer_location(int snum, char *location)
241 {
242         const char *printer_name = SERVICE(snum);
243
244         send_notify_field_buffer(
245                 printer_name, PRINTER_NOTIFY_TYPE, PRINTER_NOTIFY_LOCATION,
246                 snum, strlen(location) + 1, location);
247 }