]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/printers.c
Fix source file header text duplication text duplication.
[thirdparty/cups.git] / cgi-bin / printers.c
1 /*
2 * Printer status CGI for CUPS.
3 *
4 * Copyright 2007-2016 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 * 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 first, /* First printer to show */
308 count; /* Number of printers */
309 const char *var; /* Form variable */
310 void *search; /* Search data */
311 char val[1024]; /* Form variable */
312
313
314 fprintf(stderr, "DEBUG: show_all_printers(http=%p, user=\"%s\")\n",
315 http, user ? user : "(null)");
316
317 /*
318 * Show the standard header...
319 */
320
321 cgiStartHTML(cgiText(_("Printers")));
322
323 /*
324 * Build a CUPS_GET_PRINTERS request, which requires the following
325 * attributes:
326 *
327 * attributes-charset
328 * attributes-natural-language
329 * printer-type
330 * printer-type-mask
331 * requesting-user-name
332 */
333
334 request = ippNewRequest(CUPS_GET_PRINTERS);
335
336 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
337 "printer-type", 0);
338 ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
339 "printer-type-mask", CUPS_PRINTER_CLASS);
340
341 if (user)
342 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
343 "requesting-user-name", NULL, user);
344
345 cgiGetAttributes(request, "printers.tmpl");
346
347 /*
348 * Do the request and get back a response...
349 */
350
351 if ((response = cupsDoRequest(http, request, "/")) != NULL)
352 {
353 /*
354 * Get a list of matching job objects.
355 */
356
357 if ((var = cgiGetVariable("QUERY")) != NULL &&
358 !cgiGetVariable("CLEAR"))
359 search = cgiCompileSearch(var);
360 else
361 search = NULL;
362
363 printers = cgiGetIPPObjects(response, search);
364 count = cupsArrayCount(printers);
365
366 if (search)
367 cgiFreeSearch(search);
368
369 /*
370 * Figure out which printers to display...
371 */
372
373 if ((var = cgiGetVariable("FIRST")) != NULL)
374 first = atoi(var);
375 else
376 first = 0;
377
378 if (first >= count)
379 first = count - CUPS_PAGE_MAX;
380
381 first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX;
382
383 if (first < 0)
384 first = 0;
385
386 sprintf(val, "%d", count);
387 cgiSetVariable("TOTAL", val);
388
389 for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first);
390 i < CUPS_PAGE_MAX && printer;
391 i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers))
392 cgiSetIPPObjectVars(printer, NULL, i);
393
394 /*
395 * Save navigation URLs...
396 */
397
398 cgiSetVariable("THISURL", "/printers/");
399
400 if (first > 0)
401 {
402 sprintf(val, "%d", first - CUPS_PAGE_MAX);
403 cgiSetVariable("PREV", val);
404 }
405
406 if ((first + CUPS_PAGE_MAX) < count)
407 {
408 sprintf(val, "%d", first + CUPS_PAGE_MAX);
409 cgiSetVariable("NEXT", val);
410 }
411
412 if (count > CUPS_PAGE_MAX)
413 {
414 snprintf(val, sizeof(val), "%d", CUPS_PAGE_MAX * (count / CUPS_PAGE_MAX));
415 cgiSetVariable("LAST", val);
416 }
417
418 /*
419 * Then show everything...
420 */
421
422 cgiCopyTemplateLang("search.tmpl");
423
424 cgiCopyTemplateLang("printers-header.tmpl");
425
426 if (count > CUPS_PAGE_MAX)
427 cgiCopyTemplateLang("pager.tmpl");
428
429 cgiCopyTemplateLang("printers.tmpl");
430
431 if (count > CUPS_PAGE_MAX)
432 cgiCopyTemplateLang("pager.tmpl");
433
434 /*
435 * Delete the response...
436 */
437
438 cupsArrayDelete(printers);
439 ippDelete(response);
440 }
441 else
442 {
443 /*
444 * Show the error...
445 */
446
447 cgiShowIPPError(_("Unable to get printer list"));
448 }
449
450 cgiEndHTML();
451 }
452
453
454 /*
455 * 'show_printer()' - Show a single printer.
456 */
457
458 static void
459 show_printer(http_t *http, /* I - Connection to server */
460 const char *printer) /* I - Name of printer */
461 {
462 ipp_t *request, /* IPP request */
463 *response; /* IPP response */
464 ipp_attribute_t *attr; /* IPP attribute */
465 char uri[HTTP_MAX_URI]; /* Printer URI */
466 char refresh[1024]; /* Refresh URL */
467
468
469 fprintf(stderr, "DEBUG: show_printer(http=%p, printer=\"%s\")\n",
470 http, printer ? printer : "(null)");
471
472 /*
473 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
474 * attributes:
475 *
476 * attributes-charset
477 * attributes-natural-language
478 * printer-uri
479 */
480
481 request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
482
483 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
484 "localhost", 0, "/printers/%s", printer);
485 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
486 uri);
487
488 cgiGetAttributes(request, "printer.tmpl");
489
490 /*
491 * Do the request and get back a response...
492 */
493
494 if ((response = cupsDoRequest(http, request, "/")) != NULL)
495 {
496 /*
497 * Got the result; set the CGI variables and check the status of a
498 * single-queue request...
499 */
500
501 cgiSetIPPVars(response, NULL, NULL, NULL, 0);
502
503 if (printer && (attr = ippFindAttribute(response, "printer-state",
504 IPP_TAG_ENUM)) != NULL &&
505 attr->values[0].integer == IPP_PRINTER_PROCESSING)
506 {
507 /*
508 * Printer is processing - automatically refresh the page until we
509 * are done printing...
510 */
511
512 cgiFormEncode(uri, printer, sizeof(uri));
513 snprintf(refresh, sizeof(refresh), "10;URL=/printers/%s", uri);
514 cgiSetVariable("refresh_page", refresh);
515 }
516
517 /*
518 * Delete the response...
519 */
520
521 ippDelete(response);
522
523 /*
524 * Show the standard header...
525 */
526
527 cgiStartHTML(printer);
528
529 /*
530 * Show the printer status...
531 */
532
533 cgiCopyTemplateLang("printer.tmpl");
534
535 /*
536 * Show jobs for the specified printer...
537 */
538
539 cgiCopyTemplateLang("printer-jobs-header.tmpl");
540 cgiShowJobs(http, printer);
541 }
542 else
543 {
544 /*
545 * Show the IPP error...
546 */
547
548 cgiStartHTML(printer);
549 cgiShowIPPError(_("Unable to get printer status"));
550 }
551
552 cgiEndHTML();
553 }