Revert manifest to default one
[external/cups.git] / systemv / lpinfo.c
1 /*
2  * "$Id: lpinfo.c 9384 2010-11-22 07:06:39Z mike $"
3  *
4  *   "lpinfo" command for CUPS.
5  *
6  *   Copyright 2007-2010 by Apple Inc.
7  *   Copyright 1997-2006 by Easy Software Products.
8  *
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/".
14  *
15  * Contents:
16  *
17  *   main()         - Parse options and show information.
18  *   device_cb      - Device callback.
19  *   show_devices() - Show available devices.
20  *   show_models()  - Show available PPDs.
21  */
22
23 /*
24  * Include necessary headers...
25  */
26
27 #include <cups/cups-private.h>
28
29
30 /*
31  * Local functions...
32  */
33
34 static void     device_cb(const char *device_clas, const char *device_id,
35                           const char *device_info,
36                           const char *device_make_and_model,
37                           const char *device_uri, const char *device_location,
38                           void *user_data);
39 static int      show_devices(int long_status, int timeout,
40                              const char *include_schemes,
41                              const char *exclude_schemes);
42 static int      show_models(int long_status,
43                             const char *device_id, const char *language,
44                             const char *make_model, const char *product,
45                             const char *include_schemes,
46                             const char *exclude_schemes);
47
48
49 /*
50  * 'main()' - Parse options and show status information.
51  */
52
53 int
54 main(int  argc,                         /* I - Number of command-line arguments */
55      char *argv[])                      /* I - Command-line arguments */
56 {
57   int           i;                      /* Looping var */
58   int           long_status;            /* Long listing? */
59   const char    *device_id,             /* 1284 device ID */
60                 *language,              /* Language */
61                 *make_model,            /* Make and model */
62                 *product,               /* Product */
63                 *include_schemes,       /* Schemes to include */
64                 *exclude_schemes;       /* Schemes to exclude */
65   int           timeout;                /* Device timeout */
66
67
68   _cupsSetLocale(argv);
69
70   long_status     = 0;
71   device_id       = NULL;
72   language        = NULL;
73   make_model      = NULL;
74   product         = NULL;
75   include_schemes = CUPS_INCLUDE_ALL;
76   exclude_schemes = CUPS_EXCLUDE_NONE;
77   timeout         = CUPS_TIMEOUT_DEFAULT;
78
79   for (i = 1; i < argc; i ++)
80     if (argv[i][0] == '-')
81       switch (argv[i][1])
82       {
83         case 'E' : /* Encrypt */
84 #ifdef HAVE_SSL
85             cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
86 #else
87             _cupsLangPrintf(stderr,
88                             _("%s: Sorry, no encryption support."),
89                             argv[0]);
90 #endif /* HAVE_SSL */
91             break;
92
93         case 'h' : /* Connect to host */
94             if (argv[i][2] != '\0')
95               cupsSetServer(argv[i] + 2);
96             else
97             {
98               i ++;
99
100               if (i >= argc)
101               {
102                 _cupsLangPuts(stderr,
103                               _("Error: need hostname after \"-h\" option."));
104                 return (1);
105               }
106
107               cupsSetServer(argv[i]);
108             }
109             break;
110
111         case 'l' : /* Show long listing */
112             long_status = 1;
113             break;
114
115         case 'm' : /* Show models */
116             if (show_models(long_status, device_id, language, make_model,
117                             product, include_schemes, exclude_schemes))
118               return (1);
119             break;
120             
121         case 'v' : /* Show available devices */
122             if (show_devices(long_status, timeout, include_schemes,
123                              exclude_schemes))
124               return (1);
125             break;
126
127         case '-' : /* --something */
128             if (!strcmp(argv[i], "--device-id"))
129             {
130               i ++;
131
132               if (i < argc)
133                 device_id = argv[i];
134               else
135               {
136                 _cupsLangPuts(stderr,
137                               _("lpinfo: Expected 1284 device ID string "
138                                 "after \"--device-id\"."));
139                 return (1);
140               }
141             }
142             else if (!strncmp(argv[i], "--device-id=", 12) && argv[i][12])
143             {
144               device_id = argv[i] + 12;
145             }
146             else if (!strcmp(argv[i], "--exclude-schemes"))
147             {
148               i ++;
149
150               if (i < argc)
151                 exclude_schemes = argv[i];
152               else
153               {
154                 _cupsLangPuts(stderr,
155                               _("lpinfo: Expected scheme list after "
156                                 "\"--exclude-schemes\"."));
157                 return (1);
158               }
159             }
160             else if (!strncmp(argv[i], "--exclude-schemes=", 18) && argv[i][18])
161             {
162               exclude_schemes = argv[i] + 18;
163             }
164             else if (!strcmp(argv[i], "--include-schemes"))
165             {
166               i ++;
167
168               if (i < argc)
169                 include_schemes = argv[i];
170               else
171               {
172                 _cupsLangPuts(stderr,
173                               _("lpinfo: Expected scheme list after "
174                                 "\"--include-schemes\"."));
175                 return (1);
176               }
177             }
178             else if (!strncmp(argv[i], "--include-schemes=", 18) && argv[i][18])
179             {
180               include_schemes = argv[i] + 18;
181             }
182             else if (!strcmp(argv[i], "--language"))
183             {
184               i ++;
185               if (i < argc)
186                 language = argv[i];
187               else
188               {
189                 _cupsLangPuts(stderr,
190                               _("lpinfo: Expected language after "
191                                 "\"--language\"."));
192                 return (1);
193               }
194             }
195             else if (!strncmp(argv[i], "--language=", 11) && argv[i][11])
196             {
197               language = argv[i] + 11;
198             }
199             else if (!strcmp(argv[i], "--make-and-model"))
200             {
201               i ++;
202               if (i < argc)
203                 make_model= argv[i];
204               else
205               {
206                 _cupsLangPuts(stderr,
207                               _("lpinfo: Expected make and model after "
208                                 "\"--make-and-model\"."));
209                 return (1);
210               }
211             }
212             else if (!strncmp(argv[i], "--make-and-model=", 17) && argv[i][17])
213             {
214               make_model = argv[i] + 17;
215             }
216             else if (!strcmp(argv[i], "--product"))
217             {
218               i ++;
219               if (i < argc)
220                 product = argv[i];
221               else
222               {
223                 _cupsLangPuts(stderr,
224                               _("lpinfo: Expected product string after "
225                                 "\"--product\"."));
226                 return (1);
227               }
228             }
229             else if (!strncmp(argv[i], "--product=", 10) && argv[i][10])
230             {
231               product = argv[i] + 10;
232             }
233             else if (!strcmp(argv[i], "--timeout"))
234             {
235               i ++;
236               if (i < argc)
237                 timeout = atoi(argv[i]);
238               else
239               {
240                 _cupsLangPuts(stderr,
241                               _("lpinfo: Expected timeout after "
242                                 "\"--timeout\"."));
243                 return (1);
244               }
245             }
246             else if (!strncmp(argv[i], "--timeout=", 10) && argv[i][10])
247             {
248               timeout = atoi(argv[i] + 10);
249             }
250             else
251             {
252               _cupsLangPrintf(stderr, _("lpinfo: Unknown option \"%s\"."),
253                               argv[i]);
254               return (1);
255             }
256             break;
257
258         default :
259             _cupsLangPrintf(stderr, _("lpinfo: Unknown option \"%c\"."),
260                             argv[i][1]);
261             return (1);
262       }
263     else
264     {
265       _cupsLangPrintf(stderr, _("lpinfo: Unknown argument \"%s\"."),
266                       argv[i]);
267       return (1);
268     }
269
270   return (0);
271 }
272
273
274 /*
275  * 'device_cb()' - Device callback.
276  */
277
278 static void
279 device_cb(
280     const char *device_class,           /* I - device-class string */
281     const char *device_id,              /* I - device-id string */
282     const char *device_info,            /* I - device-info string */
283     const char *device_make_and_model,  /* I - device-make-and-model string */
284     const char *device_uri,             /* I - device-uri string */
285     const char *device_location,        /* I - device-location string */
286     void       *user_data)              /* I - User data */
287 {
288   int   *long_status;                   /* Show verbose info? */
289
290
291  /*
292   * Display the device...
293   */
294
295   long_status = (int *)user_data;
296
297   if (*long_status)
298   {
299     _cupsLangPrintf(stdout,
300                     _("Device: uri = %s\n"
301                       "        class = %s\n"
302                       "        info = %s\n"
303                       "        make-and-model = %s\n"
304                       "        device-id = %s\n"
305                       "        location = %s"),
306                     device_uri, device_class, device_info,
307                     device_make_and_model, device_id, device_location);
308   }
309   else
310     _cupsLangPrintf(stdout, "%s %s", device_class, device_uri);
311 }
312
313
314 /*
315  * 'show_devices()' - Show available devices.
316  */
317
318 static int                              /* O - 0 on success, 1 on failure */
319 show_devices(
320     int        long_status,             /* I - Long status report? */
321     int        timeout,                 /* I - Timeout */
322     const char *include_schemes,        /* I - List of schemes to include */
323     const char *exclude_schemes)        /* I - List of schemes to exclude */
324 {
325   if (cupsGetDevices(CUPS_HTTP_DEFAULT, timeout, include_schemes,
326                      exclude_schemes, device_cb, &long_status) != IPP_OK)
327   {
328     _cupsLangPrintf(stderr, "lpinfo: %s", cupsLastErrorString());
329     return (1);
330   }
331
332   return (0);
333 }
334
335
336 /*
337  * 'show_models()' - Show available PPDs.
338  */
339
340 static int                              /* O - 0 on success, 1 on failure */
341 show_models(
342     int        long_status,             /* I - Long status report? */
343     const char *device_id,              /* I - 1284 device ID */
344     const char *language,               /* I - Language */
345     const char *make_model,             /* I - Make and model */
346     const char *product,                /* I - Product */
347     const char *include_schemes,        /* I - List of schemes to include */
348     const char *exclude_schemes)        /* I - List of schemes to exclude */
349 {
350   ipp_t         *request,               /* IPP Request */
351                 *response;              /* IPP Response */
352   ipp_attribute_t *attr;                /* Current attribute */
353   const char    *ppd_device_id,         /* Pointer to ppd-device-id */
354                 *ppd_language,          /* Pointer to ppd-natural-language */
355                 *ppd_make_model,        /* Pointer to ppd-make-and-model */
356                 *ppd_name;              /* Pointer to ppd-name */
357   cups_option_t option;                 /* in/exclude-schemes option */
358
359
360  /*
361   * Build a CUPS_GET_PPDS request...
362   */
363
364   request = ippNewRequest(CUPS_GET_PPDS);
365
366   if (device_id)
367     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-device-id",
368                  NULL, device_id);
369   if (language)
370     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "ppd-language",
371                  NULL, language);
372   if (make_model)
373     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-make-and-model",
374                  NULL, make_model);
375   if (product)
376     ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "ppd-product",
377                  NULL, product);
378
379   if (include_schemes)
380   {
381     option.name  = "include-schemes";
382     option.value = (char *)include_schemes;
383
384     cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
385   }
386
387   if (exclude_schemes)
388   {
389     option.name  = "exclude-schemes";
390     option.value = (char *)exclude_schemes;
391
392     cupsEncodeOptions2(request, 1, &option, IPP_TAG_OPERATION);
393   }
394
395  /*
396   * Do the request and get back a response...
397   */
398
399   if ((response = cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/")) != NULL)
400   {
401    /*
402     * Loop through the device list and display them...
403     */
404
405     if (response->request.status.status_code > IPP_OK_CONFLICT)
406     {
407       _cupsLangPrintf(stderr, "lpinfo: %s", cupsLastErrorString());
408       ippDelete(response);
409       return (1);
410     }
411
412     for (attr = response->attrs; attr != NULL; attr = attr->next)
413     {
414      /*
415       * Skip leading attributes until we hit a PPD...
416       */
417
418       while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
419         attr = attr->next;
420
421       if (attr == NULL)
422         break;
423
424      /*
425       * Pull the needed attributes from this PPD...
426       */
427
428       ppd_device_id  = "NONE";
429       ppd_language   = NULL;
430       ppd_make_model = NULL;
431       ppd_name       = NULL;
432
433       while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
434       {
435         if (!strcmp(attr->name, "ppd-device-id") &&
436             attr->value_tag == IPP_TAG_TEXT)
437           ppd_device_id = attr->values[0].string.text;
438         else if (!strcmp(attr->name, "ppd-natural-language") &&
439                  attr->value_tag == IPP_TAG_LANGUAGE)
440           ppd_language = attr->values[0].string.text;
441         else if (!strcmp(attr->name, "ppd-make-and-model") &&
442                  attr->value_tag == IPP_TAG_TEXT)
443           ppd_make_model = attr->values[0].string.text;
444         else if (!strcmp(attr->name, "ppd-name") &&
445                  attr->value_tag == IPP_TAG_NAME)
446           ppd_name = attr->values[0].string.text;
447
448         attr = attr->next;
449       }
450
451      /*
452       * See if we have everything needed...
453       */
454
455       if (ppd_language == NULL || ppd_make_model == NULL || ppd_name == NULL)
456       {
457         if (attr == NULL)
458           break;
459         else
460           continue;
461       }
462
463      /*
464       * Display the device...
465       */
466
467       if (long_status)
468       {
469         _cupsLangPrintf(stdout,
470                         _("Model:  name = %s\n"
471                           "        natural_language = %s\n"
472                           "        make-and-model = %s\n"
473                           "        device-id = %s"),
474                         ppd_name, ppd_language, ppd_make_model, ppd_device_id);
475       }
476       else
477         _cupsLangPrintf(stdout, "%s %s", ppd_name, ppd_make_model);
478
479       if (attr == NULL)
480         break;
481     }
482
483     ippDelete(response);
484   }
485   else
486   {
487     _cupsLangPrintf(stderr, "lpinfo: %s", cupsLastErrorString());
488
489     return (1);
490   }
491
492   return (0);
493 }
494
495
496 /*
497  * End of "$Id: lpinfo.c 9384 2010-11-22 07:06:39Z mike $".
498  */