1*5e7646d2SAndroid Build Coastguard Worker //
2*5e7646d2SAndroid Build Coastguard Worker // PPD file compiler main entry for the CUPS PPD Compiler.
3*5e7646d2SAndroid Build Coastguard Worker //
4*5e7646d2SAndroid Build Coastguard Worker // Copyright 2007-2014 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker // Copyright 2002-2007 by Easy Software Products.
6*5e7646d2SAndroid Build Coastguard Worker //
7*5e7646d2SAndroid Build Coastguard Worker // Licensed under Apache License v2.0. See the file "LICENSE" for more information.
8*5e7646d2SAndroid Build Coastguard Worker //
9*5e7646d2SAndroid Build Coastguard Worker
10*5e7646d2SAndroid Build Coastguard Worker //
11*5e7646d2SAndroid Build Coastguard Worker // Include necessary headers...
12*5e7646d2SAndroid Build Coastguard Worker //
13*5e7646d2SAndroid Build Coastguard Worker
14*5e7646d2SAndroid Build Coastguard Worker #include "ppdc-private.h"
15*5e7646d2SAndroid Build Coastguard Worker #include <unistd.h>
16*5e7646d2SAndroid Build Coastguard Worker #include <sys/stat.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <sys/types.h>
18*5e7646d2SAndroid Build Coastguard Worker
19*5e7646d2SAndroid Build Coastguard Worker
20*5e7646d2SAndroid Build Coastguard Worker //
21*5e7646d2SAndroid Build Coastguard Worker // Local functions...
22*5e7646d2SAndroid Build Coastguard Worker //
23*5e7646d2SAndroid Build Coastguard Worker
24*5e7646d2SAndroid Build Coastguard Worker static void usage(void) _CUPS_NORETURN;
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker //
28*5e7646d2SAndroid Build Coastguard Worker // 'main()' - Main entry for the PPD compiler.
29*5e7646d2SAndroid Build Coastguard Worker //
30*5e7646d2SAndroid Build Coastguard Worker
31*5e7646d2SAndroid Build Coastguard Worker int // O - Exit status
main(int argc,char * argv[])32*5e7646d2SAndroid Build Coastguard Worker main(int argc, // I - Number of command-line arguments
33*5e7646d2SAndroid Build Coastguard Worker char *argv[]) // I - Command-line arguments
34*5e7646d2SAndroid Build Coastguard Worker {
35*5e7646d2SAndroid Build Coastguard Worker int i, j; // Looping vars
36*5e7646d2SAndroid Build Coastguard Worker ppdcCatalog *catalog; // Message catalog
37*5e7646d2SAndroid Build Coastguard Worker const char *outdir; // Output directory
38*5e7646d2SAndroid Build Coastguard Worker ppdcSource *src; // PPD source file data
39*5e7646d2SAndroid Build Coastguard Worker ppdcDriver *d; // Current driver
40*5e7646d2SAndroid Build Coastguard Worker cups_file_t *fp; // PPD file
41*5e7646d2SAndroid Build Coastguard Worker char *opt, // Current option
42*5e7646d2SAndroid Build Coastguard Worker *value, // Value in option
43*5e7646d2SAndroid Build Coastguard Worker *outname, // Output filename
44*5e7646d2SAndroid Build Coastguard Worker make_model[1024],
45*5e7646d2SAndroid Build Coastguard Worker // Make and model
46*5e7646d2SAndroid Build Coastguard Worker pcfilename[1024],
47*5e7646d2SAndroid Build Coastguard Worker // Lowercase pcfilename
48*5e7646d2SAndroid Build Coastguard Worker filename[1024]; // PPD filename
49*5e7646d2SAndroid Build Coastguard Worker int comp, // Compress
50*5e7646d2SAndroid Build Coastguard Worker do_test, // Test PPD files
51*5e7646d2SAndroid Build Coastguard Worker single_language,// Generate single-language files
52*5e7646d2SAndroid Build Coastguard Worker use_model_name, // Use ModelName for filename
53*5e7646d2SAndroid Build Coastguard Worker verbose; // Verbosity
54*5e7646d2SAndroid Build Coastguard Worker ppdcLineEnding le; // Line ending to use
55*5e7646d2SAndroid Build Coastguard Worker ppdcArray *locales; // List of locales
56*5e7646d2SAndroid Build Coastguard Worker cups_array_t *filenames; // List of generated filenames
57*5e7646d2SAndroid Build Coastguard Worker
58*5e7646d2SAndroid Build Coastguard Worker
59*5e7646d2SAndroid Build Coastguard Worker _cupsSetLocale(argv);
60*5e7646d2SAndroid Build Coastguard Worker
61*5e7646d2SAndroid Build Coastguard Worker // Scan the command-line...
62*5e7646d2SAndroid Build Coastguard Worker catalog = NULL;
63*5e7646d2SAndroid Build Coastguard Worker comp = 0;
64*5e7646d2SAndroid Build Coastguard Worker do_test = 0;
65*5e7646d2SAndroid Build Coastguard Worker le = PPDC_LFONLY;
66*5e7646d2SAndroid Build Coastguard Worker locales = NULL;
67*5e7646d2SAndroid Build Coastguard Worker outdir = "ppd";
68*5e7646d2SAndroid Build Coastguard Worker single_language = 0;
69*5e7646d2SAndroid Build Coastguard Worker src = new ppdcSource();
70*5e7646d2SAndroid Build Coastguard Worker use_model_name = 0;
71*5e7646d2SAndroid Build Coastguard Worker verbose = 0;
72*5e7646d2SAndroid Build Coastguard Worker filenames = cupsArrayNew((cups_array_func_t)_cups_strcasecmp, NULL);
73*5e7646d2SAndroid Build Coastguard Worker
74*5e7646d2SAndroid Build Coastguard Worker for (i = 1; i < argc; i ++)
75*5e7646d2SAndroid Build Coastguard Worker if (argv[i][0] == '-')
76*5e7646d2SAndroid Build Coastguard Worker {
77*5e7646d2SAndroid Build Coastguard Worker for (opt = argv[i] + 1; *opt; opt ++)
78*5e7646d2SAndroid Build Coastguard Worker switch (*opt)
79*5e7646d2SAndroid Build Coastguard Worker {
80*5e7646d2SAndroid Build Coastguard Worker case 'D' : // Define variable
81*5e7646d2SAndroid Build Coastguard Worker i ++;
82*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
83*5e7646d2SAndroid Build Coastguard Worker usage();
84*5e7646d2SAndroid Build Coastguard Worker
85*5e7646d2SAndroid Build Coastguard Worker if ((value = strchr(argv[i], '=')) != NULL)
86*5e7646d2SAndroid Build Coastguard Worker {
87*5e7646d2SAndroid Build Coastguard Worker *value++ = '\0';
88*5e7646d2SAndroid Build Coastguard Worker
89*5e7646d2SAndroid Build Coastguard Worker src->set_variable(argv[i], value);
90*5e7646d2SAndroid Build Coastguard Worker }
91*5e7646d2SAndroid Build Coastguard Worker else
92*5e7646d2SAndroid Build Coastguard Worker src->set_variable(argv[i], "1");
93*5e7646d2SAndroid Build Coastguard Worker break;
94*5e7646d2SAndroid Build Coastguard Worker
95*5e7646d2SAndroid Build Coastguard Worker case 'I' : // Include directory...
96*5e7646d2SAndroid Build Coastguard Worker i ++;
97*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
98*5e7646d2SAndroid Build Coastguard Worker usage();
99*5e7646d2SAndroid Build Coastguard Worker
100*5e7646d2SAndroid Build Coastguard Worker if (verbose > 1)
101*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stdout,
102*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Adding include directory \"%s\"."),
103*5e7646d2SAndroid Build Coastguard Worker argv[i]);
104*5e7646d2SAndroid Build Coastguard Worker
105*5e7646d2SAndroid Build Coastguard Worker ppdcSource::add_include(argv[i]);
106*5e7646d2SAndroid Build Coastguard Worker break;
107*5e7646d2SAndroid Build Coastguard Worker
108*5e7646d2SAndroid Build Coastguard Worker case 'c' : // Message catalog...
109*5e7646d2SAndroid Build Coastguard Worker i ++;
110*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
111*5e7646d2SAndroid Build Coastguard Worker usage();
112*5e7646d2SAndroid Build Coastguard Worker
113*5e7646d2SAndroid Build Coastguard Worker if (verbose > 1)
114*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stdout,
115*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Loading messages from \"%s\"."),
116*5e7646d2SAndroid Build Coastguard Worker argv[i]);
117*5e7646d2SAndroid Build Coastguard Worker
118*5e7646d2SAndroid Build Coastguard Worker if (!catalog)
119*5e7646d2SAndroid Build Coastguard Worker catalog = new ppdcCatalog("en");
120*5e7646d2SAndroid Build Coastguard Worker
121*5e7646d2SAndroid Build Coastguard Worker if (catalog->load_messages(argv[i]))
122*5e7646d2SAndroid Build Coastguard Worker {
123*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
124*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Unable to load localization file "
125*5e7646d2SAndroid Build Coastguard Worker "\"%s\" - %s"), argv[i], strerror(errno));
126*5e7646d2SAndroid Build Coastguard Worker return (1);
127*5e7646d2SAndroid Build Coastguard Worker }
128*5e7646d2SAndroid Build Coastguard Worker break;
129*5e7646d2SAndroid Build Coastguard Worker
130*5e7646d2SAndroid Build Coastguard Worker case 'd' : // Output directory...
131*5e7646d2SAndroid Build Coastguard Worker i ++;
132*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
133*5e7646d2SAndroid Build Coastguard Worker usage();
134*5e7646d2SAndroid Build Coastguard Worker
135*5e7646d2SAndroid Build Coastguard Worker if (verbose > 1)
136*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stdout,
137*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Writing PPD files to directory "
138*5e7646d2SAndroid Build Coastguard Worker "\"%s\"."), argv[i]);
139*5e7646d2SAndroid Build Coastguard Worker
140*5e7646d2SAndroid Build Coastguard Worker outdir = argv[i];
141*5e7646d2SAndroid Build Coastguard Worker break;
142*5e7646d2SAndroid Build Coastguard Worker
143*5e7646d2SAndroid Build Coastguard Worker case 'l' : // Language(s)...
144*5e7646d2SAndroid Build Coastguard Worker i ++;
145*5e7646d2SAndroid Build Coastguard Worker if (i >= argc)
146*5e7646d2SAndroid Build Coastguard Worker usage();
147*5e7646d2SAndroid Build Coastguard Worker
148*5e7646d2SAndroid Build Coastguard Worker if (strchr(argv[i], ','))
149*5e7646d2SAndroid Build Coastguard Worker {
150*5e7646d2SAndroid Build Coastguard Worker // Comma-delimited list of languages...
151*5e7646d2SAndroid Build Coastguard Worker char temp[1024], // Copy of language list
152*5e7646d2SAndroid Build Coastguard Worker *start, // Start of current locale name
153*5e7646d2SAndroid Build Coastguard Worker *end; // End of current locale name
154*5e7646d2SAndroid Build Coastguard Worker
155*5e7646d2SAndroid Build Coastguard Worker
156*5e7646d2SAndroid Build Coastguard Worker locales = new ppdcArray();
157*5e7646d2SAndroid Build Coastguard Worker
158*5e7646d2SAndroid Build Coastguard Worker strlcpy(temp, argv[i], sizeof(temp));
159*5e7646d2SAndroid Build Coastguard Worker for (start = temp; *start; start = end)
160*5e7646d2SAndroid Build Coastguard Worker {
161*5e7646d2SAndroid Build Coastguard Worker if ((end = strchr(start, ',')) != NULL)
162*5e7646d2SAndroid Build Coastguard Worker *end++ = '\0';
163*5e7646d2SAndroid Build Coastguard Worker else
164*5e7646d2SAndroid Build Coastguard Worker end = start + strlen(start);
165*5e7646d2SAndroid Build Coastguard Worker
166*5e7646d2SAndroid Build Coastguard Worker if (end > start)
167*5e7646d2SAndroid Build Coastguard Worker locales->add(new ppdcString(start));
168*5e7646d2SAndroid Build Coastguard Worker }
169*5e7646d2SAndroid Build Coastguard Worker }
170*5e7646d2SAndroid Build Coastguard Worker else
171*5e7646d2SAndroid Build Coastguard Worker {
172*5e7646d2SAndroid Build Coastguard Worker single_language = 1;
173*5e7646d2SAndroid Build Coastguard Worker
174*5e7646d2SAndroid Build Coastguard Worker if (verbose > 1)
175*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stdout,
176*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Loading messages for locale "
177*5e7646d2SAndroid Build Coastguard Worker "\"%s\"."), argv[i]);
178*5e7646d2SAndroid Build Coastguard Worker
179*5e7646d2SAndroid Build Coastguard Worker if (catalog)
180*5e7646d2SAndroid Build Coastguard Worker catalog->release();
181*5e7646d2SAndroid Build Coastguard Worker
182*5e7646d2SAndroid Build Coastguard Worker catalog = new ppdcCatalog(argv[i]);
183*5e7646d2SAndroid Build Coastguard Worker
184*5e7646d2SAndroid Build Coastguard Worker if (catalog->messages->count == 0 && strcmp(argv[i], "en"))
185*5e7646d2SAndroid Build Coastguard Worker {
186*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
187*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Unable to find localization for "
188*5e7646d2SAndroid Build Coastguard Worker "\"%s\" - %s"), argv[i], strerror(errno));
189*5e7646d2SAndroid Build Coastguard Worker return (1);
190*5e7646d2SAndroid Build Coastguard Worker }
191*5e7646d2SAndroid Build Coastguard Worker }
192*5e7646d2SAndroid Build Coastguard Worker break;
193*5e7646d2SAndroid Build Coastguard Worker
194*5e7646d2SAndroid Build Coastguard Worker case 'm' : // Use ModelName for filename
195*5e7646d2SAndroid Build Coastguard Worker use_model_name = 1;
196*5e7646d2SAndroid Build Coastguard Worker break;
197*5e7646d2SAndroid Build Coastguard Worker
198*5e7646d2SAndroid Build Coastguard Worker case 't' : // Test PPDs instead of generating them
199*5e7646d2SAndroid Build Coastguard Worker do_test = 1;
200*5e7646d2SAndroid Build Coastguard Worker break;
201*5e7646d2SAndroid Build Coastguard Worker
202*5e7646d2SAndroid Build Coastguard Worker case 'v' : // Be verbose...
203*5e7646d2SAndroid Build Coastguard Worker verbose ++;
204*5e7646d2SAndroid Build Coastguard Worker break;
205*5e7646d2SAndroid Build Coastguard Worker
206*5e7646d2SAndroid Build Coastguard Worker case 'z' : // Compress files...
207*5e7646d2SAndroid Build Coastguard Worker comp = 1;
208*5e7646d2SAndroid Build Coastguard Worker break;
209*5e7646d2SAndroid Build Coastguard Worker
210*5e7646d2SAndroid Build Coastguard Worker case '-' : // --option
211*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(opt, "-lf"))
212*5e7646d2SAndroid Build Coastguard Worker {
213*5e7646d2SAndroid Build Coastguard Worker le = PPDC_LFONLY;
214*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
215*5e7646d2SAndroid Build Coastguard Worker break;
216*5e7646d2SAndroid Build Coastguard Worker }
217*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(opt, "-cr"))
218*5e7646d2SAndroid Build Coastguard Worker {
219*5e7646d2SAndroid Build Coastguard Worker le = PPDC_CRONLY;
220*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
221*5e7646d2SAndroid Build Coastguard Worker break;
222*5e7646d2SAndroid Build Coastguard Worker }
223*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(opt, "-crlf"))
224*5e7646d2SAndroid Build Coastguard Worker {
225*5e7646d2SAndroid Build Coastguard Worker le = PPDC_CRLF;
226*5e7646d2SAndroid Build Coastguard Worker opt += strlen(opt) - 1;
227*5e7646d2SAndroid Build Coastguard Worker break;
228*5e7646d2SAndroid Build Coastguard Worker }
229*5e7646d2SAndroid Build Coastguard Worker
230*5e7646d2SAndroid Build Coastguard Worker default : // Unknown
231*5e7646d2SAndroid Build Coastguard Worker usage();
232*5e7646d2SAndroid Build Coastguard Worker }
233*5e7646d2SAndroid Build Coastguard Worker }
234*5e7646d2SAndroid Build Coastguard Worker else
235*5e7646d2SAndroid Build Coastguard Worker {
236*5e7646d2SAndroid Build Coastguard Worker // Open and load the driver info file...
237*5e7646d2SAndroid Build Coastguard Worker if (verbose > 1)
238*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stdout,
239*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Loading driver information file \"%s\"."),
240*5e7646d2SAndroid Build Coastguard Worker argv[i]);
241*5e7646d2SAndroid Build Coastguard Worker
242*5e7646d2SAndroid Build Coastguard Worker src->read_file(argv[i]);
243*5e7646d2SAndroid Build Coastguard Worker }
244*5e7646d2SAndroid Build Coastguard Worker
245*5e7646d2SAndroid Build Coastguard Worker
246*5e7646d2SAndroid Build Coastguard Worker if (src->drivers->count > 0)
247*5e7646d2SAndroid Build Coastguard Worker {
248*5e7646d2SAndroid Build Coastguard Worker // Create the output directory...
249*5e7646d2SAndroid Build Coastguard Worker if (mkdir(outdir, 0777))
250*5e7646d2SAndroid Build Coastguard Worker {
251*5e7646d2SAndroid Build Coastguard Worker if (errno != EEXIST)
252*5e7646d2SAndroid Build Coastguard Worker {
253*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
254*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Unable to create output directory %s: %s"),
255*5e7646d2SAndroid Build Coastguard Worker outdir, strerror(errno));
256*5e7646d2SAndroid Build Coastguard Worker return (1);
257*5e7646d2SAndroid Build Coastguard Worker }
258*5e7646d2SAndroid Build Coastguard Worker }
259*5e7646d2SAndroid Build Coastguard Worker
260*5e7646d2SAndroid Build Coastguard Worker // Write PPD files...
261*5e7646d2SAndroid Build Coastguard Worker for (d = (ppdcDriver *)src->drivers->first();
262*5e7646d2SAndroid Build Coastguard Worker d;
263*5e7646d2SAndroid Build Coastguard Worker d = (ppdcDriver *)src->drivers->next())
264*5e7646d2SAndroid Build Coastguard Worker {
265*5e7646d2SAndroid Build Coastguard Worker if (do_test)
266*5e7646d2SAndroid Build Coastguard Worker {
267*5e7646d2SAndroid Build Coastguard Worker // Test the PPD file for this driver...
268*5e7646d2SAndroid Build Coastguard Worker int pid, // Process ID
269*5e7646d2SAndroid Build Coastguard Worker fds[2]; // Pipe file descriptors
270*5e7646d2SAndroid Build Coastguard Worker
271*5e7646d2SAndroid Build Coastguard Worker
272*5e7646d2SAndroid Build Coastguard Worker if (pipe(fds))
273*5e7646d2SAndroid Build Coastguard Worker {
274*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
275*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Unable to create output pipes: %s"),
276*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
277*5e7646d2SAndroid Build Coastguard Worker return (1);
278*5e7646d2SAndroid Build Coastguard Worker }
279*5e7646d2SAndroid Build Coastguard Worker
280*5e7646d2SAndroid Build Coastguard Worker if ((pid = fork()) == 0)
281*5e7646d2SAndroid Build Coastguard Worker {
282*5e7646d2SAndroid Build Coastguard Worker // Child process comes here...
283*5e7646d2SAndroid Build Coastguard Worker dup2(fds[0], 0);
284*5e7646d2SAndroid Build Coastguard Worker
285*5e7646d2SAndroid Build Coastguard Worker close(fds[0]);
286*5e7646d2SAndroid Build Coastguard Worker close(fds[1]);
287*5e7646d2SAndroid Build Coastguard Worker
288*5e7646d2SAndroid Build Coastguard Worker execlp("cupstestppd", "cupstestppd", "-", (char *)0);
289*5e7646d2SAndroid Build Coastguard Worker
290*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
291*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Unable to execute cupstestppd: %s"),
292*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
293*5e7646d2SAndroid Build Coastguard Worker return (errno);
294*5e7646d2SAndroid Build Coastguard Worker }
295*5e7646d2SAndroid Build Coastguard Worker else if (pid < 0)
296*5e7646d2SAndroid Build Coastguard Worker {
297*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr, _("ppdc: Unable to execute cupstestppd: %s"),
298*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
299*5e7646d2SAndroid Build Coastguard Worker return (errno);
300*5e7646d2SAndroid Build Coastguard Worker }
301*5e7646d2SAndroid Build Coastguard Worker
302*5e7646d2SAndroid Build Coastguard Worker close(fds[0]);
303*5e7646d2SAndroid Build Coastguard Worker fp = cupsFileOpenFd(fds[1], "w");
304*5e7646d2SAndroid Build Coastguard Worker }
305*5e7646d2SAndroid Build Coastguard Worker else
306*5e7646d2SAndroid Build Coastguard Worker {
307*5e7646d2SAndroid Build Coastguard Worker // Write the PPD file for this driver...
308*5e7646d2SAndroid Build Coastguard Worker if (use_model_name)
309*5e7646d2SAndroid Build Coastguard Worker {
310*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(d->model_name->value, d->manufacturer->value,
311*5e7646d2SAndroid Build Coastguard Worker strlen(d->manufacturer->value)))
312*5e7646d2SAndroid Build Coastguard Worker {
313*5e7646d2SAndroid Build Coastguard Worker // Model name already starts with the manufacturer...
314*5e7646d2SAndroid Build Coastguard Worker outname = d->model_name->value;
315*5e7646d2SAndroid Build Coastguard Worker }
316*5e7646d2SAndroid Build Coastguard Worker else
317*5e7646d2SAndroid Build Coastguard Worker {
318*5e7646d2SAndroid Build Coastguard Worker // Add manufacturer to the front of the model name...
319*5e7646d2SAndroid Build Coastguard Worker snprintf(make_model, sizeof(make_model), "%s %s",
320*5e7646d2SAndroid Build Coastguard Worker d->manufacturer->value, d->model_name->value);
321*5e7646d2SAndroid Build Coastguard Worker outname = make_model;
322*5e7646d2SAndroid Build Coastguard Worker }
323*5e7646d2SAndroid Build Coastguard Worker }
324*5e7646d2SAndroid Build Coastguard Worker else if (d->file_name)
325*5e7646d2SAndroid Build Coastguard Worker outname = d->file_name->value;
326*5e7646d2SAndroid Build Coastguard Worker else
327*5e7646d2SAndroid Build Coastguard Worker outname = d->pc_file_name->value;
328*5e7646d2SAndroid Build Coastguard Worker
329*5e7646d2SAndroid Build Coastguard Worker if (strstr(outname, ".PPD"))
330*5e7646d2SAndroid Build Coastguard Worker {
331*5e7646d2SAndroid Build Coastguard Worker // Convert PCFileName to lowercase...
332*5e7646d2SAndroid Build Coastguard Worker for (j = 0;
333*5e7646d2SAndroid Build Coastguard Worker outname[j] && j < (int)(sizeof(pcfilename) - 1);
334*5e7646d2SAndroid Build Coastguard Worker j ++)
335*5e7646d2SAndroid Build Coastguard Worker pcfilename[j] = (char)tolower(outname[j] & 255);
336*5e7646d2SAndroid Build Coastguard Worker
337*5e7646d2SAndroid Build Coastguard Worker pcfilename[j] = '\0';
338*5e7646d2SAndroid Build Coastguard Worker }
339*5e7646d2SAndroid Build Coastguard Worker else
340*5e7646d2SAndroid Build Coastguard Worker {
341*5e7646d2SAndroid Build Coastguard Worker // Leave PCFileName as-is...
342*5e7646d2SAndroid Build Coastguard Worker strlcpy(pcfilename, outname, sizeof(pcfilename));
343*5e7646d2SAndroid Build Coastguard Worker }
344*5e7646d2SAndroid Build Coastguard Worker
345*5e7646d2SAndroid Build Coastguard Worker // Open the PPD file for writing...
346*5e7646d2SAndroid Build Coastguard Worker if (comp)
347*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/%s.gz", outdir, pcfilename);
348*5e7646d2SAndroid Build Coastguard Worker else
349*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/%s", outdir, pcfilename);
350*5e7646d2SAndroid Build Coastguard Worker
351*5e7646d2SAndroid Build Coastguard Worker if (cupsArrayFind(filenames, filename))
352*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
353*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Warning - overlapping filename \"%s\"."),
354*5e7646d2SAndroid Build Coastguard Worker filename);
355*5e7646d2SAndroid Build Coastguard Worker else
356*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(filenames, strdup(filename));
357*5e7646d2SAndroid Build Coastguard Worker
358*5e7646d2SAndroid Build Coastguard Worker fp = cupsFileOpen(filename, comp ? "w9" : "w");
359*5e7646d2SAndroid Build Coastguard Worker if (!fp)
360*5e7646d2SAndroid Build Coastguard Worker {
361*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stderr,
362*5e7646d2SAndroid Build Coastguard Worker _("ppdc: Unable to create PPD file \"%s\" - %s."),
363*5e7646d2SAndroid Build Coastguard Worker filename, strerror(errno));
364*5e7646d2SAndroid Build Coastguard Worker return (1);
365*5e7646d2SAndroid Build Coastguard Worker }
366*5e7646d2SAndroid Build Coastguard Worker
367*5e7646d2SAndroid Build Coastguard Worker if (verbose)
368*5e7646d2SAndroid Build Coastguard Worker _cupsLangPrintf(stdout, _("ppdc: Writing %s."), filename);
369*5e7646d2SAndroid Build Coastguard Worker }
370*5e7646d2SAndroid Build Coastguard Worker
371*5e7646d2SAndroid Build Coastguard Worker /*
372*5e7646d2SAndroid Build Coastguard Worker * Write the PPD file...
373*5e7646d2SAndroid Build Coastguard Worker */
374*5e7646d2SAndroid Build Coastguard Worker
375*5e7646d2SAndroid Build Coastguard Worker ppdcArray *templocales = locales;
376*5e7646d2SAndroid Build Coastguard Worker
377*5e7646d2SAndroid Build Coastguard Worker if (!templocales && !single_language)
378*5e7646d2SAndroid Build Coastguard Worker {
379*5e7646d2SAndroid Build Coastguard Worker templocales = new ppdcArray();
380*5e7646d2SAndroid Build Coastguard Worker for (ppdcCatalog *tempcatalog = (ppdcCatalog *)src->po_files->first();
381*5e7646d2SAndroid Build Coastguard Worker tempcatalog;
382*5e7646d2SAndroid Build Coastguard Worker tempcatalog = (ppdcCatalog *)src->po_files->next())
383*5e7646d2SAndroid Build Coastguard Worker {
384*5e7646d2SAndroid Build Coastguard Worker tempcatalog->locale->retain();
385*5e7646d2SAndroid Build Coastguard Worker templocales->add(tempcatalog->locale);
386*5e7646d2SAndroid Build Coastguard Worker }
387*5e7646d2SAndroid Build Coastguard Worker }
388*5e7646d2SAndroid Build Coastguard Worker
389*5e7646d2SAndroid Build Coastguard Worker if (d->write_ppd_file(fp, catalog, templocales, src, le))
390*5e7646d2SAndroid Build Coastguard Worker {
391*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
392*5e7646d2SAndroid Build Coastguard Worker return (1);
393*5e7646d2SAndroid Build Coastguard Worker }
394*5e7646d2SAndroid Build Coastguard Worker
395*5e7646d2SAndroid Build Coastguard Worker if (templocales && templocales != locales)
396*5e7646d2SAndroid Build Coastguard Worker templocales->release();
397*5e7646d2SAndroid Build Coastguard Worker
398*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(fp);
399*5e7646d2SAndroid Build Coastguard Worker }
400*5e7646d2SAndroid Build Coastguard Worker }
401*5e7646d2SAndroid Build Coastguard Worker else
402*5e7646d2SAndroid Build Coastguard Worker usage();
403*5e7646d2SAndroid Build Coastguard Worker
404*5e7646d2SAndroid Build Coastguard Worker // Delete the printer driver information...
405*5e7646d2SAndroid Build Coastguard Worker src->release();
406*5e7646d2SAndroid Build Coastguard Worker
407*5e7646d2SAndroid Build Coastguard Worker // Message catalog...
408*5e7646d2SAndroid Build Coastguard Worker if (catalog)
409*5e7646d2SAndroid Build Coastguard Worker catalog->release();
410*5e7646d2SAndroid Build Coastguard Worker
411*5e7646d2SAndroid Build Coastguard Worker // Return with no errors.
412*5e7646d2SAndroid Build Coastguard Worker return (0);
413*5e7646d2SAndroid Build Coastguard Worker }
414*5e7646d2SAndroid Build Coastguard Worker
415*5e7646d2SAndroid Build Coastguard Worker
416*5e7646d2SAndroid Build Coastguard Worker //
417*5e7646d2SAndroid Build Coastguard Worker // 'usage()' - Show usage and exit.
418*5e7646d2SAndroid Build Coastguard Worker //
419*5e7646d2SAndroid Build Coastguard Worker
420*5e7646d2SAndroid Build Coastguard Worker static void
usage(void)421*5e7646d2SAndroid Build Coastguard Worker usage(void)
422*5e7646d2SAndroid Build Coastguard Worker {
423*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Usage: ppdc [options] filename.drv [ ... "
424*5e7646d2SAndroid Build Coastguard Worker "filenameN.drv ]"));
425*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _("Options:"));
426*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -D name=value Set named variable to "
427*5e7646d2SAndroid Build Coastguard Worker "value."));
428*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -I include-dir Add include directory to "
429*5e7646d2SAndroid Build Coastguard Worker "search path."));
430*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -c catalog.po Load the specified "
431*5e7646d2SAndroid Build Coastguard Worker "message catalog."));
432*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -d output-dir Specify the output "
433*5e7646d2SAndroid Build Coastguard Worker "directory."));
434*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -l lang[,lang,...] Specify the output "
435*5e7646d2SAndroid Build Coastguard Worker "language(s) (locale)."));
436*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -m Use the ModelName value "
437*5e7646d2SAndroid Build Coastguard Worker "as the filename."));
438*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -t Test PPDs instead of "
439*5e7646d2SAndroid Build Coastguard Worker "generating them."));
440*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -v Be verbose."));
441*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" -z Compress PPD files using "
442*5e7646d2SAndroid Build Coastguard Worker "GNU zip."));
443*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" --cr End lines with CR (Mac "
444*5e7646d2SAndroid Build Coastguard Worker "OS 9)."));
445*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" --crlf End lines with CR + LF "
446*5e7646d2SAndroid Build Coastguard Worker "(Windows)."));
447*5e7646d2SAndroid Build Coastguard Worker _cupsLangPuts(stdout, _(" --lf End lines with LF "
448*5e7646d2SAndroid Build Coastguard Worker "(UNIX/Linux/macOS)."));
449*5e7646d2SAndroid Build Coastguard Worker
450*5e7646d2SAndroid Build Coastguard Worker exit(1);
451*5e7646d2SAndroid Build Coastguard Worker }
452