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