]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/jobs.c
Fixed support and download links for ESP Print Pro.
[thirdparty/cups.git] / cgi-bin / jobs.c
1 /*
2 * "$Id: jobs.c,v 1.10 1999/11/04 14:57:57 mike Exp $"
3 *
4 * Job status CGI for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-1999 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 * show_job_list() - Show a list of jobs...
28 * show_job_info() - Show job information.
29 */
30
31 /*
32 * Include necessary headers...
33 */
34
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <ctype.h>
38 #include <cups/cups.h>
39 #include <cups/language.h>
40 #include <cups/debug.h>
41 #include <config.h>
42
43
44 /*
45 * Local functions...
46 */
47
48 static void show_job_list(http_t *http, cups_lang_t *language);
49 static void show_job_info(http_t *http, cups_lang_t *language,
50 char *name);
51
52
53 /*
54 * 'main()' - Main entry for CGI.
55 */
56
57 int /* O - Exit status */
58 main(int argc, /* I - Number of command-line arguments */
59 char *argv[]) /* I - Command-line arguments */
60 {
61 cups_lang_t *language; /* Language information */
62 char *job; /* Job name */
63 http_t *http; /* Connection to the server */
64
65
66 /*
67 * Get the request language...
68 */
69
70 language = cupsLangDefault();
71
72 /*
73 * Connect to the HTTP server...
74 */
75
76 http = httpConnect("localhost", ippPort());
77
78 /*
79 * Tell the client to expect HTML...
80 */
81
82 printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
83
84 /*
85 * See if we need to show a list of jobs or the status of a
86 * single job...
87 */
88
89 job = argv[0];
90 if (strcmp(job, "/") == 0 || strcmp(job, "jobs.cgi") == 0)
91 job = NULL;
92
93 /*
94 * Print the standard header...
95 */
96
97 puts("<HTML>");
98 puts("<HEAD>");
99 if (job)
100 puts("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"10\">");
101 else
102 puts("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"30\">");
103 printf("<TITLE>%s on %s - " CUPS_SVERSION "</TITLE>\n",
104 job == NULL ? "Jobs" : job, getenv("SERVER_NAME"));
105 puts("<LINK REL=STYLESHEET TYPE=\"text/css\" HREF=\"/cups.css\">");
106 puts("<MAP NAME=\"navbar\">");
107 #ifdef ESPPRINTPRO
108 puts("<AREA SHAPE=\"RECT\" COORDS=\"10,10,76,30\" HREF=\"/printers\" ALT=\"Current Printer Status\">");
109 puts("<AREA SHAPE=\"RECT\" COORDS=\"88,10,158,30\" HREF=\"/classes\" ALT=\"Current Printer Classes Status\">");
110 puts("<AREA SHAPE=\"RECT\" COORDS=\"170,10,210,30\" HREF=\"jobs\" ALT=\"Current Jobs Status\">");
111 puts("<AREA SHAPE=\"RECT\" COORDS=\"222,10,354,30\" HREF=\"/documentation.html\" ALT=\"Read CUPS Documentation On-Line\">");
112 puts("<AREA SHAPE=\"RECT\" COORDS=\"366,10,442,30\" HREF=\"http://www.easysw.com/software.html\" ALT=\"Download the Current ESP Print Pro Software\">");
113 puts("<AREA SHAPE=\"RECT\" COORDS=\"454,10,530,30\" HREF=\"http://www.easysw.com/support.html\" ALT=\"Get Tech Support for Current ESP Print Pro\">");
114 #else
115 puts("<AREA SHAPE=\"RECT\" COORDS=\"10,10,85,30\" HREF=\"/printers\" ALT=\"Current Printer Status\">");
116 puts("<AREA SHAPE=\"RECT\" COORDS=\"95,10,175,30\" HREF=\"/classes\" ALT=\"Current Printer Classes Status\">");
117 puts("<AREA SHAPE=\"RECT\" COORDS=\"185,10,235,30\" HREF=\"/jobs\" ALT=\"Current Jobs Status\">");
118 puts("<AREA SHAPE=\"RECT\" COORDS=\"245,10,395,30\" HREF=\"/documentation.html\" ALT=\"Read CUPS Documentation On-Line\">");
119 puts("<AREA SHAPE=\"RECT\" COORDS=\"405,10,490,30\" HREF=\"http://www.cups.org\" ALT=\"Download the Current CUPS Software\">");
120 #endif /* ESPPRINTPRO */
121 puts("</MAP>");
122 puts("</HEAD>");
123 puts("<BODY>");
124 puts("<P ALIGN=CENTER>");
125 puts("<A HREF=\"http://www.easysw.com\" ALT=\"Easy Software Products Home Page\">");
126 puts("<IMG SRC=\"/images/logo.gif\" WIDTH=\"71\" HEIGHT=\"40\" BORDER=0 ALT=\"Easy Software Products Home Page\"></A>");
127 puts("<IMG SRC=\"/images/navbar.gif\" WIDTH=\"540\" HEIGHT=\"40\" USEMAP=\"#navbar\" BORDER=0>");
128
129 fflush(stdout);
130
131 /*
132 * Show the information...
133 */
134
135 if (job == NULL)
136 show_job_list(http, language);
137 else
138 show_job_info(http, language, job);
139
140 /*
141 * Write a standard trailer...
142 */
143
144 puts("<HR>");
145
146 puts("<P>The Common UNIX Printing System, CUPS, and the CUPS logo are the");
147 puts("trademark property of <A HREF=\"http://www.easysw.com\">Easy Software");
148 puts("Products</A>. CUPS is copyright 1997-1999 by Easy Software Products,");
149 puts("All Rights Reserved.");
150
151 puts("</BODY>");
152 puts("</HTML>");
153
154 /*
155 * Close the HTTP server connection...
156 */
157
158 httpClose(http);
159 cupsLangFree(language);
160
161 /*
162 * Return with no errors...
163 */
164
165 return (0);
166 }
167
168
169 /*
170 * 'show_job_list()' - Show a list of jobs...
171 */
172
173 static void
174 show_job_list(http_t *http, /* I - HTTP connection */
175 cups_lang_t *language) /* I - Client's language */
176 {
177 ipp_t *request, /* IPP request */
178 *response; /* IPP response */
179 ipp_attribute_t *attr; /* IPP attribute */
180 char *job_uri, /* job-uri */
181 *printer_uri, /* job-printer-uri */
182 *job_name, /* job-name */
183 *job_user; /* job-originating-user-name */
184 int job_id, /* job-id */
185 job_priority, /* job-priority */
186 job_k_octets, /* job-k-octets */
187 copies; /* copies */
188 ipp_jstate_t job_state; /* job-state */
189
190
191 printf("<H1>Jobs on %s</H1>\n", getenv("SERVER_NAME"));
192
193 /*
194 * Build an IPP_GET_JOBS request, which requires the following
195 * attributes:
196 *
197 * attributes-charset
198 * attributes-natural-language
199 * job-uri
200 */
201
202 request = ippNew();
203
204 request->request.op.operation_id = IPP_GET_JOBS;
205 request->request.op.request_id = 1;
206
207 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
208 "attributes-charset", NULL, cupsLangEncoding(language));
209
210 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
211 "attributes-natural-language", NULL, language->language);
212
213 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
214 NULL, "ipp://localhost/jobs/");
215
216 /*
217 * Do the request and get back a response...
218 */
219
220 if ((response = cupsDoRequest(http, request, "/")) != NULL)
221 {
222 /*
223 * Do a table for the jobs...
224 */
225
226 puts("<CENTER>");
227 puts("<TABLE WIDTH=\"90%\" BORDER=\"1\">");
228 puts("<TR>");
229 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_PRINT_JOBS));
230 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_JOB_STATE));
231 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_JOB_NAME));
232 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_USER_NAME));
233 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_PRIORITY));
234 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_COPIES));
235 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_FILE_SIZE));
236 puts("</TR>");
237
238 /*
239 * Loop through the jobs returned in the list and display
240 * their devices...
241 */
242
243 for (attr = response->attrs; attr != NULL; attr = attr->next)
244 {
245 /*
246 * Skip leading attributes until we hit a job...
247 */
248
249 while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
250 attr = attr->next;
251
252 if (attr == NULL)
253 break;
254
255 /*
256 * Show the job status for each job...
257 */
258
259 job_uri = NULL;
260 printer_uri = NULL;
261 job_name = "unknown";
262 job_user = "unknown";
263 job_id = 0;
264 job_priority = 50;
265 job_k_octets = 0;
266 copies = 1;
267 job_state = IPP_JOB_PENDING;
268
269 while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
270 {
271 if (strcmp(attr->name, "job-uri") == 0 &&
272 attr->value_tag == IPP_TAG_URI)
273 job_uri = attr->values[0].string.text;
274
275 if (strcmp(attr->name, "job-printer-uri") == 0 &&
276 attr->value_tag == IPP_TAG_URI)
277 printer_uri = attr->values[0].string.text;
278
279 if (strcmp(attr->name, "job-name") == 0 &&
280 attr->value_tag == IPP_TAG_NAME)
281 job_name = attr->values[0].string.text;
282
283 if (strcmp(attr->name, "job-originating-user-name") == 0 &&
284 attr->value_tag == IPP_TAG_NAME)
285 job_user = attr->values[0].string.text;
286
287 if (strcmp(attr->name, "job-id") == 0 &&
288 attr->value_tag == IPP_TAG_INTEGER)
289 job_id = attr->values[0].integer;
290
291 if (strcmp(attr->name, "job-priority") == 0 &&
292 attr->value_tag == IPP_TAG_INTEGER)
293 job_priority = attr->values[0].integer;
294
295 if (strcmp(attr->name, "job-k-octets") == 0 &&
296 attr->value_tag == IPP_TAG_INTEGER)
297 job_k_octets = attr->values[0].integer;
298
299 if (strcmp(attr->name, "copies") == 0 &&
300 attr->value_tag == IPP_TAG_INTEGER)
301 copies = attr->values[0].integer;
302
303 if (strcmp(attr->name, "job-state") == 0 &&
304 attr->value_tag == IPP_TAG_ENUM)
305 job_state = (ipp_jstate_t)attr->values[0].integer;
306
307 attr = attr->next;
308 }
309
310 /*
311 * See if we have everything needed...
312 */
313
314 if (job_id && job_uri != NULL && printer_uri != NULL)
315 {
316 puts("<TR>");
317 printf("<TD><A HREF=\"http://%s:%s/jobs/%d\">%s-%d</A></TD>\n",
318 getenv("SERVER_NAME"), getenv("SERVER_PORT"), job_id,
319 strrchr(printer_uri, '/') + 1, job_id);
320 printf("<TD>%s</TD>\n", job_state == IPP_JOB_PROCESSING ?
321 cupsLangString(language, CUPS_MSG_PROCESSING) :
322 cupsLangString(language, CUPS_MSG_PENDING));
323 printf("<TD>%s</TD>\n", job_name);
324 printf("<TD>%s</TD>\n", job_user);
325 printf("<TD>%d</TD>\n", job_priority);
326 printf("<TD>%d</TD>\n", copies);
327 printf("<TD>%dk</TD>\n", job_k_octets);
328 puts("</TR>");
329 }
330
331 if (attr == NULL)
332 break;
333 }
334
335 ippDelete(response);
336
337 puts("</TABLE>");
338 puts("</CENTER>");
339 }
340 else
341 puts("<P>No jobs found.");
342 }
343
344
345 /*
346 * 'show_job_info()' - Show job information.
347 */
348
349 static void
350 show_job_info(http_t *http, /* I - Server connection */
351 cups_lang_t *language, /* I - Language */
352 char *name) /* I - Job "name" */
353 {
354 int i; /* Looping var */
355 ipp_t *request, /* IPP request */
356 *response; /* IPP response */
357 ipp_attribute_t *attr; /* IPP attribute */
358 char uri[HTTP_MAX_URI];/* Real URI */
359 char *job_uri, /* job-uri */
360 *printer_uri, /* job-printer-uri */
361 *job_name, /* job-name */
362 *job_user; /* job-originating-user-name */
363 int job_id, /* job-id */
364 job_priority, /* job-priority */
365 job_k_octets; /* job-k-octets */
366 ipp_jstate_t job_state; /* job-state */
367
368
369 /*
370 * Build an IPP_GET_JOB_ATTRIBUTES request, which requires the following
371 * attributes:
372 *
373 * attributes-charset
374 * attributes-natural-language
375 * job-uri
376 */
377
378 request = ippNew();
379
380 request->request.op.operation_id = IPP_GET_JOB_ATTRIBUTES;
381 request->request.op.request_id = 1;
382
383 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
384 "attributes-charset", NULL, cupsLangEncoding(language));
385
386 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
387 "attributes-natural-language", NULL, language->language);
388
389 snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%s", name);
390 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri);
391
392 /*
393 * Do the request and get back a response...
394 */
395
396 if ((response = cupsDoRequest(http, request, "/")) == NULL)
397 {
398 puts("<P>Unable to communicate with CUPS server!");
399 return;
400 }
401
402 if (response->request.status.status_code == IPP_NOT_FOUND)
403 {
404 puts("<P>Job does not exist or has completed.");
405 ippDelete(response);
406 return;
407 }
408
409 /*
410 * Get the job status for this job...
411 */
412
413 if ((attr = ippFindAttribute(response, "job-uri", IPP_TAG_URI)) != NULL)
414 job_uri = attr->values[0].string.text;
415 else
416 {
417 puts("<P>Missing job-uri attribute!");
418 ippDelete(request);
419 return;
420 }
421
422 if ((attr = ippFindAttribute(response, "job-printer-uri", IPP_TAG_URI)) != NULL)
423 printer_uri = attr->values[0].string.text;
424 else
425 {
426 puts("<P>Missing job-printer-uri attribute!");
427 ippDelete(request);
428 return;
429 }
430
431 if ((attr = ippFindAttribute(response, "job-name", IPP_TAG_NAME)) != NULL)
432 job_name = attr->values[0].string.text;
433 else
434 job_name = "unknown";
435
436 if ((attr = ippFindAttribute(response, "job-originating-user-name",
437 IPP_TAG_NAME)) != NULL)
438 job_user = attr->values[0].string.text;
439 else
440 job_user = "unknown";
441
442 if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL)
443 job_id = attr->values[0].integer;
444 else
445 {
446 puts("<P>Missing job-id attribute!");
447 ippDelete(request);
448 return;
449 }
450
451 if ((attr = ippFindAttribute(response, "job-priority", IPP_TAG_INTEGER)) != NULL)
452 job_priority = attr->values[0].integer;
453 else
454 job_priority = 50;
455
456 if ((attr = ippFindAttribute(response, "job-k-octets", IPP_TAG_INTEGER)) != NULL)
457 job_k_octets = attr->values[0].integer;
458 else
459 job_k_octets = 0;
460
461 if ((attr = ippFindAttribute(response, "job-state", IPP_TAG_ENUM)) != NULL)
462 job_state = (ipp_jstate_t)attr->values[0].integer;
463 else
464 job_state = IPP_JOB_PENDING;
465
466 /*
467 * Do a table for the job...
468 */
469
470 printf("<H1><A HREF=\"http://%s:%s/printers/%s\">%s-%d</A></H1>\n",
471 getenv("SERVER_NAME"), getenv("SERVER_PORT"),
472 strrchr(printer_uri, '/') + 1, strrchr(printer_uri, '/') + 1, job_id);
473
474 puts("<CENTER>");
475 puts("<TABLE WIDTH=\"90%\" BORDER=\"1\">");
476
477 puts("<TR>");
478 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_JOB_STATE));
479 printf("<TD>%s</TD>\n", job_state == IPP_JOB_PROCESSING ?
480 cupsLangString(language, CUPS_MSG_PROCESSING) :
481 cupsLangString(language, CUPS_MSG_PENDING));
482 puts("</TR>");
483
484 puts("<TR>");
485 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_JOB_NAME));
486 printf("<TD>%s</TD>\n", job_name);
487 puts("</TR>");
488
489 puts("<TR>");
490 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_USER_NAME));
491 printf("<TD>%s</TD>\n", job_user);
492 puts("</TR>");
493
494 puts("<TR>");
495 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_PRIORITY));
496 printf("<TD>%d</TD>\n", job_priority);
497 puts("</TR>");
498
499 puts("<TR>");
500 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_FILE_SIZE));
501 printf("<TD>%dk</TD>\n", job_k_octets);
502 puts("</TR>");
503
504 puts("<TR VALIGN=\"TOP\">");
505 printf("<TH>%s</TH>\n", cupsLangString(language, CUPS_MSG_OPTIONS));
506 puts("<TD>");
507
508 for (attr = response->attrs; attr != NULL; attr = attr->next)
509 {
510 if (attr->group_tag != IPP_TAG_JOB)
511 continue;
512
513 if (strcmp(attr->name, "job-uri") == 0 ||
514 strcmp(attr->name, "job-printer-uri") == 0 ||
515 strcmp(attr->name, "job-name") == 0 ||
516 strcmp(attr->name, "job-originating-user-name") == 0 ||
517 strcmp(attr->name, "job-id") == 0 ||
518 strcmp(attr->name, "job-priority") == 0 ||
519 strcmp(attr->name, "job-k-octets") == 0 ||
520 strcmp(attr->name, "job-state") == 0)
521 continue;
522
523 if (attr->value_tag != IPP_TAG_BOOLEAN)
524 printf("%s=", attr->name);
525
526 for (i = 0; i < attr->num_values; i ++)
527 {
528 if (i)
529 putchar(',');
530
531 switch (attr->value_tag)
532 {
533 case IPP_TAG_INTEGER :
534 case IPP_TAG_ENUM :
535 printf("%d", attr->values[i].integer);
536 break;
537
538 case IPP_TAG_BOOLEAN :
539 if (!attr->values[i].boolean)
540 printf("no");
541
542 case IPP_TAG_NOVALUE :
543 fputs(attr->name, stdout);
544 break;
545
546 case IPP_TAG_RANGE :
547 printf("%d-%d", attr->values[i].range.lower,
548 attr->values[i].range.upper);
549 break;
550
551 case IPP_TAG_RESOLUTION :
552 printf("%dx%d%s", attr->values[i].resolution.xres,
553 attr->values[i].resolution.yres,
554 attr->values[i].resolution.units == IPP_RES_PER_INCH ?
555 "dpi" : "dpc");
556 break;
557
558 case IPP_TAG_STRING :
559 case IPP_TAG_TEXT :
560 case IPP_TAG_NAME :
561 case IPP_TAG_KEYWORD :
562 case IPP_TAG_CHARSET :
563 case IPP_TAG_LANGUAGE :
564 case IPP_TAG_MIMETYPE :
565 case IPP_TAG_URI :
566 printf("\"%s\"", attr->values[i].string.text);
567 break;
568 }
569 }
570
571 puts("<BR>");
572 }
573
574 puts("</TD>");
575 puts("</TR>");
576 puts("</TABLE></CENTER>");
577
578 ippDelete(response);
579 }
580
581
582 /*
583 * End of "$Id: jobs.c,v 1.10 1999/11/04 14:57:57 mike Exp $".
584 */