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