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); }
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); }