2
* "$Id: printers.c 10996 2013-05-29 11:51:34Z msweet $"
4
* Printer status CGI for CUPS.
6
* Copyright 2007-2012 by Apple Inc.
7
* Copyright 1997-2006 by Easy Software Products.
9
* These coded instructions, statements, and computer programs are the
10
* property of Apple Inc. and are protected by Federal copyright
11
* law. Distribution and use rights are outlined in the file "LICENSE.txt"
12
* which should have been included with this file. If this file is
13
* file is missing or damaged, see the license at "http://www.cups.org/".
17
* main() - Main entry for CGI.
18
* do_printer_op() - Do a printer operation.
19
* show_all_printers() - Show all printers...
20
* show_printer() - Show a single printer.
24
* Include necessary headers...
27
#include "cgi-private.h"
35
static void do_printer_op(http_t *http, const char *printer, ipp_op_t op,
37
static void show_all_printers(http_t *http, const char *username);
38
static void show_printer(http_t *http, const char *printer);
42
* 'main()' - Main entry for CGI.
45
int /* O - Exit status */
46
main(int argc, /* I - Number of command-line arguments */
47
char *argv[]) /* I - Command-line arguments */
49
const char *printer; /* Printer name */
50
const char *user; /* Username */
51
http_t *http; /* Connection to the server */
52
ipp_t *request, /* IPP request */
53
*response; /* IPP response */
54
ipp_attribute_t *attr; /* IPP attribute */
55
const char *op; /* Operation to perform, if any */
56
static const char *def_attrs[] = /* Attributes for default printer */
59
"printer-uri-supported"
64
* Get any form variables...
69
op = cgiGetVariable("OP");
72
* Set the web interface section...
75
cgiSetVariable("SECTION", "printers");
76
cgiSetVariable("REFRESH_PAGE", "");
79
* See if we are displaying a printer or all printers...
82
if ((printer = getenv("PATH_INFO")) != NULL)
90
cgiSetVariable("PRINTER_NAME", printer);
94
* See who is logged in...
97
user = getenv("REMOTE_USER");
100
* Connect to the HTTP server...
103
http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
106
* Get the default printer...
109
if (!op || !cgiIsPOST())
112
* Get the default destination...
115
request = ippNewRequest(CUPS_GET_DEFAULT);
117
ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
118
"requested-attributes",
119
sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs);
121
if ((response = cupsDoRequest(http, request, "/")) != NULL)
123
if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
124
cgiSetVariable("DEFAULT_NAME", attr->values[0].string.text);
126
if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
128
char url[HTTP_MAX_URI]; /* New URL */
131
cgiSetVariable("DEFAULT_URI",
132
cgiRewriteURL(attr->values[0].string.text,
133
url, sizeof(url), NULL));
140
* See if we need to show a list of printers or the status of a
145
show_all_printers(http, user);
147
show_printer(http, printer);
153
const char *server_port = getenv("SERVER_PORT");
154
/* Port number string */
155
int port = atoi(server_port ? server_port : "0");
157
char uri[1024]; /* URL */
159
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri),
160
getenv("HTTPS") ? "https" : "http", NULL,
161
getenv("SERVER_NAME"), port, "/printers/%s", printer);
163
printf("Location: %s\n\n", uri);
165
else if (!strcmp(op, "start-printer"))
166
do_printer_op(http, printer, IPP_RESUME_PRINTER,
167
cgiText(_("Resume Printer")));
168
else if (!strcmp(op, "stop-printer"))
169
do_printer_op(http, printer, IPP_PAUSE_PRINTER,
170
cgiText(_("Pause Printer")));
171
else if (!strcmp(op, "accept-jobs"))
172
do_printer_op(http, printer, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs")));
173
else if (!strcmp(op, "reject-jobs"))
174
do_printer_op(http, printer, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs")));
175
else if (!strcmp(op, "purge-jobs"))
176
do_printer_op(http, printer, IPP_PURGE_JOBS, cgiText(_("Purge Jobs")));
177
else if (!_cups_strcasecmp(op, "print-self-test-page"))
178
cgiPrintCommand(http, printer, "PrintSelfTestPage",
179
cgiText(_("Print Self-Test Page")));
180
else if (!_cups_strcasecmp(op, "clean-print-heads"))
181
cgiPrintCommand(http, printer, "Clean all",
182
cgiText(_("Clean Print Heads")));
183
else if (!_cups_strcasecmp(op, "print-test-page"))
184
cgiPrintTestPage(http, printer);
185
else if (!_cups_strcasecmp(op, "move-jobs"))
186
cgiMoveJobs(http, printer, 0);
190
* Unknown/bad operation...
193
cgiStartHTML(printer);
194
cgiCopyTemplateLang("error-op.tmpl");
201
* Unknown/bad operation...
204
cgiStartHTML(cgiText(_("Printers")));
205
cgiCopyTemplateLang("error-op.tmpl");
210
* Close the HTTP server connection...
216
* Return with no errors...
224
* 'do_printer_op()' - Do a printer operation.
228
do_printer_op(http_t *http, /* I - HTTP connection */
229
const char *printer, /* I - Printer name */
230
ipp_op_t op, /* I - Operation to perform */
231
const char *title) /* I - Title of page */
233
ipp_t *request; /* IPP request */
234
char uri[HTTP_MAX_URI], /* Printer URI */
235
resource[HTTP_MAX_URI]; /* Path for request */
239
* Build a printer request, which requires the following
243
* attributes-natural-language
247
request = ippNewRequest(op);
249
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
250
"localhost", 0, "/printers/%s", printer);
251
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
255
* Do the request and get back a response...
258
snprintf(resource, sizeof(resource), "/printers/%s", printer);
259
ippDelete(cupsDoRequest(http, request, resource));
261
if (cupsLastError() == IPP_NOT_AUTHORIZED)
263
puts("Status: 401\n");
266
else if (cupsLastError() > IPP_OK_CONFLICT)
269
cgiShowIPPError(_("Unable to do maintenance command"));
274
* Redirect successful updates back to the printer page...
277
char url[1024], /* Printer/class URL */
278
refresh[1024]; /* Refresh URL */
281
cgiRewriteURL(uri, url, sizeof(url), NULL);
282
cgiFormEncode(uri, url, sizeof(uri));
283
snprintf(refresh, sizeof(refresh), "5;URL=%s", uri);
284
cgiSetVariable("refresh_page", refresh);
288
if (op == IPP_PAUSE_PRINTER)
289
cgiCopyTemplateLang("printer-stop.tmpl");
290
else if (op == IPP_RESUME_PRINTER)
291
cgiCopyTemplateLang("printer-start.tmpl");
292
else if (op == CUPS_ACCEPT_JOBS)
293
cgiCopyTemplateLang("printer-accept.tmpl");
294
else if (op == CUPS_REJECT_JOBS)
295
cgiCopyTemplateLang("printer-reject.tmpl");
296
else if (op == IPP_PURGE_JOBS)
297
cgiCopyTemplateLang("printer-purge.tmpl");
305
* 'show_all_printers()' - Show all printers...
309
show_all_printers(http_t *http, /* I - Connection to server */
310
const char *user) /* I - Username */
312
int i; /* Looping var */
313
ipp_t *request, /* IPP request */
314
*response; /* IPP response */
315
cups_array_t *printers; /* Array of printer objects */
316
ipp_attribute_t *printer; /* Printer object */
317
int ascending, /* Order of printers (0 = descending) */
318
first, /* First printer to show */
319
count; /* Number of printers */
320
const char *var; /* Form variable */
321
void *search; /* Search data */
322
char val[1024]; /* Form variable */
325
fprintf(stderr, "DEBUG: show_all_printers(http=%p, user=\"%s\")\n",
326
http, user ? user : "(null)");
329
* Show the standard header...
332
cgiStartHTML(cgiText(_("Printers")));
335
* Build a CUPS_GET_PRINTERS request, which requires the following
339
* attributes-natural-language
342
* requesting-user-name
345
request = ippNewRequest(CUPS_GET_PRINTERS);
347
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
349
ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
350
"printer-type-mask", CUPS_PRINTER_CLASS);
353
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
354
"requesting-user-name", NULL, user);
356
cgiGetAttributes(request, "printers.tmpl");
359
* Do the request and get back a response...
362
if ((response = cupsDoRequest(http, request, "/")) != NULL)
365
* Get a list of matching job objects.
368
if ((var = cgiGetVariable("QUERY")) != NULL &&
369
!cgiGetVariable("CLEAR"))
370
search = cgiCompileSearch(var);
374
printers = cgiGetIPPObjects(response, search);
375
count = cupsArrayCount(printers);
378
cgiFreeSearch(search);
381
* Figure out which printers to display...
384
if ((var = cgiGetVariable("FIRST")) != NULL)
390
first = count - CUPS_PAGE_MAX;
392
first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX;
397
sprintf(val, "%d", count);
398
cgiSetVariable("TOTAL", val);
400
if ((var = cgiGetVariable("ORDER")) != NULL && *var)
401
ascending = !_cups_strcasecmp(var, "asc");
407
for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first);
408
i < CUPS_PAGE_MAX && printer;
409
i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers))
410
cgiSetIPPObjectVars(printer, NULL, i);
414
for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1);
415
i < CUPS_PAGE_MAX && printer;
416
i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers))
417
cgiSetIPPObjectVars(printer, NULL, i);
421
* Save navigation URLs...
424
cgiSetVariable("THISURL", "/printers/");
428
sprintf(val, "%d", first - CUPS_PAGE_MAX);
429
cgiSetVariable("PREV", val);
432
if ((first + CUPS_PAGE_MAX) < count)
434
sprintf(val, "%d", first + CUPS_PAGE_MAX);
435
cgiSetVariable("NEXT", val);
439
* Then show everything...
442
cgiCopyTemplateLang("search.tmpl");
444
cgiCopyTemplateLang("printers-header.tmpl");
446
if (count > CUPS_PAGE_MAX)
447
cgiCopyTemplateLang("pager.tmpl");
449
cgiCopyTemplateLang("printers.tmpl");
451
if (count > CUPS_PAGE_MAX)
452
cgiCopyTemplateLang("pager.tmpl");
455
* Delete the response...
458
cupsArrayDelete(printers);
467
cgiShowIPPError(_("Unable to get printer list"));
475
* 'show_printer()' - Show a single printer.
479
show_printer(http_t *http, /* I - Connection to server */
480
const char *printer) /* I - Name of printer */
482
ipp_t *request, /* IPP request */
483
*response; /* IPP response */
484
ipp_attribute_t *attr; /* IPP attribute */
485
char uri[HTTP_MAX_URI]; /* Printer URI */
486
char refresh[1024]; /* Refresh URL */
489
fprintf(stderr, "DEBUG: show_printer(http=%p, printer=\"%s\")\n",
490
http, printer ? printer : "(null)");
493
* Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
497
* attributes-natural-language
501
request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
503
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
504
"localhost", 0, "/printers/%s", printer);
505
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL,
508
cgiGetAttributes(request, "printer.tmpl");
511
* Do the request and get back a response...
514
if ((response = cupsDoRequest(http, request, "/")) != NULL)
517
* Got the result; set the CGI variables and check the status of a
518
* single-queue request...
521
cgiSetIPPVars(response, NULL, NULL, NULL, 0);
523
if (printer && (attr = ippFindAttribute(response, "printer-state",
524
IPP_TAG_ENUM)) != NULL &&
525
attr->values[0].integer == IPP_PRINTER_PROCESSING)
528
* Printer is processing - automatically refresh the page until we
529
* are done printing...
532
cgiFormEncode(uri, printer, sizeof(uri));
533
snprintf(refresh, sizeof(refresh), "10;URL=/printers/%s", uri);
534
cgiSetVariable("refresh_page", refresh);
538
* Delete the response...
544
* Show the standard header...
547
cgiStartHTML(printer);
550
* Show the printer status...
553
cgiCopyTemplateLang("printer.tmpl");
556
* Show jobs for the specified printer...
559
cgiCopyTemplateLang("printer-jobs-header.tmpl");
560
cgiShowJobs(http, printer);
565
* Show the IPP error...
568
cgiStartHTML(printer);
569
cgiShowIPPError(_("Unable to get printer status"));
577
* End of "$Id: printers.c 10996 2013-05-29 11:51:34Z msweet $".