]>
git.ipfire.org Git - thirdparty/cups.git/blob - ppdc/drv.cxx
4 // DDK driver interface main entry for the CUPS PPD Compiler.
6 // Copyright 2007-2008 by Apple Inc.
7 // Copyright 2002-2006 by Easy Software Products.
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/".
17 // main() - Enumerate or display PPD files.
18 // cat_ppd() - Display a PPD file.
19 // list_ppds() - List PPDs.
23 // Include necessary headers...
27 #include <cups/cups.h>
30 #include <sys/types.h>
37 static int cat_ppd(ppdcSource
*src
, const char *name
);
38 static int list_drvs(const char *pathname
, const char *prefix
);
39 static int list_ppds(ppdcSource
*src
, const char *name
);
43 // 'main()' - Enumerate or display PPD files.
46 int // O - Exit status
47 main(int argc
, // I - Number of command-line arguments
48 char *argv
[]) // I - Command-line arguments
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
62 // Determine where CUPS has installed the data files...
63 if ((datadir
= getenv("CUPS_DATADIR")) == NULL
)
64 datadir
= CUPS_DATADIR
;
66 // List all available PPDs or cat a single PPD...
67 if (argc
== 2 && !strcmp(argv
[1], "list"))
70 if (!access("/Library/Printers/PPDs.drv", 0))
71 list_drvs("/Library/Printers/PPDs.drv", "/Library/Printers/PPDs.drv");
74 snprintf(filename
, sizeof(filename
), "%s/drv", datadir
);
75 return (list_drvs(filename
, "/"));
77 else if (argc
== 3 && !strcmp(argv
[1], "cat"))
79 httpSeparateURI(HTTP_URI_CODING_ALL
, argv
[2], scheme
, sizeof(scheme
),
80 userpass
, sizeof(userpass
), host
, sizeof(host
), &port
,
81 resource
, sizeof(resource
));
83 if (strstr(resource
, "../") ||
84 (pc_file_name
= strrchr(resource
, '/')) == NULL
||
85 pc_file_name
== resource
)
87 fprintf(stderr
, "ERROR: Bad driver info URI \"%s\"!\n", argv
[2]);
91 *pc_file_name
++ = '\0';
94 if (!strncmp(resource
, "/Library/Printers/PPDs.drv/", 27))
95 strlcpy(filename
, resource
, sizeof(filename
));
99 snprintf(filename
, sizeof(filename
), "%s/drv%s", datadir
, resource
);
101 src
= new ppdcSource(filename
);
103 status
= cat_ppd(src
, pc_file_name
);
110 fprintf(stderr
, "ERROR: Usage: %s cat URI\n", argv
[0]);
111 fprintf(stderr
, "ERROR: Usage: %s list\n", argv
[0]);
118 // 'cat_ppd()' - Display a PPD file.
121 static int // O - Exit status
122 cat_ppd(ppdcSource
*src
, // I - Driver info file
123 const char *name
) // I - PC filename
125 ppdcDriver
*d
; // Current driver
126 cups_file_t
*out
; // Stdout via CUPS file API
129 for (d
= (ppdcDriver
*)src
->drivers
->first();
131 d
= (ppdcDriver
*)src
->drivers
->next())
132 if (!strcmp(name
, d
->pc_file_name
->value
))
134 out
= cupsFileStdout();
136 d
->write_ppd_file(out
, NULL
, NULL
, src
, PPDC_LFONLY
);
146 // 'list_drvs()' - List all drv files in the given path...
149 static int // O - Exit status
150 list_drvs(const char *pathname
, // I - Full path to directory
151 const char *prefix
) // I - Prefix for directory
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
160 if ((dir
= cupsDirOpen(pathname
)) == NULL
)
163 while ((dent
= cupsDirRead(dir
)) != NULL
)
165 // Skip "dot" files...
166 if (dent
->filename
[0] == '.')
169 // See if this is a file or directory...
170 snprintf(filename
, sizeof(filename
), "%s/%s", pathname
, dent
->filename
);
172 if (S_ISDIR(dent
->fileinfo
.st_mode
))
174 // Descend into the subdirectory...
175 snprintf(newprefix
, sizeof(newprefix
), "%s%s/", prefix
, dent
->filename
);
177 if (list_drvs(filename
, newprefix
))
183 else if ((ext
= strrchr(dent
->filename
, '.')) != NULL
&&
184 (!strcmp(ext
, ".drv") || !strcmp(ext
, ".drv.gz")))
186 // List the PPDs in this driver info file...
187 ppdcSource
*src
= new ppdcSource(filename
);
190 snprintf(newprefix
, sizeof(newprefix
), "%s%s", prefix
, dent
->filename
);
191 list_ppds(src
, newprefix
);
203 // 'list_ppds()' - List PPDs in a driver info file.
206 static int // O - Exit status
207 list_ppds(ppdcSource
*src
, // I - Driver info file
208 const char *name
) // I - Name of driver info file
210 ppdcDriver
*d
; // Current driver
211 ppdcAttr
*attr
; // 1284DeviceID attribute
212 char uri
[1024]; // Driver URI
215 for (d
= (ppdcDriver
*)src
->drivers
->first();
217 d
= (ppdcDriver
*)src
->drivers
->next())
219 httpAssembleURIf(HTTP_URI_CODING_ALL
, uri
, sizeof(uri
), "drv", "", "", 0,
220 "%s/%s", name
, d
->pc_file_name
->value
);
222 attr
= d
->find_attr("1284DeviceID", NULL
);
224 printf("\"%s\" en \"%s\" \"%s\" \"%s\"\n", uri
, d
->manufacturer
->value
,
225 d
->model_name
->value
, attr
? attr
->value
->value
: "");
238 // Scan the command-line...
244 comp
= PPDC_NO_COMPRESSION
;
247 for (i
= 1; i
< argc
; i
++)
248 if (argv
[i
][0] == '-')
250 for (opt
= argv
[i
] + 1; *opt
; opt
++)
253 case 'c' : // Message catalog...
259 printf("ppdc: Loading messages from \"%s\"...\n", argv
[i
]);
262 catalog
= new ppdcCatalog("en");
264 if (catalog
->load_messages(argv
[i
]))
267 "ppdc: Unable to load localization file \"%s\" - %s\n",
268 argv
[i
], strerror(errno
));
273 case 'd' : // Output directory...
279 printf("ppdc: Writing PPD files to directory \"%s\"...\n",
285 case 'l' : // Language(s)...
290 if (strchr(argv
[i
], ','))
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
298 locales
= new ppdcArray();
300 strlcpy(temp
, argv
[i
], sizeof(temp
));
301 for (start
= temp
; *start
; start
= end
)
303 if ((end
= strchr(start
, ',')) != NULL
)
306 end
= start
+ strlen(start
);
309 locales
->add(new ppdcString(start
));
315 printf("ppdc: Loading messages for locale \"%s\"...\n",
321 catalog
= new ppdcCatalog(argv
[i
]);
323 if (catalog
->messages
->count
== 0)
326 "ppdc: Unable to find localization for \"%s\" - %s\n",
327 argv
[i
], strerror(errno
));
333 case 'I' : // Include directory...
339 printf("ppdc: Adding include directory \"%s\"...\n", argv
[i
]);
341 ppdcSource::add_include(argv
[i
]);
344 case 'v' : // Be verbose...
348 case 'z' : // Compress files...
349 comp
= PPDC_GZIP_COMPRESSION
;
352 case '-' : // --option
353 if (!strcmp(opt
, "-lf"))
356 opt
+= strlen(opt
) - 1;
359 else if (!strcmp(opt
, "-cr"))
362 opt
+= strlen(opt
) - 1;
365 else if (!strcmp(opt
, "-crlf"))
368 opt
+= strlen(opt
) - 1;
379 // Open and load the driver info file...
381 printf("ppdc: Loading driver information file \"%s\"...\n", argv
[i
]);
383 src
= new ppdcSource(argv
[i
]);
385 // Create the output directory...
386 if (mkdir(outdir
, 0777))
390 fprintf(stderr
, "ppdc: Unable to create output directory %s: %s\n",
391 outdir
, strerror(errno
));
396 // Write PPD files...
397 for (d
= (ppdcDriver
*)src
->drivers
->first();
399 d
= (ppdcDriver
*)src
->drivers
->next())
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
]);
405 pcfilename
[j
] = '\0';
407 if (comp
== PPDC_GZIP_COMPRESSION
)
408 snprintf(filename
, sizeof(filename
), "%s/%s.gz", outdir
, pcfilename
);
410 snprintf(filename
, sizeof(filename
), "%s/%s", outdir
, pcfilename
);
413 printf("ppdc: Writing %s...\n", filename
);
415 if (d
->write_ppd_file(filename
, catalog
, locales
, src
, le
, comp
))
419 // Delete the printer driver information...
426 // If no drivers have been loaded, display the program usage message.
430 // Return with no errors.