#include "ipp-var.h"
#include <ctype.h>
#include <errno.h>
static void do_am_class(http_t *http, cups_lang_t *language, int modify);
static void do_am_printer(http_t *http, cups_lang_t *language, int modify);
static void do_config_printer(http_t *http, cups_lang_t *language);
static void do_delete_class(http_t *http, cups_lang_t *language);
static void do_delete_printer(http_t *http, cups_lang_t *language);
static void do_printer_op(http_t *http, cups_lang_t *language, ipp_op_t op);
static char *get_line(char *buf, int length, FILE *fp);
int
main(int argc,
char *argv[])
{
cups_lang_t *language;
http_t *http;
const char *op;
language = cupsLangDefault();
printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language));
cgiSetVariable("TITLE", "Admin");
ippSetServerVersion();
cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG"));
if (!cgiInitialize())
{
cgiCopyTemplateLang(stdout, TEMPLATES, "admin.tmpl", getenv("LANG"));
}
else if ((op = cgiGetVariable("OP")) != NULL)
{
http = httpConnectEncrypt("localhost", ippPort(), cupsEncryption());
if (strcmp(op, "start-printer") == 0)
do_printer_op(http, language, IPP_RESUME_PRINTER);
else if (strcmp(op, "stop-printer") == 0)
do_printer_op(http, language, IPP_PAUSE_PRINTER);
else if (strcmp(op, "accept-jobs") == 0)
do_printer_op(http, language, CUPS_ACCEPT_JOBS);
else if (strcmp(op, "reject-jobs") == 0)
do_printer_op(http, language, CUPS_REJECT_JOBS);
else if (strcmp(op, "purge-jobs") == 0)
do_printer_op(http, language, IPP_PURGE_JOBS);
else if (strcmp(op, "add-class") == 0)
do_am_class(http, language, 0);
else if (strcmp(op, "add-printer") == 0)
do_am_printer(http, language, 0);
else if (strcmp(op, "modify-class") == 0)
do_am_class(http, language, 1);
else if (strcmp(op, "modify-printer") == 0)
do_am_printer(http, language, 1);
else if (strcmp(op, "delete-class") == 0)
do_delete_class(http, language);
else if (strcmp(op, "delete-printer") == 0)
do_delete_printer(http, language);
else if (strcmp(op, "config-printer") == 0)
do_config_printer(http, language);
else
{
cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG"));
}
httpClose(http);
}
else
{
cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG"));
}
cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG"));
cupsLangFree(language);
return (0);
}
static void
do_am_class(http_t *http,
cups_lang_t *language,
int modify)
{
int i, j;
int element;
int num_printers;
ipp_t *request,
*response;
ipp_attribute_t *attr;
ipp_status_t status;
char uri[HTTP_MAX_URI];
const char *name,
*ptr;
if (cgiGetVariable("PRINTER_LOCATION") == NULL)
{
if (modify)
{
request = ippNew();
request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
cgiGetVariable("PRINTER_NAME"));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
ippSetCGIVars(response, NULL, NULL, NULL, 0);
ippDelete(response);
}
cgiCopyTemplateLang(stdout, TEMPLATES, "modify-class.tmpl", getenv("LANG"));
}
else
{
cgiCopyTemplateLang(stdout, TEMPLATES, "add-class.tmpl", getenv("LANG"));
}
return;
}
name = cgiGetVariable("PRINTER_NAME");
for (ptr = name; *ptr; ptr ++)
if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/')
break;
if (*ptr || ptr == name || strlen(name) > 127)
{
cgiSetVariable("ERROR", "The class name may only contain up to 127 printable "
"characters.");
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
return;
}
if (cgiGetVariable("MEMBER_URIS") == NULL)
{
request = ippNew();
request->request.op.operation_id = CUPS_GET_PRINTERS;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, "ipp://localhost/printers");
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
for (element = 0, attr = response->attrs;
attr != NULL;
attr = attr->next)
if (attr->name && strcmp(attr->name, "printer-uri-supported") == 0)
{
cgiSetArray("MEMBER_URIS", element, attr->values[0].string.text);
element ++;
}
for (element = 0, attr = response->attrs;
attr != NULL;
attr = attr->next)
if (attr->name && strcmp(attr->name, "printer-name") == 0)
{
cgiSetArray("MEMBER_NAMES", element, attr->values[0].string.text);
element ++;
}
num_printers = cgiGetSize("MEMBER_URIS");
ippDelete(response);
}
else
num_printers = 0;
request = ippNew();
request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
cgiGetVariable("PRINTER_NAME"));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL)
{
for (j = 0; j < num_printers; j ++)
cgiSetArray("MEMBER_SELECTED", j, "");
for (i = 0; i < attr->num_values; i ++)
for (j = 0; j < num_printers; j ++)
if (strcmp(attr->values[i].string.text, cgiGetArray("MEMBER_URIS", j)) == 0)
{
cgiSetArray("MEMBER_SELECTED", j, "SELECTED");
break;
}
}
ippDelete(response);
}
cgiCopyTemplateLang(stdout, TEMPLATES, "choose-members.tmpl", getenv("LANG"));
}
else
{
request = ippNew();
request->request.op.operation_id = CUPS_ADD_CLASS;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s",
cgiGetVariable("PRINTER_NAME"));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
NULL, cgiGetVariable("PRINTER_LOCATION"));
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
NULL, cgiGetVariable("PRINTER_INFO"));
ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
IPP_PRINTER_IDLE);
if ((num_printers = cgiGetSize("MEMBER_URIS")) > 0)
{
attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris",
num_printers, NULL, NULL);
for (i = 0; i < num_printers; i ++)
attr->values[i].string.text = strdup(cgiGetArray("MEMBER_URIS", i));
}
if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
{
status = response->request.status.status_code;
ippDelete(response);
}
else
status = cupsLastError();
if (status > IPP_OK_CONFLICT)
{
cgiSetVariable("ERROR", ippErrorString(status));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
else if (modify)
cgiCopyTemplateLang(stdout, TEMPLATES, "class-modified.tmpl", getenv("LANG"));
else
cgiCopyTemplateLang(stdout, TEMPLATES, "class-added.tmpl", getenv("LANG"));
}
}
static void
do_am_printer(http_t *http,
cups_lang_t *language,
int modify)
{
int i;
int element;
ipp_attribute_t *attr,
*last;
ipp_t *request,
*response,
*oldinfo;
ipp_status_t status;
const char *var;
char uri[HTTP_MAX_URI],
*uriptr;
int maxrate;
char baudrate[255];
char make[255];
const char *name,
*ptr;
static int baudrates[] =
{
1200,
2400,
4800,
9600,
19200,
38400,
57600,
115200,
230400,
460800
};
if (modify)
{
request = ippNew();
request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
cgiGetVariable("PRINTER_NAME"));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
oldinfo = cupsDoRequest(http, request, "/");
}
else
oldinfo = NULL;
if ((name = cgiGetVariable("PRINTER_NAME")) == NULL ||
cgiGetVariable("PRINTER_LOCATION") == NULL)
{
if (modify)
{
if (oldinfo)
ippSetCGIVars(oldinfo, NULL, NULL, NULL, 0);
cgiCopyTemplateLang(stdout, TEMPLATES, "modify-printer.tmpl", getenv("LANG"));
}
else
{
cgiCopyTemplateLang(stdout, TEMPLATES, "add-printer.tmpl", getenv("LANG"));
}
if (oldinfo)
ippDelete(oldinfo);
return;
}
for (ptr = name; *ptr; ptr ++)
if ((*ptr >= 0 && *ptr <= ' ') || *ptr == 127 || *ptr == '/')
break;
if (*ptr || ptr == name || strlen(name) > 127)
{
cgiSetVariable("ERROR", "The printer name may only contain up to 127 printable "
"characters.");
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
return;
}
if ((var = cgiGetVariable("DEVICE_URI")) == NULL)
{
request = ippNew();
request->request.op.operation_id = CUPS_GET_DEVICES;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, "ipp://localhost/printers/");
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
ippSetCGIVars(response, NULL, NULL, NULL, 0);
ippDelete(response);
}
if (oldinfo &&
(attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
{
strlcpy(uri, attr->values[0].string.text, sizeof(uri));
if ((uriptr = strchr(uri, ':')) != NULL && strncmp(uriptr, "://", 3) == 0)
*uriptr = '\0';
cgiSetVariable("CURRENT_DEVICE_URI", uri);
}
cgiCopyTemplateLang(stdout, TEMPLATES, "choose-device.tmpl", getenv("LANG"));
}
else if (strchr(var, '/') == NULL)
{
if (oldinfo &&
(attr = ippFindAttribute(oldinfo, "device-uri", IPP_TAG_URI)) != NULL)
{
if (strncmp(attr->values[0].string.text, var, strlen(var)) == 0)
cgiSetVariable("DEVICE_URI", attr->values[0].string.text);
}
cgiCopyTemplateLang(stdout, TEMPLATES, "choose-uri.tmpl", getenv("LANG"));
}
else if (strncmp(var, "serial:", 7) == 0 && cgiGetVariable("BAUDRATE") == NULL)
{
if ((var = strchr(var, '?')) != NULL &&
strncmp(var, "?baud=", 6) == 0)
maxrate = atoi(var + 6);
else
maxrate = 19200;
for (i = 0; i < 10; i ++)
if (baudrates[i] > maxrate)
break;
else
{
sprintf(baudrate, "%d", baudrates[i]);
cgiSetArray("BAUDRATES", i, baudrate);
}
cgiCopyTemplateLang(stdout, TEMPLATES, "choose-serial.tmpl", getenv("LANG"));
}
else if ((var = cgiGetVariable("PPD_NAME")) == NULL)
{
if (modify)
{
int fd;
char filename[1024];
ppd_file_t *ppd;
char buffer[1024];
int bytes;
snprintf(uri, sizeof(uri), "/printers/%s.ppd", name);
if (httpGet(http, uri))
httpGet(http, uri);
while (httpUpdate(http) == HTTP_CONTINUE);
if ((fd = cupsTempFd(filename, sizeof(filename))) >= 0)
{
while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0)
write(fd, buffer, bytes);
close(fd);
if ((ppd = ppdOpenFile(filename)) != NULL)
{
if (ppd->manufacturer)
cgiSetVariable("CURRENT_MAKE", ppd->manufacturer);
if (ppd->nickname)
cgiSetVariable("CURRENT_MAKE_AND_MODEL", ppd->nickname);
ppdClose(ppd);
}
unlink(filename);
}
else
httpFlush(http);
}
request = ippNew();
request->request.op.operation_id = CUPS_GET_PPDS;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, "ipp://localhost/printers/");
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
if ((var = cgiGetVariable("PPD_MAKE")) == NULL)
{
for (element = 0, attr = response->attrs, last = NULL;
attr != NULL;
attr = attr->next)
if (attr->name && strcmp(attr->name, "ppd-make") == 0)
if (last == NULL ||
strcasecmp(last->values[0].string.text,
attr->values[0].string.text) != 0)
{
cgiSetArray("PPD_MAKE", element, attr->values[0].string.text);
element ++;
last = attr;
}
cgiCopyTemplateLang(stdout, TEMPLATES, "choose-make.tmpl",
getenv("LANG"));
}
else
{
strlcpy(make, var, sizeof(make));
ippSetCGIVars(response, "ppd-make", make, NULL, 0);
cgiCopyTemplateLang(stdout, TEMPLATES, "choose-model.tmpl",
getenv("LANG"));
}
ippDelete(response);
}
else
{
char message[1024];
snprintf(message, sizeof(message), "Unable to get list of printer drivers: %s",
ippErrorString(cupsLastError()));
cgiSetVariable("ERROR", message);
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
}
else
{
request = ippNew();
request->request.op.operation_id = CUPS_ADD_PRINTER;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
cgiGetVariable("PRINTER_NAME"));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
NULL, cgiGetVariable("PRINTER_LOCATION"));
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
NULL, cgiGetVariable("PRINTER_INFO"));
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name",
NULL, cgiGetVariable("PPD_NAME"));
strlcpy(uri, cgiGetVariable("DEVICE_URI"), sizeof(uri));
if (strncmp(uri, "serial:", 7) == 0)
{
if ((uriptr = strchr(uri, '?')) == NULL)
uriptr = uri + strlen(uri);
snprintf(uriptr, sizeof(uri) - (uriptr - uri),
"?baud=%s+bits=%s+parity=%s+flow=%s",
cgiGetVariable("BAUDRATE"), cgiGetVariable("BITS"),
cgiGetVariable("PARITY"), cgiGetVariable("FLOW"));
}
ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri",
NULL, uri);
ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
IPP_PRINTER_IDLE);
if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
{
status = response->request.status.status_code;
ippDelete(response);
}
else
status = cupsLastError();
if (status > IPP_OK_CONFLICT)
{
cgiSetVariable("ERROR", ippErrorString(status));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
else if (modify)
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-modified.tmpl", getenv("LANG"));
else
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-added.tmpl", getenv("LANG"));
}
if (oldinfo)
ippDelete(oldinfo);
}
static void
do_config_printer(http_t *http,
cups_lang_t *language)
{
int i, j, k;
int have_options;
ipp_t *request,
*response;
ipp_attribute_t *attr;
char uri[HTTP_MAX_URI];
const char *var;
const char *printer;
ipp_status_t status;
const char *filename;
char tempfile[1024];
FILE *in,
*out;
int outfd;
char line[1024];
char keyword[1024],
*keyptr;
ppd_file_t *ppd;
ppd_group_t *group;
ppd_option_t *option;
ppd_attr_t *protocol;
if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
else
{
cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
return;
}
cupsSetServer("localhost");
if ((filename = cupsGetPPD(printer)) == NULL)
{
if (cupsLastError() == IPP_NOT_FOUND)
{
cgiSetVariable("ERROR", ippErrorString(IPP_NOT_POSSIBLE));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
else
{
cgiSetVariable("ERROR", ippErrorString(cupsLastError()));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
return;
}
ppd = ppdOpenFile(filename);
if (cgiGetVariable("job_sheets_start") != NULL ||
cgiGetVariable("job_sheets_end") != NULL)
have_options = 1;
else
have_options = 0;
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_puts("</UL></LI>");
}
DEBUG_printf(("</UL>\n"
"<P>ppdConflicts(ppd) = %d\n", ppdConflicts(ppd)));
if (!have_options || ppdConflicts(ppd))
{
cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer.tmpl",
getenv("LANG"));
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 ++;
}
cgiCopyTemplateLang(stdout, TEMPLATES, "option-conflict.tmpl",
getenv("LANG"));
}
for (i = ppd->num_groups, group = ppd->groups;
i > 0;
i --, group ++)
{
if (strcmp(group->text, "InstallableOptions") == 0)
cgiSetVariable("GROUP",
cupsLangString(language, CUPS_MSG_OPTIONS_INSTALLED));
else
cgiSetVariable("GROUP", group->text);
cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
getenv("LANG"));
for (j = group->num_options, option = group->options;
j > 0;
j --, option ++)
{
if (strcmp(option->keyword, "PageRegion") == 0)
continue;
cgiSetVariable("KEYWORD", option->keyword);
cgiSetVariable("KEYTEXT", option->text);
if (option->conflicted)
cgiSetVariable("CONFLICTED", "1");
else
cgiSetVariable("CONFLICTED", "0");
cgiSetSize("CHOICES", option->num_choices);
cgiSetSize("TEXT", option->num_choices);
for (k = 0; k < option->num_choices; k ++)
{
cgiSetArray("CHOICES", k, option->choices[k].choice);
cgiSetArray("TEXT", k, option->choices[k].text);
if (option->choices[k].marked)
cgiSetVariable("DEFCHOICE", option->choices[k].choice);
}
switch (option->ui)
{
case PPD_UI_BOOLEAN :
cgiCopyTemplateLang(stdout, TEMPLATES, "option-boolean.tmpl",
getenv("LANG"));
break;
case PPD_UI_PICKONE :
cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
getenv("LANG"));
break;
case PPD_UI_PICKMANY :
cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickmany.tmpl",
getenv("LANG"));
break;
}
}
cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
getenv("LANG"));
}
request = ippNew();
request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
cgiGetVariable("PRINTER_NAME"));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
if ((response = cupsDoRequest(http, request, "/")) != NULL)
{
if ((attr = ippFindAttribute(response, "job-sheets-supported", IPP_TAG_ZERO)) != NULL)
{
cgiSetVariable("GROUP", "Banners");
cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
getenv("LANG"));
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", "Starting Banner");
cgiSetVariable("DEFCHOICE", attr == NULL ?
"" : attr->values[0].string.text);
cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
getenv("LANG"));
cgiSetVariable("KEYWORD", "job_sheets_end");
cgiSetVariable("KEYTEXT", "Ending Banner");
cgiSetVariable("DEFCHOICE", attr == NULL && attr->num_values > 1 ?
"" : attr->values[1].string.text);
cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
getenv("LANG"));
cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
getenv("LANG"));
}
ippDelete(response);
}
if (ppd->protocols && strstr(ppd->protocols, "BCP"))
{
protocol = ppdFindAttr(ppd, "cupsProtocol", NULL);
cgiSetVariable("GROUP", "PS Binary Protocol");
cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl",
getenv("LANG"));
cgiSetSize("CHOICES", 2);
cgiSetSize("TEXT", 2);
cgiSetArray("CHOICES", 0, "None");
cgiSetArray("TEXT", 0, "None");
if (strstr(ppd->protocols, "TBCP"))
{
cgiSetArray("CHOICES", 1, "TBCP");
cgiSetArray("TEXT", 1, "TBCP");
}
else
{
cgiSetArray("CHOICES", 1, "BCP");
cgiSetArray("TEXT", 1, "BCP");
}
cgiSetVariable("KEYWORD", "protocol");
cgiSetVariable("KEYTEXT", "PS Binary Protocol");
cgiSetVariable("DEFCHOICE", protocol ? protocol->value : "None");
cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl",
getenv("LANG"));
cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl",
getenv("LANG"));
}
cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer2.tmpl",
getenv("LANG"));
}
else
{
outfd = cupsTempFd(tempfile, sizeof(tempfile));
in = fopen(filename, "rb");
out = fdopen(outfd, "wb");
if (outfd < 0 || in == NULL || out == NULL)
{
cgiSetVariable("ERROR", strerror(errno));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
unlink(filename);
return;
}
while (get_line(line, sizeof(line), in) != NULL)
{
if (!strncmp(line, "*cupsProtocol:", 14) && cgiGetVariable("protocol"))
continue;
else if (strncmp(line, "*Default", 8))
fprintf(out, "%s\n", line);
else
{
strlcpy(keyword, line + 8, sizeof(keyword));
for (keyptr = keyword; *keyptr; keyptr ++)
if (*keyptr == ':' || isspace(*keyptr))
break;
*keyptr = '\0';
if (strcmp(keyword, "PageRegion") == 0)
var = cgiGetVariable("PageSize");
else
var = cgiGetVariable(keyword);
if (var != NULL)
fprintf(out, "*Default%s: %s\n", keyword, var);
else
fprintf(out, "%s\n", line);
}
}
if ((var = cgiGetVariable("protocol")) != NULL)
fprintf(out, "*cupsProtocol: %s\n", cgiGetVariable("protocol"));
fclose(in);
fclose(out);
close(outfd);
request = ippNew();
request->request.op.operation_id = CUPS_ADD_PRINTER;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s",
cgiGetVariable("PRINTER_NAME"));
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 = strdup(cgiGetVariable("job_sheets_start"));
attr->values[1].string.text = strdup(cgiGetVariable("job_sheets_end"));
if ((response = cupsDoFileRequest(http, request, "/admin/", tempfile)) != NULL)
{
status = response->request.status.status_code;
ippDelete(response);
}
else
status = cupsLastError();
if (status > IPP_OK_CONFLICT)
{
cgiSetVariable("ERROR", ippErrorString(status));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
else
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-configured.tmpl", getenv("LANG"));
unlink(tempfile);
}
unlink(filename);
}
static void
do_delete_class(http_t *http,
cups_lang_t *language)
{
ipp_t *request,
*response;
char uri[HTTP_MAX_URI];
const char *pclass;
ipp_status_t status;
if (cgiGetVariable("CONFIRM") == NULL)
{
cgiCopyTemplateLang(stdout, TEMPLATES, "class-confirm.tmpl", getenv("LANG"));
return;
}
if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL)
snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass);
else
{
cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
return;
}
request = ippNew();
request->request.op.operation_id = CUPS_DELETE_CLASS;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
{
status = response->request.status.status_code;
ippDelete(response);
}
else
status = cupsLastError();
if (status > IPP_OK_CONFLICT)
{
cgiSetVariable("ERROR", ippErrorString(status));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
else
cgiCopyTemplateLang(stdout, TEMPLATES, "class-deleted.tmpl", getenv("LANG"));
}
static void
do_delete_printer(http_t *http,
cups_lang_t *language)
{
ipp_t *request,
*response;
char uri[HTTP_MAX_URI];
const char *printer;
ipp_status_t status;
if (cgiGetVariable("CONFIRM") == NULL)
{
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-confirm.tmpl", getenv("LANG"));
return;
}
if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
else
{
cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
return;
}
request = ippNew();
request->request.op.operation_id = CUPS_DELETE_PRINTER;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
{
status = response->request.status.status_code;
ippDelete(response);
}
else
status = cupsLastError();
if (status > IPP_OK_CONFLICT)
{
cgiSetVariable("ERROR", ippErrorString(status));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
else
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-deleted.tmpl", getenv("LANG"));
}
static void
do_printer_op(http_t *http,
cups_lang_t *language,
ipp_op_t op)
{
ipp_t *request,
*response;
char uri[HTTP_MAX_URI];
const char *printer;
ipp_status_t status;
if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL)
snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer);
else
{
cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
return;
}
request = ippNew();
request->request.op.operation_id = op;
request->request.op.request_id = 1;
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
"attributes-charset", NULL, cupsLangEncoding(language));
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
"attributes-natural-language", NULL, language->language);
ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
NULL, uri);
if ((response = cupsDoRequest(http, request, "/admin/")) != NULL)
{
status = response->request.status.status_code;
ippDelete(response);
}
else
status = cupsLastError();
if (status > IPP_OK_CONFLICT)
{
cgiSetVariable("ERROR", ippErrorString(status));
cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG"));
}
else if (op == IPP_PAUSE_PRINTER)
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-stop.tmpl", getenv("LANG"));
else if (op == IPP_RESUME_PRINTER)
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-start.tmpl", getenv("LANG"));
else if (op == CUPS_ACCEPT_JOBS)
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-accept.tmpl", getenv("LANG"));
else if (op == CUPS_REJECT_JOBS)
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-reject.tmpl", getenv("LANG"));
else if (op == IPP_PURGE_JOBS)
cgiCopyTemplateLang(stdout, TEMPLATES, "printer-purge.tmpl", getenv("LANG"));
}
static char *
get_line(char *buf,
int length,
FILE *fp)
{
char *bufptr;
int ch;
length --;
bufptr = buf;
while ((ch = getc(fp)) != EOF)
{
if (ch == '\n')
break;
else if (ch == '\r')
{
ch = getc(fp);
if (ch != '\n' && ch != EOF)
ungetc(ch, fp);
break;
}
*bufptr++ = ch;
length --;
if (length == 0)
break;
}
*bufptr = '\0';
if (ch == EOF)
return (NULL);
else
return (buf);
}