]> git.ipfire.org Git - thirdparty/cups.git/blame - ppdc/drv.cxx
Merge changes from CUPS 1.4svn-r7614.
[thirdparty/cups.git] / ppdc / drv.cxx
CommitLineData
ac884b6a
MS
1//
2// "$Id$"
3//
4// DDK driver interface main entry for the CUPS PPD Compiler.
5//
3dfe78b3 6// Copyright 2007-2008 by Apple Inc.
ac884b6a
MS
7// Copyright 2002-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() - Enumerate or display PPD files.
18// cat_ppd() - Display a PPD file.
19// list_ppds() - List PPDs.
20//
21
22//
23// Include necessary headers...
24//
25
26#include "ppdc.h"
27#include <cups/cups.h>
28#include <cups/dir.h>
29#include <sys/stat.h>
30#include <sys/types.h>
31
32
33//
34// Local functions...
35//
36
37static int cat_ppd(ppdcSource *src, const char *name);
38static int list_drvs(const char *pathname, const char *prefix);
39static int list_ppds(ppdcSource *src, const char *name);
40
41
42//
43// 'main()' - Enumerate or display PPD files.
44//
45
46int // O - Exit status
47main(int argc, // I - Number of command-line arguments
48 char *argv[]) // I - Command-line arguments
49{
50 const char *datadir; // CUPS_DATADIR
51 ppdcSource *src; // PPD source file data
52 char filename[1024], // Full path to .drv file(s)
53 scheme[32], // URI scheme ("drv")
54 userpass[256], // User/password info (unused)
55 host[2], // Hostname (unused)
56 resource[1024], // Resource path (/dir/to/filename.drv)
57 *pc_file_name; // Filename portion of URI
58 int port, // Port number (unused)
59 status; // Exit status
60
61
62 // Determine where CUPS has installed the data files...
63 if ((datadir = getenv("CUPS_DATADIR")) == NULL)
64 datadir = CUPS_DATADIR;
65
66 // List all available PPDs or cat a single PPD...
67 if (argc == 2 && !strcmp(argv[1], "list"))
68 {
3dfe78b3
MS
69#ifdef __APPLE__
70 if (!access("/Library/Printers/PPDs.drv", 0))
71 list_drvs("/Library/Printers/PPDs.drv", "/Library/Printers/PPDs.drv");
72#endif // __APPLE__
73
ac884b6a
MS
74 snprintf(filename, sizeof(filename), "%s/drv", datadir);
75 return (list_drvs(filename, "/"));
76 }
77 else if (argc == 3 && !strcmp(argv[1], "cat"))
78 {
79 httpSeparateURI(HTTP_URI_CODING_ALL, argv[2], scheme, sizeof(scheme),
80 userpass, sizeof(userpass), host, sizeof(host), &port,
81 resource, sizeof(resource));
82
83 if (strstr(resource, "../") ||
84 (pc_file_name = strrchr(resource, '/')) == NULL ||
85 pc_file_name == resource)
86 {
87 fprintf(stderr, "ERROR: Bad driver info URI \"%s\"!\n", argv[2]);
88 return (1);
89 }
90
91 *pc_file_name++ = '\0';
92
3dfe78b3
MS
93#ifdef __APPLE__
94 if (!strncmp(resource, "/Library/Printers/PPDs.drv/", 27))
95 strlcpy(filename, resource, sizeof(filename));
96 else
97#endif // __APPLE__
98
ac884b6a
MS
99 snprintf(filename, sizeof(filename), "%s/drv%s", datadir, resource);
100
101 src = new ppdcSource(filename);
102
103 status = cat_ppd(src, pc_file_name);
104
105 delete src;
106
107 return (status);
108 }
109
110 fprintf(stderr, "ERROR: Usage: %s cat URI\n", argv[0]);
111 fprintf(stderr, "ERROR: Usage: %s list\n", argv[0]);
112
113 return (1);
114}
115
116
117//
118// 'cat_ppd()' - Display a PPD file.
119//
120
121static int // O - Exit status
122cat_ppd(ppdcSource *src, // I - Driver info file
123 const char *name) // I - PC filename
124{
125 ppdcDriver *d; // Current driver
126 cups_file_t *out; // Stdout via CUPS file API
127
128
129 for (d = (ppdcDriver *)src->drivers->first();
130 d;
131 d = (ppdcDriver *)src->drivers->next())
132 if (!strcmp(name, d->pc_file_name->value))
133 {
134 out = cupsFileStdout();
135
136 d->write_ppd_file(out, NULL, NULL, src, PPDC_LFONLY);
137 cupsFileClose(out);
138 return (0);
139 }
140
141 return (1);
142}
143
144
145//
146// 'list_drvs()' - List all drv files in the given path...
147//
148
149static int // O - Exit status
150list_drvs(const char *pathname, // I - Full path to directory
151 const char *prefix) // I - Prefix for directory
152{
153 char *ext, // Extension on file
154 filename[1024], // Full path to .drv file(s)
155 newprefix[1024]; // New prefix for directory
156 cups_dir_t *dir; // Current directory
157 cups_dentry_t *dent; // Current directory entry
158
159
160 if ((dir = cupsDirOpen(pathname)) == NULL)
161 return (1);
162
163 while ((dent = cupsDirRead(dir)) != NULL)
164 {
165 // Skip "dot" files...
166 if (dent->filename[0] == '.')
167 continue;
168
169 // See if this is a file or directory...
170 snprintf(filename, sizeof(filename), "%s/%s", pathname, dent->filename);
171
172 if (S_ISDIR(dent->fileinfo.st_mode))
173 {
174 // Descend into the subdirectory...
175 snprintf(newprefix, sizeof(newprefix), "%s%s/", prefix, dent->filename);
176
177 if (list_drvs(filename, newprefix))
178 {
179 cupsDirClose(dir);
180 return (1);
181 }
182 }
183 else if ((ext = strrchr(dent->filename, '.')) != NULL &&
184 (!strcmp(ext, ".drv") || !strcmp(ext, ".drv.gz")))
185 {
186 // List the PPDs in this driver info file...
187 ppdcSource *src = new ppdcSource(filename);
188 // Driver info file
189
190 snprintf(newprefix, sizeof(newprefix), "%s%s", prefix, dent->filename);
191 list_ppds(src, newprefix);
192 delete src;
193 }
194 }
195
196 cupsDirClose(dir);
197
198 return (0);
199}
200
201
202//
203// 'list_ppds()' - List PPDs in a driver info file.
204//
205
206static int // O - Exit status
207list_ppds(ppdcSource *src, // I - Driver info file
208 const char *name) // I - Name of driver info file
209{
210 ppdcDriver *d; // Current driver
211 ppdcAttr *attr; // 1284DeviceID attribute
212 char uri[1024]; // Driver URI
213
214
215 for (d = (ppdcDriver *)src->drivers->first();
216 d;
217 d = (ppdcDriver *)src->drivers->next())
218 {
219 httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "drv", "", "", 0,
220 "%s/%s", name, d->pc_file_name->value);
221
222 attr = d->find_attr("1284DeviceID", NULL);
223
224 printf("\"%s\" en \"%s\" \"%s\" \"%s\"\n", uri, d->manufacturer->value,
225 d->model_name->value, attr ? attr->value->value : "");
226 }
227
228 return (0);
229}
230
231
232
233
234#if 0
235
236
237
238 // Scan the command-line...
239 catalog = NULL;
240 outdir = "ppd";
241 src = 0;
242 verbose = 0;
243 locales = NULL;
244 comp = PPDC_NO_COMPRESSION;
245 le = PPDC_LFONLY;
246
247 for (i = 1; i < argc; i ++)
248 if (argv[i][0] == '-')
249 {
250 for (opt = argv[i] + 1; *opt; opt ++)
251 switch (*opt)
252 {
253 case 'c' : // Message catalog...
254 i ++;
255 if (i >= argc)
256 usage();
257
258 if (verbose > 1)
259 printf("ppdc: Loading messages from \"%s\"...\n", argv[i]);
260
261 if (!catalog)
262 catalog = new ppdcCatalog("en");
263
264 if (catalog->load_messages(argv[i]))
265 {
266 fprintf(stderr,
267 "ppdc: Unable to load localization file \"%s\" - %s\n",
268 argv[i], strerror(errno));
269 return (1);
270 }
271 break;
272
273 case 'd' : // Output directory...
274 i ++;
275 if (i >= argc)
276 usage();
277
278 if (verbose > 1)
279 printf("ppdc: Writing PPD files to directory \"%s\"...\n",
280 argv[i]);
281
282 outdir = argv[i];
283 break;
284
285 case 'l' : // Language(s)...
286 i ++;
287 if (i >= argc)
288 usage();
289
290 if (strchr(argv[i], ','))
291 {
292 // Comma-delimited list of languages...
293 char temp[1024], // Copy of language list
294 *start, // Start of current locale name
295 *end; // End of current locale name
296
297
298 locales = new ppdcArray();
299
300 strlcpy(temp, argv[i], sizeof(temp));
301 for (start = temp; *start; start = end)
302 {
303 if ((end = strchr(start, ',')) != NULL)
304 *end++ = '\0';
305 else
306 end = start + strlen(start);
307
308 if (end > start)
309 locales->add(new ppdcString(start));
310 }
311 }
312 else
313 {
314 if (verbose > 1)
315 printf("ppdc: Loading messages for locale \"%s\"...\n",
316 argv[i]);
317
318 if (catalog)
319 delete catalog;
320
321 catalog = new ppdcCatalog(argv[i]);
322
323 if (catalog->messages->count == 0)
324 {
325 fprintf(stderr,
326 "ppdc: Unable to find localization for \"%s\" - %s\n",
327 argv[i], strerror(errno));
328 return (1);
329 }
330 }
331 break;
332
333 case 'I' : // Include directory...
334 i ++;
335 if (i >= argc)
336 usage();
337
338 if (verbose > 1)
339 printf("ppdc: Adding include directory \"%s\"...\n", argv[i]);
340
341 ppdcSource::add_include(argv[i]);
342 break;
343
344 case 'v' : // Be verbose...
345 verbose ++;
346 break;
347
348 case 'z' : // Compress files...
349 comp = PPDC_GZIP_COMPRESSION;
350 break;
351
352 case '-' : // --option
353 if (!strcmp(opt, "-lf"))
354 {
355 le = PPDC_LFONLY;
356 opt += strlen(opt) - 1;
357 break;
358 }
359 else if (!strcmp(opt, "-cr"))
360 {
361 le = PPDC_CRONLY;
362 opt += strlen(opt) - 1;
363 break;
364 }
365 else if (!strcmp(opt, "-crlf"))
366 {
367 le = PPDC_CRLF;
368 opt += strlen(opt) - 1;
369 break;
370 }
371
372 default : // Unknown
373 usage();
374 break;
375 }
376 }
377 else
378 {
379 // Open and load the driver info file...
380 if (verbose > 1)
381 printf("ppdc: Loading driver information file \"%s\"...\n", argv[i]);
382
383 src = new ppdcSource(argv[i]);
384
385 // Create the output directory...
386 if (mkdir(outdir, 0777))
387 {
388 if (errno != EEXIST)
389 {
390 fprintf(stderr, "ppdc: Unable to create output directory %s: %s\n",
391 outdir, strerror(errno));
392 return (1);
393 }
394 }
395
396 // Write PPD files...
397 for (d = (ppdcDriver *)src->drivers->first();
398 d;
399 d = (ppdcDriver *)src->drivers->next())
400 {
401 // Write the PPD file for this driver...
402 for (j = 0; d->pc_file_name->value[j]; j ++)
403 pcfilename[j] = tolower(d->pc_file_name->value[j]);
404
405 pcfilename[j] = '\0';
406
407 if (comp == PPDC_GZIP_COMPRESSION)
408 snprintf(filename, sizeof(filename), "%s/%s.gz", outdir, pcfilename);
409 else
410 snprintf(filename, sizeof(filename), "%s/%s", outdir, pcfilename);
411
412 if (verbose)
413 printf("ppdc: Writing %s...\n", filename);
414
415 if (d->write_ppd_file(filename, catalog, locales, src, le, comp))
416 return (1);
417 }
418
419 // Delete the printer driver information...
420 delete src;
421 }
422
423 if (catalog)
424 delete catalog;
425
426 // If no drivers have been loaded, display the program usage message.
427 if (!src)
428 usage();
429
430 // Return with no errors.
431 return (0);
432}
433#endif // 0
434
435
436//
437// End of "$Id$".
438//