/*
- * "$Id: admin.c 5572 2006-05-22 18:47:09Z mike $"
+ * "$Id: admin.c 6649 2007-07-11 21:46:42Z mike $"
*
* Administration CGI for the Common UNIX Printing System (CUPS).
*
- * Copyright 1997-2006 by Easy Software Products.
+ * Copyright 2007 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products.
*
* These coded instructions, statements, and computer programs are the
- * property of Easy Software Products and are protected by Federal
- * copyright law. Distribution and use rights are outlined in the file
- * "LICENSE.txt" which should have been included with this file. If this
- * file is missing or damaged please contact Easy Software Products
- * at:
- *
- * Attn: CUPS Licensing Information
- * Easy Software Products
- * 44141 Airport View Drive, Suite 204
- * Hollywood, Maryland 20636 USA
- *
- * Voice: (301) 373-9600
- * EMail: cups-info@cups.org
- * WWW: http://www.cups.org
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*
* Contents:
*
* main() - Main entry for CGI.
+ * do_add_rss_subscription() - Add a RSS subscription.
* do_am_class() - Add or modify a class.
* do_am_printer() - Add or modify a printer.
- * do_config_printer() - Configure the default options for a printer.
+ * do_cancel_subscription() - Cancel a subscription.
* do_config_server() - Configure server settings.
* do_delete_class() - Delete a class...
* do_delete_printer() - Delete a printer...
* do_export() - Export printers to Samba...
+ * do_list_printers() - List available printers...
* do_menu() - Show the main menu...
* do_printer_op() - Do a printer operation.
* do_set_allowed_users() - Set the allowed/denied users for a queue.
+ * do_set_options() - Configure the default options for a queue.
* do_set_sharing() - Set printer-is-shared value...
* match_string() - Return the number of matching characters.
*/
* Local functions...
*/
+static void do_add_rss_subscription(http_t *http);
static void do_am_class(http_t *http, int modify);
static void do_am_printer(http_t *http, int modify);
-static void do_config_printer(http_t *http);
+static void do_cancel_subscription(http_t *http);
+static void do_set_options(http_t *http, int is_class);
static void do_config_server(http_t *http);
static void do_delete_class(http_t *http);
static void do_delete_printer(http_t *http);
static void do_export(http_t *http);
+static void do_list_printers(http_t *http);
static void do_menu(http_t *http);
static void do_printer_op(http_t *http,
ipp_op_t op, const char *title);
do_printer_op(http, CUPS_SET_DEFAULT, cgiText(_("Set As Default")));
else if (!strcmp(op, "set-sharing"))
do_set_sharing(http);
+ else if (!strcmp(op, "list-available-printers"))
+ do_list_printers(http);
else if (!strcmp(op, "add-class"))
do_am_class(http, 0);
else if (!strcmp(op, "add-printer"))
do_delete_class(http);
else if (!strcmp(op, "delete-printer"))
do_delete_printer(http);
+ else if (!strcmp(op, "set-class-options"))
+ do_set_options(http, 1);
else if (!strcmp(op, "set-printer-options"))
- do_config_printer(http);
+ do_set_options(http, 0);
else if (!strcmp(op, "config-server"))
do_config_server(http);
else if (!strcmp(op, "export-samba"))
do_export(http);
+ else if (!strcmp(op, "add-rss-subscription"))
+ do_add_rss_subscription(http);
+ else if (!strcmp(op, "cancel-subscription"))
+ do_cancel_subscription(http);
else
{
/*
}
+/*
+ * 'do_add_rss_subscription()' - Add a RSS subscription.
+ */
+
+static void
+do_add_rss_subscription(http_t *http) /* I - HTTP connection */
+{
+ ipp_t *request, /* IPP request data */
+ *response; /* IPP response data */
+ char rss_uri[1024]; /* RSS notify-recipient URI */
+ int num_events; /* Number of events */
+ const char *events[12], /* Subscribed events */
+ *subscription_name, /* Subscription name */
+ *printer_uri, /* Printer URI */
+ *ptr, /* Pointer into name */
+ *user; /* Username */
+ int max_events; /* Maximum number of events */
+
+
+ /*
+ * See if we have all of the required information...
+ */
+
+ subscription_name = cgiGetVariable("SUBSCRIPTION_NAME");
+ printer_uri = cgiGetVariable("PRINTER_URI");
+ num_events = 0;
+
+ if (cgiGetVariable("EVENT_JOB_CREATED"))
+ events[num_events ++] = "job-created";
+ if (cgiGetVariable("EVENT_JOB_COMPLETED"))
+ events[num_events ++] = "job-completed";
+ if (cgiGetVariable("EVENT_JOB_STOPPED"))
+ events[num_events ++] = "job-stopped";
+ if (cgiGetVariable("EVENT_JOB_CONFIG_CHANGED"))
+ events[num_events ++] = "job-config-changed";
+ if (cgiGetVariable("EVENT_PRINTER_STOPPED"))
+ events[num_events ++] = "printer-stopped";
+ if (cgiGetVariable("EVENT_PRINTER_ADDED"))
+ events[num_events ++] = "printer-added";
+ if (cgiGetVariable("EVENT_PRINTER_MODIFIED"))
+ events[num_events ++] = "printer-modified";
+ if (cgiGetVariable("EVENT_PRINTER_DELETED"))
+ events[num_events ++] = "printer-deleted";
+ if (cgiGetVariable("EVENT_SERVER_STARTED"))
+ events[num_events ++] = "server-started";
+ if (cgiGetVariable("EVENT_SERVER_STOPPED"))
+ events[num_events ++] = "server-stopped";
+ if (cgiGetVariable("EVENT_SERVER_RESTARTED"))
+ events[num_events ++] = "server-restarted";
+ if (cgiGetVariable("EVENT_SERVER_AUDIT"))
+ events[num_events ++] = "server-audit";
+
+ if ((ptr = cgiGetVariable("MAX_EVENTS")) != NULL)
+ max_events = atoi(ptr);
+ else
+ max_events = 0;
+
+ if (!subscription_name || !printer_uri || !num_events ||
+ max_events <= 0 || max_events > 9999)
+ {
+ /*
+ * Don't have everything we need, so get the available printers
+ * and classes and (re)show the add page...
+ */
+
+ request = ippNewRequest(CUPS_GET_PRINTERS);
+ response = cupsDoRequest(http, request, "/");
+
+ cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+
+ ippDelete(response);
+
+ cgiStartHTML(cgiText(_("Add RSS Subscription")));
+
+ cgiCopyTemplateLang("add-rss-subscription.tmpl");
+
+ cgiEndHTML();
+ return;
+ }
+
+ /*
+ * Validate the subscription name...
+ */
+
+ for (ptr = subscription_name; *ptr; ptr ++)
+ if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/' ||
+ *ptr == '?' || *ptr == '#')
+ break;
+
+ if (*ptr)
+ {
+ cgiSetVariable("ERROR",
+ cgiText(_("The subscription name may not "
+ "contain spaces, slashes (/), question marks (?), "
+ "or the pound sign (#).")));
+ cgiStartHTML(_("Add RSS Subscription"));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
+ }
+
+ /*
+ * Add the subscription...
+ */
+
+ ptr = subscription_name + strlen(subscription_name) - 4;
+ if (ptr < subscription_name || strcmp(ptr, ".rss"))
+ httpAssembleURIf(HTTP_URI_CODING_ALL, rss_uri, sizeof(rss_uri), "rss",
+ NULL, NULL, 0, "/%s.rss?max_events=%d", subscription_name,
+ max_events);
+ else
+ httpAssembleURIf(HTTP_URI_CODING_ALL, rss_uri, sizeof(rss_uri), "rss",
+ NULL, NULL, 0, "/%s?max_events=%d", subscription_name,
+ max_events);
+
+ request = ippNewRequest(IPP_CREATE_PRINTER_SUBSCRIPTION);
+
+ if (!strcasecmp(printer_uri, "#ALL#"))
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/");
+ else
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, printer_uri);
+
+ if ((user = getenv("REMOTE_USER")) == NULL)
+ user = "guest";
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, user);
+
+ ippAddString(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_URI,
+ "notify-recipient-uri", NULL, rss_uri);
+ ippAddStrings(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_KEYWORD, "notify-events",
+ num_events, NULL, events);
+ ippAddInteger(request, IPP_TAG_SUBSCRIPTION, IPP_TAG_INTEGER,
+ "notify-lease-duration", 0);
+
+ ippDelete(cupsDoRequest(http, request, "/"));
+
+ if (cupsLastError() > IPP_OK_CONFLICT)
+ {
+ cgiStartHTML(_("Add RSS Subscription"));
+ cgiShowIPPError(_("Unable to add RSS subscription:"));
+ }
+ else
+ {
+ /*
+ * Redirect successful updates back to the admin page...
+ */
+
+ cgiSetVariable("refresh_page", "5;URL=/admin");
+ cgiStartHTML(_("Add RSS Subscription"));
+ cgiCopyTemplateLang("subscription-added.tmpl");
+ }
+
+ cgiEndHTML();
+}
+
+
/*
* 'do_am_class()' - Add or modify a class.
*/
*
* attributes-charset
* attributes-natural-language
- * printer-uri
*/
request = ippNewRequest(CUPS_GET_PRINTERS);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, "ipp://localhost/printers");
-
/*
* Do the request and get back a response...
*/
* Do the request and get back a response...
*/
- fprintf(stderr, "DEBUG: http=%p (%s)\n", http, http->hostname);
-
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
fputs("DEBUG: Got device list!\n", stderr);
/*
- * 'do_config_printer()' - Configure the default options for a printer.
+ * 'do_cancel_subscription()' - Cancel a subscription.
*/
static void
-do_config_printer(http_t *http) /* I - HTTP connection */
+do_cancel_subscription(http_t *http)/* I - HTTP connection */
{
- int i, j, k, m; /* Looping vars */
- int have_options; /* Have options? */
- ipp_t *request, /* IPP request */
- *response; /* IPP response */
- ipp_attribute_t *attr; /* IPP attribute */
- char uri[HTTP_MAX_URI]; /* Job URI */
- const char *var; /* Variable value */
- const char *printer; /* Printer printer name */
- const char *filename; /* PPD filename */
- char tempfile[1024]; /* Temporary filename */
- cups_file_t *in, /* Input file */
- *out; /* Output file */
- char line[1024]; /* Line from PPD file */
- char keyword[1024], /* Keyword from Default line */
- *keyptr; /* Pointer into keyword... */
- ppd_file_t *ppd; /* PPD file */
- ppd_group_t *group; /* Option group */
- ppd_option_t *option; /* Option */
- ppd_attr_t *protocol; /* cupsProtocol attribute */
- const char *title; /* Page title */
-
+ ipp_t *request; /* IPP request data */
+ const char *var, /* Form variable */
+ *user; /* Username */
+ int id; /* Subscription ID */
- title = cgiText(_("Set Printer Options"));
-
- fprintf(stderr, "DEBUG: do_config_printer(http=%p)\n", http);
/*
- * Get the printer name...
+ * See if we have all of the required information...
*/
- if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s", printer);
+ if ((var = cgiGetVariable("NOTIFY_SUBSCRIPTION_ID")) != NULL)
+ id = atoi(var);
else
+ id = 0;
+
+ if (id <= 0)
{
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
- cgiStartHTML(title);
+ cgiSetVariable("ERROR", cgiText(_("Bad subscription ID!")));
+ cgiStartHTML(_("Cancel RSS Subscription"));
cgiCopyTemplateLang("error.tmpl");
cgiEndHTML();
return;
}
- fprintf(stderr, "DEBUG: printer=\"%s\", uri=\"%s\"...\n", printer, uri);
-
/*
- * Get the PPD file...
+ * Cancel the subscription...
*/
- if ((filename = cupsGetPPD2(http, printer)) == NULL)
- {
- fputs("DEBUG: No PPD file!?!\n", stderr);
+ request = ippNewRequest(IPP_CANCEL_SUBSCRIPTION);
- cgiStartHTML(title);
- cgiShowIPPError(_("Unable to get PPD file!"));
- cgiEndHTML();
- return;
- }
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/");
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER,
+ "notify-subscription-id", id);
+
+ if ((user = getenv("REMOTE_USER")) == NULL)
+ user = "guest";
- fprintf(stderr, "DEBUG: Got PPD file: \"%s\"\n", filename);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+ NULL, user);
- if ((ppd = ppdOpenFile(filename)) == NULL)
+ ippDelete(cupsDoRequest(http, request, "/"));
+
+ if (cupsLastError() > IPP_OK_CONFLICT)
{
- cgiSetVariable("ERROR", ppdErrorString(ppdLastError(&i)));
- cgiSetVariable("MESSAGE", cgiText(_("Unable to open PPD file:")));
- cgiStartHTML(title);
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
- return;
+ cgiStartHTML(_("Cancel RSS Subscription"));
+ cgiShowIPPError(_("Unable to cancel RSS subscription:"));
}
-
- if (cgiGetVariable("job_sheets_start") != NULL ||
- cgiGetVariable("job_sheets_end") != NULL)
- have_options = 1;
else
- have_options = 0;
+ {
+ /*
+ * Redirect successful updates back to the admin page...
+ */
+
+ cgiSetVariable("refresh_page", "5;URL=/admin");
+ cgiStartHTML(_("Cancel RSS Subscription"));
+ cgiCopyTemplateLang("subscription-canceled.tmpl");
+ }
- ppdMarkDefaults(ppd);
+ cgiEndHTML();
+}
- DEBUG_printf(("<P>ppd->num_groups = %d\n"
- "<UL>\n", ppd->num_groups));
- for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
- {
- DEBUG_printf(("<LI>%s<UL>\n", group->text));
+/*
+ * 'do_config_server()' - Configure server settings.
+ */
- for (j = group->num_options, option = group->options;
- j > 0;
- j --, option ++)
- if ((var = cgiGetVariable(option->keyword)) != NULL)
- {
- DEBUG_printf(("<LI>%s = \"%s\"</LI>\n", option->keyword, var));
- have_options = 1;
- ppdMarkOption(ppd, option->keyword, var);
- }
-#ifdef DEBUG
- else
- printf("<LI>%s not defined!</LI>\n", option->keyword);
-#endif /* DEBUG */
+static void
+do_config_server(http_t *http) /* I - HTTP connection */
+{
+ if (cgiIsPOST() && !cgiGetVariable("CUPSDCONF"))
+ {
+ /*
+ * Save basic setting changes...
+ */
- DEBUG_puts("</UL></LI>");
- }
+ int num_settings; /* Number of server settings */
+ cups_option_t *settings; /* Server settings */
+ const char *debug_logging, /* DEBUG_LOGGING value */
+ *remote_admin, /* REMOTE_ADMIN value */
+ *remote_any, /* REMOTE_ANY value */
+ *remote_printers,
+ /* REMOTE_PRINTERS value */
+ *share_printers,/* SHARE_PRINTERS value */
+#ifdef HAVE_GSSAPI
+ *default_auth_type,
+ /* DefaultAuthType value */
+#endif /* HAVE_GSSAPI */
+ *user_cancel_any;
+ /* USER_CANCEL_ANY value */
- DEBUG_printf(("</UL>\n"
- "<P>ppdConflicts(ppd) = %d\n", ppdConflicts(ppd)));
- if (!have_options || ppdConflicts(ppd))
- {
/*
- * Show the options to the user...
+ * Get the checkbox values from the form...
*/
- fputs("DEBUG: Showing options...\n", stderr);
+ debug_logging = cgiGetVariable("DEBUG_LOGGING") ? "1" : "0";
+ remote_admin = cgiGetVariable("REMOTE_ADMIN") ? "1" : "0";
+ remote_any = cgiGetVariable("REMOTE_ANY") ? "1" : "0";
+ remote_printers = cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0";
+ share_printers = cgiGetVariable("SHARE_PRINTERS") ? "1" : "0";
+ user_cancel_any = cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0";
+#ifdef HAVE_GSSAPI
+ default_auth_type = cgiGetVariable("KERBEROS") ? "Negotiate" : "Basic";
- ppdLocalize(ppd);
+ fprintf(stderr, "DEBUG: DefaultAuthType %s\n", default_auth_type);
+#endif /* HAVE_GSSAPI */
- cgiStartHTML(cgiText(_("Set Printer Options")));
- cgiCopyTemplateLang("set-printer-options-header.tmpl");
+ /*
+ * Get the current server settings...
+ */
- if (ppdConflicts(ppd))
+ if (!cupsAdminGetServerSettings(http, &num_settings, &settings))
{
- for (i = ppd->num_groups, k = 0, group = ppd->groups;
- i > 0;
- i --, group ++)
- for (j = group->num_options, option = group->options;
- j > 0;
- j --, option ++)
- if (option->conflicted)
- {
- cgiSetArray("ckeyword", k, option->keyword);
- cgiSetArray("ckeytext", k, option->text);
- k ++;
- }
-
- cgiCopyTemplateLang("option-conflict.tmpl");
+ cgiStartHTML(cgiText(_("Change Settings")));
+ cgiSetVariable("MESSAGE",
+ cgiText(_("Unable to change server settings:")));
+ cgiSetVariable("ERROR", cupsLastErrorString());
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
}
- for (i = ppd->num_groups, group = ppd->groups;
- i > 0;
- i --, group ++)
+ /*
+ * See if the settings have changed...
+ */
+
+ if (strcmp(debug_logging, cupsGetOption(CUPS_SERVER_DEBUG_LOGGING,
+ num_settings, settings)) ||
+ strcmp(remote_admin, cupsGetOption(CUPS_SERVER_REMOTE_ADMIN,
+ num_settings, settings)) ||
+ strcmp(remote_any, cupsGetOption(CUPS_SERVER_REMOTE_ANY,
+ num_settings, settings)) ||
+ strcmp(remote_printers, cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS,
+ num_settings, settings)) ||
+ strcmp(share_printers, cupsGetOption(CUPS_SERVER_SHARE_PRINTERS,
+ num_settings, settings)) ||
+#ifdef HAVE_GSSAPI
+ !cupsGetOption("DefaultAuthType", num_settings, settings) ||
+ strcmp(default_auth_type, cupsGetOption("DefaultAuthType",
+ num_settings, settings)) ||
+#endif /* HAVE_GSSAPI */
+ strcmp(user_cancel_any, cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY,
+ num_settings, settings)))
{
- if (!strcmp(group->name, "InstallableOptions"))
- cgiSetVariable("GROUP", cgiText(_("Options Installed")));
- else
- cgiSetVariable("GROUP", group->text);
+ /*
+ * Settings *have* changed, so save the changes...
+ */
- cgiCopyTemplateLang("option-header.tmpl");
-
- for (j = group->num_options, option = group->options;
- j > 0;
- j --, option ++)
+ cupsFreeOptions(num_settings, settings);
+
+ num_settings = 0;
+ num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
+ debug_logging, num_settings, &settings);
+ num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
+ remote_admin, num_settings, &settings);
+ num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY,
+ remote_any, num_settings, &settings);
+ num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS,
+ remote_printers, num_settings, &settings);
+ num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
+ share_printers, num_settings, &settings);
+ num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
+ user_cancel_any, num_settings, &settings);
+#ifdef HAVE_GSSAPI
+ num_settings = cupsAddOption("DefaultAuthType", default_auth_type,
+ num_settings, &settings);
+#endif /* HAVE_GSSAPI */
+
+ if (!cupsAdminSetServerSettings(http, num_settings, settings))
{
- if (!strcmp(option->keyword, "PageRegion"))
- continue;
-
- cgiSetVariable("KEYWORD", option->keyword);
- cgiSetVariable("KEYTEXT", option->text);
-
- if (option->conflicted)
- cgiSetVariable("CONFLICTED", "1");
- else
- cgiSetVariable("CONFLICTED", "0");
-
- cgiSetSize("CHOICES", 0);
- cgiSetSize("TEXT", 0);
- for (k = 0, m = 0; k < option->num_choices; k ++)
- {
- /*
- * Hide custom option values...
- */
-
- if (!strcmp(option->choices[k].choice, "Custom"))
- continue;
-
- cgiSetArray("CHOICES", m, option->choices[k].choice);
- cgiSetArray("TEXT", m, option->choices[k].text);
-
- m ++;
-
- if (option->choices[k].marked)
- cgiSetVariable("DEFCHOICE", option->choices[k].choice);
- }
-
- switch (option->ui)
- {
- case PPD_UI_BOOLEAN :
- cgiCopyTemplateLang("option-boolean.tmpl");
- break;
- case PPD_UI_PICKONE :
- cgiCopyTemplateLang("option-pickone.tmpl");
- break;
- case PPD_UI_PICKMANY :
- cgiCopyTemplateLang("option-pickmany.tmpl");
- break;
- }
+ cgiStartHTML(cgiText(_("Change Settings")));
+ cgiSetVariable("MESSAGE",
+ cgiText(_("Unable to change server settings:")));
+ cgiSetVariable("ERROR", cupsLastErrorString());
+ cgiCopyTemplateLang("error.tmpl");
+ }
+ else
+ {
+ cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
+ cgiStartHTML(cgiText(_("Change Settings")));
+ cgiCopyTemplateLang("restart.tmpl");
}
+ }
+ else
+ {
+ /*
+ * No changes...
+ */
- cgiCopyTemplateLang("option-trailer.tmpl");
+ cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
+ cgiStartHTML(cgiText(_("Change Settings")));
+ cgiCopyTemplateLang("norestart.tmpl");
}
+ cupsFreeOptions(num_settings, settings);
+
+ cgiEndHTML();
+ }
+ else if (cgiIsPOST())
+ {
/*
- * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
- * following attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
+ * Save hand-edited config file...
*/
- request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+ http_status_t status; /* PUT status */
+ char tempfile[1024]; /* Temporary new cupsd.conf */
+ int tempfd; /* Temporary file descriptor */
+ cups_file_t *temp; /* Temporary file */
+ const char *start, /* Start of line */
+ *end; /* End of line */
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s", printer);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
/*
- * Do the request and get back a response...
+ * Create a temporary file for the new cupsd.conf file...
*/
- if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ if ((tempfd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
{
- if ((attr = ippFindAttribute(response, "job-sheets-supported",
- IPP_TAG_ZERO)) != NULL)
- {
- /*
- * Add the job sheets options...
- */
-
- cgiSetVariable("GROUP", cgiText(_("Banners")));
- cgiCopyTemplateLang("option-header.tmpl");
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file:")));
+ cgiSetVariable("ERROR", strerror(errno));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+
+ perror(tempfile);
+ return;
+ }
- cgiSetSize("CHOICES", attr->num_values);
- cgiSetSize("TEXT", attr->num_values);
- for (k = 0; k < attr->num_values; k ++)
- {
- cgiSetArray("CHOICES", k, attr->values[k].string.text);
- cgiSetArray("TEXT", k, attr->values[k].string.text);
- }
-
- attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO);
+ if ((temp = cupsFileOpenFd(tempfd, "w")) == NULL)
+ {
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file:")));
+ cgiSetVariable("ERROR", strerror(errno));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+
+ perror(tempfile);
+ close(tempfd);
+ unlink(tempfile);
+ return;
+ }
- cgiSetVariable("KEYWORD", "job_sheets_start");
- cgiSetVariable("KEYTEXT", cgiText(_("Starting Banner")));
- cgiSetVariable("DEFCHOICE", attr == NULL ?
- "" : attr->values[0].string.text);
+ /*
+ * Copy the cupsd.conf text from the form variable...
+ */
- cgiCopyTemplateLang("option-pickone.tmpl");
+ start = cgiGetVariable("CUPSDCONF");
+ while (start)
+ {
+ if ((end = strstr(start, "\r\n")) == NULL)
+ if ((end = strstr(start, "\n")) == NULL)
+ end = start + strlen(start);
- cgiSetVariable("KEYWORD", "job_sheets_end");
- cgiSetVariable("KEYTEXT", cgiText(_("Ending Banner")));
- cgiSetVariable("DEFCHOICE", attr == NULL && attr->num_values > 1 ?
- "" : attr->values[1].string.text);
+ cupsFileWrite(temp, start, end - start);
+ cupsFilePutChar(temp, '\n');
- cgiCopyTemplateLang("option-pickone.tmpl");
+ if (*end == '\r')
+ start = end + 2;
+ else if (*end == '\n')
+ start = end + 1;
+ else
+ start = NULL;
+ }
- cgiCopyTemplateLang("option-trailer.tmpl");
- }
+ cupsFileClose(temp);
- if (ippFindAttribute(response, "printer-error-policy-supported",
- IPP_TAG_ZERO) ||
- ippFindAttribute(response, "printer-op-policy-supported",
- IPP_TAG_ZERO))
- {
- /*
- * Add the error and operation policy options...
- */
+ /*
+ * Upload the configuration file to the server...
+ */
- cgiSetVariable("GROUP", cgiText(_("Policies")));
- cgiCopyTemplateLang("option-header.tmpl");
+ status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile);
- /*
- * Error policy...
- */
+ if (status != HTTP_CREATED)
+ {
+ cgiSetVariable("MESSAGE",
+ cgiText(_("Unable to upload cupsd.conf file:")));
+ cgiSetVariable("ERROR", httpStatus(status));
- attr = ippFindAttribute(response, "printer-error-policy-supported",
- IPP_TAG_ZERO);
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiCopyTemplateLang("error.tmpl");
+ }
+ else
+ {
+ cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
- if (attr)
- {
- cgiSetSize("CHOICES", attr->num_values);
- cgiSetSize("TEXT", attr->num_values);
- for (k = 0; k < attr->num_values; k ++)
- {
- cgiSetArray("CHOICES", k, attr->values[k].string.text);
- cgiSetArray("TEXT", k, attr->values[k].string.text);
- }
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiCopyTemplateLang("restart.tmpl");
+ }
- attr = ippFindAttribute(response, "printer-error-policy",
- IPP_TAG_ZERO);
+ cgiEndHTML();
- cgiSetVariable("KEYWORD", "printer_error_policy");
- cgiSetVariable("KEYTEXT", cgiText(_("Error Policy")));
- cgiSetVariable("DEFCHOICE", attr == NULL ?
- "" : attr->values[0].string.text);
- }
+ unlink(tempfile);
+ }
+ else
+ {
+ struct stat info; /* cupsd.conf information */
+ cups_file_t *cupsd; /* cupsd.conf file */
+ char *buffer; /* Buffer for entire file */
+ char filename[1024]; /* Filename */
+ const char *server_root; /* Location of config files */
- cgiCopyTemplateLang("option-pickone.tmpl");
- /*
- * Operation policy...
- */
+ /*
+ * Locate the cupsd.conf file...
+ */
- attr = ippFindAttribute(response, "printer-op-policy-supported",
- IPP_TAG_ZERO);
+ if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
+ server_root = CUPS_SERVERROOT;
- if (attr)
- {
- cgiSetSize("CHOICES", attr->num_values);
- cgiSetSize("TEXT", attr->num_values);
- for (k = 0; k < attr->num_values; k ++)
- {
- cgiSetArray("CHOICES", k, attr->values[k].string.text);
- cgiSetArray("TEXT", k, attr->values[k].string.text);
- }
+ snprintf(filename, sizeof(filename), "%s/cupsd.conf", server_root);
- attr = ippFindAttribute(response, "printer-op-policy", IPP_TAG_ZERO);
+ /*
+ * Figure out the size...
+ */
- cgiSetVariable("KEYWORD", "printer_op_policy");
- cgiSetVariable("KEYTEXT", cgiText(_("Operation Policy")));
- cgiSetVariable("DEFCHOICE", attr == NULL ?
- "" : attr->values[0].string.text);
+ if (stat(filename, &info))
+ {
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiSetVariable("MESSAGE",
+ cgiText(_("Unable to access cupsd.conf file:")));
+ cgiSetVariable("ERROR", strerror(errno));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
- cgiCopyTemplateLang("option-pickone.tmpl");
- }
+ perror(filename);
+ return;
+ }
- cgiCopyTemplateLang("option-trailer.tmpl");
- }
+ if (info.st_size > (1024 * 1024))
+ {
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiSetVariable("MESSAGE",
+ cgiText(_("Unable to access cupsd.conf file:")));
+ cgiSetVariable("ERROR",
+ cgiText(_("Unable to edit cupsd.conf files larger than "
+ "1MB!")));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
- ippDelete(response);
+ fprintf(stderr, "ERROR: \"%s\" too large (%ld) to edit!\n", filename,
+ (long)info.st_size);
+ return;
}
/*
- * Binary protocol support...
+ * Open the cupsd.conf file...
*/
- if (ppd->protocols && strstr(ppd->protocols, "BCP"))
+ if ((cupsd = cupsFileOpen(filename, "r")) == NULL)
{
- protocol = ppdFindAttr(ppd, "cupsProtocol", NULL);
+ /*
+ * Unable to open - log an error...
+ */
- cgiSetVariable("GROUP", cgiText(_("PS Binary Protocol")));
- cgiCopyTemplateLang("option-header.tmpl");
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
+ cgiSetVariable("MESSAGE",
+ cgiText(_("Unable to access cupsd.conf file:")));
+ cgiSetVariable("ERROR", strerror(errno));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
- cgiSetSize("CHOICES", 2);
- cgiSetSize("TEXT", 2);
- cgiSetArray("CHOICES", 0, "None");
- cgiSetArray("TEXT", 0, cgiText(_("None")));
+ perror(filename);
+ return;
+ }
- if (strstr(ppd->protocols, "TBCP"))
- {
- cgiSetArray("CHOICES", 1, "TBCP");
- cgiSetArray("TEXT", 1, "TBCP");
- }
- else
- {
- cgiSetArray("CHOICES", 1, "BCP");
- cgiSetArray("TEXT", 1, "BCP");
- }
+ /*
+ * Allocate memory and load the file into a string buffer...
+ */
- cgiSetVariable("KEYWORD", "protocol");
- cgiSetVariable("KEYTEXT", cgiText(_("PS Binary Protocol")));
- cgiSetVariable("DEFCHOICE", protocol ? protocol->value : "None");
+ buffer = calloc(1, info.st_size + 1);
- cgiCopyTemplateLang("option-pickone.tmpl");
+ cupsFileRead(cupsd, buffer, info.st_size);
+ cupsFileClose(cupsd);
- cgiCopyTemplateLang("option-trailer.tmpl");
- }
+ cgiSetVariable("CUPSDCONF", buffer);
+ free(buffer);
- cgiCopyTemplateLang("set-printer-options-trailer.tmpl");
- cgiEndHTML();
- }
- else
- {
/*
- * Set default options...
+ * Show the current config file...
*/
- fputs("DEBUG: Setting options...\n", stderr);
+ cgiStartHTML(cgiText(_("Edit Configuration File")));
- out = cupsTempFile2(tempfile, sizeof(tempfile));
- in = cupsFileOpen(filename, "r");
+ printf("<!-- \"%s\" -->\n", filename);
- if (!in || !out)
- {
- cgiSetVariable("ERROR", strerror(errno));
- cgiStartHTML(cgiText(_("Set Printer Options")));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
+ cgiCopyTemplateLang("edit-config.tmpl");
- if (in)
- cupsFileClose(in);
+ cgiEndHTML();
+ }
+}
- if (out)
- {
- cupsFileClose(out);
- unlink(tempfile);
- }
- unlink(filename);
- return;
- }
+/*
+ * 'do_delete_class()' - Delete a class...
+ */
- while (cupsFileGets(in, line, sizeof(line)))
- {
- if (!strncmp(line, "*cupsProtocol:", 14) && cgiGetVariable("protocol"))
- continue;
- else if (strncmp(line, "*Default", 8))
- cupsFilePrintf(out, "%s\n", line);
- else
- {
- /*
- * Get default option name...
- */
+static void
+do_delete_class(http_t *http) /* I - HTTP connection */
+{
+ ipp_t *request; /* IPP request */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ const char *pclass; /* Printer class name */
- strlcpy(keyword, line + 8, sizeof(keyword));
- for (keyptr = keyword; *keyptr; keyptr ++)
- if (*keyptr == ':' || isspace(*keyptr & 255))
- break;
+ /*
+ * Get form variables...
+ */
- *keyptr = '\0';
+ if (cgiGetVariable("CONFIRM") == NULL)
+ {
+ cgiStartHTML(cgiText(_("Delete Class")));
+ cgiCopyTemplateLang("class-confirm.tmpl");
+ cgiEndHTML();
+ return;
+ }
- if (!strcmp(keyword, "PageRegion") ||
- !strcmp(keyword, "PaperDimension") ||
- !strcmp(keyword, "ImageableArea"))
- var = cgiGetVariable("PageSize");
- else
- var = cgiGetVariable(keyword);
+ if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL)
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, "/classes/%s", pclass);
+ else
+ {
+ cgiStartHTML(cgiText(_("Delete Class")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
+ }
- if (var != NULL)
- cupsFilePrintf(out, "*Default%s: %s\n", keyword, var);
- else
- cupsFilePrintf(out, "%s\n", line);
- }
- }
+ /*
+ * Build a CUPS_DELETE_CLASS request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNewRequest(CUPS_DELETE_CLASS);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
- if ((var = cgiGetVariable("protocol")) != NULL)
- cupsFilePrintf(out, "*cupsProtocol: %s\n", cgiGetVariable("protocol"));
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
- cupsFileClose(in);
- cupsFileClose(out);
+ /*
+ * Show the results...
+ */
+ if (cupsLastError() <= IPP_OK_CONFLICT)
+ {
/*
- * Build a CUPS_ADD_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * job-sheets-default
- * [ppd file]
+ * Redirect successful updates back to the classes page...
*/
- request = ippNewRequest(CUPS_ADD_PRINTER);
+ cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/classes");
+ }
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s",
- cgiGetVariable("PRINTER_NAME"));
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
+ cgiStartHTML(cgiText(_("Delete Class")));
- attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "job-sheets-default", 2, NULL, NULL);
- attr->values[0].string.text = strdup(cgiGetVariable("job_sheets_start"));
- attr->values[1].string.text = strdup(cgiGetVariable("job_sheets_end"));
+ if (cupsLastError() > IPP_OK_CONFLICT)
+ cgiShowIPPError(_("Unable to delete class:"));
+ else
+ cgiCopyTemplateLang("class-deleted.tmpl");
- if ((var = cgiGetVariable("printer_error_policy")) != NULL)
- attr = ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "printer-error-policy", NULL, var);
+ cgiEndHTML();
+}
- if ((var = cgiGetVariable("printer_op_policy")) != NULL)
- attr = ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "printer-op-policy", NULL, var);
- /*
- * Do the request and get back a response...
- */
+/*
+ * 'do_delete_printer()' - Delete a printer...
+ */
- ippDelete(cupsDoFileRequest(http, request, "/admin/", tempfile));
+static void
+do_delete_printer(http_t *http) /* I - HTTP connection */
+{
+ ipp_t *request; /* IPP request */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ const char *printer; /* Printer printer name */
- if (cupsLastError() > IPP_OK_CONFLICT)
- {
- cgiStartHTML(title);
- cgiShowIPPError(_("Unable to set options:"));
- }
- else
- {
- /*
- * Redirect successful updates back to the printer page...
- */
- char refresh[1024]; /* Refresh URL */
+ /*
+ * Get form variables...
+ */
+ if (cgiGetVariable("CONFIRM") == NULL)
+ {
+ cgiStartHTML(cgiText(_("Delete Printer")));
+ cgiCopyTemplateLang("printer-confirm.tmpl");
+ cgiEndHTML();
+ return;
+ }
- cgiFormEncode(uri, printer, sizeof(uri));
- snprintf(refresh, sizeof(refresh),
- "5;URL=/admin/?OP=redirect&URL=/printers/%s", uri);
- cgiSetVariable("refresh_page", refresh);
+ if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, "/printers/%s", printer);
+ else
+ {
+ cgiStartHTML(cgiText(_("Delete Printer")));
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
+ }
- cgiStartHTML(title);
+ /*
+ * Build a CUPS_DELETE_PRINTER request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
- cgiCopyTemplateLang("printer-configured.tmpl");
- }
+ request = ippNewRequest(CUPS_DELETE_PRINTER);
- cgiEndHTML();
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
- unlink(tempfile);
+ /*
+ * Do the request and get back a response...
+ */
+
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
+
+ /*
+ * Show the results...
+ */
+
+ if (cupsLastError() <= IPP_OK_CONFLICT)
+ {
+ /*
+ * Redirect successful updates back to the printers page...
+ */
+
+ cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect&URL=/printers");
}
- unlink(filename);
+ cgiStartHTML(cgiText(_("Delete Printer")));
+
+ if (cupsLastError() > IPP_OK_CONFLICT)
+ cgiShowIPPError(_("Unable to delete printer:"));
+ else
+ cgiCopyTemplateLang("printer-deleted.tmpl");
+
+ cgiEndHTML();
}
/*
- * 'do_config_server()' - Configure server settings.
+ * 'do_export()' - Export printers to Samba...
*/
static void
-do_config_server(http_t *http) /* I - HTTP connection */
+do_export(http_t *http) /* I - HTTP connection */
{
- if (cgiIsPOST() && !cgiGetVariable("CUPSDCONF"))
- {
- /*
- * Save basic setting changes...
- */
+ int i, j; /* Looping vars */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ const char *username, /* Samba username */
+ *password, /* Samba password */
+ *export_all; /* Export all printers? */
+ int export_count, /* Number of printers to export */
+ printer_count; /* Number of available printers */
+ const char *name, /* What name to pull */
+ *dest; /* Current destination */
+ char ppd[1024]; /* PPD file */
- int num_settings; /* Number of server settings */
- cups_option_t *settings; /* Server settings */
+ /*
+ * Get form data...
+ */
- num_settings = 0;
- num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING,
- cgiGetVariable("DEBUG_LOGGING") ? "1" : "0",
- num_settings, &settings);
- num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN,
- cgiGetVariable("REMOTE_ADMIN") ? "1" : "0",
- num_settings, &settings);
- num_settings = cupsAddOption(CUPS_SERVER_REMOTE_PRINTERS,
- cgiGetVariable("REMOTE_PRINTERS") ? "1" : "0",
- num_settings, &settings);
- num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS,
- cgiGetVariable("SHARE_PRINTERS") ? "1" : "0",
- num_settings, &settings);
- num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY,
- cgiGetVariable("USER_CANCEL_ANY") ? "1" : "0",
- num_settings, &settings);
-
-
- if (!_cupsAdminSetServerSettings(http, num_settings, settings))
- {
- cgiStartHTML(cgiText(_("Change Settings")));
- cgiSetVariable("MESSAGE",
- cgiText(_("Unable to change server settings:")));
- cgiSetVariable("ERROR", cupsLastErrorString());
- cgiCopyTemplateLang("error.tmpl");
- }
- else
+ username = cgiGetVariable("USERNAME");
+ password = cgiGetVariable("PASSWORD");
+ export_all = cgiGetVariable("EXPORT_ALL");
+ export_count = cgiGetSize("EXPORT_NAME");
+
+ /*
+ * Get list of available printers...
+ */
+
+ cgiSetSize("PRINTER_NAME", 0);
+ cgiSetSize("PRINTER_EXPORT", 0);
+
+ request = ippNewRequest(CUPS_GET_PRINTERS);
+
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
+ "printer-type", 0);
+
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
+ "printer-type-mask", CUPS_PRINTER_CLASS | CUPS_PRINTER_REMOTE |
+ CUPS_PRINTER_IMPLICIT);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "printer-name");
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+ ippDelete(response);
+
+ if (!export_all)
{
- cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
- cgiStartHTML(cgiText(_("Change Settings")));
- cgiCopyTemplateLang("restart.tmpl");
- }
+ printer_count = cgiGetSize("PRINTER_NAME");
- cupsFreeOptions(num_settings, settings);
+ for (i = 0; i < printer_count; i ++)
+ {
+ dest = cgiGetArray("PRINTER_NAME", i);
- cgiEndHTML();
+ for (j = 0; j < export_count; j ++)
+ if (!strcasecmp(dest, cgiGetArray("EXPORT_NAME", j)))
+ break;
+
+ cgiSetArray("PRINTER_EXPORT", i, j < export_count ? "Y" : "");
+ }
+ }
}
- else if (cgiIsPOST())
+
+ /*
+ * Export or get the printers to export...
+ */
+
+ if (username && *username && password && *password &&
+ (export_all || export_count > 0))
{
/*
- * Save hand-edited config file...
+ * Do export...
*/
- http_status_t status; /* PUT status */
- char tempfile[1024]; /* Temporary new cupsd.conf */
- int tempfd; /* Temporary file descriptor */
- cups_file_t *temp; /* Temporary file */
- const char *start, /* Start of line */
- *end; /* End of line */
+ fputs("DEBUG: Export printers...\n", stderr);
+ if (export_all)
+ {
+ name = "PRINTER_NAME";
+ export_count = cgiGetSize("PRINTER_NAME");
+ }
+ else
+ name = "EXPORT_NAME";
- /*
- * Create a temporary file for the new cupsd.conf file...
- */
-
- if ((tempfd = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
+ for (i = 0; i < export_count; i ++)
{
- cgiStartHTML(cgiText(_("Edit Configuration File")));
- cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file:")));
- cgiSetVariable("ERROR", strerror(errno));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
-
- perror(tempfile);
- return;
+ dest = cgiGetArray(name, i);
+
+ if (!cupsAdminCreateWindowsPPD(http, dest, ppd, sizeof(ppd)))
+ break;
+
+ j = cupsAdminExportSamba(dest, ppd, "localhost", username, password,
+ stderr);
+
+ unlink(ppd);
+
+ if (!j)
+ break;
}
- if ((temp = cupsFileOpenFd(tempfd, "w")) == NULL)
+ if (i < export_count)
+ cgiSetVariable("ERROR", cupsLastErrorString());
+ else
{
- cgiStartHTML(cgiText(_("Edit Configuration File")));
- cgiSetVariable("MESSAGE", cgiText(_("Unable to create temporary file:")));
- cgiSetVariable("ERROR", strerror(errno));
- cgiCopyTemplateLang("error.tmpl");
+ cgiStartHTML(cgiText(_("Export Printers to Samba")));
+ cgiCopyTemplateLang("samba-exported.tmpl");
cgiEndHTML();
-
- perror(tempfile);
- close(tempfd);
- unlink(tempfile);
return;
}
+ }
+ else if (username && !*username)
+ cgiSetVariable("ERROR",
+ cgiText(_("A Samba username is required to export "
+ "printer drivers!")));
+ else if (username && (!password || !*password))
+ cgiSetVariable("ERROR",
+ cgiText(_("A Samba password is required to export "
+ "printer drivers!")));
- /*
- * Copy the cupsd.conf text from the form variable...
- */
+ /*
+ * Show form...
+ */
- start = cgiGetVariable("CUPSDCONF");
- while (start)
- {
- if ((end = strstr(start, "\r\n")) == NULL)
- if ((end = strstr(start, "\n")) == NULL)
- end = start + strlen(start);
+ cgiStartHTML(cgiText(_("Export Printers to Samba")));
+ cgiCopyTemplateLang("samba-export.tmpl");
+ cgiEndHTML();
+}
- cupsFileWrite(temp, start, end - start);
- cupsFilePutChar(temp, '\n');
- if (*end == '\r')
- start = end + 2;
- else if (*end == '\n')
- start = end + 1;
- else
- start = NULL;
- }
+/*
+ * 'do_list_printers()' - List available printers...
+ */
- cupsFileClose(temp);
+static void
+do_list_printers(http_t *http) /* I - HTTP connection */
+{
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP attribute */
- /*
- * Upload the configuration file to the server...
- */
- status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile);
+ cgiStartHTML(cgiText(_("List Available Printers")));
+ fflush(stdout);
- if (status != HTTP_CREATED)
- {
- cgiSetVariable("MESSAGE",
- cgiText(_("Unable to upload cupsd.conf file:")));
- cgiSetVariable("ERROR", httpStatus(status));
+ /*
+ * Get the list of printers and their devices...
+ */
- cgiStartHTML(cgiText(_("Edit Configuration File")));
- cgiCopyTemplateLang("error.tmpl");
- }
- else
- {
- cgiSetVariable("refresh_page", "5;URL=/admin/?OP=redirect");
+ request = ippNewRequest(CUPS_GET_PRINTERS);
- cgiStartHTML(cgiText(_("Edit Configuration File")));
- cgiCopyTemplateLang("restart.tmpl");
- }
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", NULL, "device-uri");
- cgiEndHTML();
+ 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_LOCAL);
- unlink(tempfile);
- }
- else
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
- struct stat info; /* cupsd.conf information */
- cups_file_t *cupsd; /* cupsd.conf file */
- char *buffer; /* Buffer for entire file */
- char filename[1024]; /* Filename */
- const char *server_root; /* Location of config files */
-
-
/*
- * Locate the cupsd.conf file...
+ * Got the printer list, now load the devices...
*/
- if ((server_root = getenv("CUPS_SERVERROOT")) == NULL)
- server_root = CUPS_SERVERROOT;
+ int i; /* Looping var */
+ cups_array_t *printer_devices; /* Printer devices for local printers */
+ char *printer_device; /* Current printer device */
- snprintf(filename, sizeof(filename), "%s/cupsd.conf", server_root);
/*
- * Figure out the size...
+ * Allocate an array and copy the device strings...
*/
- if (stat(filename, &info))
- {
- cgiStartHTML(cgiText(_("Edit Configuration File")));
- cgiSetVariable("MESSAGE",
- cgiText(_("Unable to access cupsd.conf file:")));
- cgiSetVariable("ERROR", strerror(errno));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
-
- perror(filename);
- return;
- }
+ printer_devices = cupsArrayNew((cups_array_func_t)strcmp, NULL);
- if (info.st_size > (1024 * 1024))
+ for (attr = ippFindAttribute(response, "device-uri", IPP_TAG_URI);
+ attr;
+ attr = ippFindNextAttribute(response, "device-uri", IPP_TAG_URI))
{
- cgiStartHTML(cgiText(_("Edit Configuration File")));
- cgiSetVariable("MESSAGE",
- cgiText(_("Unable to access cupsd.conf file:")));
- cgiSetVariable("ERROR",
- cgiText(_("Unable to edit cupsd.conf files larger than "
- "1MB!")));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
-
- fprintf(stderr, "ERROR: \"%s\" too large (%ld) to edit!\n", filename,
- (long)info.st_size);
- return;
+ cupsArrayAdd(printer_devices, strdup(attr->values[0].string.text));
}
/*
- * Open the cupsd.conf file...
+ * Free the printer list and get the device list...
*/
- if ((cupsd = cupsFileOpen(filename, "r")) == NULL)
+ ippDelete(response);
+
+ request = ippNewRequest(CUPS_GET_DEVICES);
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
/*
- * Unable to open - log an error...
+ * Got the device list, let's parse it...
*/
- cgiStartHTML(cgiText(_("Edit Configuration File")));
- cgiSetVariable("MESSAGE",
- cgiText(_("Unable to access cupsd.conf file:")));
- cgiSetVariable("ERROR", strerror(errno));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
+ const char *device_uri, /* device-uri attribute value */
+ *device_make_and_model, /* device-make-and-model value */
+ *device_info; /* device-info value */
- perror(filename);
- return;
- }
- /*
- * Allocate memory and load the file into a string buffer...
- */
+ for (i = 0, attr = response->attrs; attr; attr = attr->next)
+ {
+ /*
+ * Skip leading attributes until we hit a device...
+ */
- buffer = calloc(1, info.st_size + 1);
+ while (attr && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
- cupsFileRead(cupsd, buffer, info.st_size);
- cupsFileClose(cupsd);
+ if (!attr)
+ break;
- cgiSetVariable("CUPSDCONF", buffer);
- free(buffer);
+ /*
+ * Pull the needed attributes from this device...
+ */
- /*
- * Show the current config file...
- */
+ device_info = NULL;
+ device_make_and_model = NULL;
+ device_uri = NULL;
- cgiStartHTML(cgiText(_("Edit Configuration File")));
+ while (attr && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (!strcmp(attr->name, "device-info") &&
+ attr->value_tag == IPP_TAG_TEXT)
+ device_info = attr->values[0].string.text;
- printf("<!-- \"%s\" -->\n", filename);
+ if (!strcmp(attr->name, "device-make-and-model") &&
+ attr->value_tag == IPP_TAG_TEXT)
+ device_make_and_model = attr->values[0].string.text;
- cgiCopyTemplateLang("edit-config.tmpl");
+ if (!strcmp(attr->name, "device-uri") &&
+ attr->value_tag == IPP_TAG_URI)
+ device_uri = attr->values[0].string.text;
- cgiEndHTML();
- }
-}
+ attr = attr->next;
+ }
+ /*
+ * See if we have everything needed...
+ */
-/*
- * 'do_delete_class()' - Delete a class...
- */
+ if (device_info && device_make_and_model && device_uri &&
+ strcasecmp(device_make_and_model, "unknown") &&
+ strchr(device_uri, ':'))
+ {
+ /*
+ * Yes, now see if there is already a printer for this
+ * device...
+ */
-static void
-do_delete_class(http_t *http) /* I - HTTP connection */
-{
- ipp_t *request; /* IPP request */
- char uri[HTTP_MAX_URI]; /* Job URI */
- const char *pclass; /* Printer class name */
+ if (!cupsArrayFind(printer_devices, (void *)device_uri))
+ {
+ /*
+ * Not found, so it must be a new printer...
+ */
+ char options[1024], /* Form variables for this device */
+ *options_ptr; /* Pointer into string */
+ const char *ptr; /* Pointer into device string */
- /*
- * Get form variables...
- */
- if (cgiGetVariable("CONFIRM") == NULL)
- {
- cgiStartHTML(cgiText(_("Delete Class")));
- cgiCopyTemplateLang("class-confirm.tmpl");
- cgiEndHTML();
- return;
- }
+ /*
+ * Format the printer name variable for this device...
+ *
+ * We use the device-info string first, then device-uri,
+ * and finally device-make-and-model to come up with a
+ * suitable name.
+ */
- if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL)
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/classes/%s", pclass);
- else
- {
- cgiStartHTML(cgiText(_("Delete Class")));
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
- return;
- }
+ strcpy(options, "TEMPLATE_NAME=");
+ options_ptr = options + strlen(options);
- /*
- * Build a CUPS_DELETE_CLASS request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- */
+ if (strncasecmp(device_info, "unknown", 7))
+ ptr = device_info;
+ else if ((ptr = strstr(device_uri, "://")) != NULL)
+ ptr += 3;
+ else
+ ptr = device_make_and_model;
- request = ippNewRequest(CUPS_DELETE_CLASS);
+ for (;
+ options_ptr < (options + sizeof(options) - 1) && *ptr;
+ ptr ++)
+ if (isalnum(*ptr & 255) || *ptr == '_' || *ptr == '-' ||
+ *ptr == '.')
+ *options_ptr++ = *ptr;
+ else if ((*ptr == ' ' || *ptr == '/') && options_ptr[-1] != '_')
+ *options_ptr++ = '_';
+ else if (*ptr == '?' || *ptr == '(')
+ break;
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
+ /*
+ * Then add the make and model in the printer info, so
+ * that MacOS clients see something reasonable...
+ */
- /*
- * Do the request and get back a response...
- */
+ strlcpy(options_ptr, "&PRINTER_LOCATION=Local+Printer"
+ "&PRINTER_INFO=",
+ sizeof(options) - (options_ptr - options));
+ options_ptr += strlen(options_ptr);
- ippDelete(cupsDoRequest(http, request, "/admin/"));
+ cgiFormEncode(options_ptr, device_make_and_model,
+ sizeof(options) - (options_ptr - options));
+ options_ptr += strlen(options_ptr);
+
+ /*
+ * Then copy the device URI...
+ */
+
+ strlcpy(options_ptr, "&DEVICE_URI=",
+ sizeof(options) - (options_ptr - options));
+ options_ptr += strlen(options_ptr);
+
+ cgiFormEncode(options_ptr, device_uri,
+ sizeof(options) - (options_ptr - options));
+ options_ptr += strlen(options_ptr);
+
+ if (options_ptr < (options + sizeof(options) - 1))
+ {
+ *options_ptr++ = '|';
+ cgiFormEncode(options_ptr, device_make_and_model,
+ sizeof(options) - (options_ptr - options));
+ }
+
+ /*
+ * Finally, set the form variables for this printer...
+ */
+
+ cgiSetArray("device_info", i, device_info);
+ cgiSetArray("device_make_and_model", i, device_make_and_model);
+ cgiSetArray("device_options", i, options);
+ cgiSetArray("device_uri", i, device_uri);
+ i ++;
+ }
+ }
+
+ if (!attr)
+ break;
+ }
+
+ ippDelete(response);
+
+ /*
+ * Free the device list...
+ */
+
+ for (printer_device = (char *)cupsArrayFirst(printer_devices);
+ printer_device;
+ printer_device = (char *)cupsArrayNext(printer_devices))
+ free(printer_device);
+
+ cupsArrayDelete(printer_devices);
+ }
+ }
/*
- * Show the results...
+ * Finally, show the printer list...
*/
- cgiStartHTML(cgiText(_("Delete Class")));
-
- if (cupsLastError() > IPP_OK_CONFLICT)
- cgiShowIPPError(_("Unable to delete class:"));
- else
- cgiCopyTemplateLang("class-deleted.tmpl");
+ cgiCopyTemplateLang("list-available-printers.tmpl");
cgiEndHTML();
}
/*
- * 'do_delete_printer()' - Delete a printer...
+ * 'do_menu()' - Show the main menu...
*/
static void
-do_delete_printer(http_t *http) /* I - HTTP connection */
+do_menu(http_t *http) /* I - HTTP connection */
{
- ipp_t *request; /* IPP request */
- char uri[HTTP_MAX_URI]; /* Job URI */
- const char *printer; /* Printer printer name */
+ int num_settings; /* Number of server settings */
+ cups_option_t *settings; /* Server settings */
+ const char *val; /* Setting value */
+ char filename[1024]; /* Temporary filename */
+ const char *datadir; /* Location of data files */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
/*
- * Get form variables...
+ * Get the current server settings...
*/
- if (cgiGetVariable("CONFIRM") == NULL)
+ if (!cupsAdminGetServerSettings(http, &num_settings, &settings))
{
- cgiStartHTML(cgiText(_("Delete Printer")));
- cgiCopyTemplateLang("printer-confirm.tmpl");
- cgiEndHTML();
- return;
+ cgiSetVariable("SETTINGS_MESSAGE",
+ cgiText(_("Unable to open cupsd.conf file:")));
+ cgiSetVariable("SETTINGS_ERROR", cupsLastErrorString());
}
- if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, "/printers/%s", printer);
- else
- {
- cgiStartHTML(cgiText(_("Delete Printer")));
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
- return;
- }
+ if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings,
+ settings)) != NULL && atoi(val))
+ cgiSetVariable("DEBUG_LOGGING", "CHECKED");
+
+ if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings,
+ settings)) != NULL && atoi(val))
+ cgiSetVariable("REMOTE_ADMIN", "CHECKED");
+
+ if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings,
+ settings)) != NULL && atoi(val))
+ cgiSetVariable("REMOTE_ANY", "CHECKED");
+
+ if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, num_settings,
+ settings)) != NULL && atoi(val))
+ cgiSetVariable("REMOTE_PRINTERS", "CHECKED");
+
+ if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings,
+ settings)) != NULL && atoi(val))
+ cgiSetVariable("SHARE_PRINTERS", "CHECKED");
+
+ if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings,
+ settings)) != NULL && atoi(val))
+ cgiSetVariable("USER_CANCEL_ANY", "CHECKED");
+
+#ifdef HAVE_GSSAPI
+ cgiSetVariable("HAVE_GSSAPI", "1");
+
+ if ((val = cupsGetOption("DefaultAuthType", num_settings,
+ settings)) != NULL && !strcasecmp(val, "Negotiate"))
+ cgiSetVariable("KERBEROS", "CHECKED");
+#endif /* HAVE_GSSAPI */
+
+ cupsFreeOptions(num_settings, settings);
/*
- * Build a CUPS_DELETE_PRINTER request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
+ * See if Samba and the Windows drivers are installed...
*/
- request = ippNewRequest(CUPS_DELETE_PRINTER);
+ if ((datadir = getenv("CUPS_DATADIR")) == NULL)
+ datadir = CUPS_DATADIR;
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
+ snprintf(filename, sizeof(filename), "%s/drivers/pscript5.dll", datadir);
+ if (!access(filename, R_OK))
+ {
+ /*
+ * Found Windows 2000 driver file, see if we have smbclient and
+ * rpcclient...
+ */
+
+ if (cupsFileFind("smbclient", getenv("PATH"), 1, filename,
+ sizeof(filename)) &&
+ cupsFileFind("rpcclient", getenv("PATH"), 1, filename,
+ sizeof(filename)))
+ cgiSetVariable("HAVE_SAMBA", "Y");
+ else
+ {
+ if (!cupsFileFind("smbclient", getenv("PATH"), 1, filename,
+ sizeof(filename)))
+ fputs("ERROR: smbclient not found!\n", stderr);
+
+ if (!cupsFileFind("rpcclient", getenv("PATH"), 1, filename,
+ sizeof(filename)))
+ fputs("ERROR: rpcclient not found!\n", stderr);
+ }
+ }
+ else
+ perror(filename);
/*
- * Do the request and get back a response...
+ * Subscriptions...
*/
- ippDelete(cupsDoRequest(http, request, "/admin/"));
+ request = ippNewRequest(IPP_GET_SUBSCRIPTIONS);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, "ipp://localhost/");
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+ ippDelete(response);
+ }
/*
- * Show the results...
+ * Finally, show the main menu template...
*/
- cgiStartHTML(cgiText(_("Delete Printer")));
+ cgiStartHTML(cgiText(_("Administration")));
- if (cupsLastError() > IPP_OK_CONFLICT)
- cgiShowIPPError(_("Unable to delete printer:"));
- else
- cgiCopyTemplateLang("printer-deleted.tmpl");
+ cgiCopyTemplateLang("admin.tmpl");
cgiEndHTML();
}
/*
- * 'do_export()' - Export printers to Samba...
+ * 'do_printer_op()' - Do a printer operation.
*/
static void
-do_export(http_t *http) /* I - HTTP connection */
+do_printer_op(http_t *http, /* I - HTTP connection */
+ ipp_op_t op, /* I - Operation to perform */
+ const char *title) /* I - Title of page */
{
- int i, j; /* Looping vars */
- ipp_t *request, /* IPP request */
- *response; /* IPP response */
- const char *username, /* Samba username */
- *password, /* Samba password */
- *export_all; /* Export all printers? */
- int export_count, /* Number of printers to export */
- printer_count; /* Number of available printers */
- const char *name, /* What name to pull */
- *dest; /* Current destination */
- char ppd[1024]; /* PPD file */
+ ipp_t *request; /* IPP request */
+ char uri[HTTP_MAX_URI]; /* Printer URI */
+ const char *printer, /* Printer name (purge-jobs) */
+ *is_class; /* Is a class? */
- /*
- * Get form data...
- */
+ is_class = cgiGetVariable("IS_CLASS");
+ printer = cgiGetVariable("PRINTER_NAME");
- username = cgiGetVariable("USERNAME");
- password = cgiGetVariable("PASSWORD");
- export_all = cgiGetVariable("EXPORT_ALL");
- export_count = cgiGetSize("EXPORT_NAME");
+ if (!printer)
+ {
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
+ }
/*
- * Get list of available printers...
+ * Build a printer request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
*/
- cgiSetSize("PRINTER_NAME", 0);
- cgiSetSize("PRINTER_EXPORT", 0);
-
- request = ippNewRequest(CUPS_GET_PRINTERS);
+ request = ippNewRequest(op);
- ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_ENUM,
- "printer-type", 0);
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+ printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
- 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...
+ */
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes", NULL, "printer-name");
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
- if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ if (cupsLastError() > IPP_OK_CONFLICT)
{
- cgiSetIPPVars(response, NULL, NULL, NULL, 0);
- ippDelete(response);
-
- if (!export_all)
- {
- printer_count = cgiGetSize("PRINTER_NAME");
-
- for (i = 0; i < printer_count; i ++)
- {
- dest = cgiGetArray("PRINTER_NAME", i);
-
- for (j = 0; j < export_count; j ++)
- if (!strcasecmp(dest, cgiGetArray("EXPORT_NAME", j)))
- break;
-
- cgiSetArray("PRINTER_EXPORT", i, j < export_count ? "Y" : "");
- }
- }
+ cgiStartHTML(title);
+ cgiShowIPPError(_("Unable to change printer:"));
}
-
- /*
- * Export or get the printers to export...
- */
-
- if (username && *username && password && *password &&
- (export_all || export_count > 0))
+ else
{
/*
- * Do export...
+ * Redirect successful updates back to the printer page...
*/
- fputs("DEBUG: Export printers...\n", stderr);
-
- if (export_all)
- {
- name = "PRINTER_NAME";
- export_count = cgiGetSize("PRINTER_NAME");
- }
- else
- name = "EXPORT_NAME";
-
- for (i = 0; i < export_count; i ++)
- {
- dest = cgiGetArray(name, i);
-
- if (!cupsAdminCreateWindowsPPD(http, dest, ppd, sizeof(ppd)))
- break;
+ char url[1024], /* Printer/class URL */
+ refresh[1024]; /* Refresh URL */
- j = cupsAdminExportSamba(dest, ppd, "localhost", username, password,
- stderr);
- unlink(ppd);
+ cgiRewriteURL(uri, url, sizeof(url), NULL);
+ cgiFormEncode(uri, url, sizeof(uri));
+ snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri);
+ cgiSetVariable("refresh_page", refresh);
- if (!j)
- break;
- }
+ cgiStartHTML(title);
- if (i < export_count)
- cgiSetVariable("ERROR", cupsLastErrorString());
- else
- {
- cgiStartHTML(cgiText(_("Export Printers to Samba")));
- cgiCopyTemplateLang("samba-exported.tmpl");
- cgiEndHTML();
- return;
- }
+ if (op == IPP_PAUSE_PRINTER)
+ cgiCopyTemplateLang("printer-stop.tmpl");
+ else if (op == IPP_RESUME_PRINTER)
+ cgiCopyTemplateLang("printer-start.tmpl");
+ else if (op == CUPS_ACCEPT_JOBS)
+ cgiCopyTemplateLang("printer-accept.tmpl");
+ else if (op == CUPS_REJECT_JOBS)
+ cgiCopyTemplateLang("printer-reject.tmpl");
+ else if (op == IPP_PURGE_JOBS)
+ cgiCopyTemplateLang("printer-purge.tmpl");
+ else if (op == CUPS_SET_DEFAULT)
+ cgiCopyTemplateLang("printer-default.tmpl");
}
- else if (username && !*username)
- cgiSetVariable("ERROR",
- cgiText(_("A Samba username is required to export "
- "printer drivers!")));
- else if (username && (!password || !*password))
- cgiSetVariable("ERROR",
- cgiText(_("A Samba password is required to export "
- "printer drivers!")));
-
- /*
- * Show form...
- */
- cgiStartHTML(cgiText(_("Export Printers to Samba")));
- cgiCopyTemplateLang("samba-export.tmpl");
cgiEndHTML();
}
/*
- * 'do_menu()' - Show the main menu...
+ * 'do_set_allowed_users()' - Set the allowed/denied users for a queue.
*/
static void
-do_menu(http_t *http) /* I - HTTP connection */
+do_set_allowed_users(http_t *http) /* I - HTTP connection */
{
- int num_settings; /* Number of server settings */
- cups_option_t *settings; /* Server settings */
- const char *val; /* Setting value */
- char filename[1024]; /* Temporary filename */
- const char *datadir; /* Location of data files */
+ int i; /* Looping var */
ipp_t *request, /* IPP request */
*response; /* IPP response */
- ipp_attribute_t *attr; /* IPP attribute */
+ char uri[HTTP_MAX_URI]; /* Printer URI */
+ const char *printer, /* Printer name (purge-jobs) */
+ *is_class, /* Is a class? */
+ *users, /* List of users or groups */
+ *type; /* Allow/deny type */
+ int num_users; /* Number of users */
+ char *ptr, /* Pointer into users string */
+ *end, /* Pointer to end of users string */
+ quote; /* Quote character */
+ ipp_attribute_t *attr; /* Attribute */
+ static const char * const attrs[] = /* Requested attributes */
+ {
+ "requesting-user-name-allowed",
+ "requesting-user-name-denied"
+ };
- /*
- * Get the current server settings...
- */
+ is_class = cgiGetVariable("IS_CLASS");
+ printer = cgiGetVariable("PRINTER_NAME");
- if (!_cupsAdminGetServerSettings(http, &num_settings, &settings))
+ if (!printer)
{
- cgiSetVariable("SETTINGS_MESSAGE",
- cgiText(_("Unable to open cupsd.conf file:")));
- cgiSetVariable("SETTINGS_ERROR", cupsLastErrorString());
+ cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
+ cgiStartHTML(cgiText(_("Set Allowed Users")));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
}
- if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings,
- settings)) != NULL && atoi(val))
- cgiSetVariable("DEBUG_LOGGING", "CHECKED");
+ users = cgiGetVariable("users");
+ type = cgiGetVariable("type");
- if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings,
- settings)) != NULL && atoi(val))
- cgiSetVariable("REMOTE_ADMIN", "CHECKED");
+ if (!users || !type ||
+ (strcmp(type, "requesting-user-name-allowed") &&
+ strcmp(type, "requesting-user-name-denied")))
+ {
+ /*
+ * Build a Get-Printer-Attributes request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requested-attributes
+ */
- if ((val = cupsGetOption(CUPS_SERVER_REMOTE_PRINTERS, num_settings,
- settings)) != NULL && atoi(val))
- cgiSetVariable("REMOTE_PRINTERS", "CHECKED");
+ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
- if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings,
- settings)) != NULL && atoi(val))
- cgiSetVariable("SHARE_PRINTERS", "CHECKED");
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+ printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
- if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings,
- settings)) != NULL && atoi(val))
- cgiSetVariable("USER_CANCEL_ANY", "CHECKED");
+ ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes",
+ (int)(sizeof(attrs) / sizeof(attrs[0])), NULL, attrs);
- cupsFreeOptions(num_settings, settings);
+ /*
+ * Do the request and get back a response...
+ */
- /*
- * Get the list of printers and their devices...
- */
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ cgiSetIPPVars(response, NULL, NULL, NULL, 0);
- request = ippNewRequest(CUPS_GET_PRINTERS);
+ ippDelete(response);
+ }
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes", NULL, "device-uri");
+ cgiStartHTML(cgiText(_("Set Allowed Users")));
- 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_LOCAL);
+ if (cupsLastError() > IPP_OK_CONFLICT)
+ cgiShowIPPError(_("Unable to get printer attributes:"));
+ else
+ cgiCopyTemplateLang("users.tmpl");
- if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ cgiEndHTML();
+ }
+ else
{
/*
- * Got the printer list, now load the devices...
- */
-
- int i; /* Looping var */
- cups_array_t *printer_devices; /* Printer devices for local printers */
- char *printer_device; /* Current printer device */
-
-
- /*
- * Allocate an array and copy the device strings...
- */
-
- printer_devices = cupsArrayNew((cups_array_func_t)strcmp, NULL);
-
- for (attr = ippFindAttribute(response, "device-uri", IPP_TAG_URI);
- attr;
- attr = ippFindNextAttribute(response, "device-uri", IPP_TAG_URI))
- {
- cupsArrayAdd(printer_devices, strdup(attr->values[0].string.text));
- }
-
- /*
- * Free the printer list and get the device list...
+ * Save the changes...
*/
- ippDelete(response);
-
- request = ippNewRequest(CUPS_GET_DEVICES);
-
- if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ for (num_users = 0, ptr = (char *)users; *ptr; num_users ++)
{
/*
- * Got the device list, let's parse it...
+ * Skip whitespace and commas...
*/
- const char *device_uri, /* device-uri attribute value */
- *device_make_and_model, /* device-make-and-model value */
- *device_info; /* device-info value */
-
+ while (*ptr == ',' || isspace(*ptr & 255))
+ ptr ++;
- for (i = 0, attr = response->attrs; attr; attr = attr->next)
+ if (*ptr == '\'' || *ptr == '\"')
{
/*
- * Skip leading attributes until we hit a device...
+ * Scan quoted name...
*/
- while (attr && attr->group_tag != IPP_TAG_PRINTER)
- attr = attr->next;
-
- if (!attr)
- break;
+ quote = *ptr++;
+ for (end = ptr; *end; end ++)
+ if (*end == quote)
+ break;
+ }
+ else
+ {
/*
- * Pull the needed attributes from this device...
+ * Scan space or comma-delimited name...
*/
- device_info = NULL;
- device_make_and_model = NULL;
- device_uri = NULL;
+ for (end = ptr; *end; end ++)
+ if (isspace(*end & 255) || *end == ',')
+ break;
+ }
- while (attr && attr->group_tag == IPP_TAG_PRINTER)
- {
- if (!strcmp(attr->name, "device-info") &&
- attr->value_tag == IPP_TAG_TEXT)
- device_info = attr->values[0].string.text;
+ /*
+ * Advance to the next name...
+ */
- if (!strcmp(attr->name, "device-make-and-model") &&
- attr->value_tag == IPP_TAG_TEXT)
- device_make_and_model = attr->values[0].string.text;
+ ptr = end;
+ }
- if (!strcmp(attr->name, "device-uri") &&
- attr->value_tag == IPP_TAG_URI)
- device_uri = attr->values[0].string.text;
+ /*
+ * Build a CUPS-Add-Printer/Class request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * requesting-user-name-{allowed,denied}
+ */
- attr = attr->next;
- }
+ request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER);
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+ printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ if (num_users == 0)
+ ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "requesting-user-name-allowed", NULL, "all");
+ else
+ {
+ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ type, num_users, NULL, NULL);
+ for (i = 0, ptr = (char *)users; *ptr; i ++)
+ {
/*
- * See if we have everything needed...
+ * Skip whitespace and commas...
*/
- if (device_info && device_make_and_model && device_uri &&
- strcasecmp(device_make_and_model, "unknown") &&
- strchr(device_uri, ':'))
+ while (*ptr == ',' || isspace(*ptr & 255))
+ ptr ++;
+
+ if (*ptr == '\'' || *ptr == '\"')
{
/*
- * Yes, now see if there is already a printer for this
- * device...
+ * Scan quoted name...
*/
- if (!cupsArrayFind(printer_devices, (void *)device_uri))
- {
- /*
- * Not found, so it must be a new printer...
- */
-
- char options[1024], /* Form variables for this device */
- *options_ptr; /* Pointer into string */
- const char *ptr; /* Pointer into device string */
+ quote = *ptr++;
+ for (end = ptr; *end; end ++)
+ if (*end == quote)
+ break;
+ }
+ else
+ {
+ /*
+ * Scan space or comma-delimited name...
+ */
- /*
- * Format the printer name variable for this device...
- *
- * We use the device-info string first, then device-uri,
- * and finally device-make-and-model to come up with a
- * suitable name.
- */
+ for (end = ptr; *end; end ++)
+ if (isspace(*end & 255) || *end == ',')
+ break;
+ }
- strcpy(options, "PRINTER_NAME=");
- options_ptr = options + strlen(options);
+ /*
+ * Terminate the name...
+ */
- if (strncasecmp(device_info, "unknown", 7))
- ptr = device_info;
- else if ((ptr = strstr(device_uri, "://")) != NULL)
- ptr += 3;
- else
- ptr = device_make_and_model;
+ if (*end)
+ *end++ = '\0';
- for (;
- options_ptr < (options + sizeof(options) - 1) && *ptr;
- ptr ++)
- if (isalnum(*ptr & 255) || *ptr == '_' || *ptr == '-' ||
- *ptr == '.')
- *options_ptr++ = *ptr;
- else if ((*ptr == ' ' || *ptr == '/') && options_ptr[-1] != '_')
- *options_ptr++ = '_';
- else if (*ptr == '?' || *ptr == '(')
- break;
+ /*
+ * Add the name...
+ */
- /*
- * Then add the make and model in the printer info, so
- * that MacOS clients see something reasonable...
- */
+ attr->values[i].string.text = strdup(ptr);
- strlcpy(options_ptr, "&PRINTER_LOCATION=Local+Printer"
- "&PRINTER_INFO=",
- sizeof(options) - (options_ptr - options));
- options_ptr += strlen(options_ptr);
+ /*
+ * Advance to the next name...
+ */
- cgiFormEncode(options_ptr, device_make_and_model,
- sizeof(options) - (options_ptr - options));
- options_ptr += strlen(options_ptr);
+ ptr = end;
+ }
+ }
- /*
- * Then copy the device URI...
- */
+ /*
+ * Do the request and get back a response...
+ */
- strlcpy(options_ptr, "&DEVICE_URI=",
- sizeof(options) - (options_ptr - options));
- options_ptr += strlen(options_ptr);
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
- cgiFormEncode(options_ptr, device_uri,
- sizeof(options) - (options_ptr - options));
- options_ptr += strlen(options_ptr);
+ if (cupsLastError() > IPP_OK_CONFLICT)
+ {
+ cgiStartHTML(cgiText(_("Set Allowed Users")));
+ cgiShowIPPError(_("Unable to change printer:"));
+ }
+ else
+ {
+ /*
+ * Redirect successful updates back to the printer page...
+ */
- if (options_ptr < (options + sizeof(options) - 1))
- {
- *options_ptr++ = '|';
- cgiFormEncode(options_ptr, device_make_and_model,
- sizeof(options) - (options_ptr - options));
- }
+ char url[1024], /* Printer/class URL */
+ refresh[1024]; /* Refresh URL */
- /*
- * Finally, set the form variables for this printer...
- */
- cgiSetArray("device_info", i, device_info);
- cgiSetArray("device_make_and_model", i, device_make_and_model);
- cgiSetArray("device_options", i, options);
- cgiSetArray("device_uri", i, device_uri);
- i ++;
- }
- }
+ cgiRewriteURL(uri, url, sizeof(url), NULL);
+ cgiFormEncode(uri, url, sizeof(uri));
+ snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s",
+ uri);
+ cgiSetVariable("refresh_page", refresh);
- if (!attr)
- break;
- }
+ cgiStartHTML(cgiText(_("Set Allowed Users")));
- ippDelete(response);
+ cgiCopyTemplateLang(is_class ? "class-modified.tmpl" :
+ "printer-modified.tmpl");
+ }
- /*
- * Free the device list...
- */
-
- for (printer_device = (char *)cupsArrayFirst(printer_devices);
- printer_device;
- printer_device = (char *)cupsArrayNext(printer_devices))
- free(printer_device);
-
- cupsArrayDelete(printer_devices);
- }
- }
-
- /*
- * See if Samba and the Windows drivers are installed...
- */
-
- if ((datadir = getenv("CUPS_DATADIR")) == NULL)
- datadir = CUPS_DATADIR;
-
- snprintf(filename, sizeof(filename), "%s/drivers/pscript5.dll", datadir);
- if (!access(filename, R_OK))
- {
- /*
- * Found Windows 2000 driver file, see if we have smbclient and
- * rpcclient...
- */
-
- if (cupsFileFind("smbclient", getenv("PATH"), 1, filename,
- sizeof(filename)) &&
- cupsFileFind("rpcclient", getenv("PATH"), 1, filename,
- sizeof(filename)))
- cgiSetVariable("HAVE_SAMBA", "Y");
- else
- {
- if (!cupsFileFind("smbclient", getenv("PATH"), 1, filename,
- sizeof(filename)))
- fputs("ERROR: smbclient not found!\n", stderr);
-
- if (!cupsFileFind("rpcclient", getenv("PATH"), 1, filename,
- sizeof(filename)))
- fputs("ERROR: rpcclient not found!\n", stderr);
- }
+ cgiEndHTML();
}
- else
- perror(filename);
-
- /*
- * Finally, show the main menu template...
- */
-
- cgiStartHTML(cgiText(_("Administration")));
-
- cgiCopyTemplateLang("admin.tmpl");
-
- cgiEndHTML();
}
/*
- * 'do_printer_op()' - Do a printer operation.
+ * 'do_set_options()' - Configure the default options for a queue.
*/
static void
-do_printer_op(http_t *http, /* I - HTTP connection */
- ipp_op_t op, /* I - Operation to perform */
- const char *title) /* I - Title of page */
+do_set_options(http_t *http, /* I - HTTP connection */
+ int is_class) /* I - Set options for class? */
{
- ipp_t *request; /* IPP request */
- char uri[HTTP_MAX_URI]; /* Printer URI */
- const char *printer, /* Printer name (purge-jobs) */
- *is_class; /* Is a class? */
+ int i, j, k, m; /* Looping vars */
+ int have_options; /* Have options? */
+ ipp_t *request, /* IPP request */
+ *response; /* IPP response */
+ ipp_attribute_t *attr; /* IPP attribute */
+ char uri[HTTP_MAX_URI]; /* Job URI */
+ const char *var; /* Variable value */
+ const char *printer; /* Printer printer name */
+ const char *filename; /* PPD filename */
+ char tempfile[1024]; /* Temporary filename */
+ cups_file_t *in, /* Input file */
+ *out; /* Output file */
+ char line[1024]; /* Line from PPD file */
+ char keyword[1024], /* Keyword from Default line */
+ *keyptr; /* Pointer into keyword... */
+ ppd_file_t *ppd; /* PPD file */
+ ppd_group_t *group; /* Option group */
+ ppd_option_t *option; /* Option */
+ ppd_attr_t *protocol; /* cupsProtocol attribute */
+ const char *title; /* Page title */
- is_class = cgiGetVariable("IS_CLASS");
- printer = cgiGetVariable("PRINTER_NAME");
+ title = cgiText(is_class ? _("Set Class Options") : _("Set Printer Options"));
- if (!printer)
+ fprintf(stderr, "DEBUG: do_set_options(http=%p, is_class=%d)\n", http,
+ is_class);
+
+ /*
+ * Get the printer name...
+ */
+
+ if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
+ printer);
+ else
{
cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
cgiStartHTML(title);
return;
}
+ fprintf(stderr, "DEBUG: printer=\"%s\", uri=\"%s\"...\n", printer, uri);
+
/*
- * Build a printer request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
+ * Get the PPD file...
*/
- request = ippNewRequest(op);
+ if (is_class)
+ filename = NULL;
+ else
+ filename = cupsGetPPD2(http, printer);
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
- printer);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
+ if (filename)
+ {
+ fprintf(stderr, "DEBUG: Got PPD file: \"%s\"\n", filename);
- /*
- * Do the request and get back a response...
- */
+ if ((ppd = ppdOpenFile(filename)) == NULL)
+ {
+ cgiSetVariable("ERROR", ppdErrorString(ppdLastError(&i)));
+ cgiSetVariable("MESSAGE", cgiText(_("Unable to open PPD file:")));
+ cgiStartHTML(title);
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
+ return;
+ }
+ }
+ else
+ {
+ fputs("DEBUG: No PPD file\n", stderr);
+ ppd = NULL;
+ }
- ippDelete(cupsDoRequest(http, request, "/admin/"));
+ if (cgiGetVariable("job_sheets_start") != NULL ||
+ cgiGetVariable("job_sheets_end") != NULL)
+ have_options = 1;
+ else
+ have_options = 0;
- if (cupsLastError() > IPP_OK_CONFLICT)
+ if (ppd)
{
- cgiStartHTML(title);
- cgiShowIPPError(_("Unable to change printer:"));
+ ppdMarkDefaults(ppd);
+
+ DEBUG_printf(("<P>ppd->num_groups = %d\n"
+ "<UL>\n", ppd->num_groups));
+
+ for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
+ {
+ DEBUG_printf(("<LI>%s<UL>\n", group->text));
+
+ for (j = group->num_options, option = group->options;
+ j > 0;
+ j --, option ++)
+ if ((var = cgiGetVariable(option->keyword)) != NULL)
+ {
+ DEBUG_printf(("<LI>%s = \"%s\"</LI>\n", option->keyword, var));
+ have_options = 1;
+ ppdMarkOption(ppd, option->keyword, var);
+ }
+#ifdef DEBUG
+ else
+ printf("<LI>%s not defined!</LI>\n", option->keyword);
+#endif /* DEBUG */
+
+ DEBUG_puts("</UL></LI>");
+ }
+
+ DEBUG_printf(("</UL>\n"
+ "<P>ppdConflicts(ppd) = %d\n", ppdConflicts(ppd)));
}
- else
+
+ if (!have_options || ppdConflicts(ppd))
{
/*
- * Redirect successful updates back to the printer page...
+ * Show the options to the user...
*/
- char url[1024], /* Printer/class URL */
- refresh[1024]; /* Refresh URL */
+ fputs("DEBUG: Showing options...\n", stderr);
+
+ cgiStartHTML(cgiText(_("Set Printer Options")));
+ cgiCopyTemplateLang("set-printer-options-header.tmpl");
+ if (ppd)
+ {
+ ppdLocalize(ppd);
- cgiRewriteURL(uri, url, sizeof(url), NULL);
- cgiFormEncode(uri, url, sizeof(uri));
- snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s", uri);
- cgiSetVariable("refresh_page", refresh);
+ if (ppdConflicts(ppd))
+ {
+ for (i = ppd->num_groups, k = 0, group = ppd->groups;
+ i > 0;
+ i --, group ++)
+ for (j = group->num_options, option = group->options;
+ j > 0;
+ j --, option ++)
+ if (option->conflicted)
+ {
+ cgiSetArray("ckeyword", k, option->keyword);
+ cgiSetArray("ckeytext", k, option->text);
+ k ++;
+ }
- cgiStartHTML(title);
+ cgiCopyTemplateLang("option-conflict.tmpl");
+ }
- if (op == IPP_PAUSE_PRINTER)
- cgiCopyTemplateLang("printer-stop.tmpl");
- else if (op == IPP_RESUME_PRINTER)
- cgiCopyTemplateLang("printer-start.tmpl");
- else if (op == CUPS_ACCEPT_JOBS)
- cgiCopyTemplateLang("printer-accept.tmpl");
- else if (op == CUPS_REJECT_JOBS)
- cgiCopyTemplateLang("printer-reject.tmpl");
- else if (op == IPP_PURGE_JOBS)
- cgiCopyTemplateLang("printer-purge.tmpl");
- else if (op == CUPS_SET_DEFAULT)
- cgiCopyTemplateLang("printer-default.tmpl");
- }
+ for (i = ppd->num_groups, group = ppd->groups;
+ i > 0;
+ i --, group ++)
+ {
+ if (!strcmp(group->name, "InstallableOptions"))
+ cgiSetVariable("GROUP", cgiText(_("Options Installed")));
+ else
+ cgiSetVariable("GROUP", group->text);
- cgiEndHTML();
-}
+ cgiCopyTemplateLang("option-header.tmpl");
+
+ for (j = group->num_options, option = group->options;
+ j > 0;
+ j --, option ++)
+ {
+ if (!strcmp(option->keyword, "PageRegion"))
+ continue;
+ cgiSetVariable("KEYWORD", option->keyword);
+ cgiSetVariable("KEYTEXT", option->text);
+
+ if (option->conflicted)
+ cgiSetVariable("CONFLICTED", "1");
+ else
+ cgiSetVariable("CONFLICTED", "0");
+
+ cgiSetSize("CHOICES", 0);
+ cgiSetSize("TEXT", 0);
+ for (k = 0, m = 0; k < option->num_choices; k ++)
+ {
+ /*
+ * Hide custom option values...
+ */
-/*
- * 'do_set_allowed_users()' - Set the allowed/denied users for a queue.
- */
+ if (!strcmp(option->choices[k].choice, "Custom"))
+ continue;
-static void
-do_set_allowed_users(http_t *http) /* I - HTTP connection */
-{
- int i; /* Looping var */
- ipp_t *request, /* IPP request */
- *response; /* IPP response */
- char uri[HTTP_MAX_URI]; /* Printer URI */
- const char *printer, /* Printer name (purge-jobs) */
- *is_class, /* Is a class? */
- *users, /* List of users or groups */
- *type; /* Allow/deny type */
- int num_users; /* Number of users */
- char *ptr, /* Pointer into users string */
- *end, /* Pointer to end of users string */
- quote; /* Quote character */
- ipp_attribute_t *attr; /* Attribute */
- static const char * const attrs[] = /* Requested attributes */
- {
- "requesting-user-name-allowed",
- "requesting-user-name-denied"
- };
+ cgiSetArray("CHOICES", m, option->choices[k].choice);
+ cgiSetArray("TEXT", m, option->choices[k].text);
+
+ m ++;
+
+ if (option->choices[k].marked)
+ cgiSetVariable("DEFCHOICE", option->choices[k].choice);
+ }
+
+ switch (option->ui)
+ {
+ case PPD_UI_BOOLEAN :
+ cgiCopyTemplateLang("option-boolean.tmpl");
+ break;
+ case PPD_UI_PICKONE :
+ cgiCopyTemplateLang("option-pickone.tmpl");
+ break;
+ case PPD_UI_PICKMANY :
+ cgiCopyTemplateLang("option-pickmany.tmpl");
+ break;
+ }
+ }
+
+ cgiCopyTemplateLang("option-trailer.tmpl");
+ }
+ }
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+
+ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
+ "localhost", 0, "/printers/%s", printer);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if ((attr = ippFindAttribute(response, "job-sheets-supported",
+ IPP_TAG_ZERO)) != NULL)
+ {
+ /*
+ * Add the job sheets options...
+ */
+
+ cgiSetVariable("GROUP", cgiText(_("Banners")));
+ cgiCopyTemplateLang("option-header.tmpl");
+
+ cgiSetSize("CHOICES", attr->num_values);
+ cgiSetSize("TEXT", attr->num_values);
+ for (k = 0; k < attr->num_values; k ++)
+ {
+ cgiSetArray("CHOICES", k, attr->values[k].string.text);
+ cgiSetArray("TEXT", k, attr->values[k].string.text);
+ }
+
+ attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO);
+
+ cgiSetVariable("KEYWORD", "job_sheets_start");
+ cgiSetVariable("KEYTEXT", cgiText(_("Starting Banner")));
+ cgiSetVariable("DEFCHOICE", attr == NULL ?
+ "" : attr->values[0].string.text);
+
+ cgiCopyTemplateLang("option-pickone.tmpl");
+
+ cgiSetVariable("KEYWORD", "job_sheets_end");
+ cgiSetVariable("KEYTEXT", cgiText(_("Ending Banner")));
+ cgiSetVariable("DEFCHOICE", attr == NULL && attr->num_values > 1 ?
+ "" : attr->values[1].string.text);
+
+ cgiCopyTemplateLang("option-pickone.tmpl");
+
+ cgiCopyTemplateLang("option-trailer.tmpl");
+ }
+
+ if (ippFindAttribute(response, "printer-error-policy-supported",
+ IPP_TAG_ZERO) ||
+ ippFindAttribute(response, "printer-op-policy-supported",
+ IPP_TAG_ZERO))
+ {
+ /*
+ * Add the error and operation policy options...
+ */
+
+ cgiSetVariable("GROUP", cgiText(_("Policies")));
+ cgiCopyTemplateLang("option-header.tmpl");
+
+ /*
+ * Error policy...
+ */
+
+ attr = ippFindAttribute(response, "printer-error-policy-supported",
+ IPP_TAG_ZERO);
+
+ if (attr)
+ {
+ cgiSetSize("CHOICES", attr->num_values);
+ cgiSetSize("TEXT", attr->num_values);
+ for (k = 0; k < attr->num_values; k ++)
+ {
+ cgiSetArray("CHOICES", k, attr->values[k].string.text);
+ cgiSetArray("TEXT", k, attr->values[k].string.text);
+ }
+ attr = ippFindAttribute(response, "printer-error-policy",
+ IPP_TAG_ZERO);
- is_class = cgiGetVariable("IS_CLASS");
- printer = cgiGetVariable("PRINTER_NAME");
+ cgiSetVariable("KEYWORD", "printer_error_policy");
+ cgiSetVariable("KEYTEXT", cgiText(_("Error Policy")));
+ cgiSetVariable("DEFCHOICE", attr == NULL ?
+ "" : attr->values[0].string.text);
+ }
- if (!printer)
- {
- cgiSetVariable("ERROR", cgiText(_("Missing form variable!")));
- cgiStartHTML(cgiText(_("Set Allowed Users")));
- cgiCopyTemplateLang("error.tmpl");
- cgiEndHTML();
- return;
- }
+ cgiCopyTemplateLang("option-pickone.tmpl");
- users = cgiGetVariable("users");
- type = cgiGetVariable("type");
+ /*
+ * Operation policy...
+ */
- if (!users || !type ||
- (strcmp(type, "requesting-user-name-allowed") &&
- strcmp(type, "requesting-user-name-denied")))
- {
- /*
- * Build a Get-Printer-Attributes request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requested-attributes
- */
+ attr = ippFindAttribute(response, "printer-op-policy-supported",
+ IPP_TAG_ZERO);
- request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES);
+ if (attr)
+ {
+ cgiSetSize("CHOICES", attr->num_values);
+ cgiSetSize("TEXT", attr->num_values);
+ for (k = 0; k < attr->num_values; k ++)
+ {
+ cgiSetArray("CHOICES", k, attr->values[k].string.text);
+ cgiSetArray("TEXT", k, attr->values[k].string.text);
+ }
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
- printer);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
+ attr = ippFindAttribute(response, "printer-op-policy", IPP_TAG_ZERO);
- ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
- "requested-attributes",
- (int)(sizeof(attrs) / sizeof(attrs[0])), NULL, attrs);
+ cgiSetVariable("KEYWORD", "printer_op_policy");
+ cgiSetVariable("KEYTEXT", cgiText(_("Operation Policy")));
+ cgiSetVariable("DEFCHOICE", attr == NULL ?
+ "" : attr->values[0].string.text);
- /*
- * Do the request and get back a response...
- */
+ cgiCopyTemplateLang("option-pickone.tmpl");
+ }
- if ((response = cupsDoRequest(http, request, "/")) != NULL)
- {
- cgiSetIPPVars(response, NULL, NULL, NULL, 0);
+ cgiCopyTemplateLang("option-trailer.tmpl");
+ }
ippDelete(response);
}
- cgiStartHTML(cgiText(_("Set Allowed Users")));
-
- if (cupsLastError() > IPP_OK_CONFLICT)
- cgiShowIPPError(_("Unable to get printer attributes:"));
- else
- cgiCopyTemplateLang("users.tmpl");
-
- cgiEndHTML();
- }
- else
- {
/*
- * Save the changes...
+ * Binary protocol support...
*/
- for (num_users = 0, ptr = (char *)users; *ptr; num_users ++)
+ if (ppd->protocols && strstr(ppd->protocols, "BCP"))
{
- /*
- * Skip whitespace and commas...
- */
-
- while (*ptr == ',' || isspace(*ptr & 255))
- ptr ++;
+ protocol = ppdFindAttr(ppd, "cupsProtocol", NULL);
- if (*ptr == '\'' || *ptr == '\"')
- {
- /*
- * Scan quoted name...
- */
+ cgiSetVariable("GROUP", cgiText(_("PS Binary Protocol")));
+ cgiCopyTemplateLang("option-header.tmpl");
- quote = *ptr++;
+ cgiSetSize("CHOICES", 2);
+ cgiSetSize("TEXT", 2);
+ cgiSetArray("CHOICES", 0, "None");
+ cgiSetArray("TEXT", 0, cgiText(_("None")));
- for (end = ptr; *end; end ++)
- if (*end == quote)
- break;
+ if (strstr(ppd->protocols, "TBCP"))
+ {
+ cgiSetArray("CHOICES", 1, "TBCP");
+ cgiSetArray("TEXT", 1, "TBCP");
}
else
{
- /*
- * Scan space or comma-delimited name...
- */
-
- for (end = ptr; *end; end ++)
- if (isspace(*end & 255) || *end == ',')
- break;
+ cgiSetArray("CHOICES", 1, "BCP");
+ cgiSetArray("TEXT", 1, "BCP");
}
- /*
- * Advance to the next name...
- */
+ cgiSetVariable("KEYWORD", "protocol");
+ cgiSetVariable("KEYTEXT", cgiText(_("PS Binary Protocol")));
+ cgiSetVariable("DEFCHOICE", protocol ? protocol->value : "None");
- ptr = end;
+ cgiCopyTemplateLang("option-pickone.tmpl");
+
+ cgiCopyTemplateLang("option-trailer.tmpl");
}
+ cgiCopyTemplateLang("set-printer-options-trailer.tmpl");
+ cgiEndHTML();
+ }
+ else
+ {
/*
- * Build a CUPS-Add-Printer/Class request, which requires the following
- * attributes:
- *
- * attributes-charset
- * attributes-natural-language
- * printer-uri
- * requesting-user-name-{allowed,denied}
+ * Set default options...
*/
- request = ippNewRequest(is_class ? CUPS_ADD_CLASS : CUPS_ADD_PRINTER);
-
- httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL,
- "localhost", 0, is_class ? "/classes/%s" : "/printers/%s",
- printer);
- ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
- NULL, uri);
+ fputs("DEBUG: Setting options...\n", stderr);
- if (num_users == 0)
- ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "requesting-user-name-allowed", NULL, "all");
- else
+ if (filename)
{
- attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
- type, num_users, NULL, NULL);
+ out = cupsTempFile2(tempfile, sizeof(tempfile));
+ in = cupsFileOpen(filename, "r");
- for (i = 0, ptr = (char *)users; *ptr; i ++)
+ if (!in || !out)
{
- /*
- * Skip whitespace and commas...
- */
+ cgiSetVariable("ERROR", strerror(errno));
+ cgiStartHTML(cgiText(_("Set Printer Options")));
+ cgiCopyTemplateLang("error.tmpl");
+ cgiEndHTML();
- while (*ptr == ',' || isspace(*ptr & 255))
- ptr ++;
+ if (in)
+ cupsFileClose(in);
- if (*ptr == '\'' || *ptr == '\"')
+ if (out)
{
- /*
- * Scan quoted name...
- */
+ cupsFileClose(out);
+ unlink(tempfile);
+ }
- quote = *ptr++;
+ unlink(filename);
+ return;
+ }
- for (end = ptr; *end; end ++)
- if (*end == quote)
- break;
- }
+ while (cupsFileGets(in, line, sizeof(line)))
+ {
+ if (!strncmp(line, "*cupsProtocol:", 14) && cgiGetVariable("protocol"))
+ continue;
+ else if (strncmp(line, "*Default", 8))
+ cupsFilePrintf(out, "%s\n", line);
else
{
/*
- * Scan space or comma-delimited name...
+ * Get default option name...
*/
- for (end = ptr; *end; end ++)
- if (isspace(*end & 255) || *end == ',')
+ strlcpy(keyword, line + 8, sizeof(keyword));
+
+ for (keyptr = keyword; *keyptr; keyptr ++)
+ if (*keyptr == ':' || isspace(*keyptr & 255))
break;
- }
- /*
- * Terminate the name...
- */
+ *keyptr = '\0';
- if (*end)
- *end++ = '\0';
+ if (!strcmp(keyword, "PageRegion") ||
+ !strcmp(keyword, "PaperDimension") ||
+ !strcmp(keyword, "ImageableArea"))
+ var = cgiGetVariable("PageSize");
+ else
+ var = cgiGetVariable(keyword);
- /*
- * Add the name...
- */
+ if (var != NULL)
+ cupsFilePrintf(out, "*Default%s: %s\n", keyword, var);
+ else
+ cupsFilePrintf(out, "%s\n", line);
+ }
+ }
- attr->values[i].string.text = strdup(ptr);
+ if ((var = cgiGetVariable("protocol")) != NULL)
+ cupsFilePrintf(out, "*cupsProtocol: %s\n", cgiGetVariable("protocol"));
- /*
- * Advance to the next name...
- */
+ cupsFileClose(in);
+ cupsFileClose(out);
+ }
+ else
+ {
+ /*
+ * Make sure temporary filename is cleared when there is no PPD...
+ */
- ptr = end;
- }
+ tempfile[0] = '\0';
}
+ /*
+ * Build a CUPS_ADD_MODIFY_CLASS/PRINTER request, which requires the
+ * following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ * job-sheets-default
+ * printer-error-policy
+ * printer-op-policy
+ * [ppd file]
+ */
+
+ request = ippNewRequest(is_class ? CUPS_ADD_MODIFY_CLASS :
+ CUPS_ADD_MODIFY_PRINTER);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, uri);
+
+ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "job-sheets-default", 2, NULL, NULL);
+ attr->values[0].string.text = _cupsStrAlloc(cgiGetVariable("job_sheets_start"));
+ attr->values[1].string.text = _cupsStrAlloc(cgiGetVariable("job_sheets_end"));
+
+ if ((var = cgiGetVariable("printer_error_policy")) != NULL)
+ attr = ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "printer-error-policy", NULL, var);
+
+ if ((var = cgiGetVariable("printer_op_policy")) != NULL)
+ attr = ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME,
+ "printer-op-policy", NULL, var);
+
/*
* Do the request and get back a response...
*/
- ippDelete(cupsDoRequest(http, request, "/admin/"));
+ if (filename)
+ ippDelete(cupsDoFileRequest(http, request, "/admin/", tempfile));
+ else
+ ippDelete(cupsDoRequest(http, request, "/admin/"));
if (cupsLastError() > IPP_OK_CONFLICT)
{
- cgiStartHTML(cgiText(_("Set Allowed Users")));
- cgiShowIPPError(_("Unable to change printer:"));
+ cgiStartHTML(title);
+ cgiShowIPPError(_("Unable to set options:"));
}
else
{
* Redirect successful updates back to the printer page...
*/
- char url[1024], /* Printer/class URL */
- refresh[1024]; /* Refresh URL */
+ char refresh[1024]; /* Refresh URL */
- cgiRewriteURL(uri, url, sizeof(url), NULL);
- cgiFormEncode(uri, url, sizeof(uri));
- snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=%s",
- uri);
+ cgiFormEncode(uri, printer, sizeof(uri));
+ snprintf(refresh, sizeof(refresh), "5;URL=/admin/?OP=redirect&URL=/%s/%s",
+ is_class ? "classes" : "printers", uri);
cgiSetVariable("refresh_page", refresh);
- cgiStartHTML(cgiText(_("Set Allowed Users")));
+ cgiStartHTML(title);
- cgiCopyTemplateLang(is_class ? "class-modified.tmpl" :
- "printer-modified.tmpl");
+ cgiCopyTemplateLang("printer-configured.tmpl");
}
cgiEndHTML();
+
+ if (filename)
+ unlink(tempfile);
}
+
+ if (filename)
+ unlink(filename);
}
/*
- * End of "$Id: admin.c 5572 2006-05-22 18:47:09Z mike $".
+ * End of "$Id: admin.c 6649 2007-07-11 21:46:42Z mike $".
*/