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