]> git.ipfire.org Git - thirdparty/cups.git/blob - scripting/php/phpcups.c
Load cups into easysw/current.
[thirdparty/cups.git] / scripting / php / phpcups.c
1 /*
2 +----------------------------------------------------------------------+
3 | PHP version 4.0 |
4 +----------------------------------------------------------------------+
5 | Copyright (c) 1997, 1998, 1999, 2000, 2001 The PHP Group |
6 +----------------------------------------------------------------------+
7 | This source file is subject to version 2.02 of the PHP license, |
8 | that is bundled with this package in the file LICENSE, and is |
9 | available at through the world-wide-web at |
10 | http://www.php.net/license/2_02.txt. |
11 | If you did not receive a copy of the PHP license and are unable to |
12 | obtain it through the world-wide-web, please send a note to |
13 | license@php.net so we can mail you a copy immediately. |
14 +----------------------------------------------------------------------+
15 | Authors: |
16 | |
17 +----------------------------------------------------------------------+
18 */
19
20 /*
21 * "$Id: phpcups.c 4530 2005-06-01 20:15:51Z mike $"
22 *
23 * Printing utilities for the Common UNIX Printing System (CUPS).
24 *
25 * Copyright 1997-2002 by Easy Software Products.
26 *
27 * These coded instructions, statements, and computer programs are the
28 * property of Easy Software Products and are protected by Federal
29 * copyright law. Distribution and use rights are outlined in the file
30 * "LICENSE.txt" which should have been included with this file. If this
31 * file is missing or damaged please contact Easy Software Products
32 * at:
33 *
34 * Attn: CUPS Licensing Information
35 * Easy Software Products
36 * 44141 Airport View Drive, Suite 204
37 * Hollywood, Maryland 20636-3111 USA
38 *
39 * Voice: (301) 373-9603
40 * EMail: cups-info@cups.org
41 * WWW: http://www.cups.org
42 */
43
44 #ifdef HAVE_CONFIG_H
45 #include "config.h"
46 #endif
47
48 #include "php.h"
49 #include "php_ini.h"
50 #include "ext/standard/info.h"
51 #include "php_phpcups.h"
52
53 /*
54 * Include necessary headers...
55 */
56
57 #include <config.h>
58 #include <cups/cups.h>
59 #include <cups/ipp.h>
60 #include <cups/language.h>
61 #include <cups/string.h>
62 #include <cups/debug.h>
63 #include <stdlib.h>
64 #include <ctype.h>
65 #include <errno.h>
66 #include <fcntl.h>
67 #include <sys/stat.h>
68 #if defined(WIN32) || defined(__EMX__)
69 # include <io.h>
70 #else
71 # include <unistd.h>
72 #endif /* WIN32 || __EMX__ */
73
74
75 static int le_result, le_link, le_plink;
76
77
78
79
80 /*
81 * Local globals...
82 */
83
84 static http_t *cups_server = NULL; /* Current server connection */
85 static ipp_status_t last_error = IPP_OK; /* Last IPP error */
86 static char authstring[HTTP_MAX_VALUE] = "";
87 /* Authorization string */
88 static char pwdstring[33] = ""; /* Last password string */
89
90
91
92
93
94 /*
95 * *********************************************************************
96 */
97
98
99
100
101 /* If you declare any globals in php_phpcups.h uncomment this:
102 ZEND_DECLARE_MODULE_GLOBALS(phpcups)
103 */
104
105 /* True global resources - no need for thread safety here */
106 static int le_phpcups;
107
108 /*
109 * Every user visible function must have an entry in phpcups_functions[].
110 */
111 function_entry phpcups_functions[] = {
112 PHP_FE(confirm_phpcups_compiled,NULL)
113 PHP_FE(cups_get_dest_list, NULL)
114 PHP_FE(cups_get_dest_options, NULL)
115 PHP_FE(cups_get_jobs, NULL)
116 PHP_FE(cups_cancel_job, NULL)
117 PHP_FE(cups_last_error, NULL)
118 PHP_FE(cups_print_file, NULL)
119 PHP_FE(cups_get_printer_attributes, NULL)
120 {NULL, NULL, NULL}
121 };
122
123
124
125
126 zend_module_entry phpcups_module_entry = {
127 STANDARD_MODULE_HEADER,
128 "phpcups",
129 phpcups_functions,
130 PHP_MINIT(phpcups),
131 PHP_MSHUTDOWN(phpcups),
132 PHP_RINIT(phpcups), /* Replace with NULL if there's nothing to do at request start */
133 PHP_RSHUTDOWN(phpcups), /* Replace with NULL if there's nothing to do at request end */
134 PHP_MINFO(phpcups),
135 "0.1", /* Replace with version number for your extension */
136 STANDARD_MODULE_PROPERTIES
137 };
138
139 #ifdef COMPILE_DL_PHPCUPS
140 ZEND_GET_MODULE(phpcups)
141 #endif
142
143
144
145
146 /* Remove comments and fill if you need to have entries in php.ini
147 PHP_INI_BEGIN()
148 STD_PHP_INI_ENTRY("phpcups.value", "42", PHP_INI_ALL, OnUpdateInt, global_value, zend_phpcups_globals, phpcups_globals)
149 STD_PHP_INI_ENTRY("phpcups.string", "foobar", PHP_INI_ALL, OnUpdateString, global_string, zend_phpcups_globals, phpcups_globals)
150 PHP_INI_END()
151 */
152
153
154
155
156 /* Uncomment this function if you have INI entries
157 static void php_phpcups_init_globals(zend_phpcups_globals *phpcups_globals)
158 {
159 phpcups_globals->value = 0;
160 phpcups_globals->string = NULL;
161 }
162 */
163
164
165
166
167 PHP_MINIT_FUNCTION(phpcups)
168 {
169 /* If you have INI entries, uncomment these lines
170 ZEND_INIT_MODULE_GLOBALS(phpcups, php_phpcups_init_globals, NULL);
171 REGISTER_INI_ENTRIES();
172 */
173 return SUCCESS;
174 }
175
176 PHP_MSHUTDOWN_FUNCTION(phpcups)
177 {
178 /* uncomment this line if you have INI entries
179 UNREGISTER_INI_ENTRIES();
180 */
181 return SUCCESS;
182 }
183
184 /* Remove if there's nothing to do at request start */
185 PHP_RINIT_FUNCTION(phpcups)
186 {
187 return SUCCESS;
188 }
189
190 /* Remove if there's nothing to do at request end */
191 PHP_RSHUTDOWN_FUNCTION(phpcups)
192 {
193 return SUCCESS;
194 }
195
196
197
198 PHP_MINFO_FUNCTION(phpcups)
199 {
200 php_info_print_table_start();
201 php_info_print_table_header(2, "phpcups support", "enabled");
202 php_info_print_table_end();
203
204 /* Remove comments if you have entries in php.ini
205 DISPLAY_INI_ENTRIES();
206 */
207 }
208
209
210
211
212
213
214
215 /* Remove the following function when you have succesfully modified config.m4
216 so that your module can be compiled into PHP, it exists only for testing
217 purposes. */
218
219 /* Every user-visible function in PHP should document itself in the source */
220 PHP_FUNCTION(confirm_phpcups_compiled)
221 {
222 char *arg = NULL;
223 int arg_len, len;
224 char string[256];
225
226 if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &arg, &arg_len) == FAILURE) {
227 return;
228 }
229
230 len = sprintf(string, "Congratulations! You have successfully modified ext/%.78s/config.m4. Module %.78s is now compiled into PHP.", "phpcups", arg);
231 RETURN_STRINGL(string, len, 1);
232 }
233 /* The previous line is meant for vim and emacs, so it can correctly fold and
234 unfold functions in source code. See the corresponding marks just before
235 function definition, where the functions purpose is also documented. Please
236 follow this convention for the convenience of others editing your code.
237 */
238
239
240
241
242
243
244
245
246
247
248
249 /*
250 * Function: cups_get_dest_options
251 *
252 * Date: 8 April 2002 - TDB
253 *
254 * Parameters: d_name - String - Name of destination.
255 * d_instance - String - Name of instance on destination.
256 *
257 * Returns: Array of option "objects", with each object
258 * containing the members:
259 *
260 * name - String - Option name
261 * value - String - Option value
262 *
263 * Comments:
264 *
265 */
266 PHP_FUNCTION(cups_get_dest_options)
267 {
268 char *arg = NULL;
269 int arg_len, len;
270
271 zval *new_object;
272
273 zval **d_server,
274 **d_name,
275 **d_instance;
276
277 char c_server[256],
278 c_name[256],
279 c_instance[256];
280
281 char l_server[256],
282 l_name[256],
283 l_instance[256];
284
285 cups_dest_t *dests, *dptr;
286 int num_dests;
287 int i, j;
288
289 array_init(return_value);
290
291 if ((ZEND_NUM_ARGS() != 3) ||
292 (zend_get_parameters_ex(3,&d_server,&d_name,&d_instance) != SUCCESS))
293 {
294 WRONG_PARAM_COUNT;
295 }
296
297 convert_to_string_ex( d_server );
298 convert_to_string_ex( d_name );
299 convert_to_string_ex( d_instance );
300
301 /*
302 * Find the dest/instance we want options for.
303 */
304 bzero( c_server, 256 );
305 bzero( c_name, 256 );
306 bzero( c_instance, 256 );
307
308 if ( (char *)(*d_server)->value.str.val != NULL )
309 strcpy( c_server,(char *)(*d_server)->value.str.val );
310 if ( (char *)(*d_name)->value.str.val != NULL )
311 strcpy( c_name,(char *)(*d_name)->value.str.val );
312 if ( (char *)(*d_instance)->value.str.val != NULL )
313 strcpy( c_instance,(char *)(*d_instance)->value.str.val );
314
315
316 if (strlen(c_server))
317 cupsSetServer(c_server);
318
319 num_dests = cupsGetDests(&dests);
320 for (i=0, j = -1; (i < num_dests) && (j < 0); i++)
321 {
322 dptr = &dests[i];
323
324 if (dptr->name == NULL)
325 strcpy( l_name, "" );
326 else
327 strcpy( l_name, dptr->name );
328
329 if (dptr->instance == NULL)
330 strcpy( l_instance, "" );
331 else
332 strcpy( l_instance, dptr->instance );
333
334 if ((!strcmp( l_name, c_name )) &&
335 (!strcmp( l_instance, c_instance )))
336 {
337
338 for (j=0; j < dptr->num_options; j++ )
339 {
340 if ((dptr->options[j].name != NULL) &&
341 (dptr->options[j].value != NULL))
342 {
343 MAKE_STD_ZVAL(new_object);
344 if (object_init(new_object) == SUCCESS)
345 {
346 add_property_string(new_object,"name",dptr->options[j].name, 1 );
347 add_property_string(new_object,"value",dptr->options[j].value,1);
348 add_next_index_zval( return_value, new_object );
349 }
350 }
351 }
352 }
353 }
354 cupsFreeDests(num_dests,dests);
355 }
356
357
358
359
360 /*
361 * Function: cups_get_dest_list
362 *
363 * Date: 8 April 2002 - TDB
364 *
365 * Parameters: cups server (optional)
366 *
367 * Returns: Array of destination "objects", with each object
368 * containing the members:
369 *
370 * name - String - Name of destination.
371 * instance - String - Name of instance on destination.
372 * is_default - Long - 1 if default printer.
373 * num_options - Long - Number of options for destination.
374 *
375 * Comments:
376 *
377 */
378 PHP_FUNCTION(cups_get_dest_list)
379 {
380 char *arg = NULL;
381 int arg_len, len;
382
383 zval **z_server;
384 zval *new_object;
385
386 char c_server[256];
387
388 char string[2560];
389 char temp[256];
390
391 cups_dest_t *dests, *dptr;
392 int num_dests;
393 int i;
394
395 /*
396 * Initialize the return array.
397 */
398 array_init(return_value);
399
400 switch (ZEND_NUM_ARGS())
401 {
402 /*
403 * Change servers if passed.
404 */
405 case 1: if (zend_get_parameters_ex(1,&z_server) != SUCCESS)
406 {
407 WRONG_PARAM_COUNT;
408 }
409 convert_to_string_ex( z_server );
410 if ( (char *)(*z_server)->value.str.val != NULL )
411 {
412 strcpy( c_server,(char *)(*z_server)->value.str.val );
413 cupsSetServer( c_server );
414 }
415 break;
416 }
417
418
419 /*
420 * First get the destination list from the cups server.
421 */
422 num_dests = cupsGetDests(&dests);
423
424 /*
425 * Loop through the list, create and fill in the objects, and
426 * add them to the array.
427 */
428 string[0] = '\0';
429 for (i=0; i < num_dests; i++)
430 {
431 dptr = &dests[i];
432
433 MAKE_STD_ZVAL(new_object);
434 if (object_init(new_object) == SUCCESS)
435 {
436 if (strlen(c_server))
437 add_property_string( new_object, "server", c_server, 1 );
438 else
439 add_property_string( new_object, "server", "", 1 );
440
441 if (dptr->name != NULL)
442 add_property_string( new_object, "name", dptr->name, 1 );
443 else
444 add_property_string( new_object, "name", "", 1 );
445
446 if (dptr->instance != NULL)
447 add_property_string( new_object, "instance", dptr->instance, 1 );
448 else
449 add_property_string( new_object, "instance", "", 1 );
450
451 add_property_long( new_object, "is_default", dptr->is_default );
452 add_property_long( new_object, "num_options", dptr->num_options );
453 add_next_index_zval( return_value, new_object );
454 }
455 }
456
457 /*
458 * free the list .....
459 */
460 cupsFreeDests(num_dests,dests);
461 }
462
463
464
465 /*
466 * Function: cups_get_jobs
467 *
468 * Date: 8 April 2002 - TDB
469 *
470 * Parameters: server - String - Name or IP of cups server. Blank
471 * for localhost.
472 *
473 * name - String - Name of destination to query.
474 *
475 * user - String - Username to get job list for.
476 * * Optional, default all users
477 *
478 * my_jobs - Long - Show only my jobs
479 * * Optional, default FALSE
480 *
481 * completed - Long - Show completed jobs
482 * * Optional, default FALSE
483 *
484 * Returns: Array of print job "objects", with each object
485 * containing the members:
486 *
487 * id - Long - Job id
488 * dest - String - Name of destination.
489 * title - String - Title of document.
490 * user - String - User who submitted job.
491 * format - String - Document format (MIME type)
492 * state - Long - Current state of the job.
493 * size - Long - Size in bytes of the job.
494 * priority - Long - Job priority.
495 * completed_time - Long - Time job completed (UNIX time).
496 * creation_time - Long - Time job created (UNIX time).
497 * processing_time- Long - Processing time in seconds?
498 *
499 * Comments:
500 *
501 */
502 PHP_FUNCTION( cups_get_jobs )
503 {
504 char *arg = NULL;
505
506 int arg_len,
507 len;
508
509 zval *new_object;
510
511 zval **z_server,
512 **z_name,
513 **z_user,
514 **z_myjobs,
515 **z_completed;
516
517 char p_server[256],
518 p_name[256],
519 p_user[256];
520
521 int p_myjobs,
522 p_completed;
523
524 cups_job_t *jobs,
525 *jptr;
526
527 int num_jobs;
528 int i;
529
530 bzero( p_server, 256 );
531 bzero( p_name, 256 );
532 bzero( p_user, 256 );
533 p_myjobs = 0;
534 p_completed = 0;
535
536 /*
537 * Initialize return value.
538 */
539 array_init(return_value);
540
541 /*
542 * Parse params.
543 */
544 switch(ZEND_NUM_ARGS())
545 {
546 /*
547 * server, destination only provided.
548 */
549 case 2:
550 if (zend_get_parameters_ex( 2, &z_server,&z_name ) == SUCCESS)
551 {
552 convert_to_string_ex( z_server);
553 if ( (char *)(*z_server)->value.str.val != NULL )
554 strcpy( p_server,(char *)(*z_server)->value.str.val );
555 convert_to_string_ex( z_name );
556 if ( (char *)(*z_name)->value.str.val != NULL )
557 strcpy( p_name,(char *)(*z_name)->value.str.val );
558 }
559 break;
560
561 /*
562 * server, destination and user
563 */
564 case 3:
565 if (zend_get_parameters_ex( 3, &z_server, &z_name,
566 &z_user ) == SUCCESS)
567 {
568 convert_to_string_ex( z_name );
569 convert_to_string_ex( z_user );
570 convert_to_string_ex( z_server);
571 if ( (char *)(*z_server)->value.str.val != NULL )
572 strcpy( p_server,(char *)(*z_server)->value.str.val );
573 if ( (char *)(*z_name)->value.str.val != NULL )
574 strcpy( p_name,(char *)(*z_name)->value.str.val );
575 if ( (char *)(*z_user)->value.str.val != NULL )
576 strcpy( p_user,(char *)(*z_user)->value.str.val );
577 }
578 break;
579
580 /*
581 * server, destination, user, and myjobs
582 */
583 case 4:
584 if (zend_get_parameters_ex( 4, &z_server, &z_name, &z_user,
585 &z_myjobs ) == SUCCESS)
586 {
587 convert_to_string_ex( z_name );
588 convert_to_string_ex( z_user );
589 convert_to_string_ex( z_server);
590 if ( (char *)(*z_server)->value.str.val != NULL )
591 strcpy( p_server,(char *)(*z_server)->value.str.val );
592 if ( (char *)(*z_name)->value.str.val != NULL )
593 strcpy( p_name,(char *)(*z_name)->value.str.val );
594 if ( (char *)(*z_user)->value.str.val != NULL )
595 strcpy( p_user,(char *)(*z_user)->value.str.val );
596
597 convert_to_string_ex( z_myjobs );
598 p_myjobs = strtoul((char *)(*z_myjobs)->value.str.val,NULL,10);
599 }
600 break;
601
602 /*
603 * server, destination, user, myjobs, and completed
604 */
605 case 5:
606 if (zend_get_parameters_ex( 5, &z_server, &z_name, &z_user,
607 &z_myjobs, &z_completed ) == SUCCESS)
608 {
609 convert_to_string_ex( z_name );
610 convert_to_string_ex( z_user );
611 convert_to_string_ex( z_server);
612 if ( (char *)(*z_server)->value.str.val != NULL )
613 strcpy( p_server,(char *)(*z_server)->value.str.val );
614 if ( (char *)(*z_name)->value.str.val != NULL )
615 strcpy( p_name,(char *)(*z_name)->value.str.val );
616 if ( (char *)(*z_user)->value.str.val != NULL )
617 strcpy( p_user,(char *)(*z_user)->value.str.val );
618
619 convert_to_string_ex( z_myjobs );
620 p_myjobs = strtoul((char *)(*z_myjobs)->value.str.val,NULL,10);
621
622 convert_to_string_ex( z_completed);
623 p_completed = strtoul((char *)(*z_completed)->value.str.val,NULL,10);
624 }
625 break;
626 }
627
628 /*
629 * Set the cups server if given.
630 */
631 if (strlen(p_server))
632 cupsSetServer(p_server);
633
634 /*
635 * Set the cups user if given, otherwise get all jobs.
636 */
637 if (strlen(p_user))
638 cupsSetUser(p_user);
639 else
640 cupsSetUser("root");
641
642 /*
643 * Get the jobs list from the CUPS server.
644 */
645 num_jobs = cupsGetJobs(&jobs,p_name,p_myjobs,p_completed);
646
647 /*
648 * Build the array of objects to return.
649 */
650 for (i=0; i < num_jobs; i++)
651 {
652 jptr = &jobs[i];
653
654 MAKE_STD_ZVAL(new_object);
655 if (object_init(new_object) == SUCCESS)
656 {
657 add_property_long(new_object,"id",jptr->id );
658 add_property_string(new_object,"dest",jptr->dest, 1 );
659 add_property_string(new_object,"title",jptr->title, 1 );
660 add_property_string(new_object,"user",jptr->user, 1 );
661 add_property_string(new_object,"format",jptr->format, 1 );
662 add_property_long(new_object,"state",jptr->state );
663 add_property_long(new_object,"size",jptr->size );
664 add_property_long(new_object,"priority",jptr->priority );
665 add_property_long(new_object,"completed_time",jptr->completed_time);
666 add_property_long(new_object,"creation_time",jptr->creation_time);
667 add_property_long(new_object,"processing_time",jptr->processing_time);
668 add_next_index_zval( return_value, new_object );
669 }
670 else
671 {
672 printf("\nError creating new object\n");
673 }
674 }
675 cupsFreeJobs(num_jobs,jobs);
676 }
677
678
679
680
681 /*
682 * Function: cups_last_error
683 *
684 * Date: 8 April 2002 - TDB
685 *
686 * Parameters: none.
687 *
688 * Returns: error number - Long
689 *
690 * Comments:
691 *
692 */
693 PHP_FUNCTION(cups_last_error)
694 {
695 static char error[1024];
696
697 zval **z_server;
698 char c_server[256];
699
700 bzero( c_server, 256 );
701
702 switch (ZEND_NUM_ARGS())
703 {
704 /*
705 * Change servers if passed.
706 */
707 case 1: if (zend_get_parameters_ex(1,&z_server) != SUCCESS)
708 {
709 WRONG_PARAM_COUNT;
710 }
711 convert_to_string_ex( z_server );
712 if ( (char *)(*z_server)->value.str.val != NULL )
713 {
714 strcpy( c_server,(char *)(*z_server)->value.str.val );
715 cupsSetServer( c_server );
716 }
717 break;
718 }
719 sprintf( error,"%d", cupsLastError());
720
721 RETURN_STRINGL(error, strlen(error)+1, 1);
722 }
723
724
725
726
727
728
729 /*
730 * Function: cups_cancel_job
731 *
732 * Date: 8 April 2002 - TDB
733 *
734 * Parameters: server - String - Name or IP of cups server.
735 * name - String - Name of destination.
736 * job - Long - Job ID to cancel.
737 *
738 * Returns: error number - Long?????????
739 *
740 * Comments:
741 *
742 */
743 PHP_FUNCTION(cups_cancel_job)
744 {
745 zval **z_server, **z_name, **z_job;
746
747 char p_server[256], p_name[256];
748 int p_job;
749
750 int ret_val = -1;
751
752 /*
753 * Get parameters .....
754 */
755 if ((ZEND_NUM_ARGS() != 3) ||
756 (zend_get_parameters_ex( 3, &z_server, &z_name, &z_job ) != SUCCESS))
757 {
758 WRONG_PARAM_COUNT;
759 }
760
761 convert_to_string_ex( z_server);
762 if ( (char *)(*z_name)->value.str.val != NULL )
763 {
764 strcpy( p_server,(char *)(*z_server)->value.str.val );
765 cupsSetServer(p_server);
766 }
767
768 convert_to_string_ex( z_name );
769 if ( (char *)(*z_name)->value.str.val != NULL )
770 strcpy( p_name,(char *)(*z_name)->value.str.val );
771
772 convert_to_string_ex( z_job );
773 p_job = strtoul((char *)(*z_job)->value.str.val,NULL,10);
774
775 if (strlen(p_server))
776 cupsSetServer(p_server);
777 cupsSetUser("root");
778
779 /*
780 * Errrr .... Cancel the job ......
781 */
782 ret_val = cupsCancelJob(p_name,p_job);
783
784 RETURN_LONG(ret_val);
785 }
786
787
788
789 cups_option_t *_phpcups_parse_options( cups_option_t *options,
790 int *num_options, char *param )
791 {
792 char name[1024], value[1024];
793
794 sscanf(param,"%1023[^=]=%1023s", name, value );
795
796 if (strlen(name) && strlen(value))
797 {
798 if (options == NULL)
799 {
800 options = (cups_option_t *)emalloc(sizeof(cups_option_t));
801 options->name = (char *)emalloc(strlen(name)+1);
802 options->value = (char *)emalloc(strlen(value)+1);
803 strcpy( options->name, name );
804 strcpy( options->value, value );
805 *num_options++;
806 }
807 else
808 {
809 options = (cups_option_t *)erealloc(options,
810 (*num_options+1) * sizeof(cups_option_t));
811 options[*num_options].name = (char *)emalloc(strlen(name)+1);
812 options[*num_options].value = (char *)emalloc(strlen(value)+1);
813 strcpy( options[*num_options].name, name );
814 strcpy( options[*num_options].value, value );
815 *num_options++;
816 }
817 }
818 return(options);
819 }
820
821
822 /*
823 * Function: cups_print_file
824 *
825 * Date: 8 April 2002 - TDB
826 *
827 * Parameters: printer - String - Name of destination.
828 * filename - String - Name of file to print (full path).
829 * title - String - Title of document.
830 *
831 * Returns: Job ID - Long
832 *
833 * Comments:
834 *
835 */
836 PHP_FUNCTION(cups_print_file)
837 {
838 zval **z_server, **z_printer, **z_filename, **z_title,
839 **z_options, **keydata;
840
841 HashTable *param_ht;
842
843 char p_server[256];
844 char p_printer[256];
845 char p_filename[256];
846 char p_title[256];
847
848 char temp[4096];
849 cups_option_t *options = NULL;
850
851 int count, current;
852 int ret_val = -1;
853
854 bzero( p_server, 256 );
855 bzero( p_printer, 256 );
856 bzero( p_filename, 256 );
857 bzero( p_title, 256 );
858 bzero( temp, 4096);
859 current = 0;
860
861 int zend_num_args = ZEND_NUM_ARGS();
862 switch (zend_num_args)
863 {
864 /*
865 * Server / Destination / filename only.
866 */
867 case 3:
868 if (zend_get_parameters_ex( 3, &z_server, &z_printer,
869 &z_filename) != SUCCESS)
870 {
871 WRONG_PARAM_COUNT;
872 }
873 convert_to_string_ex( z_server);
874 if ( (char *)(*z_server)->value.str.val != NULL )
875 {
876 strcpy( p_server,(char *)(*z_server)->value.str.val );
877 cupsSetServer(p_server);
878 }
879 convert_to_string_ex( z_printer);
880 if ( (char *)(*z_printer)->value.str.val != NULL )
881 strcpy( p_printer,(char *)(*z_printer)->value.str.val );
882 convert_to_string_ex( z_filename );
883 if ( (char *)(*z_filename)->value.str.val != NULL )
884 strcpy( p_filename,(char *)(*z_filename)->value.str.val );
885 strcpy( p_title,"untitled");
886 break;
887
888 /*
889 * Server, destination, filename and title.
890 */
891 case 4:
892 if (zend_get_parameters_ex( 4, &z_server,
893 &z_printer,
894 &z_filename,
895 &z_title) != SUCCESS)
896 {
897 WRONG_PARAM_COUNT;
898 }
899
900 convert_to_string_ex( z_server);
901 if ( (char *)(*z_server)->value.str.val != NULL )
902 {
903 strcpy( p_server,(char *)(*z_server)->value.str.val );
904 cupsSetServer(p_server);
905 }
906
907 convert_to_string_ex( z_printer);
908 if ( (char *)(*z_printer)->value.str.val != NULL )
909 strcpy( p_printer,(char *)(*z_printer)->value.str.val );
910
911 convert_to_string_ex( z_filename );
912 if ( (char *)(*z_filename)->value.str.val != NULL )
913 strcpy( p_filename,(char *)(*z_filename)->value.str.val );
914
915 convert_to_string_ex( z_title );
916 if ( (char *)(*z_title)->value.str.val != NULL )
917 strcpy( p_title,(char *)(*z_title)->value.str.val );
918
919 _zz_internal_log( "cups_print_file", p_server );
920 _zz_internal_log( "cups_print_file", p_printer );
921 _zz_internal_log( "cups_print_file", p_filename );
922 _zz_internal_log( "cups_print_file", p_title );
923 break;
924
925 /*
926 * Server, destination, filename and title plus printer options.
927 */
928 case 5:
929 if (zend_get_parameters_ex( 5, &z_server,
930 &z_printer,
931 &z_filename,
932 &z_title,
933 &z_options) != SUCCESS)
934 {
935 WRONG_PARAM_COUNT;
936 }
937 convert_to_string_ex( z_server);
938 if ( (char *)(*z_server)->value.str.val != NULL )
939 {
940 strcpy( p_server,(char *)(*z_server)->value.str.val );
941 cupsSetServer(p_server);
942 }
943 convert_to_string_ex( z_printer);
944 if ( (char *)(*z_printer)->value.str.val != NULL )
945 strcpy( p_printer,(char *)(*z_printer)->value.str.val );
946 convert_to_string_ex( z_filename );
947 if ( (char *)(*z_filename)->value.str.val != NULL )
948 strcpy( p_filename,(char *)(*z_filename)->value.str.val );
949 convert_to_string_ex( z_title );
950 if ( (char *)(*z_title)->value.str.val != NULL )
951 strcpy( p_title,(char *)(*z_title)->value.str.val );
952
953 _zz_internal_log( "cups_print_file(server)", p_server );
954 _zz_internal_log( "cups_print_file(printer)", p_printer );
955 _zz_internal_log( "cups_print_file(filename)", p_filename );
956 _zz_internal_log( "cups_print_file(title)", p_title );
957
958 /*
959 * Convert options array.
960 */
961 convert_to_array_ex( z_options );
962 param_ht = Z_ARRVAL_PP( z_options );
963 count = zend_hash_num_elements( param_ht );
964 options = emalloc(sizeof(zval **) * count);
965
966 current = 0;
967 zend_hash_internal_pointer_reset(param_ht);
968 for (current=0; current < count; current++)
969 {
970 zend_hash_get_current_data(param_ht,(void **)&keydata);
971 switch(Z_TYPE_PP(keydata))
972 {
973 case IS_STRING:
974 convert_to_string_ex(keydata);
975 strcpy(temp,(char *)(*keydata)->value.str.val );
976 _zz_internal_log( "cups_print_file(option)", temp );
977 options = _phpcups_parse_options( options, &current,
978 temp );
979 break;
980 }
981 zend_hash_move_forward(param_ht);
982 }
983 break;
984
985 default: WRONG_PARAM_COUNT;
986 }
987
988 if (current > 0)
989 {
990
991 bzero(temp,4096);
992 sprintf(temp,"(2) - P: %s F: %s T: %s C: %d", p_printer, p_filename,
993 p_title, current );
994 _zz_internal_log( "cups_print_file", temp );
995 ret_val = cupsPrintFile( p_printer,p_filename,p_title,current,options);
996 for (current=0; current < count; current++)
997 {
998 efree( options[current].name );
999 efree( options[current].value );
1000 }
1001 efree(options);
1002 }
1003 else
1004 {
1005 _zz_internal_log( "cups_print_file", "going to print");
1006 ret_val = cupsPrintFile( p_printer,p_filename,p_title,0,NULL );
1007 }
1008
1009 RETURN_LONG(ret_val);
1010 }
1011
1012
1013 int _phpcups_get_printer_status(char *server, int port, char *name );
1014
1015 typedef struct printer_attrs_type
1016 {
1017 char *name;
1018 char *value;
1019 } printer_attrs_t;
1020
1021
1022
1023 int num_attrs = 0;
1024 printer_attrs_t *printer_attrs = NULL;
1025
1026 void free_attrs_list(void);
1027 void _phpcups_free_attrs_list(void);
1028
1029 /*
1030 * Function: cups_get_printer_attributes
1031 *
1032 * Date: 8 April 2002 - TDB
1033 *
1034 * Parameters: name - String - Name of destination.
1035 *
1036 * Returns: state - String
1037 *
1038 * Comments:
1039 *
1040 */
1041 PHP_FUNCTION(cups_get_printer_attributes)
1042 {
1043 zval **z_server, **z_port, **z_name;
1044
1045 zval *new_object;
1046
1047 char p_server[256], p_name[256];
1048 int p_port = 631;
1049
1050 int i, count;
1051
1052
1053 /*
1054 * Initialize return value.
1055 */
1056 array_init(return_value);
1057
1058 /*
1059 * Get parameters .....
1060 */
1061 switch(ZEND_NUM_ARGS())
1062 {
1063 //
1064 // Destination name only, assume localhost
1065 //
1066 case 1:
1067 if (zend_get_parameters_ex( 1, &z_name ) != SUCCESS)
1068 {
1069 WRONG_PARAM_COUNT;
1070 }
1071 strcpy( p_server,"localhost" );
1072 convert_to_string_ex( z_name );
1073 if ( (char *)(*z_name)->value.str.val != NULL )
1074 strcpy( p_name,(char *)(*z_name)->value.str.val );
1075 break;
1076
1077 //
1078 // Server and estination name only, assume port 631
1079 //
1080 case 2:
1081 if (zend_get_parameters_ex( 2, &z_server, &z_name ) != SUCCESS)
1082 {
1083 WRONG_PARAM_COUNT;
1084 }
1085 convert_to_string_ex( z_server);
1086 if ((char *)(*z_server)->value.str.val != NULL)
1087 strcpy( p_server,(char *)(*z_server)->value.str.val );
1088 convert_to_string_ex( z_name );
1089 if ( (char *)(*z_name)->value.str.val != NULL )
1090 strcpy( p_name,(char *)(*z_name)->value.str.val );
1091 break;
1092
1093 //
1094 // Server, destination name and port.
1095 //
1096 case 3:
1097 if(zend_get_parameters_ex(3,&z_server,&z_port,&z_name) != SUCCESS)
1098 {
1099 WRONG_PARAM_COUNT;
1100 }
1101 convert_to_string_ex(z_server);
1102 if ((char *)(*z_server)->value.str.val != NULL)
1103 strcpy( p_server,(char *)(*z_server)->value.str.val );
1104 convert_to_string_ex(z_name);
1105 if ( (char *)(*z_name)->value.str.val != NULL )
1106 strcpy( p_name,(char *)(*z_name)->value.str.val );
1107 convert_to_string_ex(z_port);
1108 if ( (char *)(*z_port)->value.str.val != NULL )
1109 p_port = atoi( (char *)(*z_name)->value.str.val );
1110 break;
1111
1112 default: WRONG_PARAM_COUNT;
1113 }
1114
1115 printer_attrs = NULL;
1116 count = _phpcups_get_printer_status( p_server, p_port, p_name );
1117
1118 /*
1119 * Create an array of objects containing name / value pairs.
1120 */
1121 for (i=0; i < count; i++)
1122 {
1123 if ((printer_attrs[i].name != NULL) && (printer_attrs[i].value != NULL))
1124 {
1125 MAKE_STD_ZVAL(new_object);
1126 if (object_init(new_object) == SUCCESS)
1127 {
1128 add_property_string(new_object,"name",printer_attrs[i].name, 1 );
1129 add_property_string(new_object,"value",printer_attrs[i].value, 1 );
1130 add_next_index_zval( return_value, new_object );
1131 }
1132 }
1133 }
1134 _phpcups_free_attrs_list();
1135 }
1136
1137
1138
1139
1140 void _phpcups_free_attrs_list(void)
1141 {
1142 int i;
1143
1144 if (num_attrs < 1)
1145 return;
1146
1147 for ( i=0; i < num_attrs; i++ )
1148 {
1149 if (printer_attrs[i].name != NULL)
1150 efree(printer_attrs[i].name);
1151 if (printer_attrs[i].value != NULL)
1152 efree(printer_attrs[i].value );
1153 }
1154 efree(printer_attrs);
1155 num_attrs = 0;
1156 }
1157
1158
1159
1160
1161
1162
1163
1164 int _phpcups_update_attrs_list( char *name, char *value )
1165 {
1166 if (num_attrs < 1)
1167 {
1168 printer_attrs = (printer_attrs_t *)emalloc(sizeof(printer_attrs_t));
1169 printer_attrs->name = (char *)emalloc(strlen(name)+1);
1170 printer_attrs->value = (char *)emalloc(strlen(value)+1);
1171 strcpy( printer_attrs->name, name );
1172 strcpy( printer_attrs->value, value );
1173 num_attrs = 1;
1174 }
1175 else
1176 {
1177 printer_attrs = (printer_attrs_t *)erealloc(printer_attrs,
1178 (num_attrs + 1) * sizeof(printer_attrs_t));
1179
1180 printer_attrs[num_attrs].name = (char *)emalloc(strlen(name)+1);
1181 printer_attrs[num_attrs].value = (char *)emalloc(strlen(value)+1);
1182 strcpy( printer_attrs[num_attrs].name, name );
1183 strcpy( printer_attrs[num_attrs].value, value );
1184 num_attrs++;
1185 }
1186 return(num_attrs);
1187 }
1188
1189
1190
1191 int _phpcups_get_printer_status( char *server, int port, char *name )
1192 {
1193 http_encryption_t encrypt = HTTP_ENCRYPT_IF_REQUESTED;
1194
1195 ipp_t *request, /* IPP Request */
1196 *response; /* IPP Response */
1197 ipp_attribute_t *attr; /* Current attribute */
1198 cups_lang_t *language; /* Default language */
1199
1200 char printer_uri[1024];
1201 char temp[1024];
1202 static char *req_attrs[] = {"printer-state", "printer-state-reason" };
1203 int i;
1204 FILE *fp;
1205
1206 if (name == NULL)
1207 {
1208 last_error = IPP_INTERNAL_ERROR;
1209 return (0);
1210 }
1211
1212 /*
1213 * Try to connect to the server...
1214 */
1215
1216 if ((cups_server = httpConnectEncrypt(server, port, encrypt)) == NULL)
1217 {
1218 last_error = IPP_SERVICE_UNAVAILABLE;
1219 return (0);
1220 }
1221
1222 /*
1223 * Build a CUPS_GET_PRINTERS request, which requires the following
1224 * attributes:
1225 *
1226 * attributes-charset
1227 * attributes-natural-language
1228 * requested-attributes
1229 */
1230
1231 request = ippNew();
1232
1233 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
1234 request->request.op.request_id = 1;
1235
1236 language = cupsLangDefault();
1237
1238 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1239 "attributes-charset", NULL, cupsLangEncoding(language));
1240
1241 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1242 "attributes-natural-language", NULL, language->language);
1243
1244 sprintf(printer_uri, "ipp://localhost/printers/%-s", name );
1245 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
1246 "printer-uri", NULL, printer_uri );
1247
1248 /*
1249 * Do the request and get back a response...
1250 */
1251
1252 num_attrs = 0;
1253 printer_attrs = NULL;
1254
1255 if ((response = cupsDoRequest(cups_server, request, "/")) != NULL)
1256 {
1257 last_error = response->request.status.status_code;
1258
1259 for (attr = response->attrs; attr != NULL; attr = attr->next)
1260 {
1261
1262 if (attr->num_values < 1)
1263 continue;
1264
1265 if (attr->name != NULL &&
1266 strcasecmp(attr->name, "printer-state") == 0 &&
1267 attr->value_tag == IPP_TAG_ENUM)
1268 {
1269 strcpy( temp, "unknown" );
1270 switch( attr->values[0].integer )
1271 {
1272 case 3: strcpy( temp, "idle" );
1273 break;
1274 case 4: strcpy( temp, "processing" );
1275 break;
1276 case 5: strcpy( temp, "stopped" );
1277 break;
1278 default: continue;
1279 }
1280 _phpcups_update_attrs_list( attr->name, temp );
1281 }
1282 else if (attr->name != NULL &&
1283 (attr->value_tag == IPP_TAG_TEXT ||
1284 attr->value_tag == IPP_TAG_URI ||
1285 attr->value_tag == IPP_TAG_KEYWORD ||
1286 attr->value_tag == IPP_TAG_STRING))
1287 {
1288 for (i=0; i < attr->num_values; i++)
1289 _phpcups_update_attrs_list(attr->name, attr->values[i].string.text );
1290 }
1291 else if (attr->name != NULL &&
1292 (attr->value_tag == IPP_TAG_ENUM ||
1293 attr->value_tag == IPP_TAG_BOOLEAN ||
1294 attr->value_tag == IPP_TAG_INTEGER))
1295 {
1296 for (i=0; i < attr->num_values; i++)
1297 {
1298 sprintf(temp,"%-d", attr->values[i].integer );
1299 _phpcups_update_attrs_list(attr->name, temp );
1300 }
1301 }
1302 else if (attr->name != NULL &&
1303 attr->value_tag == IPP_TAG_RESOLUTION)
1304 {
1305 for (i=0; i < attr->num_values; i++)
1306 {
1307 sprintf(temp,"%-dx%-dx%-d",
1308 attr->values[i].resolution.xres,
1309 attr->values[i].resolution.yres,
1310 attr->values[i].resolution.units );
1311 _phpcups_update_attrs_list(attr->name, temp );
1312 }
1313 }
1314 else if (attr->name != NULL &&
1315 attr->value_tag == IPP_TAG_RANGE)
1316 {
1317 for (i=0; i < attr->num_values; i++)
1318 {
1319 sprintf(temp,"%d-%d",
1320 attr->values[i].range.lower,
1321 attr->values[i].range.upper );
1322 _phpcups_update_attrs_list(attr->name, temp );
1323 }
1324 }
1325 }
1326 ippDelete(response);
1327 }
1328 else
1329 {
1330 last_error = IPP_BAD_REQUEST;
1331 return(0);
1332 }
1333 return (num_attrs);
1334 }
1335
1336
1337 void _zz_internal_log( char *func, char *line )
1338 {
1339 FILE *fp;
1340
1341 if ((fp = fopen("/var/log/cups/project.log","a")) == NULL)
1342 return;
1343
1344 fprintf(fp,"phpcups: %s - %s\n", func, line );
1345 fflush(fp);
1346 fclose(fp);
1347 }
1348
1349
1350
1351 /*
1352 * End of "$Id: phpcups.c 4530 2005-06-01 20:15:51Z mike $".
1353 */
1354
1355
1356 /*
1357 */