]>
Commit | Line | Data |
---|---|---|
f8ab8b97 | 1 | /* |
4e243213 | 2 | * "$Id: lpq.c,v 1.8 2000/02/24 15:20:18 mike Exp $" |
f8ab8b97 | 3 | * |
4 | * "lpq" command for the Common UNIX Printing System (CUPS). | |
5 | * | |
71fe22b7 | 6 | * Copyright 1997-2000 by Easy Software Products. |
f8ab8b97 | 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 | * | |
bf56a667 | 26 | * main() - Parse options and commands. |
27 | * show_jobs() - Show jobs. | |
f8ab8b97 | 28 | */ |
29 | ||
30 | /* | |
31 | * Include necessary headers... | |
32 | */ | |
33 | ||
34 | /* | |
35 | * Include necessary headers... | |
36 | */ | |
37 | ||
38 | #include <stdio.h> | |
39 | #include <stdlib.h> | |
40 | #include <ctype.h> | |
41 | #include <cups/cups.h> | |
42 | #include <cups/language.h> | |
43 | #include <cups/debug.h> | |
44 | ||
45 | ||
46 | /* | |
47 | * Local functions... | |
48 | */ | |
49 | ||
bf56a667 | 50 | static int show_jobs(http_t *, const char *, const char *, const int, |
51 | const int); | |
4e243213 | 52 | static void show_printer(http_t *, const char *); |
f8ab8b97 | 53 | |
54 | ||
55 | /* | |
56 | * 'main()' - Parse options and commands. | |
57 | */ | |
58 | ||
59 | int | |
60 | main(int argc, /* I - Number of command-line arguments */ | |
61 | char *argv[]) /* I - Command-line arguments */ | |
62 | { | |
63 | int i; /* Looping var */ | |
64 | http_t *http; /* Connection to server */ | |
bf56a667 | 65 | const char *dest, /* Desired printer */ |
f8ab8b97 | 66 | *user; /* Desired user */ |
67 | int id, /* Desired job ID */ | |
68 | interval, /* Reporting interval */ | |
69 | longstatus; /* Show file details */ | |
70 | ||
71 | /* | |
72 | * Connect to the scheduler... | |
73 | */ | |
74 | ||
56b5b8ca | 75 | http = httpConnect(cupsServer(), ippPort()); |
f8ab8b97 | 76 | |
77 | /* | |
78 | * Check for command-line options... | |
79 | */ | |
80 | ||
bf56a667 | 81 | dest = cupsGetDefault(); |
f8ab8b97 | 82 | user = NULL; |
83 | id = 0; | |
84 | interval = 0; | |
85 | longstatus = 0; | |
86 | ||
87 | for (i = 1; i < argc; i ++) | |
88 | if (argv[i][0] == '+') | |
89 | interval = atoi(argv[i] + 1); | |
90 | else if (argv[i][0] == '-') | |
91 | { | |
92 | switch (argv[i][1]) | |
93 | { | |
94 | case 'P' : /* Printer */ | |
95 | if (argv[i][2]) | |
96 | dest = argv[i] + 2; | |
97 | else | |
98 | { | |
99 | i ++; | |
100 | dest = argv[i]; | |
101 | } | |
102 | break; | |
103 | ||
104 | case 'l' : /* Long status */ | |
105 | longstatus = 1; | |
106 | break; | |
107 | ||
108 | default : | |
109 | fputs("Usage: lpq [-P dest] [-l] [+interval]\n", stderr); | |
110 | return (1); | |
111 | } | |
112 | } | |
113 | else if (isdigit(argv[i][0])) | |
114 | id = atoi(argv[i]); | |
115 | else | |
116 | user = argv[i]; | |
117 | ||
118 | /* | |
119 | * Show the status in a loop... | |
120 | */ | |
121 | ||
122 | for (;;) | |
123 | { | |
4e243213 | 124 | if (dest) |
125 | show_printer(http, dest); | |
126 | ||
f8ab8b97 | 127 | i = show_jobs(http, dest, user, id, longstatus); |
128 | ||
129 | if (i && interval) | |
4e243213 | 130 | { |
131 | fflush(stdout); | |
f8ab8b97 | 132 | sleep(interval); |
4e243213 | 133 | } |
f8ab8b97 | 134 | else |
135 | break; | |
136 | } | |
137 | ||
138 | /* | |
139 | * Close the connection to the server and return... | |
140 | */ | |
141 | ||
142 | httpClose(http); | |
143 | ||
144 | return (0); | |
145 | } | |
146 | ||
147 | ||
148 | /* | |
bf56a667 | 149 | * 'show_jobs()' - Show jobs. |
f8ab8b97 | 150 | */ |
151 | ||
152 | static int /* O - Number of jobs in queue */ | |
bf56a667 | 153 | show_jobs(http_t *http, /* I - HTTP connection to server */ |
154 | const char *dest, /* I - Destination */ | |
155 | const char *user, /* I - User */ | |
156 | const int id, /* I - Job ID */ | |
157 | const int longstatus)/* I - 1 if long report desired */ | |
f8ab8b97 | 158 | { |
159 | ipp_t *request, /* IPP Request */ | |
160 | *response; /* IPP Response */ | |
161 | ipp_attribute_t *attr; /* Current attribute */ | |
162 | cups_lang_t *language; /* Default language */ | |
bf56a667 | 163 | const char *jobdest, /* Pointer into job-printer-uri */ |
f8ab8b97 | 164 | *jobuser, /* Pointer to job-originating-user-name */ |
165 | *jobname; /* Pointer to job-name */ | |
166 | ipp_jstate_t jobstate; /* job-state */ | |
167 | int jobid, /* job-id */ | |
168 | jobsize, /* job-k-octets */ | |
169 | jobpriority, /* job-priority */ | |
170 | jobcount, /* Number of jobs */ | |
4e243213 | 171 | jobcopies, /* Number of copies */ |
f8ab8b97 | 172 | rank; /* Rank of job */ |
173 | char resource[1024]; /* Resource string */ | |
4e243213 | 174 | char rankstr[255]; /* Rank string */ |
175 | char namestr[1024]; /* Job name string */ | |
bf56a667 | 176 | static const char *ranks[10] =/* Ranking strings */ |
f8ab8b97 | 177 | { |
178 | "th", | |
179 | "st", | |
180 | "nd", | |
181 | "rd", | |
182 | "th", | |
183 | "th", | |
184 | "th", | |
185 | "th", | |
186 | "th", | |
187 | "th" | |
188 | }; | |
189 | ||
190 | ||
191 | DEBUG_printf(("show_jobs(%08x, %08x, %08x, %d, %d)\n", http, dest, user, id, | |
192 | longstatus)); | |
193 | ||
194 | if (http == NULL) | |
74045830 | 195 | return (0); |
f8ab8b97 | 196 | |
197 | /* | |
198 | * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires | |
199 | * the following attributes: | |
200 | * | |
201 | * attributes-charset | |
202 | * attributes-natural-language | |
203 | * job-uri or printer-uri | |
f8ab8b97 | 204 | */ |
205 | ||
206 | request = ippNew(); | |
207 | ||
208 | request->request.op.operation_id = id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS; | |
209 | request->request.op.request_id = 1; | |
210 | ||
211 | language = cupsLangDefault(); | |
212 | ||
213 | attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, | |
214 | "attributes-charset", NULL, cupsLangEncoding(language)); | |
215 | ||
216 | attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
217 | "attributes-natural-language", NULL, language->language); | |
218 | ||
219 | if (dest == NULL) | |
220 | { | |
221 | if (id) | |
222 | sprintf(resource, "ipp://localhost/jobs/%d", id); | |
223 | else | |
224 | strcpy(resource, "ipp://localhost/jobs"); | |
225 | ||
226 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", | |
227 | NULL, resource); | |
228 | } | |
229 | else | |
230 | { | |
970017a4 | 231 | snprintf(resource, sizeof(resource), "ipp://localhost/printers/%s", dest); |
f8ab8b97 | 232 | |
233 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", | |
234 | NULL, resource); | |
235 | } | |
236 | ||
237 | if (user) | |
238 | { | |
239 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, | |
240 | "requesting-user-name", NULL, user); | |
241 | ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); | |
242 | } | |
243 | ||
244 | /* | |
245 | * Do the request and get back a response... | |
246 | */ | |
247 | ||
f8ab8b97 | 248 | jobcount = 0; |
249 | ||
250 | if ((response = cupsDoRequest(http, request, "/jobs/")) != NULL) | |
251 | { | |
4e243213 | 252 | if (response->request.status.status_code > IPP_OK_CONFLICT) |
253 | { | |
254 | fprintf(stderr, "lpq: get-jobs failed: %s\n", | |
255 | ippErrorString(response->request.status.status_code)); | |
256 | ippDelete(response); | |
257 | return (0); | |
258 | } | |
259 | ||
f8ab8b97 | 260 | rank = 1; |
261 | ||
262 | /* | |
263 | * Loop through the job list and display them... | |
264 | */ | |
265 | ||
266 | for (attr = response->attrs; attr != NULL; attr = attr->next) | |
267 | { | |
268 | /* | |
269 | * Skip leading attributes until we hit a job... | |
270 | */ | |
271 | ||
272 | while (attr != NULL && attr->group_tag != IPP_TAG_JOB) | |
273 | attr = attr->next; | |
274 | ||
275 | if (attr == NULL) | |
276 | break; | |
277 | ||
278 | /* | |
279 | * Pull the needed attributes from this job... | |
280 | */ | |
281 | ||
282 | jobid = 0; | |
283 | jobsize = 0; | |
284 | jobpriority = 50; | |
285 | jobstate = IPP_JOB_PENDING; | |
286 | jobname = "untitled"; | |
287 | jobuser = NULL; | |
288 | jobdest = NULL; | |
4e243213 | 289 | jobcopies = 1; |
f8ab8b97 | 290 | |
291 | while (attr != NULL && attr->group_tag == IPP_TAG_JOB) | |
292 | { | |
293 | if (strcmp(attr->name, "job-id") == 0 && | |
294 | attr->value_tag == IPP_TAG_INTEGER) | |
295 | jobid = attr->values[0].integer; | |
296 | ||
297 | if (strcmp(attr->name, "job-k-octets") == 0 && | |
298 | attr->value_tag == IPP_TAG_INTEGER) | |
299 | jobsize = attr->values[0].integer * 1024; | |
300 | ||
301 | if (strcmp(attr->name, "job-priority") == 0 && | |
302 | attr->value_tag == IPP_TAG_INTEGER) | |
303 | jobpriority = attr->values[0].integer; | |
304 | ||
305 | if (strcmp(attr->name, "job-state") == 0 && | |
306 | attr->value_tag == IPP_TAG_ENUM) | |
307 | jobstate = (ipp_jstate_t)attr->values[0].integer; | |
308 | ||
309 | if (strcmp(attr->name, "job-printer-uri") == 0 && | |
310 | attr->value_tag == IPP_TAG_URI) | |
311 | if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) | |
312 | jobdest ++; | |
313 | ||
314 | if (strcmp(attr->name, "job-originating-user-name") == 0 && | |
315 | attr->value_tag == IPP_TAG_NAME) | |
316 | jobuser = attr->values[0].string.text; | |
317 | ||
318 | if (strcmp(attr->name, "job-name") == 0 && | |
319 | attr->value_tag == IPP_TAG_NAME) | |
320 | jobname = attr->values[0].string.text; | |
321 | ||
4e243213 | 322 | if (strcmp(attr->name, "copies") == 0 && |
323 | attr->value_tag == IPP_TAG_INTEGER) | |
324 | jobcopies = attr->values[0].integer; | |
325 | ||
f8ab8b97 | 326 | attr = attr->next; |
327 | } | |
328 | ||
329 | /* | |
330 | * See if we have everything needed... | |
331 | */ | |
332 | ||
333 | if (jobdest == NULL || jobid == 0) | |
334 | { | |
335 | if (attr == NULL) | |
336 | break; | |
337 | else | |
338 | continue; | |
339 | } | |
340 | ||
4e243213 | 341 | if (!longstatus && jobcount == 0) |
342 | puts("Rank Owner Job Files Total Size"); | |
343 | ||
f8ab8b97 | 344 | jobcount ++; |
345 | ||
346 | /* | |
347 | * Display the job... | |
348 | */ | |
349 | ||
4e243213 | 350 | if (jobstate == IPP_JOB_PROCESSING) |
351 | strcpy(rankstr, "active"); | |
352 | else | |
353 | { | |
354 | sprintf(rankstr, "%d%s\t", rank, ranks[rank % 10]); | |
355 | rank ++; | |
356 | } | |
357 | ||
f8ab8b97 | 358 | if (longstatus) |
359 | { | |
360 | puts(""); | |
361 | ||
4e243213 | 362 | if (jobcopies > 1) |
363 | sprintf(namestr, "%d copies of %s", jobcopies, jobname); | |
f8ab8b97 | 364 | else |
4e243213 | 365 | strcpy(namestr, jobname); |
f8ab8b97 | 366 | |
4e243213 | 367 | printf("%s: %-31s [job %d localhost]\n", jobuser, rankstr, jobid); |
368 | printf(" %-31.31s %d bytes\n", namestr, jobsize); | |
f8ab8b97 | 369 | } |
370 | else | |
4e243213 | 371 | printf("%-6s %-10.10s %-15d %-27.27s %d bytes\n", rankstr, jobuser, |
9ad819c3 | 372 | jobid, jobname, jobsize); |
4e243213 | 373 | |
f8ab8b97 | 374 | if (attr == NULL) |
375 | break; | |
376 | } | |
377 | ||
378 | ippDelete(response); | |
379 | } | |
4e243213 | 380 | else |
381 | { | |
382 | fprintf(stderr, "lpq: get-jobs failed: %s\n", ippErrorString(cupsLastError())); | |
383 | return (0); | |
384 | } | |
385 | ||
386 | if (jobcount == 0) | |
387 | puts("no entries"); | |
f8ab8b97 | 388 | |
389 | return (jobcount); | |
390 | } | |
391 | ||
392 | ||
393 | /* | |
4e243213 | 394 | * 'show_printer()' - Show printer status. |
395 | */ | |
396 | ||
397 | static void | |
398 | show_printer(http_t *http, /* I - HTTP connection to server */ | |
399 | const char *dest) /* I - Destination */ | |
400 | { | |
401 | ipp_t *request, /* IPP Request */ | |
402 | *response; /* IPP Response */ | |
403 | ipp_attribute_t *attr; /* Current attribute */ | |
404 | cups_lang_t *language; /* Default language */ | |
405 | const char *printer, /* Printer name */ | |
406 | *message; /* Printer device URI */ | |
407 | ipp_pstate_t state; /* Printer state */ | |
408 | char uri[HTTP_MAX_URI]; | |
409 | /* Printer URI */ | |
410 | ||
411 | ||
412 | if (http == NULL) | |
413 | return; | |
414 | ||
415 | /* | |
416 | * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following | |
417 | * attributes: | |
418 | * | |
419 | * attributes-charset | |
420 | * attributes-natural-language | |
421 | * printer-uri | |
422 | */ | |
423 | ||
424 | request = ippNew(); | |
425 | ||
426 | request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; | |
427 | request->request.op.request_id = 1; | |
428 | ||
429 | language = cupsLangDefault(); | |
430 | ||
431 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, | |
432 | "attributes-charset", NULL, cupsLangEncoding(language)); | |
433 | ||
434 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
435 | "attributes-natural-language", NULL, language->language); | |
436 | ||
437 | sprintf(uri, "ipp://localhost/printers/%s", dest); | |
438 | ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
439 | "printer-uri", NULL, uri); | |
440 | ||
441 | /* | |
442 | * Do the request and get back a response... | |
443 | */ | |
444 | ||
445 | if ((response = cupsDoRequest(http, request, "/")) != NULL) | |
446 | { | |
447 | if (response->request.status.status_code > IPP_OK_CONFLICT) | |
448 | { | |
449 | fprintf(stderr, "lpq: get-printer-attributes failed: %s\n", | |
450 | ippErrorString(response->request.status.status_code)); | |
451 | ippDelete(response); | |
452 | return; | |
453 | } | |
454 | ||
455 | if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) | |
456 | state = (ipp_pstate_t)attr->values[0].integer; | |
457 | else | |
458 | state = IPP_PRINTER_STOPPED; | |
459 | ||
460 | switch (state) | |
461 | { | |
462 | case IPP_PRINTER_IDLE : | |
463 | printf("%s is ready\n", dest); | |
464 | break; | |
465 | case IPP_PRINTER_PROCESSING : | |
466 | printf("%s is ready and printing\n", dest); | |
467 | break; | |
468 | case IPP_PRINTER_STOPPED : | |
469 | printf("%s is not ready\n", dest); | |
470 | break; | |
471 | } | |
472 | ||
473 | ippDelete(response); | |
474 | } | |
475 | else | |
476 | fprintf(stderr, "lpq: get-printer-attributes failed: %s\n", | |
477 | ippErrorString(cupsLastError())); | |
478 | } | |
479 | ||
480 | ||
481 | /* | |
482 | * End of "$Id: lpq.c,v 1.8 2000/02/24 15:20:18 mike Exp $". | |
f8ab8b97 | 483 | */ |