]> git.ipfire.org Git - thirdparty/cups.git/blob - berkeley/lpc.c
2dd21ba26c39e482fdad9f536ff3f9eea1450fb2
[thirdparty/cups.git] / berkeley / lpc.c
1 /*
2 * "$Id: lpc.c,v 1.14 2002/06/05 20:13:12 mike Exp $"
3 *
4 * "lpc" command for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1997-2002 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 * compare_strings() - Compare two command-line strings.
28 * do_command() - Do an lpc command...
29 * show_help() - Show help messages.
30 * show_status() - Show printers.
31 */
32
33 /*
34 * Include necessary headers...
35 */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <ctype.h>
40 #include <cups/cups.h>
41 #include <cups/language.h>
42 #include <cups/debug.h>
43 #include <cups/string.h>
44
45
46 /*
47 * Local functions...
48 */
49
50 static int compare_strings(char *, char *, int);
51 static void do_command(http_t *, char *, char *);
52 static void show_help(char *);
53 static void show_status(http_t *, char *);
54
55
56 /*
57 * 'main()' - Parse options and commands.
58 */
59
60 int
61 main(int argc, /* I - Number of command-line arguments */
62 char *argv[]) /* I - Command-line arguments */
63 {
64 http_t *http; /* Connection to server */
65 char line[1024], /* Input line from user */
66 *params; /* Pointer to parameters */
67
68
69 /*
70 * Connect to the scheduler...
71 */
72
73 http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
74
75 if (argc > 1)
76 {
77 /*
78 * Process a single command on the command-line...
79 */
80
81 do_command(http, argv[1], argv[2]);
82 }
83 else
84 {
85 /*
86 * Do the command prompt thing...
87 */
88
89 printf("lpc> ");
90 while (fgets(line, sizeof(line), stdin) != NULL)
91 {
92 /*
93 * Strip the trailing newline...
94 */
95
96 line[strlen(line) - 1] = '\0';
97
98 /*
99 * Find any options in the string...
100 */
101
102 while (isspace(line[0]))
103 strcpy(line, line + 1);
104
105 for (params = line; *params != '\0'; params ++)
106 if (isspace(*params))
107 break;
108
109 /*
110 * Remove whitespace between the command and parameters...
111 */
112
113 while (isspace(*params))
114 *params++ = '\0';
115
116 /*
117 * The "quit" and "exit" commands exit; otherwise, process as needed...
118 */
119
120 if (compare_strings(line, "quit", 1) == 0 ||
121 compare_strings(line, "exit", 2) == 0)
122 break;
123
124 if (*params == '\0')
125 do_command(http, line, NULL);
126 else
127 do_command(http, line, params);
128
129 /*
130 * Put another prompt out to the user...
131 */
132
133 printf("lpc> ");
134 }
135 }
136
137 /*
138 * Close the connection to the server and return...
139 */
140
141 httpClose(http);
142
143 return (0);
144 }
145
146
147 /*
148 * 'compare_strings()' - Compare two command-line strings.
149 */
150
151 static int /* O - -1 or 1 = no match, 0 = match */
152 compare_strings(char *s, /* I - Command-line string */
153 char *t, /* I - Option string */
154 int tmin) /* I - Minimum number of unique chars in option */
155 {
156 int slen; /* Length of command-line string */
157
158
159 slen = strlen(s);
160 if (slen < tmin)
161 return (-1);
162 else
163 return (strncmp(s, t, slen));
164 }
165
166
167 /*
168 * 'do_command()' - Do an lpc command...
169 */
170
171 static void
172 do_command(http_t *http, /* I - HTTP connection to server */
173 char *command, /* I - Command string */
174 char *params) /* I - Parameters for command */
175 {
176 if (compare_strings(command, "status", 4) == 0)
177 show_status(http, params);
178 else if (compare_strings(command, "help", 1) == 0 ||
179 strcmp(command, "?") == 0)
180 show_help(params);
181 else
182 printf("%s is not implemented by the CUPS version of lpc.\n", command);
183 }
184
185
186 /*
187 * 'show_help()' - Show help messages.
188 */
189
190 static void
191 show_help(char *command) /* I - Command to describe or NULL */
192 {
193 if (command == NULL)
194 {
195 puts("Commands may be abbreviated. Commands are:");
196 puts("");
197 puts("exit help quit status ?");
198 }
199 else if (compare_strings(command, "help", 1) == 0 ||
200 strcmp(command, "?") == 0)
201 puts("help\t\tget help on commands");
202 else if (compare_strings(command, "status", 4) == 0)
203 puts("status\t\tshow status of daemon and queue");
204 else
205 puts("?Invalid help command unknown");
206 }
207
208
209 /*
210 * 'show_status()' - Show printers.
211 */
212
213 static void
214 show_status(http_t *http, /* I - HTTP connection to server */
215 char *dests) /* I - Destinations */
216 {
217 ipp_t *request, /* IPP Request */
218 *response, /* IPP Response */
219 *jobs; /* IPP Get Jobs response */
220 ipp_attribute_t *attr, /* Current attribute */
221 *jattr; /* Current job attribute */
222 cups_lang_t *language; /* Default language */
223 char *printer, /* Printer name */
224 *device; /* Device URI */
225 ipp_pstate_t pstate; /* Printer state */
226 int accepting; /* Is printer accepting jobs? */
227 int jobcount; /* Count of current jobs */
228 char *dptr, /* Pointer into destination list */
229 *ptr; /* Pointer into printer name */
230 int match; /* Non-zero if this job matches */
231 char printer_uri[HTTP_MAX_URI];
232 /* Printer URI */
233 static const char *requested[] =
234 { /* Requested attributes */
235 "printer-name",
236 "device-uri",
237 "printer-state",
238 "printer-is-accepting-jobs"
239 };
240
241
242 DEBUG_printf(("show_status(%08x, %08x)\n", http, dests));
243
244 if (http == NULL)
245 return;
246
247 /*
248 * Build a CUPS_GET_PRINTERS request, which requires the following
249 * attributes:
250 *
251 * attributes-charset
252 * attributes-natural-language
253 */
254
255 request = ippNew();
256
257 request->request.op.operation_id = CUPS_GET_PRINTERS;
258 request->request.op.request_id = 1;
259
260 language = cupsLangDefault();
261
262 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
263 "attributes-charset", NULL, cupsLangEncoding(language));
264
265 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
266 "attributes-natural-language", NULL, language->language);
267
268 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
269 "requested-attributes", sizeof(requested) / sizeof(requested[0]),
270 NULL, requested);
271
272 /*
273 * Do the request and get back a response...
274 */
275
276 if ((response = cupsDoRequest(http, request, "/printers/")) != NULL)
277 {
278 DEBUG_puts("show_status: request succeeded...");
279
280 /*
281 * Loop through the printers returned in the list and display
282 * their status...
283 */
284
285 for (attr = response->attrs; attr != NULL; attr = attr->next)
286 {
287 /*
288 * Skip leading attributes until we hit a job...
289 */
290
291 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
292 attr = attr->next;
293
294 if (attr == NULL)
295 break;
296
297 /*
298 * Pull the needed attributes from this job...
299 */
300
301 printer = NULL;
302 device = "file:/dev/null";
303 pstate = IPP_PRINTER_IDLE;
304 jobcount = 0;
305 accepting = 1;
306
307 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
308 {
309 if (strcmp(attr->name, "printer-name") == 0 &&
310 attr->value_tag == IPP_TAG_NAME)
311 printer = attr->values[0].string.text;
312
313 if (strcmp(attr->name, "device-uri") == 0 &&
314 attr->value_tag == IPP_TAG_URI)
315 device = attr->values[0].string.text;
316
317 if (strcmp(attr->name, "printer-state") == 0 &&
318 attr->value_tag == IPP_TAG_ENUM)
319 pstate = (ipp_pstate_t)attr->values[0].integer;
320
321 if (strcmp(attr->name, "printer-is-accepting-jobs") == 0 &&
322 attr->value_tag == IPP_TAG_BOOLEAN)
323 accepting = attr->values[0].boolean;
324
325 attr = attr->next;
326 }
327
328 /*
329 * See if we have everything needed...
330 */
331
332 if (printer == NULL)
333 {
334 if (attr == NULL)
335 break;
336 else
337 continue;
338 }
339
340 /*
341 * See if this is a printer we're interested in...
342 */
343
344 match = dests == NULL;
345
346 if (dests != NULL)
347 {
348 for (dptr = dests; *dptr != '\0';)
349 {
350 /*
351 * Skip leading whitespace and commas...
352 */
353
354 while (isspace(*dptr) || *dptr == ',')
355 dptr ++;
356
357 if (*dptr == '\0')
358 break;
359
360 /*
361 * Compare names...
362 */
363
364 for (ptr = printer;
365 *ptr != '\0' && *dptr != '\0' && *ptr == *dptr;
366 ptr ++, dptr ++);
367
368 if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr)))
369 {
370 match = 1;
371 break;
372 }
373
374 /*
375 * Skip trailing junk...
376 */
377
378 while (!isspace(*dptr) && *dptr != '\0')
379 dptr ++;
380 while (isspace(*dptr) || *dptr == ',')
381 dptr ++;
382
383 if (*dptr == '\0')
384 break;
385 }
386 }
387
388 /*
389 * Display the printer entry if needed...
390 */
391
392 if (match)
393 {
394 /*
395 * If the printer state is "IPP_PRINTER_PROCESSING", then grab the
396 * current job for the printer.
397 */
398
399 if (pstate == IPP_PRINTER_PROCESSING)
400 {
401 /*
402 * Build an IPP_GET_JOBS request, which requires the following
403 * attributes:
404 *
405 * attributes-charset
406 * attributes-natural-language
407 * printer-uri
408 * limit
409 */
410
411 request = ippNew();
412
413 request->request.op.operation_id = IPP_GET_JOBS;
414 request->request.op.request_id = 1;
415
416 language = cupsLangDefault();
417
418 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
419 "attributes-charset", NULL,
420 cupsLangEncoding(language));
421
422 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
423 "attributes-natural-language", NULL,
424 language->language);
425
426 snprintf(printer_uri, sizeof(printer_uri),
427 "ipp://localhost/printers/%s", printer);
428 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
429 "printer-uri", NULL, printer_uri);
430
431 ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
432 "requested-attributes", NULL, "job-id");
433
434 if ((jobs = cupsDoRequest(http, request, "/jobs/")) != NULL)
435 {
436 for (jattr = jobs->attrs; jattr != NULL; jattr = jattr->next)
437 if (jattr->name && strcmp(jattr->name, "job-id") == 0)
438 jobcount ++;
439
440 ippDelete(jobs);
441 }
442 }
443
444 /*
445 * Display it...
446 */
447
448 printf("%s:\n", printer);
449 if (strncmp(device, "file:", 5) == 0)
450 printf("\tprinter is on device \'%s\' speed -1\n", device + 5);
451 else
452 {
453 /*
454 * Just show the method...
455 */
456
457 *strchr(device, ':') = '\0';
458 printf("\tprinter is on device \'%s\' speed -1\n", device);
459 }
460
461 printf("\tqueuing is %sabled\n", accepting ? "en" : "dis");
462 printf("\tprinting is %sabled\n",
463 pstate == IPP_PRINTER_STOPPED ? "dis" : "en");
464 if (jobcount == 0)
465 puts("\tno entries");
466 else
467 printf("\t%d entries\n", jobcount);
468 puts("\tdaemon present");
469 }
470
471 if (attr == NULL)
472 break;
473 }
474
475 ippDelete(response);
476 }
477 }
478
479
480 /*
481 * End of "$Id: lpc.c,v 1.14 2002/06/05 20:13:12 mike Exp $".
482 */