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