1*5e7646d2SAndroid Build Coastguard Worker /*
2*5e7646d2SAndroid Build Coastguard Worker * Administration CGI for CUPS.
3*5e7646d2SAndroid Build Coastguard Worker *
4*5e7646d2SAndroid Build Coastguard Worker * Copyright © 2007-2021 by Apple Inc.
5*5e7646d2SAndroid Build Coastguard Worker * Copyright © 1997-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
8*5e7646d2SAndroid Build Coastguard Worker * information.
9*5e7646d2SAndroid Build Coastguard Worker */
10*5e7646d2SAndroid Build Coastguard Worker
11*5e7646d2SAndroid Build Coastguard Worker /*
12*5e7646d2SAndroid Build Coastguard Worker * Include necessary headers...
13*5e7646d2SAndroid Build Coastguard Worker */
14*5e7646d2SAndroid Build Coastguard Worker
15*5e7646d2SAndroid Build Coastguard Worker #include "cgi-private.h"
16*5e7646d2SAndroid Build Coastguard Worker #include <cups/http-private.h>
17*5e7646d2SAndroid Build Coastguard Worker #include <cups/ppd-private.h>
18*5e7646d2SAndroid Build Coastguard Worker #include <cups/adminutil.h>
19*5e7646d2SAndroid Build Coastguard Worker #include <cups/ppd.h>
20*5e7646d2SAndroid Build Coastguard Worker #include <errno.h>
21*5e7646d2SAndroid Build Coastguard Worker #include <unistd.h>
22*5e7646d2SAndroid Build Coastguard Worker #include <fcntl.h>
23*5e7646d2SAndroid Build Coastguard Worker #include <sys/wait.h>
24*5e7646d2SAndroid Build Coastguard Worker #include <limits.h>
25*5e7646d2SAndroid Build Coastguard Worker
26*5e7646d2SAndroid Build Coastguard Worker
27*5e7646d2SAndroid Build Coastguard Worker /*
28*5e7646d2SAndroid Build Coastguard Worker * Local globals...
29*5e7646d2SAndroid Build Coastguard Worker */
30*5e7646d2SAndroid Build Coastguard Worker
31*5e7646d2SAndroid Build Coastguard Worker static int current_device = 0; /* Current device shown */
32*5e7646d2SAndroid Build Coastguard Worker
33*5e7646d2SAndroid Build Coastguard Worker
34*5e7646d2SAndroid Build Coastguard Worker /*
35*5e7646d2SAndroid Build Coastguard Worker * Local functions...
36*5e7646d2SAndroid Build Coastguard Worker */
37*5e7646d2SAndroid Build Coastguard Worker
38*5e7646d2SAndroid Build Coastguard Worker static void choose_device_cb(const char *device_class, const char *device_id, const char *device_info, const char *device_make_and_model, const char *device_uri, const char *device_location, const char *title);
39*5e7646d2SAndroid Build Coastguard Worker static void do_am_class(http_t *http, int modify);
40*5e7646d2SAndroid Build Coastguard Worker static void do_am_printer(http_t *http, int modify);
41*5e7646d2SAndroid Build Coastguard Worker static void do_config_server(http_t *http);
42*5e7646d2SAndroid Build Coastguard Worker static void do_delete_class(http_t *http);
43*5e7646d2SAndroid Build Coastguard Worker static void do_delete_printer(http_t *http);
44*5e7646d2SAndroid Build Coastguard Worker static void do_list_printers(http_t *http);
45*5e7646d2SAndroid Build Coastguard Worker static void do_menu(http_t *http);
46*5e7646d2SAndroid Build Coastguard Worker static void do_set_allowed_users(http_t *http);
47*5e7646d2SAndroid Build Coastguard Worker static void do_set_default(http_t *http);
48*5e7646d2SAndroid Build Coastguard Worker static void do_set_options(http_t *http, int is_class);
49*5e7646d2SAndroid Build Coastguard Worker static void do_set_sharing(http_t *http);
50*5e7646d2SAndroid Build Coastguard Worker static char *get_option_value(ppd_file_t *ppd, const char *name,
51*5e7646d2SAndroid Build Coastguard Worker char *buffer, size_t bufsize);
52*5e7646d2SAndroid Build Coastguard Worker static double get_points(double number, const char *uval);
53*5e7646d2SAndroid Build Coastguard Worker
54*5e7646d2SAndroid Build Coastguard Worker
55*5e7646d2SAndroid Build Coastguard Worker /*
56*5e7646d2SAndroid Build Coastguard Worker * 'main()' - Main entry for CGI.
57*5e7646d2SAndroid Build Coastguard Worker */
58*5e7646d2SAndroid Build Coastguard Worker
59*5e7646d2SAndroid Build Coastguard Worker int /* O - Exit status */
main(void)60*5e7646d2SAndroid Build Coastguard Worker main(void)
61*5e7646d2SAndroid Build Coastguard Worker {
62*5e7646d2SAndroid Build Coastguard Worker http_t *http; /* Connection to the server */
63*5e7646d2SAndroid Build Coastguard Worker const char *op; /* Operation name */
64*5e7646d2SAndroid Build Coastguard Worker
65*5e7646d2SAndroid Build Coastguard Worker
66*5e7646d2SAndroid Build Coastguard Worker /*
67*5e7646d2SAndroid Build Coastguard Worker * Connect to the HTTP server...
68*5e7646d2SAndroid Build Coastguard Worker */
69*5e7646d2SAndroid Build Coastguard Worker
70*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: admin.cgi started...\n", stderr);
71*5e7646d2SAndroid Build Coastguard Worker
72*5e7646d2SAndroid Build Coastguard Worker http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption());
73*5e7646d2SAndroid Build Coastguard Worker
74*5e7646d2SAndroid Build Coastguard Worker if (!http)
75*5e7646d2SAndroid Build Coastguard Worker {
76*5e7646d2SAndroid Build Coastguard Worker perror("ERROR: Unable to connect to cupsd");
77*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: cupsServer()=\"%s\"\n",
78*5e7646d2SAndroid Build Coastguard Worker cupsServer() ? cupsServer() : "(null)");
79*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: ippPort()=%d\n", ippPort());
80*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: cupsEncryption()=%d\n", cupsEncryption());
81*5e7646d2SAndroid Build Coastguard Worker exit(1);
82*5e7646d2SAndroid Build Coastguard Worker }
83*5e7646d2SAndroid Build Coastguard Worker
84*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: http=%p\n", http);
85*5e7646d2SAndroid Build Coastguard Worker
86*5e7646d2SAndroid Build Coastguard Worker /*
87*5e7646d2SAndroid Build Coastguard Worker * Set the web interface section...
88*5e7646d2SAndroid Build Coastguard Worker */
89*5e7646d2SAndroid Build Coastguard Worker
90*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("SECTION", "admin");
91*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("REFRESH_PAGE", "");
92*5e7646d2SAndroid Build Coastguard Worker
93*5e7646d2SAndroid Build Coastguard Worker /*
94*5e7646d2SAndroid Build Coastguard Worker * See if we have form data...
95*5e7646d2SAndroid Build Coastguard Worker */
96*5e7646d2SAndroid Build Coastguard Worker
97*5e7646d2SAndroid Build Coastguard Worker if (!cgiInitialize() || !cgiGetVariable("OP"))
98*5e7646d2SAndroid Build Coastguard Worker {
99*5e7646d2SAndroid Build Coastguard Worker /*
100*5e7646d2SAndroid Build Coastguard Worker * Nope, send the administration menu...
101*5e7646d2SAndroid Build Coastguard Worker */
102*5e7646d2SAndroid Build Coastguard Worker
103*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: No form data, showing main menu...\n", stderr);
104*5e7646d2SAndroid Build Coastguard Worker
105*5e7646d2SAndroid Build Coastguard Worker do_menu(http);
106*5e7646d2SAndroid Build Coastguard Worker }
107*5e7646d2SAndroid Build Coastguard Worker else if ((op = cgiGetVariable("OP")) != NULL && cgiIsPOST())
108*5e7646d2SAndroid Build Coastguard Worker {
109*5e7646d2SAndroid Build Coastguard Worker /*
110*5e7646d2SAndroid Build Coastguard Worker * Do the operation...
111*5e7646d2SAndroid Build Coastguard Worker */
112*5e7646d2SAndroid Build Coastguard Worker
113*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: op=\"%s\"...\n", op);
114*5e7646d2SAndroid Build Coastguard Worker
115*5e7646d2SAndroid Build Coastguard Worker if (!*op)
116*5e7646d2SAndroid Build Coastguard Worker {
117*5e7646d2SAndroid Build Coastguard Worker const char *printer = getenv("PRINTER_NAME"),
118*5e7646d2SAndroid Build Coastguard Worker /* Printer or class name */
119*5e7646d2SAndroid Build Coastguard Worker *server_port = getenv("SERVER_PORT");
120*5e7646d2SAndroid Build Coastguard Worker /* Port number string */
121*5e7646d2SAndroid Build Coastguard Worker int port = atoi(server_port ? server_port : "0");
122*5e7646d2SAndroid Build Coastguard Worker /* Port number */
123*5e7646d2SAndroid Build Coastguard Worker char uri[1024]; /* URL */
124*5e7646d2SAndroid Build Coastguard Worker
125*5e7646d2SAndroid Build Coastguard Worker if (printer)
126*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri),
127*5e7646d2SAndroid Build Coastguard Worker getenv("HTTPS") ? "https" : "http", NULL,
128*5e7646d2SAndroid Build Coastguard Worker getenv("SERVER_NAME"), port, "/%s/%s",
129*5e7646d2SAndroid Build Coastguard Worker cgiGetVariable("IS_CLASS") ? "classes" : "printers",
130*5e7646d2SAndroid Build Coastguard Worker printer);
131*5e7646d2SAndroid Build Coastguard Worker else
132*5e7646d2SAndroid Build Coastguard Worker httpAssembleURI(HTTP_URI_CODING_ALL, uri, sizeof(uri),
133*5e7646d2SAndroid Build Coastguard Worker getenv("HTTPS") ? "https" : "http", NULL,
134*5e7646d2SAndroid Build Coastguard Worker getenv("SERVER_NAME"), port, "/admin");
135*5e7646d2SAndroid Build Coastguard Worker
136*5e7646d2SAndroid Build Coastguard Worker printf("Location: %s\n\n", uri);
137*5e7646d2SAndroid Build Coastguard Worker }
138*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "set-allowed-users"))
139*5e7646d2SAndroid Build Coastguard Worker do_set_allowed_users(http);
140*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "set-as-default"))
141*5e7646d2SAndroid Build Coastguard Worker do_set_default(http);
142*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "set-sharing"))
143*5e7646d2SAndroid Build Coastguard Worker do_set_sharing(http);
144*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "find-new-printers") ||
145*5e7646d2SAndroid Build Coastguard Worker !strcmp(op, "list-available-printers"))
146*5e7646d2SAndroid Build Coastguard Worker do_list_printers(http);
147*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "add-class"))
148*5e7646d2SAndroid Build Coastguard Worker do_am_class(http, 0);
149*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "add-printer"))
150*5e7646d2SAndroid Build Coastguard Worker do_am_printer(http, 0);
151*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "modify-class"))
152*5e7646d2SAndroid Build Coastguard Worker do_am_class(http, 1);
153*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "modify-printer"))
154*5e7646d2SAndroid Build Coastguard Worker do_am_printer(http, 1);
155*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "delete-class"))
156*5e7646d2SAndroid Build Coastguard Worker do_delete_class(http);
157*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "delete-printer"))
158*5e7646d2SAndroid Build Coastguard Worker do_delete_printer(http);
159*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "set-class-options"))
160*5e7646d2SAndroid Build Coastguard Worker do_set_options(http, 1);
161*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "set-printer-options"))
162*5e7646d2SAndroid Build Coastguard Worker do_set_options(http, 0);
163*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(op, "config-server"))
164*5e7646d2SAndroid Build Coastguard Worker do_config_server(http);
165*5e7646d2SAndroid Build Coastguard Worker else
166*5e7646d2SAndroid Build Coastguard Worker {
167*5e7646d2SAndroid Build Coastguard Worker /*
168*5e7646d2SAndroid Build Coastguard Worker * Bad operation code - display an error...
169*5e7646d2SAndroid Build Coastguard Worker */
170*5e7646d2SAndroid Build Coastguard Worker
171*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Administration")));
172*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error-op.tmpl");
173*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
174*5e7646d2SAndroid Build Coastguard Worker }
175*5e7646d2SAndroid Build Coastguard Worker }
176*5e7646d2SAndroid Build Coastguard Worker else if (op && !strcmp(op, "redirect"))
177*5e7646d2SAndroid Build Coastguard Worker {
178*5e7646d2SAndroid Build Coastguard Worker const char *url; /* Redirection URL... */
179*5e7646d2SAndroid Build Coastguard Worker char prefix[1024]; /* URL prefix */
180*5e7646d2SAndroid Build Coastguard Worker
181*5e7646d2SAndroid Build Coastguard Worker
182*5e7646d2SAndroid Build Coastguard Worker if (getenv("HTTPS"))
183*5e7646d2SAndroid Build Coastguard Worker snprintf(prefix, sizeof(prefix), "https://%s:%s",
184*5e7646d2SAndroid Build Coastguard Worker getenv("SERVER_NAME"), getenv("SERVER_PORT"));
185*5e7646d2SAndroid Build Coastguard Worker else
186*5e7646d2SAndroid Build Coastguard Worker snprintf(prefix, sizeof(prefix), "http://%s:%s",
187*5e7646d2SAndroid Build Coastguard Worker getenv("SERVER_NAME"), getenv("SERVER_PORT"));
188*5e7646d2SAndroid Build Coastguard Worker
189*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: redirecting with prefix %s!\n", prefix);
190*5e7646d2SAndroid Build Coastguard Worker
191*5e7646d2SAndroid Build Coastguard Worker if ((url = cgiGetVariable("URL")) != NULL)
192*5e7646d2SAndroid Build Coastguard Worker {
193*5e7646d2SAndroid Build Coastguard Worker char encoded[1024], /* Encoded URL string */
194*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer into encoded string */
195*5e7646d2SAndroid Build Coastguard Worker
196*5e7646d2SAndroid Build Coastguard Worker
197*5e7646d2SAndroid Build Coastguard Worker ptr = encoded;
198*5e7646d2SAndroid Build Coastguard Worker if (*url != '/')
199*5e7646d2SAndroid Build Coastguard Worker *ptr++ = '/';
200*5e7646d2SAndroid Build Coastguard Worker
201*5e7646d2SAndroid Build Coastguard Worker for (; *url && ptr < (encoded + sizeof(encoded) - 4); url ++)
202*5e7646d2SAndroid Build Coastguard Worker {
203*5e7646d2SAndroid Build Coastguard Worker if (strchr("%@&+ <>#=", *url) || *url < ' ' || *url & 128)
204*5e7646d2SAndroid Build Coastguard Worker {
205*5e7646d2SAndroid Build Coastguard Worker /*
206*5e7646d2SAndroid Build Coastguard Worker * Percent-encode this character; safe because we have at least 4
207*5e7646d2SAndroid Build Coastguard Worker * bytes left in the array...
208*5e7646d2SAndroid Build Coastguard Worker */
209*5e7646d2SAndroid Build Coastguard Worker
210*5e7646d2SAndroid Build Coastguard Worker snprintf(ptr, sizeof(encoded) - (size_t)(ptr - encoded), "%%%02X", *url & 255);
211*5e7646d2SAndroid Build Coastguard Worker ptr += 3;
212*5e7646d2SAndroid Build Coastguard Worker }
213*5e7646d2SAndroid Build Coastguard Worker else
214*5e7646d2SAndroid Build Coastguard Worker *ptr++ = *url;
215*5e7646d2SAndroid Build Coastguard Worker }
216*5e7646d2SAndroid Build Coastguard Worker
217*5e7646d2SAndroid Build Coastguard Worker *ptr = '\0';
218*5e7646d2SAndroid Build Coastguard Worker
219*5e7646d2SAndroid Build Coastguard Worker if (*url)
220*5e7646d2SAndroid Build Coastguard Worker {
221*5e7646d2SAndroid Build Coastguard Worker /*
222*5e7646d2SAndroid Build Coastguard Worker * URL was too long, just redirect to the admin page...
223*5e7646d2SAndroid Build Coastguard Worker */
224*5e7646d2SAndroid Build Coastguard Worker
225*5e7646d2SAndroid Build Coastguard Worker printf("Location: %s/admin\n\n", prefix);
226*5e7646d2SAndroid Build Coastguard Worker }
227*5e7646d2SAndroid Build Coastguard Worker else
228*5e7646d2SAndroid Build Coastguard Worker {
229*5e7646d2SAndroid Build Coastguard Worker /*
230*5e7646d2SAndroid Build Coastguard Worker * URL is OK, redirect there...
231*5e7646d2SAndroid Build Coastguard Worker */
232*5e7646d2SAndroid Build Coastguard Worker
233*5e7646d2SAndroid Build Coastguard Worker printf("Location: %s%s\n\n", prefix, encoded);
234*5e7646d2SAndroid Build Coastguard Worker }
235*5e7646d2SAndroid Build Coastguard Worker }
236*5e7646d2SAndroid Build Coastguard Worker else
237*5e7646d2SAndroid Build Coastguard Worker printf("Location: %s/admin\n\n", prefix);
238*5e7646d2SAndroid Build Coastguard Worker }
239*5e7646d2SAndroid Build Coastguard Worker else
240*5e7646d2SAndroid Build Coastguard Worker {
241*5e7646d2SAndroid Build Coastguard Worker /*
242*5e7646d2SAndroid Build Coastguard Worker * Form data but no operation code - display an error...
243*5e7646d2SAndroid Build Coastguard Worker */
244*5e7646d2SAndroid Build Coastguard Worker
245*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Administration")));
246*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error-op.tmpl");
247*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
248*5e7646d2SAndroid Build Coastguard Worker }
249*5e7646d2SAndroid Build Coastguard Worker
250*5e7646d2SAndroid Build Coastguard Worker /*
251*5e7646d2SAndroid Build Coastguard Worker * Close the HTTP server connection...
252*5e7646d2SAndroid Build Coastguard Worker */
253*5e7646d2SAndroid Build Coastguard Worker
254*5e7646d2SAndroid Build Coastguard Worker httpClose(http);
255*5e7646d2SAndroid Build Coastguard Worker
256*5e7646d2SAndroid Build Coastguard Worker /*
257*5e7646d2SAndroid Build Coastguard Worker * Return with no errors...
258*5e7646d2SAndroid Build Coastguard Worker */
259*5e7646d2SAndroid Build Coastguard Worker
260*5e7646d2SAndroid Build Coastguard Worker return (0);
261*5e7646d2SAndroid Build Coastguard Worker }
262*5e7646d2SAndroid Build Coastguard Worker
263*5e7646d2SAndroid Build Coastguard Worker
264*5e7646d2SAndroid Build Coastguard Worker /*
265*5e7646d2SAndroid Build Coastguard Worker * 'choose_device_cb()' - Add a device to the device selection page.
266*5e7646d2SAndroid Build Coastguard Worker */
267*5e7646d2SAndroid Build Coastguard Worker
268*5e7646d2SAndroid Build Coastguard Worker static void
choose_device_cb(const char * device_class,const char * device_id,const char * device_info,const char * device_make_and_model,const char * device_uri,const char * device_location,const char * title)269*5e7646d2SAndroid Build Coastguard Worker choose_device_cb(
270*5e7646d2SAndroid Build Coastguard Worker const char *device_class, /* I - Class */
271*5e7646d2SAndroid Build Coastguard Worker const char *device_id, /* I - 1284 device ID */
272*5e7646d2SAndroid Build Coastguard Worker const char *device_info, /* I - Description */
273*5e7646d2SAndroid Build Coastguard Worker const char *device_make_and_model, /* I - Make and model */
274*5e7646d2SAndroid Build Coastguard Worker const char *device_uri, /* I - Device URI */
275*5e7646d2SAndroid Build Coastguard Worker const char *device_location, /* I - Location */
276*5e7646d2SAndroid Build Coastguard Worker const char *title) /* I - Page title */
277*5e7646d2SAndroid Build Coastguard Worker {
278*5e7646d2SAndroid Build Coastguard Worker /*
279*5e7646d2SAndroid Build Coastguard Worker * For modern browsers, start a multi-part page so we can show that something
280*5e7646d2SAndroid Build Coastguard Worker * is happening. Non-modern browsers just get everything at the end...
281*5e7646d2SAndroid Build Coastguard Worker */
282*5e7646d2SAndroid Build Coastguard Worker
283*5e7646d2SAndroid Build Coastguard Worker if (current_device == 0 && cgiSupportsMultipart())
284*5e7646d2SAndroid Build Coastguard Worker {
285*5e7646d2SAndroid Build Coastguard Worker cgiStartMultipart();
286*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
287*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("choose-device.tmpl");
288*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
289*5e7646d2SAndroid Build Coastguard Worker fflush(stdout);
290*5e7646d2SAndroid Build Coastguard Worker }
291*5e7646d2SAndroid Build Coastguard Worker
292*5e7646d2SAndroid Build Coastguard Worker
293*5e7646d2SAndroid Build Coastguard Worker /*
294*5e7646d2SAndroid Build Coastguard Worker * Add the device to the array...
295*5e7646d2SAndroid Build Coastguard Worker */
296*5e7646d2SAndroid Build Coastguard Worker
297*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_class", current_device, device_class);
298*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_id", current_device, device_id);
299*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_info", current_device, device_info);
300*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_make_and_model", current_device, device_make_and_model);
301*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_uri", current_device, device_uri);
302*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_location", current_device, device_location);
303*5e7646d2SAndroid Build Coastguard Worker
304*5e7646d2SAndroid Build Coastguard Worker current_device ++;
305*5e7646d2SAndroid Build Coastguard Worker }
306*5e7646d2SAndroid Build Coastguard Worker
307*5e7646d2SAndroid Build Coastguard Worker
308*5e7646d2SAndroid Build Coastguard Worker /*
309*5e7646d2SAndroid Build Coastguard Worker * 'do_am_class()' - Add or modify a class.
310*5e7646d2SAndroid Build Coastguard Worker */
311*5e7646d2SAndroid Build Coastguard Worker
312*5e7646d2SAndroid Build Coastguard Worker static void
do_am_class(http_t * http,int modify)313*5e7646d2SAndroid Build Coastguard Worker do_am_class(http_t *http, /* I - HTTP connection */
314*5e7646d2SAndroid Build Coastguard Worker int modify) /* I - Modify the printer? */
315*5e7646d2SAndroid Build Coastguard Worker {
316*5e7646d2SAndroid Build Coastguard Worker int i, j; /* Looping vars */
317*5e7646d2SAndroid Build Coastguard Worker int element; /* Element number */
318*5e7646d2SAndroid Build Coastguard Worker int num_printers; /* Number of printers */
319*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* IPP request */
320*5e7646d2SAndroid Build Coastguard Worker *response; /* IPP response */
321*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* member-uris attribute */
322*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI]; /* Device or printer URI */
323*5e7646d2SAndroid Build Coastguard Worker const char *name, /* Pointer to class name */
324*5e7646d2SAndroid Build Coastguard Worker *op, /* Operation name */
325*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer to CGI variable */
326*5e7646d2SAndroid Build Coastguard Worker const char *title; /* Title of page */
327*5e7646d2SAndroid Build Coastguard Worker static const char * const pattrs[] = /* Requested printer attributes */
328*5e7646d2SAndroid Build Coastguard Worker {
329*5e7646d2SAndroid Build Coastguard Worker "member-names",
330*5e7646d2SAndroid Build Coastguard Worker "printer-info",
331*5e7646d2SAndroid Build Coastguard Worker "printer-location"
332*5e7646d2SAndroid Build Coastguard Worker };
333*5e7646d2SAndroid Build Coastguard Worker
334*5e7646d2SAndroid Build Coastguard Worker
335*5e7646d2SAndroid Build Coastguard Worker title = cgiText(modify ? _("Modify Class") : _("Add Class"));
336*5e7646d2SAndroid Build Coastguard Worker op = cgiGetVariable("OP");
337*5e7646d2SAndroid Build Coastguard Worker name = cgiGetVariable("PRINTER_NAME");
338*5e7646d2SAndroid Build Coastguard Worker
339*5e7646d2SAndroid Build Coastguard Worker if (cgiGetVariable("PRINTER_LOCATION") == NULL)
340*5e7646d2SAndroid Build Coastguard Worker {
341*5e7646d2SAndroid Build Coastguard Worker /*
342*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_GET_PRINTERS request, which requires the
343*5e7646d2SAndroid Build Coastguard Worker * following attributes:
344*5e7646d2SAndroid Build Coastguard Worker *
345*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
346*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
347*5e7646d2SAndroid Build Coastguard Worker */
348*5e7646d2SAndroid Build Coastguard Worker
349*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_GET_PRINTERS);
350*5e7646d2SAndroid Build Coastguard Worker
351*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type",
352*5e7646d2SAndroid Build Coastguard Worker CUPS_PRINTER_LOCAL);
353*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask",
354*5e7646d2SAndroid Build Coastguard Worker CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE);
355*5e7646d2SAndroid Build Coastguard Worker
356*5e7646d2SAndroid Build Coastguard Worker /*
357*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
358*5e7646d2SAndroid Build Coastguard Worker */
359*5e7646d2SAndroid Build Coastguard Worker
360*5e7646d2SAndroid Build Coastguard Worker cgiClearVariables();
361*5e7646d2SAndroid Build Coastguard Worker if (op)
362*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("OP", op);
363*5e7646d2SAndroid Build Coastguard Worker if (name)
364*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRINTER_NAME", name);
365*5e7646d2SAndroid Build Coastguard Worker
366*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/")) != NULL)
367*5e7646d2SAndroid Build Coastguard Worker {
368*5e7646d2SAndroid Build Coastguard Worker /*
369*5e7646d2SAndroid Build Coastguard Worker * Create MEMBER_URIS and MEMBER_NAMES arrays...
370*5e7646d2SAndroid Build Coastguard Worker */
371*5e7646d2SAndroid Build Coastguard Worker
372*5e7646d2SAndroid Build Coastguard Worker for (element = 0, attr = response->attrs;
373*5e7646d2SAndroid Build Coastguard Worker attr != NULL;
374*5e7646d2SAndroid Build Coastguard Worker attr = attr->next)
375*5e7646d2SAndroid Build Coastguard Worker if (attr->name && !strcmp(attr->name, "printer-uri-supported"))
376*5e7646d2SAndroid Build Coastguard Worker {
377*5e7646d2SAndroid Build Coastguard Worker if ((ptr = strrchr(attr->values[0].string.text, '/')) != NULL &&
378*5e7646d2SAndroid Build Coastguard Worker (!name || _cups_strcasecmp(name, ptr + 1)))
379*5e7646d2SAndroid Build Coastguard Worker {
380*5e7646d2SAndroid Build Coastguard Worker /*
381*5e7646d2SAndroid Build Coastguard Worker * Don't show the current class...
382*5e7646d2SAndroid Build Coastguard Worker */
383*5e7646d2SAndroid Build Coastguard Worker
384*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("MEMBER_URIS", element, attr->values[0].string.text);
385*5e7646d2SAndroid Build Coastguard Worker element ++;
386*5e7646d2SAndroid Build Coastguard Worker }
387*5e7646d2SAndroid Build Coastguard Worker }
388*5e7646d2SAndroid Build Coastguard Worker
389*5e7646d2SAndroid Build Coastguard Worker for (element = 0, attr = response->attrs;
390*5e7646d2SAndroid Build Coastguard Worker attr != NULL;
391*5e7646d2SAndroid Build Coastguard Worker attr = attr->next)
392*5e7646d2SAndroid Build Coastguard Worker if (attr->name && !strcmp(attr->name, "printer-name"))
393*5e7646d2SAndroid Build Coastguard Worker {
394*5e7646d2SAndroid Build Coastguard Worker if (!name || _cups_strcasecmp(name, attr->values[0].string.text))
395*5e7646d2SAndroid Build Coastguard Worker {
396*5e7646d2SAndroid Build Coastguard Worker /*
397*5e7646d2SAndroid Build Coastguard Worker * Don't show the current class...
398*5e7646d2SAndroid Build Coastguard Worker */
399*5e7646d2SAndroid Build Coastguard Worker
400*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("MEMBER_NAMES", element, attr->values[0].string.text);
401*5e7646d2SAndroid Build Coastguard Worker element ++;
402*5e7646d2SAndroid Build Coastguard Worker }
403*5e7646d2SAndroid Build Coastguard Worker }
404*5e7646d2SAndroid Build Coastguard Worker
405*5e7646d2SAndroid Build Coastguard Worker num_printers = cgiGetSize("MEMBER_URIS");
406*5e7646d2SAndroid Build Coastguard Worker
407*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
408*5e7646d2SAndroid Build Coastguard Worker }
409*5e7646d2SAndroid Build Coastguard Worker else
410*5e7646d2SAndroid Build Coastguard Worker num_printers = 0;
411*5e7646d2SAndroid Build Coastguard Worker
412*5e7646d2SAndroid Build Coastguard Worker if (modify)
413*5e7646d2SAndroid Build Coastguard Worker {
414*5e7646d2SAndroid Build Coastguard Worker /*
415*5e7646d2SAndroid Build Coastguard Worker * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
416*5e7646d2SAndroid Build Coastguard Worker * following attributes:
417*5e7646d2SAndroid Build Coastguard Worker *
418*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
419*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
420*5e7646d2SAndroid Build Coastguard Worker * printer-uri
421*5e7646d2SAndroid Build Coastguard Worker */
422*5e7646d2SAndroid Build Coastguard Worker
423*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
424*5e7646d2SAndroid Build Coastguard Worker
425*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
426*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/classes/%s", name);
427*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
428*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
429*5e7646d2SAndroid Build Coastguard Worker
430*5e7646d2SAndroid Build Coastguard Worker ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
431*5e7646d2SAndroid Build Coastguard Worker "requested-attributes",
432*5e7646d2SAndroid Build Coastguard Worker (int)(sizeof(pattrs) / sizeof(pattrs[0])),
433*5e7646d2SAndroid Build Coastguard Worker NULL, pattrs);
434*5e7646d2SAndroid Build Coastguard Worker
435*5e7646d2SAndroid Build Coastguard Worker /*
436*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
437*5e7646d2SAndroid Build Coastguard Worker */
438*5e7646d2SAndroid Build Coastguard Worker
439*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/")) != NULL)
440*5e7646d2SAndroid Build Coastguard Worker {
441*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "member-names",
442*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_NAME)) != NULL)
443*5e7646d2SAndroid Build Coastguard Worker {
444*5e7646d2SAndroid Build Coastguard Worker /*
445*5e7646d2SAndroid Build Coastguard Worker * Mark any current members in the class...
446*5e7646d2SAndroid Build Coastguard Worker */
447*5e7646d2SAndroid Build Coastguard Worker
448*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < num_printers; j ++)
449*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("MEMBER_SELECTED", j, "");
450*5e7646d2SAndroid Build Coastguard Worker
451*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
452*5e7646d2SAndroid Build Coastguard Worker {
453*5e7646d2SAndroid Build Coastguard Worker for (j = 0; j < num_printers; j ++)
454*5e7646d2SAndroid Build Coastguard Worker {
455*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(attr->values[i].string.text,
456*5e7646d2SAndroid Build Coastguard Worker cgiGetArray("MEMBER_NAMES", j)))
457*5e7646d2SAndroid Build Coastguard Worker {
458*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("MEMBER_SELECTED", j, "SELECTED");
459*5e7646d2SAndroid Build Coastguard Worker break;
460*5e7646d2SAndroid Build Coastguard Worker }
461*5e7646d2SAndroid Build Coastguard Worker }
462*5e7646d2SAndroid Build Coastguard Worker }
463*5e7646d2SAndroid Build Coastguard Worker }
464*5e7646d2SAndroid Build Coastguard Worker
465*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "printer-info",
466*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_TEXT)) != NULL)
467*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRINTER_INFO", attr->values[0].string.text);
468*5e7646d2SAndroid Build Coastguard Worker
469*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "printer-location",
470*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_TEXT)) != NULL)
471*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRINTER_LOCATION", attr->values[0].string.text);
472*5e7646d2SAndroid Build Coastguard Worker
473*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
474*5e7646d2SAndroid Build Coastguard Worker }
475*5e7646d2SAndroid Build Coastguard Worker
476*5e7646d2SAndroid Build Coastguard Worker /*
477*5e7646d2SAndroid Build Coastguard Worker * Update the location and description of an existing printer...
478*5e7646d2SAndroid Build Coastguard Worker */
479*5e7646d2SAndroid Build Coastguard Worker
480*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
481*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("modify-class.tmpl");
482*5e7646d2SAndroid Build Coastguard Worker }
483*5e7646d2SAndroid Build Coastguard Worker else
484*5e7646d2SAndroid Build Coastguard Worker {
485*5e7646d2SAndroid Build Coastguard Worker /*
486*5e7646d2SAndroid Build Coastguard Worker * Get the name, location, and description for a new printer...
487*5e7646d2SAndroid Build Coastguard Worker */
488*5e7646d2SAndroid Build Coastguard Worker
489*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
490*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("add-class.tmpl");
491*5e7646d2SAndroid Build Coastguard Worker }
492*5e7646d2SAndroid Build Coastguard Worker
493*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
494*5e7646d2SAndroid Build Coastguard Worker
495*5e7646d2SAndroid Build Coastguard Worker return;
496*5e7646d2SAndroid Build Coastguard Worker }
497*5e7646d2SAndroid Build Coastguard Worker
498*5e7646d2SAndroid Build Coastguard Worker if (!name)
499*5e7646d2SAndroid Build Coastguard Worker {
500*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
501*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
502*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
503*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
504*5e7646d2SAndroid Build Coastguard Worker return;
505*5e7646d2SAndroid Build Coastguard Worker }
506*5e7646d2SAndroid Build Coastguard Worker
507*5e7646d2SAndroid Build Coastguard Worker for (ptr = name; *ptr; ptr ++)
508*5e7646d2SAndroid Build Coastguard Worker if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '#')
509*5e7646d2SAndroid Build Coastguard Worker break;
510*5e7646d2SAndroid Build Coastguard Worker
511*5e7646d2SAndroid Build Coastguard Worker if (*ptr || ptr == name || strlen(name) > 127)
512*5e7646d2SAndroid Build Coastguard Worker {
513*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR",
514*5e7646d2SAndroid Build Coastguard Worker cgiText(_("The class name may only contain up to "
515*5e7646d2SAndroid Build Coastguard Worker "127 printable characters and may not "
516*5e7646d2SAndroid Build Coastguard Worker "contain spaces, slashes (/), or the "
517*5e7646d2SAndroid Build Coastguard Worker "pound sign (#).")));
518*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
519*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
520*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
521*5e7646d2SAndroid Build Coastguard Worker return;
522*5e7646d2SAndroid Build Coastguard Worker }
523*5e7646d2SAndroid Build Coastguard Worker
524*5e7646d2SAndroid Build Coastguard Worker /*
525*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_ADD_CLASS request, which requires the following
526*5e7646d2SAndroid Build Coastguard Worker * attributes:
527*5e7646d2SAndroid Build Coastguard Worker *
528*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
529*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
530*5e7646d2SAndroid Build Coastguard Worker * printer-uri
531*5e7646d2SAndroid Build Coastguard Worker * printer-location
532*5e7646d2SAndroid Build Coastguard Worker * printer-info
533*5e7646d2SAndroid Build Coastguard Worker * printer-is-accepting-jobs
534*5e7646d2SAndroid Build Coastguard Worker * printer-state
535*5e7646d2SAndroid Build Coastguard Worker * member-uris
536*5e7646d2SAndroid Build Coastguard Worker */
537*5e7646d2SAndroid Build Coastguard Worker
538*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_ADD_CLASS);
539*5e7646d2SAndroid Build Coastguard Worker
540*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
541*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/classes/%s", name);
542*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
543*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
544*5e7646d2SAndroid Build Coastguard Worker
545*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
546*5e7646d2SAndroid Build Coastguard Worker NULL, cgiGetVariable("PRINTER_LOCATION"));
547*5e7646d2SAndroid Build Coastguard Worker
548*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
549*5e7646d2SAndroid Build Coastguard Worker NULL, cgiGetVariable("PRINTER_INFO"));
550*5e7646d2SAndroid Build Coastguard Worker
551*5e7646d2SAndroid Build Coastguard Worker ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
552*5e7646d2SAndroid Build Coastguard Worker
553*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
554*5e7646d2SAndroid Build Coastguard Worker IPP_PRINTER_IDLE);
555*5e7646d2SAndroid Build Coastguard Worker
556*5e7646d2SAndroid Build Coastguard Worker if ((num_printers = cgiGetSize("MEMBER_URIS")) > 0)
557*5e7646d2SAndroid Build Coastguard Worker {
558*5e7646d2SAndroid Build Coastguard Worker attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris",
559*5e7646d2SAndroid Build Coastguard Worker num_printers, NULL, NULL);
560*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < num_printers; i ++)
561*5e7646d2SAndroid Build Coastguard Worker ippSetString(request, &attr, i, cgiGetArray("MEMBER_URIS", i));
562*5e7646d2SAndroid Build Coastguard Worker }
563*5e7646d2SAndroid Build Coastguard Worker
564*5e7646d2SAndroid Build Coastguard Worker /*
565*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
566*5e7646d2SAndroid Build Coastguard Worker */
567*5e7646d2SAndroid Build Coastguard Worker
568*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/admin/"));
569*5e7646d2SAndroid Build Coastguard Worker
570*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
571*5e7646d2SAndroid Build Coastguard Worker {
572*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
573*5e7646d2SAndroid Build Coastguard Worker exit(0);
574*5e7646d2SAndroid Build Coastguard Worker }
575*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() > IPP_OK_CONFLICT)
576*5e7646d2SAndroid Build Coastguard Worker {
577*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
578*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(modify ? _("Unable to modify class") :
579*5e7646d2SAndroid Build Coastguard Worker _("Unable to add class"));
580*5e7646d2SAndroid Build Coastguard Worker }
581*5e7646d2SAndroid Build Coastguard Worker else
582*5e7646d2SAndroid Build Coastguard Worker {
583*5e7646d2SAndroid Build Coastguard Worker /*
584*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the class page...
585*5e7646d2SAndroid Build Coastguard Worker */
586*5e7646d2SAndroid Build Coastguard Worker
587*5e7646d2SAndroid Build Coastguard Worker char refresh[1024]; /* Refresh URL */
588*5e7646d2SAndroid Build Coastguard Worker
589*5e7646d2SAndroid Build Coastguard Worker cgiFormEncode(uri, name, sizeof(uri));
590*5e7646d2SAndroid Build Coastguard Worker snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=/classes/%s",
591*5e7646d2SAndroid Build Coastguard Worker uri);
592*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", refresh);
593*5e7646d2SAndroid Build Coastguard Worker
594*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
595*5e7646d2SAndroid Build Coastguard Worker
596*5e7646d2SAndroid Build Coastguard Worker if (modify)
597*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("class-modified.tmpl");
598*5e7646d2SAndroid Build Coastguard Worker else
599*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("class-added.tmpl");
600*5e7646d2SAndroid Build Coastguard Worker }
601*5e7646d2SAndroid Build Coastguard Worker
602*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
603*5e7646d2SAndroid Build Coastguard Worker }
604*5e7646d2SAndroid Build Coastguard Worker
605*5e7646d2SAndroid Build Coastguard Worker
606*5e7646d2SAndroid Build Coastguard Worker /*
607*5e7646d2SAndroid Build Coastguard Worker * 'do_am_printer()' - Add or modify a printer.
608*5e7646d2SAndroid Build Coastguard Worker */
609*5e7646d2SAndroid Build Coastguard Worker
610*5e7646d2SAndroid Build Coastguard Worker static void
do_am_printer(http_t * http,int modify)611*5e7646d2SAndroid Build Coastguard Worker do_am_printer(http_t *http, /* I - HTTP connection */
612*5e7646d2SAndroid Build Coastguard Worker int modify) /* I - Modify the printer? */
613*5e7646d2SAndroid Build Coastguard Worker {
614*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
615*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Current attribute */
616*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* IPP request */
617*5e7646d2SAndroid Build Coastguard Worker *response, /* IPP response */
618*5e7646d2SAndroid Build Coastguard Worker *oldinfo; /* Old printer information */
619*5e7646d2SAndroid Build Coastguard Worker const cgi_file_t *file; /* Uploaded file, if any */
620*5e7646d2SAndroid Build Coastguard Worker const char *var; /* CGI variable */
621*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI], /* Device or printer URI */
622*5e7646d2SAndroid Build Coastguard Worker *uriptr, /* Pointer into URI */
623*5e7646d2SAndroid Build Coastguard Worker evefile[1024] = ""; /* IPP Everywhere PPD file */
624*5e7646d2SAndroid Build Coastguard Worker int maxrate; /* Maximum baud rate */
625*5e7646d2SAndroid Build Coastguard Worker char baudrate[255]; /* Baud rate string */
626*5e7646d2SAndroid Build Coastguard Worker const char *name, /* Pointer to class name */
627*5e7646d2SAndroid Build Coastguard Worker *ptr; /* Pointer to CGI variable */
628*5e7646d2SAndroid Build Coastguard Worker const char *title; /* Title of page */
629*5e7646d2SAndroid Build Coastguard Worker static int baudrates[] = /* Baud rates */
630*5e7646d2SAndroid Build Coastguard Worker {
631*5e7646d2SAndroid Build Coastguard Worker 1200,
632*5e7646d2SAndroid Build Coastguard Worker 2400,
633*5e7646d2SAndroid Build Coastguard Worker 4800,
634*5e7646d2SAndroid Build Coastguard Worker 9600,
635*5e7646d2SAndroid Build Coastguard Worker 19200,
636*5e7646d2SAndroid Build Coastguard Worker 38400,
637*5e7646d2SAndroid Build Coastguard Worker 57600,
638*5e7646d2SAndroid Build Coastguard Worker 115200,
639*5e7646d2SAndroid Build Coastguard Worker 230400,
640*5e7646d2SAndroid Build Coastguard Worker 460800
641*5e7646d2SAndroid Build Coastguard Worker };
642*5e7646d2SAndroid Build Coastguard Worker
643*5e7646d2SAndroid Build Coastguard Worker
644*5e7646d2SAndroid Build Coastguard Worker ptr = cgiGetVariable("DEVICE_URI");
645*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: do_am_printer: DEVICE_URI=\"%s\"\n",
646*5e7646d2SAndroid Build Coastguard Worker ptr ? ptr : "(null)");
647*5e7646d2SAndroid Build Coastguard Worker
648*5e7646d2SAndroid Build Coastguard Worker title = cgiText(modify ? _("Modify Printer") : _("Add Printer"));
649*5e7646d2SAndroid Build Coastguard Worker
650*5e7646d2SAndroid Build Coastguard Worker if (modify)
651*5e7646d2SAndroid Build Coastguard Worker {
652*5e7646d2SAndroid Build Coastguard Worker /*
653*5e7646d2SAndroid Build Coastguard Worker * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
654*5e7646d2SAndroid Build Coastguard Worker * following attributes:
655*5e7646d2SAndroid Build Coastguard Worker *
656*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
657*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
658*5e7646d2SAndroid Build Coastguard Worker * printer-uri
659*5e7646d2SAndroid Build Coastguard Worker */
660*5e7646d2SAndroid Build Coastguard Worker
661*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
662*5e7646d2SAndroid Build Coastguard Worker
663*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
664*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/printers/%s",
665*5e7646d2SAndroid Build Coastguard Worker cgiGetVariable("PRINTER_NAME"));
666*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
667*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
668*5e7646d2SAndroid Build Coastguard Worker
669*5e7646d2SAndroid Build Coastguard Worker /*
670*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
671*5e7646d2SAndroid Build Coastguard Worker */
672*5e7646d2SAndroid Build Coastguard Worker
673*5e7646d2SAndroid Build Coastguard Worker oldinfo = cupsDoRequest(http, request, "/");
674*5e7646d2SAndroid Build Coastguard Worker }
675*5e7646d2SAndroid Build Coastguard Worker else
676*5e7646d2SAndroid Build Coastguard Worker oldinfo = NULL;
677*5e7646d2SAndroid Build Coastguard Worker
678*5e7646d2SAndroid Build Coastguard Worker file = cgiGetFile();
679*5e7646d2SAndroid Build Coastguard Worker
680*5e7646d2SAndroid Build Coastguard Worker if (file)
681*5e7646d2SAndroid Build Coastguard Worker {
682*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: file->tempfile=%s\n", file->tempfile);
683*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: file->name=%s\n", file->name);
684*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: file->filename=%s\n", file->filename);
685*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: file->mimetype=%s\n", file->mimetype);
686*5e7646d2SAndroid Build Coastguard Worker }
687*5e7646d2SAndroid Build Coastguard Worker
688*5e7646d2SAndroid Build Coastguard Worker if ((name = cgiGetVariable("PRINTER_NAME")) != NULL)
689*5e7646d2SAndroid Build Coastguard Worker {
690*5e7646d2SAndroid Build Coastguard Worker for (ptr = name; *ptr; ptr ++)
691*5e7646d2SAndroid Build Coastguard Worker if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '\\' || *ptr == '?' || *ptr == '\'' || *ptr == '\"' || *ptr == '#')
692*5e7646d2SAndroid Build Coastguard Worker break;
693*5e7646d2SAndroid Build Coastguard Worker
694*5e7646d2SAndroid Build Coastguard Worker if (*ptr || ptr == name || strlen(name) > 127)
695*5e7646d2SAndroid Build Coastguard Worker {
696*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR",
697*5e7646d2SAndroid Build Coastguard Worker cgiText(_("The printer name may only contain up to 127 printable characters and may not contain spaces, slashes (/ \\), quotes (' \"), question mark (?), or the pound sign (#).")));
698*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
699*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
700*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
701*5e7646d2SAndroid Build Coastguard Worker return;
702*5e7646d2SAndroid Build Coastguard Worker }
703*5e7646d2SAndroid Build Coastguard Worker }
704*5e7646d2SAndroid Build Coastguard Worker
705*5e7646d2SAndroid Build Coastguard Worker if ((var = cgiGetVariable("DEVICE_URI")) != NULL)
706*5e7646d2SAndroid Build Coastguard Worker {
707*5e7646d2SAndroid Build Coastguard Worker if ((uriptr = strrchr(var, '|')) != NULL)
708*5e7646d2SAndroid Build Coastguard Worker {
709*5e7646d2SAndroid Build Coastguard Worker /*
710*5e7646d2SAndroid Build Coastguard Worker * Extract make and make/model from device URI string...
711*5e7646d2SAndroid Build Coastguard Worker */
712*5e7646d2SAndroid Build Coastguard Worker
713*5e7646d2SAndroid Build Coastguard Worker char make[1024], /* Make string */
714*5e7646d2SAndroid Build Coastguard Worker *makeptr; /* Pointer into make */
715*5e7646d2SAndroid Build Coastguard Worker
716*5e7646d2SAndroid Build Coastguard Worker
717*5e7646d2SAndroid Build Coastguard Worker *uriptr++ = '\0';
718*5e7646d2SAndroid Build Coastguard Worker
719*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, uriptr, sizeof(make));
720*5e7646d2SAndroid Build Coastguard Worker
721*5e7646d2SAndroid Build Coastguard Worker if ((makeptr = strchr(make, ' ')) != NULL)
722*5e7646d2SAndroid Build Coastguard Worker *makeptr = '\0';
723*5e7646d2SAndroid Build Coastguard Worker else if ((makeptr = strchr(make, '-')) != NULL)
724*5e7646d2SAndroid Build Coastguard Worker *makeptr = '\0';
725*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make, "laserjet", 8) ||
726*5e7646d2SAndroid Build Coastguard Worker !_cups_strncasecmp(make, "deskjet", 7) ||
727*5e7646d2SAndroid Build Coastguard Worker !_cups_strncasecmp(make, "designjet", 9))
728*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, "HP", sizeof(make));
729*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make, "phaser", 6))
730*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, "Xerox", sizeof(make));
731*5e7646d2SAndroid Build Coastguard Worker else if (!_cups_strncasecmp(make, "stylus", 6))
732*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, "Epson", sizeof(make));
733*5e7646d2SAndroid Build Coastguard Worker else
734*5e7646d2SAndroid Build Coastguard Worker strlcpy(make, "Generic", sizeof(make));
735*5e7646d2SAndroid Build Coastguard Worker
736*5e7646d2SAndroid Build Coastguard Worker if (!cgiGetVariable("CURRENT_MAKE"))
737*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CURRENT_MAKE", make);
738*5e7646d2SAndroid Build Coastguard Worker
739*5e7646d2SAndroid Build Coastguard Worker if (!cgiGetVariable("CURRENT_MAKE_AND_MODEL"))
740*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CURRENT_MAKE_AND_MODEL", uriptr);
741*5e7646d2SAndroid Build Coastguard Worker
742*5e7646d2SAndroid Build Coastguard Worker if (!modify)
743*5e7646d2SAndroid Build Coastguard Worker {
744*5e7646d2SAndroid Build Coastguard Worker char template[128], /* Template name */
745*5e7646d2SAndroid Build Coastguard Worker *tptr; /* Pointer into template name */
746*5e7646d2SAndroid Build Coastguard Worker
747*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRINTER_INFO", uriptr);
748*5e7646d2SAndroid Build Coastguard Worker
749*5e7646d2SAndroid Build Coastguard Worker for (tptr = template;
750*5e7646d2SAndroid Build Coastguard Worker tptr < (template + sizeof(template) - 1) && *uriptr;
751*5e7646d2SAndroid Build Coastguard Worker uriptr ++)
752*5e7646d2SAndroid Build Coastguard Worker if (isalnum(*uriptr & 255) || *uriptr == '_' || *uriptr == '-' ||
753*5e7646d2SAndroid Build Coastguard Worker *uriptr == '.')
754*5e7646d2SAndroid Build Coastguard Worker *tptr++ = *uriptr;
755*5e7646d2SAndroid Build Coastguard Worker else if ((*uriptr == ' ' || *uriptr == '/') && tptr > template &&
756*5e7646d2SAndroid Build Coastguard Worker tptr[-1] != '_')
757*5e7646d2SAndroid Build Coastguard Worker *tptr++ = '_';
758*5e7646d2SAndroid Build Coastguard Worker else if (*uriptr == '?' || *uriptr == '(')
759*5e7646d2SAndroid Build Coastguard Worker break;
760*5e7646d2SAndroid Build Coastguard Worker
761*5e7646d2SAndroid Build Coastguard Worker *tptr = '\0';
762*5e7646d2SAndroid Build Coastguard Worker
763*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("TEMPLATE_NAME", template);
764*5e7646d2SAndroid Build Coastguard Worker }
765*5e7646d2SAndroid Build Coastguard Worker
766*5e7646d2SAndroid Build Coastguard Worker /*
767*5e7646d2SAndroid Build Coastguard Worker * Set DEVICE_URI to the actual device uri, without make and model from
768*5e7646d2SAndroid Build Coastguard Worker * html form.
769*5e7646d2SAndroid Build Coastguard Worker */
770*5e7646d2SAndroid Build Coastguard Worker
771*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEVICE_URI", var);
772*5e7646d2SAndroid Build Coastguard Worker }
773*5e7646d2SAndroid Build Coastguard Worker }
774*5e7646d2SAndroid Build Coastguard Worker
775*5e7646d2SAndroid Build Coastguard Worker if (!var)
776*5e7646d2SAndroid Build Coastguard Worker {
777*5e7646d2SAndroid Build Coastguard Worker /*
778*5e7646d2SAndroid Build Coastguard Worker * Look for devices so the user can pick something...
779*5e7646d2SAndroid Build Coastguard Worker */
780*5e7646d2SAndroid Build Coastguard Worker
781*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
782*5e7646d2SAndroid Build Coastguard Worker {
783*5e7646d2SAndroid Build Coastguard Worker strlcpy(uri, attr->values[0].string.text, sizeof(uri));
784*5e7646d2SAndroid Build Coastguard Worker if ((uriptr = strchr(uri, ':')) != NULL && strncmp(uriptr, "://", 3) == 0)
785*5e7646d2SAndroid Build Coastguard Worker *uriptr = '\0';
786*5e7646d2SAndroid Build Coastguard Worker
787*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CURRENT_DEVICE_URI", attr->values[0].string.text);
788*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CURRENT_DEVICE_SCHEME", uri);
789*5e7646d2SAndroid Build Coastguard Worker }
790*5e7646d2SAndroid Build Coastguard Worker
791*5e7646d2SAndroid Build Coastguard Worker /*
792*5e7646d2SAndroid Build Coastguard Worker * Scan for devices for up to 30 seconds...
793*5e7646d2SAndroid Build Coastguard Worker */
794*5e7646d2SAndroid Build Coastguard Worker
795*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: Getting list of devices...\n", stderr);
796*5e7646d2SAndroid Build Coastguard Worker
797*5e7646d2SAndroid Build Coastguard Worker current_device = 0;
798*5e7646d2SAndroid Build Coastguard Worker if (cupsGetDevices(http, 5, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
799*5e7646d2SAndroid Build Coastguard Worker (cups_device_cb_t)choose_device_cb,
800*5e7646d2SAndroid Build Coastguard Worker (void *)title) == IPP_OK)
801*5e7646d2SAndroid Build Coastguard Worker {
802*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: Got device list!\n", stderr);
803*5e7646d2SAndroid Build Coastguard Worker
804*5e7646d2SAndroid Build Coastguard Worker if (cgiSupportsMultipart())
805*5e7646d2SAndroid Build Coastguard Worker cgiStartMultipart();
806*5e7646d2SAndroid Build Coastguard Worker
807*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CUPS_GET_DEVICES_DONE", "1");
808*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
809*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("choose-device.tmpl");
810*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
811*5e7646d2SAndroid Build Coastguard Worker
812*5e7646d2SAndroid Build Coastguard Worker if (cgiSupportsMultipart())
813*5e7646d2SAndroid Build Coastguard Worker cgiEndMultipart();
814*5e7646d2SAndroid Build Coastguard Worker }
815*5e7646d2SAndroid Build Coastguard Worker else
816*5e7646d2SAndroid Build Coastguard Worker {
817*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr,
818*5e7646d2SAndroid Build Coastguard Worker "ERROR: CUPS-Get-Devices request failed with status %x: %s\n",
819*5e7646d2SAndroid Build Coastguard Worker cupsLastError(), cupsLastErrorString());
820*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
821*5e7646d2SAndroid Build Coastguard Worker {
822*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
823*5e7646d2SAndroid Build Coastguard Worker exit(0);
824*5e7646d2SAndroid Build Coastguard Worker }
825*5e7646d2SAndroid Build Coastguard Worker else
826*5e7646d2SAndroid Build Coastguard Worker {
827*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
828*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(modify ? _("Unable to modify printer") :
829*5e7646d2SAndroid Build Coastguard Worker _("Unable to add printer"));
830*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
831*5e7646d2SAndroid Build Coastguard Worker return;
832*5e7646d2SAndroid Build Coastguard Worker }
833*5e7646d2SAndroid Build Coastguard Worker }
834*5e7646d2SAndroid Build Coastguard Worker }
835*5e7646d2SAndroid Build Coastguard Worker else if (!strchr(var, '/') ||
836*5e7646d2SAndroid Build Coastguard Worker (!strncmp(var, "lpd://", 6) && !strchr(var + 6, '/')))
837*5e7646d2SAndroid Build Coastguard Worker {
838*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
839*5e7646d2SAndroid Build Coastguard Worker {
840*5e7646d2SAndroid Build Coastguard Worker /*
841*5e7646d2SAndroid Build Coastguard Worker * Set the current device URI for the form to the old one...
842*5e7646d2SAndroid Build Coastguard Worker */
843*5e7646d2SAndroid Build Coastguard Worker
844*5e7646d2SAndroid Build Coastguard Worker if (strncmp(attr->values[0].string.text, var, strlen(var)) == 0)
845*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CURRENT_DEVICE_URI", attr->values[0].string.text);
846*5e7646d2SAndroid Build Coastguard Worker }
847*5e7646d2SAndroid Build Coastguard Worker
848*5e7646d2SAndroid Build Coastguard Worker /*
849*5e7646d2SAndroid Build Coastguard Worker * User needs to set the full URI...
850*5e7646d2SAndroid Build Coastguard Worker */
851*5e7646d2SAndroid Build Coastguard Worker
852*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
853*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("choose-uri.tmpl");
854*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
855*5e7646d2SAndroid Build Coastguard Worker }
856*5e7646d2SAndroid Build Coastguard Worker else if (!strncmp(var, "serial:", 7) && !cgiGetVariable("BAUDRATE"))
857*5e7646d2SAndroid Build Coastguard Worker {
858*5e7646d2SAndroid Build Coastguard Worker /*
859*5e7646d2SAndroid Build Coastguard Worker * Need baud rate, parity, etc.
860*5e7646d2SAndroid Build Coastguard Worker */
861*5e7646d2SAndroid Build Coastguard Worker
862*5e7646d2SAndroid Build Coastguard Worker if ((var = strchr(var, '?')) != NULL &&
863*5e7646d2SAndroid Build Coastguard Worker strncmp(var, "?baud=", 6) == 0)
864*5e7646d2SAndroid Build Coastguard Worker maxrate = atoi(var + 6);
865*5e7646d2SAndroid Build Coastguard Worker else
866*5e7646d2SAndroid Build Coastguard Worker maxrate = 19200;
867*5e7646d2SAndroid Build Coastguard Worker
868*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < 10; i ++)
869*5e7646d2SAndroid Build Coastguard Worker if (baudrates[i] > maxrate)
870*5e7646d2SAndroid Build Coastguard Worker break;
871*5e7646d2SAndroid Build Coastguard Worker else
872*5e7646d2SAndroid Build Coastguard Worker {
873*5e7646d2SAndroid Build Coastguard Worker snprintf(baudrate, sizeof(baudrate), "%d", baudrates[i]);
874*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("BAUDRATES", i, baudrate);
875*5e7646d2SAndroid Build Coastguard Worker }
876*5e7646d2SAndroid Build Coastguard Worker
877*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
878*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("choose-serial.tmpl");
879*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
880*5e7646d2SAndroid Build Coastguard Worker }
881*5e7646d2SAndroid Build Coastguard Worker else if (!name || !cgiGetVariable("PRINTER_LOCATION"))
882*5e7646d2SAndroid Build Coastguard Worker {
883*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
884*5e7646d2SAndroid Build Coastguard Worker
885*5e7646d2SAndroid Build Coastguard Worker if (modify)
886*5e7646d2SAndroid Build Coastguard Worker {
887*5e7646d2SAndroid Build Coastguard Worker /*
888*5e7646d2SAndroid Build Coastguard Worker * Update the location and description of an existing printer...
889*5e7646d2SAndroid Build Coastguard Worker */
890*5e7646d2SAndroid Build Coastguard Worker
891*5e7646d2SAndroid Build Coastguard Worker if (oldinfo)
892*5e7646d2SAndroid Build Coastguard Worker {
893*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(oldinfo, "printer-info",
894*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_TEXT)) != NULL)
895*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRINTER_INFO", attr->values[0].string.text);
896*5e7646d2SAndroid Build Coastguard Worker
897*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(oldinfo, "printer-location",
898*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_TEXT)) != NULL)
899*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRINTER_LOCATION", attr->values[0].string.text);
900*5e7646d2SAndroid Build Coastguard Worker
901*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(oldinfo, "printer-is-shared",
902*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_BOOLEAN)) != NULL)
903*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRINTER_IS_SHARED",
904*5e7646d2SAndroid Build Coastguard Worker attr->values[0].boolean ? "1" : "0");
905*5e7646d2SAndroid Build Coastguard Worker }
906*5e7646d2SAndroid Build Coastguard Worker
907*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("modify-printer.tmpl");
908*5e7646d2SAndroid Build Coastguard Worker }
909*5e7646d2SAndroid Build Coastguard Worker else
910*5e7646d2SAndroid Build Coastguard Worker {
911*5e7646d2SAndroid Build Coastguard Worker /*
912*5e7646d2SAndroid Build Coastguard Worker * Get the name, location, and description for a new printer...
913*5e7646d2SAndroid Build Coastguard Worker */
914*5e7646d2SAndroid Build Coastguard Worker
915*5e7646d2SAndroid Build Coastguard Worker #ifdef __APPLE__
916*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(var, "usb:", 4))
917*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("printer_is_shared", "1");
918*5e7646d2SAndroid Build Coastguard Worker else
919*5e7646d2SAndroid Build Coastguard Worker #endif /* __APPLE__ */
920*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("printer_is_shared", "0");
921*5e7646d2SAndroid Build Coastguard Worker
922*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("add-printer.tmpl");
923*5e7646d2SAndroid Build Coastguard Worker }
924*5e7646d2SAndroid Build Coastguard Worker
925*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
926*5e7646d2SAndroid Build Coastguard Worker
927*5e7646d2SAndroid Build Coastguard Worker if (oldinfo)
928*5e7646d2SAndroid Build Coastguard Worker ippDelete(oldinfo);
929*5e7646d2SAndroid Build Coastguard Worker
930*5e7646d2SAndroid Build Coastguard Worker return;
931*5e7646d2SAndroid Build Coastguard Worker }
932*5e7646d2SAndroid Build Coastguard Worker else if (!file &&
933*5e7646d2SAndroid Build Coastguard Worker (!cgiGetVariable("PPD_NAME") || cgiGetVariable("SELECT_MAKE")))
934*5e7646d2SAndroid Build Coastguard Worker {
935*5e7646d2SAndroid Build Coastguard Worker int ipp_everywhere = !strncmp(var, "ipp://", 6) || !strncmp(var, "ipps://", 7) || (!strncmp(var, "dnssd://", 8) && (strstr(var, "_ipp._tcp") || strstr(var, "_ipps._tcp")));
936*5e7646d2SAndroid Build Coastguard Worker
937*5e7646d2SAndroid Build Coastguard Worker if (modify && !cgiGetVariable("SELECT_MAKE"))
938*5e7646d2SAndroid Build Coastguard Worker {
939*5e7646d2SAndroid Build Coastguard Worker /*
940*5e7646d2SAndroid Build Coastguard Worker * Get the PPD file...
941*5e7646d2SAndroid Build Coastguard Worker */
942*5e7646d2SAndroid Build Coastguard Worker
943*5e7646d2SAndroid Build Coastguard Worker int fd; /* PPD file */
944*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* PPD filename */
945*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd; /* PPD information */
946*5e7646d2SAndroid Build Coastguard Worker char buffer[1024]; /* Buffer */
947*5e7646d2SAndroid Build Coastguard Worker ssize_t bytes; /* Number of bytes */
948*5e7646d2SAndroid Build Coastguard Worker http_status_t get_status; /* Status of GET */
949*5e7646d2SAndroid Build Coastguard Worker
950*5e7646d2SAndroid Build Coastguard Worker
951*5e7646d2SAndroid Build Coastguard Worker /* TODO: Use cupsGetFile() API... */
952*5e7646d2SAndroid Build Coastguard Worker snprintf(uri, sizeof(uri), "/printers/%s.ppd", name);
953*5e7646d2SAndroid Build Coastguard Worker
954*5e7646d2SAndroid Build Coastguard Worker if (httpGet(http, uri))
955*5e7646d2SAndroid Build Coastguard Worker httpGet(http, uri);
956*5e7646d2SAndroid Build Coastguard Worker
957*5e7646d2SAndroid Build Coastguard Worker while ((get_status = httpUpdate(http)) == HTTP_CONTINUE);
958*5e7646d2SAndroid Build Coastguard Worker
959*5e7646d2SAndroid Build Coastguard Worker if (get_status != HTTP_OK)
960*5e7646d2SAndroid Build Coastguard Worker {
961*5e7646d2SAndroid Build Coastguard Worker httpFlush(http);
962*5e7646d2SAndroid Build Coastguard Worker
963*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Unable to get PPD file %s: %d - %s\n",
964*5e7646d2SAndroid Build Coastguard Worker uri, get_status, httpStatus(get_status));
965*5e7646d2SAndroid Build Coastguard Worker }
966*5e7646d2SAndroid Build Coastguard Worker else if ((fd = cupsTempFd(filename, sizeof(filename))) >= 0)
967*5e7646d2SAndroid Build Coastguard Worker {
968*5e7646d2SAndroid Build Coastguard Worker while ((bytes = httpRead2(http, buffer, sizeof(buffer))) > 0)
969*5e7646d2SAndroid Build Coastguard Worker write(fd, buffer, (size_t)bytes);
970*5e7646d2SAndroid Build Coastguard Worker
971*5e7646d2SAndroid Build Coastguard Worker close(fd);
972*5e7646d2SAndroid Build Coastguard Worker
973*5e7646d2SAndroid Build Coastguard Worker if ((ppd = ppdOpenFile(filename)) != NULL)
974*5e7646d2SAndroid Build Coastguard Worker {
975*5e7646d2SAndroid Build Coastguard Worker if (ppd->manufacturer)
976*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CURRENT_MAKE", ppd->manufacturer);
977*5e7646d2SAndroid Build Coastguard Worker
978*5e7646d2SAndroid Build Coastguard Worker if (ppd->nickname)
979*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CURRENT_MAKE_AND_MODEL", ppd->nickname);
980*5e7646d2SAndroid Build Coastguard Worker
981*5e7646d2SAndroid Build Coastguard Worker ppdClose(ppd);
982*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
983*5e7646d2SAndroid Build Coastguard Worker }
984*5e7646d2SAndroid Build Coastguard Worker else
985*5e7646d2SAndroid Build Coastguard Worker {
986*5e7646d2SAndroid Build Coastguard Worker int linenum; /* Line number */
987*5e7646d2SAndroid Build Coastguard Worker
988*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: Unable to open PPD file %s: %s\n",
989*5e7646d2SAndroid Build Coastguard Worker filename, ppdErrorString(ppdLastError(&linenum)));
990*5e7646d2SAndroid Build Coastguard Worker }
991*5e7646d2SAndroid Build Coastguard Worker }
992*5e7646d2SAndroid Build Coastguard Worker else
993*5e7646d2SAndroid Build Coastguard Worker {
994*5e7646d2SAndroid Build Coastguard Worker httpFlush(http);
995*5e7646d2SAndroid Build Coastguard Worker
996*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr,
997*5e7646d2SAndroid Build Coastguard Worker "ERROR: Unable to create temporary file for PPD file: %s\n",
998*5e7646d2SAndroid Build Coastguard Worker strerror(errno));
999*5e7646d2SAndroid Build Coastguard Worker }
1000*5e7646d2SAndroid Build Coastguard Worker }
1001*5e7646d2SAndroid Build Coastguard Worker
1002*5e7646d2SAndroid Build Coastguard Worker /*
1003*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_GET_PPDS request, which requires the following
1004*5e7646d2SAndroid Build Coastguard Worker * attributes:
1005*5e7646d2SAndroid Build Coastguard Worker *
1006*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
1007*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
1008*5e7646d2SAndroid Build Coastguard Worker * printer-uri
1009*5e7646d2SAndroid Build Coastguard Worker */
1010*5e7646d2SAndroid Build Coastguard Worker
1011*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_GET_PPDS);
1012*5e7646d2SAndroid Build Coastguard Worker
1013*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1014*5e7646d2SAndroid Build Coastguard Worker NULL, "ipp://localhost/printers/");
1015*5e7646d2SAndroid Build Coastguard Worker
1016*5e7646d2SAndroid Build Coastguard Worker if ((var = cgiGetVariable("PPD_MAKE")) == NULL)
1017*5e7646d2SAndroid Build Coastguard Worker var = cgiGetVariable("CURRENT_MAKE");
1018*5e7646d2SAndroid Build Coastguard Worker if (var && !cgiGetVariable("SELECT_MAKE"))
1019*5e7646d2SAndroid Build Coastguard Worker {
1020*5e7646d2SAndroid Build Coastguard Worker const char *make_model; /* Make and model */
1021*5e7646d2SAndroid Build Coastguard Worker
1022*5e7646d2SAndroid Build Coastguard Worker
1023*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
1024*5e7646d2SAndroid Build Coastguard Worker "ppd-make", NULL, var);
1025*5e7646d2SAndroid Build Coastguard Worker
1026*5e7646d2SAndroid Build Coastguard Worker if ((make_model = cgiGetVariable("CURRENT_MAKE_AND_MODEL")) != NULL)
1027*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
1028*5e7646d2SAndroid Build Coastguard Worker "ppd-make-and-model", NULL, make_model);
1029*5e7646d2SAndroid Build Coastguard Worker }
1030*5e7646d2SAndroid Build Coastguard Worker else
1031*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1032*5e7646d2SAndroid Build Coastguard Worker "requested-attributes", NULL, "ppd-make");
1033*5e7646d2SAndroid Build Coastguard Worker
1034*5e7646d2SAndroid Build Coastguard Worker /*
1035*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
1036*5e7646d2SAndroid Build Coastguard Worker */
1037*5e7646d2SAndroid Build Coastguard Worker
1038*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/")) != NULL)
1039*5e7646d2SAndroid Build Coastguard Worker {
1040*5e7646d2SAndroid Build Coastguard Worker /*
1041*5e7646d2SAndroid Build Coastguard Worker * Got the list of PPDs, see if the user has selected a make...
1042*5e7646d2SAndroid Build Coastguard Worker */
1043*5e7646d2SAndroid Build Coastguard Worker
1044*5e7646d2SAndroid Build Coastguard Worker if (cgiSetIPPVars(response, NULL, NULL, NULL, 0) == 0 && !modify)
1045*5e7646d2SAndroid Build Coastguard Worker {
1046*5e7646d2SAndroid Build Coastguard Worker /*
1047*5e7646d2SAndroid Build Coastguard Worker * No PPD files with this make, try again with all makes...
1048*5e7646d2SAndroid Build Coastguard Worker */
1049*5e7646d2SAndroid Build Coastguard Worker
1050*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
1051*5e7646d2SAndroid Build Coastguard Worker
1052*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_GET_PPDS);
1053*5e7646d2SAndroid Build Coastguard Worker
1054*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1055*5e7646d2SAndroid Build Coastguard Worker NULL, "ipp://localhost/printers/");
1056*5e7646d2SAndroid Build Coastguard Worker
1057*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1058*5e7646d2SAndroid Build Coastguard Worker "requested-attributes", NULL, "ppd-make");
1059*5e7646d2SAndroid Build Coastguard Worker
1060*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/")) != NULL)
1061*5e7646d2SAndroid Build Coastguard Worker cgiSetIPPVars(response, NULL, NULL, NULL, 0);
1062*5e7646d2SAndroid Build Coastguard Worker
1063*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
1064*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("choose-make.tmpl");
1065*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1066*5e7646d2SAndroid Build Coastguard Worker }
1067*5e7646d2SAndroid Build Coastguard Worker else if (!var || cgiGetVariable("SELECT_MAKE"))
1068*5e7646d2SAndroid Build Coastguard Worker {
1069*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
1070*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("choose-make.tmpl");
1071*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1072*5e7646d2SAndroid Build Coastguard Worker }
1073*5e7646d2SAndroid Build Coastguard Worker else
1074*5e7646d2SAndroid Build Coastguard Worker {
1075*5e7646d2SAndroid Build Coastguard Worker /*
1076*5e7646d2SAndroid Build Coastguard Worker * Let the user choose a model...
1077*5e7646d2SAndroid Build Coastguard Worker */
1078*5e7646d2SAndroid Build Coastguard Worker
1079*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
1080*5e7646d2SAndroid Build Coastguard Worker if (!cgiGetVariable("PPD_MAKE"))
1081*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PPD_MAKE", cgiGetVariable("CURRENT_MAKE"));
1082*5e7646d2SAndroid Build Coastguard Worker if (ipp_everywhere)
1083*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("SHOW_IPP_EVERYWHERE", "1");
1084*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("choose-model.tmpl");
1085*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1086*5e7646d2SAndroid Build Coastguard Worker }
1087*5e7646d2SAndroid Build Coastguard Worker
1088*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
1089*5e7646d2SAndroid Build Coastguard Worker }
1090*5e7646d2SAndroid Build Coastguard Worker else
1091*5e7646d2SAndroid Build Coastguard Worker {
1092*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
1093*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to get list of printer drivers"));
1094*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1095*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1096*5e7646d2SAndroid Build Coastguard Worker }
1097*5e7646d2SAndroid Build Coastguard Worker }
1098*5e7646d2SAndroid Build Coastguard Worker else
1099*5e7646d2SAndroid Build Coastguard Worker {
1100*5e7646d2SAndroid Build Coastguard Worker /*
1101*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_ADD_PRINTER request, which requires the following
1102*5e7646d2SAndroid Build Coastguard Worker * attributes:
1103*5e7646d2SAndroid Build Coastguard Worker *
1104*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
1105*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
1106*5e7646d2SAndroid Build Coastguard Worker * printer-uri
1107*5e7646d2SAndroid Build Coastguard Worker * printer-location
1108*5e7646d2SAndroid Build Coastguard Worker * printer-info
1109*5e7646d2SAndroid Build Coastguard Worker * ppd-name
1110*5e7646d2SAndroid Build Coastguard Worker * device-uri
1111*5e7646d2SAndroid Build Coastguard Worker * printer-is-accepting-jobs
1112*5e7646d2SAndroid Build Coastguard Worker * printer-is-shared
1113*5e7646d2SAndroid Build Coastguard Worker * printer-state
1114*5e7646d2SAndroid Build Coastguard Worker */
1115*5e7646d2SAndroid Build Coastguard Worker
1116*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_ADD_PRINTER);
1117*5e7646d2SAndroid Build Coastguard Worker
1118*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
1119*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/printers/%s",
1120*5e7646d2SAndroid Build Coastguard Worker cgiGetVariable("PRINTER_NAME"));
1121*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1122*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
1123*5e7646d2SAndroid Build Coastguard Worker
1124*5e7646d2SAndroid Build Coastguard Worker if (!file)
1125*5e7646d2SAndroid Build Coastguard Worker {
1126*5e7646d2SAndroid Build Coastguard Worker var = cgiGetVariable("PPD_NAME");
1127*5e7646d2SAndroid Build Coastguard Worker if (strcmp(var, "__no_change__"))
1128*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "ppd-name",
1129*5e7646d2SAndroid Build Coastguard Worker NULL, var);
1130*5e7646d2SAndroid Build Coastguard Worker }
1131*5e7646d2SAndroid Build Coastguard Worker
1132*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
1133*5e7646d2SAndroid Build Coastguard Worker NULL, cgiGetVariable("PRINTER_LOCATION"));
1134*5e7646d2SAndroid Build Coastguard Worker
1135*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
1136*5e7646d2SAndroid Build Coastguard Worker NULL, cgiGetVariable("PRINTER_INFO"));
1137*5e7646d2SAndroid Build Coastguard Worker
1138*5e7646d2SAndroid Build Coastguard Worker strlcpy(uri, cgiGetVariable("DEVICE_URI"), sizeof(uri));
1139*5e7646d2SAndroid Build Coastguard Worker
1140*5e7646d2SAndroid Build Coastguard Worker /*
1141*5e7646d2SAndroid Build Coastguard Worker * Strip make and model from URI...
1142*5e7646d2SAndroid Build Coastguard Worker */
1143*5e7646d2SAndroid Build Coastguard Worker
1144*5e7646d2SAndroid Build Coastguard Worker if ((uriptr = strrchr(uri, '|')) != NULL)
1145*5e7646d2SAndroid Build Coastguard Worker *uriptr = '\0';
1146*5e7646d2SAndroid Build Coastguard Worker
1147*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(uri, "serial:", 7))
1148*5e7646d2SAndroid Build Coastguard Worker {
1149*5e7646d2SAndroid Build Coastguard Worker /*
1150*5e7646d2SAndroid Build Coastguard Worker * Update serial port URI to include baud rate, etc.
1151*5e7646d2SAndroid Build Coastguard Worker */
1152*5e7646d2SAndroid Build Coastguard Worker
1153*5e7646d2SAndroid Build Coastguard Worker if ((uriptr = strchr(uri, '?')) == NULL)
1154*5e7646d2SAndroid Build Coastguard Worker uriptr = uri + strlen(uri);
1155*5e7646d2SAndroid Build Coastguard Worker
1156*5e7646d2SAndroid Build Coastguard Worker snprintf(uriptr, sizeof(uri) - (size_t)(uriptr - uri),
1157*5e7646d2SAndroid Build Coastguard Worker "?baud=%s+bits=%s+parity=%s+flow=%s",
1158*5e7646d2SAndroid Build Coastguard Worker cgiGetVariable("BAUDRATE"), cgiGetVariable("BITS"),
1159*5e7646d2SAndroid Build Coastguard Worker cgiGetVariable("PARITY"), cgiGetVariable("FLOW"));
1160*5e7646d2SAndroid Build Coastguard Worker }
1161*5e7646d2SAndroid Build Coastguard Worker
1162*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri",
1163*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
1164*5e7646d2SAndroid Build Coastguard Worker
1165*5e7646d2SAndroid Build Coastguard Worker ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
1166*5e7646d2SAndroid Build Coastguard Worker
1167*5e7646d2SAndroid Build Coastguard Worker var = cgiGetVariable("printer_is_shared");
1168*5e7646d2SAndroid Build Coastguard Worker ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-shared",
1169*5e7646d2SAndroid Build Coastguard Worker var && (!strcmp(var, "1") || !strcmp(var, "on")));
1170*5e7646d2SAndroid Build Coastguard Worker
1171*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
1172*5e7646d2SAndroid Build Coastguard Worker IPP_PRINTER_IDLE);
1173*5e7646d2SAndroid Build Coastguard Worker
1174*5e7646d2SAndroid Build Coastguard Worker /*
1175*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
1176*5e7646d2SAndroid Build Coastguard Worker */
1177*5e7646d2SAndroid Build Coastguard Worker
1178*5e7646d2SAndroid Build Coastguard Worker if (file)
1179*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoFileRequest(http, request, "/admin/", file->tempfile));
1180*5e7646d2SAndroid Build Coastguard Worker else if (evefile[0])
1181*5e7646d2SAndroid Build Coastguard Worker {
1182*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoFileRequest(http, request, "/admin/", evefile));
1183*5e7646d2SAndroid Build Coastguard Worker unlink(evefile);
1184*5e7646d2SAndroid Build Coastguard Worker }
1185*5e7646d2SAndroid Build Coastguard Worker else
1186*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/admin/"));
1187*5e7646d2SAndroid Build Coastguard Worker
1188*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
1189*5e7646d2SAndroid Build Coastguard Worker {
1190*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
1191*5e7646d2SAndroid Build Coastguard Worker exit(0);
1192*5e7646d2SAndroid Build Coastguard Worker }
1193*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() > IPP_OK_CONFLICT)
1194*5e7646d2SAndroid Build Coastguard Worker {
1195*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
1196*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(modify ? _("Unable to modify printer") :
1197*5e7646d2SAndroid Build Coastguard Worker _("Unable to add printer"));
1198*5e7646d2SAndroid Build Coastguard Worker }
1199*5e7646d2SAndroid Build Coastguard Worker else if (modify)
1200*5e7646d2SAndroid Build Coastguard Worker {
1201*5e7646d2SAndroid Build Coastguard Worker /*
1202*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the printer page...
1203*5e7646d2SAndroid Build Coastguard Worker */
1204*5e7646d2SAndroid Build Coastguard Worker
1205*5e7646d2SAndroid Build Coastguard Worker char refresh[1024]; /* Refresh URL */
1206*5e7646d2SAndroid Build Coastguard Worker
1207*5e7646d2SAndroid Build Coastguard Worker
1208*5e7646d2SAndroid Build Coastguard Worker cgiFormEncode(uri, name, sizeof(uri));
1209*5e7646d2SAndroid Build Coastguard Worker
1210*5e7646d2SAndroid Build Coastguard Worker snprintf(refresh, sizeof(refresh),
1211*5e7646d2SAndroid Build Coastguard Worker "5;/admin/?OP=redirect&URL=/printers/%s", uri);
1212*5e7646d2SAndroid Build Coastguard Worker
1213*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", refresh);
1214*5e7646d2SAndroid Build Coastguard Worker
1215*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
1216*5e7646d2SAndroid Build Coastguard Worker
1217*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("printer-modified.tmpl");
1218*5e7646d2SAndroid Build Coastguard Worker }
1219*5e7646d2SAndroid Build Coastguard Worker else
1220*5e7646d2SAndroid Build Coastguard Worker {
1221*5e7646d2SAndroid Build Coastguard Worker /*
1222*5e7646d2SAndroid Build Coastguard Worker * Set the printer options...
1223*5e7646d2SAndroid Build Coastguard Worker */
1224*5e7646d2SAndroid Build Coastguard Worker
1225*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("OP", "set-printer-options");
1226*5e7646d2SAndroid Build Coastguard Worker do_set_options(http, 0);
1227*5e7646d2SAndroid Build Coastguard Worker return;
1228*5e7646d2SAndroid Build Coastguard Worker }
1229*5e7646d2SAndroid Build Coastguard Worker
1230*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1231*5e7646d2SAndroid Build Coastguard Worker }
1232*5e7646d2SAndroid Build Coastguard Worker
1233*5e7646d2SAndroid Build Coastguard Worker if (oldinfo)
1234*5e7646d2SAndroid Build Coastguard Worker ippDelete(oldinfo);
1235*5e7646d2SAndroid Build Coastguard Worker }
1236*5e7646d2SAndroid Build Coastguard Worker
1237*5e7646d2SAndroid Build Coastguard Worker
1238*5e7646d2SAndroid Build Coastguard Worker /*
1239*5e7646d2SAndroid Build Coastguard Worker * 'do_config_server()' - Configure server settings.
1240*5e7646d2SAndroid Build Coastguard Worker */
1241*5e7646d2SAndroid Build Coastguard Worker
1242*5e7646d2SAndroid Build Coastguard Worker static void
do_config_server(http_t * http)1243*5e7646d2SAndroid Build Coastguard Worker do_config_server(http_t *http) /* I - HTTP connection */
1244*5e7646d2SAndroid Build Coastguard Worker {
1245*5e7646d2SAndroid Build Coastguard Worker if (cgiGetVariable("CHANGESETTINGS"))
1246*5e7646d2SAndroid Build Coastguard Worker {
1247*5e7646d2SAndroid Build Coastguard Worker /*
1248*5e7646d2SAndroid Build Coastguard Worker * Save basic setting changes...
1249*5e7646d2SAndroid Build Coastguard Worker */
1250*5e7646d2SAndroid Build Coastguard Worker
1251*5e7646d2SAndroid Build Coastguard Worker int num_settings; /* Number of server settings */
1252*5e7646d2SAndroid Build Coastguard Worker cups_option_t *settings; /* Server settings */
1253*5e7646d2SAndroid Build Coastguard Worker int advanced, /* Advanced settings shown? */
1254*5e7646d2SAndroid Build Coastguard Worker changed; /* Have settings changed? */
1255*5e7646d2SAndroid Build Coastguard Worker const char *debug_logging, /* DEBUG_LOGGING value */
1256*5e7646d2SAndroid Build Coastguard Worker *preserve_jobs = NULL,
1257*5e7646d2SAndroid Build Coastguard Worker /* PRESERVE_JOBS value */
1258*5e7646d2SAndroid Build Coastguard Worker *remote_admin, /* REMOTE_ADMIN value */
1259*5e7646d2SAndroid Build Coastguard Worker *remote_any, /* REMOTE_ANY value */
1260*5e7646d2SAndroid Build Coastguard Worker *share_printers,/* SHARE_PRINTERS value */
1261*5e7646d2SAndroid Build Coastguard Worker *user_cancel_any,
1262*5e7646d2SAndroid Build Coastguard Worker /* USER_CANCEL_ANY value */
1263*5e7646d2SAndroid Build Coastguard Worker *browse_web_if = NULL,
1264*5e7646d2SAndroid Build Coastguard Worker /* BrowseWebIF value */
1265*5e7646d2SAndroid Build Coastguard Worker *preserve_job_history = NULL,
1266*5e7646d2SAndroid Build Coastguard Worker /* PreserveJobHistory value */
1267*5e7646d2SAndroid Build Coastguard Worker *preserve_job_files = NULL,
1268*5e7646d2SAndroid Build Coastguard Worker /* PreserveJobFiles value */
1269*5e7646d2SAndroid Build Coastguard Worker *max_clients = NULL,
1270*5e7646d2SAndroid Build Coastguard Worker /* MaxClients value */
1271*5e7646d2SAndroid Build Coastguard Worker *max_jobs = NULL,
1272*5e7646d2SAndroid Build Coastguard Worker /* MaxJobs value */
1273*5e7646d2SAndroid Build Coastguard Worker *max_log_size = NULL;
1274*5e7646d2SAndroid Build Coastguard Worker /* MaxLogSize value */
1275*5e7646d2SAndroid Build Coastguard Worker const char *current_browse_web_if,
1276*5e7646d2SAndroid Build Coastguard Worker /* BrowseWebIF value */
1277*5e7646d2SAndroid Build Coastguard Worker *current_preserve_job_history,
1278*5e7646d2SAndroid Build Coastguard Worker /* PreserveJobHistory value */
1279*5e7646d2SAndroid Build Coastguard Worker *current_preserve_job_files,
1280*5e7646d2SAndroid Build Coastguard Worker /* PreserveJobFiles value */
1281*5e7646d2SAndroid Build Coastguard Worker *current_max_clients,
1282*5e7646d2SAndroid Build Coastguard Worker /* MaxClients value */
1283*5e7646d2SAndroid Build Coastguard Worker *current_max_jobs,
1284*5e7646d2SAndroid Build Coastguard Worker /* MaxJobs value */
1285*5e7646d2SAndroid Build Coastguard Worker *current_max_log_size;
1286*5e7646d2SAndroid Build Coastguard Worker /* MaxLogSize value */
1287*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GSSAPI
1288*5e7646d2SAndroid Build Coastguard Worker char default_auth_type[255];
1289*5e7646d2SAndroid Build Coastguard Worker /* DefaultAuthType value */
1290*5e7646d2SAndroid Build Coastguard Worker const char *val; /* Setting value */
1291*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GSSAPI */
1292*5e7646d2SAndroid Build Coastguard Worker
1293*5e7646d2SAndroid Build Coastguard Worker
1294*5e7646d2SAndroid Build Coastguard Worker /*
1295*5e7646d2SAndroid Build Coastguard Worker * Get the checkbox values from the form...
1296*5e7646d2SAndroid Build Coastguard Worker */
1297*5e7646d2SAndroid Build Coastguard Worker
1298*5e7646d2SAndroid Build Coastguard Worker debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0";
1299*5e7646d2SAndroid Build Coastguard Worker remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0";
1300*5e7646d2SAndroid Build Coastguard Worker remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0";
1301*5e7646d2SAndroid Build Coastguard Worker share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0";
1302*5e7646d2SAndroid Build Coastguard Worker user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0";
1303*5e7646d2SAndroid Build Coastguard Worker
1304*5e7646d2SAndroid Build Coastguard Worker advanced = cgiGetVariable("ADVANCEDSETTINGS") != NULL;
1305*5e7646d2SAndroid Build Coastguard Worker if (advanced)
1306*5e7646d2SAndroid Build Coastguard Worker {
1307*5e7646d2SAndroid Build Coastguard Worker /*
1308*5e7646d2SAndroid Build Coastguard Worker * Get advanced settings...
1309*5e7646d2SAndroid Build Coastguard Worker */
1310*5e7646d2SAndroid Build Coastguard Worker
1311*5e7646d2SAndroid Build Coastguard Worker browse_web_if = cgiGetVariable("BROWSE_WEB_IF") ? "Yes" : "No";
1312*5e7646d2SAndroid Build Coastguard Worker max_clients = cgiGetVariable("MAX_CLIENTS");
1313*5e7646d2SAndroid Build Coastguard Worker max_log_size = cgiGetVariable("MAX_LOG_SIZE");
1314*5e7646d2SAndroid Build Coastguard Worker preserve_jobs = cgiGetVariable("PRESERVE_JOBS");
1315*5e7646d2SAndroid Build Coastguard Worker
1316*5e7646d2SAndroid Build Coastguard Worker if (preserve_jobs)
1317*5e7646d2SAndroid Build Coastguard Worker {
1318*5e7646d2SAndroid Build Coastguard Worker max_jobs = cgiGetVariable("MAX_JOBS");
1319*5e7646d2SAndroid Build Coastguard Worker preserve_job_history = cgiGetVariable("PRESERVE_JOB_HISTORY");
1320*5e7646d2SAndroid Build Coastguard Worker preserve_job_files = cgiGetVariable("PRESERVE_JOB_FILES");
1321*5e7646d2SAndroid Build Coastguard Worker
1322*5e7646d2SAndroid Build Coastguard Worker if (!max_jobs || atoi(max_jobs) < 0)
1323*5e7646d2SAndroid Build Coastguard Worker max_jobs = "500";
1324*5e7646d2SAndroid Build Coastguard Worker
1325*5e7646d2SAndroid Build Coastguard Worker if (!preserve_job_history)
1326*5e7646d2SAndroid Build Coastguard Worker preserve_job_history = "On";
1327*5e7646d2SAndroid Build Coastguard Worker
1328*5e7646d2SAndroid Build Coastguard Worker if (!preserve_job_files)
1329*5e7646d2SAndroid Build Coastguard Worker preserve_job_files = "1d";
1330*5e7646d2SAndroid Build Coastguard Worker }
1331*5e7646d2SAndroid Build Coastguard Worker else
1332*5e7646d2SAndroid Build Coastguard Worker {
1333*5e7646d2SAndroid Build Coastguard Worker max_jobs = "0";
1334*5e7646d2SAndroid Build Coastguard Worker preserve_job_history = "No";
1335*5e7646d2SAndroid Build Coastguard Worker preserve_job_files = "No";
1336*5e7646d2SAndroid Build Coastguard Worker }
1337*5e7646d2SAndroid Build Coastguard Worker
1338*5e7646d2SAndroid Build Coastguard Worker if (!max_clients || atoi(max_clients) <= 0)
1339*5e7646d2SAndroid Build Coastguard Worker max_clients = "100";
1340*5e7646d2SAndroid Build Coastguard Worker
1341*5e7646d2SAndroid Build Coastguard Worker if (!max_log_size || atoi(max_log_size) <= 0.0)
1342*5e7646d2SAndroid Build Coastguard Worker max_log_size = "1m";
1343*5e7646d2SAndroid Build Coastguard Worker }
1344*5e7646d2SAndroid Build Coastguard Worker
1345*5e7646d2SAndroid Build Coastguard Worker /*
1346*5e7646d2SAndroid Build Coastguard Worker * Get the current server settings...
1347*5e7646d2SAndroid Build Coastguard Worker */
1348*5e7646d2SAndroid Build Coastguard Worker
1349*5e7646d2SAndroid Build Coastguard Worker if (!cupsAdminGetServerSettings(http, &num_settings, &settings))
1350*5e7646d2SAndroid Build Coastguard Worker {
1351*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Change Settings")));
1352*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE",
1353*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to change server settings")));
1354*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cupsLastErrorString());
1355*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1356*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1357*5e7646d2SAndroid Build Coastguard Worker return;
1358*5e7646d2SAndroid Build Coastguard Worker }
1359*5e7646d2SAndroid Build Coastguard Worker
1360*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GSSAPI
1361*5e7646d2SAndroid Build Coastguard Worker /*
1362*5e7646d2SAndroid Build Coastguard Worker * Get authentication settings...
1363*5e7646d2SAndroid Build Coastguard Worker */
1364*5e7646d2SAndroid Build Coastguard Worker
1365*5e7646d2SAndroid Build Coastguard Worker if (cgiGetVariable("KERBEROS"))
1366*5e7646d2SAndroid Build Coastguard Worker strlcpy(default_auth_type, "Negotiate", sizeof(default_auth_type));
1367*5e7646d2SAndroid Build Coastguard Worker else
1368*5e7646d2SAndroid Build Coastguard Worker {
1369*5e7646d2SAndroid Build Coastguard Worker val = cupsGetOption("DefaultAuthType", num_settings, settings);
1370*5e7646d2SAndroid Build Coastguard Worker
1371*5e7646d2SAndroid Build Coastguard Worker if (!val || !_cups_strcasecmp(val, "Negotiate"))
1372*5e7646d2SAndroid Build Coastguard Worker strlcpy(default_auth_type, "Basic", sizeof(default_auth_type));
1373*5e7646d2SAndroid Build Coastguard Worker else
1374*5e7646d2SAndroid Build Coastguard Worker strlcpy(default_auth_type, val, sizeof(default_auth_type));
1375*5e7646d2SAndroid Build Coastguard Worker }
1376*5e7646d2SAndroid Build Coastguard Worker
1377*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: DefaultAuthType %s\n", default_auth_type);
1378*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GSSAPI */
1379*5e7646d2SAndroid Build Coastguard Worker
1380*5e7646d2SAndroid Build Coastguard Worker if ((current_browse_web_if = cupsGetOption("BrowseWebIF", num_settings,
1381*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
1382*5e7646d2SAndroid Build Coastguard Worker current_browse_web_if = "No";
1383*5e7646d2SAndroid Build Coastguard Worker
1384*5e7646d2SAndroid Build Coastguard Worker if ((current_preserve_job_history = cupsGetOption("PreserveJobHistory",
1385*5e7646d2SAndroid Build Coastguard Worker num_settings,
1386*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
1387*5e7646d2SAndroid Build Coastguard Worker current_preserve_job_history = "Yes";
1388*5e7646d2SAndroid Build Coastguard Worker
1389*5e7646d2SAndroid Build Coastguard Worker if ((current_preserve_job_files = cupsGetOption("PreserveJobFiles",
1390*5e7646d2SAndroid Build Coastguard Worker num_settings,
1391*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
1392*5e7646d2SAndroid Build Coastguard Worker current_preserve_job_files = "1d";
1393*5e7646d2SAndroid Build Coastguard Worker
1394*5e7646d2SAndroid Build Coastguard Worker if ((current_max_clients = cupsGetOption("MaxClients", num_settings,
1395*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
1396*5e7646d2SAndroid Build Coastguard Worker current_max_clients = "100";
1397*5e7646d2SAndroid Build Coastguard Worker
1398*5e7646d2SAndroid Build Coastguard Worker if ((current_max_jobs = cupsGetOption("MaxJobs", num_settings,
1399*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
1400*5e7646d2SAndroid Build Coastguard Worker current_max_jobs = "500";
1401*5e7646d2SAndroid Build Coastguard Worker
1402*5e7646d2SAndroid Build Coastguard Worker if ((current_max_log_size = cupsGetOption("MaxLogSize", num_settings,
1403*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
1404*5e7646d2SAndroid Build Coastguard Worker current_max_log_size = "1m";
1405*5e7646d2SAndroid Build Coastguard Worker
1406*5e7646d2SAndroid Build Coastguard Worker /*
1407*5e7646d2SAndroid Build Coastguard Worker * See if the settings have changed...
1408*5e7646d2SAndroid Build Coastguard Worker */
1409*5e7646d2SAndroid Build Coastguard Worker
1410*5e7646d2SAndroid Build Coastguard Worker changed = strcmp(debug_logging, cupsGetOption(CUPS_SERVER_DEBUG_LOGGING,
1411*5e7646d2SAndroid Build Coastguard Worker num_settings, settings)) ||
1412*5e7646d2SAndroid Build Coastguard Worker strcmp(remote_admin, cupsGetOption(CUPS_SERVER_REMOTE_ADMIN,
1413*5e7646d2SAndroid Build Coastguard Worker num_settings, settings)) ||
1414*5e7646d2SAndroid Build Coastguard Worker strcmp(remote_any, cupsGetOption(CUPS_SERVER_REMOTE_ANY,
1415*5e7646d2SAndroid Build Coastguard Worker num_settings, settings)) ||
1416*5e7646d2SAndroid Build Coastguard Worker strcmp(share_printers, cupsGetOption(CUPS_SERVER_SHARE_PRINTERS,
1417*5e7646d2SAndroid Build Coastguard Worker num_settings, settings)) ||
1418*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GSSAPI
1419*5e7646d2SAndroid Build Coastguard Worker !cupsGetOption("DefaultAuthType", num_settings, settings) ||
1420*5e7646d2SAndroid Build Coastguard Worker strcmp(default_auth_type, cupsGetOption("DefaultAuthType",
1421*5e7646d2SAndroid Build Coastguard Worker num_settings, settings)) ||
1422*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GSSAPI */
1423*5e7646d2SAndroid Build Coastguard Worker strcmp(user_cancel_any, cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY,
1424*5e7646d2SAndroid Build Coastguard Worker num_settings, settings));
1425*5e7646d2SAndroid Build Coastguard Worker
1426*5e7646d2SAndroid Build Coastguard Worker if (advanced && !changed)
1427*5e7646d2SAndroid Build Coastguard Worker changed = _cups_strcasecmp(browse_web_if, current_browse_web_if) ||
1428*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(preserve_job_history, current_preserve_job_history) ||
1429*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(preserve_job_files, current_preserve_job_files) ||
1430*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(max_clients, current_max_clients) ||
1431*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(max_jobs, current_max_jobs) ||
1432*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(max_log_size, current_max_log_size);
1433*5e7646d2SAndroid Build Coastguard Worker
1434*5e7646d2SAndroid Build Coastguard Worker if (changed)
1435*5e7646d2SAndroid Build Coastguard Worker {
1436*5e7646d2SAndroid Build Coastguard Worker /*
1437*5e7646d2SAndroid Build Coastguard Worker * Settings *have* changed, so save the changes...
1438*5e7646d2SAndroid Build Coastguard Worker */
1439*5e7646d2SAndroid Build Coastguard Worker
1440*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_settings, settings);
1441*5e7646d2SAndroid Build Coastguard Worker
1442*5e7646d2SAndroid Build Coastguard Worker num_settings = 0;
1443*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
1444*5e7646d2SAndroid Build Coastguard Worker debug_logging, num_settings, &settings);
1445*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
1446*5e7646d2SAndroid Build Coastguard Worker remote_admin, num_settings, &settings);
1447*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
1448*5e7646d2SAndroid Build Coastguard Worker remote_any, num_settings, &settings);
1449*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
1450*5e7646d2SAndroid Build Coastguard Worker share_printers, num_settings, &settings);
1451*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
1452*5e7646d2SAndroid Build Coastguard Worker user_cancel_any, num_settings, &settings);
1453*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GSSAPI
1454*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption("DefaultAuthType", default_auth_type,
1455*5e7646d2SAndroid Build Coastguard Worker num_settings, &settings);
1456*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GSSAPI */
1457*5e7646d2SAndroid Build Coastguard Worker
1458*5e7646d2SAndroid Build Coastguard Worker if (advanced)
1459*5e7646d2SAndroid Build Coastguard Worker {
1460*5e7646d2SAndroid Build Coastguard Worker /*
1461*5e7646d2SAndroid Build Coastguard Worker * Add advanced settings...
1462*5e7646d2SAndroid Build Coastguard Worker */
1463*5e7646d2SAndroid Build Coastguard Worker
1464*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(browse_web_if, current_browse_web_if))
1465*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption("BrowseWebIF", browse_web_if,
1466*5e7646d2SAndroid Build Coastguard Worker num_settings, &settings);
1467*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(preserve_job_history, current_preserve_job_history))
1468*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption("PreserveJobHistory",
1469*5e7646d2SAndroid Build Coastguard Worker preserve_job_history, num_settings,
1470*5e7646d2SAndroid Build Coastguard Worker &settings);
1471*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(preserve_job_files, current_preserve_job_files))
1472*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption("PreserveJobFiles", preserve_job_files,
1473*5e7646d2SAndroid Build Coastguard Worker num_settings, &settings);
1474*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(max_clients, current_max_clients))
1475*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption("MaxClients", max_clients, num_settings,
1476*5e7646d2SAndroid Build Coastguard Worker &settings);
1477*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(max_jobs, current_max_jobs))
1478*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption("MaxJobs", max_jobs, num_settings,
1479*5e7646d2SAndroid Build Coastguard Worker &settings);
1480*5e7646d2SAndroid Build Coastguard Worker if (_cups_strcasecmp(max_log_size, current_max_log_size))
1481*5e7646d2SAndroid Build Coastguard Worker num_settings = cupsAddOption("MaxLogSize", max_log_size, num_settings,
1482*5e7646d2SAndroid Build Coastguard Worker &settings);
1483*5e7646d2SAndroid Build Coastguard Worker }
1484*5e7646d2SAndroid Build Coastguard Worker
1485*5e7646d2SAndroid Build Coastguard Worker if (!cupsAdminSetServerSettings(http, num_settings, settings))
1486*5e7646d2SAndroid Build Coastguard Worker {
1487*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
1488*5e7646d2SAndroid Build Coastguard Worker {
1489*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
1490*5e7646d2SAndroid Build Coastguard Worker exit(0);
1491*5e7646d2SAndroid Build Coastguard Worker }
1492*5e7646d2SAndroid Build Coastguard Worker
1493*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Change Settings")));
1494*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE",
1495*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to change server settings")));
1496*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cupsLastErrorString());
1497*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1498*5e7646d2SAndroid Build Coastguard Worker }
1499*5e7646d2SAndroid Build Coastguard Worker else
1500*5e7646d2SAndroid Build Coastguard Worker {
1501*5e7646d2SAndroid Build Coastguard Worker if (advanced)
1502*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&"
1503*5e7646d2SAndroid Build Coastguard Worker "URL=/admin/?ADVANCEDSETTINGS=YES");
1504*5e7646d2SAndroid Build Coastguard Worker else
1505*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
1506*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Change Settings")));
1507*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("restart.tmpl");
1508*5e7646d2SAndroid Build Coastguard Worker }
1509*5e7646d2SAndroid Build Coastguard Worker }
1510*5e7646d2SAndroid Build Coastguard Worker else
1511*5e7646d2SAndroid Build Coastguard Worker {
1512*5e7646d2SAndroid Build Coastguard Worker /*
1513*5e7646d2SAndroid Build Coastguard Worker * No changes...
1514*5e7646d2SAndroid Build Coastguard Worker */
1515*5e7646d2SAndroid Build Coastguard Worker
1516*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
1517*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Change Settings")));
1518*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("norestart.tmpl");
1519*5e7646d2SAndroid Build Coastguard Worker }
1520*5e7646d2SAndroid Build Coastguard Worker
1521*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_settings, settings);
1522*5e7646d2SAndroid Build Coastguard Worker
1523*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1524*5e7646d2SAndroid Build Coastguard Worker }
1525*5e7646d2SAndroid Build Coastguard Worker else if (cgiGetVariable("SAVECHANGES") && cgiGetVariable("CUPSDCONF"))
1526*5e7646d2SAndroid Build Coastguard Worker {
1527*5e7646d2SAndroid Build Coastguard Worker /*
1528*5e7646d2SAndroid Build Coastguard Worker * Save hand-edited config file...
1529*5e7646d2SAndroid Build Coastguard Worker */
1530*5e7646d2SAndroid Build Coastguard Worker
1531*5e7646d2SAndroid Build Coastguard Worker http_status_t status; /* PUT status */
1532*5e7646d2SAndroid Build Coastguard Worker char tempfile[1024]; /* Temporary new cupsd.conf */
1533*5e7646d2SAndroid Build Coastguard Worker int tempfd; /* Temporary file descriptor */
1534*5e7646d2SAndroid Build Coastguard Worker cups_file_t *temp; /* Temporary file */
1535*5e7646d2SAndroid Build Coastguard Worker const char *start, /* Start of line */
1536*5e7646d2SAndroid Build Coastguard Worker *end; /* End of line */
1537*5e7646d2SAndroid Build Coastguard Worker
1538*5e7646d2SAndroid Build Coastguard Worker
1539*5e7646d2SAndroid Build Coastguard Worker /*
1540*5e7646d2SAndroid Build Coastguard Worker * Create a temporary file for the new cupsd.conf file...
1541*5e7646d2SAndroid Build Coastguard Worker */
1542*5e7646d2SAndroid Build Coastguard Worker
1543*5e7646d2SAndroid Build Coastguard Worker if ((tempfd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
1544*5e7646d2SAndroid Build Coastguard Worker {
1545*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1546*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file")));
1547*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", strerror(errno));
1548*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1549*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1550*5e7646d2SAndroid Build Coastguard Worker
1551*5e7646d2SAndroid Build Coastguard Worker perror(tempfile);
1552*5e7646d2SAndroid Build Coastguard Worker return;
1553*5e7646d2SAndroid Build Coastguard Worker }
1554*5e7646d2SAndroid Build Coastguard Worker
1555*5e7646d2SAndroid Build Coastguard Worker if ((temp = cupsFileOpenFd(tempfd, "w")) == NULL)
1556*5e7646d2SAndroid Build Coastguard Worker {
1557*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1558*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file")));
1559*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", strerror(errno));
1560*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1561*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1562*5e7646d2SAndroid Build Coastguard Worker
1563*5e7646d2SAndroid Build Coastguard Worker perror(tempfile);
1564*5e7646d2SAndroid Build Coastguard Worker close(tempfd);
1565*5e7646d2SAndroid Build Coastguard Worker unlink(tempfile);
1566*5e7646d2SAndroid Build Coastguard Worker return;
1567*5e7646d2SAndroid Build Coastguard Worker }
1568*5e7646d2SAndroid Build Coastguard Worker
1569*5e7646d2SAndroid Build Coastguard Worker /*
1570*5e7646d2SAndroid Build Coastguard Worker * Copy the cupsd.conf text from the form variable...
1571*5e7646d2SAndroid Build Coastguard Worker */
1572*5e7646d2SAndroid Build Coastguard Worker
1573*5e7646d2SAndroid Build Coastguard Worker start = cgiGetVariable("CUPSDCONF");
1574*5e7646d2SAndroid Build Coastguard Worker while (start)
1575*5e7646d2SAndroid Build Coastguard Worker {
1576*5e7646d2SAndroid Build Coastguard Worker if ((end = strstr(start, "\r\n")) == NULL)
1577*5e7646d2SAndroid Build Coastguard Worker if ((end = strstr(start, "\n")) == NULL)
1578*5e7646d2SAndroid Build Coastguard Worker end = start + strlen(start);
1579*5e7646d2SAndroid Build Coastguard Worker
1580*5e7646d2SAndroid Build Coastguard Worker cupsFileWrite(temp, start, (size_t)(end - start));
1581*5e7646d2SAndroid Build Coastguard Worker cupsFilePutChar(temp, '\n');
1582*5e7646d2SAndroid Build Coastguard Worker
1583*5e7646d2SAndroid Build Coastguard Worker if (*end == '\r')
1584*5e7646d2SAndroid Build Coastguard Worker start = end + 2;
1585*5e7646d2SAndroid Build Coastguard Worker else if (*end == '\n')
1586*5e7646d2SAndroid Build Coastguard Worker start = end + 1;
1587*5e7646d2SAndroid Build Coastguard Worker else
1588*5e7646d2SAndroid Build Coastguard Worker start = NULL;
1589*5e7646d2SAndroid Build Coastguard Worker }
1590*5e7646d2SAndroid Build Coastguard Worker
1591*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(temp);
1592*5e7646d2SAndroid Build Coastguard Worker
1593*5e7646d2SAndroid Build Coastguard Worker /*
1594*5e7646d2SAndroid Build Coastguard Worker * Upload the configuration file to the server...
1595*5e7646d2SAndroid Build Coastguard Worker */
1596*5e7646d2SAndroid Build Coastguard Worker
1597*5e7646d2SAndroid Build Coastguard Worker status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile);
1598*5e7646d2SAndroid Build Coastguard Worker
1599*5e7646d2SAndroid Build Coastguard Worker if (status == HTTP_UNAUTHORIZED)
1600*5e7646d2SAndroid Build Coastguard Worker {
1601*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
1602*5e7646d2SAndroid Build Coastguard Worker unlink(tempfile);
1603*5e7646d2SAndroid Build Coastguard Worker exit(0);
1604*5e7646d2SAndroid Build Coastguard Worker }
1605*5e7646d2SAndroid Build Coastguard Worker else if (status != HTTP_CREATED)
1606*5e7646d2SAndroid Build Coastguard Worker {
1607*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE",
1608*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to upload cupsd.conf file")));
1609*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", httpStatus(status));
1610*5e7646d2SAndroid Build Coastguard Worker
1611*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1612*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1613*5e7646d2SAndroid Build Coastguard Worker }
1614*5e7646d2SAndroid Build Coastguard Worker else
1615*5e7646d2SAndroid Build Coastguard Worker {
1616*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", "5;URL=/admin/");
1617*5e7646d2SAndroid Build Coastguard Worker
1618*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1619*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("restart.tmpl");
1620*5e7646d2SAndroid Build Coastguard Worker }
1621*5e7646d2SAndroid Build Coastguard Worker
1622*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1623*5e7646d2SAndroid Build Coastguard Worker
1624*5e7646d2SAndroid Build Coastguard Worker unlink(tempfile);
1625*5e7646d2SAndroid Build Coastguard Worker }
1626*5e7646d2SAndroid Build Coastguard Worker else
1627*5e7646d2SAndroid Build Coastguard Worker {
1628*5e7646d2SAndroid Build Coastguard Worker struct stat info; /* cupsd.conf information */
1629*5e7646d2SAndroid Build Coastguard Worker cups_file_t *cupsd; /* cupsd.conf file */
1630*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* Buffer for entire file */
1631*5e7646d2SAndroid Build Coastguard Worker *bufptr, /* Pointer into buffer */
1632*5e7646d2SAndroid Build Coastguard Worker *bufend; /* End of buffer */
1633*5e7646d2SAndroid Build Coastguard Worker int ch; /* Character from file */
1634*5e7646d2SAndroid Build Coastguard Worker char filename[1024]; /* Filename */
1635*5e7646d2SAndroid Build Coastguard Worker const char *server_root; /* Location of config files */
1636*5e7646d2SAndroid Build Coastguard Worker
1637*5e7646d2SAndroid Build Coastguard Worker
1638*5e7646d2SAndroid Build Coastguard Worker /*
1639*5e7646d2SAndroid Build Coastguard Worker * Locate the cupsd.conf file...
1640*5e7646d2SAndroid Build Coastguard Worker */
1641*5e7646d2SAndroid Build Coastguard Worker
1642*5e7646d2SAndroid Build Coastguard Worker if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
1643*5e7646d2SAndroid Build Coastguard Worker server_root = CUPS_SERVERROOT;
1644*5e7646d2SAndroid Build Coastguard Worker
1645*5e7646d2SAndroid Build Coastguard Worker snprintf(filename, sizeof(filename), "%s/cupsd.conf", server_root);
1646*5e7646d2SAndroid Build Coastguard Worker
1647*5e7646d2SAndroid Build Coastguard Worker /*
1648*5e7646d2SAndroid Build Coastguard Worker * Figure out the size...
1649*5e7646d2SAndroid Build Coastguard Worker */
1650*5e7646d2SAndroid Build Coastguard Worker
1651*5e7646d2SAndroid Build Coastguard Worker if (stat(filename, &info))
1652*5e7646d2SAndroid Build Coastguard Worker {
1653*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1654*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE",
1655*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to access cupsd.conf file")));
1656*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", strerror(errno));
1657*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1658*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1659*5e7646d2SAndroid Build Coastguard Worker
1660*5e7646d2SAndroid Build Coastguard Worker perror(filename);
1661*5e7646d2SAndroid Build Coastguard Worker return;
1662*5e7646d2SAndroid Build Coastguard Worker }
1663*5e7646d2SAndroid Build Coastguard Worker
1664*5e7646d2SAndroid Build Coastguard Worker if (info.st_size > (1024 * 1024))
1665*5e7646d2SAndroid Build Coastguard Worker {
1666*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1667*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE",
1668*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to access cupsd.conf file")));
1669*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR",
1670*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to edit cupsd.conf files larger than "
1671*5e7646d2SAndroid Build Coastguard Worker "1MB")));
1672*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1673*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1674*5e7646d2SAndroid Build Coastguard Worker
1675*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "ERROR: \"%s\" too large (%ld) to edit!\n", filename,
1676*5e7646d2SAndroid Build Coastguard Worker (long)info.st_size);
1677*5e7646d2SAndroid Build Coastguard Worker return;
1678*5e7646d2SAndroid Build Coastguard Worker }
1679*5e7646d2SAndroid Build Coastguard Worker
1680*5e7646d2SAndroid Build Coastguard Worker /*
1681*5e7646d2SAndroid Build Coastguard Worker * Open the cupsd.conf file...
1682*5e7646d2SAndroid Build Coastguard Worker */
1683*5e7646d2SAndroid Build Coastguard Worker
1684*5e7646d2SAndroid Build Coastguard Worker if ((cupsd = cupsFileOpen(filename, "r")) == NULL)
1685*5e7646d2SAndroid Build Coastguard Worker {
1686*5e7646d2SAndroid Build Coastguard Worker /*
1687*5e7646d2SAndroid Build Coastguard Worker * Unable to open - log an error...
1688*5e7646d2SAndroid Build Coastguard Worker */
1689*5e7646d2SAndroid Build Coastguard Worker
1690*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1691*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE",
1692*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to access cupsd.conf file")));
1693*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", strerror(errno));
1694*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1695*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1696*5e7646d2SAndroid Build Coastguard Worker
1697*5e7646d2SAndroid Build Coastguard Worker perror(filename);
1698*5e7646d2SAndroid Build Coastguard Worker return;
1699*5e7646d2SAndroid Build Coastguard Worker }
1700*5e7646d2SAndroid Build Coastguard Worker
1701*5e7646d2SAndroid Build Coastguard Worker /*
1702*5e7646d2SAndroid Build Coastguard Worker * Allocate memory and load the file into a string buffer...
1703*5e7646d2SAndroid Build Coastguard Worker */
1704*5e7646d2SAndroid Build Coastguard Worker
1705*5e7646d2SAndroid Build Coastguard Worker if ((buffer = calloc(1, (size_t)info.st_size + 1)) != NULL)
1706*5e7646d2SAndroid Build Coastguard Worker {
1707*5e7646d2SAndroid Build Coastguard Worker cupsFileRead(cupsd, buffer, (size_t)info.st_size);
1708*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CUPSDCONF", buffer);
1709*5e7646d2SAndroid Build Coastguard Worker free(buffer);
1710*5e7646d2SAndroid Build Coastguard Worker }
1711*5e7646d2SAndroid Build Coastguard Worker
1712*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(cupsd);
1713*5e7646d2SAndroid Build Coastguard Worker
1714*5e7646d2SAndroid Build Coastguard Worker /*
1715*5e7646d2SAndroid Build Coastguard Worker * Then get the default cupsd.conf file and put that into a string as
1716*5e7646d2SAndroid Build Coastguard Worker * well...
1717*5e7646d2SAndroid Build Coastguard Worker */
1718*5e7646d2SAndroid Build Coastguard Worker
1719*5e7646d2SAndroid Build Coastguard Worker strlcat(filename, ".default", sizeof(filename));
1720*5e7646d2SAndroid Build Coastguard Worker
1721*5e7646d2SAndroid Build Coastguard Worker if (!stat(filename, &info) && info.st_size < (1024 * 1024) &&
1722*5e7646d2SAndroid Build Coastguard Worker (cupsd = cupsFileOpen(filename, "r")) != NULL)
1723*5e7646d2SAndroid Build Coastguard Worker {
1724*5e7646d2SAndroid Build Coastguard Worker if ((buffer = calloc(1, 2 * (size_t)info.st_size + 1)) != NULL)
1725*5e7646d2SAndroid Build Coastguard Worker {
1726*5e7646d2SAndroid Build Coastguard Worker bufend = buffer + 2 * info.st_size - 1;
1727*5e7646d2SAndroid Build Coastguard Worker
1728*5e7646d2SAndroid Build Coastguard Worker for (bufptr = buffer;
1729*5e7646d2SAndroid Build Coastguard Worker bufptr < bufend && (ch = cupsFileGetChar(cupsd)) != EOF;)
1730*5e7646d2SAndroid Build Coastguard Worker {
1731*5e7646d2SAndroid Build Coastguard Worker if (ch == '\\' || ch == '\"')
1732*5e7646d2SAndroid Build Coastguard Worker {
1733*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
1734*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (char)ch;
1735*5e7646d2SAndroid Build Coastguard Worker }
1736*5e7646d2SAndroid Build Coastguard Worker else if (ch == '\n')
1737*5e7646d2SAndroid Build Coastguard Worker {
1738*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
1739*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 'n';
1740*5e7646d2SAndroid Build Coastguard Worker }
1741*5e7646d2SAndroid Build Coastguard Worker else if (ch == '\t')
1742*5e7646d2SAndroid Build Coastguard Worker {
1743*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
1744*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = 't';
1745*5e7646d2SAndroid Build Coastguard Worker }
1746*5e7646d2SAndroid Build Coastguard Worker else if (ch >= ' ')
1747*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = (char)ch;
1748*5e7646d2SAndroid Build Coastguard Worker }
1749*5e7646d2SAndroid Build Coastguard Worker
1750*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
1751*5e7646d2SAndroid Build Coastguard Worker
1752*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CUPSDCONF_DEFAULT", buffer);
1753*5e7646d2SAndroid Build Coastguard Worker free(buffer);
1754*5e7646d2SAndroid Build Coastguard Worker }
1755*5e7646d2SAndroid Build Coastguard Worker
1756*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(cupsd);
1757*5e7646d2SAndroid Build Coastguard Worker }
1758*5e7646d2SAndroid Build Coastguard Worker
1759*5e7646d2SAndroid Build Coastguard Worker /*
1760*5e7646d2SAndroid Build Coastguard Worker * Show the current config file...
1761*5e7646d2SAndroid Build Coastguard Worker */
1762*5e7646d2SAndroid Build Coastguard Worker
1763*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Edit Configuration File")));
1764*5e7646d2SAndroid Build Coastguard Worker
1765*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("edit-config.tmpl");
1766*5e7646d2SAndroid Build Coastguard Worker
1767*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1768*5e7646d2SAndroid Build Coastguard Worker }
1769*5e7646d2SAndroid Build Coastguard Worker }
1770*5e7646d2SAndroid Build Coastguard Worker
1771*5e7646d2SAndroid Build Coastguard Worker
1772*5e7646d2SAndroid Build Coastguard Worker /*
1773*5e7646d2SAndroid Build Coastguard Worker * 'do_delete_class()' - Delete a class.
1774*5e7646d2SAndroid Build Coastguard Worker */
1775*5e7646d2SAndroid Build Coastguard Worker
1776*5e7646d2SAndroid Build Coastguard Worker static void
do_delete_class(http_t * http)1777*5e7646d2SAndroid Build Coastguard Worker do_delete_class(http_t *http) /* I - HTTP connection */
1778*5e7646d2SAndroid Build Coastguard Worker {
1779*5e7646d2SAndroid Build Coastguard Worker ipp_t *request; /* IPP request */
1780*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI]; /* Job URI */
1781*5e7646d2SAndroid Build Coastguard Worker const char *pclass; /* Printer class name */
1782*5e7646d2SAndroid Build Coastguard Worker
1783*5e7646d2SAndroid Build Coastguard Worker
1784*5e7646d2SAndroid Build Coastguard Worker /*
1785*5e7646d2SAndroid Build Coastguard Worker * Get form variables...
1786*5e7646d2SAndroid Build Coastguard Worker */
1787*5e7646d2SAndroid Build Coastguard Worker
1788*5e7646d2SAndroid Build Coastguard Worker if (cgiGetVariable("CONFIRM") == NULL)
1789*5e7646d2SAndroid Build Coastguard Worker {
1790*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Delete Class")));
1791*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("class-confirm.tmpl");
1792*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1793*5e7646d2SAndroid Build Coastguard Worker return;
1794*5e7646d2SAndroid Build Coastguard Worker }
1795*5e7646d2SAndroid Build Coastguard Worker
1796*5e7646d2SAndroid Build Coastguard Worker if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL)
1797*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
1798*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/classes/%s", pclass);
1799*5e7646d2SAndroid Build Coastguard Worker else
1800*5e7646d2SAndroid Build Coastguard Worker {
1801*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Delete Class")));
1802*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
1803*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1804*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1805*5e7646d2SAndroid Build Coastguard Worker return;
1806*5e7646d2SAndroid Build Coastguard Worker }
1807*5e7646d2SAndroid Build Coastguard Worker
1808*5e7646d2SAndroid Build Coastguard Worker /*
1809*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_DELETE_CLASS request, which requires the following
1810*5e7646d2SAndroid Build Coastguard Worker * attributes:
1811*5e7646d2SAndroid Build Coastguard Worker *
1812*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
1813*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
1814*5e7646d2SAndroid Build Coastguard Worker * printer-uri
1815*5e7646d2SAndroid Build Coastguard Worker */
1816*5e7646d2SAndroid Build Coastguard Worker
1817*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_DELETE_CLASS);
1818*5e7646d2SAndroid Build Coastguard Worker
1819*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1820*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
1821*5e7646d2SAndroid Build Coastguard Worker
1822*5e7646d2SAndroid Build Coastguard Worker /*
1823*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
1824*5e7646d2SAndroid Build Coastguard Worker */
1825*5e7646d2SAndroid Build Coastguard Worker
1826*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/admin/"));
1827*5e7646d2SAndroid Build Coastguard Worker
1828*5e7646d2SAndroid Build Coastguard Worker /*
1829*5e7646d2SAndroid Build Coastguard Worker * Show the results...
1830*5e7646d2SAndroid Build Coastguard Worker */
1831*5e7646d2SAndroid Build Coastguard Worker
1832*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
1833*5e7646d2SAndroid Build Coastguard Worker {
1834*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
1835*5e7646d2SAndroid Build Coastguard Worker exit(0);
1836*5e7646d2SAndroid Build Coastguard Worker }
1837*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() <= IPP_OK_CONFLICT)
1838*5e7646d2SAndroid Build Coastguard Worker {
1839*5e7646d2SAndroid Build Coastguard Worker /*
1840*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the classes page...
1841*5e7646d2SAndroid Build Coastguard Worker */
1842*5e7646d2SAndroid Build Coastguard Worker
1843*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/classes");
1844*5e7646d2SAndroid Build Coastguard Worker }
1845*5e7646d2SAndroid Build Coastguard Worker
1846*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Delete Class")));
1847*5e7646d2SAndroid Build Coastguard Worker
1848*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() > IPP_OK_CONFLICT)
1849*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to delete class"));
1850*5e7646d2SAndroid Build Coastguard Worker else
1851*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("class-deleted.tmpl");
1852*5e7646d2SAndroid Build Coastguard Worker
1853*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1854*5e7646d2SAndroid Build Coastguard Worker }
1855*5e7646d2SAndroid Build Coastguard Worker
1856*5e7646d2SAndroid Build Coastguard Worker
1857*5e7646d2SAndroid Build Coastguard Worker /*
1858*5e7646d2SAndroid Build Coastguard Worker * 'do_delete_printer()' - Delete a printer.
1859*5e7646d2SAndroid Build Coastguard Worker */
1860*5e7646d2SAndroid Build Coastguard Worker
1861*5e7646d2SAndroid Build Coastguard Worker static void
do_delete_printer(http_t * http)1862*5e7646d2SAndroid Build Coastguard Worker do_delete_printer(http_t *http) /* I - HTTP connection */
1863*5e7646d2SAndroid Build Coastguard Worker {
1864*5e7646d2SAndroid Build Coastguard Worker ipp_t *request; /* IPP request */
1865*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI]; /* Job URI */
1866*5e7646d2SAndroid Build Coastguard Worker const char *printer; /* Printer printer name */
1867*5e7646d2SAndroid Build Coastguard Worker
1868*5e7646d2SAndroid Build Coastguard Worker
1869*5e7646d2SAndroid Build Coastguard Worker /*
1870*5e7646d2SAndroid Build Coastguard Worker * Get form variables...
1871*5e7646d2SAndroid Build Coastguard Worker */
1872*5e7646d2SAndroid Build Coastguard Worker
1873*5e7646d2SAndroid Build Coastguard Worker if (cgiGetVariable("CONFIRM") == NULL)
1874*5e7646d2SAndroid Build Coastguard Worker {
1875*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Delete Printer")));
1876*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("printer-confirm.tmpl");
1877*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1878*5e7646d2SAndroid Build Coastguard Worker return;
1879*5e7646d2SAndroid Build Coastguard Worker }
1880*5e7646d2SAndroid Build Coastguard Worker
1881*5e7646d2SAndroid Build Coastguard Worker if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
1882*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
1883*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/printers/%s", printer);
1884*5e7646d2SAndroid Build Coastguard Worker else
1885*5e7646d2SAndroid Build Coastguard Worker {
1886*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Delete Printer")));
1887*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
1888*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
1889*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1890*5e7646d2SAndroid Build Coastguard Worker return;
1891*5e7646d2SAndroid Build Coastguard Worker }
1892*5e7646d2SAndroid Build Coastguard Worker
1893*5e7646d2SAndroid Build Coastguard Worker /*
1894*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_DELETE_PRINTER request, which requires the following
1895*5e7646d2SAndroid Build Coastguard Worker * attributes:
1896*5e7646d2SAndroid Build Coastguard Worker *
1897*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
1898*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
1899*5e7646d2SAndroid Build Coastguard Worker * printer-uri
1900*5e7646d2SAndroid Build Coastguard Worker */
1901*5e7646d2SAndroid Build Coastguard Worker
1902*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_DELETE_PRINTER);
1903*5e7646d2SAndroid Build Coastguard Worker
1904*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
1905*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
1906*5e7646d2SAndroid Build Coastguard Worker
1907*5e7646d2SAndroid Build Coastguard Worker /*
1908*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
1909*5e7646d2SAndroid Build Coastguard Worker */
1910*5e7646d2SAndroid Build Coastguard Worker
1911*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/admin/"));
1912*5e7646d2SAndroid Build Coastguard Worker
1913*5e7646d2SAndroid Build Coastguard Worker /*
1914*5e7646d2SAndroid Build Coastguard Worker * Show the results...
1915*5e7646d2SAndroid Build Coastguard Worker */
1916*5e7646d2SAndroid Build Coastguard Worker
1917*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
1918*5e7646d2SAndroid Build Coastguard Worker {
1919*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
1920*5e7646d2SAndroid Build Coastguard Worker exit(0);
1921*5e7646d2SAndroid Build Coastguard Worker }
1922*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() <= IPP_OK_CONFLICT)
1923*5e7646d2SAndroid Build Coastguard Worker {
1924*5e7646d2SAndroid Build Coastguard Worker /*
1925*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the printers page...
1926*5e7646d2SAndroid Build Coastguard Worker */
1927*5e7646d2SAndroid Build Coastguard Worker
1928*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/printers");
1929*5e7646d2SAndroid Build Coastguard Worker }
1930*5e7646d2SAndroid Build Coastguard Worker
1931*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Delete Printer")));
1932*5e7646d2SAndroid Build Coastguard Worker
1933*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() > IPP_OK_CONFLICT)
1934*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to delete printer"));
1935*5e7646d2SAndroid Build Coastguard Worker else
1936*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("printer-deleted.tmpl");
1937*5e7646d2SAndroid Build Coastguard Worker
1938*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
1939*5e7646d2SAndroid Build Coastguard Worker }
1940*5e7646d2SAndroid Build Coastguard Worker
1941*5e7646d2SAndroid Build Coastguard Worker
1942*5e7646d2SAndroid Build Coastguard Worker /*
1943*5e7646d2SAndroid Build Coastguard Worker * 'do_list_printers()' - List available printers.
1944*5e7646d2SAndroid Build Coastguard Worker */
1945*5e7646d2SAndroid Build Coastguard Worker
1946*5e7646d2SAndroid Build Coastguard Worker static void
do_list_printers(http_t * http)1947*5e7646d2SAndroid Build Coastguard Worker do_list_printers(http_t *http) /* I - HTTP connection */
1948*5e7646d2SAndroid Build Coastguard Worker {
1949*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* IPP request */
1950*5e7646d2SAndroid Build Coastguard Worker *response; /* IPP response */
1951*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* IPP attribute */
1952*5e7646d2SAndroid Build Coastguard Worker
1953*5e7646d2SAndroid Build Coastguard Worker
1954*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("List Available Printers")));
1955*5e7646d2SAndroid Build Coastguard Worker fflush(stdout);
1956*5e7646d2SAndroid Build Coastguard Worker
1957*5e7646d2SAndroid Build Coastguard Worker /*
1958*5e7646d2SAndroid Build Coastguard Worker * Get the list of printers and their devices...
1959*5e7646d2SAndroid Build Coastguard Worker */
1960*5e7646d2SAndroid Build Coastguard Worker
1961*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_GET_PRINTERS);
1962*5e7646d2SAndroid Build Coastguard Worker
1963*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
1964*5e7646d2SAndroid Build Coastguard Worker "requested-attributes", NULL, "device-uri");
1965*5e7646d2SAndroid Build Coastguard Worker
1966*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type",
1967*5e7646d2SAndroid Build Coastguard Worker CUPS_PRINTER_LOCAL);
1968*5e7646d2SAndroid Build Coastguard Worker ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask",
1969*5e7646d2SAndroid Build Coastguard Worker CUPS_PRINTER_LOCAL);
1970*5e7646d2SAndroid Build Coastguard Worker
1971*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/")) != NULL)
1972*5e7646d2SAndroid Build Coastguard Worker {
1973*5e7646d2SAndroid Build Coastguard Worker /*
1974*5e7646d2SAndroid Build Coastguard Worker * Got the printer list, now load the devices...
1975*5e7646d2SAndroid Build Coastguard Worker */
1976*5e7646d2SAndroid Build Coastguard Worker
1977*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
1978*5e7646d2SAndroid Build Coastguard Worker cups_array_t *printer_devices; /* Printer devices for local printers */
1979*5e7646d2SAndroid Build Coastguard Worker char *printer_device; /* Current printer device */
1980*5e7646d2SAndroid Build Coastguard Worker
1981*5e7646d2SAndroid Build Coastguard Worker
1982*5e7646d2SAndroid Build Coastguard Worker /*
1983*5e7646d2SAndroid Build Coastguard Worker * Allocate an array and copy the device strings...
1984*5e7646d2SAndroid Build Coastguard Worker */
1985*5e7646d2SAndroid Build Coastguard Worker
1986*5e7646d2SAndroid Build Coastguard Worker printer_devices = cupsArrayNew((cups_array_func_t)strcmp, NULL);
1987*5e7646d2SAndroid Build Coastguard Worker
1988*5e7646d2SAndroid Build Coastguard Worker for (attr = ippFindAttribute(response, "device-uri", IPP_TAG_URI);
1989*5e7646d2SAndroid Build Coastguard Worker attr;
1990*5e7646d2SAndroid Build Coastguard Worker attr = ippFindNextAttribute(response, "device-uri", IPP_TAG_URI))
1991*5e7646d2SAndroid Build Coastguard Worker {
1992*5e7646d2SAndroid Build Coastguard Worker cupsArrayAdd(printer_devices, strdup(attr->values[0].string.text));
1993*5e7646d2SAndroid Build Coastguard Worker }
1994*5e7646d2SAndroid Build Coastguard Worker
1995*5e7646d2SAndroid Build Coastguard Worker /*
1996*5e7646d2SAndroid Build Coastguard Worker * Free the printer list and get the device list...
1997*5e7646d2SAndroid Build Coastguard Worker */
1998*5e7646d2SAndroid Build Coastguard Worker
1999*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
2000*5e7646d2SAndroid Build Coastguard Worker
2001*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_GET_DEVICES);
2002*5e7646d2SAndroid Build Coastguard Worker
2003*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/")) != NULL)
2004*5e7646d2SAndroid Build Coastguard Worker {
2005*5e7646d2SAndroid Build Coastguard Worker /*
2006*5e7646d2SAndroid Build Coastguard Worker * Got the device list, let's parse it...
2007*5e7646d2SAndroid Build Coastguard Worker */
2008*5e7646d2SAndroid Build Coastguard Worker
2009*5e7646d2SAndroid Build Coastguard Worker const char *device_uri, /* device-uri attribute value */
2010*5e7646d2SAndroid Build Coastguard Worker *device_make_and_model, /* device-make-and-model value */
2011*5e7646d2SAndroid Build Coastguard Worker *device_info; /* device-info value */
2012*5e7646d2SAndroid Build Coastguard Worker
2013*5e7646d2SAndroid Build Coastguard Worker
2014*5e7646d2SAndroid Build Coastguard Worker for (i = 0, attr = response->attrs; attr; attr = attr->next)
2015*5e7646d2SAndroid Build Coastguard Worker {
2016*5e7646d2SAndroid Build Coastguard Worker /*
2017*5e7646d2SAndroid Build Coastguard Worker * Skip leading attributes until we hit a device...
2018*5e7646d2SAndroid Build Coastguard Worker */
2019*5e7646d2SAndroid Build Coastguard Worker
2020*5e7646d2SAndroid Build Coastguard Worker while (attr && attr->group_tag != IPP_TAG_PRINTER)
2021*5e7646d2SAndroid Build Coastguard Worker attr = attr->next;
2022*5e7646d2SAndroid Build Coastguard Worker
2023*5e7646d2SAndroid Build Coastguard Worker if (!attr)
2024*5e7646d2SAndroid Build Coastguard Worker break;
2025*5e7646d2SAndroid Build Coastguard Worker
2026*5e7646d2SAndroid Build Coastguard Worker /*
2027*5e7646d2SAndroid Build Coastguard Worker * Pull the needed attributes from this device...
2028*5e7646d2SAndroid Build Coastguard Worker */
2029*5e7646d2SAndroid Build Coastguard Worker
2030*5e7646d2SAndroid Build Coastguard Worker device_info = NULL;
2031*5e7646d2SAndroid Build Coastguard Worker device_make_and_model = NULL;
2032*5e7646d2SAndroid Build Coastguard Worker device_uri = NULL;
2033*5e7646d2SAndroid Build Coastguard Worker
2034*5e7646d2SAndroid Build Coastguard Worker while (attr && attr->group_tag == IPP_TAG_PRINTER)
2035*5e7646d2SAndroid Build Coastguard Worker {
2036*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(attr->name, "device-info") &&
2037*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_TEXT)
2038*5e7646d2SAndroid Build Coastguard Worker device_info = attr->values[0].string.text;
2039*5e7646d2SAndroid Build Coastguard Worker
2040*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(attr->name, "device-make-and-model") &&
2041*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_TEXT)
2042*5e7646d2SAndroid Build Coastguard Worker device_make_and_model = attr->values[0].string.text;
2043*5e7646d2SAndroid Build Coastguard Worker
2044*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(attr->name, "device-uri") &&
2045*5e7646d2SAndroid Build Coastguard Worker attr->value_tag == IPP_TAG_URI)
2046*5e7646d2SAndroid Build Coastguard Worker device_uri = attr->values[0].string.text;
2047*5e7646d2SAndroid Build Coastguard Worker
2048*5e7646d2SAndroid Build Coastguard Worker attr = attr->next;
2049*5e7646d2SAndroid Build Coastguard Worker }
2050*5e7646d2SAndroid Build Coastguard Worker
2051*5e7646d2SAndroid Build Coastguard Worker /*
2052*5e7646d2SAndroid Build Coastguard Worker * See if we have everything needed...
2053*5e7646d2SAndroid Build Coastguard Worker */
2054*5e7646d2SAndroid Build Coastguard Worker
2055*5e7646d2SAndroid Build Coastguard Worker if (device_info && device_make_and_model && device_uri &&
2056*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(device_make_and_model, "unknown") &&
2057*5e7646d2SAndroid Build Coastguard Worker strchr(device_uri, ':'))
2058*5e7646d2SAndroid Build Coastguard Worker {
2059*5e7646d2SAndroid Build Coastguard Worker /*
2060*5e7646d2SAndroid Build Coastguard Worker * Yes, now see if there is already a printer for this
2061*5e7646d2SAndroid Build Coastguard Worker * device...
2062*5e7646d2SAndroid Build Coastguard Worker */
2063*5e7646d2SAndroid Build Coastguard Worker
2064*5e7646d2SAndroid Build Coastguard Worker if (!cupsArrayFind(printer_devices, (void *)device_uri))
2065*5e7646d2SAndroid Build Coastguard Worker {
2066*5e7646d2SAndroid Build Coastguard Worker /*
2067*5e7646d2SAndroid Build Coastguard Worker * Not found, so it must be a new printer...
2068*5e7646d2SAndroid Build Coastguard Worker */
2069*5e7646d2SAndroid Build Coastguard Worker
2070*5e7646d2SAndroid Build Coastguard Worker char option[1024], /* Form variables for this device */
2071*5e7646d2SAndroid Build Coastguard Worker *option_ptr; /* Pointer into string */
2072*5e7646d2SAndroid Build Coastguard Worker const char *ptr; /* Pointer into device string */
2073*5e7646d2SAndroid Build Coastguard Worker
2074*5e7646d2SAndroid Build Coastguard Worker
2075*5e7646d2SAndroid Build Coastguard Worker /*
2076*5e7646d2SAndroid Build Coastguard Worker * Format the printer name variable for this device...
2077*5e7646d2SAndroid Build Coastguard Worker *
2078*5e7646d2SAndroid Build Coastguard Worker * We use the device-info string first, then device-uri,
2079*5e7646d2SAndroid Build Coastguard Worker * and finally device-make-and-model to come up with a
2080*5e7646d2SAndroid Build Coastguard Worker * suitable name.
2081*5e7646d2SAndroid Build Coastguard Worker */
2082*5e7646d2SAndroid Build Coastguard Worker
2083*5e7646d2SAndroid Build Coastguard Worker if (_cups_strncasecmp(device_info, "unknown", 7))
2084*5e7646d2SAndroid Build Coastguard Worker ptr = device_info;
2085*5e7646d2SAndroid Build Coastguard Worker else if ((ptr = strstr(device_uri, "://")) != NULL)
2086*5e7646d2SAndroid Build Coastguard Worker ptr += 3;
2087*5e7646d2SAndroid Build Coastguard Worker else
2088*5e7646d2SAndroid Build Coastguard Worker ptr = device_make_and_model;
2089*5e7646d2SAndroid Build Coastguard Worker
2090*5e7646d2SAndroid Build Coastguard Worker for (option_ptr = option;
2091*5e7646d2SAndroid Build Coastguard Worker option_ptr < (option + sizeof(option) - 1) && *ptr;
2092*5e7646d2SAndroid Build Coastguard Worker ptr ++)
2093*5e7646d2SAndroid Build Coastguard Worker if (isalnum(*ptr & 255) || *ptr == '_' || *ptr == '-' ||
2094*5e7646d2SAndroid Build Coastguard Worker *ptr == '.')
2095*5e7646d2SAndroid Build Coastguard Worker *option_ptr++ = *ptr;
2096*5e7646d2SAndroid Build Coastguard Worker else if ((*ptr == ' ' || *ptr == '/') && option_ptr > option &&
2097*5e7646d2SAndroid Build Coastguard Worker option_ptr[-1] != '_')
2098*5e7646d2SAndroid Build Coastguard Worker *option_ptr++ = '_';
2099*5e7646d2SAndroid Build Coastguard Worker else if (*ptr == '?' || *ptr == '(')
2100*5e7646d2SAndroid Build Coastguard Worker break;
2101*5e7646d2SAndroid Build Coastguard Worker
2102*5e7646d2SAndroid Build Coastguard Worker *option_ptr = '\0';
2103*5e7646d2SAndroid Build Coastguard Worker
2104*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("TEMPLATE_NAME", i, option);
2105*5e7646d2SAndroid Build Coastguard Worker
2106*5e7646d2SAndroid Build Coastguard Worker /*
2107*5e7646d2SAndroid Build Coastguard Worker * Finally, set the form variables for this printer...
2108*5e7646d2SAndroid Build Coastguard Worker */
2109*5e7646d2SAndroid Build Coastguard Worker
2110*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_info", i, device_info);
2111*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_make_and_model", i, device_make_and_model);
2112*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("device_uri", i, device_uri);
2113*5e7646d2SAndroid Build Coastguard Worker i ++;
2114*5e7646d2SAndroid Build Coastguard Worker }
2115*5e7646d2SAndroid Build Coastguard Worker }
2116*5e7646d2SAndroid Build Coastguard Worker
2117*5e7646d2SAndroid Build Coastguard Worker if (!attr)
2118*5e7646d2SAndroid Build Coastguard Worker break;
2119*5e7646d2SAndroid Build Coastguard Worker }
2120*5e7646d2SAndroid Build Coastguard Worker
2121*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
2122*5e7646d2SAndroid Build Coastguard Worker
2123*5e7646d2SAndroid Build Coastguard Worker /*
2124*5e7646d2SAndroid Build Coastguard Worker * Free the device list...
2125*5e7646d2SAndroid Build Coastguard Worker */
2126*5e7646d2SAndroid Build Coastguard Worker
2127*5e7646d2SAndroid Build Coastguard Worker for (printer_device = (char *)cupsArrayFirst(printer_devices);
2128*5e7646d2SAndroid Build Coastguard Worker printer_device;
2129*5e7646d2SAndroid Build Coastguard Worker printer_device = (char *)cupsArrayNext(printer_devices))
2130*5e7646d2SAndroid Build Coastguard Worker free(printer_device);
2131*5e7646d2SAndroid Build Coastguard Worker
2132*5e7646d2SAndroid Build Coastguard Worker cupsArrayDelete(printer_devices);
2133*5e7646d2SAndroid Build Coastguard Worker }
2134*5e7646d2SAndroid Build Coastguard Worker }
2135*5e7646d2SAndroid Build Coastguard Worker
2136*5e7646d2SAndroid Build Coastguard Worker /*
2137*5e7646d2SAndroid Build Coastguard Worker * Finally, show the printer list...
2138*5e7646d2SAndroid Build Coastguard Worker */
2139*5e7646d2SAndroid Build Coastguard Worker
2140*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("list-available-printers.tmpl");
2141*5e7646d2SAndroid Build Coastguard Worker
2142*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2143*5e7646d2SAndroid Build Coastguard Worker }
2144*5e7646d2SAndroid Build Coastguard Worker
2145*5e7646d2SAndroid Build Coastguard Worker
2146*5e7646d2SAndroid Build Coastguard Worker /*
2147*5e7646d2SAndroid Build Coastguard Worker * 'do_menu()' - Show the main menu.
2148*5e7646d2SAndroid Build Coastguard Worker */
2149*5e7646d2SAndroid Build Coastguard Worker
2150*5e7646d2SAndroid Build Coastguard Worker static void
do_menu(http_t * http)2151*5e7646d2SAndroid Build Coastguard Worker do_menu(http_t *http) /* I - HTTP connection */
2152*5e7646d2SAndroid Build Coastguard Worker {
2153*5e7646d2SAndroid Build Coastguard Worker int num_settings; /* Number of server settings */
2154*5e7646d2SAndroid Build Coastguard Worker cups_option_t *settings; /* Server settings */
2155*5e7646d2SAndroid Build Coastguard Worker const char *val; /* Setting value */
2156*5e7646d2SAndroid Build Coastguard Worker
2157*5e7646d2SAndroid Build Coastguard Worker
2158*5e7646d2SAndroid Build Coastguard Worker /*
2159*5e7646d2SAndroid Build Coastguard Worker * Get the current server settings...
2160*5e7646d2SAndroid Build Coastguard Worker */
2161*5e7646d2SAndroid Build Coastguard Worker
2162*5e7646d2SAndroid Build Coastguard Worker if (!cupsAdminGetServerSettings(http, &num_settings, &settings))
2163*5e7646d2SAndroid Build Coastguard Worker {
2164*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("SETTINGS_MESSAGE",
2165*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Unable to open cupsd.conf file:")));
2166*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("SETTINGS_ERROR", cupsLastErrorString());
2167*5e7646d2SAndroid Build Coastguard Worker }
2168*5e7646d2SAndroid Build Coastguard Worker
2169*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings,
2170*5e7646d2SAndroid Build Coastguard Worker settings)) != NULL && atoi(val))
2171*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEBUG_LOGGING", "CHECKED");
2172*5e7646d2SAndroid Build Coastguard Worker
2173*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings,
2174*5e7646d2SAndroid Build Coastguard Worker settings)) != NULL && atoi(val))
2175*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("REMOTE_ADMIN", "CHECKED");
2176*5e7646d2SAndroid Build Coastguard Worker
2177*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings,
2178*5e7646d2SAndroid Build Coastguard Worker settings)) != NULL && atoi(val))
2179*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("REMOTE_ANY", "CHECKED");
2180*5e7646d2SAndroid Build Coastguard Worker
2181*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings,
2182*5e7646d2SAndroid Build Coastguard Worker settings)) != NULL && atoi(val))
2183*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("SHARE_PRINTERS", "CHECKED");
2184*5e7646d2SAndroid Build Coastguard Worker
2185*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings,
2186*5e7646d2SAndroid Build Coastguard Worker settings)) != NULL && atoi(val))
2187*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("USER_CANCEL_ANY", "CHECKED");
2188*5e7646d2SAndroid Build Coastguard Worker
2189*5e7646d2SAndroid Build Coastguard Worker #ifdef HAVE_GSSAPI
2190*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("HAVE_GSSAPI", "1");
2191*5e7646d2SAndroid Build Coastguard Worker
2192*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption("DefaultAuthType", num_settings,
2193*5e7646d2SAndroid Build Coastguard Worker settings)) != NULL && !_cups_strcasecmp(val, "Negotiate"))
2194*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KERBEROS", "CHECKED");
2195*5e7646d2SAndroid Build Coastguard Worker else
2196*5e7646d2SAndroid Build Coastguard Worker #endif /* HAVE_GSSAPI */
2197*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KERBEROS", "");
2198*5e7646d2SAndroid Build Coastguard Worker
2199*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption("BrowseWebIF", num_settings,
2200*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
2201*5e7646d2SAndroid Build Coastguard Worker val = "No";
2202*5e7646d2SAndroid Build Coastguard Worker
2203*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(val, "yes") || !_cups_strcasecmp(val, "on") ||
2204*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(val, "true"))
2205*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("BROWSE_WEB_IF", "CHECKED");
2206*5e7646d2SAndroid Build Coastguard Worker
2207*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption("PreserveJobHistory", num_settings,
2208*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
2209*5e7646d2SAndroid Build Coastguard Worker val = "Yes";
2210*5e7646d2SAndroid Build Coastguard Worker
2211*5e7646d2SAndroid Build Coastguard Worker if (val &&
2212*5e7646d2SAndroid Build Coastguard Worker (!_cups_strcasecmp(val, "0") || !_cups_strcasecmp(val, "no") ||
2213*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(val, "off") || !_cups_strcasecmp(val, "false") ||
2214*5e7646d2SAndroid Build Coastguard Worker !_cups_strcasecmp(val, "disabled")))
2215*5e7646d2SAndroid Build Coastguard Worker {
2216*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRESERVE_JOB_HISTORY", "0");
2217*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRESERVE_JOB_FILES", "0");
2218*5e7646d2SAndroid Build Coastguard Worker }
2219*5e7646d2SAndroid Build Coastguard Worker else
2220*5e7646d2SAndroid Build Coastguard Worker {
2221*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRESERVE_JOBS", "CHECKED");
2222*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRESERVE_JOB_HISTORY", val);
2223*5e7646d2SAndroid Build Coastguard Worker
2224*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption("PreserveJobFiles", num_settings,
2225*5e7646d2SAndroid Build Coastguard Worker settings)) == NULL)
2226*5e7646d2SAndroid Build Coastguard Worker val = "1d";
2227*5e7646d2SAndroid Build Coastguard Worker
2228*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("PRESERVE_JOB_FILES", val);
2229*5e7646d2SAndroid Build Coastguard Worker
2230*5e7646d2SAndroid Build Coastguard Worker }
2231*5e7646d2SAndroid Build Coastguard Worker
2232*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption("MaxClients", num_settings, settings)) == NULL)
2233*5e7646d2SAndroid Build Coastguard Worker val = "100";
2234*5e7646d2SAndroid Build Coastguard Worker
2235*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MAX_CLIENTS", val);
2236*5e7646d2SAndroid Build Coastguard Worker
2237*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption("MaxJobs", num_settings, settings)) == NULL)
2238*5e7646d2SAndroid Build Coastguard Worker val = "500";
2239*5e7646d2SAndroid Build Coastguard Worker
2240*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MAX_JOBS", val);
2241*5e7646d2SAndroid Build Coastguard Worker
2242*5e7646d2SAndroid Build Coastguard Worker if ((val = cupsGetOption("MaxLogSize", num_settings, settings)) == NULL)
2243*5e7646d2SAndroid Build Coastguard Worker val = "1m";
2244*5e7646d2SAndroid Build Coastguard Worker
2245*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MAX_LOG_SIZE", val);
2246*5e7646d2SAndroid Build Coastguard Worker
2247*5e7646d2SAndroid Build Coastguard Worker cupsFreeOptions(num_settings, settings);
2248*5e7646d2SAndroid Build Coastguard Worker
2249*5e7646d2SAndroid Build Coastguard Worker /*
2250*5e7646d2SAndroid Build Coastguard Worker * Finally, show the main menu template...
2251*5e7646d2SAndroid Build Coastguard Worker */
2252*5e7646d2SAndroid Build Coastguard Worker
2253*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Administration")));
2254*5e7646d2SAndroid Build Coastguard Worker
2255*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("admin.tmpl");
2256*5e7646d2SAndroid Build Coastguard Worker
2257*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2258*5e7646d2SAndroid Build Coastguard Worker }
2259*5e7646d2SAndroid Build Coastguard Worker
2260*5e7646d2SAndroid Build Coastguard Worker
2261*5e7646d2SAndroid Build Coastguard Worker /*
2262*5e7646d2SAndroid Build Coastguard Worker * 'do_set_allowed_users()' - Set the allowed/denied users for a queue.
2263*5e7646d2SAndroid Build Coastguard Worker */
2264*5e7646d2SAndroid Build Coastguard Worker
2265*5e7646d2SAndroid Build Coastguard Worker static void
do_set_allowed_users(http_t * http)2266*5e7646d2SAndroid Build Coastguard Worker do_set_allowed_users(http_t *http) /* I - HTTP connection */
2267*5e7646d2SAndroid Build Coastguard Worker {
2268*5e7646d2SAndroid Build Coastguard Worker int i; /* Looping var */
2269*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* IPP request */
2270*5e7646d2SAndroid Build Coastguard Worker *response; /* IPP response */
2271*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI]; /* Printer URI */
2272*5e7646d2SAndroid Build Coastguard Worker const char *printer, /* Printer name (purge-jobs) */
2273*5e7646d2SAndroid Build Coastguard Worker *is_class, /* Is a class? */
2274*5e7646d2SAndroid Build Coastguard Worker *users, /* List of users or groups */
2275*5e7646d2SAndroid Build Coastguard Worker *type; /* Allow/deny type */
2276*5e7646d2SAndroid Build Coastguard Worker int num_users; /* Number of users */
2277*5e7646d2SAndroid Build Coastguard Worker char *ptr, /* Pointer into users string */
2278*5e7646d2SAndroid Build Coastguard Worker *end, /* Pointer to end of users string */
2279*5e7646d2SAndroid Build Coastguard Worker quote; /* Quote character */
2280*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* Attribute */
2281*5e7646d2SAndroid Build Coastguard Worker static const char * const attrs[] = /* Requested attributes */
2282*5e7646d2SAndroid Build Coastguard Worker {
2283*5e7646d2SAndroid Build Coastguard Worker "requesting-user-name-allowed",
2284*5e7646d2SAndroid Build Coastguard Worker "requesting-user-name-denied"
2285*5e7646d2SAndroid Build Coastguard Worker };
2286*5e7646d2SAndroid Build Coastguard Worker
2287*5e7646d2SAndroid Build Coastguard Worker
2288*5e7646d2SAndroid Build Coastguard Worker is_class = cgiGetVariable("IS_CLASS");
2289*5e7646d2SAndroid Build Coastguard Worker printer = cgiGetVariable("PRINTER_NAME");
2290*5e7646d2SAndroid Build Coastguard Worker
2291*5e7646d2SAndroid Build Coastguard Worker if (!printer)
2292*5e7646d2SAndroid Build Coastguard Worker {
2293*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
2294*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Allowed Users")));
2295*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
2296*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2297*5e7646d2SAndroid Build Coastguard Worker return;
2298*5e7646d2SAndroid Build Coastguard Worker }
2299*5e7646d2SAndroid Build Coastguard Worker
2300*5e7646d2SAndroid Build Coastguard Worker users = cgiGetVariable("users");
2301*5e7646d2SAndroid Build Coastguard Worker type = cgiGetVariable("type");
2302*5e7646d2SAndroid Build Coastguard Worker
2303*5e7646d2SAndroid Build Coastguard Worker if (!users || !type ||
2304*5e7646d2SAndroid Build Coastguard Worker (strcmp(type, "requesting-user-name-allowed") &&
2305*5e7646d2SAndroid Build Coastguard Worker strcmp(type, "requesting-user-name-denied")))
2306*5e7646d2SAndroid Build Coastguard Worker {
2307*5e7646d2SAndroid Build Coastguard Worker /*
2308*5e7646d2SAndroid Build Coastguard Worker * Build a Get-Printer-Attributes request, which requires the following
2309*5e7646d2SAndroid Build Coastguard Worker * attributes:
2310*5e7646d2SAndroid Build Coastguard Worker *
2311*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
2312*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
2313*5e7646d2SAndroid Build Coastguard Worker * printer-uri
2314*5e7646d2SAndroid Build Coastguard Worker * requested-attributes
2315*5e7646d2SAndroid Build Coastguard Worker */
2316*5e7646d2SAndroid Build Coastguard Worker
2317*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
2318*5e7646d2SAndroid Build Coastguard Worker
2319*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
2320*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
2321*5e7646d2SAndroid Build Coastguard Worker printer);
2322*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
2323*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
2324*5e7646d2SAndroid Build Coastguard Worker
2325*5e7646d2SAndroid Build Coastguard Worker ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
2326*5e7646d2SAndroid Build Coastguard Worker "requested-attributes",
2327*5e7646d2SAndroid Build Coastguard Worker (int)(sizeof(attrs) / sizeof(attrs[0])), NULL, attrs);
2328*5e7646d2SAndroid Build Coastguard Worker
2329*5e7646d2SAndroid Build Coastguard Worker /*
2330*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
2331*5e7646d2SAndroid Build Coastguard Worker */
2332*5e7646d2SAndroid Build Coastguard Worker
2333*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/")) != NULL)
2334*5e7646d2SAndroid Build Coastguard Worker {
2335*5e7646d2SAndroid Build Coastguard Worker cgiSetIPPVars(response, NULL, NULL, NULL, 0);
2336*5e7646d2SAndroid Build Coastguard Worker
2337*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
2338*5e7646d2SAndroid Build Coastguard Worker }
2339*5e7646d2SAndroid Build Coastguard Worker
2340*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Allowed Users")));
2341*5e7646d2SAndroid Build Coastguard Worker
2342*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
2343*5e7646d2SAndroid Build Coastguard Worker {
2344*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
2345*5e7646d2SAndroid Build Coastguard Worker exit(0);
2346*5e7646d2SAndroid Build Coastguard Worker }
2347*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() > IPP_OK_CONFLICT)
2348*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to get printer attributes"));
2349*5e7646d2SAndroid Build Coastguard Worker else
2350*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("users.tmpl");
2351*5e7646d2SAndroid Build Coastguard Worker
2352*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2353*5e7646d2SAndroid Build Coastguard Worker }
2354*5e7646d2SAndroid Build Coastguard Worker else
2355*5e7646d2SAndroid Build Coastguard Worker {
2356*5e7646d2SAndroid Build Coastguard Worker /*
2357*5e7646d2SAndroid Build Coastguard Worker * Save the changes...
2358*5e7646d2SAndroid Build Coastguard Worker */
2359*5e7646d2SAndroid Build Coastguard Worker
2360*5e7646d2SAndroid Build Coastguard Worker for (num_users = 0, ptr = (char *)users; *ptr; num_users ++)
2361*5e7646d2SAndroid Build Coastguard Worker {
2362*5e7646d2SAndroid Build Coastguard Worker /*
2363*5e7646d2SAndroid Build Coastguard Worker * Skip whitespace and commas...
2364*5e7646d2SAndroid Build Coastguard Worker */
2365*5e7646d2SAndroid Build Coastguard Worker
2366*5e7646d2SAndroid Build Coastguard Worker while (*ptr == ',' || isspace(*ptr & 255))
2367*5e7646d2SAndroid Build Coastguard Worker ptr ++;
2368*5e7646d2SAndroid Build Coastguard Worker
2369*5e7646d2SAndroid Build Coastguard Worker if (!*ptr)
2370*5e7646d2SAndroid Build Coastguard Worker break;
2371*5e7646d2SAndroid Build Coastguard Worker
2372*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\'' || *ptr == '\"')
2373*5e7646d2SAndroid Build Coastguard Worker {
2374*5e7646d2SAndroid Build Coastguard Worker /*
2375*5e7646d2SAndroid Build Coastguard Worker * Scan quoted name...
2376*5e7646d2SAndroid Build Coastguard Worker */
2377*5e7646d2SAndroid Build Coastguard Worker
2378*5e7646d2SAndroid Build Coastguard Worker quote = *ptr++;
2379*5e7646d2SAndroid Build Coastguard Worker
2380*5e7646d2SAndroid Build Coastguard Worker for (end = ptr; *end; end ++)
2381*5e7646d2SAndroid Build Coastguard Worker if (*end == quote)
2382*5e7646d2SAndroid Build Coastguard Worker break;
2383*5e7646d2SAndroid Build Coastguard Worker }
2384*5e7646d2SAndroid Build Coastguard Worker else
2385*5e7646d2SAndroid Build Coastguard Worker {
2386*5e7646d2SAndroid Build Coastguard Worker /*
2387*5e7646d2SAndroid Build Coastguard Worker * Scan space or comma-delimited name...
2388*5e7646d2SAndroid Build Coastguard Worker */
2389*5e7646d2SAndroid Build Coastguard Worker
2390*5e7646d2SAndroid Build Coastguard Worker for (end = ptr; *end; end ++)
2391*5e7646d2SAndroid Build Coastguard Worker if (isspace(*end & 255) || *end == ',')
2392*5e7646d2SAndroid Build Coastguard Worker break;
2393*5e7646d2SAndroid Build Coastguard Worker }
2394*5e7646d2SAndroid Build Coastguard Worker
2395*5e7646d2SAndroid Build Coastguard Worker /*
2396*5e7646d2SAndroid Build Coastguard Worker * Advance to the next name...
2397*5e7646d2SAndroid Build Coastguard Worker */
2398*5e7646d2SAndroid Build Coastguard Worker
2399*5e7646d2SAndroid Build Coastguard Worker ptr = end;
2400*5e7646d2SAndroid Build Coastguard Worker }
2401*5e7646d2SAndroid Build Coastguard Worker
2402*5e7646d2SAndroid Build Coastguard Worker /*
2403*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS-Add-Printer/Class request, which requires the following
2404*5e7646d2SAndroid Build Coastguard Worker * attributes:
2405*5e7646d2SAndroid Build Coastguard Worker *
2406*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
2407*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
2408*5e7646d2SAndroid Build Coastguard Worker * printer-uri
2409*5e7646d2SAndroid Build Coastguard Worker * requesting-user-name-{allowed,denied}
2410*5e7646d2SAndroid Build Coastguard Worker */
2411*5e7646d2SAndroid Build Coastguard Worker
2412*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER);
2413*5e7646d2SAndroid Build Coastguard Worker
2414*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
2415*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
2416*5e7646d2SAndroid Build Coastguard Worker printer);
2417*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
2418*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
2419*5e7646d2SAndroid Build Coastguard Worker
2420*5e7646d2SAndroid Build Coastguard Worker if (num_users == 0)
2421*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
2422*5e7646d2SAndroid Build Coastguard Worker "requesting-user-name-allowed", NULL, "all");
2423*5e7646d2SAndroid Build Coastguard Worker else
2424*5e7646d2SAndroid Build Coastguard Worker {
2425*5e7646d2SAndroid Build Coastguard Worker attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
2426*5e7646d2SAndroid Build Coastguard Worker type, num_users, NULL, NULL);
2427*5e7646d2SAndroid Build Coastguard Worker
2428*5e7646d2SAndroid Build Coastguard Worker for (i = 0, ptr = (char *)users; *ptr; i ++)
2429*5e7646d2SAndroid Build Coastguard Worker {
2430*5e7646d2SAndroid Build Coastguard Worker /*
2431*5e7646d2SAndroid Build Coastguard Worker * Skip whitespace and commas...
2432*5e7646d2SAndroid Build Coastguard Worker */
2433*5e7646d2SAndroid Build Coastguard Worker
2434*5e7646d2SAndroid Build Coastguard Worker while (*ptr == ',' || isspace(*ptr & 255))
2435*5e7646d2SAndroid Build Coastguard Worker ptr ++;
2436*5e7646d2SAndroid Build Coastguard Worker
2437*5e7646d2SAndroid Build Coastguard Worker if (!*ptr)
2438*5e7646d2SAndroid Build Coastguard Worker break;
2439*5e7646d2SAndroid Build Coastguard Worker
2440*5e7646d2SAndroid Build Coastguard Worker if (*ptr == '\'' || *ptr == '\"')
2441*5e7646d2SAndroid Build Coastguard Worker {
2442*5e7646d2SAndroid Build Coastguard Worker /*
2443*5e7646d2SAndroid Build Coastguard Worker * Scan quoted name...
2444*5e7646d2SAndroid Build Coastguard Worker */
2445*5e7646d2SAndroid Build Coastguard Worker
2446*5e7646d2SAndroid Build Coastguard Worker quote = *ptr++;
2447*5e7646d2SAndroid Build Coastguard Worker
2448*5e7646d2SAndroid Build Coastguard Worker for (end = ptr; *end; end ++)
2449*5e7646d2SAndroid Build Coastguard Worker if (*end == quote)
2450*5e7646d2SAndroid Build Coastguard Worker break;
2451*5e7646d2SAndroid Build Coastguard Worker }
2452*5e7646d2SAndroid Build Coastguard Worker else
2453*5e7646d2SAndroid Build Coastguard Worker {
2454*5e7646d2SAndroid Build Coastguard Worker /*
2455*5e7646d2SAndroid Build Coastguard Worker * Scan space or comma-delimited name...
2456*5e7646d2SAndroid Build Coastguard Worker */
2457*5e7646d2SAndroid Build Coastguard Worker
2458*5e7646d2SAndroid Build Coastguard Worker for (end = ptr; *end; end ++)
2459*5e7646d2SAndroid Build Coastguard Worker if (isspace(*end & 255) || *end == ',')
2460*5e7646d2SAndroid Build Coastguard Worker break;
2461*5e7646d2SAndroid Build Coastguard Worker }
2462*5e7646d2SAndroid Build Coastguard Worker
2463*5e7646d2SAndroid Build Coastguard Worker /*
2464*5e7646d2SAndroid Build Coastguard Worker * Terminate the name...
2465*5e7646d2SAndroid Build Coastguard Worker */
2466*5e7646d2SAndroid Build Coastguard Worker
2467*5e7646d2SAndroid Build Coastguard Worker if (*end)
2468*5e7646d2SAndroid Build Coastguard Worker *end++ = '\0';
2469*5e7646d2SAndroid Build Coastguard Worker
2470*5e7646d2SAndroid Build Coastguard Worker /*
2471*5e7646d2SAndroid Build Coastguard Worker * Add the name...
2472*5e7646d2SAndroid Build Coastguard Worker */
2473*5e7646d2SAndroid Build Coastguard Worker
2474*5e7646d2SAndroid Build Coastguard Worker ippSetString(request, &attr, i, ptr);
2475*5e7646d2SAndroid Build Coastguard Worker
2476*5e7646d2SAndroid Build Coastguard Worker /*
2477*5e7646d2SAndroid Build Coastguard Worker * Advance to the next name...
2478*5e7646d2SAndroid Build Coastguard Worker */
2479*5e7646d2SAndroid Build Coastguard Worker
2480*5e7646d2SAndroid Build Coastguard Worker ptr = end;
2481*5e7646d2SAndroid Build Coastguard Worker }
2482*5e7646d2SAndroid Build Coastguard Worker }
2483*5e7646d2SAndroid Build Coastguard Worker
2484*5e7646d2SAndroid Build Coastguard Worker /*
2485*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
2486*5e7646d2SAndroid Build Coastguard Worker */
2487*5e7646d2SAndroid Build Coastguard Worker
2488*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/admin/"));
2489*5e7646d2SAndroid Build Coastguard Worker
2490*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
2491*5e7646d2SAndroid Build Coastguard Worker {
2492*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
2493*5e7646d2SAndroid Build Coastguard Worker exit(0);
2494*5e7646d2SAndroid Build Coastguard Worker }
2495*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() > IPP_OK_CONFLICT)
2496*5e7646d2SAndroid Build Coastguard Worker {
2497*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Allowed Users")));
2498*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to change printer"));
2499*5e7646d2SAndroid Build Coastguard Worker }
2500*5e7646d2SAndroid Build Coastguard Worker else
2501*5e7646d2SAndroid Build Coastguard Worker {
2502*5e7646d2SAndroid Build Coastguard Worker /*
2503*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the printer page...
2504*5e7646d2SAndroid Build Coastguard Worker */
2505*5e7646d2SAndroid Build Coastguard Worker
2506*5e7646d2SAndroid Build Coastguard Worker char url[1024], /* Printer/class URL */
2507*5e7646d2SAndroid Build Coastguard Worker refresh[1024]; /* Refresh URL */
2508*5e7646d2SAndroid Build Coastguard Worker
2509*5e7646d2SAndroid Build Coastguard Worker
2510*5e7646d2SAndroid Build Coastguard Worker cgiRewriteURL(uri, url, sizeof(url), NULL);
2511*5e7646d2SAndroid Build Coastguard Worker cgiFormEncode(uri, url, sizeof(uri));
2512*5e7646d2SAndroid Build Coastguard Worker snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s",
2513*5e7646d2SAndroid Build Coastguard Worker uri);
2514*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", refresh);
2515*5e7646d2SAndroid Build Coastguard Worker
2516*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Allowed Users")));
2517*5e7646d2SAndroid Build Coastguard Worker
2518*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang(is_class ? "class-modified.tmpl" :
2519*5e7646d2SAndroid Build Coastguard Worker "printer-modified.tmpl");
2520*5e7646d2SAndroid Build Coastguard Worker }
2521*5e7646d2SAndroid Build Coastguard Worker
2522*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2523*5e7646d2SAndroid Build Coastguard Worker }
2524*5e7646d2SAndroid Build Coastguard Worker }
2525*5e7646d2SAndroid Build Coastguard Worker
2526*5e7646d2SAndroid Build Coastguard Worker
2527*5e7646d2SAndroid Build Coastguard Worker /*
2528*5e7646d2SAndroid Build Coastguard Worker * 'do_set_default()' - Set the server default printer/class.
2529*5e7646d2SAndroid Build Coastguard Worker */
2530*5e7646d2SAndroid Build Coastguard Worker
2531*5e7646d2SAndroid Build Coastguard Worker static void
do_set_default(http_t * http)2532*5e7646d2SAndroid Build Coastguard Worker do_set_default(http_t *http) /* I - HTTP connection */
2533*5e7646d2SAndroid Build Coastguard Worker {
2534*5e7646d2SAndroid Build Coastguard Worker const char *title; /* Page title */
2535*5e7646d2SAndroid Build Coastguard Worker ipp_t *request; /* IPP request */
2536*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI]; /* Printer URI */
2537*5e7646d2SAndroid Build Coastguard Worker const char *printer, /* Printer name (purge-jobs) */
2538*5e7646d2SAndroid Build Coastguard Worker *is_class; /* Is a class? */
2539*5e7646d2SAndroid Build Coastguard Worker
2540*5e7646d2SAndroid Build Coastguard Worker
2541*5e7646d2SAndroid Build Coastguard Worker is_class = cgiGetVariable("IS_CLASS");
2542*5e7646d2SAndroid Build Coastguard Worker printer = cgiGetVariable("PRINTER_NAME");
2543*5e7646d2SAndroid Build Coastguard Worker title = cgiText(_("Set As Server Default"));
2544*5e7646d2SAndroid Build Coastguard Worker
2545*5e7646d2SAndroid Build Coastguard Worker if (!printer)
2546*5e7646d2SAndroid Build Coastguard Worker {
2547*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
2548*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
2549*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
2550*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2551*5e7646d2SAndroid Build Coastguard Worker return;
2552*5e7646d2SAndroid Build Coastguard Worker }
2553*5e7646d2SAndroid Build Coastguard Worker
2554*5e7646d2SAndroid Build Coastguard Worker /*
2555*5e7646d2SAndroid Build Coastguard Worker * Build a printer request, which requires the following
2556*5e7646d2SAndroid Build Coastguard Worker * attributes:
2557*5e7646d2SAndroid Build Coastguard Worker *
2558*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
2559*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
2560*5e7646d2SAndroid Build Coastguard Worker * printer-uri
2561*5e7646d2SAndroid Build Coastguard Worker */
2562*5e7646d2SAndroid Build Coastguard Worker
2563*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(CUPS_SET_DEFAULT);
2564*5e7646d2SAndroid Build Coastguard Worker
2565*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
2566*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
2567*5e7646d2SAndroid Build Coastguard Worker printer);
2568*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
2569*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
2570*5e7646d2SAndroid Build Coastguard Worker
2571*5e7646d2SAndroid Build Coastguard Worker /*
2572*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
2573*5e7646d2SAndroid Build Coastguard Worker */
2574*5e7646d2SAndroid Build Coastguard Worker
2575*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/admin/"));
2576*5e7646d2SAndroid Build Coastguard Worker
2577*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
2578*5e7646d2SAndroid Build Coastguard Worker {
2579*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
2580*5e7646d2SAndroid Build Coastguard Worker exit(0);
2581*5e7646d2SAndroid Build Coastguard Worker }
2582*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() > IPP_OK_CONFLICT)
2583*5e7646d2SAndroid Build Coastguard Worker {
2584*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
2585*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to set server default"));
2586*5e7646d2SAndroid Build Coastguard Worker }
2587*5e7646d2SAndroid Build Coastguard Worker else
2588*5e7646d2SAndroid Build Coastguard Worker {
2589*5e7646d2SAndroid Build Coastguard Worker /*
2590*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the printer page...
2591*5e7646d2SAndroid Build Coastguard Worker */
2592*5e7646d2SAndroid Build Coastguard Worker
2593*5e7646d2SAndroid Build Coastguard Worker char url[1024], /* Printer/class URL */
2594*5e7646d2SAndroid Build Coastguard Worker refresh[1024]; /* Refresh URL */
2595*5e7646d2SAndroid Build Coastguard Worker
2596*5e7646d2SAndroid Build Coastguard Worker
2597*5e7646d2SAndroid Build Coastguard Worker cgiRewriteURL(uri, url, sizeof(url), NULL);
2598*5e7646d2SAndroid Build Coastguard Worker cgiFormEncode(uri, url, sizeof(uri));
2599*5e7646d2SAndroid Build Coastguard Worker snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri);
2600*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", refresh);
2601*5e7646d2SAndroid Build Coastguard Worker
2602*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
2603*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("printer-default.tmpl");
2604*5e7646d2SAndroid Build Coastguard Worker }
2605*5e7646d2SAndroid Build Coastguard Worker
2606*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2607*5e7646d2SAndroid Build Coastguard Worker }
2608*5e7646d2SAndroid Build Coastguard Worker
2609*5e7646d2SAndroid Build Coastguard Worker
2610*5e7646d2SAndroid Build Coastguard Worker /*
2611*5e7646d2SAndroid Build Coastguard Worker * 'do_set_options()' - Configure the default options for a queue.
2612*5e7646d2SAndroid Build Coastguard Worker */
2613*5e7646d2SAndroid Build Coastguard Worker
2614*5e7646d2SAndroid Build Coastguard Worker static void
do_set_options(http_t * http,int is_class)2615*5e7646d2SAndroid Build Coastguard Worker do_set_options(http_t *http, /* I - HTTP connection */
2616*5e7646d2SAndroid Build Coastguard Worker int is_class) /* I - Set options for class? */
2617*5e7646d2SAndroid Build Coastguard Worker {
2618*5e7646d2SAndroid Build Coastguard Worker int i, j, k, m; /* Looping vars */
2619*5e7646d2SAndroid Build Coastguard Worker int have_options; /* Have options? */
2620*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* IPP request */
2621*5e7646d2SAndroid Build Coastguard Worker *response; /* IPP response */
2622*5e7646d2SAndroid Build Coastguard Worker ipp_attribute_t *attr; /* IPP attribute */
2623*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI]; /* Job URI */
2624*5e7646d2SAndroid Build Coastguard Worker const char *var; /* Variable value */
2625*5e7646d2SAndroid Build Coastguard Worker const char *printer; /* Printer printer name */
2626*5e7646d2SAndroid Build Coastguard Worker const char *filename; /* PPD filename */
2627*5e7646d2SAndroid Build Coastguard Worker char tempfile[1024]; /* Temporary filename */
2628*5e7646d2SAndroid Build Coastguard Worker cups_file_t *in, /* Input file */
2629*5e7646d2SAndroid Build Coastguard Worker *out; /* Output file */
2630*5e7646d2SAndroid Build Coastguard Worker char line[1024], /* Line from PPD file */
2631*5e7646d2SAndroid Build Coastguard Worker value[1024], /* Option value */
2632*5e7646d2SAndroid Build Coastguard Worker keyword[1024], /* Keyword from Default line */
2633*5e7646d2SAndroid Build Coastguard Worker *keyptr; /* Pointer into keyword... */
2634*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd; /* PPD file */
2635*5e7646d2SAndroid Build Coastguard Worker ppd_group_t *group; /* Option group */
2636*5e7646d2SAndroid Build Coastguard Worker ppd_option_t *option; /* Option */
2637*5e7646d2SAndroid Build Coastguard Worker ppd_coption_t *coption; /* Custom option */
2638*5e7646d2SAndroid Build Coastguard Worker ppd_cparam_t *cparam; /* Custom parameter */
2639*5e7646d2SAndroid Build Coastguard Worker ppd_attr_t *ppdattr; /* PPD attribute */
2640*5e7646d2SAndroid Build Coastguard Worker const char *title; /* Page title */
2641*5e7646d2SAndroid Build Coastguard Worker
2642*5e7646d2SAndroid Build Coastguard Worker
2643*5e7646d2SAndroid Build Coastguard Worker title = cgiText(is_class ? _("Set Class Options") : _("Set Printer Options"));
2644*5e7646d2SAndroid Build Coastguard Worker
2645*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: do_set_options(http=%p, is_class=%d)\n", http,
2646*5e7646d2SAndroid Build Coastguard Worker is_class);
2647*5e7646d2SAndroid Build Coastguard Worker
2648*5e7646d2SAndroid Build Coastguard Worker /*
2649*5e7646d2SAndroid Build Coastguard Worker * Get the printer name...
2650*5e7646d2SAndroid Build Coastguard Worker */
2651*5e7646d2SAndroid Build Coastguard Worker
2652*5e7646d2SAndroid Build Coastguard Worker if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
2653*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
2654*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
2655*5e7646d2SAndroid Build Coastguard Worker printer);
2656*5e7646d2SAndroid Build Coastguard Worker else
2657*5e7646d2SAndroid Build Coastguard Worker {
2658*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
2659*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
2660*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
2661*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2662*5e7646d2SAndroid Build Coastguard Worker return;
2663*5e7646d2SAndroid Build Coastguard Worker }
2664*5e7646d2SAndroid Build Coastguard Worker
2665*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: printer=\"%s\", uri=\"%s\"...\n", printer, uri);
2666*5e7646d2SAndroid Build Coastguard Worker
2667*5e7646d2SAndroid Build Coastguard Worker /*
2668*5e7646d2SAndroid Build Coastguard Worker * If the user clicks on the Auto-Configure button, send an AutoConfigure
2669*5e7646d2SAndroid Build Coastguard Worker * command file to the printer...
2670*5e7646d2SAndroid Build Coastguard Worker */
2671*5e7646d2SAndroid Build Coastguard Worker
2672*5e7646d2SAndroid Build Coastguard Worker if (cgiGetVariable("AUTOCONFIGURE"))
2673*5e7646d2SAndroid Build Coastguard Worker {
2674*5e7646d2SAndroid Build Coastguard Worker cgiPrintCommand(http, printer, "AutoConfigure", "Set Default Options");
2675*5e7646d2SAndroid Build Coastguard Worker return;
2676*5e7646d2SAndroid Build Coastguard Worker }
2677*5e7646d2SAndroid Build Coastguard Worker
2678*5e7646d2SAndroid Build Coastguard Worker /*
2679*5e7646d2SAndroid Build Coastguard Worker * Get the PPD file...
2680*5e7646d2SAndroid Build Coastguard Worker */
2681*5e7646d2SAndroid Build Coastguard Worker
2682*5e7646d2SAndroid Build Coastguard Worker if (is_class)
2683*5e7646d2SAndroid Build Coastguard Worker filename = NULL;
2684*5e7646d2SAndroid Build Coastguard Worker else
2685*5e7646d2SAndroid Build Coastguard Worker filename = cupsGetPPD2(http, printer);
2686*5e7646d2SAndroid Build Coastguard Worker
2687*5e7646d2SAndroid Build Coastguard Worker if (filename)
2688*5e7646d2SAndroid Build Coastguard Worker {
2689*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: Got PPD file: \"%s\"\n", filename);
2690*5e7646d2SAndroid Build Coastguard Worker
2691*5e7646d2SAndroid Build Coastguard Worker if ((ppd = ppdOpenFile(filename)) == NULL)
2692*5e7646d2SAndroid Build Coastguard Worker {
2693*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", ppdErrorString(ppdLastError(&i)));
2694*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("MESSAGE", cgiText(_("Unable to open PPD file")));
2695*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
2696*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
2697*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
2698*5e7646d2SAndroid Build Coastguard Worker return;
2699*5e7646d2SAndroid Build Coastguard Worker }
2700*5e7646d2SAndroid Build Coastguard Worker }
2701*5e7646d2SAndroid Build Coastguard Worker else
2702*5e7646d2SAndroid Build Coastguard Worker {
2703*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: No PPD file\n", stderr);
2704*5e7646d2SAndroid Build Coastguard Worker ppd = NULL;
2705*5e7646d2SAndroid Build Coastguard Worker }
2706*5e7646d2SAndroid Build Coastguard Worker
2707*5e7646d2SAndroid Build Coastguard Worker if (cgiGetVariable("job_sheets_start") != NULL ||
2708*5e7646d2SAndroid Build Coastguard Worker cgiGetVariable("job_sheets_end") != NULL)
2709*5e7646d2SAndroid Build Coastguard Worker have_options = 1;
2710*5e7646d2SAndroid Build Coastguard Worker else
2711*5e7646d2SAndroid Build Coastguard Worker have_options = 0;
2712*5e7646d2SAndroid Build Coastguard Worker
2713*5e7646d2SAndroid Build Coastguard Worker if (ppd)
2714*5e7646d2SAndroid Build Coastguard Worker {
2715*5e7646d2SAndroid Build Coastguard Worker ppdMarkDefaults(ppd);
2716*5e7646d2SAndroid Build Coastguard Worker
2717*5e7646d2SAndroid Build Coastguard Worker for (option = ppdFirstOption(ppd);
2718*5e7646d2SAndroid Build Coastguard Worker option;
2719*5e7646d2SAndroid Build Coastguard Worker option = ppdNextOption(ppd))
2720*5e7646d2SAndroid Build Coastguard Worker {
2721*5e7646d2SAndroid Build Coastguard Worker if ((var = cgiGetVariable(option->keyword)) != NULL)
2722*5e7646d2SAndroid Build Coastguard Worker {
2723*5e7646d2SAndroid Build Coastguard Worker have_options = 1;
2724*5e7646d2SAndroid Build Coastguard Worker ppdMarkOption(ppd, option->keyword, var);
2725*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: Set %s to %s...\n", option->keyword, var);
2726*5e7646d2SAndroid Build Coastguard Worker }
2727*5e7646d2SAndroid Build Coastguard Worker else
2728*5e7646d2SAndroid Build Coastguard Worker fprintf(stderr, "DEBUG: Didn't find %s...\n", option->keyword);
2729*5e7646d2SAndroid Build Coastguard Worker }
2730*5e7646d2SAndroid Build Coastguard Worker }
2731*5e7646d2SAndroid Build Coastguard Worker
2732*5e7646d2SAndroid Build Coastguard Worker if (!have_options || ppdConflicts(ppd))
2733*5e7646d2SAndroid Build Coastguard Worker {
2734*5e7646d2SAndroid Build Coastguard Worker /*
2735*5e7646d2SAndroid Build Coastguard Worker * Show the options to the user...
2736*5e7646d2SAndroid Build Coastguard Worker */
2737*5e7646d2SAndroid Build Coastguard Worker
2738*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: Showing options...\n", stderr);
2739*5e7646d2SAndroid Build Coastguard Worker
2740*5e7646d2SAndroid Build Coastguard Worker /*
2741*5e7646d2SAndroid Build Coastguard Worker * Show auto-configure button if supported...
2742*5e7646d2SAndroid Build Coastguard Worker */
2743*5e7646d2SAndroid Build Coastguard Worker
2744*5e7646d2SAndroid Build Coastguard Worker if (ppd)
2745*5e7646d2SAndroid Build Coastguard Worker {
2746*5e7646d2SAndroid Build Coastguard Worker if (ppd->num_filters == 0 ||
2747*5e7646d2SAndroid Build Coastguard Worker ((ppdattr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL &&
2748*5e7646d2SAndroid Build Coastguard Worker ppdattr->value && strstr(ppdattr->value, "AutoConfigure")))
2749*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("HAVE_AUTOCONFIGURE", "YES");
2750*5e7646d2SAndroid Build Coastguard Worker else
2751*5e7646d2SAndroid Build Coastguard Worker {
2752*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < ppd->num_filters; i ++)
2753*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(ppd->filters[i], "application/vnd.cups-postscript", 31))
2754*5e7646d2SAndroid Build Coastguard Worker {
2755*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("HAVE_AUTOCONFIGURE", "YES");
2756*5e7646d2SAndroid Build Coastguard Worker break;
2757*5e7646d2SAndroid Build Coastguard Worker }
2758*5e7646d2SAndroid Build Coastguard Worker }
2759*5e7646d2SAndroid Build Coastguard Worker }
2760*5e7646d2SAndroid Build Coastguard Worker
2761*5e7646d2SAndroid Build Coastguard Worker /*
2762*5e7646d2SAndroid Build Coastguard Worker * Get the printer attributes...
2763*5e7646d2SAndroid Build Coastguard Worker */
2764*5e7646d2SAndroid Build Coastguard Worker
2765*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
2766*5e7646d2SAndroid Build Coastguard Worker
2767*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
2768*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, "/printers/%s", printer);
2769*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
2770*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
2771*5e7646d2SAndroid Build Coastguard Worker
2772*5e7646d2SAndroid Build Coastguard Worker response = cupsDoRequest(http, request, "/");
2773*5e7646d2SAndroid Build Coastguard Worker
2774*5e7646d2SAndroid Build Coastguard Worker /*
2775*5e7646d2SAndroid Build Coastguard Worker * List the groups used as "tabs"...
2776*5e7646d2SAndroid Build Coastguard Worker */
2777*5e7646d2SAndroid Build Coastguard Worker
2778*5e7646d2SAndroid Build Coastguard Worker i = 0;
2779*5e7646d2SAndroid Build Coastguard Worker
2780*5e7646d2SAndroid Build Coastguard Worker if (ppd)
2781*5e7646d2SAndroid Build Coastguard Worker {
2782*5e7646d2SAndroid Build Coastguard Worker for (group = ppd->groups;
2783*5e7646d2SAndroid Build Coastguard Worker i < ppd->num_groups;
2784*5e7646d2SAndroid Build Coastguard Worker i ++, group ++)
2785*5e7646d2SAndroid Build Coastguard Worker {
2786*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP_ID", i, group->name);
2787*5e7646d2SAndroid Build Coastguard Worker
2788*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(group->name, "InstallableOptions"))
2789*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP", i, cgiText(_("Options Installed")));
2790*5e7646d2SAndroid Build Coastguard Worker else
2791*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP", i, group->text);
2792*5e7646d2SAndroid Build Coastguard Worker }
2793*5e7646d2SAndroid Build Coastguard Worker }
2794*5e7646d2SAndroid Build Coastguard Worker
2795*5e7646d2SAndroid Build Coastguard Worker if (ippFindAttribute(response, "job-sheets-supported", IPP_TAG_ZERO))
2796*5e7646d2SAndroid Build Coastguard Worker {
2797*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP_ID", i, "CUPS_BANNERS");
2798*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP", i ++, cgiText(_("Banners")));
2799*5e7646d2SAndroid Build Coastguard Worker }
2800*5e7646d2SAndroid Build Coastguard Worker
2801*5e7646d2SAndroid Build Coastguard Worker if (ippFindAttribute(response, "printer-error-policy-supported",
2802*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO) ||
2803*5e7646d2SAndroid Build Coastguard Worker ippFindAttribute(response, "printer-op-policy-supported",
2804*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO))
2805*5e7646d2SAndroid Build Coastguard Worker {
2806*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP_ID", i, "CUPS_POLICIES");
2807*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP", i ++, cgiText(_("Policies")));
2808*5e7646d2SAndroid Build Coastguard Worker }
2809*5e7646d2SAndroid Build Coastguard Worker
2810*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "port-monitor-supported",
2811*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_NAME)) != NULL && attr->num_values > 1)
2812*5e7646d2SAndroid Build Coastguard Worker {
2813*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP_ID", i, "CUPS_PORT_MONITOR");
2814*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("GROUP", i, cgiText(_("Port Monitor")));
2815*5e7646d2SAndroid Build Coastguard Worker }
2816*5e7646d2SAndroid Build Coastguard Worker
2817*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Printer Options")));
2818*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("set-printer-options-header.tmpl");
2819*5e7646d2SAndroid Build Coastguard Worker
2820*5e7646d2SAndroid Build Coastguard Worker if (ppd)
2821*5e7646d2SAndroid Build Coastguard Worker {
2822*5e7646d2SAndroid Build Coastguard Worker ppdLocalize(ppd);
2823*5e7646d2SAndroid Build Coastguard Worker
2824*5e7646d2SAndroid Build Coastguard Worker if (ppdConflicts(ppd))
2825*5e7646d2SAndroid Build Coastguard Worker {
2826*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_groups, k = 0, group = ppd->groups;
2827*5e7646d2SAndroid Build Coastguard Worker i > 0;
2828*5e7646d2SAndroid Build Coastguard Worker i --, group ++)
2829*5e7646d2SAndroid Build Coastguard Worker for (j = group->num_options, option = group->options;
2830*5e7646d2SAndroid Build Coastguard Worker j > 0;
2831*5e7646d2SAndroid Build Coastguard Worker j --, option ++)
2832*5e7646d2SAndroid Build Coastguard Worker if (option->conflicted)
2833*5e7646d2SAndroid Build Coastguard Worker {
2834*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("ckeyword", k, option->keyword);
2835*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("ckeytext", k, option->text);
2836*5e7646d2SAndroid Build Coastguard Worker
2837*5e7646d2SAndroid Build Coastguard Worker for (m = 0; m < option->num_choices; m ++)
2838*5e7646d2SAndroid Build Coastguard Worker {
2839*5e7646d2SAndroid Build Coastguard Worker if (option->choices[m].marked)
2840*5e7646d2SAndroid Build Coastguard Worker {
2841*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("cchoice", k, option->choices[m].text);
2842*5e7646d2SAndroid Build Coastguard Worker break;
2843*5e7646d2SAndroid Build Coastguard Worker }
2844*5e7646d2SAndroid Build Coastguard Worker }
2845*5e7646d2SAndroid Build Coastguard Worker
2846*5e7646d2SAndroid Build Coastguard Worker k ++;
2847*5e7646d2SAndroid Build Coastguard Worker }
2848*5e7646d2SAndroid Build Coastguard Worker
2849*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-conflict.tmpl");
2850*5e7646d2SAndroid Build Coastguard Worker }
2851*5e7646d2SAndroid Build Coastguard Worker
2852*5e7646d2SAndroid Build Coastguard Worker for (i = ppd->num_groups, group = ppd->groups;
2853*5e7646d2SAndroid Build Coastguard Worker i > 0;
2854*5e7646d2SAndroid Build Coastguard Worker i --, group ++)
2855*5e7646d2SAndroid Build Coastguard Worker {
2856*5e7646d2SAndroid Build Coastguard Worker for (j = group->num_options, option = group->options;
2857*5e7646d2SAndroid Build Coastguard Worker j > 0;
2858*5e7646d2SAndroid Build Coastguard Worker j --, option ++)
2859*5e7646d2SAndroid Build Coastguard Worker {
2860*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(option->keyword, "PageRegion"))
2861*5e7646d2SAndroid Build Coastguard Worker continue;
2862*5e7646d2SAndroid Build Coastguard Worker
2863*5e7646d2SAndroid Build Coastguard Worker if (option->num_choices > 1)
2864*5e7646d2SAndroid Build Coastguard Worker break;
2865*5e7646d2SAndroid Build Coastguard Worker }
2866*5e7646d2SAndroid Build Coastguard Worker
2867*5e7646d2SAndroid Build Coastguard Worker if (j == 0)
2868*5e7646d2SAndroid Build Coastguard Worker continue;
2869*5e7646d2SAndroid Build Coastguard Worker
2870*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP_ID", group->name);
2871*5e7646d2SAndroid Build Coastguard Worker
2872*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(group->name, "InstallableOptions"))
2873*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP", cgiText(_("Options Installed")));
2874*5e7646d2SAndroid Build Coastguard Worker else
2875*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP", group->text);
2876*5e7646d2SAndroid Build Coastguard Worker
2877*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-header.tmpl");
2878*5e7646d2SAndroid Build Coastguard Worker
2879*5e7646d2SAndroid Build Coastguard Worker for (j = group->num_options, option = group->options;
2880*5e7646d2SAndroid Build Coastguard Worker j > 0;
2881*5e7646d2SAndroid Build Coastguard Worker j --, option ++)
2882*5e7646d2SAndroid Build Coastguard Worker {
2883*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(option->keyword, "PageRegion") || option->num_choices < 2)
2884*5e7646d2SAndroid Build Coastguard Worker continue;
2885*5e7646d2SAndroid Build Coastguard Worker
2886*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYWORD", option->keyword);
2887*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYTEXT", option->text);
2888*5e7646d2SAndroid Build Coastguard Worker
2889*5e7646d2SAndroid Build Coastguard Worker if (option->conflicted)
2890*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CONFLICTED", "1");
2891*5e7646d2SAndroid Build Coastguard Worker else
2892*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("CONFLICTED", "0");
2893*5e7646d2SAndroid Build Coastguard Worker
2894*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("CHOICES", 0);
2895*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("TEXT", 0);
2896*5e7646d2SAndroid Build Coastguard Worker for (k = 0, m = 0; k < option->num_choices; k ++)
2897*5e7646d2SAndroid Build Coastguard Worker {
2898*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("CHOICES", m, option->choices[k].choice);
2899*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("TEXT", m, option->choices[k].text);
2900*5e7646d2SAndroid Build Coastguard Worker
2901*5e7646d2SAndroid Build Coastguard Worker m ++;
2902*5e7646d2SAndroid Build Coastguard Worker
2903*5e7646d2SAndroid Build Coastguard Worker if (option->choices[k].marked)
2904*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEFCHOICE", option->choices[k].choice);
2905*5e7646d2SAndroid Build Coastguard Worker }
2906*5e7646d2SAndroid Build Coastguard Worker
2907*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("PARAMS", 0);
2908*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("PARAMTEXT", 0);
2909*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("PARAMVALUE", 0);
2910*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("INPUTTYPE", 0);
2911*5e7646d2SAndroid Build Coastguard Worker
2912*5e7646d2SAndroid Build Coastguard Worker if ((coption = ppdFindCustomOption(ppd, option->keyword)))
2913*5e7646d2SAndroid Build Coastguard Worker {
2914*5e7646d2SAndroid Build Coastguard Worker const char *units = NULL; /* Units value, if any */
2915*5e7646d2SAndroid Build Coastguard Worker
2916*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ISCUSTOM", "1");
2917*5e7646d2SAndroid Build Coastguard Worker
2918*5e7646d2SAndroid Build Coastguard Worker for (cparam = ppdFirstCustomParam(coption), m = 0;
2919*5e7646d2SAndroid Build Coastguard Worker cparam;
2920*5e7646d2SAndroid Build Coastguard Worker cparam = ppdNextCustomParam(coption), m ++)
2921*5e7646d2SAndroid Build Coastguard Worker {
2922*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strcasecmp(option->keyword, "PageSize") &&
2923*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(cparam->name, "Width") &&
2924*5e7646d2SAndroid Build Coastguard Worker _cups_strcasecmp(cparam->name, "Height"))
2925*5e7646d2SAndroid Build Coastguard Worker {
2926*5e7646d2SAndroid Build Coastguard Worker m --;
2927*5e7646d2SAndroid Build Coastguard Worker continue;
2928*5e7646d2SAndroid Build Coastguard Worker }
2929*5e7646d2SAndroid Build Coastguard Worker
2930*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMS", m, cparam->name);
2931*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMTEXT", m, cparam->text);
2932*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("INPUTTYPE", m, "text");
2933*5e7646d2SAndroid Build Coastguard Worker
2934*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
2935*5e7646d2SAndroid Build Coastguard Worker {
2936*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
2937*5e7646d2SAndroid Build Coastguard Worker break;
2938*5e7646d2SAndroid Build Coastguard Worker
2939*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
2940*5e7646d2SAndroid Build Coastguard Worker if (!_cups_strncasecmp(option->defchoice, "Custom.", 7))
2941*5e7646d2SAndroid Build Coastguard Worker {
2942*5e7646d2SAndroid Build Coastguard Worker units = option->defchoice + strlen(option->defchoice) - 2;
2943*5e7646d2SAndroid Build Coastguard Worker
2944*5e7646d2SAndroid Build Coastguard Worker if (strcmp(units, "mm") && strcmp(units, "cm") &&
2945*5e7646d2SAndroid Build Coastguard Worker strcmp(units, "in") && strcmp(units, "ft"))
2946*5e7646d2SAndroid Build Coastguard Worker {
2947*5e7646d2SAndroid Build Coastguard Worker if (units[1] == 'm')
2948*5e7646d2SAndroid Build Coastguard Worker units ++;
2949*5e7646d2SAndroid Build Coastguard Worker else
2950*5e7646d2SAndroid Build Coastguard Worker units = "pt";
2951*5e7646d2SAndroid Build Coastguard Worker }
2952*5e7646d2SAndroid Build Coastguard Worker }
2953*5e7646d2SAndroid Build Coastguard Worker else
2954*5e7646d2SAndroid Build Coastguard Worker units = "pt";
2955*5e7646d2SAndroid Build Coastguard Worker
2956*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(units, "mm"))
2957*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%g",
2958*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points / 72.0 * 25.4);
2959*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(units, "cm"))
2960*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%g",
2961*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points / 72.0 * 2.54);
2962*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(units, "in"))
2963*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%g",
2964*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points / 72.0);
2965*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(units, "ft"))
2966*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%g",
2967*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points / 72.0 / 12.0);
2968*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(units, "m"))
2969*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%g",
2970*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points / 72.0 * 0.0254);
2971*5e7646d2SAndroid Build Coastguard Worker else
2972*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%g",
2973*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_points);
2974*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m, value);
2975*5e7646d2SAndroid Build Coastguard Worker break;
2976*5e7646d2SAndroid Build Coastguard Worker
2977*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
2978*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
2979*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
2980*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%g",
2981*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_real);
2982*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m, value);
2983*5e7646d2SAndroid Build Coastguard Worker break;
2984*5e7646d2SAndroid Build Coastguard Worker
2985*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT:
2986*5e7646d2SAndroid Build Coastguard Worker snprintf(value, sizeof(value), "%d",
2987*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_int);
2988*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m, value);
2989*5e7646d2SAndroid Build Coastguard Worker break;
2990*5e7646d2SAndroid Build Coastguard Worker
2991*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE:
2992*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD:
2993*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_password)
2994*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m,
2995*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_password);
2996*5e7646d2SAndroid Build Coastguard Worker else
2997*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m, "");
2998*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("INPUTTYPE", m, "password");
2999*5e7646d2SAndroid Build Coastguard Worker break;
3000*5e7646d2SAndroid Build Coastguard Worker
3001*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING:
3002*5e7646d2SAndroid Build Coastguard Worker if (cparam->current.custom_string)
3003*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m,
3004*5e7646d2SAndroid Build Coastguard Worker cparam->current.custom_string);
3005*5e7646d2SAndroid Build Coastguard Worker else
3006*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m, "");
3007*5e7646d2SAndroid Build Coastguard Worker break;
3008*5e7646d2SAndroid Build Coastguard Worker }
3009*5e7646d2SAndroid Build Coastguard Worker }
3010*5e7646d2SAndroid Build Coastguard Worker
3011*5e7646d2SAndroid Build Coastguard Worker if (units)
3012*5e7646d2SAndroid Build Coastguard Worker {
3013*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMS", m, "Units");
3014*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMTEXT", m, cgiText(_("Units")));
3015*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("PARAMVALUE", m, units);
3016*5e7646d2SAndroid Build Coastguard Worker }
3017*5e7646d2SAndroid Build Coastguard Worker }
3018*5e7646d2SAndroid Build Coastguard Worker else
3019*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ISCUSTOM", "0");
3020*5e7646d2SAndroid Build Coastguard Worker
3021*5e7646d2SAndroid Build Coastguard Worker switch (option->ui)
3022*5e7646d2SAndroid Build Coastguard Worker {
3023*5e7646d2SAndroid Build Coastguard Worker case PPD_UI_BOOLEAN :
3024*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-boolean.tmpl");
3025*5e7646d2SAndroid Build Coastguard Worker break;
3026*5e7646d2SAndroid Build Coastguard Worker case PPD_UI_PICKONE :
3027*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-pickone.tmpl");
3028*5e7646d2SAndroid Build Coastguard Worker break;
3029*5e7646d2SAndroid Build Coastguard Worker case PPD_UI_PICKMANY :
3030*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-pickmany.tmpl");
3031*5e7646d2SAndroid Build Coastguard Worker break;
3032*5e7646d2SAndroid Build Coastguard Worker }
3033*5e7646d2SAndroid Build Coastguard Worker }
3034*5e7646d2SAndroid Build Coastguard Worker
3035*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-trailer.tmpl");
3036*5e7646d2SAndroid Build Coastguard Worker }
3037*5e7646d2SAndroid Build Coastguard Worker }
3038*5e7646d2SAndroid Build Coastguard Worker
3039*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "job-sheets-supported",
3040*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO)) != NULL)
3041*5e7646d2SAndroid Build Coastguard Worker {
3042*5e7646d2SAndroid Build Coastguard Worker /*
3043*5e7646d2SAndroid Build Coastguard Worker * Add the job sheets options...
3044*5e7646d2SAndroid Build Coastguard Worker */
3045*5e7646d2SAndroid Build Coastguard Worker
3046*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP_ID", "CUPS_BANNERS");
3047*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP", cgiText(_("Banners")));
3048*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-header.tmpl");
3049*5e7646d2SAndroid Build Coastguard Worker
3050*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("CHOICES", attr->num_values);
3051*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("TEXT", attr->num_values);
3052*5e7646d2SAndroid Build Coastguard Worker for (k = 0; k < attr->num_values; k ++)
3053*5e7646d2SAndroid Build Coastguard Worker {
3054*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("CHOICES", k, attr->values[k].string.text);
3055*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("TEXT", k, attr->values[k].string.text);
3056*5e7646d2SAndroid Build Coastguard Worker }
3057*5e7646d2SAndroid Build Coastguard Worker
3058*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO);
3059*5e7646d2SAndroid Build Coastguard Worker
3060*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYWORD", "job_sheets_start");
3061*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYTEXT",
3062*5e7646d2SAndroid Build Coastguard Worker /* TRANSLATORS: Banner/cover sheet before the print job. */
3063*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Starting Banner")));
3064*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEFCHOICE", attr != NULL ?
3065*5e7646d2SAndroid Build Coastguard Worker attr->values[0].string.text : "");
3066*5e7646d2SAndroid Build Coastguard Worker
3067*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-pickone.tmpl");
3068*5e7646d2SAndroid Build Coastguard Worker
3069*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYWORD", "job_sheets_end");
3070*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYTEXT",
3071*5e7646d2SAndroid Build Coastguard Worker /* TRANSLATORS: Banner/cover sheet after the print job. */
3072*5e7646d2SAndroid Build Coastguard Worker cgiText(_("Ending Banner")));
3073*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEFCHOICE", attr != NULL && attr->num_values > 1 ?
3074*5e7646d2SAndroid Build Coastguard Worker attr->values[1].string.text : "");
3075*5e7646d2SAndroid Build Coastguard Worker
3076*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-pickone.tmpl");
3077*5e7646d2SAndroid Build Coastguard Worker
3078*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-trailer.tmpl");
3079*5e7646d2SAndroid Build Coastguard Worker }
3080*5e7646d2SAndroid Build Coastguard Worker
3081*5e7646d2SAndroid Build Coastguard Worker if (ippFindAttribute(response, "printer-error-policy-supported",
3082*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO) ||
3083*5e7646d2SAndroid Build Coastguard Worker ippFindAttribute(response, "printer-op-policy-supported",
3084*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO))
3085*5e7646d2SAndroid Build Coastguard Worker {
3086*5e7646d2SAndroid Build Coastguard Worker /*
3087*5e7646d2SAndroid Build Coastguard Worker * Add the error and operation policy options...
3088*5e7646d2SAndroid Build Coastguard Worker */
3089*5e7646d2SAndroid Build Coastguard Worker
3090*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP_ID", "CUPS_POLICIES");
3091*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP", cgiText(_("Policies")));
3092*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-header.tmpl");
3093*5e7646d2SAndroid Build Coastguard Worker
3094*5e7646d2SAndroid Build Coastguard Worker /*
3095*5e7646d2SAndroid Build Coastguard Worker * Error policy...
3096*5e7646d2SAndroid Build Coastguard Worker */
3097*5e7646d2SAndroid Build Coastguard Worker
3098*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(response, "printer-error-policy-supported",
3099*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO);
3100*5e7646d2SAndroid Build Coastguard Worker
3101*5e7646d2SAndroid Build Coastguard Worker if (attr)
3102*5e7646d2SAndroid Build Coastguard Worker {
3103*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("CHOICES", attr->num_values);
3104*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("TEXT", attr->num_values);
3105*5e7646d2SAndroid Build Coastguard Worker for (k = 0; k < attr->num_values; k ++)
3106*5e7646d2SAndroid Build Coastguard Worker {
3107*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("CHOICES", k, attr->values[k].string.text);
3108*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("TEXT", k, attr->values[k].string.text);
3109*5e7646d2SAndroid Build Coastguard Worker }
3110*5e7646d2SAndroid Build Coastguard Worker
3111*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(response, "printer-error-policy",
3112*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO);
3113*5e7646d2SAndroid Build Coastguard Worker
3114*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYWORD", "printer_error_policy");
3115*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYTEXT", cgiText(_("Error Policy")));
3116*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEFCHOICE", attr == NULL ?
3117*5e7646d2SAndroid Build Coastguard Worker "" : attr->values[0].string.text);
3118*5e7646d2SAndroid Build Coastguard Worker }
3119*5e7646d2SAndroid Build Coastguard Worker
3120*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-pickone.tmpl");
3121*5e7646d2SAndroid Build Coastguard Worker
3122*5e7646d2SAndroid Build Coastguard Worker /*
3123*5e7646d2SAndroid Build Coastguard Worker * Operation policy...
3124*5e7646d2SAndroid Build Coastguard Worker */
3125*5e7646d2SAndroid Build Coastguard Worker
3126*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(response, "printer-op-policy-supported",
3127*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_ZERO);
3128*5e7646d2SAndroid Build Coastguard Worker
3129*5e7646d2SAndroid Build Coastguard Worker if (attr)
3130*5e7646d2SAndroid Build Coastguard Worker {
3131*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("CHOICES", attr->num_values);
3132*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("TEXT", attr->num_values);
3133*5e7646d2SAndroid Build Coastguard Worker for (k = 0; k < attr->num_values; k ++)
3134*5e7646d2SAndroid Build Coastguard Worker {
3135*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("CHOICES", k, attr->values[k].string.text);
3136*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("TEXT", k, attr->values[k].string.text);
3137*5e7646d2SAndroid Build Coastguard Worker }
3138*5e7646d2SAndroid Build Coastguard Worker
3139*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(response, "printer-op-policy", IPP_TAG_ZERO);
3140*5e7646d2SAndroid Build Coastguard Worker
3141*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYWORD", "printer_op_policy");
3142*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYTEXT", cgiText(_("Operation Policy")));
3143*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEFCHOICE", attr == NULL ?
3144*5e7646d2SAndroid Build Coastguard Worker "" : attr->values[0].string.text);
3145*5e7646d2SAndroid Build Coastguard Worker
3146*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-pickone.tmpl");
3147*5e7646d2SAndroid Build Coastguard Worker }
3148*5e7646d2SAndroid Build Coastguard Worker
3149*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-trailer.tmpl");
3150*5e7646d2SAndroid Build Coastguard Worker }
3151*5e7646d2SAndroid Build Coastguard Worker
3152*5e7646d2SAndroid Build Coastguard Worker /*
3153*5e7646d2SAndroid Build Coastguard Worker * Binary protocol support...
3154*5e7646d2SAndroid Build Coastguard Worker */
3155*5e7646d2SAndroid Build Coastguard Worker
3156*5e7646d2SAndroid Build Coastguard Worker if ((attr = ippFindAttribute(response, "port-monitor-supported",
3157*5e7646d2SAndroid Build Coastguard Worker IPP_TAG_NAME)) != NULL && attr->num_values > 1)
3158*5e7646d2SAndroid Build Coastguard Worker {
3159*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP_ID", "CUPS_PORT_MONITOR");
3160*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("GROUP", cgiText(_("Port Monitor")));
3161*5e7646d2SAndroid Build Coastguard Worker
3162*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("CHOICES", attr->num_values);
3163*5e7646d2SAndroid Build Coastguard Worker cgiSetSize("TEXT", attr->num_values);
3164*5e7646d2SAndroid Build Coastguard Worker
3165*5e7646d2SAndroid Build Coastguard Worker for (i = 0; i < attr->num_values; i ++)
3166*5e7646d2SAndroid Build Coastguard Worker {
3167*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("CHOICES", i, attr->values[i].string.text);
3168*5e7646d2SAndroid Build Coastguard Worker cgiSetArray("TEXT", i, attr->values[i].string.text);
3169*5e7646d2SAndroid Build Coastguard Worker }
3170*5e7646d2SAndroid Build Coastguard Worker
3171*5e7646d2SAndroid Build Coastguard Worker attr = ippFindAttribute(response, "port-monitor", IPP_TAG_NAME);
3172*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYWORD", "port_monitor");
3173*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("KEYTEXT", cgiText(_("Port Monitor")));
3174*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("DEFCHOICE", attr ? attr->values[0].string.text : "none");
3175*5e7646d2SAndroid Build Coastguard Worker
3176*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-header.tmpl");
3177*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-pickone.tmpl");
3178*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("option-trailer.tmpl");
3179*5e7646d2SAndroid Build Coastguard Worker }
3180*5e7646d2SAndroid Build Coastguard Worker
3181*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("set-printer-options-trailer.tmpl");
3182*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
3183*5e7646d2SAndroid Build Coastguard Worker
3184*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
3185*5e7646d2SAndroid Build Coastguard Worker }
3186*5e7646d2SAndroid Build Coastguard Worker else
3187*5e7646d2SAndroid Build Coastguard Worker {
3188*5e7646d2SAndroid Build Coastguard Worker /*
3189*5e7646d2SAndroid Build Coastguard Worker * Set default options...
3190*5e7646d2SAndroid Build Coastguard Worker */
3191*5e7646d2SAndroid Build Coastguard Worker
3192*5e7646d2SAndroid Build Coastguard Worker fputs("DEBUG: Setting options...\n", stderr);
3193*5e7646d2SAndroid Build Coastguard Worker
3194*5e7646d2SAndroid Build Coastguard Worker if (filename)
3195*5e7646d2SAndroid Build Coastguard Worker {
3196*5e7646d2SAndroid Build Coastguard Worker out = cupsTempFile2(tempfile, sizeof(tempfile));
3197*5e7646d2SAndroid Build Coastguard Worker in = cupsFileOpen(filename, "r");
3198*5e7646d2SAndroid Build Coastguard Worker
3199*5e7646d2SAndroid Build Coastguard Worker if (!in || !out)
3200*5e7646d2SAndroid Build Coastguard Worker {
3201*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", strerror(errno));
3202*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Printer Options")));
3203*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
3204*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
3205*5e7646d2SAndroid Build Coastguard Worker
3206*5e7646d2SAndroid Build Coastguard Worker if (in)
3207*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(in);
3208*5e7646d2SAndroid Build Coastguard Worker
3209*5e7646d2SAndroid Build Coastguard Worker if (out)
3210*5e7646d2SAndroid Build Coastguard Worker {
3211*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(out);
3212*5e7646d2SAndroid Build Coastguard Worker unlink(tempfile);
3213*5e7646d2SAndroid Build Coastguard Worker }
3214*5e7646d2SAndroid Build Coastguard Worker
3215*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
3216*5e7646d2SAndroid Build Coastguard Worker return;
3217*5e7646d2SAndroid Build Coastguard Worker }
3218*5e7646d2SAndroid Build Coastguard Worker
3219*5e7646d2SAndroid Build Coastguard Worker while (cupsFileGets(in, line, sizeof(line)))
3220*5e7646d2SAndroid Build Coastguard Worker {
3221*5e7646d2SAndroid Build Coastguard Worker if (!strncmp(line, "*cupsProtocol:", 14))
3222*5e7646d2SAndroid Build Coastguard Worker continue;
3223*5e7646d2SAndroid Build Coastguard Worker else if (strncmp(line, "*Default", 8))
3224*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(out, "%s\n", line);
3225*5e7646d2SAndroid Build Coastguard Worker else
3226*5e7646d2SAndroid Build Coastguard Worker {
3227*5e7646d2SAndroid Build Coastguard Worker /*
3228*5e7646d2SAndroid Build Coastguard Worker * Get default option name...
3229*5e7646d2SAndroid Build Coastguard Worker */
3230*5e7646d2SAndroid Build Coastguard Worker
3231*5e7646d2SAndroid Build Coastguard Worker strlcpy(keyword, line + 8, sizeof(keyword));
3232*5e7646d2SAndroid Build Coastguard Worker
3233*5e7646d2SAndroid Build Coastguard Worker for (keyptr = keyword; *keyptr; keyptr ++)
3234*5e7646d2SAndroid Build Coastguard Worker if (*keyptr == ':' || isspace(*keyptr & 255))
3235*5e7646d2SAndroid Build Coastguard Worker break;
3236*5e7646d2SAndroid Build Coastguard Worker
3237*5e7646d2SAndroid Build Coastguard Worker *keyptr = '\0';
3238*5e7646d2SAndroid Build Coastguard Worker
3239*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(keyword, "PageRegion") ||
3240*5e7646d2SAndroid Build Coastguard Worker !strcmp(keyword, "PaperDimension") ||
3241*5e7646d2SAndroid Build Coastguard Worker !strcmp(keyword, "ImageableArea"))
3242*5e7646d2SAndroid Build Coastguard Worker var = get_option_value(ppd, "PageSize", value, sizeof(value));
3243*5e7646d2SAndroid Build Coastguard Worker else
3244*5e7646d2SAndroid Build Coastguard Worker var = get_option_value(ppd, keyword, value, sizeof(value));
3245*5e7646d2SAndroid Build Coastguard Worker
3246*5e7646d2SAndroid Build Coastguard Worker if (!var)
3247*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(out, "%s\n", line);
3248*5e7646d2SAndroid Build Coastguard Worker else
3249*5e7646d2SAndroid Build Coastguard Worker cupsFilePrintf(out, "*Default%s: %s\n", keyword, var);
3250*5e7646d2SAndroid Build Coastguard Worker }
3251*5e7646d2SAndroid Build Coastguard Worker }
3252*5e7646d2SAndroid Build Coastguard Worker
3253*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(in);
3254*5e7646d2SAndroid Build Coastguard Worker cupsFileClose(out);
3255*5e7646d2SAndroid Build Coastguard Worker }
3256*5e7646d2SAndroid Build Coastguard Worker else
3257*5e7646d2SAndroid Build Coastguard Worker {
3258*5e7646d2SAndroid Build Coastguard Worker /*
3259*5e7646d2SAndroid Build Coastguard Worker * Make sure temporary filename is cleared when there is no PPD...
3260*5e7646d2SAndroid Build Coastguard Worker */
3261*5e7646d2SAndroid Build Coastguard Worker
3262*5e7646d2SAndroid Build Coastguard Worker tempfile[0] = '\0';
3263*5e7646d2SAndroid Build Coastguard Worker }
3264*5e7646d2SAndroid Build Coastguard Worker
3265*5e7646d2SAndroid Build Coastguard Worker /*
3266*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS_ADD_MODIFY_CLASS/PRINTER request, which requires the
3267*5e7646d2SAndroid Build Coastguard Worker * following attributes:
3268*5e7646d2SAndroid Build Coastguard Worker *
3269*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
3270*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
3271*5e7646d2SAndroid Build Coastguard Worker * printer-uri
3272*5e7646d2SAndroid Build Coastguard Worker * job-sheets-default
3273*5e7646d2SAndroid Build Coastguard Worker * printer-error-policy
3274*5e7646d2SAndroid Build Coastguard Worker * printer-op-policy
3275*5e7646d2SAndroid Build Coastguard Worker * [ppd file]
3276*5e7646d2SAndroid Build Coastguard Worker */
3277*5e7646d2SAndroid Build Coastguard Worker
3278*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(is_class ? CUPS_ADD_MODIFY_CLASS :
3279*5e7646d2SAndroid Build Coastguard Worker CUPS_ADD_MODIFY_PRINTER);
3280*5e7646d2SAndroid Build Coastguard Worker
3281*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
3282*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
3283*5e7646d2SAndroid Build Coastguard Worker
3284*5e7646d2SAndroid Build Coastguard Worker attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
3285*5e7646d2SAndroid Build Coastguard Worker "job-sheets-default", 2, NULL, NULL);
3286*5e7646d2SAndroid Build Coastguard Worker ippSetString(request, &attr, 0, cgiGetVariable("job_sheets_start"));
3287*5e7646d2SAndroid Build Coastguard Worker ippSetString(request, &attr, 1, cgiGetVariable("job_sheets_end"));
3288*5e7646d2SAndroid Build Coastguard Worker
3289*5e7646d2SAndroid Build Coastguard Worker if ((var = cgiGetVariable("printer_error_policy")) != NULL)
3290*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
3291*5e7646d2SAndroid Build Coastguard Worker "printer-error-policy", NULL, var);
3292*5e7646d2SAndroid Build Coastguard Worker
3293*5e7646d2SAndroid Build Coastguard Worker if ((var = cgiGetVariable("printer_op_policy")) != NULL)
3294*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
3295*5e7646d2SAndroid Build Coastguard Worker "printer-op-policy", NULL, var);
3296*5e7646d2SAndroid Build Coastguard Worker
3297*5e7646d2SAndroid Build Coastguard Worker if ((var = cgiGetVariable("port_monitor")) != NULL)
3298*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
3299*5e7646d2SAndroid Build Coastguard Worker "port-monitor", NULL, var);
3300*5e7646d2SAndroid Build Coastguard Worker
3301*5e7646d2SAndroid Build Coastguard Worker /*
3302*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
3303*5e7646d2SAndroid Build Coastguard Worker */
3304*5e7646d2SAndroid Build Coastguard Worker
3305*5e7646d2SAndroid Build Coastguard Worker if (filename)
3306*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoFileRequest(http, request, "/admin/", tempfile));
3307*5e7646d2SAndroid Build Coastguard Worker else
3308*5e7646d2SAndroid Build Coastguard Worker ippDelete(cupsDoRequest(http, request, "/admin/"));
3309*5e7646d2SAndroid Build Coastguard Worker
3310*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
3311*5e7646d2SAndroid Build Coastguard Worker {
3312*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
3313*5e7646d2SAndroid Build Coastguard Worker exit(0);
3314*5e7646d2SAndroid Build Coastguard Worker }
3315*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() > IPP_OK_CONFLICT)
3316*5e7646d2SAndroid Build Coastguard Worker {
3317*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
3318*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to set options"));
3319*5e7646d2SAndroid Build Coastguard Worker }
3320*5e7646d2SAndroid Build Coastguard Worker else
3321*5e7646d2SAndroid Build Coastguard Worker {
3322*5e7646d2SAndroid Build Coastguard Worker /*
3323*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the printer page...
3324*5e7646d2SAndroid Build Coastguard Worker */
3325*5e7646d2SAndroid Build Coastguard Worker
3326*5e7646d2SAndroid Build Coastguard Worker char refresh[1024]; /* Refresh URL */
3327*5e7646d2SAndroid Build Coastguard Worker
3328*5e7646d2SAndroid Build Coastguard Worker
3329*5e7646d2SAndroid Build Coastguard Worker cgiFormEncode(uri, printer, sizeof(uri));
3330*5e7646d2SAndroid Build Coastguard Worker snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=/%s/%s",
3331*5e7646d2SAndroid Build Coastguard Worker is_class ? "classes" : "printers", uri);
3332*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", refresh);
3333*5e7646d2SAndroid Build Coastguard Worker
3334*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(title);
3335*5e7646d2SAndroid Build Coastguard Worker
3336*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("printer-configured.tmpl");
3337*5e7646d2SAndroid Build Coastguard Worker }
3338*5e7646d2SAndroid Build Coastguard Worker
3339*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
3340*5e7646d2SAndroid Build Coastguard Worker
3341*5e7646d2SAndroid Build Coastguard Worker if (filename)
3342*5e7646d2SAndroid Build Coastguard Worker unlink(tempfile);
3343*5e7646d2SAndroid Build Coastguard Worker }
3344*5e7646d2SAndroid Build Coastguard Worker
3345*5e7646d2SAndroid Build Coastguard Worker if (filename)
3346*5e7646d2SAndroid Build Coastguard Worker unlink(filename);
3347*5e7646d2SAndroid Build Coastguard Worker }
3348*5e7646d2SAndroid Build Coastguard Worker
3349*5e7646d2SAndroid Build Coastguard Worker
3350*5e7646d2SAndroid Build Coastguard Worker /*
3351*5e7646d2SAndroid Build Coastguard Worker * 'do_set_sharing()' - Set printer-is-shared value.
3352*5e7646d2SAndroid Build Coastguard Worker */
3353*5e7646d2SAndroid Build Coastguard Worker
3354*5e7646d2SAndroid Build Coastguard Worker static void
do_set_sharing(http_t * http)3355*5e7646d2SAndroid Build Coastguard Worker do_set_sharing(http_t *http) /* I - HTTP connection */
3356*5e7646d2SAndroid Build Coastguard Worker {
3357*5e7646d2SAndroid Build Coastguard Worker ipp_t *request, /* IPP request */
3358*5e7646d2SAndroid Build Coastguard Worker *response; /* IPP response */
3359*5e7646d2SAndroid Build Coastguard Worker char uri[HTTP_MAX_URI]; /* Printer URI */
3360*5e7646d2SAndroid Build Coastguard Worker const char *printer, /* Printer name */
3361*5e7646d2SAndroid Build Coastguard Worker *is_class, /* Is a class? */
3362*5e7646d2SAndroid Build Coastguard Worker *shared; /* Sharing value */
3363*5e7646d2SAndroid Build Coastguard Worker
3364*5e7646d2SAndroid Build Coastguard Worker
3365*5e7646d2SAndroid Build Coastguard Worker is_class = cgiGetVariable("IS_CLASS");
3366*5e7646d2SAndroid Build Coastguard Worker printer = cgiGetVariable("PRINTER_NAME");
3367*5e7646d2SAndroid Build Coastguard Worker shared = cgiGetVariable("SHARED");
3368*5e7646d2SAndroid Build Coastguard Worker
3369*5e7646d2SAndroid Build Coastguard Worker if (!printer || !shared)
3370*5e7646d2SAndroid Build Coastguard Worker {
3371*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
3372*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Publishing")));
3373*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang("error.tmpl");
3374*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
3375*5e7646d2SAndroid Build Coastguard Worker return;
3376*5e7646d2SAndroid Build Coastguard Worker }
3377*5e7646d2SAndroid Build Coastguard Worker
3378*5e7646d2SAndroid Build Coastguard Worker /*
3379*5e7646d2SAndroid Build Coastguard Worker * Build a CUPS-Add-Printer/CUPS-Add-Class request, which requires the
3380*5e7646d2SAndroid Build Coastguard Worker * following attributes:
3381*5e7646d2SAndroid Build Coastguard Worker *
3382*5e7646d2SAndroid Build Coastguard Worker * attributes-charset
3383*5e7646d2SAndroid Build Coastguard Worker * attributes-natural-language
3384*5e7646d2SAndroid Build Coastguard Worker * printer-uri
3385*5e7646d2SAndroid Build Coastguard Worker * printer-is-shared
3386*5e7646d2SAndroid Build Coastguard Worker */
3387*5e7646d2SAndroid Build Coastguard Worker
3388*5e7646d2SAndroid Build Coastguard Worker request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER);
3389*5e7646d2SAndroid Build Coastguard Worker
3390*5e7646d2SAndroid Build Coastguard Worker httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
3391*5e7646d2SAndroid Build Coastguard Worker "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
3392*5e7646d2SAndroid Build Coastguard Worker printer);
3393*5e7646d2SAndroid Build Coastguard Worker ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
3394*5e7646d2SAndroid Build Coastguard Worker NULL, uri);
3395*5e7646d2SAndroid Build Coastguard Worker
3396*5e7646d2SAndroid Build Coastguard Worker ippAddBoolean(request, IPP_TAG_OPERATION, "printer-is-shared", (char)atoi(shared));
3397*5e7646d2SAndroid Build Coastguard Worker
3398*5e7646d2SAndroid Build Coastguard Worker /*
3399*5e7646d2SAndroid Build Coastguard Worker * Do the request and get back a response...
3400*5e7646d2SAndroid Build Coastguard Worker */
3401*5e7646d2SAndroid Build Coastguard Worker
3402*5e7646d2SAndroid Build Coastguard Worker if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
3403*5e7646d2SAndroid Build Coastguard Worker {
3404*5e7646d2SAndroid Build Coastguard Worker cgiSetIPPVars(response, NULL, NULL, NULL, 0);
3405*5e7646d2SAndroid Build Coastguard Worker
3406*5e7646d2SAndroid Build Coastguard Worker ippDelete(response);
3407*5e7646d2SAndroid Build Coastguard Worker }
3408*5e7646d2SAndroid Build Coastguard Worker
3409*5e7646d2SAndroid Build Coastguard Worker if (cupsLastError() == IPP_NOT_AUTHORIZED)
3410*5e7646d2SAndroid Build Coastguard Worker {
3411*5e7646d2SAndroid Build Coastguard Worker puts("Status: 401\n");
3412*5e7646d2SAndroid Build Coastguard Worker exit(0);
3413*5e7646d2SAndroid Build Coastguard Worker }
3414*5e7646d2SAndroid Build Coastguard Worker else if (cupsLastError() > IPP_OK_CONFLICT)
3415*5e7646d2SAndroid Build Coastguard Worker {
3416*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Publishing")));
3417*5e7646d2SAndroid Build Coastguard Worker cgiShowIPPError(_("Unable to change printer-is-shared attribute"));
3418*5e7646d2SAndroid Build Coastguard Worker }
3419*5e7646d2SAndroid Build Coastguard Worker else
3420*5e7646d2SAndroid Build Coastguard Worker {
3421*5e7646d2SAndroid Build Coastguard Worker /*
3422*5e7646d2SAndroid Build Coastguard Worker * Redirect successful updates back to the printer page...
3423*5e7646d2SAndroid Build Coastguard Worker */
3424*5e7646d2SAndroid Build Coastguard Worker
3425*5e7646d2SAndroid Build Coastguard Worker char url[1024], /* Printer/class URL */
3426*5e7646d2SAndroid Build Coastguard Worker refresh[1024]; /* Refresh URL */
3427*5e7646d2SAndroid Build Coastguard Worker
3428*5e7646d2SAndroid Build Coastguard Worker
3429*5e7646d2SAndroid Build Coastguard Worker cgiRewriteURL(uri, url, sizeof(url), NULL);
3430*5e7646d2SAndroid Build Coastguard Worker cgiFormEncode(uri, url, sizeof(uri));
3431*5e7646d2SAndroid Build Coastguard Worker snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri);
3432*5e7646d2SAndroid Build Coastguard Worker cgiSetVariable("refresh_page", refresh);
3433*5e7646d2SAndroid Build Coastguard Worker
3434*5e7646d2SAndroid Build Coastguard Worker cgiStartHTML(cgiText(_("Set Publishing")));
3435*5e7646d2SAndroid Build Coastguard Worker cgiCopyTemplateLang(is_class ? "class-modified.tmpl" :
3436*5e7646d2SAndroid Build Coastguard Worker "printer-modified.tmpl");
3437*5e7646d2SAndroid Build Coastguard Worker }
3438*5e7646d2SAndroid Build Coastguard Worker
3439*5e7646d2SAndroid Build Coastguard Worker cgiEndHTML();
3440*5e7646d2SAndroid Build Coastguard Worker }
3441*5e7646d2SAndroid Build Coastguard Worker
3442*5e7646d2SAndroid Build Coastguard Worker
3443*5e7646d2SAndroid Build Coastguard Worker /*
3444*5e7646d2SAndroid Build Coastguard Worker * 'get_option_value()' - Return the value of an option.
3445*5e7646d2SAndroid Build Coastguard Worker *
3446*5e7646d2SAndroid Build Coastguard Worker * This function also handles generation of custom option values.
3447*5e7646d2SAndroid Build Coastguard Worker */
3448*5e7646d2SAndroid Build Coastguard Worker
3449*5e7646d2SAndroid Build Coastguard Worker static char * /* O - Value string or NULL on error */
get_option_value(ppd_file_t * ppd,const char * name,char * buffer,size_t bufsize)3450*5e7646d2SAndroid Build Coastguard Worker get_option_value(
3451*5e7646d2SAndroid Build Coastguard Worker ppd_file_t *ppd, /* I - PPD file */
3452*5e7646d2SAndroid Build Coastguard Worker const char *name, /* I - Option name */
3453*5e7646d2SAndroid Build Coastguard Worker char *buffer, /* I - String buffer */
3454*5e7646d2SAndroid Build Coastguard Worker size_t bufsize) /* I - Size of buffer */
3455*5e7646d2SAndroid Build Coastguard Worker {
3456*5e7646d2SAndroid Build Coastguard Worker char *bufptr, /* Pointer into buffer */
3457*5e7646d2SAndroid Build Coastguard Worker *bufend; /* End of buffer */
3458*5e7646d2SAndroid Build Coastguard Worker ppd_coption_t *coption; /* Custom option */
3459*5e7646d2SAndroid Build Coastguard Worker ppd_cparam_t *cparam; /* Current custom parameter */
3460*5e7646d2SAndroid Build Coastguard Worker char keyword[256]; /* Parameter name */
3461*5e7646d2SAndroid Build Coastguard Worker const char *val, /* Parameter value */
3462*5e7646d2SAndroid Build Coastguard Worker *uval; /* Units value */
3463*5e7646d2SAndroid Build Coastguard Worker long integer; /* Integer value */
3464*5e7646d2SAndroid Build Coastguard Worker double number, /* Number value */
3465*5e7646d2SAndroid Build Coastguard Worker number_points; /* Number in points */
3466*5e7646d2SAndroid Build Coastguard Worker
3467*5e7646d2SAndroid Build Coastguard Worker
3468*5e7646d2SAndroid Build Coastguard Worker /*
3469*5e7646d2SAndroid Build Coastguard Worker * See if we have a custom option choice...
3470*5e7646d2SAndroid Build Coastguard Worker */
3471*5e7646d2SAndroid Build Coastguard Worker
3472*5e7646d2SAndroid Build Coastguard Worker if ((val = cgiGetVariable(name)) == NULL)
3473*5e7646d2SAndroid Build Coastguard Worker {
3474*5e7646d2SAndroid Build Coastguard Worker /*
3475*5e7646d2SAndroid Build Coastguard Worker * Option not found!
3476*5e7646d2SAndroid Build Coastguard Worker */
3477*5e7646d2SAndroid Build Coastguard Worker
3478*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3479*5e7646d2SAndroid Build Coastguard Worker }
3480*5e7646d2SAndroid Build Coastguard Worker else if (_cups_strcasecmp(val, "Custom") ||
3481*5e7646d2SAndroid Build Coastguard Worker (coption = ppdFindCustomOption(ppd, name)) == NULL)
3482*5e7646d2SAndroid Build Coastguard Worker {
3483*5e7646d2SAndroid Build Coastguard Worker /*
3484*5e7646d2SAndroid Build Coastguard Worker * Not a custom choice...
3485*5e7646d2SAndroid Build Coastguard Worker */
3486*5e7646d2SAndroid Build Coastguard Worker
3487*5e7646d2SAndroid Build Coastguard Worker strlcpy(buffer, val, bufsize);
3488*5e7646d2SAndroid Build Coastguard Worker return (buffer);
3489*5e7646d2SAndroid Build Coastguard Worker }
3490*5e7646d2SAndroid Build Coastguard Worker
3491*5e7646d2SAndroid Build Coastguard Worker /*
3492*5e7646d2SAndroid Build Coastguard Worker * OK, we have a custom option choice, format it...
3493*5e7646d2SAndroid Build Coastguard Worker */
3494*5e7646d2SAndroid Build Coastguard Worker
3495*5e7646d2SAndroid Build Coastguard Worker *buffer = '\0';
3496*5e7646d2SAndroid Build Coastguard Worker
3497*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(coption->keyword, "PageSize"))
3498*5e7646d2SAndroid Build Coastguard Worker {
3499*5e7646d2SAndroid Build Coastguard Worker const char *lval; /* Length string value */
3500*5e7646d2SAndroid Build Coastguard Worker double width, /* Width value */
3501*5e7646d2SAndroid Build Coastguard Worker width_points, /* Width in points */
3502*5e7646d2SAndroid Build Coastguard Worker length, /* Length value */
3503*5e7646d2SAndroid Build Coastguard Worker length_points; /* Length in points */
3504*5e7646d2SAndroid Build Coastguard Worker
3505*5e7646d2SAndroid Build Coastguard Worker
3506*5e7646d2SAndroid Build Coastguard Worker val = cgiGetVariable("PageSize.Width");
3507*5e7646d2SAndroid Build Coastguard Worker lval = cgiGetVariable("PageSize.Height");
3508*5e7646d2SAndroid Build Coastguard Worker uval = cgiGetVariable("PageSize.Units");
3509*5e7646d2SAndroid Build Coastguard Worker
3510*5e7646d2SAndroid Build Coastguard Worker if (!val || !lval || !uval ||
3511*5e7646d2SAndroid Build Coastguard Worker (width = strtod(val, NULL)) == 0.0 ||
3512*5e7646d2SAndroid Build Coastguard Worker (length = strtod(lval, NULL)) == 0.0 ||
3513*5e7646d2SAndroid Build Coastguard Worker (strcmp(uval, "pt") && strcmp(uval, "in") && strcmp(uval, "ft") &&
3514*5e7646d2SAndroid Build Coastguard Worker strcmp(uval, "cm") && strcmp(uval, "mm") && strcmp(uval, "m")))
3515*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3516*5e7646d2SAndroid Build Coastguard Worker
3517*5e7646d2SAndroid Build Coastguard Worker width_points = get_points(width, uval);
3518*5e7646d2SAndroid Build Coastguard Worker length_points = get_points(length, uval);
3519*5e7646d2SAndroid Build Coastguard Worker
3520*5e7646d2SAndroid Build Coastguard Worker if (width_points < ppd->custom_min[0] ||
3521*5e7646d2SAndroid Build Coastguard Worker width_points > ppd->custom_max[0] ||
3522*5e7646d2SAndroid Build Coastguard Worker length_points < ppd->custom_min[1] ||
3523*5e7646d2SAndroid Build Coastguard Worker length_points > ppd->custom_max[1])
3524*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3525*5e7646d2SAndroid Build Coastguard Worker
3526*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Custom.%gx%g%s", width, length, uval);
3527*5e7646d2SAndroid Build Coastguard Worker }
3528*5e7646d2SAndroid Build Coastguard Worker else if (cupsArrayCount(coption->params) == 1)
3529*5e7646d2SAndroid Build Coastguard Worker {
3530*5e7646d2SAndroid Build Coastguard Worker cparam = ppdFirstCustomParam(coption);
3531*5e7646d2SAndroid Build Coastguard Worker snprintf(keyword, sizeof(keyword), "%s.%s", coption->keyword, cparam->name);
3532*5e7646d2SAndroid Build Coastguard Worker
3533*5e7646d2SAndroid Build Coastguard Worker if ((val = cgiGetVariable(keyword)) == NULL)
3534*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3535*5e7646d2SAndroid Build Coastguard Worker
3536*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
3537*5e7646d2SAndroid Build Coastguard Worker {
3538*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
3539*5e7646d2SAndroid Build Coastguard Worker break;
3540*5e7646d2SAndroid Build Coastguard Worker
3541*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
3542*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
3543*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
3544*5e7646d2SAndroid Build Coastguard Worker if ((number = strtod(val, NULL)) == 0.0 ||
3545*5e7646d2SAndroid Build Coastguard Worker number < cparam->minimum.custom_real ||
3546*5e7646d2SAndroid Build Coastguard Worker number > cparam->maximum.custom_real)
3547*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3548*5e7646d2SAndroid Build Coastguard Worker
3549*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Custom.%g", number);
3550*5e7646d2SAndroid Build Coastguard Worker break;
3551*5e7646d2SAndroid Build Coastguard Worker
3552*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
3553*5e7646d2SAndroid Build Coastguard Worker if (!*val || (integer = strtol(val, NULL, 10)) == LONG_MIN ||
3554*5e7646d2SAndroid Build Coastguard Worker integer == LONG_MAX ||
3555*5e7646d2SAndroid Build Coastguard Worker integer < cparam->minimum.custom_int ||
3556*5e7646d2SAndroid Build Coastguard Worker integer > cparam->maximum.custom_int)
3557*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3558*5e7646d2SAndroid Build Coastguard Worker
3559*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Custom.%ld", integer);
3560*5e7646d2SAndroid Build Coastguard Worker break;
3561*5e7646d2SAndroid Build Coastguard Worker
3562*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
3563*5e7646d2SAndroid Build Coastguard Worker snprintf(keyword, sizeof(keyword), "%s.Units", coption->keyword);
3564*5e7646d2SAndroid Build Coastguard Worker
3565*5e7646d2SAndroid Build Coastguard Worker if ((number = strtod(val, NULL)) == 0.0 ||
3566*5e7646d2SAndroid Build Coastguard Worker (uval = cgiGetVariable(keyword)) == NULL ||
3567*5e7646d2SAndroid Build Coastguard Worker (strcmp(uval, "pt") && strcmp(uval, "in") && strcmp(uval, "ft") &&
3568*5e7646d2SAndroid Build Coastguard Worker strcmp(uval, "cm") && strcmp(uval, "mm") && strcmp(uval, "m")))
3569*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3570*5e7646d2SAndroid Build Coastguard Worker
3571*5e7646d2SAndroid Build Coastguard Worker number_points = get_points(number, uval);
3572*5e7646d2SAndroid Build Coastguard Worker if (number_points < cparam->minimum.custom_points ||
3573*5e7646d2SAndroid Build Coastguard Worker number_points > cparam->maximum.custom_points)
3574*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3575*5e7646d2SAndroid Build Coastguard Worker
3576*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Custom.%g%s", number, uval);
3577*5e7646d2SAndroid Build Coastguard Worker break;
3578*5e7646d2SAndroid Build Coastguard Worker
3579*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
3580*5e7646d2SAndroid Build Coastguard Worker for (uval = val; *uval; uval ++)
3581*5e7646d2SAndroid Build Coastguard Worker if (!isdigit(*uval & 255))
3582*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3583*5e7646d2SAndroid Build Coastguard Worker
3584*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
3585*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
3586*5e7646d2SAndroid Build Coastguard Worker integer = (long)strlen(val);
3587*5e7646d2SAndroid Build Coastguard Worker if (integer < cparam->minimum.custom_string ||
3588*5e7646d2SAndroid Build Coastguard Worker integer > cparam->maximum.custom_string)
3589*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3590*5e7646d2SAndroid Build Coastguard Worker
3591*5e7646d2SAndroid Build Coastguard Worker snprintf(buffer, bufsize, "Custom.%s", val);
3592*5e7646d2SAndroid Build Coastguard Worker break;
3593*5e7646d2SAndroid Build Coastguard Worker }
3594*5e7646d2SAndroid Build Coastguard Worker }
3595*5e7646d2SAndroid Build Coastguard Worker else
3596*5e7646d2SAndroid Build Coastguard Worker {
3597*5e7646d2SAndroid Build Coastguard Worker const char *prefix = "{"; /* Prefix string */
3598*5e7646d2SAndroid Build Coastguard Worker
3599*5e7646d2SAndroid Build Coastguard Worker
3600*5e7646d2SAndroid Build Coastguard Worker bufptr = buffer;
3601*5e7646d2SAndroid Build Coastguard Worker bufend = buffer + bufsize;
3602*5e7646d2SAndroid Build Coastguard Worker
3603*5e7646d2SAndroid Build Coastguard Worker for (cparam = ppdFirstCustomParam(coption);
3604*5e7646d2SAndroid Build Coastguard Worker cparam;
3605*5e7646d2SAndroid Build Coastguard Worker cparam = ppdNextCustomParam(coption))
3606*5e7646d2SAndroid Build Coastguard Worker {
3607*5e7646d2SAndroid Build Coastguard Worker snprintf(keyword, sizeof(keyword), "%s.%s", coption->keyword,
3608*5e7646d2SAndroid Build Coastguard Worker cparam->name);
3609*5e7646d2SAndroid Build Coastguard Worker
3610*5e7646d2SAndroid Build Coastguard Worker if ((val = cgiGetVariable(keyword)) == NULL)
3611*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3612*5e7646d2SAndroid Build Coastguard Worker
3613*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr), "%s%s=", prefix, cparam->name);
3614*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
3615*5e7646d2SAndroid Build Coastguard Worker prefix = " ";
3616*5e7646d2SAndroid Build Coastguard Worker
3617*5e7646d2SAndroid Build Coastguard Worker switch (cparam->type)
3618*5e7646d2SAndroid Build Coastguard Worker {
3619*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_UNKNOWN :
3620*5e7646d2SAndroid Build Coastguard Worker break;
3621*5e7646d2SAndroid Build Coastguard Worker
3622*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_CURVE :
3623*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INVCURVE :
3624*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_REAL :
3625*5e7646d2SAndroid Build Coastguard Worker if ((number = strtod(val, NULL)) == 0.0 ||
3626*5e7646d2SAndroid Build Coastguard Worker number < cparam->minimum.custom_real ||
3627*5e7646d2SAndroid Build Coastguard Worker number > cparam->maximum.custom_real)
3628*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3629*5e7646d2SAndroid Build Coastguard Worker
3630*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr), "%g", number);
3631*5e7646d2SAndroid Build Coastguard Worker break;
3632*5e7646d2SAndroid Build Coastguard Worker
3633*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_INT :
3634*5e7646d2SAndroid Build Coastguard Worker if (!*val || (integer = strtol(val, NULL, 10)) == LONG_MIN ||
3635*5e7646d2SAndroid Build Coastguard Worker integer == LONG_MAX ||
3636*5e7646d2SAndroid Build Coastguard Worker integer < cparam->minimum.custom_int ||
3637*5e7646d2SAndroid Build Coastguard Worker integer > cparam->maximum.custom_int)
3638*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3639*5e7646d2SAndroid Build Coastguard Worker
3640*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr), "%ld", integer);
3641*5e7646d2SAndroid Build Coastguard Worker break;
3642*5e7646d2SAndroid Build Coastguard Worker
3643*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_POINTS :
3644*5e7646d2SAndroid Build Coastguard Worker snprintf(keyword, sizeof(keyword), "%s.Units", coption->keyword);
3645*5e7646d2SAndroid Build Coastguard Worker
3646*5e7646d2SAndroid Build Coastguard Worker if ((number = strtod(val, NULL)) == 0.0 ||
3647*5e7646d2SAndroid Build Coastguard Worker (uval = cgiGetVariable(keyword)) == NULL ||
3648*5e7646d2SAndroid Build Coastguard Worker (strcmp(uval, "pt") && strcmp(uval, "in") &&
3649*5e7646d2SAndroid Build Coastguard Worker strcmp(uval, "ft") && strcmp(uval, "cm") &&
3650*5e7646d2SAndroid Build Coastguard Worker strcmp(uval, "mm") && strcmp(uval, "m")))
3651*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3652*5e7646d2SAndroid Build Coastguard Worker
3653*5e7646d2SAndroid Build Coastguard Worker number_points = get_points(number, uval);
3654*5e7646d2SAndroid Build Coastguard Worker if (number_points < cparam->minimum.custom_points ||
3655*5e7646d2SAndroid Build Coastguard Worker number_points > cparam->maximum.custom_points)
3656*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3657*5e7646d2SAndroid Build Coastguard Worker
3658*5e7646d2SAndroid Build Coastguard Worker snprintf(bufptr, (size_t)(bufend - bufptr), "%g%s", number, uval);
3659*5e7646d2SAndroid Build Coastguard Worker break;
3660*5e7646d2SAndroid Build Coastguard Worker
3661*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSCODE :
3662*5e7646d2SAndroid Build Coastguard Worker for (uval = val; *uval; uval ++)
3663*5e7646d2SAndroid Build Coastguard Worker if (!isdigit(*uval & 255))
3664*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3665*5e7646d2SAndroid Build Coastguard Worker
3666*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_PASSWORD :
3667*5e7646d2SAndroid Build Coastguard Worker case PPD_CUSTOM_STRING :
3668*5e7646d2SAndroid Build Coastguard Worker integer = (long)strlen(val);
3669*5e7646d2SAndroid Build Coastguard Worker if (integer < cparam->minimum.custom_string ||
3670*5e7646d2SAndroid Build Coastguard Worker integer > cparam->maximum.custom_string)
3671*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3672*5e7646d2SAndroid Build Coastguard Worker
3673*5e7646d2SAndroid Build Coastguard Worker if ((bufptr + 2) > bufend)
3674*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3675*5e7646d2SAndroid Build Coastguard Worker
3676*5e7646d2SAndroid Build Coastguard Worker bufend --;
3677*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\"';
3678*5e7646d2SAndroid Build Coastguard Worker
3679*5e7646d2SAndroid Build Coastguard Worker while (*val && bufptr < bufend)
3680*5e7646d2SAndroid Build Coastguard Worker {
3681*5e7646d2SAndroid Build Coastguard Worker if (*val == '\\' || *val == '\"')
3682*5e7646d2SAndroid Build Coastguard Worker {
3683*5e7646d2SAndroid Build Coastguard Worker if ((bufptr + 1) >= bufend)
3684*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3685*5e7646d2SAndroid Build Coastguard Worker
3686*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\\';
3687*5e7646d2SAndroid Build Coastguard Worker }
3688*5e7646d2SAndroid Build Coastguard Worker
3689*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = *val++;
3690*5e7646d2SAndroid Build Coastguard Worker }
3691*5e7646d2SAndroid Build Coastguard Worker
3692*5e7646d2SAndroid Build Coastguard Worker if (bufptr >= bufend)
3693*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3694*5e7646d2SAndroid Build Coastguard Worker
3695*5e7646d2SAndroid Build Coastguard Worker *bufptr++ = '\"';
3696*5e7646d2SAndroid Build Coastguard Worker *bufptr = '\0';
3697*5e7646d2SAndroid Build Coastguard Worker bufend ++;
3698*5e7646d2SAndroid Build Coastguard Worker break;
3699*5e7646d2SAndroid Build Coastguard Worker }
3700*5e7646d2SAndroid Build Coastguard Worker
3701*5e7646d2SAndroid Build Coastguard Worker bufptr += strlen(bufptr);
3702*5e7646d2SAndroid Build Coastguard Worker }
3703*5e7646d2SAndroid Build Coastguard Worker
3704*5e7646d2SAndroid Build Coastguard Worker if (bufptr == buffer || (bufend - bufptr) < 2)
3705*5e7646d2SAndroid Build Coastguard Worker return (NULL);
3706*5e7646d2SAndroid Build Coastguard Worker
3707*5e7646d2SAndroid Build Coastguard Worker memcpy(bufptr, "}", 2);
3708*5e7646d2SAndroid Build Coastguard Worker }
3709*5e7646d2SAndroid Build Coastguard Worker
3710*5e7646d2SAndroid Build Coastguard Worker return (buffer);
3711*5e7646d2SAndroid Build Coastguard Worker }
3712*5e7646d2SAndroid Build Coastguard Worker
3713*5e7646d2SAndroid Build Coastguard Worker
3714*5e7646d2SAndroid Build Coastguard Worker /*
3715*5e7646d2SAndroid Build Coastguard Worker * 'get_points()' - Get a value in points.
3716*5e7646d2SAndroid Build Coastguard Worker */
3717*5e7646d2SAndroid Build Coastguard Worker
3718*5e7646d2SAndroid Build Coastguard Worker static double /* O - Number in points */
get_points(double number,const char * uval)3719*5e7646d2SAndroid Build Coastguard Worker get_points(double number, /* I - Original number */
3720*5e7646d2SAndroid Build Coastguard Worker const char *uval) /* I - Units */
3721*5e7646d2SAndroid Build Coastguard Worker {
3722*5e7646d2SAndroid Build Coastguard Worker if (!strcmp(uval, "mm")) /* Millimeters */
3723*5e7646d2SAndroid Build Coastguard Worker return (number * 72.0 / 25.4);
3724*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(uval, "cm")) /* Centimeters */
3725*5e7646d2SAndroid Build Coastguard Worker return (number * 72.0 / 2.54);
3726*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(uval, "in")) /* Inches */
3727*5e7646d2SAndroid Build Coastguard Worker return (number * 72.0);
3728*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(uval, "ft")) /* Feet */
3729*5e7646d2SAndroid Build Coastguard Worker return (number * 72.0 * 12.0);
3730*5e7646d2SAndroid Build Coastguard Worker else if (!strcmp(uval, "m")) /* Meters */
3731*5e7646d2SAndroid Build Coastguard Worker return (number * 72.0 / 0.0254);
3732*5e7646d2SAndroid Build Coastguard Worker else /* Points */
3733*5e7646d2SAndroid Build Coastguard Worker return (number);
3734*5e7646d2SAndroid Build Coastguard Worker }
3735