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