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