Tizen 2.1 base
[platform/upstream/cups-filters.git] / scripting / php / phpcups.c
1 /*
2  * "$Id$"
3  *
4  *   Printing utilities for CUPS.
5  *
6  *   Copyright 2007-2011 by Apple Inc.
7  *   Copyright 1997-2007 by Easy Software Products.
8  *
9  *   These coded instructions, statements, and computer programs are the
10  *   property of Apple Inc. and are protected by Federal copyright
11  *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
12  *   which should have been included with this file.  If this file is
13  *   file is missing or damaged, see the license at "http://www.cups.org/".
14  *
15  * Contents:
16  *
17  *   cups_convert_options()        - Convert a PHP options array to a CUPS options array.
18  *   zm_startup_phpcups()          - Initialize the CUPS module.
19  *   zif_cups_cancel_job()         - Cancel a job.
20  *   zif_cups_get_dests()          - Get a list of printers and classes.
21  *   zif_cups_get_jobs()           - Get a list of jobs.
22  *   zif_cups_last_error()         - Return the last IPP status code.
23  *   zif_cups_last_error_string()  - Return the last IPP status
24  *   zif_cups_print_file()         - Print a single file.
25  *   zif_cups_print_files()        - Print multiple files.
26  */
27
28 /*
29  * Include necessary headers...
30  */
31
32 #include <cups/string-private.h>
33 #include "php.h"
34 #include "php_ini.h"
35 #include "ext/standard/info.h"
36 #include "phpcups.h"
37
38
39 /*
40  * PHP function list...
41  */
42
43 function_entry phpcups_functions[] =
44 {
45   PHP_FE(cups_cancel_job, NULL)
46   PHP_FE(cups_get_dests, NULL)
47   PHP_FE(cups_get_jobs, NULL)
48   PHP_FE(cups_last_error, NULL)
49   PHP_FE(cups_last_error_string, NULL)
50   PHP_FE(cups_print_file, NULL)
51   PHP_FE(cups_print_files, NULL)
52   {NULL, NULL, NULL}
53 };
54
55
56 /*
57  * PHP module info...
58  */
59
60 zend_module_entry phpcups_module_entry =
61 {
62   STANDARD_MODULE_HEADER,
63   "phpcups",
64   phpcups_functions,
65   PHP_MINIT(phpcups),
66   NULL,
67   NULL,
68   NULL,
69   NULL,
70   CUPS_SVERSION,
71   STANDARD_MODULE_PROPERTIES
72 };
73
74
75 ZEND_GET_MODULE(phpcups)
76
77
78 /*
79  * 'cups_convert_options()' - Convert a PHP options array to a CUPS options array.
80  */
81
82 static int                              /* O - Number of options */
83 cups_convert_options(
84     zval          *optionsobj,          /* I - Options array object */
85     cups_option_t **options)            /* O - Options */
86 {
87   int           num_options;            /* Number of options */
88   HashTable     *ht;                    /* Option array hash table */
89   Bucket        *current;               /* Current element in array */
90   zval          *value;                 /* Current value in array */
91   char          temp[255];              /* String value for numbers */
92
93
94   ht          = Z_ARRVAL_P(optionsobj);
95   num_options = 0;
96
97   for (current = ht->pListHead; current; current = current->pListNext)
98   {
99     value = (zval *)current->pDataPtr;
100
101     switch (Z_TYPE_P(value))
102     {
103       case IS_LONG :
104           sprintf(temp, "%ld", Z_LVAL_P(value));
105           num_options = cupsAddOption(current->arKey, temp, num_options,
106                                       options);
107           break;
108
109       case IS_DOUBLE :
110           sprintf(temp, "%g", Z_DVAL_P(value));
111           num_options = cupsAddOption(current->arKey, temp, num_options,
112                                       options);
113           break;
114
115       case IS_BOOL :
116           num_options = cupsAddOption(current->arKey,
117                                       Z_BVAL_P(value) ? "true" : "false",
118                                       num_options, options);
119           break;
120
121       case IS_STRING :
122           num_options = cupsAddOption(current->arKey, Z_STRVAL_P(value),
123                                       num_options, options);
124           break;
125     }
126   }
127
128   return (num_options);
129 }
130
131
132 /*
133  * 'zm_startup_phpcups()' - Initialize the CUPS module.
134  */
135
136 PHP_MINIT_FUNCTION(phpcups)
137 {
138   REGISTER_LONG_CONSTANT("CUPS_PRINTER_LOCAL", CUPS_PRINTER_LOCAL, CONST_CS);
139   REGISTER_LONG_CONSTANT("CUPS_PRINTER_CLASS", CUPS_PRINTER_CLASS, CONST_CS);
140   REGISTER_LONG_CONSTANT("CUPS_PRINTER_REMOTE", CUPS_PRINTER_REMOTE, CONST_CS);
141   REGISTER_LONG_CONSTANT("CUPS_PRINTER_BW", CUPS_PRINTER_BW, CONST_CS);
142   REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLOR", CUPS_PRINTER_COLOR, CONST_CS);
143   REGISTER_LONG_CONSTANT("CUPS_PRINTER_DUPLEX", CUPS_PRINTER_DUPLEX, CONST_CS);
144   REGISTER_LONG_CONSTANT("CUPS_PRINTER_STAPLE", CUPS_PRINTER_STAPLE, CONST_CS);
145   REGISTER_LONG_CONSTANT("CUPS_PRINTER_COPIES", CUPS_PRINTER_COPIES, CONST_CS);
146   REGISTER_LONG_CONSTANT("CUPS_PRINTER_COLLATE", CUPS_PRINTER_COLLATE, CONST_CS);
147   REGISTER_LONG_CONSTANT("CUPS_PRINTER_PUNCH", CUPS_PRINTER_PUNCH, CONST_CS);
148   REGISTER_LONG_CONSTANT("CUPS_PRINTER_COVER", CUPS_PRINTER_COVER, CONST_CS);
149   REGISTER_LONG_CONSTANT("CUPS_PRINTER_BIND", CUPS_PRINTER_BIND, CONST_CS);
150   REGISTER_LONG_CONSTANT("CUPS_PRINTER_SORT", CUPS_PRINTER_SORT, CONST_CS);
151   REGISTER_LONG_CONSTANT("CUPS_PRINTER_SMALL", CUPS_PRINTER_SMALL, CONST_CS);
152   REGISTER_LONG_CONSTANT("CUPS_PRINTER_MEDIUM", CUPS_PRINTER_MEDIUM, CONST_CS);
153   REGISTER_LONG_CONSTANT("CUPS_PRINTER_LARGE", CUPS_PRINTER_LARGE, CONST_CS);
154   REGISTER_LONG_CONSTANT("CUPS_PRINTER_VARIABLE", CUPS_PRINTER_VARIABLE, CONST_CS);
155   REGISTER_LONG_CONSTANT("CUPS_PRINTER_IMPLICIT", CUPS_PRINTER_IMPLICIT, CONST_CS);
156   REGISTER_LONG_CONSTANT("CUPS_PRINTER_DEFAULT", CUPS_PRINTER_DEFAULT, CONST_CS);
157   REGISTER_LONG_CONSTANT("CUPS_PRINTER_FAX", CUPS_PRINTER_FAX, CONST_CS);
158   REGISTER_LONG_CONSTANT("CUPS_PRINTER_REJECTING", CUPS_PRINTER_REJECTING, CONST_CS);
159   REGISTER_LONG_CONSTANT("CUPS_PRINTER_DELETE", CUPS_PRINTER_DELETE, CONST_CS);
160   REGISTER_LONG_CONSTANT("CUPS_PRINTER_NOT_SHARED", CUPS_PRINTER_NOT_SHARED, CONST_CS);
161   REGISTER_LONG_CONSTANT("CUPS_PRINTER_AUTHENTICATED", CUPS_PRINTER_AUTHENTICATED, CONST_CS);
162   REGISTER_LONG_CONSTANT("CUPS_PRINTER_COMMANDS", CUPS_PRINTER_COMMANDS, CONST_CS);
163   REGISTER_LONG_CONSTANT("CUPS_PRINTER_DISCOVERED", CUPS_PRINTER_DISCOVERED, CONST_CS);
164   REGISTER_LONG_CONSTANT("CUPS_PRINTER_OPTIONS", CUPS_PRINTER_OPTIONS, CONST_CS);
165
166   REGISTER_LONG_CONSTANT("IPP_OK", IPP_OK, CONST_CS);
167   REGISTER_LONG_CONSTANT("IPP_OK_SUBST", IPP_OK_SUBST, CONST_CS);
168   REGISTER_LONG_CONSTANT("IPP_OK_CONFLICT", IPP_OK_CONFLICT, CONST_CS);
169   REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_SUBSCRIPTIONS", IPP_OK_IGNORED_SUBSCRIPTIONS, CONST_CS);
170   REGISTER_LONG_CONSTANT("IPP_OK_IGNORED_NOTIFICATIONS", IPP_OK_IGNORED_NOTIFICATIONS, CONST_CS);
171   REGISTER_LONG_CONSTANT("IPP_OK_TOO_MANY_EVENTS", IPP_OK_TOO_MANY_EVENTS, CONST_CS);
172   REGISTER_LONG_CONSTANT("IPP_OK_BUT_CANCEL_SUBSCRIPTION", IPP_OK_BUT_CANCEL_SUBSCRIPTION, CONST_CS);
173   REGISTER_LONG_CONSTANT("IPP_OK_EVENTS_COMPLETE", IPP_OK_EVENTS_COMPLETE, CONST_CS);
174   REGISTER_LONG_CONSTANT("IPP_REDIRECTION_OTHER_SITE", IPP_REDIRECTION_OTHER_SITE, CONST_CS);
175   REGISTER_LONG_CONSTANT("IPP_BAD_REQUEST", IPP_BAD_REQUEST, CONST_CS);
176   REGISTER_LONG_CONSTANT("IPP_FORBIDDEN", IPP_FORBIDDEN, CONST_CS);
177   REGISTER_LONG_CONSTANT("IPP_NOT_AUTHENTICATED", IPP_NOT_AUTHENTICATED, CONST_CS);
178   REGISTER_LONG_CONSTANT("IPP_NOT_AUTHORIZED", IPP_NOT_AUTHORIZED, CONST_CS);
179   REGISTER_LONG_CONSTANT("IPP_NOT_POSSIBLE", IPP_NOT_POSSIBLE, CONST_CS);
180   REGISTER_LONG_CONSTANT("IPP_TIMEOUT", IPP_TIMEOUT, CONST_CS);
181   REGISTER_LONG_CONSTANT("IPP_NOT_FOUND", IPP_NOT_FOUND, CONST_CS);
182   REGISTER_LONG_CONSTANT("IPP_GONE", IPP_GONE, CONST_CS);
183   REGISTER_LONG_CONSTANT("IPP_REQUEST_ENTITY", IPP_REQUEST_ENTITY, CONST_CS);
184   REGISTER_LONG_CONSTANT("IPP_REQUEST_VALUE", IPP_REQUEST_VALUE, CONST_CS);
185   REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT", IPP_DOCUMENT_FORMAT, CONST_CS);
186   REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES", IPP_ATTRIBUTES, CONST_CS);
187   REGISTER_LONG_CONSTANT("IPP_URI_SCHEME", IPP_URI_SCHEME, CONST_CS);
188   REGISTER_LONG_CONSTANT("IPP_CHARSET", IPP_CHARSET, CONST_CS);
189   REGISTER_LONG_CONSTANT("IPP_CONFLICT", IPP_CONFLICT, CONST_CS);
190   REGISTER_LONG_CONSTANT("IPP_COMPRESSION_NOT_SUPPORTED", IPP_COMPRESSION_NOT_SUPPORTED, CONST_CS);
191   REGISTER_LONG_CONSTANT("IPP_COMPRESSION_ERROR", IPP_COMPRESSION_ERROR, CONST_CS);
192   REGISTER_LONG_CONSTANT("IPP_DOCUMENT_FORMAT_ERROR", IPP_DOCUMENT_FORMAT_ERROR, CONST_CS);
193   REGISTER_LONG_CONSTANT("IPP_DOCUMENT_ACCESS_ERROR", IPP_DOCUMENT_ACCESS_ERROR, CONST_CS);
194   REGISTER_LONG_CONSTANT("IPP_ATTRIBUTES_NOT_SETTABLE", IPP_ATTRIBUTES_NOT_SETTABLE, CONST_CS);
195   REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_SUBSCRIPTIONS", IPP_IGNORED_ALL_SUBSCRIPTIONS, CONST_CS);
196   REGISTER_LONG_CONSTANT("IPP_TOO_MANY_SUBSCRIPTIONS", IPP_TOO_MANY_SUBSCRIPTIONS, CONST_CS);
197   REGISTER_LONG_CONSTANT("IPP_IGNORED_ALL_NOTIFICATIONS", IPP_IGNORED_ALL_NOTIFICATIONS, CONST_CS);
198   REGISTER_LONG_CONSTANT("IPP_PRINT_SUPPORT_FILE_NOT_FOUND", IPP_PRINT_SUPPORT_FILE_NOT_FOUND, CONST_CS);
199   REGISTER_LONG_CONSTANT("IPP_INTERNAL_ERROR", IPP_INTERNAL_ERROR, CONST_CS);
200   REGISTER_LONG_CONSTANT("IPP_OPERATION_NOT_SUPPORTED", IPP_OPERATION_NOT_SUPPORTED, CONST_CS);
201   REGISTER_LONG_CONSTANT("IPP_SERVICE_UNAVAILABLE", IPP_SERVICE_UNAVAILABLE, CONST_CS);
202   REGISTER_LONG_CONSTANT("IPP_VERSION_NOT_SUPPORTED", IPP_VERSION_NOT_SUPPORTED, CONST_CS);
203   REGISTER_LONG_CONSTANT("IPP_DEVICE_ERROR", IPP_DEVICE_ERROR, CONST_CS);
204   REGISTER_LONG_CONSTANT("IPP_TEMPORARY_ERROR", IPP_TEMPORARY_ERROR, CONST_CS);
205   REGISTER_LONG_CONSTANT("IPP_NOT_ACCEPTING", IPP_NOT_ACCEPTING, CONST_CS);
206   REGISTER_LONG_CONSTANT("IPP_PRINTER_BUSY", IPP_PRINTER_BUSY, CONST_CS);
207   REGISTER_LONG_CONSTANT("IPP_ERROR_JOB_CANCELLED", IPP_ERROR_JOB_CANCELLED, CONST_CS);
208   REGISTER_LONG_CONSTANT("IPP_MULTIPLE_JOBS_NOT_SUPPORTED", IPP_MULTIPLE_JOBS_NOT_SUPPORTED, CONST_CS);
209   REGISTER_LONG_CONSTANT("IPP_PRINTER_IS_DEACTIVATED", IPP_PRINTER_IS_DEACTIVATED, CONST_CS);
210
211   return (SUCCESS);
212 }
213
214 /*
215  * 'zif_cups_cancel_job()' - Cancel a job.
216  */
217
218 PHP_FUNCTION(cups_cancel_job)
219 {
220   char  *dest;                          /* Destination */
221   int   dest_len,                       /* Length of destination */
222         id;                             /* Job ID */
223
224
225   if (ZEND_NUM_ARGS() != 2 ||
226       zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sl", &dest, &dest_len, &id))
227   {
228     WRONG_PARAM_COUNT;
229   }
230
231   RETURN_LONG(cupsCancelJob(dest, id));
232 }
233
234
235 /*
236  * 'zif_cups_get_dests()' - Get a list of printers and classes.
237  */
238
239 PHP_FUNCTION(cups_get_dests)
240 {
241   int           i, j,                   /* Looping vars */
242                 num_dests;              /* Number of destinations */
243   cups_dest_t   *dests,                 /* Destinations */
244                 *dest;                  /* Current destination */
245   cups_option_t *option;                /* Current option */
246   zval          *destobj,               /* Destination object */
247                 *optionsobj;            /* Options object */
248
249
250   if (ZEND_NUM_ARGS() != 0)
251   {
252     WRONG_PARAM_COUNT;
253   }
254
255   if ((num_dests = cupsGetDests(&dests)) <= 0)
256   {
257     RETURN_NULL();
258   }
259
260   if (array_init(return_value) == SUCCESS)
261   {
262     for (i = 0, dest = dests; i < num_dests; i ++, dest ++)
263     {
264       MAKE_STD_ZVAL(destobj);
265
266       if (object_init(destobj) == SUCCESS)
267       {
268        /*
269         * Add properties to the destination for each of the cups_dest_t
270         * members...
271         */
272
273         add_property_string(destobj, "name", dest->name, 1);
274         add_property_string(destobj, "instance",
275                             dest->instance ? dest->instance : "", 1);
276         add_property_long(destobj, "is_default", dest->is_default);
277
278        /*
279         * Create an associative array for the options...
280         */
281
282         MAKE_STD_ZVAL(optionsobj);
283
284         if (array_init(optionsobj) == SUCCESS)
285         {
286           for (j = 0, option = dest->options;
287                j < dest->num_options;
288                j ++, option ++)
289             add_assoc_string(optionsobj, option->name, option->value, 1);
290
291           add_property_zval(destobj, "options", optionsobj);
292         }
293
294         add_index_zval(return_value, i, destobj);
295       }
296     }
297   }
298
299   cupsFreeDests(num_dests, dests);
300 }
301
302
303 /*
304  * 'zif_cups_get_jobs()' - Get a list of jobs.
305  */
306
307 PHP_FUNCTION(cups_get_jobs)
308 {
309   char          *dest;                  /* Destination */
310   int           dest_len,               /* Length of destination */
311                 myjobs,                 /* Only show my jobs? */
312                 completed;              /* Show completed jobs? */
313   int           i,                      /* Looping var */
314                 num_jobs;               /* Number of jobs */
315   cups_job_t    *jobs,                  /* Jobs */
316                 *job;                   /* Current job */
317   zval          *jobobj;                /* Job object */
318
319
320
321
322   if (ZEND_NUM_ARGS() != 3 ||
323       zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sll", &dest, &dest_len, &myjobs, &completed))
324   {
325     WRONG_PARAM_COUNT;
326   }
327
328   if (!*dest)
329     dest = NULL;
330
331   if ((num_jobs = cupsGetJobs(&jobs, dest, myjobs, completed)) <= 0)
332   {
333     RETURN_NULL();
334   }
335
336   if (array_init(return_value) == SUCCESS)
337   {
338     for (i = 0, job = jobs; i < num_jobs; i ++, job ++)
339     {
340       MAKE_STD_ZVAL(jobobj);
341
342       if (object_init(jobobj) == SUCCESS)
343       {
344        /*
345         * Add properties to the job for each of the cups_job_t
346         * members...
347         */
348
349         add_property_long(jobobj, "id", job->id);
350         add_property_string(jobobj, "dest", job->dest, 1);
351         add_property_string(jobobj, "title", job->title, 1);
352         add_property_string(jobobj, "user", job->user, 1);
353         add_property_string(jobobj, "format", job->format, 1);
354         add_property_long(jobobj, "state", job->state);
355         add_property_long(jobobj, "size", job->size);
356         add_property_long(jobobj, "priority", job->priority);
357         add_property_long(jobobj, "completed_time", job->completed_time);
358         add_property_long(jobobj, "creation_time", job->creation_time);
359         add_property_long(jobobj, "processing_time", job->processing_time);
360
361         add_index_zval(return_value, i, jobobj);
362       }
363     }
364   }
365
366   cupsFreeJobs(num_jobs, jobs);
367 }
368
369
370 /*
371  * 'zif_cups_last_error()' - Return the last IPP status code.
372  */
373
374 PHP_FUNCTION(cups_last_error)
375 {
376   if (ZEND_NUM_ARGS() != 0)
377   {
378     WRONG_PARAM_COUNT;
379   }
380
381   RETURN_LONG(cupsLastError());
382 }
383
384
385 /*
386  * 'zif_cups_last_error_string()' - Return the last IPP status-message.
387  */
388
389 PHP_FUNCTION(cups_last_error_string)
390 {
391   if (ZEND_NUM_ARGS() != 0)
392   {
393     WRONG_PARAM_COUNT;
394   }
395
396   RETURN_STRING((char *)cupsLastErrorString(), 1);
397 }
398
399
400 /*
401  * 'zif_cups_print_file()' - Print a single file.
402  */
403
404 PHP_FUNCTION(cups_print_file)
405 {
406   char          *dest;                  /* Destination */
407   int           dest_len;               /* Length of destination */
408   char          *filename;              /* Filename */
409   int           filename_len;           /* Length of filename */
410   char          *title;                 /* Title */
411   int           title_len;              /* Length of title */
412   zval          *optionsobj;            /* Array of options */
413   int           num_options;            /* Number of options */
414   cups_option_t *options;               /* Options */
415   int           id;                     /* Job ID */
416
417
418   if (ZEND_NUM_ARGS() != 4 ||
419       zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sssa", &dest, &dest_len,
420                             &filename, &filename_len,
421                             &title, &title_len, &optionsobj))
422   {
423     WRONG_PARAM_COUNT;
424   }
425
426   num_options = cups_convert_options(optionsobj, &options);
427
428   id = cupsPrintFile(dest, filename, title, num_options, options);
429
430   cupsFreeOptions(num_options, options);
431
432   RETURN_LONG(id);
433 }
434
435
436 /*
437  * 'zif_cups_print_files()' - Print multiple files.
438  */
439
440 PHP_FUNCTION(cups_print_files)
441 {
442   char          *dest;                  /* Destination */
443   int           dest_len;               /* Length of destination */
444   zval          *filesobj;              /* Files array */
445   int           num_files;              /* Number of files */
446   const char    *files[1000];           /* Files */
447   char          *title;                 /* Title */
448   int           title_len;              /* Length of title */
449   zval          *optionsobj;            /* Array of options */
450   int           num_options;            /* Number of options */
451   cups_option_t *options;               /* Options */
452   HashTable     *ht2;                   /* Option array hash table */
453   Bucket        *current;               /* Current element in array */
454   int           id;                     /* Job ID */
455
456
457   if (ZEND_NUM_ARGS() != 4 ||
458       zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sasa", &dest, &dest_len, &filesobj,
459                             &title, &title_len, &optionsobj))
460   {
461     WRONG_PARAM_COUNT;
462   }
463
464   ht2       = Z_ARRVAL_P(filesobj);
465   num_files = 0;
466
467   for (current = ht2->pListHead; current; current = current->pListNext)
468   {
469     files[num_files ++] = Z_STRVAL_P(((zval *)current->pDataPtr));
470
471     if (num_files >= (int)(sizeof(files) / sizeof(files[0])))
472       break;
473   }
474
475   num_options = cups_convert_options(optionsobj, &options);
476
477   id = cupsPrintFiles(dest, num_files, files, title, num_options, options);
478
479   cupsFreeOptions(num_options, options);
480
481   RETURN_LONG(id);
482 }
483
484
485 /*
486  * End of "$Id$".
487  */