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