]> git.ipfire.org Git - thirdparty/cups.git/blame - berkeley/lpc.c
Update ipp documentation to reflect the behavior of configuring WiFi on IPP USB printers.
[thirdparty/cups.git] / berkeley / lpc.c
CommitLineData
ef416fc2 1/*
7e86f2f6 2 * "lpc" command for CUPS.
ef416fc2 3 *
7e86f2f6
MS
4 * Copyright 2007-2014 by Apple Inc.
5 * Copyright 1997-2006 by Easy Software Products.
ef416fc2 6 *
e3101897 7 * Licensed under Apache License v2.0. See the file "LICENSE" for more information.
ef416fc2 8 */
9
10/*
11 * Include necessary headers...
12 */
13
71e16022 14#include <cups/cups-private.h>
ef416fc2 15
16
17/*
18 * Local functions...
19 */
20
7e86f2f6 21static int compare_strings(const char *, const char *, size_t);
ef416fc2 22static void do_command(http_t *, const char *, const char *);
23static void show_help(const char *);
9d4e1ef7 24static void show_prompt(const char *message);
ef416fc2 25static void show_status(http_t *, const char *);
26
27
28/*
29 * 'main()' - Parse options and commands.
30 */
31
32int
33main(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
07725fee 41 _cupsSetLocale(argv);
d09495fa 42
ef416fc2 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
9d4e1ef7 63 show_prompt(_("lpc> "));
ef416fc2 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
9d4e1ef7 91 show_prompt(_("lpc> "));
ef416fc2 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
9d4e1ef7 127 show_prompt(_("lpc> "));
ef416fc2 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
145static int /* O - -1 or 1 = no match, 0 = match */
146compare_strings(const char *s, /* I - Command-line string */
147 const char *t, /* I - Option string */
7e86f2f6 148 size_t tmin) /* I - Minimum number of unique chars in option */
ef416fc2 149{
7e86f2f6 150 size_t slen; /* Length of command-line string */
ef416fc2 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
165static void
166do_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
fa73b229 175 _cupsLangPrintf(stdout,
0837b7e8 176 _("%s is not implemented by the CUPS version of lpc."),
ef416fc2 177 command);
178}
179
180
181/*
182 * 'show_help()' - Show help messages.
183 */
184
185static void
186show_help(const char *command) /* I - Command to describe or NULL */
187{
188 if (!command)
189 {
fa73b229 190 _cupsLangPrintf(stdout,
ef416fc2 191 _("Commands may be abbreviated. Commands are:\n"
192 "\n"
0837b7e8 193 "exit help quit status ?"));
ef416fc2 194 }
195 else if (!compare_strings(command, "help", 1) || !strcmp(command, "?"))
0837b7e8 196 _cupsLangPrintf(stdout, _("help\t\tGet help on commands."));
ef416fc2 197 else if (!compare_strings(command, "status", 4))
0837b7e8 198 _cupsLangPrintf(stdout, _("status\t\tShow status of daemon and queue."));
ef416fc2 199 else
0837b7e8 200 _cupsLangPrintf(stdout, _("?Invalid help command unknown."));
ef416fc2 201}
202
203
9d4e1ef7
MS
204/*
205 * 'show_prompt()' - Show a localized prompt message.
206 */
207
208static void
209show_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
ef416fc2 228/*
229 * 'show_status()' - Show printers.
230 */
231
232static void
233show_status(http_t *http, /* I - HTTP connection to server */
234 const char *dests) /* I - Destinations */
235{
236 ipp_t *request, /* IPP Request */
26d47ec6 237 *response; /* IPP Response */
238 ipp_attribute_t *attr; /* Current attribute */
ef416fc2 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 */
ef416fc2 248 static const char *requested[] = /* Requested attributes */
249 {
ef416fc2 250 "device-uri",
26d47ec6 251 "printer-is-accepting-jobs",
252 "printer-name",
ef416fc2 253 "printer-state",
26d47ec6 254 "queued-job-count"
ef416fc2 255 };
256
257
ef416fc2 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
0a682745 269 request = ippNewRequest(CUPS_GET_PRINTERS);
ef416fc2 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 {
ef416fc2 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 {
ef416fc2 310 if (!strcmp(attr->name, "device-uri") &&
311 attr->value_tag == IPP_TAG_URI)
312 device = attr->values[0].string.text;
26d47ec6 313 else if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
314 attr->value_tag == IPP_TAG_BOOLEAN)
ef416fc2 315 accepting = attr->values[0].boolean;
26d47ec6 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;
ef416fc2 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;
82cc1f9a
MS
374 ptr ++, dptr ++)
375 /* do nothing */;
ef416fc2 376
26d47ec6 377 if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' ||
378 isspace(*dptr & 255)))
ef416fc2 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 {
ef416fc2 404 /*
405 * Display it...
406 */
407
408 printf("%s:\n", printer);
409 if (!strncmp(device, "file:", 5))
fa73b229 410 _cupsLangPrintf(stdout,
0837b7e8 411 _("\tprinter is on device \'%s\' speed -1"),
ef416fc2 412 device + 5);
413 else
414 {
415 /*
416 * Just show the scheme...
417 */
418
419 if ((delimiter = strchr(device, ':')) != NULL )
420 {
421 *delimiter = '\0';
fa73b229 422 _cupsLangPrintf(stdout,
0837b7e8 423 _("\tprinter is on device \'%s\' speed -1"),
ef416fc2 424 device);
425 }
426 }
427
428 if (accepting)
0837b7e8 429 _cupsLangPuts(stdout, _("\tqueuing is enabled"));
ef416fc2 430 else
0837b7e8 431 _cupsLangPuts(stdout, _("\tqueuing is disabled"));
ef416fc2 432
433 if (pstate != IPP_PRINTER_STOPPED)
0837b7e8 434 _cupsLangPuts(stdout, _("\tprinting is enabled"));
ef416fc2 435 else
0837b7e8 436 _cupsLangPuts(stdout, _("\tprinting is disabled"));
ef416fc2 437
438 if (jobcount == 0)
0837b7e8 439 _cupsLangPuts(stdout, _("\tno entries"));
ef416fc2 440 else
0837b7e8 441 _cupsLangPrintf(stdout, _("\t%d entries"), jobcount);
ef416fc2 442
0837b7e8 443 _cupsLangPuts(stdout, _("\tdaemon present"));
ef416fc2 444 }
445
446 if (attr == NULL)
447 break;
448 }
449
450 ippDelete(response);
451 }
452}