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