1 /*
2 * PPD file generation program for the CUPS drivers.
3 *
4 * Copyright 1993-2008 by Mike Sweet and Robert Krawitz.
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but
12 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <https://www.gnu.org/licenses/>.
18 *
19 * Contents:
20 *
21 * main() - Process files on the command-line...
22 * cat_ppd() - Copy the named PPD to stdout.
23 * generate_ppd() - Generate a PPD file.
24 * getlangs() - Get a list of available translations.
25 * help() - Show detailed help.
26 * is_special_option() - Determine if an option should be grouped.
27 * list_ppds() - List the available drivers.
28 * print_group_close() - Close a UI group.
29 * print_group_open() - Open a new UI group.
30 * printlangs() - Print list of available translations.
31 * printmodels() - Print a list of available models.
32 * usage() - Show program usage.
33 * write_ppd() - Write a PPD file.
34 */
35
36 /*
37 * 'main()' - Process files on the command-line...
38 */
39
40 #include "genppd.h"
41
42 static int cat_ppd(const char *uri);
43 static int list_ppds(const char *argv0);
44
45
46 int /* O - Exit status */
main(int argc,char * argv[])47 main(int argc, /* I - Number of command-line arguments */
48 char *argv[]) /* I - Command-line arguments */
49 {
50 /*
51 * Force POSIX locale, since stp_init incorrectly calls setlocale...
52 */
53
54 (void) setenv("LANG", "C", 1);
55 (void) setenv("LC_ALL", "C", 1);
56 (void) setenv("LC_NUMERIC", "C", 1);
57
58 /*
59 * Initialise libgutenprint
60 */
61
62 stp_init();
63
64 /*
65 * Process command-line...
66 */
67
68 if (argc == 2 && !strcmp(argv[1], "list"))
69 return (list_ppds(argv[0]));
70 else if (argc == 3 && !strcmp(argv[1], "cat"))
71 return (cat_ppd(argv[2]));
72 else if (argc == 2 && !strcmp(argv[1], "org.gutenprint.multicat"))
73 {
74 char buf[1024];
75 int status = 0;
76 while (fgets(buf, sizeof(buf) - 1, stdin))
77 {
78 size_t len = strlen(buf);
79 if (len == 0)
80 continue;
81 if (buf[len - 1] == '\n')
82 buf[len - 1] = '\0';
83 status |= cat_ppd(buf);
84 fputs("*%*%EOFEOF\n", stdout);
85 (void) fflush(stdout);
86 }
87 }
88 else if (argc == 2 && !strcmp(argv[1], "VERSION"))
89 {
90 printf("%s\n", VERSION);
91 return (0);
92 }
93 else if (argc == 2 && !strcasecmp(argv[1], "org.gutenprint.extensions"))
94 {
95 printf("org.gutenprint.multicat");
96 return (0);
97 }
98 else
99 {
100 fprintf(stderr, "Usage: %s list\n", argv[0]);
101 fprintf(stderr, " %s cat URI\n", argv[0]);
102 return (1);
103 }
104 return (0);
105 }
106
107
108 /*
109 * 'cat_ppd()' - Copy the named PPD to stdout.
110 */
111
112 static int /* O - Exit status */
cat_ppd(const char * uri)113 cat_ppd(const char *uri) /* I - Driver URI */
114 {
115 char scheme[64], /* URI scheme */
116 userpass[32], /* URI user/pass (unused) */
117 hostname[32], /* URI hostname */
118 resource[1024]; /* URI resource */
119 int port; /* URI port (unused) */
120 http_uri_status_t status; /* URI decode status */
121 const stp_printer_t *p; /* Printer driver */
122 const char *lang = NULL;
123 char *s;
124 char filename[1024], /* Filename */
125 ppd_location[2048]; /* Installed location */
126 const char *infix = "";
127 ppd_type_t ppd_type = PPD_STANDARD;
128 gpfile outFD;
129
130 if ((status = httpSeparateURI(HTTP_URI_CODING_ALL, uri,
131 scheme, sizeof(scheme),
132 userpass, sizeof(userpass),
133 hostname, sizeof(hostname),
134 &port, resource, sizeof(resource)))
135 < HTTP_URI_OK)
136 {
137 fprintf(stderr, "ERROR: Bad ppd-name \"%s\" (%d)!\n", uri, status);
138 return (1);
139 }
140
141 if (strcmp(scheme, "gutenprint." GUTENPRINT_RELEASE_VERSION) != 0)
142 {
143 fprintf(stderr, "ERROR: Gutenprint version mismatch!\n");
144 return(1);
145 }
146
147 s = strchr(resource + 1, '/');
148 if (s)
149 {
150 lang = s + 1;
151 *s = '\0';
152 }
153
154 if ((p = stp_get_printer_by_driver(hostname)) == NULL)
155 {
156 fprintf(stderr, "ERROR: Unable to find driver \"%s\"!\n", hostname);
157 return (1);
158 }
159
160 if (strcmp(resource + 1, "simple") == 0)
161 {
162 infix = ".sim";
163 ppd_type = PPD_SIMPLIFIED;
164 }
165 else if (strcmp(resource + 1, "nocolor") == 0)
166 {
167 infix = ".nc";
168 ppd_type = PPD_NO_COLOR_OPTS;
169 }
170
171 /*
172 * This isn't really the right thing to do. We really shouldn't
173 * be embedding filenames in automatically generated PPD files, but
174 * if the user ever decides to go back from generated PPD files to
175 * static PPD files we'll need to have this for genppdupdate to work.
176 */
177 snprintf(filename, sizeof(filename) - 1, "stp-%s.%s%s%s",
178 hostname, GUTENPRINT_RELEASE_VERSION, infix, ppdext);
179 snprintf(ppd_location, sizeof(ppd_location) - 1, "%s%s%s/ppd/%s%s",
180 cups_modeldir,
181 cups_modeldir[strlen(cups_modeldir) - 1] == '/' ? "" : "/",
182 lang ? lang : "C",
183 filename, gpext);
184
185 outFD.f = stdout;
186 return (write_ppd(&outFD, p, lang, ppd_location, ppd_type, filename, 0));
187 }
188
189 /*
190 * 'list_ppds()' - List the available drivers.
191 */
192
193 static int /* O - Exit status */
list_ppds(const char * argv0)194 list_ppds(const char *argv0) /* I - Name of program */
195 {
196 const char *scheme; /* URI scheme */
197 int i; /* Looping var */
198 const stp_printer_t *printer; /* Pointer to printer driver */
199
200 if ((scheme = strrchr(argv0, '/')) != NULL)
201 scheme ++;
202 else
203 scheme = argv0;
204
205 for (i = 0; i < stp_printer_model_count(); i++)
206 if ((printer = stp_get_printer_by_index(i)) != NULL)
207 {
208 const char *device_id;
209 if (!strcmp(stp_printer_get_family(printer), "ps") ||
210 !strcmp(stp_printer_get_family(printer), "raw"))
211 continue;
212
213 device_id = stp_printer_get_device_id(printer);
214 printf("\"%s://%s/expert\" "
215 "%s "
216 "\"%s\" "
217 "\"%s" CUPS_PPD_NICKNAME_STRING VERSION "\" "
218 "\"%s\"\n",
219 scheme, stp_printer_get_driver(printer),
220 "en",
221 stp_printer_get_manufacturer(printer),
222 stp_printer_get_long_name(printer),
223 device_id ? device_id : "");
224
225 #ifdef GENERATE_SIMPLIFIED_PPDS
226 printf("\"%s://%s/simple\" "
227 "%s "
228 "\"%s\" "
229 "\"%s" CUPS_PPD_NICKNAME_STRING VERSION " Simplified\" "
230 "\"%s\"\n",
231 scheme, stp_printer_get_driver(printer),
232 "en",
233 stp_printer_get_manufacturer(printer),
234 stp_printer_get_long_name(printer),
235 device_id ? device_id : "");
236 #endif
237
238 #ifdef GENERATE_NOCOLOR_PPDS
239 printf("\"%s://%s/nocolor\" "
240 "%s "
241 "\"%s\" "
242 "\"%s" CUPS_PPD_NICKNAME_STRING VERSION " No color options\" "
243 "\"%s\"\n",
244 scheme, stp_printer_get_driver(printer),
245 "en",
246 stp_printer_get_manufacturer(printer),
247 stp_printer_get_long_name(printer),
248 device_id ? device_id : "");
249 #endif
250 }
251
252 return (0);
253 }
254