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