]> git.ipfire.org Git - thirdparty/cups.git/blob - cgi-bin/classes.c
Fixed support and download links for ESP Print Pro.
[thirdparty/cups.git] / cgi-bin / classes.c
1 /*
2 * "$Id: classes.c,v 1.11 1999/11/04 14:57:57 mike Exp $"
3 *
4 * Class 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_class_list() - Show a list of classes...
28 * show_class_info() - Show class 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_class_list(http_t *http, cups_lang_t *language);
49 static void show_class_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 *name; /* Class 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 classes or the status of a
86 * single class...
87 */
88
89 name = argv[0];
90 if (strcmp(name, "/") == 0 || strcmp(name, "classes.cgi") == 0)
91 name = NULL;
92
93 /*
94 * Print the standard header...
95 */
96
97 puts("<HTML>");
98 puts("<HEAD>");
99 if (name)
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 name == NULL ? "Classes" : name, 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 printf("<H1>%s on %s</H1>\n", name == NULL ? "Classes" : name,
130 getenv("SERVER_NAME"));
131 fflush(stdout);
132
133 puts("<CENTER>");
134 puts("<TABLE WIDTH=\"90%\" BORDER=\"1\">");
135 puts("<TR>");
136 puts("<TH>Name</TH>");
137 puts("<TH WIDTH=\"50%\">Status</TH>");
138 puts("<TH WIDTH=\"25%\">Jobs</TH>");
139 puts("</TR>");
140
141 /*
142 * Show the information...
143 */
144
145 if (name == NULL)
146 show_class_list(http, language);
147 else
148 show_class_info(http, language, name);
149
150 /*
151 * Write a standard trailer...
152 */
153
154 puts("</TABLE>");
155 puts("</CENTER>");
156
157 puts("<HR>");
158
159 puts("<P>The Common UNIX Printing System, CUPS, and the CUPS logo are the");
160 puts("trademark property of <A HREF=\"http://www.easysw.com\">Easy Software");
161 puts("Products</A>. CUPS is copyright 1997-1999 by Easy Software Products,");
162 puts("All Rights Reserved.");
163
164 puts("</BODY>");
165 puts("</HTML>");
166
167 /*
168 * Close the HTTP server connection...
169 */
170
171 httpClose(http);
172 cupsLangFree(language);
173
174 /*
175 * Return with no errors...
176 */
177
178 return (0);
179 }
180
181
182 /*
183 * 'show_class_list()' - Show a list of classes...
184 */
185
186 static void
187 show_class_list(http_t *http, /* I - HTTP connection */
188 cups_lang_t *language)/* I - Client's language */
189 {
190 ipp_t *request, /* IPP request */
191 *response; /* IPP response */
192 ipp_attribute_t *attr; /* IPP attribute */
193
194
195 /*
196 * Build a CUPS_GET_CLASSES request, which requires the following
197 * attributes:
198 *
199 * attributes-charset
200 * attributes-natural-language
201 */
202
203 request = ippNew();
204
205 request->request.op.operation_id = CUPS_GET_CLASSES;
206 request->request.op.request_id = 1;
207
208
209 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
210 "attributes-charset", NULL, cupsLangEncoding(language));
211
212 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
213 "attributes-natural-language", NULL, language->language);
214
215 /*
216 * Do the request and get back a response...
217 */
218
219 if ((response = cupsDoRequest(http, request, "/")) != NULL)
220 {
221 /*
222 * Loop through the classes returned in the list and display
223 * their devices...
224 */
225
226 for (attr = response->attrs; attr != NULL; attr = attr->next)
227 {
228 /*
229 * Skip leading attributes until we hit a job...
230 */
231
232 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
233 attr = attr->next;
234
235 if (attr == NULL)
236 break;
237
238 /*
239 * Show the class status for each class...
240 */
241
242 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
243 {
244 if (strcmp(attr->name, "printer-name") == 0 &&
245 attr->value_tag == IPP_TAG_NAME)
246 show_class_info(http, language, attr->values[0].string.text);
247
248 attr = attr->next;
249 }
250
251 if (attr == NULL)
252 break;
253 }
254
255 ippDelete(response);
256 }
257 }
258
259
260 /*
261 * 'show_class_info()' - Show class information.
262 */
263
264 static void
265 show_class_info(http_t *http,
266 cups_lang_t *language,
267 char *name)
268 {
269 ipp_t *request, /* IPP request */
270 *response, /* IPP response */
271 *jobs; /* IPP Get Jobs response */
272 int jobcount; /* Number of jobs */
273 ipp_attribute_t *attr; /* IPP attribute */
274 char *message; /* Printer state message */
275 int accepting; /* Accepting requests? */
276 ipp_pstate_t pstate; /* Printer state */
277 char uri[HTTP_MAX_URI];/* Printer URI */
278
279
280 /*
281 * Build a IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
282 * attributes:
283 *
284 * attributes-charset
285 * attributes-natural-language
286 * printer-uri
287 */
288
289 request = ippNew();
290
291 request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
292 request->request.op.request_id = 1;
293
294 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
295 "attributes-charset", NULL, cupsLangEncoding(language));
296
297 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
298 "attributes-natural-language", NULL, language->language);
299
300 snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", name);
301
302 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri);
303
304 /*
305 * Do the request and get back a response...
306 */
307
308 if ((response = cupsDoRequest(http, request, "/")) == NULL)
309 {
310 puts("<P>Unable to communicate with CUPS server!");
311 return;
312 }
313
314 if (response->request.status.status_code == IPP_NOT_FOUND)
315 {
316 puts("<P>Class does not exist.");
317 ippDelete(response);
318 return;
319 }
320
321 /*
322 * Grab the needed class attributes...
323 */
324
325 if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
326 pstate = (ipp_pstate_t)attr->values[0].integer;
327 else
328 pstate = IPP_PRINTER_IDLE;
329
330 if ((attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT)) != NULL)
331 message = attr->values[0].string.text;
332 else
333 message = NULL;
334
335 if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs",
336 IPP_TAG_BOOLEAN)) != NULL)
337 accepting = attr->values[0].boolean;
338 else
339 accepting = 1;
340
341 if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL)
342 {
343 strcpy(uri, "http:");
344 strncpy(uri + 5, strchr(attr->values[0].string.text, '/'), sizeof(uri) - 6);
345 uri[sizeof(uri) - 1] = '\0';
346 }
347
348 /*
349 * Display the class entry...
350 */
351
352 puts("<TR>");
353
354 printf("<TD VALIGN=TOP><A HREF=\"%s\">%s</A></TD>\n", uri, name);
355
356 puts("<TD VALIGN=TOP><IMG SRC=\"/images/classes.gif\" ALIGN=\"LEFT\">");
357
358 printf("%s: %s, %s<BR>\n",
359 cupsLangString(language, CUPS_MSG_PRINTER_STATE),
360 cupsLangString(language, pstate == IPP_PRINTER_IDLE ? CUPS_MSG_IDLE :
361 pstate == IPP_PRINTER_PROCESSING ?
362 CUPS_MSG_PROCESSING : CUPS_MSG_STOPPED),
363 cupsLangString(language, accepting ? CUPS_MSG_ACCEPTING_JOBS :
364 CUPS_MSG_NOT_ACCEPTING_JOBS));
365
366 if (message)
367 printf("<BR CLEAR=ALL><I>\"%s\"</I>\n", message);
368 else if (!accepting || pstate == IPP_PRINTER_STOPPED)
369 puts("<BR CLEAR=ALL><I>\"Reason Unknown\"</I>");
370
371 puts("</TD>");
372
373 /*
374 * Show a list of jobs as needed...
375 */
376
377 if (pstate != IPP_PRINTER_IDLE)
378 {
379 /*
380 * Build an IPP_GET_JOBS request, which requires the following
381 * attributes:
382 *
383 * attributes-charset
384 * attributes-natural-language
385 * printer-uri
386 */
387
388 request = ippNew();
389
390 request->request.op.operation_id = IPP_GET_JOBS;
391 request->request.op.request_id = 1;
392
393 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
394 "attributes-charset", NULL,
395 cupsLangEncoding(language));
396
397 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
398 "attributes-natural-language", NULL,
399 language->language);
400
401 snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", name);
402 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
403 "printer-uri", NULL, uri);
404
405 jobs = cupsDoRequest(http, request, "/");
406 }
407 else
408 jobs = NULL;
409
410 puts("<TD VALIGN=\"TOP\">");
411 jobcount = 0;
412
413 if (jobs != NULL)
414 {
415 char *username; /* Pointer to job-originating-user-name */
416 int jobid, /* job-id */
417 size; /* job-k-octets */
418
419
420 for (attr = jobs->attrs; attr != NULL; attr = attr->next)
421 {
422 /*
423 * Skip leading attributes until we hit a job...
424 */
425
426 while (attr != NULL && attr->group_tag != IPP_TAG_JOB)
427 attr = attr->next;
428
429 if (attr == NULL)
430 break;
431
432 /*
433 * Pull the needed attributes from this job...
434 */
435
436 jobid = 0;
437 size = 0;
438 username = NULL;
439
440 while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
441 {
442 if (strcmp(attr->name, "job-id") == 0 &&
443 attr->value_tag == IPP_TAG_INTEGER)
444 jobid = attr->values[0].integer;
445
446 if (strcmp(attr->name, "job-k-octets") == 0 &&
447 attr->value_tag == IPP_TAG_INTEGER)
448 size = attr->values[0].integer;
449
450 if (strcmp(attr->name, "job-originating-user-name") == 0 &&
451 attr->value_tag == IPP_TAG_NAME)
452 username = attr->values[0].string.text;
453
454 attr = attr->next;
455 }
456
457 /*
458 * Display the job if it matches the current class...
459 */
460
461 if (username != NULL)
462 {
463 jobcount ++;
464 printf("<A HREF=\"/jobs/%d\">%s-%d %s %dk</A><BR>\n", jobid, name,
465 jobid, username, size);
466 }
467
468 if (attr == NULL)
469 break;
470 }
471
472 ippDelete(jobs);
473 }
474
475 if (jobcount == 0)
476 puts("None");
477 puts("</TD>");
478 puts("</TR>");
479
480 ippDelete(response);
481 }
482
483
484 /*
485 * End of "$Id: classes.c,v 1.11 1999/11/04 14:57:57 mike Exp $".
486 */