]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/admin.c
f4f9c36e8d4b4106a86e2dead4a90aa0d092fe80
[thirdparty/cups.git] / cgi-bin / admin.c
1 /*
2 * "$Id: admin.c,v 1.22 2001/03/05 21:37:33 mike Exp $"
3 *
4 * Administration CGI for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2001 by Easy Software Products.
7 *
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
13 * at:
14 *
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
19 *
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
23 *
24 * Contents:
25 *
26 * main() - Main entry for CGI.
27 * do_am_class() - Add or modify a class.
28 * do_am_printer() - Add or modify a printer.
29 * do_config_printer() - Configure the default options for a printer.
30 * do_delete_class() - Delete a class...
31 * do_delete_printer() - Delete a printer...
32 * do_job_op() - Do a job operation.
33 * do_printer_op() - Do a printer operation.
34 * get_line() - Get a line that is terminated by a LF, CR, or CR LF.
35 */
36
37 /*
38 * Include necessary headers...
39 */
40
41 #include "ipp-var.h"
42 #include <ctype.h>
43 #include <errno.h>
44
45
46 /*
47 * Local functions...
48 */
49
50 static void do_am_class(http_t *http, cups_lang_t *language, int modify);
51 static void do_am_printer(http_t *http, cups_lang_t *language, int modify);
52 static void do_config_printer(http_t *http, cups_lang_t *language);
53 static void do_delete_class(http_t *http, cups_lang_t *language);
54 static void do_delete_printer(http_t *http, cups_lang_t *language);
55 static void do_job_op(http_t *http, cups_lang_t *language, ipp_op_t op);
56 static void do_printer_op(http_t *http, cups_lang_t *language, ipp_op_t op);
57 static char *get_line(char *buf, int length, FILE *fp);
58
59
60 /*
61 * 'main()' - Main entry for CGI.
62 */
63
64 int /* O - Exit status */
65 main(int argc, /* I - Number of command-line arguments */
66 char *argv[]) /* I - Command-line arguments */
67 {
68 cups_lang_t *language; /* Language information */
69 http_t *http; /* Connection to the server */
70 const char *op; /* Operation name */
71
72
73 /*
74 * Get the request language...
75 */
76
77 language = cupsLangDefault();
78
79 /*
80 * Send a standard header...
81 */
82
83 printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
84
85 cgiSetVariable("TITLE", "Admin");
86 ippSetServerVersion();
87
88 cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG"));
89
90 /*
91 * See if we have form data...
92 */
93
94 if (!cgiInitialize())
95 {
96 /*
97 * Nope, send the administration menu...
98 */
99
100 cgiCopyTemplateLang(stdout, TEMPLATES, "admin.tmpl", getenv("LANG"));
101 }
102 else if ((op = cgiGetVariable("OP")) != NULL)
103 {
104 /*
105 * Connect to the HTTP server...
106 */
107
108 http = httpConnect("localhost", ippPort());
109
110 /*
111 * Do the operation...
112 */
113
114 if (strcmp(op, "cancel-job") == 0)
115 do_job_op(http, language, IPP_CANCEL_JOB);
116 else if (strcmp(op, "hold-job") == 0)
117 do_job_op(http, language, IPP_HOLD_JOB);
118 else if (strcmp(op, "release-job") == 0)
119 do_job_op(http, language, IPP_RELEASE_JOB);
120 else if (strcmp(op, "restart-job") == 0)
121 do_job_op(http, language, IPP_RESTART_JOB);
122 else if (strcmp(op, "start-printer") == 0)
123 do_printer_op(http, language, IPP_RESUME_PRINTER);
124 else if (strcmp(op, "stop-printer") == 0)
125 do_printer_op(http, language, IPP_PAUSE_PRINTER);
126 else if (strcmp(op, "accept-jobs") == 0)
127 do_printer_op(http, language, CUPS_ACCEPT_JOBS);
128 else if (strcmp(op, "reject-jobs") == 0)
129 do_printer_op(http, language, CUPS_REJECT_JOBS);
130 else if (strcmp(op, "add-class") == 0)
131 do_am_class(http, language, 0);
132 else if (strcmp(op, "add-printer") == 0)
133 do_am_printer(http, language, 0);
134 else if (strcmp(op, "modify-class") == 0)
135 do_am_class(http, language, 1);
136 else if (strcmp(op, "modify-printer") == 0)
137 do_am_printer(http, language, 1);
138 else if (strcmp(op, "delete-class") == 0)
139 do_delete_class(http, language);
140 else if (strcmp(op, "delete-printer") == 0)
141 do_delete_printer(http, language);
142 else if (strcmp(op, "config-printer") == 0)
143 do_config_printer(http, language);
144 else
145 {
146 /*
147 * Bad operation code... Display an error...
148 */
149
150 cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG"));
151 }
152
153 /*
154 * Close the HTTP server connection...
155 */
156
157 httpClose(http);
158 }
159 else
160 {
161 /*
162 * Form data but no operation code... Display an error...
163 */
164
165 cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG"));
166 }
167
168 /*
169 * Send the standard trailer...
170 */
171
172 cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG"));
173
174 /*
175 * Free the request language...
176 */
177
178 cupsLangFree(language);
179
180 /*
181 * Return with no errors...
182 */
183
184 return (0);
185 }
186
187
188 /*
189 * 'do_am_class()' - Add or modify a class.
190 */
191
192 static void
193 do_am_class(http_t *http, /* I - HTTP connection */
194 cups_lang_t *language, /* I - Client's language */
195 int modify) /* I - Modify the printer? */
196 {
197 int i, j; /* Looping vars */
198 int element; /* Element number */
199 int num_printers; /* Number of printers */
200 ipp_t *request, /* IPP request */
201 *response; /* IPP response */
202 ipp_attribute_t *attr; /* member-uris attribute */
203 ipp_status_t status; /* Request status */
204 char uri[HTTP_MAX_URI]; /* Device or printer URI */
205 const char *name, /* Pointer to class name */
206 *ptr; /* Pointer to CGI variable */
207
208
209 if (cgiGetVariable("PRINTER_LOCATION") == NULL)
210 {
211 if (modify)
212 {
213 /*
214 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
215 * following attributes:
216 *
217 * attributes-charset
218 * attributes-natural-language
219 * printer-uri
220 */
221
222 request = ippNew();
223
224 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
225 request->request.op.request_id = 1;
226
227 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
228 "attributes-charset", NULL, cupsLangEncoding(language));
229
230 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
231 "attributes-natural-language", NULL, language->language);
232
233 snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
234 cgiGetVariable("PRINTER_NAME"));
235 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
236 NULL, uri);
237
238 /*
239 * Do the request and get back a response...
240 */
241
242 if ((response = cupsDoRequest(http, request, "/")) != NULL)
243 {
244 ippSetCGIVars(response, NULL, NULL);
245 ippDelete(response);
246 }
247
248 /*
249 * Update the location and description of an existing printer...
250 */
251
252 cgiCopyTemplateLang(stdout, TEMPLATES, "modify-class.tmpl", getenv("LANG"));
253 }
254 else
255 {
256 /*
257 * Get the name, location, and description for a new printer...
258 */
259
260 cgiCopyTemplateLang(stdout, TEMPLATES, "add-class.tmpl", getenv("LANG"));
261 }
262
263 return;
264 }
265
266 name = cgiGetVariable("PRINTER_NAME");
267 if (isdigit(*name))
268 ptr = name;
269 else
270 for (ptr = name; *ptr; ptr ++)
271 if (!isalnum(*ptr) && *ptr != '_')
272 break;
273
274 if (*ptr || ptr == name)
275 {
276 cgiSetVariable("ERROR", "The class name may only contain letters, "
277 "numbers, and the underscore.");
278 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
279 return;
280 }
281
282 if (cgiGetVariable("MEMBER_URIS") == NULL)
283 {
284 /*
285 * Build a CUPS_GET_PRINTERS request, which requires the
286 * following attributes:
287 *
288 * attributes-charset
289 * attributes-natural-language
290 * printer-uri
291 */
292
293 request = ippNew();
294
295 request->request.op.operation_id = CUPS_GET_PRINTERS;
296 request->request.op.request_id = 1;
297
298 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
299 "attributes-charset", NULL, cupsLangEncoding(language));
300
301 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
302 "attributes-natural-language", NULL, language->language);
303
304 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
305 NULL, "ipp://localhost/printers");
306
307 /*
308 * Do the request and get back a response...
309 */
310
311 if ((response = cupsDoRequest(http, request, "/")) != NULL)
312 {
313 /*
314 * Create MEMBER_URIS and MEMBER_NAMES arrays...
315 */
316
317 for (element = 0, attr = response->attrs;
318 attr != NULL;
319 attr = attr->next)
320 if (attr->name && strcmp(attr->name, "printer-uri-supported") == 0)
321 {
322 cgiSetArray("MEMBER_URIS", element, attr->values[0].string.text);
323 element ++;
324 }
325
326 for (element = 0, attr = response->attrs;
327 attr != NULL;
328 attr = attr->next)
329 if (attr->name && strcmp(attr->name, "printer-name") == 0)
330 {
331 cgiSetArray("MEMBER_NAMES", element, attr->values[0].string.text);
332 element ++;
333 }
334
335 num_printers = cgiGetSize("MEMBER_URIS");
336
337 ippDelete(response);
338 }
339 else
340 num_printers = 0;
341
342 /*
343 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
344 * following attributes:
345 *
346 * attributes-charset
347 * attributes-natural-language
348 * printer-uri
349 */
350
351 request = ippNew();
352
353 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
354 request->request.op.request_id = 1;
355
356 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
357 "attributes-charset", NULL, cupsLangEncoding(language));
358
359 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
360 "attributes-natural-language", NULL, language->language);
361
362 snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
363 cgiGetVariable("PRINTER_NAME"));
364 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
365 NULL, uri);
366
367 /*
368 * Do the request and get back a response...
369 */
370
371 if ((response = cupsDoRequest(http, request, "/")) != NULL)
372 {
373 if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
374 {
375 /*
376 * Mark any current members in the class...
377 */
378
379 for (j = 0; j < num_printers; j ++)
380 cgiSetArray("MEMBER_SELECTED", j, "");
381
382 for (i = 0; i < attr->num_values; i ++)
383 for (j = 0; j < num_printers; j ++)
384 if (strcmp(attr->values[i].string.text, cgiGetArray("MEMBER_URIS", j)) == 0)
385 {
386 cgiSetArray("MEMBER_SELECTED", j, "SELECTED");
387 break;
388 }
389 }
390
391 ippDelete(response);
392 }
393
394 /*
395 * Let the user choose...
396 */
397
398 cgiCopyTemplateLang(stdout, TEMPLATES, "choose-members.tmpl", getenv("LANG"));
399 }
400 else
401 {
402 /*
403 * Build a CUPS_ADD_CLASS request, which requires the following
404 * attributes:
405 *
406 * attributes-charset
407 * attributes-natural-language
408 * printer-uri
409 * printer-location
410 * printer-info
411 * printer-is-accepting-jobs
412 * printer-state
413 * member-uris
414 */
415
416 request = ippNew();
417
418 request->request.op.operation_id = CUPS_ADD_CLASS;
419 request->request.op.request_id = 1;
420
421 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
422 "attributes-charset", NULL, cupsLangEncoding(language));
423
424 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
425 "attributes-natural-language", NULL, language->language);
426
427 snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
428 cgiGetVariable("PRINTER_NAME"));
429 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
430 NULL, uri);
431
432 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
433 NULL, cgiGetVariable("PRINTER_LOCATION"));
434
435 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
436 NULL, cgiGetVariable("PRINTER_INFO"));
437
438 ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
439
440 ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
441 IPP_PRINTER_IDLE);
442
443 if ((num_printers = cgiGetSize("MEMBER_URIS")) > 0)
444 {
445 attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris",
446 num_printers, NULL, NULL);
447 for (i = 0; i < num_printers; i ++)
448 attr->values[i].string.text = strdup(cgiGetArray("MEMBER_URIS", i));
449 }
450
451 /*
452 * Do the request and get back a response...
453 */
454
455 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
456 {
457 status = response->request.status.status_code;
458 ippDelete(response);
459 }
460 else
461 status = IPP_NOT_AUTHORIZED;
462
463 if (status > IPP_OK_CONFLICT)
464 {
465 cgiSetVariable("ERROR", ippErrorString(status));
466 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
467 }
468 else if (modify)
469 cgiCopyTemplateLang(stdout, TEMPLATES, "class-modified.tmpl", getenv("LANG"));
470 else
471 cgiCopyTemplateLang(stdout, TEMPLATES, "class-added.tmpl", getenv("LANG"));
472 }
473 }
474
475
476 /*
477 * 'do_am_printer()' - Add or modify a printer.
478 */
479
480 static void
481 do_am_printer(http_t *http, /* I - HTTP connection */
482 cups_lang_t *language, /* I - Client's language */
483 int modify) /* I - Modify the printer? */
484 {
485 int i; /* Looping var */
486 int element; /* Element number */
487 ipp_attribute_t *attr, /* Current attribute */
488 *last; /* Last attribute */
489 ipp_t *request, /* IPP request */
490 *response, /* IPP response */
491 *oldinfo; /* Old printer information */
492 ipp_status_t status; /* Request status */
493 const char *var; /* CGI variable */
494 char uri[HTTP_MAX_URI], /* Device or printer URI */
495 *uriptr; /* Pointer into URI */
496 int maxrate; /* Maximum baud rate */
497 char baudrate[255]; /* Baud rate string */
498 char make[255]; /* Make string */
499 const char *name, /* Pointer to class name */
500 *ptr; /* Pointer to CGI variable */
501 static int baudrates[] = /* Baud rates */
502 {
503 1200,
504 2400,
505 4800,
506 9600,
507 19200,
508 38400,
509 57600,
510 115200,
511 230400,
512 460800
513 };
514
515
516 if (modify)
517 {
518 /*
519 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
520 * following attributes:
521 *
522 * attributes-charset
523 * attributes-natural-language
524 * printer-uri
525 */
526
527 request = ippNew();
528
529 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
530 request->request.op.request_id = 1;
531
532 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
533 "attributes-charset", NULL, cupsLangEncoding(language));
534
535 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
536 "attributes-natural-language", NULL, language->language);
537
538 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
539 cgiGetVariable("PRINTER_NAME"));
540 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
541 NULL, uri);
542
543 /*
544 * Do the request and get back a response...
545 */
546
547 oldinfo = cupsDoRequest(http, request, "/");
548 }
549 else
550 oldinfo = NULL;
551
552 if ((name = cgiGetVariable("PRINTER_NAME")) == NULL)
553 {
554 if (modify)
555 {
556 /*
557 * Update the location and description of an existing printer...
558 */
559
560 if (oldinfo)
561 ippSetCGIVars(oldinfo, NULL, NULL);
562
563 cgiCopyTemplateLang(stdout, TEMPLATES, "modify-printer.tmpl", getenv("LANG"));
564 }
565 else
566 {
567 /*
568 * Get the name, location, and description for a new printer...
569 */
570
571 cgiCopyTemplateLang(stdout, TEMPLATES, "add-printer.tmpl", getenv("LANG"));
572 }
573
574 if (oldinfo)
575 ippDelete(oldinfo);
576
577 return;
578 }
579
580 if (isdigit(*name))
581 ptr = name;
582 else
583 for (ptr = name; *ptr; ptr ++)
584 if (!isalnum(*ptr) && *ptr != '_')
585 break;
586
587 if (*ptr || ptr == name)
588 {
589 cgiSetVariable("ERROR", "The printer name may only contain letters, "
590 "numbers, and the underscore.");
591 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
592 return;
593 }
594
595 if ((var = cgiGetVariable("DEVICE_URI")) == NULL)
596 {
597 /*
598 * Build a CUPS_GET_DEVICES request, which requires the following
599 * attributes:
600 *
601 * attributes-charset
602 * attributes-natural-language
603 * printer-uri
604 */
605
606 request = ippNew();
607
608 request->request.op.operation_id = CUPS_GET_DEVICES;
609 request->request.op.request_id = 1;
610
611 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
612 "attributes-charset", NULL, cupsLangEncoding(language));
613
614 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
615 "attributes-natural-language", NULL, language->language);
616
617 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
618 NULL, "ipp://localhost/printers/");
619
620 /*
621 * Do the request and get back a response...
622 */
623
624 if ((response = cupsDoRequest(http, request, "/")) != NULL)
625 {
626 ippSetCGIVars(response, NULL, NULL);
627 ippDelete(response);
628 }
629
630 /*
631 * Let the user choose...
632 */
633
634 if (oldinfo &&
635 (attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
636 {
637 strncpy(uri, attr->values[0].string.text, sizeof(uri) - 1);
638 uri[sizeof(uri) - 1] = '\0';
639 if ((uriptr = strchr(uri, ':')) != NULL && strncmp(uriptr, "://", 3) == 0)
640 *uriptr = '\0';
641
642 cgiSetVariable("CURRENT_DEVICE_URI", uri);
643 }
644
645 cgiCopyTemplateLang(stdout, TEMPLATES, "choose-device.tmpl", getenv("LANG"));
646 }
647 else if (strchr(var, '/') == NULL)
648 {
649 if (oldinfo &&
650 (attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
651 {
652 /*
653 * Set the current device URI for the form to the old one...
654 */
655
656 if (strncmp(attr->values[0].string.text, var, strlen(var)) == 0)
657 cgiSetVariable("DEVICE_URI", attr->values[0].string.text);
658 }
659
660 /*
661 * User needs to set the full URI...
662 */
663
664 cgiCopyTemplateLang(stdout, TEMPLATES, "choose-uri.tmpl", getenv("LANG"));
665 }
666 else if (strncmp(var, "serial:", 7) == 0 && cgiGetVariable("BAUDRATE") == NULL)
667 {
668 /*
669 * Need baud rate, parity, etc.
670 */
671
672 if ((var = strchr(var, '?')) != NULL &&
673 strncmp(var, "?baud=", 6) == 0)
674 maxrate = atoi(var + 6);
675 else
676 maxrate = 19200;
677
678 for (i = 0; i < 10; i ++)
679 if (baudrates[i] > maxrate)
680 break;
681 else
682 {
683 sprintf(baudrate, "%d", baudrates[i]);
684 cgiSetArray("BAUDRATES", i, baudrate);
685 }
686
687 cgiCopyTemplateLang(stdout, TEMPLATES, "choose-serial.tmpl", getenv("LANG"));
688 }
689 else if ((var = cgiGetVariable("PPD_NAME")) == NULL)
690 {
691 if (modify)
692 {
693 /*
694 * Get the PPD file...
695 */
696
697 int fd; /* PPD file */
698 char filename[1024]; /* PPD filename */
699 ppd_file_t *ppd; /* PPD information */
700 char buffer[1024]; /* Buffer */
701 int bytes; /* Number of bytes */
702
703
704 snprintf(uri, sizeof(uri), "/printers/%s.ppd", name);
705
706 if (httpGet(http, uri))
707 httpGet(http, uri);
708
709 while (httpUpdate(http) == HTTP_CONTINUE);
710
711 if ((fd = cupsTempFd(filename, sizeof(filename))) >= 0)
712 {
713 while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
714 write(fd, buffer, bytes);
715
716 close(fd);
717
718 if ((ppd = ppdOpenFile(filename)) != NULL)
719 {
720 if (ppd->manufacturer)
721 cgiSetVariable("CURRENT_MAKE", ppd->manufacturer);
722 if (ppd->nickname)
723 cgiSetVariable("CURRENT_MAKE_AND_MODEL", ppd->nickname);
724
725 ppdClose(ppd);
726 }
727
728 unlink(filename);
729 }
730 else
731 httpFlush(http);
732 }
733
734 /*
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 request = ippNew();
744
745 request->request.op.operation_id = CUPS_GET_PPDS;
746 request->request.op.request_id = 1;
747
748 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
749 "attributes-charset", NULL, cupsLangEncoding(language));
750
751 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
752 "attributes-natural-language", NULL, language->language);
753
754 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
755 NULL, "ipp://localhost/printers/");
756
757 /*
758 * Do the request and get back a response...
759 */
760
761 if ((response = cupsDoRequest(http, request, "/")) != NULL)
762 {
763 if ((var = cgiGetVariable("PPD_MAKE")) == NULL)
764 {
765 /*
766 * Let the user choose a make...
767 */
768
769 for (element = 0, attr = response->attrs, last = NULL;
770 attr != NULL;
771 attr = attr->next)
772 if (attr->name && strcmp(attr->name, "ppd-make") == 0)
773 if (last == NULL ||
774 strcasecmp(last->values[0].string.text,
775 attr->values[0].string.text) != 0)
776 {
777 cgiSetArray("PPD_MAKE", element, attr->values[0].string.text);
778 element ++;
779 last = attr;
780 }
781
782 cgiCopyTemplateLang(stdout, TEMPLATES, "choose-make.tmpl",
783 getenv("LANG"));
784 }
785 else
786 {
787 /*
788 * Let the user choose a model...
789 */
790
791 strncpy(make, var, sizeof(make) - 1);
792 make[sizeof(make) - 1] = '\0';
793
794 ippSetCGIVars(response, "ppd-make", make);
795 cgiCopyTemplateLang(stdout, TEMPLATES, "choose-model.tmpl",
796 getenv("LANG"));
797 }
798
799 ippDelete(response);
800 }
801 else
802 {
803 char message[1024];
804
805
806 snprintf(message, sizeof(message), "Unable to get list of printer drivers: %s",
807 ippErrorString(cupsLastError()));
808 cgiSetVariable("ERROR", message);
809 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
810 }
811 }
812 else
813 {
814 /*
815 * Build a CUPS_ADD_PRINTER request, which requires the following
816 * attributes:
817 *
818 * attributes-charset
819 * attributes-natural-language
820 * printer-uri
821 * printer-location
822 * printer-info
823 * ppd-name
824 * device-uri
825 * printer-is-accepting-jobs
826 * printer-state
827 */
828
829 request = ippNew();
830
831 request->request.op.operation_id = CUPS_ADD_PRINTER;
832 request->request.op.request_id = 1;
833
834 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
835 "attributes-charset", NULL, cupsLangEncoding(language));
836
837 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
838 "attributes-natural-language", NULL, language->language);
839
840 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
841 cgiGetVariable("PRINTER_NAME"));
842 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
843 NULL, uri);
844
845 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
846 NULL, cgiGetVariable("PRINTER_LOCATION"));
847
848 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
849 NULL, cgiGetVariable("PRINTER_INFO"));
850
851 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name",
852 NULL, cgiGetVariable("PPD_NAME"));
853
854 strncpy(uri, cgiGetVariable("DEVICE_URI"), sizeof(uri) - 1);
855 uri[sizeof(uri) - 1] = '\0';
856 if (strncmp(uri, "serial:", 7) == 0)
857 {
858 /*
859 * Update serial port URI to include baud rate, etc.
860 */
861
862 if ((uriptr = strchr(uri, '?')) == NULL)
863 uriptr = uri + strlen(uri);
864
865 snprintf(uriptr, sizeof(uri) - (uriptr - uri),
866 "?baud=%s+bits=%s+parity=%s+flow=%s",
867 cgiGetVariable("BAUDRATE"), cgiGetVariable("BITS"),
868 cgiGetVariable("PARITY"), cgiGetVariable("FLOW"));
869 }
870
871 ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri",
872 NULL, uri);
873
874 ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
875
876 ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
877 IPP_PRINTER_IDLE);
878
879 /*
880 * Do the request and get back a response...
881 */
882
883 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
884 {
885 status = response->request.status.status_code;
886 ippDelete(response);
887 }
888 else
889 status = IPP_NOT_AUTHORIZED;
890
891 if (status > IPP_OK_CONFLICT)
892 {
893 cgiSetVariable("ERROR", ippErrorString(status));
894 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
895 }
896 else if (modify)
897 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-modified.tmpl", getenv("LANG"));
898 else
899 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-added.tmpl", getenv("LANG"));
900 }
901
902 if (oldinfo)
903 ippDelete(oldinfo);
904 }
905
906
907 /*
908 * 'do_config_printer()' - Configure the default options for a printer.
909 */
910
911 static void
912 do_config_printer(http_t *http, /* I - HTTP connection */
913 cups_lang_t *language)/* I - Client's language */
914 {
915 int i, j, k; /* Looping vars */
916 int have_options; /* Have options? */
917 ipp_t *request, /* IPP request */
918 *response; /* IPP response */
919 ipp_attribute_t *attr; /* IPP attribute */
920 char uri[HTTP_MAX_URI]; /* Job URI */
921 const char *var; /* Variable value */
922 const char *printer; /* Printer printer name */
923 ipp_status_t status; /* Operation status... */
924 const char *filename; /* PPD filename */
925 char tempfile[1024]; /* Temporary filename */
926 FILE *in, /* Input file */
927 *out; /* Output file */
928 int outfd; /* Output file descriptor */
929 char line[1024]; /* Line from PPD file */
930 char keyword[1024], /* Keyword from Default line */
931 *keyptr; /* Pointer into keyword... */
932 ppd_file_t *ppd; /* PPD file */
933 ppd_group_t *group; /* Option group */
934 ppd_option_t *option; /* Option */
935
936
937 /*
938 * Get the printer name...
939 */
940
941 if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
942 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
943 else
944 {
945 cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
946 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
947 return;
948 }
949
950 /*
951 * Get the PPD file...
952 */
953
954 if ((filename = cupsGetPPD(printer)) == NULL)
955 {
956 cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
957 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
958 return;
959 }
960
961 ppd = ppdOpenFile(filename);
962
963 if (cgiGetVariable("job_sheets_start") != NULL ||
964 cgiGetVariable("job_sheets_end") != NULL)
965 have_options = 1;
966 else
967 have_options = 0;
968
969 for (i = ppd->num_groups, group = ppd->groups;
970 i > 0 && !have_options;
971 i --, group ++)
972 for (j = group->num_options, option = group->options;
973 j > 0;
974 j --, option ++)
975 if ((var = cgiGetVariable(option->keyword)) != NULL)
976 {
977 have_options = 1;
978 break;
979 }
980
981 if (!have_options)
982 {
983 /*
984 * Show the options to the user...
985 */
986
987 cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer.tmpl",
988 getenv("LANG"));
989
990 for (i = ppd->num_groups, group = ppd->groups;
991 i > 0;
992 i --, group ++)
993 {
994 cgiSetVariable("GROUP", group->text);
995 cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
996 getenv("LANG"));
997
998 for (j = group->num_options, option = group->options;
999 j > 0;
1000 j --, option ++)
1001 {
1002 if (strcmp(option->keyword, "PageRegion") == 0)
1003 continue;
1004
1005 cgiSetVariable("KEYWORD", option->keyword);
1006 cgiSetVariable("KEYTEXT", option->text);
1007 cgiSetVariable("DEFCHOICE", option->defchoice);
1008
1009 cgiSetSize("CHOICES", option->num_choices);
1010 cgiSetSize("TEXT", option->num_choices);
1011 for (k = 0; k < option->num_choices; k ++)
1012 {
1013 cgiSetArray("CHOICES", k, option->choices[k].choice);
1014 cgiSetArray("TEXT", k, option->choices[k].text);
1015 }
1016
1017 switch (option->ui)
1018 {
1019 case PPD_UI_BOOLEAN :
1020 cgiCopyTemplateLang(stdout, TEMPLATES, "option-boolean.tmpl",
1021 getenv("LANG"));
1022 break;
1023 case PPD_UI_PICKONE :
1024 cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
1025 getenv("LANG"));
1026 break;
1027 case PPD_UI_PICKMANY :
1028 cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickmany.tmpl",
1029 getenv("LANG"));
1030 break;
1031 }
1032 }
1033
1034 cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
1035 getenv("LANG"));
1036 }
1037
1038 /*
1039 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
1040 * following attributes:
1041 *
1042 * attributes-charset
1043 * attributes-natural-language
1044 * printer-uri
1045 */
1046
1047 request = ippNew();
1048
1049 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
1050 request->request.op.request_id = 1;
1051
1052 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1053 "attributes-charset", NULL, cupsLangEncoding(language));
1054
1055 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1056 "attributes-natural-language", NULL, language->language);
1057
1058 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
1059 cgiGetVariable("PRINTER_NAME"));
1060 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1061 NULL, uri);
1062
1063 /*
1064 * Do the request and get back a response...
1065 */
1066
1067 if ((response = cupsDoRequest(http, request, "/")) != NULL)
1068 {
1069 if ((attr = ippFindAttribute(response, "job-sheets-supported", IPP_TAG_ZERO)) != NULL)
1070 {
1071 /*
1072 * Add the job sheets options...
1073 */
1074
1075 cgiSetVariable("GROUP", "Banners");
1076 cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
1077 getenv("LANG"));
1078
1079 cgiSetSize("CHOICES", attr->num_values);
1080 cgiSetSize("TEXT", attr->num_values);
1081 for (k = 0; k < attr->num_values; k ++)
1082 {
1083 cgiSetArray("CHOICES", k, attr->values[k].string.text);
1084 cgiSetArray("TEXT", k, attr->values[k].string.text);
1085 }
1086
1087 attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO);
1088
1089 cgiSetVariable("KEYWORD", "job_sheets_start");
1090 cgiSetVariable("KEYTEXT", "Starting Banner");
1091 cgiSetVariable("DEFCHOICE", attr == NULL ?
1092 "" : attr->values[0].string.text);
1093
1094 cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
1095 getenv("LANG"));
1096
1097 cgiSetVariable("KEYWORD", "job_sheets_end");
1098 cgiSetVariable("KEYTEXT", "Ending Banner");
1099 cgiSetVariable("DEFCHOICE", attr == NULL && attr->num_values > 1 ?
1100 "" : attr->values[1].string.text);
1101
1102 cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
1103 getenv("LANG"));
1104
1105 cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
1106 getenv("LANG"));
1107 }
1108
1109 ippDelete(response);
1110 }
1111
1112 cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer2.tmpl",
1113 getenv("LANG"));
1114 }
1115 else
1116 {
1117 /*
1118 * Set default options...
1119 */
1120
1121 outfd = cupsTempFd(tempfile, sizeof(tempfile));
1122 in = fopen(filename, "rb");
1123 out = fdopen(outfd, "wb");
1124
1125 if (outfd < 0 || in == NULL || out == NULL)
1126 {
1127 cgiSetVariable("ERROR", strerror(errno));
1128 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1129 unlink(filename);
1130 return;
1131 }
1132
1133 while (get_line(line, sizeof(line), in) != NULL)
1134 {
1135 if (strncmp(line, "*Default", 8) != 0)
1136 fprintf(out, "%s\n", line);
1137 else
1138 {
1139 /*
1140 * Get default option name...
1141 */
1142
1143 strncpy(keyword, line + 8, sizeof(keyword) - 1);
1144 keyword[sizeof(keyword) - 1] = '\0';
1145
1146 for (keyptr = keyword; *keyptr; keyptr ++)
1147 if (*keyptr == ':' || isspace(*keyptr))
1148 break;
1149
1150 *keyptr = '\0';
1151
1152 if (strcmp(keyword, "PageRegion") == 0)
1153 var = cgiGetVariable("PageSize");
1154 else
1155 var = cgiGetVariable(keyword);
1156
1157 if (var != NULL)
1158 fprintf(out, "*Default%s: %s\n", keyword, var);
1159 else
1160 fprintf(out, "%s\n", line);
1161 }
1162 }
1163
1164 fclose(in);
1165 fclose(out);
1166 close(outfd);
1167
1168 /*
1169 * Build a CUPS_ADD_PRINTER request, which requires the following
1170 * attributes:
1171 *
1172 * attributes-charset
1173 * attributes-natural-language
1174 * printer-uri
1175 * job-sheets-default
1176 * [ppd file]
1177 */
1178
1179 request = ippNew();
1180
1181 request->request.op.operation_id = CUPS_ADD_PRINTER;
1182 request->request.op.request_id = 1;
1183
1184 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1185 "attributes-charset", NULL, cupsLangEncoding(language));
1186
1187 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1188 "attributes-natural-language", NULL, language->language);
1189
1190 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
1191 cgiGetVariable("PRINTER_NAME"));
1192 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1193 NULL, uri);
1194
1195 attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
1196 "job-sheets-default", 2, NULL, NULL);
1197 attr->values[0].string.text = strdup(cgiGetVariable("job_sheets_start"));
1198 attr->values[1].string.text = strdup(cgiGetVariable("job_sheets_end"));
1199
1200 /*
1201 * Do the request and get back a response...
1202 */
1203
1204 if ((response = cupsDoFileRequest(http, request, "/admin/", tempfile)) != NULL)
1205 {
1206 status = response->request.status.status_code;
1207 ippDelete(response);
1208 }
1209 else
1210 status = IPP_NOT_AUTHORIZED;
1211
1212 if (status > IPP_OK_CONFLICT)
1213 {
1214 cgiSetVariable("ERROR", ippErrorString(status));
1215 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1216 }
1217 else
1218 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-configured.tmpl", getenv("LANG"));
1219
1220 unlink(tempfile);
1221 }
1222
1223 unlink(filename);
1224 }
1225
1226
1227 /*
1228 * 'do_delete_class()' - Delete a class...
1229 */
1230
1231 static void
1232 do_delete_class(http_t *http, /* I - HTTP connection */
1233 cups_lang_t *language) /* I - Client's language */
1234 {
1235 ipp_t *request, /* IPP request */
1236 *response; /* IPP response */
1237 char uri[HTTP_MAX_URI]; /* Job URI */
1238 const char *pclass; /* Printer class name */
1239 ipp_status_t status; /* Operation status... */
1240
1241
1242 if (cgiGetVariable("CONFIRM") == NULL)
1243 {
1244 cgiCopyTemplateLang(stdout, TEMPLATES, "class-confirm.tmpl", getenv("LANG"));
1245 return;
1246 }
1247
1248 if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL)
1249 snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
1250 else
1251 {
1252 cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
1253 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1254 return;
1255 }
1256
1257 /*
1258 * Build a CUPS_DELETE_CLASS request, which requires the following
1259 * attributes:
1260 *
1261 * attributes-charset
1262 * attributes-natural-language
1263 * printer-uri
1264 */
1265
1266 request = ippNew();
1267
1268 request->request.op.operation_id = CUPS_DELETE_CLASS;
1269 request->request.op.request_id = 1;
1270
1271 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1272 "attributes-charset", NULL, cupsLangEncoding(language));
1273
1274 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1275 "attributes-natural-language", NULL, language->language);
1276
1277 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1278 NULL, uri);
1279
1280 /*
1281 * Do the request and get back a response...
1282 */
1283
1284 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
1285 {
1286 status = response->request.status.status_code;
1287
1288 ippDelete(response);
1289 }
1290 else
1291 status = IPP_GONE;
1292
1293 if (status > IPP_OK_CONFLICT)
1294 {
1295 cgiSetVariable("ERROR", ippErrorString(status));
1296 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1297 }
1298 else
1299 cgiCopyTemplateLang(stdout, TEMPLATES, "class-deleted.tmpl", getenv("LANG"));
1300 }
1301
1302
1303 /*
1304 * 'do_delete_printer()' - Delete a printer...
1305 */
1306
1307 static void
1308 do_delete_printer(http_t *http, /* I - HTTP connection */
1309 cups_lang_t *language)/* I - Client's language */
1310 {
1311 ipp_t *request, /* IPP request */
1312 *response; /* IPP response */
1313 char uri[HTTP_MAX_URI]; /* Job URI */
1314 const char *printer; /* Printer printer name */
1315 ipp_status_t status; /* Operation status... */
1316
1317
1318 if (cgiGetVariable("CONFIRM") == NULL)
1319 {
1320 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-confirm.tmpl", getenv("LANG"));
1321 return;
1322 }
1323
1324 if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
1325 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1326 else
1327 {
1328 cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
1329 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1330 return;
1331 }
1332
1333 /*
1334 * Build a CUPS_DELETE_PRINTER request, which requires the following
1335 * attributes:
1336 *
1337 * attributes-charset
1338 * attributes-natural-language
1339 * printer-uri
1340 */
1341
1342 request = ippNew();
1343
1344 request->request.op.operation_id = CUPS_DELETE_PRINTER;
1345 request->request.op.request_id = 1;
1346
1347 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1348 "attributes-charset", NULL, cupsLangEncoding(language));
1349
1350 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1351 "attributes-natural-language", NULL, language->language);
1352
1353 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1354 NULL, uri);
1355
1356 /*
1357 * Do the request and get back a response...
1358 */
1359
1360 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
1361 {
1362 status = response->request.status.status_code;
1363
1364 ippDelete(response);
1365 }
1366 else
1367 status = IPP_GONE;
1368
1369 if (status > IPP_OK_CONFLICT)
1370 {
1371 cgiSetVariable("ERROR", ippErrorString(status));
1372 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1373 }
1374 else
1375 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-deleted.tmpl", getenv("LANG"));
1376 }
1377
1378
1379 /*
1380 * 'do_job_op()' - Do a job operation.
1381 */
1382
1383 static void
1384 do_job_op(http_t *http, /* I - HTTP connection */
1385 cups_lang_t *language, /* I - Client's language */
1386 ipp_op_t op) /* I - Operation to perform */
1387 {
1388 ipp_t *request, /* IPP request */
1389 *response; /* IPP response */
1390 char uri[HTTP_MAX_URI]; /* Job URI */
1391 const char *job; /* Job ID */
1392 const char *printer; /* Printer name (purge-jobs) */
1393 ipp_status_t status; /* Operation status... */
1394
1395
1396 if ((job = cgiGetVariable("JOB_ID")) != NULL)
1397 snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%s", job);
1398 else if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
1399 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1400 else
1401 {
1402 cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
1403 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1404 return;
1405 }
1406
1407 /*
1408 * Build a job request, which requires the following
1409 * attributes:
1410 *
1411 * attributes-charset
1412 * attributes-natural-language
1413 * job-uri or printer-uri (purge-jobs)
1414 * requesting-user-name
1415 */
1416
1417 request = ippNew();
1418
1419 request->request.op.operation_id = op;
1420 request->request.op.request_id = 1;
1421
1422 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1423 "attributes-charset", NULL, cupsLangEncoding(language));
1424
1425 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1426 "attributes-natural-language", NULL, language->language);
1427
1428 if (job)
1429 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
1430 NULL, uri);
1431 else
1432 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1433 NULL, uri);
1434
1435 if (getenv("REMOTE_USER") != NULL)
1436 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
1437 NULL, getenv("REMOTE_USER"));
1438 else
1439 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
1440 NULL, "root");
1441
1442 /*
1443 * Do the request and get back a response...
1444 */
1445
1446 if ((response = cupsDoRequest(http, request, "/jobs")) != NULL)
1447 {
1448 status = response->request.status.status_code;
1449
1450 ippDelete(response);
1451 }
1452 else
1453 status = IPP_GONE;
1454
1455 if (status > IPP_OK_CONFLICT)
1456 {
1457 cgiSetVariable("ERROR", ippErrorString(status));
1458 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1459 }
1460 else if (op == IPP_CANCEL_JOB)
1461 cgiCopyTemplateLang(stdout, TEMPLATES, "job-cancel.tmpl", getenv("LANG"));
1462 else if (op == IPP_HOLD_JOB)
1463 cgiCopyTemplateLang(stdout, TEMPLATES, "job-hold.tmpl", getenv("LANG"));
1464 else if (op == IPP_RELEASE_JOB)
1465 cgiCopyTemplateLang(stdout, TEMPLATES, "job-release.tmpl", getenv("LANG"));
1466 else if (op == IPP_RESTART_JOB)
1467 cgiCopyTemplateLang(stdout, TEMPLATES, "job-restart.tmpl", getenv("LANG"));
1468 }
1469
1470
1471 /*
1472 * 'do_printer_op()' - Do a printer operation.
1473 */
1474
1475 static void
1476 do_printer_op(http_t *http, /* I - HTTP connection */
1477 cups_lang_t *language, /* I - Client's language */
1478 ipp_op_t op) /* I - Operation to perform */
1479 {
1480 ipp_t *request, /* IPP request */
1481 *response; /* IPP response */
1482 char uri[HTTP_MAX_URI]; /* Printer URI */
1483 const char *printer; /* Printer name (purge-jobs) */
1484 ipp_status_t status; /* Operation status... */
1485
1486
1487 if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
1488 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
1489 else
1490 {
1491 cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
1492 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1493 return;
1494 }
1495
1496 /*
1497 * Build a printer request, which requires the following
1498 * attributes:
1499 *
1500 * attributes-charset
1501 * attributes-natural-language
1502 * printer-uri
1503 */
1504
1505 request = ippNew();
1506
1507 request->request.op.operation_id = op;
1508 request->request.op.request_id = 1;
1509
1510 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
1511 "attributes-charset", NULL, cupsLangEncoding(language));
1512
1513 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
1514 "attributes-natural-language", NULL, language->language);
1515
1516 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1517 NULL, uri);
1518
1519 /*
1520 * Do the request and get back a response...
1521 */
1522
1523 if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
1524 {
1525 status = response->request.status.status_code;
1526
1527 ippDelete(response);
1528 }
1529 else
1530 status = IPP_GONE;
1531
1532 if (status > IPP_OK_CONFLICT)
1533 {
1534 cgiSetVariable("ERROR", ippErrorString(status));
1535 cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
1536 }
1537 else if (op == IPP_PAUSE_PRINTER)
1538 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-stop.tmpl", getenv("LANG"));
1539 else if (op == IPP_RESUME_PRINTER)
1540 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-start.tmpl", getenv("LANG"));
1541 else if (op == CUPS_ACCEPT_JOBS)
1542 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-accept.tmpl", getenv("LANG"));
1543 else if (op == CUPS_REJECT_JOBS)
1544 cgiCopyTemplateLang(stdout, TEMPLATES, "printer-reject.tmpl", getenv("LANG"));
1545 }
1546
1547
1548 /*
1549 * 'get_line()' - Get a line that is terminated by a LF, CR, or CR LF.
1550 */
1551
1552 static char * /* O - Pointer to buf or NULL on EOF */
1553 get_line(char *buf, /* I - Line buffer */
1554 int length, /* I - Length of buffer */
1555 FILE *fp) /* I - File to read from */
1556 {
1557 char *bufptr; /* Pointer into buffer */
1558 int ch; /* Character from file */
1559
1560
1561 length --;
1562 bufptr = buf;
1563
1564 while ((ch = getc(fp)) != EOF)
1565 {
1566 if (ch == '\n')
1567 break;
1568 else if (ch == '\r')
1569 {
1570 /*
1571 * Look for LF...
1572 */
1573
1574 ch = getc(fp);
1575 if (ch != '\n' && ch != EOF)
1576 ungetc(ch, fp);
1577
1578 break;
1579 }
1580
1581 *bufptr++ = ch;
1582 length --;
1583 if (length == 0)
1584 break;
1585 }
1586
1587 *bufptr = '\0';
1588
1589 if (ch == EOF)
1590 return (NULL);
1591 else
1592 return (buf);
1593 }
1594
1595
1596 /*
1597 * End of "$Id: admin.c,v 1.22 2001/03/05 21:37:33 mike Exp $".
1598 */