implemented lock and mknod
[Samba.git] / source / python / py_spoolss_printers.c
blob8d4cd24778c315b3fd8e7f1a485123e3a0e6668b
1 /*
2 Python wrappers for DCERPC/SMB client routines.
4 Copyright (C) Tim Potter, 2002
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 #include "python/py_spoolss.h"
23 /* Open a printer */
25 PyObject *spoolss_openprinter(PyObject *self, PyObject *args, PyObject *kw)
27 char *unc_name, *server, *errstr;
28 TALLOC_CTX *mem_ctx = NULL;
29 POLICY_HND hnd;
30 WERROR werror;
31 PyObject *result = NULL, *creds = NULL;
32 static char *kwlist[] = { "printername", "creds", "access", NULL };
33 uint32 desired_access = MAXIMUM_ALLOWED_ACCESS;
34 struct cli_state *cli;
36 if (!PyArg_ParseTupleAndKeywords(
37 args, kw, "s|Oi", kwlist, &unc_name, &creds,
38 &desired_access))
39 return NULL;
41 if (unc_name[0] != '\\' || unc_name[1] != '\\') {
42 PyErr_SetString(PyExc_ValueError, "UNC name required");
43 return NULL;
46 server = strdup(unc_name + 2);
48 if (strchr(server, '\\')) {
49 char *c = strchr(server, '\\');
50 *c = 0;
53 if (creds && creds != Py_None && !PyDict_Check(creds)) {
54 PyErr_SetString(PyExc_TypeError,
55 "credentials must be dictionary or None");
56 return NULL;
59 if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
60 PyErr_SetString(spoolss_error, errstr);
61 free(errstr);
62 goto done;
65 if (!(mem_ctx = talloc_init())) {
66 PyErr_SetString(spoolss_error,
67 "unable to init talloc context\n");
68 goto done;
71 werror = cli_spoolss_open_printer_ex(
72 cli, mem_ctx, unc_name, "", desired_access, server,
73 "", &hnd);
75 if (!W_ERROR_IS_OK(werror)) {
76 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
77 goto done;
80 result = new_spoolss_policy_hnd_object(cli, mem_ctx, &hnd);
82 done:
83 if (!result) {
84 if (cli)
85 cli_shutdown(cli);
87 if (mem_ctx)
88 talloc_destroy(mem_ctx);
91 SAFE_FREE(server);
93 return result;
96 /* Close a printer */
98 PyObject *spoolss_closeprinter(PyObject *self, PyObject *args)
100 PyObject *po;
101 spoolss_policy_hnd_object *hnd;
102 WERROR result;
104 /* Parse parameters */
106 if (!PyArg_ParseTuple(args, "O!", &spoolss_policy_hnd_type, &po))
107 return NULL;
109 hnd = (spoolss_policy_hnd_object *)po;
111 /* Call rpc function */
113 result = cli_spoolss_close_printer(hnd->cli, hnd->mem_ctx, &hnd->pol);
115 /* Return value */
117 Py_INCREF(Py_None);
118 return Py_None;
121 /* Fetch printer information */
123 PyObject *spoolss_hnd_getprinter(PyObject *self, PyObject *args, PyObject *kw)
125 spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
126 WERROR werror;
127 PyObject *result = NULL;
128 PRINTER_INFO_CTR ctr;
129 int level = 1;
130 uint32 needed;
131 static char *kwlist[] = {"level", NULL};
133 /* Parse parameters */
135 if (!PyArg_ParseTupleAndKeywords(args, kw, "|i", kwlist, &level))
136 return NULL;
138 if (level < 0 || level > 3) {
139 PyErr_SetString(spoolss_error, "Invalid info level");
140 return NULL;
143 ZERO_STRUCT(ctr);
145 /* Call rpc function */
147 werror = cli_spoolss_getprinter(
148 hnd->cli, hnd->mem_ctx, 0, &needed, &hnd->pol, level, &ctr);
150 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
151 werror = cli_spoolss_getprinter(
152 hnd->cli, hnd->mem_ctx, needed, NULL, &hnd->pol,
153 level, &ctr);
155 /* Return value */
157 if (!W_ERROR_IS_OK(werror)) {
158 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
159 return NULL;
162 result = Py_None;
164 switch (level) {
166 case 0:
167 py_from_PRINTER_INFO_0(&result, ctr.printers_0);
168 break;
170 case 1:
171 py_from_PRINTER_INFO_1(&result, ctr.printers_1);
172 break;
174 case 2:
175 py_from_PRINTER_INFO_2(&result, ctr.printers_2);
176 break;
178 case 3:
179 py_from_PRINTER_INFO_3(&result, ctr.printers_3);
180 break;
183 Py_INCREF(result);
184 return result;
187 /* Set printer information */
189 PyObject *spoolss_hnd_setprinter(PyObject *self, PyObject *args, PyObject *kw)
191 spoolss_policy_hnd_object *hnd = (spoolss_policy_hnd_object *)self;
192 WERROR werror;
193 PyObject *info;
194 PRINTER_INFO_CTR ctr;
195 uint32 level;
196 static char *kwlist[] = {"dict", NULL};
197 union {
198 PRINTER_INFO_1 printers_1;
199 PRINTER_INFO_2 printers_2;
200 PRINTER_INFO_3 printers_3;
201 } pinfo;
203 /* Parse parameters */
205 if (!PyArg_ParseTupleAndKeywords(
206 args, kw, "O!", kwlist, &PyDict_Type, &info))
207 return NULL;
209 if (!get_level_value(info, &level)) {
210 PyErr_SetString(spoolss_error, "invalid info level");
211 return NULL;
214 if (level < 1 && level > 3) {
215 PyErr_SetString(spoolss_error, "unsupported info level");
216 return NULL;
219 /* Fill in printer info */
221 ZERO_STRUCT(ctr);
223 switch (level) {
224 case 1:
225 ctr.printers_1 = &pinfo.printers_1;
227 if (!py_to_PRINTER_INFO_1(&pinfo.printers_1, info)){
228 PyErr_SetString(spoolss_error,
229 "error converting printer to info 1");
230 return NULL;
233 break;
234 case 2:
235 ctr.printers_2 = &pinfo.printers_2;
237 if (!py_to_PRINTER_INFO_2(&pinfo.printers_2, info,
238 hnd->mem_ctx)){
239 PyErr_SetString(spoolss_error,
240 "error converting printer to info 2");
241 return NULL;
244 break;
245 case 3:
246 ctr.printers_3 = &pinfo.printers_3;
248 if (!py_to_PRINTER_INFO_3(&pinfo.printers_3, info,
249 hnd->mem_ctx)) {
250 PyErr_SetString(spoolss_error,
251 "error converting to printer info 3");
252 return NULL;
255 break;
256 default:
257 PyErr_SetString(spoolss_error, "unsupported info level");
258 return NULL;
261 /* Call rpc function */
263 werror = cli_spoolss_setprinter(hnd->cli, hnd->mem_ctx, &hnd->pol,
264 level, &ctr, 0);
266 /* Return value */
268 if (!W_ERROR_IS_OK(werror)) {
269 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
270 return NULL;
273 Py_INCREF(Py_None);
274 return Py_None;
277 /* Enumerate printers */
279 PyObject *spoolss_enumprinters(PyObject *self, PyObject *args, PyObject *kw)
281 WERROR werror;
282 PyObject *result = NULL, *creds = NULL;
283 PRINTER_INFO_CTR ctr;
284 int level = 1, flags = PRINTER_ENUM_LOCAL, i;
285 uint32 needed, num_printers;
286 static char *kwlist[] = {"server", "name", "level", "flags",
287 "creds", NULL};
288 TALLOC_CTX *mem_ctx = NULL;
289 struct cli_state *cli = NULL;
290 char *server, *errstr, *name = NULL;
292 /* Parse parameters */
294 if (!PyArg_ParseTupleAndKeywords(
295 args, kw, "s|siiO", kwlist, &server, &name, &level,
296 &flags, &creds))
297 return NULL;
299 if (server[0] != '\\' || server[1] != '\\') {
300 PyErr_SetString(PyExc_ValueError, "UNC name required");
301 return NULL;
304 server += 2;
306 if (creds && creds != Py_None && !PyDict_Check(creds)) {
307 PyErr_SetString(PyExc_TypeError,
308 "credentials must be dictionary or None");
309 return NULL;
312 if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
313 PyErr_SetString(spoolss_error, errstr);
314 free(errstr);
315 goto done;
318 if (!(mem_ctx = talloc_init())) {
319 PyErr_SetString(
320 spoolss_error, "unable to init talloc context\n");
321 goto done;
324 /* This RPC is weird. By setting the server name to different
325 values we can get different behaviour. If however the server
326 name is not specified, we default it to being the full server
327 name as this is probably what the caller intended. To pass a
328 NULL name, pass a value of "" */
330 if (!name)
331 name = server;
332 else {
333 if (!name[0])
334 name = NULL;
337 /* Call rpc function */
339 werror = cli_spoolss_enum_printers(
340 cli, mem_ctx, 0, &needed, flags, level,
341 &num_printers, &ctr);
343 if (W_ERROR_V(werror) == ERRinsufficientbuffer)
344 werror = cli_spoolss_enum_printers(
345 cli, mem_ctx, needed, NULL, flags, level,
346 &num_printers, &ctr);
348 if (!W_ERROR_IS_OK(werror)) {
349 PyErr_SetObject(spoolss_werror, py_werror_tuple(werror));
350 goto done;
353 /* Return value */
355 switch (level) {
356 case 0:
357 result = PyDict_New();
359 for (i = 0; i < num_printers; i++) {
360 PyObject *value;
361 fstring name;
363 rpcstr_pull(name, ctr.printers_0[i].printername.buffer,
364 sizeof(fstring), -1, STR_TERMINATE);
366 py_from_PRINTER_INFO_0(&value, &ctr.printers_0[i]);
368 PyDict_SetItemString(
369 value, "level", PyInt_FromLong(0));
371 PyDict_SetItemString(result, name, value);
374 break;
375 case 1:
376 result = PyDict_New();
378 for(i = 0; i < num_printers; i++) {
379 PyObject *value;
380 fstring name;
382 rpcstr_pull(name, ctr.printers_1[i].name.buffer,
383 sizeof(fstring), -1, STR_TERMINATE);
385 py_from_PRINTER_INFO_1(&value, &ctr.printers_1[i]);
387 PyDict_SetItemString(
388 value, "level", PyInt_FromLong(1));
390 PyDict_SetItemString(result, name, value);
393 break;
394 case 2:
395 result = PyDict_New();
397 for(i = 0; i < num_printers; i++) {
398 PyObject *value;
399 fstring name;
401 rpcstr_pull(name, ctr.printers_2[i].printername.buffer,
402 sizeof(fstring), -1, STR_TERMINATE);
404 py_from_PRINTER_INFO_2(&value, &ctr.printers_2[i]);
406 PyDict_SetItemString(
407 value, "level", PyInt_FromLong(2));
409 PyDict_SetItemString(result, name, value);
412 break;
413 default:
414 PyErr_SetString(spoolss_error, "unknown info level");
415 goto done;
418 done:
419 if (cli)
420 cli_shutdown(cli);
422 if (mem_ctx)
423 talloc_destroy(mem_ctx);
425 return result;
428 /* Add a printer */
430 PyObject *spoolss_addprinterex(PyObject *self, PyObject *args, PyObject *kw)
432 static char *kwlist[] = { "server", "printername", "info", "creds",
433 NULL};
434 char *printername, *server, *errstr;
435 PyObject *info, *result = NULL, *creds = NULL;
436 struct cli_state *cli = NULL;
437 TALLOC_CTX *mem_ctx = NULL;
438 PRINTER_INFO_CTR ctr;
439 PRINTER_INFO_2 info2;
440 WERROR werror;
442 if (!PyArg_ParseTupleAndKeywords(
443 args, kw, "ssO!|O!", kwlist, &server, &printername,
444 &PyDict_Type, &info, &PyDict_Type, &creds))
445 return NULL;
447 if (!(cli = open_pipe_creds(server, creds, PIPE_SPOOLSS, &errstr))) {
448 PyErr_SetString(spoolss_error, errstr);
449 free(errstr);
450 goto done;
453 if (!(mem_ctx = talloc_init())) {
454 PyErr_SetString(
455 spoolss_error, "unable to init talloc context\n");
456 goto done;
459 if (!py_to_PRINTER_INFO_2(&info2, info, mem_ctx)) {
460 PyErr_SetString(spoolss_error,
461 "error converting to printer info 2");
462 goto done;
465 ctr.printers_2 = &info2;
467 werror = cli_spoolss_addprinterex(cli, mem_ctx, 2, &ctr);
469 Py_INCREF(Py_None);
470 result = Py_None;
472 done:
473 if (cli)
474 cli_shutdown(cli);
476 if (mem_ctx)
477 talloc_destroy(mem_ctx);
479 return result;