]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/printers.c
Remove all of the Subversion keywords from various source files.
[thirdparty/cups.git] / cgi-bin / printers.c
1 /*
2 * Printer status CGI for CUPS.
3 *
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2006 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 "LICENSE.txt"
10 * which should have been included with this file. If this file is
11 * file is missing or damaged, see the license at "http://www.cups.org/".
12 */
13
14 /*
15 * Include necessary headers...
16 */
17
18 #include "cgi-private.h"
19 #include <errno.h>
20
21
22 /*
23 * Local functions...
24 */
25
26 static void do_printer_op(http_t *http, const char *printer, ipp_op_t op,
27 const char *title);
28 static void show_all_printers(http_t *http, const char *username);
29 static void show_printer(http_t *http, const char *printer);
30
31
32 /*
33 * 'main()' - Main entry for CGI.
34 */
35
36 int /* O - Exit status */
37 main(void)
38 {
39 const char *printer; /* Printer name */
40 const char *user; /* Username */
41 http_t *http; /* Connection to the server */
42 ipp_t *request, /* IPP request */
43 *response; /* IPP response */
44 ipp_attribute_t *attr; /* IPP attribute */
45 const char *op; /* Operation to perform, if any */
46 static const char *def_attrs[] = /* Attributes for default printer */
47 {
48 "printer-name",
49 "printer-uri-supported"
50 };
51
52
53 /*
54 * Get any form variables...
55 */
56
57 cgiInitialize();
58
59 op = cgiGetVariable("OP");
60
61 /*
62 * Set the web interface section...
63 */
64
65 cgiSetVariable("SECTION", "printers");
66 cgiSetVariable("REFRESH_PAGE", "");
67
68 /*
69 * See if we are displaying a printer or all printers...
70 */
71
72 if ((printer = getenv("PATH_INFO")) != NULL)
73 {
74 printer ++;
75
76 if (!*printer)
77 printer = NULL;
78
79 if (printer)
80 cgiSetVariable("PRINTER_NAME", printer);
81 }
82
83 /*
84 * See who is logged in...
85 */
86
87 user = getenv("REMOTE_USER");
88
89 /*
90 * Connect to the HTTP server...
91 */
92
93 http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
94
95 /*
96 * Get the default printer...
97 */
98
99 if (!op || !cgiIsPOST())
100 {
101 /*
102 * Get the default destination...
103 */
104
105 request = ippNewRequest(CUPS_GET_DEFAULT);
106
107 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
108 "requested-attributes",
109 sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs);
110
111 if ((response = cupsDoRequest(http, request, "/")) != NULL)
112 {
113 if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
114 cgiSetVariable("DEFAULT_NAME", attr->values[0].string.text);
115
116 if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
117 {
118 char url[HTTP_MAX_URI]; /* New URL */
119
120
121 cgiSetVariable("DEFAULT_URI",
122 cgiRewriteURL(attr->values[0].string.text,
123 url, sizeof(url), NULL));
124 }
125
126 ippDelete(response);
127 }
128
129 /*
130 * See if we need to show a list of printers or the status of a
131 * single printer...
132 */
133
134 if (!printer)
135 show_all_printers(http, user);
136 else
137 show_printer(http, printer);
138 }
139 else if (printer)
140 {
141 if (!*op)
142 {
143 const char *server_port = getenv("SERVER_PORT");
144 /* Port number string */
145 int port = atoi(server_port ? server_port : "0");
146 /* Port number */
147 char uri[1024]; /* URL */
148
149 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri),
150 getenv("HTTPS") ? "https" : "http", NULL,
151 getenv("SERVER_NAME"), port, "/printers/%s", printer);
152
153 printf("Location: %s\n\n", uri);
154 }
155 else if (!strcmp(op, "start-printer"))
156 do_printer_op(http, printer, IPP_RESUME_PRINTER,
157 cgiText(_("Resume Printer")));
158 else if (!strcmp(op, "stop-printer"))
159 do_printer_op(http, printer, IPP_PAUSE_PRINTER,
160 cgiText(_("Pause Printer")));
161 else if (!strcmp(op, "accept-jobs"))
162 do_printer_op(http, printer, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs")));
163 else if (!strcmp(op, "reject-jobs"))
164 do_printer_op(http, printer, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs")));
165 else if (!strcmp(op, "cancel-jobs"))
166 do_printer_op(http, printer, IPP_OP_CANCEL_JOBS, cgiText(_("Cancel Jobs")));
167 else if (!_cups_strcasecmp(op, "print-self-test-page"))
168 cgiPrintCommand(http, printer, "PrintSelfTestPage",
169 cgiText(_("Print Self-Test Page")));
170 else if (!_cups_strcasecmp(op, "clean-print-heads"))
171 cgiPrintCommand(http, printer, "Clean all",
172 cgiText(_("Clean Print Heads")));
173 else if (!_cups_strcasecmp(op, "print-test-page"))
174 cgiPrintTestPage(http, printer);
175 else if (!_cups_strcasecmp(op, "move-jobs"))
176 cgiMoveJobs(http, printer, 0);
177 else
178 {
179 /*
180 * Unknown/bad operation...
181 */
182
183 cgiStartHTML(printer);
184 cgiCopyTemplateLang("error-op.tmpl");
185 cgiEndHTML();
186 }
187 }
188 else
189 {
190 /*
191 * Unknown/bad operation...
192 */
193
194 cgiStartHTML(cgiText(_("Printers")));
195 cgiCopyTemplateLang("error-op.tmpl");
196 cgiEndHTML();
197 }
198
199 /*
200 * Close the HTTP server connection...
201 */
202
203 httpClose(http);
204
205 /*
206 * Return with no errors...
207 */
208
209 return (0);
210 }
211
212
213 /*
214 * 'do_printer_op()' - Do a printer operation.
215 */
216
217 static void
218 do_printer_op(http_t *http, /* I - HTTP connection */
219 const char *printer, /* I - Printer name */
220 ipp_op_t op, /* I - Operation to perform */
221 const char *title) /* I - Title of page */
222 {
223 ipp_t *request; /* IPP request */
224 char uri[HTTP_MAX_URI], /* Printer URI */
225 resource[HTTP_MAX_URI]; /* Path for request */
226
227
228 /*
229 * Build a printer request, which requires the following
230 * attributes:
231 *
232 * attributes-charset
233 * attributes-natural-language
234 * printer-uri
235 */
236
237 request = ippNewRequest(op);
238
239 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
240 "localhost", 0, "/printers/%s", printer);
241 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
242 NULL, uri);
243
244 /*
245 * Do the request and get back a response...
246 */
247
248 snprintf(resource, sizeof(resource), "/printers/%s", printer);
249 ippDelete(cupsDoRequest(http, request, resource));
250
251 if (cupsLastError() == IPP_NOT_AUTHORIZED)
252 {
253 puts("Status: 401\n");
254 exit(0);
255 }
256 else if (cupsLastError() > IPP_OK_CONFLICT)
257 {
258 cgiStartHTML(title);
259 cgiShowIPPError(_("Unable to do maintenance command"));
260 }
261 else
262 {
263 /*
264 * Redirect successful updates back to the printer page...
265 */
266
267 char url[1024], /* Printer/class URL */
268 refresh[1024]; /* Refresh URL */
269
270
271 cgiRewriteURL(uri, url, sizeof(url), NULL);
272 cgiFormEncode(uri, url, sizeof(uri));
273 snprintf(refresh, sizeof(refresh), "5;URL=%s", uri);
274 cgiSetVariable("refresh_page", refresh);
275
276 cgiStartHTML(title);
277
278 if (op == IPP_PAUSE_PRINTER)
279 cgiCopyTemplateLang("printer-stop.tmpl");
280 else if (op == IPP_RESUME_PRINTER)
281 cgiCopyTemplateLang("printer-start.tmpl");
282 else if (op == CUPS_ACCEPT_JOBS)
283 cgiCopyTemplateLang("printer-accept.tmpl");
284 else if (op == CUPS_REJECT_JOBS)
285 cgiCopyTemplateLang("printer-reject.tmpl");
286 else if (op == IPP_OP_CANCEL_JOBS)
287 cgiCopyTemplateLang("printer-cancel-jobs.tmpl");
288 }
289
290 cgiEndHTML();
291 }
292
293
294 /*
295 * 'show_all_printers()' - Show all printers...
296 */
297
298 static void
299 show_all_printers(http_t *http, /* I - Connection to server */
300 const char *user) /* I - Username */
301 {
302 int i; /* Looping var */
303 ipp_t *request, /* IPP request */
304 *response; /* IPP response */
305 cups_array_t *printers; /* Array of printer objects */
306 ipp_attribute_t *printer; /* Printer object */
307 int ascending, /* Order of printers (0 = descending) */
308 first, /* First printer to show */
309 count; /* Number of printers */
310 const char *var; /* Form variable */
311 void *search; /* Search data */
312 char val[1024]; /* Form variable */
313
314
315 fprintf(stderr, "DEBUG: show_all_printers(http=%p, user=\"%s\")\n",
316 http, user ? user : "(null)");
317
318 /*
319 * Show the standard header...
320 */
321
322 cgiStartHTML(cgiText(_("Printers")));
323
324 /*
325 * Build a CUPS_GET_PRINTERS request, which requires the following
326 * attributes:
327 *
328 * attributes-charset
329 * attributes-natural-language
330 * printer-type
331 * printer-type-mask
332 * requesting-user-name
333 */
334
335 request = ippNewRequest(CUPS_GET_PRINTERS);
336
337 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
338 "printer-type", 0);
339 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
340 "printer-type-mask", CUPS_PRINTER_CLASS);
341
342 if (user)
343 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
344 "requesting-user-name", NULL, user);
345
346 cgiGetAttributes(request, "printers.tmpl");
347
348 /*
349 * Do the request and get back a response...
350 */
351
352 if ((response = cupsDoRequest(http, request, "/")) != NULL)
353 {
354 /*
355 * Get a list of matching job objects.
356 */
357
358 if ((var = cgiGetVariable("QUERY")) != NULL &&
359 !cgiGetVariable("CLEAR"))
360 search = cgiCompileSearch(var);
361 else
362 search = NULL;
363
364 printers = cgiGetIPPObjects(response, search);
365 count = cupsArrayCount(printers);
366
367 if (search)
368 cgiFreeSearch(search);
369
370 /*
371 * Figure out which printers to display...
372 */
373
374 if ((var = cgiGetVariable("FIRST")) != NULL)
375 first = atoi(var);
376 else
377 first = 0;
378
379 if (first >= count)
380 first = count - CUPS_PAGE_MAX;
381
382 first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX;
383
384 if (first < 0)
385 first = 0;
386
387 sprintf(val, "%d", count);
388 cgiSetVariable("TOTAL", val);
389
390 if ((var = cgiGetVariable("ORDER")) != NULL && *var)
391 ascending = !_cups_strcasecmp(var, "asc");
392 else
393 ascending = 1;
394
395 if (ascending)
396 {
397 for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first);
398 i < CUPS_PAGE_MAX && printer;
399 i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers))
400 cgiSetIPPObjectVars(printer, NULL, i);
401 }
402 else
403 {
404 for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1);
405 i < CUPS_PAGE_MAX && printer;
406 i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers))
407 cgiSetIPPObjectVars(printer, NULL, i);
408 }
409
410 /*
411 * Save navigation URLs...
412 */
413
414 cgiSetVariable("THISURL", "/printers/");
415
416 if (first > 0)
417 {
418 sprintf(val, "%d", first - CUPS_PAGE_MAX);
419 cgiSetVariable("PREV", val);
420 }
421
422 if ((first + CUPS_PAGE_MAX) < count)
423 {
424 sprintf(val, "%d", first + CUPS_PAGE_MAX);
425 cgiSetVariable("NEXT", val);
426 }
427
428 /*
429 * Then show everything...
430 */
431
432 cgiCopyTemplateLang("search.tmpl");
433
434 cgiCopyTemplateLang("printers-header.tmpl");
435
436 if (count > CUPS_PAGE_MAX)
437 cgiCopyTemplateLang("pager.tmpl");
438
439 cgiCopyTemplateLang("printers.tmpl");
440
441 if (count > CUPS_PAGE_MAX)
442 cgiCopyTemplateLang("pager.tmpl");
443
444 /*
445 * Delete the response...
446 */
447
448 cupsArrayDelete(printers);
449 ippDelete(response);
450 }
451 else
452 {
453 /*
454 * Show the error...
455 */
456
457 cgiShowIPPError(_("Unable to get printer list"));
458 }
459
460 cgiEndHTML();
461 }
462
463
464 /*
465 * 'show_printer()' - Show a single printer.
466 */
467
468 static void
469 show_printer(http_t *http, /* I - Connection to server */
470 const char *printer) /* I - Name of printer */
471 {
472 ipp_t *request, /* IPP request */
473 *response; /* IPP response */
474 ipp_attribute_t *attr; /* IPP attribute */
475 char uri[HTTP_MAX_URI]; /* Printer URI */
476 char refresh[1024]; /* Refresh URL */
477
478
479 fprintf(stderr, "DEBUG: show_printer(http=%p, printer=\"%s\")\n",
480 http, printer ? printer : "(null)");
481
482 /*
483 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
484 * attributes:
485 *
486 * attributes-charset
487 * attributes-natural-language
488 * printer-uri
489 */
490
491 request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
492
493 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
494 "localhost", 0, "/printers/%s", printer);
495 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
496 uri);
497
498 cgiGetAttributes(request, "printer.tmpl");
499
500 /*
501 * Do the request and get back a response...
502 */
503
504 if ((response = cupsDoRequest(http, request, "/")) != NULL)
505 {
506 /*
507 * Got the result; set the CGI variables and check the status of a
508 * single-queue request...
509 */
510
511 cgiSetIPPVars(response, NULL, NULL, NULL, 0);
512
513 if (printer && (attr = ippFindAttribute(response, "printer-state",
514 IPP_TAG_ENUM)) != NULL &&
515 attr->values[0].integer == IPP_PRINTER_PROCESSING)
516 {
517 /*
518 * Printer is processing - automatically refresh the page until we
519 * are done printing...
520 */
521
522 cgiFormEncode(uri, printer, sizeof(uri));
523 snprintf(refresh, sizeof(refresh), "10;URL=/printers/%s", uri);
524 cgiSetVariable("refresh_page", refresh);
525 }
526
527 /*
528 * Delete the response...
529 */
530
531 ippDelete(response);
532
533 /*
534 * Show the standard header...
535 */
536
537 cgiStartHTML(printer);
538
539 /*
540 * Show the printer status...
541 */
542
543 cgiCopyTemplateLang("printer.tmpl");
544
545 /*
546 * Show jobs for the specified printer...
547 */
548
549 cgiCopyTemplateLang("printer-jobs-header.tmpl");
550 cgiShowJobs(http, printer);
551 }
552 else
553 {
554 /*
555 * Show the IPP error...
556 */
557
558 cgiStartHTML(printer);
559 cgiShowIPPError(_("Unable to get printer status"));
560 }
561
562 cgiEndHTML();
563 }