1 /*
2 cupsext - Python extension class for CUPS 1.1+
3
4 (c) Copyright 2003-2015 HP Development Company, L.P.
5
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.
10
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.
15
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
20
21 Portions based on:
22 "lpadmin" command for the Common UNIX Printing System (CUPS).
23
24 Copyright 1997-2003 by Easy Software Products.
25
26 These coded instructions, statements, and computer programs are the
27 property of Easy Software Products and are protected by Federal
28 copyright law. Distribution and use rights are outlined in the file
29 "LICENSE.txt" which should have been included with this file. If this
30 file is missing or damaged please contact Easy Software Products
31 at:
32
33 Attn: CUPS Licensing Information
34 Easy Software Products
35 44141 Airport View Drive, Suite 204
36 Hollywood, Maryland 20636-3111 USA
37
38 Voice: (301) 373-9603
39 EMail: cups-info@cups.org
40 WWW: http://www.cups.org
41
42 Redistribution and use in source and binary forms, with or without
43 modification, are permitted provided that the following conditions
44 are met:
45 1. Redistributions of source code must retain the above copyright
46 notice, this list of conditions and the following disclaimer.
47 2. Redistributions in binary form must reproduce the above copyright
48 notice, this list of conditions and the following disclaimer in the
49 documentation and/or other materials provided with the distribution.
50 3. Neither the name of HP nor the names of its
51 contributors may be used to endorse or promote products derived
52 from this software without specific prior written permission.
53
54 THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR IMPLIED
55 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
56 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
57 NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
59 TO, PATENT INFRINGEMENT; PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
60 OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
61 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
62 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
63 THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64
65
66 Requires:
67 CUPS 1.1+
68 Python 2.2+
69
70 Author:
71 Don Welch
72 Yashwant Kumar Sahu
73 Sanjay Kumar
74 */
75
76
77 #include <Python.h>
78 #include <structmember.h>
79 #include <cups/cups.h>
80 #include <cups/language.h>
81 #include <cups/ppd.h>
82 #include <syslog.h>
83 #include <stdarg.h>
84 #include <sys/types.h>
85 #include <pwd.h>
86
87
88 #include "cupsext.h"
89 #include "hp_ipp.h"
90 #include "utils.h"
91
92
93 /* Ref: PEP 353 (Python 2.5) */
94 #if PY_VERSION_HEX < 0x02050000
95 typedef int Py_ssize_t;
96 #define PY_SSIZE_T_MAX INT_MAX
97 #define PY_SSIZE_T_MIN INT_MIN
98 #endif
99
100 #define _STRINGIZE(x) #x
101 #define STRINGIZE(x) _STRINGIZE(x)
102
103
104 //static http_t * http = NULL; /* HTTP object */
105
releaseCupsInstance(PyObject * self,PyObject * args)106 PyObject * releaseCupsInstance( PyObject * self, PyObject * args )
107 {
108 _releaseCupsInstance();
109
110 return Py_BuildValue( "i", 1 );
111 }
112
113 int g_num_options = 0;
114 cups_option_t * g_options;
115
116 ppd_file_t * ppd = NULL;
117 cups_dest_t * dest = NULL;
118
119 cups_dest_t * g_dests = NULL;
120 int g_num_dests = 0;
121
122 //static int auth_cancel_req = 0; // 0--> authentication cancel is not requested, 1 --> authentication cancelled
123
124 const char * g_ppd_file = NULL;
125
getUserName()126 static char *getUserName()
127 {
128 struct passwd *pw = getpwuid(geteuid());
129 if (pw)
130 {
131 return pw->pw_name;
132 }
133 return NULL;
134 }
135
PyObj_from_UTF8(const char * utf8)136 static PyObject * PyObj_from_UTF8(const char *utf8)
137 {
138 PyObject *val = PyUnicode_Decode(utf8, strlen(utf8), "utf-8", NULL);
139
140 if (!val)
141 {
142 // CUPS 1.2 always gives us UTF-8. Before CUPS 1.2, the
143 // ppd-* strings come straight from the PPD with no
144 // transcoding, but the attributes-charset is still 'utf-8'
145 // so we've no way of knowing the real encoding.
146 // In that case, detect the error and force it to ASCII.
147 char * ascii;
148 const char * orig = utf8;
149 int i;
150
151 PyErr_Clear();
152 ascii = malloc(1 + strlen (orig));
153
154 for (i = 0; orig[i]; i++)
155 {
156 ascii[i] = orig[i] & 0x7f;
157 }
158
159 ascii[i] = '\0';
160 //val = PyString_FromString( ascii );
161 val = PYUnicode_STRING( ascii );
162 free( ascii );
163 }
164
165 return val;
166 }
167
debug(const char * text)168 void debug(const char * text)
169 {
170 char buf[4096];
171 sprintf( buf, "print '%s'", text);
172 PyRun_SimpleString( buf );
173
174 }
175
176 //staticforward PyTypeObject printer_Type;
177 static PyTypeObject printer_Type;
178
179 #define printerObject_Check(v) ((v)->ob_type == &printer_Type)
180
181 typedef struct
182 {
183 PyObject_HEAD
184 PyObject * device_uri;
185 PyObject * printer_uri;
186 PyObject * name;
187 PyObject * location;
188 PyObject * makemodel;
189 PyObject * info;
190 int accepting;
191 int state;
192 }
193 printer_Object;
194
195
printer_dealloc(printer_Object * self)196 static void printer_dealloc( printer_Object * self )
197 {
198
199 Py_XDECREF( self->name );
200 Py_XDECREF( self->device_uri );
201 Py_XDECREF( self->printer_uri );
202 Py_XDECREF( self->location );
203 Py_XDECREF( self->makemodel );
204 Py_XDECREF( self->info );
205 PyObject_DEL( self );
206 }
207
208
209 static PyMemberDef printer_members[] =
210 {
211 { "device_uri", T_OBJECT_EX, offsetof( printer_Object, device_uri ), 0, "Device URI (device-uri)" },
212 { "printer_uri", T_OBJECT_EX, offsetof( printer_Object, printer_uri ), 0, "Printer URI (printer-uri)" },
213 { "name", T_OBJECT_EX, offsetof( printer_Object, name ), 0, "Name (printer-name)" },
214 { "location", T_OBJECT_EX, offsetof( printer_Object, location ), 0, "Location (printer-location)" },
215 { "makemodel", T_OBJECT_EX, offsetof( printer_Object, makemodel ), 0, "Make and model (printer-make-and-model)" },
216 { "state", T_INT, offsetof( printer_Object, state ), 0, "State (printer-state)" },
217 { "info", T_OBJECT_EX, offsetof( printer_Object, info ), 0, "Info/description (printer-info)" },
218 { "accepting", T_INT, offsetof( printer_Object, accepting ), 0, "Accepting/rejecting" },
219 {0}
220 };
221
222 static PyTypeObject printer_Type =
223 {
224 /* PyObject_HEAD_INIT( &PyType_Type ) */
225 /* 0, */
226 /* /\* ob_size *\/ */
227 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
228 "cupsext.Printer", /* tp_name */
229 sizeof( printer_Object ), /* tp_basicsize */
230 0, /* tp_itemsize */
231 ( destructor ) printer_dealloc, /* tp_dealloc */
232 0, /* tp_print */
233 0, /* tp_getattr */
234 0, /* tp_setattr */
235 0, /* tp_compare */
236 0, /* tp_repr */
237 0, /* tp_as_number */
238 0, /* tp_as_sequence */
239 0, /* tp_as_mapping */
240 0, /* tp_hash */
241 0, /* tp_call */
242 0, /* tp_str */
243 PyObject_GenericGetAttr, /* tp_getattro */
244 PyObject_GenericSetAttr, /* tp_setattro */
245 0, /* tp_as_buffer */
246 Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */
247 "CUPS Printer object", /* tp_doc */
248 0, /* tp_traverse */
249 0, /* tp_clear */
250 0, /* tp_richcompare */
251 0, /* tp_weaklistoffset */
252 0, /* tp_iter */
253 0, /* tp_iternext */
254 0, /*job_methods, */ /* tp_methods */
255 printer_members, /* tp_members */
256 0, /* tp_getset */
257 0, /* tp_base */
258 0, /* tp_dict */
259 0, /* tp_descr_get */
260 0, /* tp_descr_set */
261 0, /* tp_dictoffset */
262 0, /* tp_init */
263 0, /* tp_alloc */
264 0, /* tp_new */
265 };
266
267
268
269
_newPrinter(char * device_uri,char * name,char * printer_uri,char * location,char * makemodel,char * info,int state,int accepting)270 static PyObject * _newPrinter( char * device_uri,
271 char * name,
272 char * printer_uri,
273 char * location,
274 char * makemodel,
275 char * info,
276 int state,
277 int accepting )
278 {
279 printer_Object * self = PyObject_New( printer_Object, &printer_Type );
280
281 if ( !self )
282 return NULL;
283
284 if ( device_uri != NULL )
285 self->device_uri = Py_BuildValue( "s", device_uri );
286
287 if ( printer_uri != NULL )
288 self->printer_uri = Py_BuildValue( "s", printer_uri );
289
290 if ( name != NULL )
291 self->name = Py_BuildValue( "s", name );
292
293 if ( location != NULL )
294 self->location = Py_BuildValue( "s", location );
295
296 if ( makemodel != NULL )
297 self->makemodel = Py_BuildValue( "s", makemodel );
298
299 if ( info != NULL )
300 self->info = Py_BuildValue( "s", info );
301
302 self->accepting = accepting;
303 self->state = state;
304
305 return ( PyObject * ) self;
306 }
307
newPrinter(PyObject * self,PyObject * args,PyObject * kwargs)308 static PyObject * newPrinter( PyObject * self, PyObject * args, PyObject * kwargs )
309 {
310 char * device_uri = "";
311 char * name = "";
312 char * location = "";
313 char * makemodel = "";
314 int state = 0;
315 char * printer_uri = "";
316 char * info = "";
317 int accepting = 0;
318
319 char * kwds[] = { "device_uri", "name", "printer_uri", "location",
320 "makemodel", "info", "state", "accepting", NULL
321 };
322
323 if ( !PyArg_ParseTupleAndKeywords( args, kwargs, "zz|zzzzii", kwds,
324 &device_uri, &name, &printer_uri,
325 &location, &makemodel, &info, &state,
326 &accepting ) )
327 return NULL;
328
329 return _newPrinter( device_uri, printer_uri, name, location, makemodel, info, state, accepting);
330 }
331
332
getPrinters(PyObject * self,PyObject * args)333 PyObject * getPrinters( PyObject * self, PyObject * args )
334 {
335 int status = 0;
336 int index = 0;
337 printer_t *printer = NULL;
338 printer_t *printer_list = NULL;
339
340 PyObject * pyprinter_list;
341 pyprinter_list = PyList_New( 0 );
342
343
344 status = getCupsPrinters(&printer_list);
345
346 for (printer = printer_list; printer!=NULL; printer=printer->next)
347 {
348 printer_Object * pyprinter;
349 pyprinter = ( printer_Object * ) _newPrinter( printer->device_uri,
350 printer->name,
351 printer->printer_uri,
352 printer->location,
353 printer->make_model,
354 printer->info,
355 printer->state,
356 printer->accepting );
357
358
359 PyList_Append( pyprinter_list, ( PyObject * ) pyprinter );
360 }
361
362 abort:
363 if (printer_list != NULL) {
364 freePrinterList(printer_list);
365 }
366
367 return pyprinter_list;
368 }
369
370
addPrinter(PyObject * self,PyObject * args)371 PyObject * addPrinter( PyObject * self, PyObject * args )
372 {
373 int status = 0;
374 char * name, * device_uri, *location, *ppd_file, * info, * model;
375 const char * status_str = "successful-ok";
376
377 if ( !PyArg_ParseTuple( args, "zzzzzz",
378 &name, // name of printer
379 &device_uri, // DeviceURI (e.g., hp:/usb/PSC_2200_Series?serial=0000000010)
380 &location, // location of printer
381 &ppd_file, // path to PPD file (uncompressed, must exist)
382 &model, // model name (e.g., foomatic:...)
383 &info // info/description
384 ) )
385 {
386 status_str = "Invalid arguments";
387 goto abort;
388 }
389
390 status = addCupsPrinter(name, device_uri, location, ppd_file, model, info);
391 status_str = getCupsErrorString(status);
392
393 abort:
394
395 return Py_BuildValue( "is", status, status_str );
396
397 }
398
399 /*
400 * 'delPrinter()' - Delete a printer from the system...
401 */
delPrinter(PyObject * self,PyObject * args)402 PyObject * delPrinter( PyObject * self, PyObject * args )
403 {
404 char * name;
405 int status = 0;
406 const char * status_str = "";
407
408 if ( !PyArg_ParseTuple( args, "z",
409 &name ) ) // name of printer
410 {
411 goto abort;
412 }
413
414 status = delCupsPrinter(name);
415 status_str = getCupsErrorString(status);
416
417 abort:
418
419 return Py_BuildValue( "is", status ,status_str);
420 }
421
422
423 /*
424 * 'setDefaultPrinter()' - Set the default printing destination.
425 */
426
setDefaultPrinter(PyObject * self,PyObject * args)427 PyObject * setDefaultPrinter( PyObject * self, PyObject * args )
428
429 {
430 char * name;
431 int status = 0;
432 const char * status_str = "";
433
434 if ( !PyArg_ParseTuple( args, "z",
435 &name ) ) // name of printer
436 {
437 goto abort;
438 }
439
440 status = setDefaultCupsPrinter(name);
441 status_str = getCupsErrorString(status);
442
443 abort:
444 return Py_BuildValue( "is", status, status_str );
445 }
446
447
448
controlPrinter(PyObject * self,PyObject * args)449 PyObject * controlPrinter( PyObject * self, PyObject * args )
450 {
451 int status = 0;
452 int op;
453 char *name;
454 const char * status_str = "";
455
456 if ( !PyArg_ParseTuple( args, "zi", &name, &op) )
457 {
458 goto abort;
459 }
460
461 status = controlCupsPrinter(name, op);
462
463 status_str = getCupsErrorString(status);
464 if ( status <= IPP_OK_CONFLICT)
465 status = IPP_OK;
466
467 abort:
468 return Py_BuildValue( "is", status, status_str );
469 }
470
471
472
473 //staticforward PyTypeObject job_Type;
474 static PyTypeObject job_Type;
475 typedef struct
476 {
477 PyObject_HEAD
478 int id;
479 PyObject * dest;
480 PyObject * title;
481 PyObject * user;
482 int state;
483 int size;
484 }
485 job_Object;
486
487
488
job_dealloc(job_Object * self)489 static void job_dealloc( job_Object * self )
490 {
491
492 Py_XDECREF( self->dest );
493 Py_XDECREF( self->title );
494 Py_XDECREF( self->user );
495 PyObject_DEL( self );
496 }
497
498 static PyMemberDef job_members[] =
499 {
500 { "id", T_INT, offsetof( job_Object, id ), 0, "Id" },
501 { "dest", T_OBJECT_EX, offsetof( job_Object, dest ), 0, "Destination" },
502 { "state", T_INT, offsetof( job_Object, state ), 0, "State" },
503 { "title", T_OBJECT_EX, offsetof( job_Object, title ), 0, "Title" },
504 { "user", T_OBJECT_EX, offsetof( job_Object, user ), 0, "User" },
505 { "size", T_INT, offsetof( job_Object, size ), 0, "Size" },
506 {0}
507 };
508
509
510
511 static PyTypeObject job_Type =
512 {
513 /* PyObject_HEAD_INIT( &PyType_Type ) */
514 /* 0, /\* ob_size *\/ */
515 PyVarObject_HEAD_INIT( &PyType_Type, 0 )
516 "Job", /* tp_name */
517 sizeof( job_Object ), /* tp_basicsize */
518 0, /* tp_itemsize */
519 ( destructor ) job_dealloc, /* tp_dealloc */
520 0, /* tp_print */
521 0, /* tp_getattr */
522 0, /* tp_setattr */
523 0, /* tp_compare */
524 0, /* tp_repr */
525 0, /* tp_as_number */
526 0, /* tp_as_sequence */
527 0, /* tp_as_mapping */
528 0, /* tp_hash */
529 0, /* tp_call */
530 0, /* tp_str */
531 PyObject_GenericGetAttr, /* tp_getattro */
532 PyObject_GenericSetAttr, /* tp_setattro */
533 0, /* tp_as_buffer */
534 Py_TPFLAGS_DEFAULT, /* tp_flags */
535 "CUPS Job object", /* tp_doc */
536 0, /* tp_traverse */
537 0, /* tp_clear */
538 0, /* tp_richcompare */
539 0, /* tp_weaklistoffset */
540 0, /* tp_iter */
541 0, /* tp_iternext */
542 0, /*job_methods, */ /* tp_methods */
543 job_members, /* tp_members */
544 0, /* tp_getset */
545 0, /* tp_base */
546 0, /* tp_dict */
547 0, /* tp_descr_get */
548 0, /* tp_descr_set */
549 0, /* tp_dictoffset */
550 0, /* tp_init */
551 0, //(initproc)job_init, /* tp_init */
552 0, /* tp_alloc */
553 //PyType_GenericAlloc,
554 0, //job_new, /* tp_new */
555 //PyType_GenericNew,
556 };
557
558
_newJob(int id,int state,char * dest,char * title,char * user,int size)559 static /*job_Object **/ PyObject * _newJob( int id, int state, char * dest, char * title, char * user, int size )
560 {
561 job_Object * jo;
562 jo = PyObject_New( job_Object, &job_Type );
563 if ( jo == NULL )
564 return NULL;
565 jo->id = id;
566 jo->size = size;
567 jo->state = state;
568 if ( dest != NULL )
569 jo->dest = PyObj_from_UTF8( dest );
570 else
571 jo->dest = Py_BuildValue( "" );
572
573 if ( title != NULL )
574 jo->title = PyObj_from_UTF8( title );
575 else
576 jo->title = Py_BuildValue( "" );
577
578 if ( user != NULL )
579 jo->user = PyObj_from_UTF8( user );
580 else
581 jo->user = Py_BuildValue( "" );
582
583 return ( PyObject * ) jo;
584
585 }
586
newJob(PyObject * self,PyObject * args,PyObject * kwargs)587 static /*job_Object **/ PyObject * newJob( PyObject * self, PyObject * args, PyObject * kwargs )
588 {
589 char * dest = "";
590 int id = 0;
591 int state = 0;
592 char * title = "";
593 char * user = "";
594 int size = 0;
595
596 char * kwds[] = { "id", "state", "dest", "title", "user", "size", NULL };
597
598 if ( !PyArg_ParseTupleAndKeywords( args, kwargs, "i|izzzi", kwds,
599 &id, &state, &dest, &title, &user, &size ) )
600 return NULL;
601
602 return _newJob( id, state, dest, title, user, size );
603
604 }
605
606
getDefaultPrinter(PyObject * self,PyObject * args)607 PyObject * getDefaultPrinter( PyObject * self, PyObject * args )
608 {
609 const char * defdest;
610 defdest = cupsGetDefault();
611
612 /*char buf[1024];
613 sprintf( buf, "print 'Default Printer: %s'", defdest);
614 PyRun_SimpleString( buf );
615 */
616
617 if ( defdest == NULL )
618 return Py_BuildValue( "" ); // None
619 else
620 return Py_BuildValue( "s", defdest );
621
622 }
623
624
cancelJob(PyObject * self,PyObject * args)625 PyObject * cancelJob( PyObject * self, PyObject * args ) // cancelJob( dest, jobid )
626 {
627 int status;
628 int jobid;
629 char * dest;
630
631 if ( !PyArg_ParseTuple( args, "si", &dest, &jobid ) )
632 {
633 return Py_BuildValue( "i", 0 );
634 }
635
636 status = cupsCancelJob( dest, jobid );
637
638 return Py_BuildValue( "i", status );
639 }
640
getJobs(PyObject * self,PyObject * args)641 PyObject * getJobs( PyObject * self, PyObject * args )
642 {
643 cups_job_t * jobs;
644 Py_ssize_t i;
645 int num_jobs;
646 PyObject * job_list;
647 int my_job;
648 int completed;
649
650 if ( !PyArg_ParseTuple( args, "ii", &my_job, &completed ) )
651 {
652 return PyList_New( ( Py_ssize_t ) 0 );
653 }
654
655 num_jobs = cupsGetJobs( &jobs, NULL, my_job, completed );
656
657 if ( num_jobs > 0 )
658 {
659 job_list = PyList_New( num_jobs );
660
661 for ( i = 0; i < num_jobs; i++ )
662 {
663 job_Object * newjob;
664 newjob = ( job_Object * ) _newJob( jobs[ i ].id,
665 jobs[ i ].state,
666 jobs[ i ].dest,
667 jobs[ i ].title,
668 jobs[ i ].user,
669 jobs[ i ].size );
670
671 PyList_SetItem( job_list, i, ( PyObject * ) newjob );
672
673 }
674 cupsFreeJobs( num_jobs, jobs );
675 }
676 else
677 {
678 job_list = PyList_New( ( Py_ssize_t ) 0 );
679 }
680 return job_list;
681 }
682
getVersion(PyObject * self,PyObject * args)683 PyObject * getVersion( PyObject * self, PyObject * args )
684 {
685 return Py_BuildValue( "f", CUPS_VERSION );
686 }
687
getVersionTuple(PyObject * self,PyObject * args)688 PyObject * getVersionTuple( PyObject * self, PyObject * args )
689 {
690 return Py_BuildValue( "(iii)", CUPS_VERSION_MAJOR, CUPS_VERSION_MINOR, CUPS_VERSION_PATCH );
691 }
692
getServer(PyObject * self,PyObject * args)693 PyObject * getServer( PyObject * self, PyObject * args )
694 {
695 return Py_BuildValue( "s", cupsServer() );
696 }
697
setServer(PyObject * self,PyObject * args)698 PyObject * setServer( PyObject * self, PyObject * args )
699 {
700 char * server = NULL;
701
702 if (!PyArg_ParseTuple(args, "z", &server))
703 return Py_BuildValue( "" );
704
705 if (!strlen(server)) // Pass an empty string to restore default server
706 server = NULL;
707
708 cupsSetServer(server);
709
710 return Py_BuildValue( "" );
711 }
712
713
714 // ***************************************************************************************************
715
716 #if 0
717 PyObject * getPPDList( PyObject * self, PyObject * args )
718 {
719 int status = 0;
720 PyObject * result;
721
722 result = PyDict_New ();
723
724 status = getCupsPPDList();
725
726 abort:
727 return result;
728 }
729 #endif
730
getPPDList(PyObject * self,PyObject * args)731 PyObject *getPPDList( PyObject * self, PyObject * args )
732 {
733
734 /*Py_BuildValue( "s", device_uri )
735 * Build a CUPS_GET_PPDS request, which requires the following
736 * attributes:
737 *
738 * attributes-charset
739 * attributes-natural-language
740 * printer-uri
741 */
742
743 ipp_t *request = NULL, /* IPP Request */
744 *response = NULL; /* IPP Response */
745 PyObject * result;
746 cups_lang_t *language;
747 ipp_attribute_t * attr;
748
749 result = PyDict_New ();
750
751 if (acquireCupsInstance () == NULL)
752 {
753 goto abort;
754 }
755
756 request = ippNew();
757
758 ippSetOperation( request, CUPS_GET_PPDS );
759 ippSetRequestId ( request, 1 );
760
761 language = cupsLangDefault();
762
763 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
764 "attributes-charset", NULL, cupsLangEncoding(language));
765
766 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
767 "attributes-natural-language", NULL, language->language);
768
769 //ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
770 // NULL, "ipp://localhost/printers/");
771
772 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
773 NULL, "ipp://localhost/printers/officejet_4100");
774
775 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "requested-attributes",
776 NULL, "all");
777
778 /*
779 * Do the request and get back a response...
780 */
781
782 if ((response = cupsDoRequest(http, request, "/")) != NULL)
783 {
784
785 for (attr = ippFirstAttribute( response ); attr; attr = ippNextAttribute( response ))
786 {
787 PyObject *dict;
788 char *ppdname = NULL;
789
790 while (attr && ippGetGroupTag( attr ) != IPP_TAG_PRINTER)
791 attr = ippNextAttribute( response );
792
793 if (!attr)
794 break;
795
796 dict = PyDict_New ();
797
798 for (; attr && ippGetGroupTag( attr ) == IPP_TAG_PRINTER; attr = ippNextAttribute( response ))
799 {
800 PyObject *val = NULL;
801
802 if (!strcmp (ippGetName( attr ), "ppd-name") && ippGetValueTag( attr ) == IPP_TAG_NAME)
803 {
804 ppdname = ippGetString( attr, 0, NULL );
805
806 //sprintf( buf, "print '%s'", ppdname);
807 //PyRun_SimpleString( buf );
808 }
809
810 else if (ippGetValueTag( attr ) == IPP_TAG_TEXT || ippGetValueTag( attr ) == IPP_TAG_NAME || ippGetValueTag( attr ) == IPP_TAG_KEYWORD)
811 //else if ((!strcmp (ippGetName( attr ), "ppd-natural-language") && ippGetValueTag( attr ) == IPP_TAG_LANGUAGE) ||
812 // (!strcmp (ippGetName( attr ), "ppd-make-and-model") && ippGetValueTag( attr ) == IPP_TAG_TEXT) ||
813 // (!strcmp (ippGetName( attr ), "ppd-make") && ippGetValueTag( attr ) == IPP_TAG_TEXT) ||
814 // (!strcmp (ippGetName( attr ), "ppd-device-id") && ippGetValueTag( attr ) == IPP_TAG_TEXT))
815 {
816 val = PyObj_from_UTF8(ippGetString( attr, 0, NULL ));
817 }
818
819 if (val)
820 {
821 PyDict_SetItemString (dict, ippGetName( attr ), val);
822 Py_DECREF (val);
823 }
824 }
825
826 if (ppdname)
827 {
828 PyDict_SetItemString (result, ppdname, dict);
829 }
830 else
831 {
832 Py_DECREF (dict);
833 }
834
835 if (!attr)
836 break;
837 }
838
839 //return result;
840 }
841
842 abort:
843 if ( response != NULL )
844 ippDelete( response );
845
846 return result;
847 }
848
849
850
851 //////////////////////////////////////////////////////////////////////////
852 //NEW IPP CHANGES
853 //////////////////////////////////////////////////////////////////////////
854
855 /*
856 * 'getStatusAttributes()' - This function gets Printer status and cartridge info attributes
857 * It creates python dictionary out of those attributes and then return to the caller.
858 */
getStatusAttributes(PyObject * self,PyObject * args)859 PyObject * getStatusAttributes( PyObject * self, PyObject * args )
860 {
861 ipp_t *response = NULL; /* IPP response object */
862 ipp_attribute_t *attr = NULL; /* Current IPP attribute */
863 attr_t* attr_list = NULL;
864 PyObject * dict;
865 PyObject * pyval;
866 int attr_count = 0;
867 int index = 0;
868 int valueindex = 0;
869 char * device_uri;
870
871 if ( !PyArg_ParseTuple( args, "z", &device_uri) )
872 {
873 goto abort;
874 }
875
876 response = getDeviceStatusAttributes(device_uri, &attr_count);
877 if(!response)
878 goto abort;
879
880 //Parse the response and create the dictionary. Dictionary will look something like below.
881
882 /*{
883 ('printer-state-reasons', ['none']),
884 ('printer-state', [3]),
885 ('marker-types', ['inkCartridge', 'inkCartridge', 'inkCartridge', 'inkCartridge']),
886 ('marker-levels', [80, 60, 70, 60]),
887 ('marker-low-levels', [1, 1, 1, 1]),
888 ('marker-names', ['black ink', 'cyan ink', 'magenta ink', 'yellow ink']),
889 }
890
891 */
892
893 dict = PyDict_New();
894 if (dict == NULL)
895 goto abort;
896
897 for ( attr = ippFirstAttribute( response ); attr != NULL; attr = ippNextAttribute( response ) )
898 {
899 if ( strcmp( ippGetName( attr ), "attributes-charset" ) == 0 || strcmp(ippGetName( attr ), "attributes-natural-language" ) == 0 )
900 continue; //Don't pass common attributes
901
902 pyval = PyList_New(0);
903
904 for(index = 0; index < ippGetCount(attr); index++)
905 {
906 if (ippGetValueTag( attr ) == IPP_TAG_ENUM || ippGetValueTag( attr ) == IPP_TAG_INTEGER)
907 {
908 PyList_Append(pyval, Py_BuildValue( "i", ippGetInteger( attr, index)));
909 }
910 else if (ippGetValueTag( attr ) == IPP_TAG_TEXT || ippGetValueTag( attr ) == IPP_TAG_NAME || ippGetValueTag( attr ) == IPP_TAG_KEYWORD)
911 {
912 PyList_Append(pyval, Py_BuildValue( "s", ippGetString( attr, index, NULL )));
913 }
914 else
915 {
916 PyList_Append(pyval, Py_BuildValue( "s", "?"));
917 }
918 }
919
920 PyDict_SetItemString (dict, ippGetName( attr ), pyval);
921 Py_DECREF (pyval);
922 }
923
924 abort:
925 if ( response != NULL )
926 ippDelete( response );
927
928 return dict;
929 }
930
931 //////////////////////////////////////////////////////////////////////////
932 //NEW IPP CHANGES
933 //////////////////////////////////////////////////////////////////////////
934
935
openPPD(PyObject * self,PyObject * args)936 PyObject * openPPD( PyObject * self, PyObject * args )
937 {
938 char * printer;
939 FILE * file;
940 int j;
941
942 if ( !PyArg_ParseTuple( args, "z", &printer ) )
943 {
944 return Py_BuildValue( "" ); // None
945 }
946
947 if ( ( g_ppd_file = cupsGetPPD( ( const char * ) printer ) ) == NULL )
948 {
949 goto bailout;
950 }
951
952 if ( ( file = fopen( g_ppd_file, "r" )) == NULL )
953 {
954 unlink(g_ppd_file);
955 g_ppd_file = NULL;
956 goto bailout;
957 }
958
959 ppd = ppdOpen( file );
960 ppdLocalize( ppd );
961 fclose( file );
962
963 g_num_dests = cupsGetDests( &g_dests );
964
965 if ( g_num_dests == 0 )
966 {
967 goto bailout;
968 }
969
970 if ( ( dest = cupsGetDest( printer, NULL, g_num_dests, g_dests ) ) == NULL )
971 {
972 goto bailout;
973 }
974
975 ppdMarkDefaults( ppd );
976 cupsMarkOptions( ppd, dest->num_options, dest->options );
977
978 for ( j = 0; j < dest->num_options; j++ )
979 {
980 if ( cupsGetOption( dest->options[ j ].name, g_num_options, g_options ) == NULL )
981 {
982 g_num_options = cupsAddOption( dest->options[ j ].name, dest->options[ j ].value, g_num_options, &g_options );
983 }
984 }
985
986 bailout:
987 return Py_BuildValue( "s", g_ppd_file );
988 }
989
990
closePPD(PyObject * self,PyObject * args)991 PyObject * closePPD( PyObject * self, PyObject * args )
992 {
993 if ( ppd != NULL )
994 {
995 ppdClose( ppd );
996 unlink( g_ppd_file );
997 }
998
999 ppd = NULL;
1000
1001 return Py_BuildValue( "" ); // None
1002 }
1003
1004
getPPD(PyObject * self,PyObject * args)1005 PyObject * getPPD( PyObject * self, PyObject * args )
1006 {
1007 char * printer;
1008
1009 if ( !PyArg_ParseTuple( args, "z", &printer ) )
1010 {
1011 return Py_BuildValue( "" ); // None
1012 }
1013
1014 const char * ppd_file;
1015 ppd_file = cupsGetPPD( ( const char * ) printer );
1016
1017 return Py_BuildValue( "s", ppd_file );
1018
1019 }
1020
1021
getPPDOption(PyObject * self,PyObject * args)1022 PyObject * getPPDOption( PyObject * self, PyObject * args )
1023 {
1024 if ( ppd != NULL )
1025 {
1026 char * option;
1027
1028 if ( !PyArg_ParseTuple( args, "z", &option ) )
1029 {
1030 return Py_BuildValue( "" ); // None
1031 }
1032
1033 ppd_choice_t * marked_choice;
1034 marked_choice = ppdFindMarkedChoice( ppd, option );
1035
1036 if ( marked_choice == NULL )
1037 {
1038 return Py_BuildValue( "" ); // None
1039 }
1040 else
1041 {
1042 return Py_BuildValue( "s", marked_choice->text );
1043 }
1044 }
1045 else
1046 {
1047 return Py_BuildValue( "" ); // None
1048 }
1049 }
1050
findPPDAttribute(PyObject * self,PyObject * args)1051 PyObject * findPPDAttribute( PyObject * self, PyObject * args )
1052 {
1053 if ( ppd != NULL )
1054 {
1055 char * name;
1056 char * spec;
1057
1058 if ( !PyArg_ParseTuple( args, "zz", &name, &spec ) )
1059 {
1060 return Py_BuildValue( "" ); // None
1061 }
1062
1063 ppd_attr_t * ppd_attr;
1064 ppd_attr = ppdFindAttr(ppd, name, spec );
1065 if ( ppd_attr == NULL )
1066 {
1067 return Py_BuildValue( "" ); // None
1068 }
1069 else
1070 {
1071 return Py_BuildValue( "s", ppd_attr->value );
1072 }
1073 }
1074 else
1075 {
1076 return Py_BuildValue( "" ); // None
1077 }
1078 }
1079
getPPDPageSize(PyObject * self,PyObject * args)1080 PyObject * getPPDPageSize( PyObject * self, PyObject * args )
1081 {
1082 //char buf[1024];
1083
1084 if ( ppd != NULL )
1085 {
1086 ppd_size_t * size = NULL;
1087 float width = 0.0;
1088 float length = 0.0;
1089 ppd_choice_t * page_size = NULL;
1090
1091 page_size = ppdFindMarkedChoice( ppd, "PageSize" );
1092
1093 //sprintf( buf, "print '%s'", page_size->text );
1094 //PyRun_SimpleString( buf );
1095
1096 if ( page_size == NULL )
1097 goto bailout;
1098
1099 size = ppdPageSize( ppd, page_size->text );
1100
1101 if ( size == NULL )
1102 goto bailout;
1103
1104 //sprintf( buf, "print '%s'", size->name );
1105 //PyRun_SimpleString( buf );
1106
1107 width = ppdPageWidth( ppd, page_size->text );
1108 length = ppdPageLength( ppd, page_size->text );
1109
1110 return Py_BuildValue( "(sffffff)", page_size->text, width, length, size->left,
1111 size->bottom, size->right, size->top );
1112 }
1113
1114 bailout:
1115 return Py_BuildValue( "(sffffff)", "", 0.0, 0.0, 0.0, 0.0, 0.0, 0.0 );
1116 }
1117
1118 // ***************************************************************************************************
1119
1120
1121
resetOptions(PyObject * self,PyObject * args)1122 PyObject * resetOptions( PyObject * self, PyObject * args )
1123 {
1124 if ( g_num_options > 0 )
1125 cupsFreeOptions( g_num_options, g_options );
1126 g_num_options = 0;
1127 g_options = ( cups_option_t * ) 0;
1128
1129 return Py_BuildValue( "" );
1130
1131 }
1132
addOption(PyObject * self,PyObject * args)1133 PyObject * addOption( PyObject * self, PyObject * args )
1134 {
1135 char * option;
1136
1137 if ( !PyArg_ParseTuple( args, "z", &option ) )
1138 {
1139 return Py_BuildValue( "i", 0 );
1140 }
1141
1142 g_num_options = cupsParseOptions( option, g_num_options, &g_options );
1143
1144 return Py_BuildValue( "i", g_num_options ); // >0
1145 }
1146
removeOption(PyObject * self,PyObject * args)1147 PyObject * removeOption( PyObject * self, PyObject * args )
1148 {
1149 char * option;
1150 int j;
1151 int r = 0;
1152
1153 if ( !PyArg_ParseTuple( args, "z", &option ) )
1154 {
1155 return Py_BuildValue( "i", 0 );
1156 }
1157
1158 for (j = 0; j < g_num_options; j++)
1159 {
1160 if ( !strcasecmp(g_options[j].name, option) )
1161 {
1162 g_num_options--;
1163
1164 if ( j < g_num_options )
1165 {
1166 memcpy( (g_options + j), (g_options + j + 1),
1167 sizeof(cups_option_t) * (g_num_options - j) );
1168
1169 r = 1;
1170 }
1171 }
1172 }
1173
1174 return Py_BuildValue( "i", r );
1175 }
1176
1177
getOptions(PyObject * self,PyObject * args)1178 PyObject * getOptions( PyObject * self, PyObject * args )
1179 {
1180 PyObject * option_list;
1181 int j;
1182
1183 option_list = PyList_New( ( Py_ssize_t ) 0 );
1184 for ( j = 0; j < g_num_options; j++ )
1185 {
1186 PyList_Append( option_list, Py_BuildValue( "(ss)", g_options[ j ].name, g_options[ j ].value ) );
1187 }
1188
1189 return option_list;
1190 }
1191
duplicateSection(PyObject * self,PyObject * args)1192 PyObject * duplicateSection( PyObject * self, PyObject * args )
1193 {
1194 int i = 0, j, k, len;
1195 const char *section;
1196
1197 if ( !PyArg_ParseTuple( args, "z", §ion ) )
1198 {
1199 return Py_BuildValue( "" ); // None
1200 }
1201
1202 len = strlen(section);
1203 if ( ppd != NULL )
1204 {
1205 for( j = 0; j < ppd->num_groups; j++)
1206 {
1207 for( k = 0; k < ppd->groups[j].num_options; k++)
1208 {
1209 if(strncasecmp(ppd->groups[j].options[k].keyword, section, len) == 0)
1210 {
1211 i = 1;
1212 }
1213 }
1214 }
1215 }
1216 return Py_BuildValue( "i", i);
1217 }
1218
1219 // ***************************************************************************************************
1220
1221
1222
getGroupList(PyObject * self,PyObject * args)1223 PyObject * getGroupList( PyObject * self, PyObject * args )
1224 {
1225 PyObject * group_list;
1226 ppd_group_t *group;
1227 int i;
1228
1229 /* debug("at 0"); */
1230
1231 if ( ppd != NULL && dest != NULL )
1232 {
1233 /* debug("at 1"); */
1234
1235 group_list = PyList_New( ( Py_ssize_t ) 0 );
1236 for ( i = ppd->num_groups, group = ppd->groups; i > 0; i--, group++ )
1237 {
1238 /* debug(group->name); */
1239 PyList_Append( group_list, PyObj_from_UTF8( group->name ) );
1240 }
1241
1242 return group_list;
1243 }
1244
1245 return PyList_New( ( Py_ssize_t ) 0 );
1246 }
1247
1248
getGroup(PyObject * self,PyObject * args)1249 PyObject * getGroup( PyObject * self, PyObject * args )
1250 {
1251 const char *the_group;
1252 ppd_group_t *group;
1253 int i;
1254
1255 if ( !PyArg_ParseTuple( args, "z", &the_group ) )
1256 {
1257 goto bailout;
1258 }
1259
1260 if ( ppd != NULL && dest != NULL )
1261 {
1262 for ( i = ppd->num_groups, group = ppd->groups; i > 0; i--, group++ )
1263 {
1264 if ( strcasecmp( group->name, the_group ) == 0 )
1265 {
1266 return Py_BuildValue( "(si)", group->text, group->num_subgroups);
1267 }
1268 }
1269 }
1270
1271 bailout:
1272 return Py_BuildValue( "" );
1273 }
1274
1275
1276
getOptionList(PyObject * self,PyObject * args)1277 PyObject * getOptionList( PyObject * self, PyObject * args )
1278 {
1279 PyObject * option_list;
1280 const char *the_group;
1281 ppd_group_t *group;
1282 int i, j;
1283 ppd_option_t *option;
1284
1285 if ( !PyArg_ParseTuple( args, "z", &the_group ) )
1286 {
1287 goto bailout;
1288 }
1289
1290 if ( ppd != NULL && dest != NULL )
1291 {
1292 option_list = PyList_New( ( Py_ssize_t ) 0 );
1293
1294 for ( i = ppd->num_groups, group = ppd->groups; i > 0; i--, group++ )
1295 {
1296 if ( strcasecmp( group->name, the_group ) == 0 )
1297 {
1298 for ( j = group->num_options, option = group->options; j > 0; j--, option++ )
1299 {
1300 PyList_Append( option_list, PyObj_from_UTF8( option->keyword ) );
1301 }
1302
1303 break;
1304 }
1305 }
1306
1307 return option_list;
1308 }
1309
1310
1311
1312 bailout:
1313 return PyList_New( ( Py_ssize_t ) 0 );
1314 }
1315
1316
1317
1318
getOption(PyObject * self,PyObject * args)1319 PyObject * getOption( PyObject * self, PyObject * args )
1320 {
1321 const char *the_group;
1322 const char *the_option;
1323 ppd_group_t *group;
1324 int i, j;
1325 ppd_option_t *option;
1326
1327
1328 if ( !PyArg_ParseTuple( args, "zz", &the_group, &the_option ) )
1329 {
1330 goto bailout;
1331 }
1332
1333 if ( ppd != NULL && dest != NULL )
1334 {
1335
1336 for ( i = ppd->num_groups, group = ppd->groups; i > 0; i--, group++ )
1337 {
1338 if ( strcasecmp( group->name, the_group ) == 0 )
1339 {
1340 for ( j = group->num_options, option = group->options; j > 0; j--, option++ )
1341 {
1342 if ( strcasecmp( option->keyword, the_option ) == 0 )
1343 {
1344 return Py_BuildValue( "(ssbi)", option->text, option->defchoice,
1345 option->conflicted > 0 ? 1 : 0, option->ui );
1346 }
1347 }
1348 }
1349 }
1350 }
1351
1352 bailout:
1353 return Py_BuildValue( "" );
1354 }
1355
1356
getChoiceList(PyObject * self,PyObject * args)1357 PyObject * getChoiceList( PyObject * self, PyObject * args )
1358 {
1359 PyObject * choice_list;
1360 const char *the_group;
1361 const char *the_option;
1362 ppd_group_t *group;
1363 int i, j, k;
1364 ppd_option_t *option;
1365 ppd_choice_t *choice;
1366
1367 if ( !PyArg_ParseTuple( args, "zz", &the_group, &the_option ) )
1368 {
1369 goto bailout;
1370 }
1371
1372 if ( ppd != NULL && dest != NULL )
1373 {
1374 choice_list = PyList_New( ( Py_ssize_t ) 0 );
1375
1376 for ( i = ppd->num_groups, group = ppd->groups; i > 0; i--, group++ )
1377 {
1378 if ( strcasecmp( group->name, the_group ) == 0 )
1379 {
1380 for ( j = group->num_options, option = group->options; j > 0; j--, option++ )
1381 {
1382 if ( strcasecmp( option->keyword, the_option ) == 0 )
1383 {
1384 for ( k = option->num_choices, choice = option->choices; k > 0; k--, choice++ )
1385 {
1386 PyList_Append( choice_list, PyObj_from_UTF8( choice->choice ) );
1387 }
1388
1389 break;
1390 }
1391 }
1392 break;
1393 }
1394 }
1395
1396 return choice_list;
1397 }
1398
1399
1400 bailout:
1401 return PyList_New( ( Py_ssize_t ) 0 );
1402 }
1403
1404
1405
getChoice(PyObject * self,PyObject * args)1406 PyObject * getChoice( PyObject * self, PyObject * args )
1407 {
1408 const char * the_group;
1409 const char *the_option;
1410 const char *the_choice;
1411 ppd_group_t *group;
1412 int i, j, k;
1413 ppd_option_t *option;
1414 ppd_choice_t *choice;
1415
1416
1417 if ( !PyArg_ParseTuple( args, "zzz", &the_group, &the_option, &the_choice ) )
1418 {
1419 goto bailout;
1420 }
1421
1422 if ( ppd != NULL && dest != NULL )
1423 {
1424 for ( i = ppd->num_groups, group = ppd->groups; i > 0; i--, group++ )
1425 {
1426 if ( strcasecmp( group->name, the_group ) == 0 )
1427 {
1428 for ( j = group->num_options, option = group->options; j > 0; j--, option++ )
1429 {
1430 if ( strcasecmp( option->keyword, the_option ) == 0 )
1431 {
1432 for ( k = option->num_choices, choice = option->choices; k > 0; k--, choice++ )
1433 {
1434 if ( strcasecmp( choice->choice, the_choice ) == 0 )
1435 {
1436 return Py_BuildValue( "(sb)", choice->text, choice->marked > 0 ? 1 : 0 );
1437 }
1438 }
1439 }
1440 }
1441 }
1442 }
1443 }
1444
1445
1446 bailout:
1447 return Py_BuildValue( "" );
1448
1449
1450
1451 }
1452
setOptions(PyObject * self,PyObject * args)1453 PyObject * setOptions( PyObject * self, PyObject * args )
1454 {
1455 if ( ppd != NULL && dest != NULL )
1456 {
1457 cupsFreeOptions( dest->num_options, dest->options );
1458 dest->num_options = g_num_options;
1459 dest->options = g_options;
1460 cupsSetDests( g_num_dests, g_dests );
1461 cupsMarkOptions( ppd, dest->num_options, dest->options );
1462 }
1463
1464 return Py_BuildValue( "" );
1465 }
1466
1467 // ***************************************************************************************************
1468
printFileWithOptions(PyObject * self,PyObject * args)1469 PyObject * printFileWithOptions( PyObject * self, PyObject * args )
1470 {
1471 char * printer;
1472 char * filename;
1473 char * title;
1474 int job_id = -1;
1475 cups_dest_t * dests = NULL;
1476 cups_dest_t * dest = NULL;
1477 int num_dests = 0;
1478 int i = 0;
1479 char *requesting_user_name = NULL;
1480
1481 if ( !PyArg_ParseTuple( args, "zzz", &printer, &filename, &title ) )
1482 {
1483 return Py_BuildValue( "" ); // None
1484 }
1485 requesting_user_name = getUserName();
1486 if(requesting_user_name)
1487 {
1488 cupsSetUser(requesting_user_name);
1489 }
1490
1491 num_dests = cupsGetDests(&dests);
1492 dest = cupsGetDest( printer, NULL, num_dests, dests );
1493
1494 if ( dest != NULL )
1495 {
1496 for( i = 0; i < dest->num_options; i++ )
1497 {
1498 if ( cupsGetOption( dest->options[i].name, g_num_options, g_options ) == NULL )
1499 g_num_options = cupsAddOption( dest->options[i].name, dest->options[i].value, g_num_options, &g_options );
1500
1501 }
1502
1503 job_id = cupsPrintFile( dest->name, filename, title, g_num_options, g_options );
1504
1505 return Py_BuildValue( "i", job_id );
1506 }
1507
1508
1509 return Py_BuildValue( "i", -1 );
1510 }
1511
1512 // ***************************************************************************************************
1513
1514 static PyObject * passwordFunc = NULL;
1515 static char *passwordPrompt = NULL;
1516
password_callback(const char * prompt)1517 const char * password_callback(const char * prompt)
1518 {
1519
1520 PyObject *result = NULL;
1521 PyObject *usernameObj = NULL;
1522 PyObject *passwordObj = NULL;
1523 char *username = NULL;
1524 char *password = NULL;
1525
1526 if (passwordFunc != NULL)
1527 {
1528
1529 if (passwordPrompt)
1530 prompt = passwordPrompt;
1531
1532 result = PyObject_CallFunction(passwordFunc, "s", prompt);
1533 if (!result)
1534 return "";
1535
1536 usernameObj = PyTuple_GetItem(result, 0);
1537 if (!usernameObj)
1538 return "";
1539 username = PYUnicode_UNICODE(usernameObj);
1540 /* printf("usernameObj=%p, username='%s'\n", usernameObj, username); */
1541 if (!username)
1542 return "";
1543
1544 auth_cancel_req = ('\0' == username[0])? 1 : 0 ;
1545
1546 passwordObj = PyTuple_GetItem(result, 1);
1547 if (!passwordObj)
1548 return "";
1549 password = PYUnicode_UNICODE(passwordObj);
1550 /* printf("passwordObj=%p, password='%s'\n", passwordObj, password); */
1551 if (!password)
1552 return "";
1553
1554 cupsSetUser(username);
1555 return password;
1556
1557 }
1558
1559 return "";
1560
1561 }
1562
setPasswordPrompt(PyObject * self,PyObject * args)1563 PyObject *setPasswordPrompt(PyObject *self, PyObject *args)
1564 {
1565
1566 char *userPrompt = NULL;
1567
1568 if (!PyArg_ParseTuple(args, "z", &userPrompt))
1569 return Py_BuildValue("");
1570
1571 if (strlen(userPrompt) != 0)
1572 passwordPrompt = userPrompt;
1573 else
1574 passwordPrompt = NULL;
1575
1576 return Py_BuildValue("");
1577
1578 }
1579
setPasswordCallback(PyObject * self,PyObject * args)1580 PyObject * setPasswordCallback( PyObject * self, PyObject * args )
1581 {
1582 if( !PyArg_ParseTuple( args, "O", &passwordFunc ) )
1583 {
1584 return Py_BuildValue( "i", 0 );
1585 }
1586
1587 cupsSetPasswordCB(password_callback);
1588
1589 return Py_BuildValue( "i", 1 );
1590 }
1591
1592
getPassword(PyObject * self,PyObject * args)1593 PyObject * getPassword( PyObject * self, PyObject * args )
1594 {
1595 const char * pwd;
1596 char * prompt;
1597
1598 if( !PyArg_ParseTuple( args, "s", &prompt ) )
1599 {
1600 return Py_BuildValue( "" );
1601 }
1602
1603 pwd = cupsGetPassword( prompt );
1604
1605 if( pwd )
1606 {
1607 return Py_BuildValue( "s", pwd );
1608 }
1609 else
1610 {
1611 return Py_BuildValue( "" );
1612 }
1613 }
1614
1615
1616
1617 // ***************************************************************************************************
1618
1619 static PyMethodDef cupsext_methods[] =
1620 {
1621 { "getPrinters", ( PyCFunction ) getPrinters, METH_VARARGS },
1622 { "addPrinter", ( PyCFunction ) addPrinter, METH_VARARGS },
1623 { "delPrinter", ( PyCFunction ) delPrinter, METH_VARARGS },
1624 { "getDefaultPrinter", ( PyCFunction ) getDefaultPrinter, METH_VARARGS },
1625 { "setDefaultPrinter", ( PyCFunction ) setDefaultPrinter, METH_VARARGS },
1626 { "controlPrinter", ( PyCFunction ) controlPrinter, METH_VARARGS },
1627 { "getPPDList", ( PyCFunction ) getPPDList, METH_VARARGS },
1628 { "getPPD", ( PyCFunction ) getPPD, METH_VARARGS },
1629 { "openPPD", ( PyCFunction ) openPPD, METH_VARARGS },
1630 { "closePPD", ( PyCFunction ) closePPD, METH_VARARGS },
1631 { "getPPDOption", ( PyCFunction ) getPPDOption, METH_VARARGS },
1632 { "getPPDPageSize", ( PyCFunction ) getPPDPageSize, METH_VARARGS },
1633 { "getVersion", ( PyCFunction ) getVersion, METH_VARARGS },
1634 { "getVersionTuple", ( PyCFunction ) getVersionTuple, METH_VARARGS },
1635 { "cancelJob", ( PyCFunction ) cancelJob, METH_VARARGS },
1636 { "getJobs", ( PyCFunction ) getJobs, METH_VARARGS },
1637 { "getServer", ( PyCFunction ) getServer, METH_VARARGS },
1638 { "setServer", ( PyCFunction ) setServer, METH_VARARGS },
1639 { "addOption", ( PyCFunction ) addOption, METH_VARARGS },
1640 { "removeOption", ( PyCFunction ) removeOption, METH_VARARGS },
1641 { "resetOptions", ( PyCFunction ) resetOptions, METH_VARARGS },
1642 { "printFileWithOptions", ( PyCFunction ) printFileWithOptions, METH_VARARGS },
1643 { "Job", ( PyCFunction ) newJob, METH_VARARGS | METH_KEYWORDS },
1644 { "Printer", ( PyCFunction ) newPrinter, METH_VARARGS | METH_KEYWORDS },
1645 { "getGroupList", ( PyCFunction ) getGroupList, METH_VARARGS },
1646 { "getGroup", ( PyCFunction ) getGroup, METH_VARARGS },
1647 { "getOptionList", ( PyCFunction ) getOptionList, METH_VARARGS },
1648 { "getOption", ( PyCFunction ) getOption, METH_VARARGS },
1649 { "getChoiceList", ( PyCFunction ) getChoiceList, METH_VARARGS },
1650 { "getChoice", ( PyCFunction ) getChoice, METH_VARARGS },
1651 { "setOptions", ( PyCFunction ) setOptions, METH_VARARGS },
1652 { "getOptions", ( PyCFunction ) getOptions, METH_VARARGS },
1653 { "duplicateSection", ( PyCFunction ) duplicateSection, METH_VARARGS },
1654 { "setPasswordPrompt", (PyCFunction) setPasswordPrompt, METH_VARARGS },
1655 { "setPasswordCallback", ( PyCFunction ) setPasswordCallback, METH_VARARGS },
1656 { "getPassword", ( PyCFunction ) getPassword, METH_VARARGS },
1657 { "findPPDAttribute", ( PyCFunction ) findPPDAttribute, METH_VARARGS },
1658 { "releaseCupsInstance", ( PyCFunction ) releaseCupsInstance, METH_VARARGS },
1659 { "getStatusAttributes", ( PyCFunction ) getStatusAttributes, METH_VARARGS },
1660 { NULL, NULL }
1661 };
1662
1663
1664 static char cupsext_documentation[] = "Python extension for CUPS 1.x";
1665
1666 /* void initcupsext( void ) */
1667 /* { */
1668
1669 /* PyObject * mod = Py_InitModule4( "cupsext", cupsext_methods, */
1670 /* cupsext_documentation, ( PyObject* ) NULL, */
1671 /* PYTHON_API_VERSION ); */
1672
1673 /* if ( mod == NULL ) */
1674 /* return ; */
1675 /* } */
1676
1677
MOD_INIT(cupsext)1678 MOD_INIT(cupsext) {
1679
1680 PyObject* mod ;
1681 MOD_DEF(mod, "cupsext", cupsext_documentation, cupsext_methods);
1682 if (mod == NULL)
1683 return MOD_ERROR_VAL;
1684
1685 return MOD_SUCCESS_VAL(mod);
1686
1687 }
1688
1689