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