xref: /aosp_15_r20/external/libcups/ppdc/ppdc.cxx (revision 5e7646d21f1134fb0638875d812ef646c12ab91e)
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