2 * "$Id: lpq.c,v 1.21 2002/05/16 13:44:51 mike Exp $"
4 * "lpq" command for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2002 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() - Parse options and commands.
27 * show_jobs() - Show jobs.
28 * show_printer() - Show printer status.
32 * Include necessary headers...
36 * Include necessary headers...
41 #include <cups/string.h>
42 #include <cups/cups.h>
43 #include <cups/language.h>
44 #include <cups/debug.h>
51 static int show_jobs(http_t
*, const char *, const char *, const int,
53 static void show_printer(http_t
*, const char *);
57 * 'main()' - Parse options and commands.
61 main(int argc
, /* I - Number of command-line arguments */
62 char *argv
[]) /* I - Command-line arguments */
64 int i
; /* Looping var */
65 http_t
*http
; /* Connection to server */
66 const char *dest
, /* Desired printer */
67 *user
; /* Desired user */
68 char *instance
; /* Printer instance */
69 int id
, /* Desired job ID */
70 interval
, /* Reporting interval */
71 longstatus
; /* Show file details */
72 int num_dests
; /* Number of destinations */
73 cups_dest_t
*dests
; /* Destinations */
75 http_encryption_t encryption
; /* Encryption? */
76 #endif /* HAVE_LIBSSL */
80 * Connect to the scheduler...
83 if ((http
= httpConnectEncrypt(cupsServer(), ippPort(),
84 cupsEncryption())) == NULL
)
86 fputs("lpq: Unable to contact server!\n", stderr
);
91 * Check for command-line options...
100 num_dests
= cupsGetDests(&dests
);
102 for (i
= 0; i
< num_dests
; i
++)
103 if (dests
[i
].is_default
)
104 dest
= dests
[i
].name
;
106 for (i
= 1; i
< argc
; i
++)
107 if (argv
[i
][0] == '+')
108 interval
= atoi(argv
[i
] + 1);
109 else if (argv
[i
][0] == '-')
113 case 'E' : /* Encrypt */
115 encryption
= HTTP_ENCRYPT_REQUIRED
;
118 httpEncryption(http
, encryption
);
120 fprintf(stderr
, "%s: Sorry, no encryption support compiled in!\n",
122 #endif /* HAVE_LIBSSL */
125 case 'P' : /* Printer */
134 if ((instance
= strchr(dest
, '/')) != NULL
)
138 case 'a' : /* All printers */
142 case 'l' : /* Long status */
147 fputs("Usage: lpq [-P dest] [-l] [+interval]\n", stderr
);
149 cupsFreeDests(num_dests
, dests
);
153 else if (isdigit(argv
[i
][0]))
159 * Show the status in a loop...
165 show_printer(http
, dest
);
167 i
= show_jobs(http
, dest
, user
, id
, longstatus
);
179 * Close the connection to the server and return...
182 cupsFreeDests(num_dests
, dests
);
190 * 'show_jobs()' - Show jobs.
193 static int /* O - Number of jobs in queue */
194 show_jobs(http_t
*http
, /* I - HTTP connection to server */
195 const char *dest
, /* I - Destination */
196 const char *user
, /* I - User */
197 const int id
, /* I - Job ID */
198 const int longstatus
)/* I - 1 if long report desired */
200 ipp_t
*request
, /* IPP Request */
201 *response
; /* IPP Response */
202 ipp_attribute_t
*attr
; /* Current attribute */
203 cups_lang_t
*language
; /* Default language */
204 const char *jobdest
, /* Pointer into job-printer-uri */
205 *jobuser
, /* Pointer to job-originating-user-name */
206 *jobname
; /* Pointer to job-name */
207 ipp_jstate_t jobstate
; /* job-state */
208 int jobid
, /* job-id */
209 jobsize
, /* job-k-octets */
211 jobpriority
, /* job-priority */
213 jobcount
, /* Number of jobs */
214 jobcopies
, /* Number of copies */
215 rank
; /* Rank of job */
216 char resource
[1024]; /* Resource string */
217 char rankstr
[255]; /* Rank string */
218 char namestr
[1024]; /* Job name string */
219 static const char *ranks
[10] =/* Ranking strings */
234 DEBUG_printf(("show_jobs(%08x, %08x, %08x, %d, %d)\n", http
, dest
, user
, id
,
241 * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
242 * the following attributes:
245 * attributes-natural-language
246 * job-uri or printer-uri
251 request
->request
.op
.operation_id
= id
? IPP_GET_JOB_ATTRIBUTES
: IPP_GET_JOBS
;
252 request
->request
.op
.request_id
= 1;
254 language
= cupsLangDefault();
256 attr
= ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_CHARSET
,
257 "attributes-charset", NULL
, cupsLangEncoding(language
));
259 attr
= ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_LANGUAGE
,
260 "attributes-natural-language", NULL
, language
->language
);
265 sprintf(resource
, "ipp://localhost/jobs/%d", id
);
267 strcpy(resource
, "ipp://localhost/jobs");
269 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "job-uri",
274 snprintf(resource
, sizeof(resource
), "ipp://localhost/printers/%s", dest
);
276 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
, "printer-uri",
282 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_NAME
,
283 "requesting-user-name", NULL
, user
);
284 ippAddBoolean(request
, IPP_TAG_OPERATION
, "my-jobs", 1);
288 * Do the request and get back a response...
293 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
295 if (response
->request
.status
.status_code
> IPP_OK_CONFLICT
)
297 fprintf(stderr
, "lpq: get-jobs failed: %s\n",
298 ippErrorString(response
->request
.status
.status_code
));
306 * Loop through the job list and display them...
309 for (attr
= response
->attrs
; attr
!= NULL
; attr
= attr
->next
)
312 * Skip leading attributes until we hit a job...
315 while (attr
!= NULL
&& attr
->group_tag
!= IPP_TAG_JOB
)
322 * Pull the needed attributes from this job...
330 jobstate
= IPP_JOB_PENDING
;
331 jobname
= "untitled";
336 while (attr
!= NULL
&& attr
->group_tag
== IPP_TAG_JOB
)
338 if (strcmp(attr
->name
, "job-id") == 0 &&
339 attr
->value_tag
== IPP_TAG_INTEGER
)
340 jobid
= attr
->values
[0].integer
;
342 if (strcmp(attr
->name
, "job-k-octets") == 0 &&
343 attr
->value_tag
== IPP_TAG_INTEGER
)
344 jobsize
= attr
->values
[0].integer
* 1024;
347 if (strcmp(attr
->name
, "job-priority") == 0 &&
348 attr
->value_tag
== IPP_TAG_INTEGER
)
349 jobpriority
= attr
->values
[0].integer
;
352 if (strcmp(attr
->name
, "job-state") == 0 &&
353 attr
->value_tag
== IPP_TAG_ENUM
)
354 jobstate
= (ipp_jstate_t
)attr
->values
[0].integer
;
356 if (strcmp(attr
->name
, "job-printer-uri") == 0 &&
357 attr
->value_tag
== IPP_TAG_URI
)
358 if ((jobdest
= strrchr(attr
->values
[0].string
.text
, '/')) != NULL
)
361 if (strcmp(attr
->name
, "job-originating-user-name") == 0 &&
362 attr
->value_tag
== IPP_TAG_NAME
)
363 jobuser
= attr
->values
[0].string
.text
;
365 if (strcmp(attr
->name
, "job-name") == 0 &&
366 attr
->value_tag
== IPP_TAG_NAME
)
367 jobname
= attr
->values
[0].string
.text
;
369 if (strcmp(attr
->name
, "copies") == 0 &&
370 attr
->value_tag
== IPP_TAG_INTEGER
)
371 jobcopies
= attr
->values
[0].integer
;
377 * See if we have everything needed...
380 if (jobdest
== NULL
|| jobid
== 0)
388 if (!longstatus
&& jobcount
== 0)
390 puts("Rank Owner Pri Job Files Total Size");
392 puts("Rank Owner Job File(s) Total Size");
401 if (jobstate
== IPP_JOB_PROCESSING
)
402 strcpy(rankstr
, "active");
405 snprintf(rankstr
, sizeof(rankstr
), "%d%s", rank
, ranks
[rank
% 10]);
414 snprintf(namestr
, sizeof(namestr
), "%d copies of %s", jobcopies
,
417 strlcpy(namestr
, jobname
, sizeof(namestr
));
419 printf("%s: %-34.34s[job %d localhost]\n", jobuser
, rankstr
, jobid
);
420 printf(" %-40.40s%d bytes\n", namestr
, jobsize
);
424 printf("%-6s %-10.10s %-4d %-10d %-27.27s %d bytes\n", rankstr
, jobuser
,
425 jobpriority
, jobid
, jobname
, jobsize
);
427 printf("%-7s %-8.8s%-8d%-32.32s%d bytes\n", rankstr
, jobuser
,
428 jobid
, jobname
, jobsize
);
439 fprintf(stderr
, "lpq: get-jobs failed: %s\n", ippErrorString(cupsLastError()));
451 * 'show_printer()' - Show printer status.
455 show_printer(http_t
*http
, /* I - HTTP connection to server */
456 const char *dest
) /* I - Destination */
458 ipp_t
*request
, /* IPP Request */
459 *response
; /* IPP Response */
460 ipp_attribute_t
*attr
; /* Current attribute */
461 cups_lang_t
*language
; /* Default language */
462 ipp_pstate_t state
; /* Printer state */
463 char uri
[HTTP_MAX_URI
];
471 * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
475 * attributes-natural-language
481 request
->request
.op
.operation_id
= IPP_GET_PRINTER_ATTRIBUTES
;
482 request
->request
.op
.request_id
= 1;
484 language
= cupsLangDefault();
486 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_CHARSET
,
487 "attributes-charset", NULL
, cupsLangEncoding(language
));
489 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_LANGUAGE
,
490 "attributes-natural-language", NULL
, language
->language
);
492 snprintf(uri
, sizeof(uri
), "ipp://localhost/printers/%s", dest
);
493 ippAddString(request
, IPP_TAG_OPERATION
, IPP_TAG_URI
,
494 "printer-uri", NULL
, uri
);
497 * Do the request and get back a response...
500 if ((response
= cupsDoRequest(http
, request
, "/")) != NULL
)
502 if (response
->request
.status
.status_code
> IPP_OK_CONFLICT
)
504 fprintf(stderr
, "lpq: get-printer-attributes failed: %s\n",
505 ippErrorString(response
->request
.status
.status_code
));
510 if ((attr
= ippFindAttribute(response
, "printer-state", IPP_TAG_ENUM
)) != NULL
)
511 state
= (ipp_pstate_t
)attr
->values
[0].integer
;
513 state
= IPP_PRINTER_STOPPED
;
517 case IPP_PRINTER_IDLE
:
518 printf("%s is ready\n", dest
);
520 case IPP_PRINTER_PROCESSING
:
521 printf("%s is ready and printing\n", dest
);
523 case IPP_PRINTER_STOPPED
:
524 printf("%s is not ready\n", dest
);
531 fprintf(stderr
, "lpq: get-printer-attributes failed: %s\n",
532 ippErrorString(cupsLastError()));
537 * End of "$Id: lpq.c,v 1.21 2002/05/16 13:44:51 mike Exp $".