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