int /* O - 1 if all variables present, 0 otherwise */ cgiCheckVariables(const char *names) /* I - Variables to look for */ { char name[255], /* Current variable name */ *s; /* Pointer in string */ const char *val; /* Value of variable */ int element; /* Array element number */ if (names == NULL) return (1); while (*names != '\0') { while (*names == ' ' || *names == ',') names ++; for (s = name; *names != '\0' && *names != ' ' && *names != ','; s ++, names ++) *s = *names; *s = 0; if (name[0] == '\0') break; if ((s = strrchr(name, '-')) != NULL) { *s = '\0'; element = atoi(s + 1) - 1; val = cgiGetArray(name, element); } else val = cgiGetVariable(name); if (val == NULL) return (0); if (*val == '\0') return (0); /* Can't be blank, either! */ } return (1); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { const char *printer; /* Printer name */ const char *user; /* Username */ http_t *http; /* Connection to the server */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* IPP attribute */ const char *op; /* Operation to perform, if any */ static const char *def_attrs[] = /* Attributes for default printer */ { "printer-name", "printer-uri-supported" }; /* * Get any form variables... */ cgiInitialize(); op = cgiGetVariable("OP"); /* * Set the web interface section... */ cgiSetVariable("SECTION", "printers"); cgiSetVariable("REFRESH_PAGE", ""); /* * See if we are displaying a printer or all printers... */ if ((printer = getenv("PATH_INFO")) != NULL) { printer ++; if (!*printer) printer = NULL; if (printer) cgiSetVariable("PRINTER_NAME", printer); } /* * See who is logged in... */ user = getenv("REMOTE_USER"); /* * Connect to the HTTP server... */ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); /* * Get the default printer... */ if (!op || !cgiIsPOST()) { /* * Get the default destination... */ request = ippNewRequest(CUPS_GET_DEFAULT); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs); if ((response = cupsDoRequest(http, request, "/")) != NULL) { if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL) cgiSetVariable("DEFAULT_NAME", attr->values[0].string.text); if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL) { char url[HTTP_MAX_URI]; /* New URL */ cgiSetVariable("DEFAULT_URI", cgiRewriteURL(attr->values[0].string.text, url, sizeof(url), NULL)); } ippDelete(response); } /* * See if we need to show a list of printers or the status of a * single printer... */ if (!printer) show_all_printers(http, user); else show_printer(http, printer); } else if (printer) { if (!*op) { const char *server_port = getenv("SERVER_PORT"); /* Port number string */ int port = atoi(server_port ? server_port : "0"); /* Port number */ char uri[1024]; /* URL */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), getenv("HTTPS") ? "https" : "http", NULL, getenv("SERVER_NAME"), port, "/printers/%s", printer); printf("Location: %s\n\n", uri); } else if (!strcmp(op, "start-printer")) do_printer_op(http, printer, IPP_RESUME_PRINTER, cgiText(_("Resume Printer"))); else if (!strcmp(op, "stop-printer")) do_printer_op(http, printer, IPP_PAUSE_PRINTER, cgiText(_("Pause Printer"))); else if (!strcmp(op, "accept-jobs")) do_printer_op(http, printer, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs"))); else if (!strcmp(op, "reject-jobs")) do_printer_op(http, printer, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs"))); else if (!strcmp(op, "purge-jobs")) do_printer_op(http, printer, IPP_PURGE_JOBS, cgiText(_("Purge Jobs"))); else if (!_cups_strcasecmp(op, "print-self-test-page")) cgiPrintCommand(http, printer, "PrintSelfTestPage", cgiText(_("Print Self-Test Page"))); else if (!_cups_strcasecmp(op, "clean-print-heads")) cgiPrintCommand(http, printer, "Clean all", cgiText(_("Clean Print Heads"))); else if (!_cups_strcasecmp(op, "print-test-page")) cgiPrintTestPage(http, printer); else if (!_cups_strcasecmp(op, "move-jobs")) cgiMoveJobs(http, printer, 0); else { /* * Unknown/bad operation... */ cgiStartHTML(printer); cgiCopyTemplateLang("error-op.tmpl"); cgiEndHTML(); } } else { /* * Unknown/bad operation... */ cgiStartHTML(cgiText(_("Printers"))); cgiCopyTemplateLang("error-op.tmpl"); cgiEndHTML(); } /* * Close the HTTP server connection... */ httpClose(http); /* * Return with no errors... */ return (0); }
static void show_all_printers(http_t *http, /* I - Connection to server */ const char *user) /* I - Username */ { int i; /* Looping var */ ipp_t *request, /* IPP request */ *response; /* IPP response */ cups_array_t *printers; /* Array of printer objects */ ipp_attribute_t *printer; /* Printer object */ int ascending, /* Order of printers (0 = descending) */ first, /* First printer to show */ count; /* Number of printers */ const char *var; /* Form variable */ void *search; /* Search data */ char val[1024]; /* Form variable */ fprintf(stderr, "DEBUG: show_all_printers(http=%p, user=\"%s\")\n", http, user ? user : "******"); /* * Show the standard header... */ cgiStartHTML(cgiText(_("Printers"))); /* * Build a CUPS_GET_PRINTERS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-type * printer-type-mask * requesting-user-name */ 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); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); cgiGetAttributes(request, "printers.tmpl"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { /* * Get a list of matching job objects. */ if ((var = cgiGetVariable("QUERY")) != NULL && !cgiGetVariable("CLEAR")) search = cgiCompileSearch(var); else search = NULL; printers = cgiGetIPPObjects(response, search); count = cupsArrayCount(printers); if (search) cgiFreeSearch(search); /* * Figure out which printers to display... */ if ((var = cgiGetVariable("FIRST")) != NULL) first = atoi(var); else first = 0; if (first >= count) first = count - CUPS_PAGE_MAX; first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX; if (first < 0) first = 0; sprintf(val, "%d", count); cgiSetVariable("TOTAL", val); if ((var = cgiGetVariable("ORDER")) != NULL && *var) ascending = !_cups_strcasecmp(var, "asc"); else ascending = 1; if (ascending) { for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, first); i < CUPS_PAGE_MAX && printer; i ++, printer = (ipp_attribute_t *)cupsArrayNext(printers)) cgiSetIPPObjectVars(printer, NULL, i); } else { for (i = 0, printer = (ipp_attribute_t *)cupsArrayIndex(printers, count - first - 1); i < CUPS_PAGE_MAX && printer; i ++, printer = (ipp_attribute_t *)cupsArrayPrev(printers)) cgiSetIPPObjectVars(printer, NULL, i); } /* * Save navigation URLs... */ cgiSetVariable("THISURL", "/printers/"); if (first > 0) { sprintf(val, "%d", first - CUPS_PAGE_MAX); cgiSetVariable("PREV", val); } if ((first + CUPS_PAGE_MAX) < count) { sprintf(val, "%d", first + CUPS_PAGE_MAX); cgiSetVariable("NEXT", val); } /* * Then show everything... */ cgiCopyTemplateLang("search.tmpl"); cgiCopyTemplateLang("printers-header.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); cgiCopyTemplateLang("printers.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); /* * Delete the response... */ cupsArrayDelete(printers); ippDelete(response); } else { /* * Show the error... */ cgiShowIPPError(_("Unable to get printer list")); } cgiEndHTML(); }
static void show_all_classes(http_t *http, /* I - Connection to server */ const char *user) /* I - Username */ { int i; /* Looping var */ ipp_t *request, /* IPP request */ *response; /* IPP response */ cups_array_t *classes; /* Array of class objects */ ipp_attribute_t *pclass; /* Class object */ int first, /* First class to show */ count; /* Number of classes */ const char *var; /* Form variable */ void *search; /* Search data */ char val[1024]; /* Form variable */ /* * Show the standard header... */ cgiStartHTML(cgiText(_("Classes"))); /* * Build a CUPS_GET_CLASSES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requesting-user-name */ request = ippNewRequest(CUPS_GET_CLASSES); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); cgiGetAttributes(request, "classes.tmpl"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { /* * Get a list of matching job objects. */ if ((var = cgiGetVariable("QUERY")) != NULL && !cgiGetVariable("CLEAR")) search = cgiCompileSearch(var); else search = NULL; classes = cgiGetIPPObjects(response, search); count = cupsArrayCount(classes); if (search) cgiFreeSearch(search); /* * Figure out which classes to display... */ if ((var = cgiGetVariable("FIRST")) != NULL) first = atoi(var); else first = 0; if (first >= count) first = count - CUPS_PAGE_MAX; first = (first / CUPS_PAGE_MAX) * CUPS_PAGE_MAX; if (first < 0) first = 0; sprintf(val, "%d", count); cgiSetVariable("TOTAL", val); for (i = 0, pclass = (ipp_attribute_t *)cupsArrayIndex(classes, first); i < CUPS_PAGE_MAX && pclass; i ++, pclass = (ipp_attribute_t *)cupsArrayNext(classes)) cgiSetIPPObjectVars(pclass, NULL, i); /* * Save navigation URLs... */ cgiSetVariable("THISURL", "/classes/"); if (first > 0) { sprintf(val, "%d", first - CUPS_PAGE_MAX); cgiSetVariable("PREV", val); } if ((first + CUPS_PAGE_MAX) < count) { sprintf(val, "%d", first + CUPS_PAGE_MAX); cgiSetVariable("NEXT", val); } if (count > CUPS_PAGE_MAX) { snprintf(val, sizeof(val), "%d", CUPS_PAGE_MAX * (count / CUPS_PAGE_MAX)); cgiSetVariable("LAST", val); } /* * Then show everything... */ cgiCopyTemplateLang("search.tmpl"); cgiCopyTemplateLang("classes-header.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); cgiCopyTemplateLang("classes.tmpl"); if (count > CUPS_PAGE_MAX) cgiCopyTemplateLang("pager.tmpl"); /* * Delete the response... */ cupsArrayDelete(classes); ippDelete(response); } else { /* * Show the error... */ cgiShowIPPError(_("Unable to get class list")); } cgiEndHTML(); }
static int /* O - 1 if form data was read */ cgi_initialize_multipart( const char *boundary) /* I - Boundary string */ { char line[10240], /* MIME header line */ name[1024], /* Form variable name */ filename[1024], /* Form filename */ mimetype[1024], /* MIME media type */ bstring[256], /* Boundary string to look for */ *ptr, /* Pointer into name/filename */ *end; /* End of buffer */ int ch, /* Character from file */ fd; /* Temporary file descriptor */ size_t blen; /* Length of boundary string */ DEBUG_printf(("cgi_initialize_multipart(boundary=\"%s\")\n", boundary)); /* * Read multipart form data until we run out... */ name[0] = '\0'; filename[0] = '\0'; mimetype[0] = '\0'; snprintf(bstring, sizeof(bstring), "\r\n--%s", boundary); blen = strlen(bstring); while (fgets(line, sizeof(line), stdin)) { if (!strcmp(line, "\r\n")) { /* * End of headers, grab value... */ if (filename[0]) { /* * Read an embedded file... */ if (form_file) { /* * Remove previous file... */ cgi_unlink_file(); } /* * Allocate memory for the new file... */ if ((form_file = calloc(1, sizeof(cgi_file_t))) == NULL) return (0); form_file->name = strdup(name); form_file->filename = strdup(filename); form_file->mimetype = strdup(mimetype); fd = cupsTempFd(form_file->tempfile, sizeof(form_file->tempfile)); if (fd < 0) return (0); atexit(cgi_unlink_file); /* * Copy file data to the temp file... */ ptr = line; while ((ch = getchar()) != EOF) { *ptr++ = (char)ch; if ((size_t)(ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen)) { ptr -= blen; break; } if ((ptr - line - (int)blen) >= 8192) { /* * Write out the first 8k of the buffer... */ write(fd, line, 8192); memmove(line, line + 8192, (size_t)(ptr - line - 8192)); ptr -= 8192; } } /* * Write the rest of the data and close the temp file... */ if (ptr > line) write(fd, line, (size_t)(ptr - line)); close(fd); } else { /* * Just get a form variable; the current code only handles * form values up to 10k in size... */ ptr = line; end = line + sizeof(line) - 1; while ((ch = getchar()) != EOF) { if (ptr < end) *ptr++ = (char)ch; if ((size_t)(ptr - line) >= blen && !memcmp(ptr - blen, bstring, blen)) { ptr -= blen; break; } } *ptr = '\0'; /* * Set the form variable... */ if ((ptr = strrchr(name, '-')) != NULL && isdigit(ptr[1] & 255)) { /* * Set a specific index in the array... */ *ptr++ = '\0'; if (line[0]) cgiSetArray(name, atoi(ptr) - 1, line); } else if (cgiGetVariable(name)) { /* * Add another element in the array... */ cgiSetArray(name, cgiGetSize(name), line); } else { /* * Just set the line... */ cgiSetVariable(name, line); } } /* * Read the rest of the current line... */ fgets(line, sizeof(line), stdin); /* * Clear the state vars... */ name[0] = '\0'; filename[0] = '\0'; mimetype[0] = '\0'; } else if (!_cups_strncasecmp(line, "Content-Disposition:", 20)) { if ((ptr = strstr(line + 20, " name=\"")) != NULL) { strlcpy(name, ptr + 7, sizeof(name)); if ((ptr = strchr(name, '\"')) != NULL) *ptr = '\0'; } if ((ptr = strstr(line + 20, " filename=\"")) != NULL) { strlcpy(filename, ptr + 11, sizeof(filename)); if ((ptr = strchr(filename, '\"')) != NULL) *ptr = '\0'; } } else if (!_cups_strncasecmp(line, "Content-Type:", 13)) { for (ptr = line + 13; isspace(*ptr & 255); ptr ++); strlcpy(mimetype, ptr, sizeof(mimetype)); for (ptr = mimetype + strlen(mimetype) - 1; ptr > mimetype && isspace(*ptr & 255); *ptr-- = '\0'); } } /* * Return 1 for "form data found"... */ return (1); }
static int /* O - 1 if form data was processed */ cgi_initialize_string(const char *data) /* I - Form data string */ { int done; /* True if we're done reading a form variable */ char *s, /* Pointer to current form string */ ch, /* Temporary character */ name[255], /* Name of form variable */ value[65536]; /* Variable value */ /* * Check input... */ if (data == NULL) return (0); /* * Loop until we've read all the form data... */ while (*data != '\0') { /* * Get the variable name... */ for (s = name; *data != '\0'; data ++) if (*data == '=') break; else if (*data >= ' ' && s < (name + sizeof(name) - 1)) *s++ = *data; *s = '\0'; if (*data == '=') data ++; else return (0); /* * Read the variable value... */ for (s = value, done = 0; !done && *data != '\0'; data ++) switch (*data) { case '&' : /* End of data... */ done = 1; break; case '+' : /* Escaped space character */ if (s < (value + sizeof(value) - 1)) *s++ = ' '; break; case '%' : /* Escaped control character */ /* * Read the hex code... */ if (!isxdigit(data[1] & 255) || !isxdigit(data[2] & 255)) return (0); if (s < (value + sizeof(value) - 1)) { data ++; ch = *data - '0'; if (ch > 9) ch -= 7; *s = (char)(ch << 4); data ++; ch = *data - '0'; if (ch > 9) ch -= 7; *s++ |= ch; } else data += 2; break; default : /* Other characters come straight through */ if (*data >= ' ' && s < (value + sizeof(value) - 1)) *s++ = *data; break; } *s = '\0'; /* nul terminate the string */ /* * Remove trailing whitespace... */ if (s > value) s --; while (s >= value && isspace(*s & 255)) *s-- = '\0'; /* * Add the string to the variable "database"... */ if ((s = strrchr(name, '-')) != NULL && isdigit(s[1] & 255)) { *s++ = '\0'; if (value[0]) cgiSetArray(name, atoi(s) - 1, value); } else if (cgiGetVariable(name) != NULL) cgiSetArray(name, cgiGetSize(name), value); else cgiSetVariable(name, value); } return (1); }
int /* O - Non-zero if there was form data */ cgiInitialize(void) { const char *method, /* Form posting method */ *content_type, /* Content-Type of post data */ *cups_sid_cookie, /* SID cookie */ *cups_sid_form; /* SID form variable */ /* * Setup a password callback for authentication... */ cupsSetPasswordCB(cgi_passwd); /* * Set the locale so that times, etc. are formatted properly... */ setlocale(LC_ALL, ""); #ifdef DEBUG /* * Disable output buffering to find bugs... */ setbuf(stdout, NULL); #endif /* DEBUG */ /* * Get cookies... */ cgi_initialize_cookies(); if ((cups_sid_cookie = cgiGetCookie(CUPS_SID)) == NULL) { fputs("DEBUG: " CUPS_SID " cookie not found, initializing!\n", stderr); cups_sid_cookie = cgi_set_sid(); } fprintf(stderr, "DEBUG: " CUPS_SID " cookie is \"%s\"\n", cups_sid_cookie); /* * Get the request method (GET or POST)... */ method = getenv("REQUEST_METHOD"); content_type = getenv("CONTENT_TYPE"); if (!method) return (0); /* * Grab form data from the corresponding location... */ if (!_cups_strcasecmp(method, "GET")) return (cgi_initialize_get()); else if (!_cups_strcasecmp(method, "POST") && content_type) { const char *boundary = strstr(content_type, "boundary="); if (boundary) boundary += 9; if (content_type && !strncmp(content_type, "multipart/form-data; ", 21)) { if (!cgi_initialize_multipart(boundary)) return (0); } else if (!cgi_initialize_post()) return (0); if ((cups_sid_form = cgiGetVariable(CUPS_SID)) == NULL || strcmp(cups_sid_cookie, cups_sid_form)) { if (cups_sid_form) fprintf(stderr, "DEBUG: " CUPS_SID " form variable is \"%s\"\n", cups_sid_form); else fputs("DEBUG: " CUPS_SID " form variable is not present.\n", stderr); cgiClearVariables(); return (0); } else return (1); } else return (0); }
void cgiPrintTestPage(http_t *http, /* I - Connection to server */ const char *dest) /* I - Destination printer/class */ { ipp_t *request, /* IPP request */ *response; /* IPP response */ char uri[HTTP_MAX_URI], /* Printer URI */ resource[1024], /* POST resource path */ refresh[1024], /* Refresh URL */ filename[1024]; /* Test page filename */ const char *datadir; /* CUPS_DATADIR env var */ const char *user; /* Username */ /* * See who is logged in... */ user = getenv("REMOTE_USER"); /* * Locate the test page file... */ if ((datadir = getenv("CUPS_DATADIR")) == NULL) datadir = CUPS_DATADIR; snprintf(filename, sizeof(filename), "%s/data/testprint.ps", datadir); /* * Point to the printer/class... */ snprintf(resource, sizeof(resource), "/%s/%s", cgiGetVariable("SECTION"), dest); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"), dest); /* * Build an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * document-format */ request = ippNewRequest(IPP_PRINT_JOB); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, "Test Page"); ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", NULL, "application/postscript"); /* * Do the request and get back a response... */ if ((response = cupsDoFileRequest(http, request, resource, filename)) != NULL) { cgiSetIPPVars(response, NULL, NULL, NULL, 0); ippDelete(response); } if (cupsLastError() <= IPP_OK_CONFLICT) { /* * Automatically reload the printer status page... */ cgiFormEncode(uri, resource, sizeof(uri)); snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); cgiSetVariable("refresh_page", refresh); } else if (cupsLastError() == IPP_NOT_AUTHORIZED) { puts("Status: 401\n"); exit(0); } cgiStartHTML(cgiText(_("Print Test Page"))); if (cupsLastError() > IPP_OK_CONFLICT) cgiShowIPPError(_("Unable to print test page:")); else { cgiSetVariable("PRINTER_NAME", dest); cgiCopyTemplateLang("test-page.tmpl"); } cgiEndHTML(); }
void cgiMoveJobs(http_t *http, /* I - Connection to server */ const char *dest, /* I - Destination or NULL */ int job_id) /* I - Job ID or 0 for all */ { int i; /* Looping var */ const char *user; /* Username */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* Current attribute */ const char *name; /* Destination name */ const char *job_printer_uri; /* JOB_PRINTER_URI form variable */ char current_dest[1024]; /* Current destination */ /* * See who is logged in... */ if ((user = getenv("REMOTE_USER")) == NULL) user = "******"; /* * See if the user has already selected a new destination... */ if ((job_printer_uri = cgiGetVariable("JOB_PRINTER_URI")) == NULL) { /* * Make sure necessary form variables are set... */ if (job_id) { char temp[255]; /* Temporary string */ sprintf(temp, "%d", job_id); cgiSetVariable("JOB_ID", temp); } if (dest) cgiSetVariable("PRINTER_NAME", dest); /* * No new destination specified, show the user what the available * printers/classes are... */ if (!dest) { /* * Get the current destination for job N... */ char job_uri[1024]; /* Job URI */ request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, job_uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "job-printer-uri"); if ((response = cupsDoRequest(http, request, "/")) != NULL) { if ((attr = ippFindAttribute(response, "job-printer-uri", IPP_TAG_URI)) != NULL) { /* * Pull the name from the URI... */ strlcpy(current_dest, strrchr(attr->values[0].string.text, '/') + 1, sizeof(current_dest)); dest = current_dest; } ippDelete(response); } if (!dest) { /* * Couldn't get the current destination... */ cgiStartHTML(cgiText(_("Move Job"))); cgiShowIPPError(_("Unable to find destination for job!")); cgiEndHTML(); return; } } /* * Get the list of available destinations... */ request = ippNewRequest(CUPS_GET_PRINTERS); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-uri-supported"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); if ((response = cupsDoRequest(http, request, "/")) != NULL) { for (i = 0, attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI); attr; attr = ippFindNextAttribute(response, "printer-uri-supported", IPP_TAG_URI)) { /* * Pull the name from the URI... */ name = strrchr(attr->values[0].string.text, '/') + 1; /* * If the name is not the same as the current destination, add it! */ if (strcasecmp(name, dest)) { cgiSetArray("JOB_PRINTER_URI", i, attr->values[0].string.text); cgiSetArray("JOB_PRINTER_NAME", i, name); i ++; } } ippDelete(response); } /* * Show the form... */ if (job_id) cgiStartHTML(cgiText(_("Move Job"))); else cgiStartHTML(cgiText(_("Move All Jobs"))); cgiCopyTemplateLang("job-move.tmpl"); } else { /* * Try moving the job or jobs... */ char uri[1024], /* Job/printer URI */ resource[1024], /* Post resource */ refresh[1024]; /* Refresh URL */ const char *job_printer_name; /* New printer name */ request = ippNewRequest(CUPS_MOVE_JOB); if (job_id) { /* * Move 1 job... */ snprintf(resource, sizeof(resource), "/jobs/%d", job_id); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } else { /* * Move all active jobs on a destination... */ snprintf(resource, sizeof(resource), "/%s/%s", cgiGetVariable("SECTION"), dest); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"), dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-printer-uri", NULL, job_printer_uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippDelete(cupsDoRequest(http, request, resource)); /* * Show the results... */ job_printer_name = strrchr(job_printer_uri, '/') + 1; if (cupsLastError() <= IPP_OK_CONFLICT) { const char *path = strstr(job_printer_uri, "/printers/"); if (!path) path = strstr(job_printer_uri, "/classes/"); if (path) { cgiFormEncode(uri, path, sizeof(uri)); snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); cgiSetVariable("refresh_page", refresh); } } if (job_id) cgiStartHTML(cgiText(_("Move Job"))); else cgiStartHTML(cgiText(_("Move All Jobs"))); if (cupsLastError() > IPP_OK_CONFLICT) { if (job_id) cgiShowIPPError(_("Unable to move job")); else cgiShowIPPError(_("Unable to move jobs")); } else { cgiSetVariable("JOB_PRINTER_NAME", job_printer_name); cgiCopyTemplateLang("job-moved.tmpl"); } } cgiEndHTML(); }
int /* O - Exit status */ main(void) { http_t *http; /* Connection to the server */ const char *op; /* Operation name */ const char *job_id_var; /* Job ID form variable */ int job_id; /* Job ID */ /* * Get any form variables... */ cgiInitialize(); /* * Set the web interface section... */ cgiSetVariable("SECTION", "jobs"); cgiSetVariable("REFRESH_PAGE", ""); /* * Connect to the HTTP server... */ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); /* * Get the job ID, if any... */ if ((job_id_var = cgiGetVariable("JOB_ID")) != NULL) job_id = atoi(job_id_var); else job_id = 0; /* * Do the operation... */ if ((op = cgiGetVariable("OP")) != NULL && job_id > 0 && cgiIsPOST()) { /* * Do the operation... */ if (!strcmp(op, "cancel-job")) do_job_op(http, job_id, IPP_CANCEL_JOB); else if (!strcmp(op, "hold-job")) do_job_op(http, job_id, IPP_HOLD_JOB); else if (!strcmp(op, "move-job")) cgiMoveJobs(http, NULL, job_id); else if (!strcmp(op, "release-job")) do_job_op(http, job_id, IPP_RELEASE_JOB); else if (!strcmp(op, "restart-job")) do_job_op(http, job_id, IPP_RESTART_JOB); else { /* * Bad operation code... Display an error... */ cgiStartHTML(cgiText(_("Jobs"))); cgiCopyTemplateLang("error-op.tmpl"); cgiEndHTML(); } } else { /* * Show a list of jobs... */ cgiStartHTML(cgiText(_("Jobs"))); cgiShowJobs(http, NULL); cgiEndHTML(); } /* * Close the HTTP server connection... */ httpClose(http); /* * Return with no errors... */ return (0); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { help_index_t *hi, /* Help index */ *si; /* Search index */ help_node_t *n; /* Current help node */ int i; /* Looping var */ const char *query; /* Search query */ const char *cache_dir; /* CUPS_CACHEDIR environment variable */ const char *docroot; /* CUPS_DOCROOT environment variable */ const char *helpfile, /* Current help file */ *helptitle = NULL; /* Current help title */ const char *topic; /* Current topic */ char topic_data[1024]; /* Topic form data */ const char *section; /* Current section */ char filename[1024], /* Filename */ directory[1024]; /* Directory */ cups_file_t *fp; /* Help file */ char line[1024]; /* Line from file */ int printable; /* Show printable version? */ /* * Get any form variables... */ cgiInitialize(); printable = cgiGetVariable("PRINTABLE") != NULL; /* * Set the web interface section... */ cgiSetVariable("SECTION", "help"); cgiSetVariable("REFRESH_PAGE", ""); /* * Load the help index... */ if ((cache_dir = getenv("CUPS_CACHEDIR")) == NULL) cache_dir = CUPS_CACHEDIR; snprintf(filename, sizeof(filename), "%s/help.index", cache_dir); if ((docroot = getenv("CUPS_DOCROOT")) == NULL) docroot = CUPS_DOCROOT; snprintf(directory, sizeof(directory), "%s/help", docroot); fprintf(stderr, "DEBUG: helpLoadIndex(filename=\"%s\", directory=\"%s\")\n", filename, directory); hi = helpLoadIndex(filename, directory); if (!hi) { perror(filename); cgiStartHTML(cgiText(_("Online Help"))); cgiSetVariable("ERROR", cgiText(_("Unable to load help index."))); cgiCopyTemplateLang("error.tmpl"); cgiEndHTML(); return (1); } fprintf(stderr, "DEBUG: %d nodes in help index...\n", cupsArrayCount(hi->nodes)); /* * See if we are viewing a file... */ for (i = 0; i < argc; i ++) fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); if ((helpfile = getenv("PATH_INFO")) != NULL) { helpfile ++; if (!*helpfile) helpfile = NULL; } if (helpfile) { /* * Verify that the help file exists and is part of the index... */ snprintf(filename, sizeof(filename), "%s/help/%s", docroot, helpfile); fprintf(stderr, "DEBUG: helpfile=\"%s\", filename=\"%s\"\n", helpfile, filename); if (access(filename, R_OK)) { perror(filename); cgiStartHTML(cgiText(_("Online Help"))); cgiSetVariable("ERROR", cgiText(_("Unable to access help file."))); cgiCopyTemplateLang("error.tmpl"); cgiEndHTML(); return (1); } if ((n = helpFindNode(hi, helpfile, NULL)) == NULL) { cgiStartHTML(cgiText(_("Online Help"))); cgiSetVariable("ERROR", cgiText(_("Help file not in index."))); cgiCopyTemplateLang("error.tmpl"); cgiEndHTML(); return (1); } /* * Save the page title and help file... */ helptitle = n->text; topic = n->section; /* * Send a standard page header... */ if (printable) puts("Content-Type: text/html;charset=utf-8\n"); else cgiStartHTML(n->text); } else { /* * Send a standard page header... */ cgiStartHTML(cgiText(_("Online Help"))); topic = cgiGetVariable("TOPIC"); } /* * Do a search as needed... */ if (cgiGetVariable("CLEAR")) cgiSetVariable("QUERY", ""); query = cgiGetVariable("QUERY"); si = helpSearchIndex(hi, query, topic, helpfile); cgiClearVariables(); if (query) cgiSetVariable("QUERY", query); if (topic) cgiSetVariable("TOPIC", topic); if (helpfile) cgiSetVariable("HELPFILE", helpfile); if (helptitle) cgiSetVariable("HELPTITLE", helptitle); fprintf(stderr, "DEBUG: query=\"%s\", topic=\"%s\"\n", query ? query : "(null)", topic ? topic : "(null)"); if (si) { help_node_t *nn; /* Parent node */ fprintf(stderr, "DEBUG: si=%p, si->sorted=%p, cupsArrayCount(si->sorted)=%d\n", si, si->sorted, cupsArrayCount(si->sorted)); for (i = 0, n = (help_node_t *)cupsArrayFirst(si->sorted); n; i ++, n = (help_node_t *)cupsArrayNext(si->sorted)) { if (helpfile && n->anchor) snprintf(line, sizeof(line), "#%s", n->anchor); else if (n->anchor) snprintf(line, sizeof(line), "/help/%s?QUERY=%s#%s", n->filename, query ? query : "", n->anchor); else snprintf(line, sizeof(line), "/help/%s?QUERY=%s", n->filename, query ? query : ""); cgiSetArray("QTEXT", i, n->text); cgiSetArray("QLINK", i, line); if (!helpfile && n->anchor) { nn = helpFindNode(hi, n->filename, NULL); snprintf(line, sizeof(line), "/help/%s?QUERY=%s", nn->filename, query ? query : ""); cgiSetArray("QPTEXT", i, nn->text); cgiSetArray("QPLINK", i, line); } else { cgiSetArray("QPTEXT", i, ""); cgiSetArray("QPLINK", i, ""); } fprintf(stderr, "DEBUG: [%d] = \"%s\" @ \"%s\"\n", i, n->text, line); } helpDeleteIndex(si); } /* * OK, now list the bookmarks within the index... */ for (i = 0, section = NULL, n = (help_node_t *)cupsArrayFirst(hi->sorted); n; n = (help_node_t *)cupsArrayNext(hi->sorted)) { if (n->anchor) continue; /* * Add a section link as needed... */ if (n->section && (!section || strcmp(n->section, section))) { /* * Add a link for this node... */ snprintf(line, sizeof(line), "/help/?TOPIC=%s&QUERY=%s", cgiFormEncode(topic_data, n->section, sizeof(topic_data)), query ? query : ""); cgiSetArray("BMLINK", i, line); cgiSetArray("BMTEXT", i, n->section); cgiSetArray("BMINDENT", i, "0"); i ++; section = n->section; } if (!topic || strcmp(n->section, topic)) continue; /* * Add a link for this node... */ snprintf(line, sizeof(line), "/help/%s?TOPIC=%s&QUERY=%s", n->filename, cgiFormEncode(topic_data, n->section, sizeof(topic_data)), query ? query : ""); cgiSetArray("BMLINK", i, line); cgiSetArray("BMTEXT", i, n->text); cgiSetArray("BMINDENT", i, "1"); i ++; if (helpfile && !strcmp(helpfile, n->filename)) { help_node_t *nn; /* Pointer to sub-node */ cupsArraySave(hi->sorted); for (nn = (help_node_t *)cupsArrayFirst(hi->sorted); nn; nn = (help_node_t *)cupsArrayNext(hi->sorted)) if (nn->anchor && !strcmp(helpfile, nn->filename)) { /* * Add a link for this node... */ snprintf(line, sizeof(line), "#%s", nn->anchor); cgiSetArray("BMLINK", i, line); cgiSetArray("BMTEXT", i, nn->text); cgiSetArray("BMINDENT", i, "2"); i ++; } cupsArrayRestore(hi->sorted); } } /* * Show the search and bookmark content... */ if (!helpfile || !printable) cgiCopyTemplateLang("help-header.tmpl"); else cgiCopyTemplateLang("help-printable.tmpl"); /* * If we are viewing a file, copy it in now... */ if (helpfile) { if ((fp = cupsFileOpen(filename, "r")) != NULL) { int inbody; /* Are we inside the body? */ inbody = 0; while (cupsFileGets(fp, line, sizeof(line))) { if (inbody) { if (!_cups_strncasecmp(line, "</BODY>", 7)) break; printf("%s\n", line); } else if (!_cups_strncasecmp(line, "<BODY", 5)) inbody = 1; } cupsFileClose(fp); } else { perror(filename); cgiSetVariable("ERROR", cgiText(_("Unable to open help file."))); cgiCopyTemplateLang("error.tmpl"); } } /* * Send a standard trailer... */ if (!printable) { cgiCopyTemplateLang("help-trailer.tmpl"); cgiEndHTML(); } else puts("</BODY>\n</HTML>"); /* * Delete the index... */ helpDeleteIndex(hi); /* * Return with no errors... */ return (0); }
static void cgi_copy(FILE *out, /* I - Output file */ FILE *in, /* I - Input file */ int element, /* I - Element number (0 to N) */ char term, /* I - Terminating character */ int indent) /* I - Debug info indentation */ { int ch; /* Character from file */ char op; /* Operation */ char name[255], /* Name of variable */ *nameptr, /* Pointer into name */ innername[255], /* Inner comparison name */ *innerptr, /* Pointer into inner name */ *s; /* String pointer */ const char *value; /* Value of variable */ const char *innerval; /* Inner value */ const char *outptr; /* Output string pointer */ char outval[1024], /* Formatted output string */ compare[1024]; /* Comparison string */ int result; /* Result of comparison */ int uriencode; /* Encode as URI */ regex_t re; /* Regular expression to match */ fprintf(stderr, "DEBUG2: %*sStarting at file position %ld...\n", indent, "", ftell(in)); /* * Parse the file to the end... */ while ((ch = getc(in)) != EOF) if (ch == term) break; else if (ch == '{') { /* * Get a variable name... */ uriencode = 0; for (s = name; (ch = getc(in)) != EOF;) if (strchr("}]<>=!~ \t\n", ch)) break; else if (s == name && ch == '%') uriencode = 1; else if (s > name && ch == '?') break; else if (s < (name + sizeof(name) - 1)) *s++ = ch; *s = '\0'; if (s == name && isspace(ch & 255)) { fprintf(stderr, "DEBUG2: %*sLone { at %ld...\n", indent, "", ftell(in)); if (out) { putc('{', out); putc(ch, out); } continue; } if (ch == '}') fprintf(stderr, "DEBUG2: %*s\"{%s}\" at %ld...\n", indent, "", name, ftell(in)); /* * See if it has a value... */ if (name[0] == '?') { /* * Insert value only if it exists... */ if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1] & 255)) { *nameptr++ = '\0'; if ((value = cgiGetArray(name + 1, atoi(nameptr) - 1)) != NULL) outptr = value; else { outval[0] = '\0'; outptr = outval; } } else if ((value = cgiGetArray(name + 1, element)) != NULL) outptr = value; else { outval[0] = '\0'; outptr = outval; } } else if (name[0] == '#') { /* * Insert count... */ if (name[1]) sprintf(outval, "%d", cgiGetSize(name + 1)); else sprintf(outval, "%d", element + 1); outptr = outval; } else if (name[0] == '[') { /* * Loop for # of elements... */ int i; /* Looping var */ long pos; /* File position */ int count; /* Number of elements */ if (isdigit(name[1] & 255)) count = atoi(name + 1); else count = cgiGetSize(name + 1); pos = ftell(in); fprintf(stderr, "DEBUG2: %*sLooping on \"%s\" at %ld, count=%d...\n", indent, "", name + 1, pos, count); if (count > 0) { for (i = 0; i < count; i ++) { if (i) fseek(in, pos, SEEK_SET); cgi_copy(out, in, i, '}', indent + 2); } } else cgi_copy(NULL, in, 0, '}', indent + 2); fprintf(stderr, "DEBUG2: %*sFinished looping on \"%s\"...\n", indent, "", name + 1); continue; } else if (name[0] == '$') { /* * Insert cookie value or nothing if not defined. */ if ((value = cgiGetCookie(name + 1)) != NULL) outptr = value; else { outval[0] = '\0'; outptr = outval; } } else { /* * Insert variable or variable name (if element is NULL)... */ if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1] & 255)) { *nameptr++ = '\0'; if ((value = cgiGetArray(name, atoi(nameptr) - 1)) == NULL) { snprintf(outval, sizeof(outval), "{%s}", name); outptr = outval; } else outptr = value; } else if ((value = cgiGetArray(name, element)) == NULL) { snprintf(outval, sizeof(outval), "{%s}", name); outptr = outval; } else outptr = value; } /* * See if the terminating character requires another test... */ if (ch == '}') { /* * End of substitution... */ if (out) { if (uriencode) cgi_puturi(outptr, out); else if (!_cups_strcasecmp(name, "?cupsdconf_default")) fputs(outptr, stdout); else cgi_puts(outptr, out); } continue; } /* * OK, process one of the following checks: * * {name?exist:not-exist} Exists? * {name=value?true:false} Equal * {name<value?true:false} Less than * {name>value?true:false} Greater than * {name!value?true:false} Not equal * {name~refex?true:false} Regex match */ op = ch; if (ch == '?') { /* * Test for existance... */ if (name[0] == '?') result = cgiGetArray(name + 1, element) != NULL; else if (name[0] == '#') result = cgiGetVariable(name + 1) != NULL; else result = cgiGetArray(name, element) != NULL; result = result && outptr[0]; compare[0] = '\0'; } else { /* * Compare to a string... */ for (s = compare; (ch = getc(in)) != EOF;) if (ch == '?') break; else if (s >= (compare + sizeof(compare) - 1)) continue; else if (ch == '#') { sprintf(s, "%d", element + 1); s += strlen(s); } else if (ch == '{') { /* * Grab the value of a variable... */ innerptr = innername; while ((ch = getc(in)) != EOF && ch != '}') if (innerptr < (innername + sizeof(innername) - 1)) *innerptr++ = ch; *innerptr = '\0'; if (innername[0] == '#') sprintf(s, "%d", cgiGetSize(innername + 1)); else if ((innerptr = strrchr(innername, '-')) != NULL && isdigit(innerptr[1] & 255)) { *innerptr++ = '\0'; if ((innerval = cgiGetArray(innername, atoi(innerptr) - 1)) == NULL) *s = '\0'; else strlcpy(s, innerval, sizeof(compare) - (s - compare)); } else if (innername[0] == '?') { if ((innerval = cgiGetArray(innername + 1, element)) == NULL) *s = '\0'; else strlcpy(s, innerval, sizeof(compare) - (s - compare)); } else if ((innerval = cgiGetArray(innername, element)) == NULL) snprintf(s, sizeof(compare) - (s - compare), "{%s}", innername); else strlcpy(s, innerval, sizeof(compare) - (s - compare)); s += strlen(s); } else if (ch == '\\') *s++ = getc(in); else *s++ = ch; *s = '\0'; if (ch != '?') { fprintf(stderr, "DEBUG2: %*sBad terminator '%c' at file position %ld...\n", indent, "", ch, ftell(in)); return; } /* * Do the comparison... */ switch (op) { case '<' : result = _cups_strcasecmp(outptr, compare) < 0; break; case '>' : result = _cups_strcasecmp(outptr, compare) > 0; break; case '=' : result = _cups_strcasecmp(outptr, compare) == 0; break; case '!' : result = _cups_strcasecmp(outptr, compare) != 0; break; case '~' : fprintf(stderr, "DEBUG: Regular expression \"%s\"\n", compare); if (regcomp(&re, compare, REG_EXTENDED | REG_ICASE)) { fprintf(stderr, "ERROR: Unable to compile regular expresion \"%s\"!\n", compare); result = 0; } else { regmatch_t matches[10]; result = 0; if (!regexec(&re, outptr, 10, matches, 0)) { int i; for (i = 0; i < 10; i ++) { fprintf(stderr, "DEBUG: matches[%d].rm_so=%d\n", i, (int)matches[i].rm_so); if (matches[i].rm_so < 0) break; result ++; } } regfree(&re); } break; default : result = 1; break; } } fprintf(stderr, "DEBUG2: %*sStarting \"{%s%c%s\" at %ld, result=%d...\n", indent, "", name, op, compare, ftell(in), result); if (result) { /* * Comparison true; output first part and ignore second... */ fprintf(stderr, "DEBUG2: %*sOutput first part...\n", indent, ""); cgi_copy(out, in, element, ':', indent + 2); fprintf(stderr, "DEBUG2: %*sSkip second part...\n", indent, ""); cgi_copy(NULL, in, element, '}', indent + 2); } else { /* * Comparison false; ignore first part and output second... */ fprintf(stderr, "DEBUG2: %*sSkip first part...\n", indent, ""); cgi_copy(NULL, in, element, ':', indent + 2); fprintf(stderr, "DEBUG2: %*sOutput second part...\n", indent, ""); cgi_copy(out, in, element, '}', indent + 2); } fprintf(stderr, "DEBUG2: %*sFinished \"{%s%c%s\", out=%p...\n", indent, "", name, op, compare, out); } else if (ch == '\\') /* Quoted char */ { if (out) putc(getc(in), out); else getc(in); } else if (out) putc(ch, out); if (ch == EOF) fprintf(stderr, "DEBUG2: %*sReturning at file position %ld on EOF...\n", indent, "", ftell(in)); else fprintf(stderr, "DEBUG2: %*sReturning at file position %ld on character '%c'...\n", indent, "", ftell(in), ch); if (ch == EOF && term) fprintf(stderr, "ERROR: %*sSaw EOF, expected '%c'!\n", indent, "", term); /* * Flush any pending output... */ if (out) fflush(out); }