]> git.ipfire.org Git - thirdparty/cups.git/blame - berkeley/lpc.c
Import CUPS trunk (1.4svn) r7116.
[thirdparty/cups.git] / berkeley / lpc.c
CommitLineData
ef416fc2 1/*
bc44d920 2 * "$Id: lpc.c 6649 2007-07-11 21:46:42Z mike $"
ef416fc2 3 *
4 * "lpc" command for the Common UNIX Printing System (CUPS).
5 *
bc44d920 6 * Copyright 2007 by Apple Inc.
ef416fc2 7 * Copyright 1997-2006 by Easy Software Products.
8 *
9 * These coded instructions, statements, and computer programs are the
bc44d920 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/".
ef416fc2 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
40static int compare_strings(const char *, const char *, int);
41static void do_command(http_t *, const char *, const char *);
42static void show_help(const char *);
43static void show_status(http_t *, const char *);
44
45
46/*
47 * 'main()' - Parse options and commands.
48 */
49
50int
51main(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
07725fee 59 _cupsSetLocale(argv);
d09495fa 60
ef416fc2 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
fa73b229 81 _cupsLangPuts(stdout, _("lpc> "));
ef416fc2 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
fa73b229 109 _cupsLangPuts(stdout, _("lpc> "));
ef416fc2 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
fa73b229 145 _cupsLangPuts(stdout, _("lpc> "));
ef416fc2 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
163static int /* O - -1 or 1 = no match, 0 = match */
164compare_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
183static void
184do_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
fa73b229 193 _cupsLangPrintf(stdout,
ef416fc2 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
203static void
204show_help(const char *command) /* I - Command to describe or NULL */
205{
206 if (!command)
207 {
fa73b229 208 _cupsLangPrintf(stdout,
ef416fc2 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, "?"))
fa73b229 214 _cupsLangPrintf(stdout, _("help\t\tget help on commands\n"));
ef416fc2 215 else if (!compare_strings(command, "status", 4))
fa73b229 216 _cupsLangPrintf(stdout, _("status\t\tshow status of daemon and queue\n"));
ef416fc2 217 else
fa73b229 218 _cupsLangPrintf(stdout, _("?Invalid help command unknown\n"));
ef416fc2 219}
220
221
222/*
223 * 'show_status()' - Show printers.
224 */
225
226static void
227show_status(http_t *http, /* I - HTTP connection to server */
228 const char *dests) /* I - Destinations */
229{
230 ipp_t *request, /* IPP Request */
26d47ec6 231 *response; /* IPP Response */
232 ipp_attribute_t *attr; /* Current attribute */
ef416fc2 233 char *printer, /* Printer name */
234 *device, /* Device URI */
235 *delimiter; /* Char search result */
236 ipp_pstate_t pstate; /* Printer state */
237 int accepting; /* Is printer accepting jobs? */
238 int jobcount; /* Count of current jobs */
239 const char *dptr, /* Pointer into destination list */
240 *ptr; /* Pointer into printer name */
241 int match; /* Non-zero if this job matches */
ef416fc2 242 static const char *requested[] = /* Requested attributes */
243 {
ef416fc2 244 "device-uri",
26d47ec6 245 "printer-is-accepting-jobs",
246 "printer-name",
ef416fc2 247 "printer-state",
26d47ec6 248 "queued-job-count"
ef416fc2 249 };
250
251
252 DEBUG_printf(("show_status(http=%p, dests=\"%s\")\n", http, dests));
253
254 if (http == NULL)
255 return;
256
257 /*
258 * Build a CUPS_GET_PRINTERS request, which requires the following
259 * attributes:
260 *
261 * attributes-charset
262 * attributes-natural-language
263 */
264
0a682745 265 request = ippNewRequest(CUPS_GET_PRINTERS);
ef416fc2 266
267 ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
268 "requested-attributes", sizeof(requested) / sizeof(requested[0]),
269 NULL, requested);
270
271 /*
272 * Do the request and get back a response...
273 */
274
275 if ((response = cupsDoRequest(http, request, "/")) != NULL)
276 {
277 DEBUG_puts("show_status: request succeeded...");
278
279 /*
280 * Loop through the printers returned in the list and display
281 * their status...
282 */
283
284 for (attr = response->attrs; attr != NULL; attr = attr->next)
285 {
286 /*
287 * Skip leading attributes until we hit a job...
288 */
289
290 while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
291 attr = attr->next;
292
293 if (attr == NULL)
294 break;
295
296 /*
297 * Pull the needed attributes from this job...
298 */
299
300 printer = NULL;
301 device = "file:/dev/null";
302 pstate = IPP_PRINTER_IDLE;
303 jobcount = 0;
304 accepting = 1;
305
306 while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
307 {
ef416fc2 308 if (!strcmp(attr->name, "device-uri") &&
309 attr->value_tag == IPP_TAG_URI)
310 device = attr->values[0].string.text;
26d47ec6 311 else if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
312 attr->value_tag == IPP_TAG_BOOLEAN)
ef416fc2 313 accepting = attr->values[0].boolean;
26d47ec6 314 else if (!strcmp(attr->name, "printer-name") &&
315 attr->value_tag == IPP_TAG_NAME)
316 printer = attr->values[0].string.text;
317 else if (!strcmp(attr->name, "printer-state") &&
318 attr->value_tag == IPP_TAG_ENUM)
319 pstate = (ipp_pstate_t)attr->values[0].integer;
320 else if (!strcmp(attr->name, "queued-job-count") &&
321 attr->value_tag == IPP_TAG_INTEGER)
322 jobcount = attr->values[0].integer;
ef416fc2 323
324 attr = attr->next;
325 }
326
327 /*
328 * See if we have everything needed...
329 */
330
331 if (printer == NULL)
332 {
333 if (attr == NULL)
334 break;
335 else
336 continue;
337 }
338
339 /*
340 * A single 'all' printer name is special, meaning all printers.
341 */
342
343 if (dests != NULL && !strcmp(dests, "all"))
344 dests = NULL;
345
346 /*
347 * See if this is a printer we're interested in...
348 */
349
350 match = dests == NULL;
351
352 if (dests != NULL)
353 {
354 for (dptr = dests; *dptr != '\0';)
355 {
356 /*
357 * Skip leading whitespace and commas...
358 */
359
360 while (isspace(*dptr & 255) || *dptr == ',')
361 dptr ++;
362
363 if (*dptr == '\0')
364 break;
365
366 /*
367 * Compare names...
368 */
369
370 for (ptr = printer;
371 *ptr != '\0' && *dptr != '\0' && *ptr == *dptr;
372 ptr ++, dptr ++);
373
26d47ec6 374 if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' ||
375 isspace(*dptr & 255)))
ef416fc2 376 {
377 match = 1;
378 break;
379 }
380
381 /*
382 * Skip trailing junk...
383 */
384
385 while (!isspace(*dptr & 255) && *dptr != '\0')
386 dptr ++;
387 while (isspace(*dptr & 255) || *dptr == ',')
388 dptr ++;
389
390 if (*dptr == '\0')
391 break;
392 }
393 }
394
395 /*
396 * Display the printer entry if needed...
397 */
398
399 if (match)
400 {
ef416fc2 401 /*
402 * Display it...
403 */
404
405 printf("%s:\n", printer);
406 if (!strncmp(device, "file:", 5))
fa73b229 407 _cupsLangPrintf(stdout,
ef416fc2 408 _("\tprinter is on device \'%s\' speed -1\n"),
409 device + 5);
410 else
411 {
412 /*
413 * Just show the scheme...
414 */
415
416 if ((delimiter = strchr(device, ':')) != NULL )
417 {
418 *delimiter = '\0';
fa73b229 419 _cupsLangPrintf(stdout,
ef416fc2 420 _("\tprinter is on device \'%s\' speed -1\n"),
421 device);
422 }
423 }
424
425 if (accepting)
fa73b229 426 _cupsLangPuts(stdout, _("\tqueuing is enabled\n"));
ef416fc2 427 else
fa73b229 428 _cupsLangPuts(stdout, _("\tqueuing is disabled\n"));
ef416fc2 429
430 if (pstate != IPP_PRINTER_STOPPED)
fa73b229 431 _cupsLangPuts(stdout, _("\tprinting is enabled\n"));
ef416fc2 432 else
fa73b229 433 _cupsLangPuts(stdout, _("\tprinting is disabled\n"));
ef416fc2 434
435 if (jobcount == 0)
fa73b229 436 _cupsLangPuts(stdout, _("\tno entries\n"));
ef416fc2 437 else
fa73b229 438 _cupsLangPrintf(stdout, _("\t%d entries\n"), jobcount);
ef416fc2 439
fa73b229 440 _cupsLangPuts(stdout, _("\tdaemon present\n"));
ef416fc2 441 }
442
443 if (attr == NULL)
444 break;
445 }
446
447 ippDelete(response);
448 }
449}
450
451
452/*
bc44d920 453 * End of "$Id: lpc.c 6649 2007-07-11 21:46:42Z mike $".
ef416fc2 454 */