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