*
* Administration CGI for the Common UNIX Printing System (CUPS).
*
- * Copyright 2007-2008 by Apple Inc.
+ * Copyright 2007-2010 by Apple Inc.
* Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
* Local globals...
*/
-static int current_device; /* Current device for add/modify */
-static time_t last_device_time; /* Last update time for device list */
+static int current_device = 0; /* Current device shown */
/*
*/
cgiSetVariable("SECTION", "admin");
+ cgiSetVariable("REFRESH_PAGE", "");
/*
* See if we have form data...
}
else if (op && !strcmp(op, "redirect"))
{
- const char *url; /* Redirection URL... */
+ const char *url; /* Redirection URL... */
char prefix[1024]; /* URL prefix */
fprintf(stderr, "DEBUG: redirecting with prefix %s!\n", prefix);
if ((url = cgiGetVariable("URL")) != NULL)
- printf("Location: %s%s\n\n", prefix, url);
+ {
+ char encoded[1024], /* Encoded URL string */
+ *ptr; /* Pointer into encoded string */
+
+
+ ptr = encoded;
+ if (*url != '/')
+ *ptr++ = '/';
+
+ for (; *url && ptr < (encoded + sizeof(encoded) - 4); url ++)
+ {
+ if (strchr("%@&+ <>#=", *url) || *url < ' ' || *url & 128)
+ {
+ /*
+ * Percent-encode this character; safe because we have at least 4
+ * bytes left in the array...
+ */
+
+ sprintf(ptr, "%%%02X", *url & 255);
+ ptr += 3;
+ }
+ else
+ *ptr++ = *url;
+ }
+
+ *ptr = '\0';
+
+ if (*url)
+ {
+ /*
+ * URL was too long, just redirect to the admin page...
+ */
+
+ printf("Location: %s/admin\n\n", prefix);
+ }
+ else
+ {
+ /*
+ * URL is OK, redirect there...
+ */
+
+ printf("Location: %s%s\n\n", prefix, encoded);
+ }
+ }
else
printf("Location: %s/admin\n\n", prefix);
}
const char *device_location, /* I - Location */
const char *title) /* I - Page title */
{
+ /*
+ * For modern browsers, start a multi-part page so we can show that something
+ * is happening. Non-modern browsers just get everything at the end...
+ */
+
+ if (current_device == 0 && cgiSupportsMultipart())
+ {
+ cgiStartMultipart();
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("choose-device.tmpl");
+ cgiEndHTML();
+ fflush(stdout);
+ }
+
+
/*
* Add the device to the array...
*/
cgiSetArray("device_location", current_device, device_location);
current_device ++;
-
- if (time(NULL) > last_device_time)
- {
- /*
- * Update the page...
- */
-
- if (!last_device_time)
- cgiStartMultipart();
-
- cgiStartHTML(title);
- cgiCopyTemplateLang("choose-device.tmpl");
- cgiEndHTML();
- fflush(stdout);
-
- time(&last_device_time);
- }
}
* and classes and (re)show the add page...
*/
+ if (cgiGetVariable("EVENT_JOB_CREATED"))
+ cgiSetVariable("EVENT_JOB_CREATED", "CHECKED");
+ if (cgiGetVariable("EVENT_JOB_COMPLETED"))
+ cgiSetVariable("EVENT_JOB_COMPLETED", "CHECKED");
+ if (cgiGetVariable("EVENT_JOB_STOPPED"))
+ cgiSetVariable("EVENT_JOB_STOPPED", "CHECKED");
+ if (cgiGetVariable("EVENT_JOB_CONFIG_CHANGED"))
+ cgiSetVariable("EVENT_JOB_CONFIG_CHANGED", "CHECKED");
+ if (cgiGetVariable("EVENT_PRINTER_STOPPED"))
+ cgiSetVariable("EVENT_PRINTER_STOPPED", "CHECKED");
+ if (cgiGetVariable("EVENT_PRINTER_ADDED"))
+ cgiSetVariable("EVENT_PRINTER_ADDED", "CHECKED");
+ if (cgiGetVariable("EVENT_PRINTER_MODIFIED"))
+ cgiSetVariable("EVENT_PRINTER_MODIFIED", "CHECKED");
+ if (cgiGetVariable("EVENT_PRINTER_DELETED"))
+ cgiSetVariable("EVENT_PRINTER_DELETED", "CHECKED");
+ if (cgiGetVariable("EVENT_SERVER_STARTED"))
+ cgiSetVariable("EVENT_SERVER_STARTED", "CHECKED");
+ if (cgiGetVariable("EVENT_SERVER_STOPPED"))
+ cgiSetVariable("EVENT_SERVER_STOPPED", "CHECKED");
+ if (cgiGetVariable("EVENT_SERVER_RESTARTED"))
+ cgiSetVariable("EVENT_SERVER_RESTARTED", "CHECKED");
+ if (cgiGetVariable("EVENT_SERVER_AUDIT"))
+ cgiSetVariable("EVENT_SERVER_AUDIT", "CHECKED");
+
request = ippNewRequest(CUPS_GET_PRINTERS);
response = cupsDoRequest(http, request, "/");
ipp_attribute_t *attr; /* member-uris attribute */
char uri[HTTP_MAX_URI]; /* Device or printer URI */
const char *name, /* Pointer to class name */
+ *op, /* Operation name */
*ptr; /* Pointer to CGI variable */
const char *title; /* Title of page */
static const char * const pattrs[] = /* Requested printer attributes */
title = cgiText(modify ? _("Modify Class") : _("Add Class"));
+ op = cgiGetVariable("OP");
name = cgiGetVariable("PRINTER_NAME");
if (cgiGetVariable("PRINTER_LOCATION") == NULL)
request = ippNewRequest(CUPS_GET_PRINTERS);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type",
+ CUPS_PRINTER_LOCAL);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM, "printer-type-mask",
+ CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE |
+ CUPS_PRINTER_IMPLICIT);
+
/*
* Do the request and get back a response...
*/
+ cgiClearVariables();
+ if (op)
+ cgiSetVariable("OP", op);
+ if (name)
+ cgiSetVariable("PRINTER_NAME", name);
+
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
/*
return;
}
+ if (!name)
+ {
+ cgiStartHTML(title);
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
+ }
+
for (ptr = name; *ptr; ptr ++)
if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' || *ptr == '#')
break;
request = ippNewRequest(CUPS_ADD_CLASS);
httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/classes/%s",
- cgiGetVariable("PRINTER_NAME"));
+ "localhost", 0, "/classes/%s", name);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
if (isalnum(*uriptr & 255) || *uriptr == '_' || *uriptr == '-' ||
*uriptr == '.')
*tptr++ = *uriptr;
- else if ((*uriptr == ' ' || *uriptr == '/') && tptr[-1] != '_')
+ else if ((*uriptr == ' ' || *uriptr == '/') && tptr > template &&
+ tptr[-1] != '_')
*tptr++ = '_';
else if (*uriptr == '?' || *uriptr == '(')
break;
}
/*
- * Scan for devices for up to 30 seconds, updating the page as we find
- * them...
+ * Scan for devices for up to 30 seconds...
*/
fputs("DEBUG: Getting list of devices...\n", stderr);
- last_device_time = 0;
- current_device = 0;
+ current_device = 0;
if (cupsGetDevices(http, 30, CUPS_INCLUDE_ALL, CUPS_EXCLUDE_NONE,
(cups_device_cb_t)choose_device_cb,
(void *)title) == IPP_OK)
+ {
fputs("DEBUG: Got device list!\n", stderr);
+
+ if (cgiSupportsMultipart())
+ cgiStartMultipart();
+
+ cgiSetVariable("CUPS_GET_DEVICES_DONE", "1");
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("choose-device.tmpl");
+ cgiEndHTML();
+
+ if (cgiSupportsMultipart())
+ cgiEndMultipart();
+ }
else
{
fprintf(stderr,
return;
}
}
-
- /*
- * Show the final selection page...
- */
-
- cgiSetVariable("CUPS_GET_DEVICES_DONE", "1");
- cgiStartHTML(title);
- cgiCopyTemplateLang("choose-device.tmpl");
- cgiEndHTML();
- cgiEndMultipart();
}
else if (strchr(var, '/') == NULL)
{
if ((attr = ippFindAttribute(oldinfo, "printer-location",
IPP_TAG_TEXT)) != NULL)
cgiSetVariable("PRINTER_LOCATION", attr->values[0].string.text);
+
+ if ((attr = ippFindAttribute(oldinfo, "printer-is-shared",
+ IPP_TAG_BOOLEAN)) != NULL)
+ cgiSetVariable("PRINTER_IS_SHARED",
+ attr->values[0].boolean ? "1" : "0");
}
cgiCopyTemplateLang("modify-printer.tmpl");
return;
}
- else if (!file && !cgiGetVariable("PPD_NAME"))
+ else if (!file &&
+ (!cgiGetVariable("PPD_NAME") || cgiGetVariable("SELECT_MAKE")))
{
- if (modify)
+ if (modify && !cgiGetVariable("SELECT_MAKE"))
{
/*
* Get the PPD file...
if (get_status != HTTP_OK)
{
+ httpFlush(http);
+
fprintf(stderr, "ERROR: Unable to get PPD file %s: %d - %s\n",
uri, get_status, httpStatus(get_status));
}
if ((var = cgiGetVariable("CURRENT_MAKE")) == NULL)
var = cgiGetVariable("PPD_MAKE");
- if (var)
+ if (var && !cgiGetVariable("SELECT_MAKE"))
{
const char *make_model; /* Make and model */
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
"ppd-make", NULL, var);
- if ((make_model = cgiGetVariable("CURRENT_MAKE_AND_MODEL")) != NULL &&
- !cgiGetVariable("SELECT_MAKE"))
+ if ((make_model = cgiGetVariable("CURRENT_MAKE_AND_MODEL")) != NULL)
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT,
"ppd-make-and-model", NULL, make_model);
}
* Got the list of PPDs, see if the user has selected a make...
*/
- if (cgiSetIPPVars(response, NULL, NULL, NULL, 0) == 0)
+ if (cgiSetIPPVars(response, NULL, NULL, NULL, 0) == 0 && !modify)
{
/*
* No PPD files with this make, try again with all makes...
*/
cgiStartHTML(title);
- cgiSetVariable("CURRENT_MAKE_AND_MODEL",
- cgiGetArray("PPD_MAKE_AND_MODEL", 0));
+ if (!cgiGetVariable("PPD_MAKE"))
+ cgiSetVariable("PPD_MAKE", cgiGetVariable("CURRENT_MAKE"));
+ if (!modify)
+ cgiSetVariable("CURRENT_MAKE_AND_MODEL",
+ cgiGetArray("PPD_MAKE_AND_MODEL", 0));
cgiCopyTemplateLang("choose-model.tmpl");
cgiEndHTML();
}
if (id <= 0)
{
- cgiSetVariable("ERROR", cgiText(_("Bad subscription ID!")));
+ cgiSetVariable("ERROR", cgiText(_("Bad subscription ID")));
cgiStartHTML(_("Cancel RSS Subscription"));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
*share_printers,/* SHARE_PRINTERS value */
*user_cancel_any,
/* USER_CANCEL_ANY value */
- *browse_web_if, /* BrowseWebIF value */
- *preserve_job_history,
+ *browse_web_if = NULL,
+ /* BrowseWebIF value */
+ *preserve_job_history = NULL,
/* PreserveJobHistory value */
- *preserve_job_files,
+ *preserve_job_files = NULL,
/* PreserveJobFiles value */
- *max_clients, /* MaxClients value */
- *max_jobs, /* MaxJobs value */
- *max_log_size; /* MaxLogSize value */
+ *max_clients = NULL,
+ /* MaxClients value */
+ *max_jobs = NULL,
+ /* MaxJobs value */
+ *max_log_size = NULL;
+ /* MaxLogSize value */
char local_protocols[255],
/* BrowseLocalProtocols */
remote_protocols[255];
#ifdef HAVE_GSSAPI
char default_auth_type[255];
/* DefaultAuthType value */
- const char *val; /* Setting value */
+ const char *val; /* Setting value */
#endif /* HAVE_GSSAPI */
strcat(local_protocols, "slp");
}
#endif /* HAVE_SLP */
-
+
if (cgiGetVariable("BROWSE_REMOTE_CUPS"))
strcpy(remote_protocols, "cups");
else
cgiSetVariable("ERROR", strerror(errno));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
-
+
perror(tempfile);
return;
}
cgiSetVariable("ERROR", strerror(errno));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
-
+
perror(tempfile);
close(tempfd);
unlink(tempfile);
cgiText(_("Unable to access cupsd.conf file:")));
cgiSetVariable("ERROR",
cgiText(_("Unable to edit cupsd.conf files larger than "
- "1MB!")));
+ "1MB")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
else
{
cgiStartHTML(cgiText(_("Delete Class")));
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
return;
else
{
cgiStartHTML(cgiText(_("Delete Printer")));
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
return;
else if (username && !*username)
cgiSetVariable("ERROR",
cgiText(_("A Samba username is required to export "
- "printer drivers!")));
+ "printer drivers")));
else if (username && (!password || !*password))
cgiSetVariable("ERROR",
cgiText(_("A Samba password is required to export "
- "printer drivers!")));
+ "printer drivers")));
/*
* Show form...
if ((val = cupsGetOption("DefaultAuthType", num_settings,
settings)) != NULL && !strcasecmp(val, "Negotiate"))
cgiSetVariable("KERBEROS", "CHECKED");
+ else
#endif /* HAVE_GSSAPI */
+ cgiSetVariable("KERBEROS", "");
#ifdef HAVE_DNSSD
cgiSetVariable("HAVE_DNSSD", "1");
if (!printer)
{
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
cgiStartHTML(cgiText(_("Set Allowed Users")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
if (!printer)
{
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
cgiStartHTML(title);
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
printer);
else
{
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
cgiStartHTML(title);
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
for (option = ppdFirstOption(ppd);
option;
option = ppdNextOption(ppd))
+ {
if ((var = cgiGetVariable(option->keyword)) != NULL)
{
have_options = 1;
ppdMarkOption(ppd, option->keyword, var);
+ fprintf(stderr, "DEBUG: Set %s to %s...\n", option->keyword, var);
}
+ else
+ fprintf(stderr, "DEBUG: Didn't find %s...\n", option->keyword);
+ }
}
if (!have_options || ppdConflicts(ppd))
((ppdattr = ppdFindAttr(ppd, "cupsCommands", NULL)) != NULL &&
ppdattr->value && strstr(ppdattr->value, "AutoConfigure")))
cgiSetVariable("HAVE_AUTOCONFIGURE", "YES");
- else
+ else
{
for (i = 0; i < ppd->num_filters; i ++)
if (!strncmp(ppd->filters[i], "application/vnd.cups-postscript", 31))
{
cgiSetArray("ckeyword", k, option->keyword);
cgiSetArray("ckeytext", k, option->text);
+
+ for (m = 0; m < option->num_choices; m ++)
+ {
+ if (option->choices[m].marked)
+ {
+ cgiSetArray("cchoice", k, option->choices[m].text);
+ break;
+ }
+ }
+
k ++;
}
cgiSetVariable("GROUP", group->text);
cgiCopyTemplateLang("option-header.tmpl");
-
+
for (j = group->num_options, option = group->options;
j > 0;
j --, option ++)
if (!printer || !shared)
{
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable")));
cgiStartHTML(cgiText(_("Set Publishing")));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
snprintf(buffer, bufsize, "Custom.%gx%g%s", width, length, uval);
}
- else if (cupsArrayCount(coption->params) == 1)
+ else if (cupsArrayCount(coption->params) == 1)
{
cparam = ppdFirstCustomParam(coption);
snprintf(keyword, sizeof(keyword), "%s.%s", coption->keyword, cparam->name);