2 * "$Id: classes.c,v 1.11 1999/11/04 14:57:57 mike Exp $"
4 * Class status CGI for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-1999 by Easy Software Products.
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
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636-3111 USA
20 * Voice: (301) 373-9603
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * main() - Main entry for CGI.
27 * show_class_list() - Show a list of classes...
28 * show_class_info() - Show class information.
32 * Include necessary headers...
38 #include <cups/cups.h>
39 #include <cups/language.h>
40 #include <cups/debug.h>
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
,
54 * 'main()' - Main entry for CGI.
57 int /* O - Exit status */
58 main(int argc
, /* I - Number of command-line arguments */
59 char *argv
[]) /* I - Command-line arguments */
61 cups_lang_t
*language
; /* Language information */
62 char *name
; /* Class name */
63 http_t
*http
; /* Connection to the server */
67 * Get the request language...
70 language
= cupsLangDefault();
73 * Connect to the HTTP server...
76 http
= httpConnect("localhost", ippPort());
79 * Tell the client to expect HTML...
82 printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language
));
85 * See if we need to show a list of classes or the status of a
90 if (strcmp(name
, "/") == 0 || strcmp(name
, "classes.cgi") == 0)
94 * Print the standard header...
100 puts("<META HTTP-EQUIV=\"Refresh\" CONTENT=\"10\">");
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\">");
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\">");
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 */
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>");
129 printf("<H1>%s on %s</H1>\n", name
== NULL
? "Classes" : name
,
130 getenv("SERVER_NAME"));
134 puts("<TABLE WIDTH=\"90%\" BORDER=\"1\">");
136 puts("<TH>Name</TH>");
137 puts("<TH WIDTH=\"50%\">Status</TH>");
138 puts("<TH WIDTH=\"25%\">Jobs</TH>");
142 * Show the information...
146 show_class_list(http
, language
);
148 show_class_info(http
, language
, name
);
151 * Write a standard trailer...
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.");
168 * Close the HTTP server connection...
172 cupsLangFree(language
);
175 * Return with no errors...
183 * 'show_class_list()' - Show a list of classes...
187 show_class_list(http_t
*http
, /* I - HTTP connection */
188 cups_lang_t
*language
)/* I - Client's language */
190 ipp_t
*request
, /* IPP request */
191 *response
; /* IPP response */
192 ipp_attribute_t
*attr
; /* IPP attribute */
196 * Build a CUPS_GET_CLASSES request, which requires the following
200 * attributes-natural-language
205 request
->request
.op
.operation_id
= CUPS_GET_CLASSES
;
206 request
->request
.op
.request_id
= 1;
209 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_CHARSET
,
210 "attributes-charset", NULL
, cupsLangEncoding(language
));
212 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_LANGUAGE
,
213 "attributes-natural-language", NULL
, language
->language
);
216 * Do the request and get back a response...
219 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
222 * Loop through the classes returned in the list and display
226 for (attr
= response
->attrs
; attr
!= NULL
; attr
= attr
->next
)
229 * Skip leading attributes until we hit a job...
232 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_PRINTER
)
239 * Show the class status for each class...
242 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_PRINTER
)
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
);
261 * 'show_class_info()' - Show class information.
265 show_class_info(http_t
*http
,
266 cups_lang_t
*language
,
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 */
281 * Build a IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
285 * attributes-natural-language
291 request
->request
.op
.operation_id
= IPP_GET_PRINTER_ATTRIBUTES
;
292 request
->request
.op
.request_id
= 1;
294 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_CHARSET
,
295 "attributes-charset", NULL
, cupsLangEncoding(language
));
297 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_LANGUAGE
,
298 "attributes-natural-language", NULL
, language
->language
);
300 snprintf(uri
, sizeof(uri
), "ipp://localhost/classes/%s", name
);
302 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri", NULL
, uri
);
305 * Do the request and get back a response...
308 if ((response
= cupsDoRequest(http
, request
, "/")) == NULL
)
310 puts("<P>Unable to communicate with CUPS server!");
314 if (response
->request
.status
.status_code
== IPP_NOT_FOUND
)
316 puts("<P>Class does not exist.");
322 * Grab the needed class attributes...
325 if ((attr
= ippFindAttribute(response
, "printer-state", IPP_TAG_ENUM
)) != NULL
)
326 pstate
= (ipp_pstate_t
)attr
->values
[0].integer
;
328 pstate
= IPP_PRINTER_IDLE
;
330 if ((attr
= ippFindAttribute(response
, "printer-state-message", IPP_TAG_TEXT
)) != NULL
)
331 message
= attr
->values
[0].string
.text
;
335 if ((attr
= ippFindAttribute(response
, "printer-is-accepting-jobs",
336 IPP_TAG_BOOLEAN
)) != NULL
)
337 accepting
= attr
->values
[0].boolean
;
341 if ((attr
= ippFindAttribute(response
, "printer-uri-supported", IPP_TAG_URI
)) != NULL
)
343 strcpy(uri
, "http:");
344 strncpy(uri
+ 5, strchr(attr
->values
[0].string
.text
, '/'), sizeof(uri
) - 6);
345 uri
[sizeof(uri
) - 1] = '\0';
349 * Display the class entry...
354 printf("<TD VALIGN=TOP><A HREF=\"%s\">%s</A></TD>\n", uri
, name
);
356 puts("<TD VALIGN=TOP><IMG SRC=\"/images/classes.gif\" ALIGN=\"LEFT\">");
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
));
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>");
374 * Show a list of jobs as needed...
377 if (pstate
!= IPP_PRINTER_IDLE
)
380 * Build an IPP_GET_JOBS request, which requires the following
384 * attributes-natural-language
390 request
->request
.op
.operation_id
= IPP_GET_JOBS
;
391 request
->request
.op
.request_id
= 1;
393 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_CHARSET
,
394 "attributes-charset", NULL
,
395 cupsLangEncoding(language
));
397 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_LANGUAGE
,
398 "attributes-natural-language", NULL
,
401 snprintf(uri
, sizeof(uri
), "ipp://localhost/printers/%s", name
);
402 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
,
403 "printer-uri", NULL
, uri
);
405 jobs
= cupsDoRequest(http
, request
, "/");
410 puts("<TD VALIGN=\"TOP\">");
415 char *username
; /* Pointer to job-originating-user-name */
416 int jobid
, /* job-id */
417 size
; /* job-k-octets */
420 for (attr
= jobs
->attrs
; attr
!= NULL
; attr
= attr
->next
)
423 * Skip leading attributes until we hit a job...
426 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_JOB
)
433 * Pull the needed attributes from this job...
440 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_JOB
)
442 if (strcmp(attr
->name
, "job-id") == 0 &&
443 attr
->value_tag
== IPP_TAG_INTEGER
)
444 jobid
= attr
->values
[0].integer
;
446 if (strcmp(attr
->name
, "job-k-octets") == 0 &&
447 attr
->value_tag
== IPP_TAG_INTEGER
)
448 size
= attr
->values
[0].integer
;
450 if (strcmp(attr
->name
, "job-originating-user-name") == 0 &&
451 attr
->value_tag
== IPP_TAG_NAME
)
452 username
= attr
->values
[0].string
.text
;
458 * Display the job if it matches the current class...
461 if (username
!= NULL
)
464 printf("<A HREF=\"/jobs/%d\">%s-%d %s %dk</A><BR>\n", jobid
, name
,
465 jobid
, username
, size
);
485 * End of "$Id: classes.c,v 1.11 1999/11/04 14:57:57 mike Exp $".