]>
Commit | Line | Data |
---|---|---|
bd0b97ff | 1 | /* |
2 | * "$Id: lpc.c,v 1.1 1999/05/13 20:39:59 mike Exp $" | |
3 | * | |
4 | * "lpc" command for the Common UNIX Printing System (CUPS). | |
5 | * | |
6 | * Copyright 1997-1999 by Easy Software Products. | |
7 | * | |
8 | * These coded instructions, statements, and computer programs are the | |
9 | * property of Easy Software Products and are protected by Federal | |
10 | * copyright law. Distribution and use rights are outlined in the file | |
11 | * "LICENSE.txt" which should have been included with this file. If this | |
12 | * file is missing or damaged please contact Easy Software Products | |
13 | * at: | |
14 | * | |
15 | * Attn: CUPS Licensing Information | |
16 | * Easy Software Products | |
17 | * 44141 Airport View Drive, Suite 204 | |
18 | * Hollywood, Maryland 20636-3111 USA | |
19 | * | |
20 | * Voice: (301) 373-9603 | |
21 | * EMail: cups-info@cups.org | |
22 | * WWW: http://www.cups.org | |
23 | * | |
24 | * Contents: | |
25 | * | |
26 | * main() - Parse options and commands. | |
27 | * compare_strings() - Compare two command-line strings. | |
28 | * do_command() - Do an lpc command... | |
29 | * show_help() - Show help messages. | |
30 | * show_status() - Show printers. | |
31 | */ | |
32 | ||
33 | /* | |
34 | * Include necessary headers... | |
35 | */ | |
36 | ||
37 | #include <stdio.h> | |
38 | #include <stdlib.h> | |
39 | #include <ctype.h> | |
40 | #include <cups/cups.h> | |
41 | #include <cups/language.h> | |
42 | #include <cups/debug.h> | |
43 | ||
44 | ||
45 | /* | |
46 | * Local functions... | |
47 | */ | |
48 | ||
49 | static int compare_strings(char *, char *, int); | |
50 | static void do_command(http_t *, char *, char *); | |
51 | static void show_help(char *); | |
52 | static void show_status(http_t *, char *); | |
53 | ||
54 | ||
55 | /* | |
56 | * 'main()' - Parse options and commands. | |
57 | */ | |
58 | ||
59 | int | |
60 | main(int argc, /* I - Number of command-line arguments */ | |
61 | char *argv[]) /* I - Command-line arguments */ | |
62 | { | |
63 | int i; /* Looping var */ | |
64 | http_t *http; /* Connection to server */ | |
65 | char line[1024], /* Input line from user */ | |
66 | *params; /* Pointer to parameters */ | |
67 | ||
68 | ||
69 | /* | |
70 | * Connect to the scheduler... | |
71 | */ | |
72 | ||
73 | http = httpConnect("localhost", ippPort()); | |
74 | ||
75 | if (argc > 1) | |
76 | { | |
77 | /* | |
78 | * Process a single command on the command-line... | |
79 | */ | |
80 | ||
81 | do_command(http, argv[1], argv[2]); | |
82 | } | |
83 | else | |
84 | { | |
85 | /* | |
86 | * Do the command prompt thing... | |
87 | */ | |
88 | ||
89 | printf("lpc> "); | |
90 | while (gets(line) != NULL) | |
91 | { | |
92 | /* | |
93 | * Find any options in the string... | |
94 | */ | |
95 | ||
96 | while (isspace(line[0])) | |
97 | strcpy(line, line + 1); | |
98 | ||
99 | for (params = line; *params != '\0'; params ++) | |
100 | if (isspace(*params)) | |
101 | break; | |
102 | ||
103 | /* | |
104 | * Remove whitespace between the command and parameters... | |
105 | */ | |
106 | ||
107 | while (isspace(*params)) | |
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) == 0 || | |
115 | compare_strings(line, "exit", 2) == 0) | |
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 | printf("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(char *s, /* I - Command-line string */ | |
147 | char *t, /* I - Option string */ | |
148 | int tmin) /* I - Minimum number of unique chars in option */ | |
149 | { | |
150 | int 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 | char *command, /* I - Command string */ | |
168 | char *params) /* I - Parameters for command */ | |
169 | { | |
170 | if (compare_strings(command, "status", 4) == 0) | |
171 | show_status(http, params); | |
172 | else if (compare_strings(command, "help", 1) == 0 || | |
173 | strcmp(command, "?") == 0) | |
174 | show_help(params); | |
175 | else | |
176 | puts("?Invalid command"); | |
177 | } | |
178 | ||
179 | ||
180 | /* | |
181 | * 'show_help()' - Show help messages. | |
182 | */ | |
183 | ||
184 | static void | |
185 | show_help(char *command) /* I - Command to describe or NULL */ | |
186 | { | |
187 | if (command == NULL) | |
188 | { | |
189 | puts("Commands may be abbreviated. Commands are:"); | |
190 | puts(""); | |
191 | puts("exit help quit status ?"); | |
192 | } | |
193 | else if (compare_strings(command, "help", 1) == 0 || | |
194 | strcmp(command, "?") == 0) | |
195 | puts("help\t\tget help on commands"); | |
196 | else if (compare_strings(command, "status", 4) == 0) | |
197 | puts("status\t\tshow status of daemon and queue"); | |
198 | else | |
199 | puts("?Invalid help command unknown"); | |
200 | } | |
201 | ||
202 | ||
203 | /* | |
204 | * 'show_status()' - Show printers. | |
205 | */ | |
206 | ||
207 | static void | |
208 | show_status(http_t *http, /* I - HTTP connection to server */ | |
209 | char *dests) /* I - Destinations */ | |
210 | { | |
211 | ipp_t *request, /* IPP Request */ | |
212 | *response, /* IPP Response */ | |
213 | *jobs; /* IPP Get Jobs response */ | |
214 | ipp_attribute_t *attr; /* Current attribute */ | |
215 | cups_lang_t *language; /* Default language */ | |
216 | char *printer, /* Printer name */ | |
217 | *device; /* Device URI */ | |
218 | ipp_pstate_t pstate; /* Printer state */ | |
219 | int accepting; /* Is printer accepting jobs? */ | |
220 | int jobcount; /* Count of current jobs */ | |
221 | char *dptr, /* Pointer into destination list */ | |
222 | *ptr; /* Pointer into printer name */ | |
223 | int match; /* Non-zero if this job matches */ | |
224 | char printer_uri[HTTP_MAX_URI]; | |
225 | /* Printer URI */ | |
226 | ||
227 | ||
228 | DEBUG_printf(("show_printers(%08x, %08x)\n", http, dests)); | |
229 | ||
230 | if (http == NULL) | |
231 | return; | |
232 | ||
233 | /* | |
234 | * Build a CUPS_GET_PRINTERS request, which requires the following | |
235 | * attributes: | |
236 | * | |
237 | * attributes-charset | |
238 | * attributes-natural-language | |
239 | */ | |
240 | ||
241 | request = ippNew(); | |
242 | ||
243 | request->request.op.operation_id = CUPS_GET_PRINTERS; | |
244 | request->request.op.request_id = 1; | |
245 | ||
246 | language = cupsLangDefault(); | |
247 | ||
248 | attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, | |
249 | "attributes-charset", NULL, cupsLangEncoding(language)); | |
250 | ||
251 | attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
252 | "attributes-natural-language", NULL, language->language); | |
253 | ||
254 | /* | |
255 | * Do the request and get back a response... | |
256 | */ | |
257 | ||
258 | if ((response = cupsDoRequest(http, request, "/printers/")) != NULL) | |
259 | { | |
260 | DEBUG_puts("show_printers: request succeeded..."); | |
261 | ||
262 | /* | |
263 | * Loop through the printers returned in the list and display | |
264 | * their status... | |
265 | */ | |
266 | ||
267 | for (attr = response->attrs; attr != NULL; attr = attr->next) | |
268 | { | |
269 | /* | |
270 | * Skip leading attributes until we hit a job... | |
271 | */ | |
272 | ||
273 | while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) | |
274 | attr = attr->next; | |
275 | ||
276 | if (attr == NULL) | |
277 | break; | |
278 | ||
279 | /* | |
280 | * Pull the needed attributes from this job... | |
281 | */ | |
282 | ||
283 | printer = NULL; | |
284 | device = "file:/dev/null"; | |
285 | pstate = IPP_PRINTER_IDLE; | |
286 | jobcount = 0; | |
287 | accepting = 1; | |
288 | ||
289 | while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) | |
290 | { | |
291 | if (strcmp(attr->name, "printer-name") == 0 && | |
292 | attr->value_tag == IPP_TAG_NAME) | |
293 | printer = attr->values[0].string.text; | |
294 | ||
295 | if (strcmp(attr->name, "device-uri") == 0 && | |
296 | attr->value_tag == IPP_TAG_URI) | |
297 | device = attr->values[0].string.text; | |
298 | ||
299 | if (strcmp(attr->name, "printer-state") == 0 && | |
300 | attr->value_tag == IPP_TAG_ENUM) | |
301 | pstate = (ipp_pstate_t)attr->values[0].integer; | |
302 | ||
303 | if (strcmp(attr->name, "printer-is-accepting-jobs") == 0 && | |
304 | attr->value_tag == IPP_TAG_BOOLEAN) | |
305 | accepting = attr->values[0].boolean; | |
306 | ||
307 | attr = attr->next; | |
308 | } | |
309 | ||
310 | /* | |
311 | * See if we have everything needed... | |
312 | */ | |
313 | ||
314 | if (printer == NULL) | |
315 | { | |
316 | if (attr == NULL) | |
317 | break; | |
318 | else | |
319 | continue; | |
320 | } | |
321 | ||
322 | /* | |
323 | * See if this is a printer we're interested in... | |
324 | */ | |
325 | ||
326 | match = dests == NULL; | |
327 | ||
328 | if (dests != NULL) | |
329 | { | |
330 | for (dptr = dests; *dptr != '\0';) | |
331 | { | |
332 | /* | |
333 | * Skip leading whitespace and commas... | |
334 | */ | |
335 | ||
336 | while (isspace(*dptr) || *dptr == ',') | |
337 | dptr ++; | |
338 | ||
339 | if (*dptr == '\0') | |
340 | break; | |
341 | ||
342 | /* | |
343 | * Compare names... | |
344 | */ | |
345 | ||
346 | for (ptr = printer; | |
347 | *ptr != '\0' && *dptr != '\0' && *ptr == *dptr; | |
348 | ptr ++, dptr ++); | |
349 | ||
350 | if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr))) | |
351 | { | |
352 | match = 1; | |
353 | break; | |
354 | } | |
355 | ||
356 | /* | |
357 | * Skip trailing junk... | |
358 | */ | |
359 | ||
360 | while (!isspace(*dptr) && *dptr != '\0') | |
361 | dptr ++; | |
362 | while (isspace(*dptr) || *dptr == ',') | |
363 | dptr ++; | |
364 | ||
365 | if (*dptr == '\0') | |
366 | break; | |
367 | } | |
368 | } | |
369 | ||
370 | /* | |
371 | * Display the printer entry if needed... | |
372 | */ | |
373 | ||
374 | if (match) | |
375 | { | |
376 | /* | |
377 | * If the printer state is "IPP_PRINTER_PROCESSING", then grab the | |
378 | * current job for the printer. | |
379 | */ | |
380 | ||
381 | if (pstate == IPP_PRINTER_PROCESSING) | |
382 | { | |
383 | /* | |
384 | * Build an IPP_GET_JOBS request, which requires the following | |
385 | * attributes: | |
386 | * | |
387 | * attributes-charset | |
388 | * attributes-natural-language | |
389 | * printer-uri | |
390 | * limit | |
391 | */ | |
392 | ||
393 | request = ippNew(); | |
394 | ||
395 | request->request.op.operation_id = IPP_GET_JOBS; | |
396 | request->request.op.request_id = 1; | |
397 | ||
398 | language = cupsLangDefault(); | |
399 | ||
400 | attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, | |
401 | "attributes-charset", NULL, | |
402 | cupsLangEncoding(language)); | |
403 | ||
404 | attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, | |
405 | "attributes-natural-language", NULL, | |
406 | language->language); | |
407 | ||
408 | sprintf(printer_uri, "http://localhost/printers/%s", printer); | |
409 | attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, | |
410 | "printer-uri", NULL, printer_uri); | |
411 | ||
412 | if ((jobs = cupsDoRequest(http, request, "/jobs/")) != NULL) | |
413 | { | |
414 | for (attr = jobs->attrs; attr != NULL; attr = attr->next) | |
415 | if (strcmp(attr->name, "job-id") == 0) | |
416 | jobcount ++; | |
417 | ||
418 | ippDelete(jobs); | |
419 | } | |
420 | } | |
421 | ||
422 | /* | |
423 | * Display it... | |
424 | */ | |
425 | ||
426 | printf("%s:\n", printer); | |
427 | if (strncmp(device, "file:", 5) == 0) | |
428 | printf("\tprinter is on device \'%s\' speed -1\n", device + 5); | |
429 | else | |
430 | printf("\tprinter is on device \'%s\' speed -1\n", device); | |
431 | printf("\tqueuing is %sabled\n", accepting ? "en" : "dis"); | |
432 | printf("\tprinting is %sabled\n", | |
433 | pstate == IPP_PRINTER_STOPPED ? "dis" : "en"); | |
434 | if (jobcount == 0) | |
435 | puts("\tno entries"); | |
436 | else | |
437 | printf("\t%d entries\n", jobcount); | |
438 | puts("\tdaemon present"); | |
439 | } | |
440 | ||
441 | if (attr == NULL) | |
442 | break; | |
443 | } | |
444 | ||
445 | ippDelete(response); | |
446 | } | |
447 | } | |
448 | ||
449 | ||
450 | /* | |
451 | * End of "$Id: lpc.c,v 1.1 1999/05/13 20:39:59 mike Exp $". | |
452 | */ |