?? cgic.c
字號:
return cgiFormSuccess; }}cgiFormResultType cgiFormFileSize( char *name, int *sizeP){ cgiFormEntry *e; e = cgiFormEntryFindFirst(name); if (!e) { if (sizeP) { *sizeP = 0; } return cgiFormNotFound; } else if (!strlen(e->tfileName)) { if (sizeP) { *sizeP = 0; } return cgiFormNotAFile; } else { if (sizeP) { *sizeP = e->valueLength; } return cgiFormSuccess; }}typedef struct cgiFileStruct { FILE *in;} cgiFile;cgiFormResultType cgiFormFileOpen( char *name, cgiFilePtr *cfpp){ cgiFormEntry *e; cgiFilePtr cfp; e = cgiFormEntryFindFirst(name); if (!e) { *cfpp = 0; return cgiFormNotFound; } if (!strlen(e->tfileName)) { *cfpp = 0; return cgiFormNotAFile; } cfp = (cgiFilePtr) malloc(sizeof(cgiFile)); if (!cfp) { *cfpp = 0; return cgiFormMemory; } cfp->in = fopen(e->tfileName, "rb"); if (!cfp->in) { free(cfp); return cgiFormIO; } *cfpp = cfp; return cgiFormSuccess;}cgiFormResultType cgiFormFileRead( cgiFilePtr cfp, char *buffer, int bufferSize, int *gotP){ int got = 0; if (!cfp) { return cgiFormOpenFailed; } got = fread(buffer, 1, bufferSize, cfp->in); if (got <= 0) { return cgiFormEOF; } *gotP = got; return cgiFormSuccess;}cgiFormResultType cgiFormFileClose(cgiFilePtr cfp){ if (!cfp) { return cgiFormOpenFailed; } fclose(cfp->in); free(cfp); return cgiFormSuccess;}cgiFormResultType cgiFormStringNoNewlines( char *name, char *result, int max) { cgiFormEntry *e; e = cgiFormEntryFindFirst(name); if (!e) { strcpy(result, ""); return cgiFormNotFound; } return cgiFormEntryString(e, result, max, 0);}cgiFormResultType cgiFormStringMultiple( char *name, char ***result) { char **stringArray; cgiFormEntry *e; int i; int total = 0; /* Make two passes. One would be more efficient, but this function is not commonly used. The select menu and radio box functions are faster. */ e = cgiFormEntryFindFirst(name); if (e != 0) { do { total++; } while ((e = cgiFormEntryFindNext()) != 0); } stringArray = (char **) malloc(sizeof(char *) * (total + 1)); if (!stringArray) { *result = 0; return cgiFormMemory; } /* initialize all entries to null; the last will stay that way */ for (i=0; (i <= total); i++) { stringArray[i] = 0; } /* Now go get the entries */ e = cgiFormEntryFindFirst(name);#ifdef CGICDEBUG CGICDEBUGSTART fprintf(dout, "StringMultiple Beginning\n"); CGICDEBUGEND#endif /* CGICDEBUG */ if (e) { i = 0; do { int max = (int) (strlen(e->value) + 1); stringArray[i] = (char *) malloc(max); if (stringArray[i] == 0) { /* Memory problems */ cgiStringArrayFree(stringArray); *result = 0; return cgiFormMemory; } strcpy(stringArray[i], e->value); cgiFormEntryString(e, stringArray[i], max, 1); i++; } while ((e = cgiFormEntryFindNext()) != 0); *result = stringArray;#ifdef CGICDEBUG CGICDEBUGSTART fprintf(dout, "StringMultiple Succeeding\n"); CGICDEBUGEND#endif /* CGICDEBUG */ return cgiFormSuccess; } else { *result = stringArray;#ifdef CGICDEBUG CGICDEBUGSTART fprintf(dout, "StringMultiple found nothing\n"); CGICDEBUGEND#endif /* CGICDEBUG */ return cgiFormNotFound; } }cgiFormResultType cgiFormStringSpaceNeeded( char *name, int *result) { cgiFormEntry *e; e = cgiFormEntryFindFirst(name); if (!e) { *result = 1; return cgiFormNotFound; } *result = ((int) strlen(e->value)) + 1; return cgiFormSuccess;}static cgiFormResultType cgiFormEntryString( cgiFormEntry *e, char *result, int max, int newlines) { char *dp, *sp; int truncated = 0; int len = 0; int avail = max-1; int crCount = 0; int lfCount = 0; dp = result; sp = e->value; while (1) { int ch; /* 1.07: don't check for available space now. We check for it immediately before adding an actual character. 1.06 handled the trailing null of the source string improperly, resulting in a cgiFormTruncated error. */ ch = *sp; /* Fix the CR/LF, LF, CR nightmare: watch for consecutive bursts of CRs and LFs in whatever pattern, then actually output the larger number of LFs. Consistently sane, yet it still allows consecutive blank lines when the user actually intends them. */ if ((ch == 13) || (ch == 10)) { if (ch == 13) { crCount++; } else { lfCount++; } } else { if (crCount || lfCount) { int lfsAdd = crCount; if (lfCount > crCount) { lfsAdd = lfCount; } /* Stomp all newlines if desired */ if (!newlines) { lfsAdd = 0; } while (lfsAdd) { if (len >= avail) { truncated = 1; break; } *dp = 10; dp++; lfsAdd--; len++; } crCount = 0; lfCount = 0; } if (ch == '\0') { /* The end of the source string */ break; } /* 1.06: check available space before adding the character, because a previously added LF may have brought us to the limit */ if (len >= avail) { truncated = 1; break; } *dp = ch; dp++; len++; } sp++; } *dp = '\0'; if (truncated) { return cgiFormTruncated; } else if (!len) { return cgiFormEmpty; } else { return cgiFormSuccess; }}static int cgiFirstNonspaceChar(char *s);cgiFormResultType cgiFormInteger( char *name, int *result, int defaultV) { cgiFormEntry *e; int ch; e = cgiFormEntryFindFirst(name); if (!e) { *result = defaultV; return cgiFormNotFound; } if (!strlen(e->value)) { *result = defaultV; return cgiFormEmpty; } ch = cgiFirstNonspaceChar(e->value); if (!(isdigit(ch)) && (ch != '-') && (ch != '+')) { *result = defaultV; return cgiFormBadType; } else { *result = atoi(e->value); return cgiFormSuccess; }}cgiFormResultType cgiFormIntegerBounded( char *name, int *result, int min, int max, int defaultV) { cgiFormResultType error = cgiFormInteger(name, result, defaultV); if (error != cgiFormSuccess) { return error; } if (*result < min) { *result = min; return cgiFormConstrained; } if (*result > max) { *result = max; return cgiFormConstrained; } return cgiFormSuccess;}cgiFormResultType cgiFormDouble( char *name, double *result, double defaultV) { cgiFormEntry *e; int ch; e = cgiFormEntryFindFirst(name); if (!e) { *result = defaultV; return cgiFormNotFound; } if (!strlen(e->value)) { *result = defaultV; return cgiFormEmpty; } ch = cgiFirstNonspaceChar(e->value); if (!(isdigit(ch)) && (ch != '.') && (ch != '-') && (ch != '+')) { *result = defaultV; return cgiFormBadType; } else { *result = atof(e->value); return cgiFormSuccess; }}cgiFormResultType cgiFormDoubleBounded( char *name, double *result, double min, double max, double defaultV) { cgiFormResultType error = cgiFormDouble(name, result, defaultV); if (error != cgiFormSuccess) { return error; } if (*result < min) { *result = min; return cgiFormConstrained; } if (*result > max) { *result = max; return cgiFormConstrained; } return cgiFormSuccess;}cgiFormResultType cgiFormSelectSingle( char *name, char **choicesText, int choicesTotal, int *result, int defaultV) { cgiFormEntry *e; int i; e = cgiFormEntryFindFirst(name);#ifdef CGICDEBUG CGICDEBUGSTART fprintf(dout, "%d\n", (int) e); CGICDEBUGEND#endif /* CGICDEBUG */ if (!e) { *result = defaultV; return cgiFormNotFound; } for (i=0; (i < choicesTotal); i++) {#ifdef CGICDEBUG CGICDEBUGSTART fprintf(dout, "%s %s\n", choicesText[i], e->value); CGICDEBUGEND#endif /* CGICDEBUG */ if (cgiStrEq(choicesText[i], e->value)) {#ifdef CGICDEBUG CGICDEBUGSTART fprintf(dout, "MATCH\n"); CGICDEBUGEND#endif /* CGICDEBUG */ *result = i; return cgiFormSuccess; } } *result = defaultV; return cgiFormNoSuchChoice;}cgiFormResultType cgiFormSelectMultiple( char *name, char **choicesText, int choicesTotal, int *result, int *invalid) { cgiFormEntry *e; int i; int hits = 0; int invalidE = 0; for (i=0; (i < choicesTotal); i++) { result[i] = 0; } e = cgiFormEntryFindFirst(name); if (!e) { *invalid = invalidE; return cgiFormNotFound; } do { int hit = 0; for (i=0; (i < choicesTotal); i++) { if (cgiStrEq(choicesText[i], e->value)) { result[i] = 1; hits++; hit = 1; break; } } if (!(hit)) { invalidE++; } } while ((e = cgiFormEntryFindNext()) != 0); *invalid = invalidE; if (hits) { return cgiFormSuccess; } else { return cgiFormNotFound; }}cgiFormResultType cgiFormCheckboxSingle( char *name){ cgiFormEntry *e; e = cgiFormEntryFindFirst(name); if (!e) { return cgiFormNotFound; } return cgiFormSuccess;}extern cgiFormResultType cgiFormCheckboxMultiple( char *name, char **valuesText, int valuesTotal, int *result, int *invalid){ /* Implementation is identical to cgiFormSelectMultiple. */ return cgiFormSelectMultiple(name, valuesText, valuesTotal, result, invalid);}cgiFormResultType cgiFormRadio( char *name, char **valuesText, int valuesTotal, int *result, int defaultV){ /* Implementation is identical to cgiFormSelectSingle. */ return cgiFormSelectSingle(name, valuesText, valuesTotal, result, defaultV);}cgiFormResultType cgiCookieString( char *name, char *value, int space){ char *p = cgiCookie; while (*p) { char *n = name; /* 2.02: if cgiCookie is exactly equal to name, this can cause an overrun. The server probably wouldn't allow it, since a name without values makes no sense -- but then again it might not check, so this is a genuine security concern. Thanks to Nicolas Tomadakis. */ while (*p == *n) { if ((p == '\0') && (n == '\0')) { /* Malformed cookie header from client */ return cgiFormNotFound; } p++; n++; } if ((!*n) && (*p == '=')) { p++; while ((*p != ';') && (*p != '\0') && (space > 1)) { *value = *p; value++; p++; space--; } if (space > 0) { *value = '\0'; } /* Correct parens: 2.02. Thanks to Mathieu Villeneuve-Belair. */ if (!(((*p) == ';') || ((*p) == '\0'))) { return cgiFormTruncated; } else { return cgiFormSuccess; } } else { /* Skip to next cookie */ while (*p) { if (*p == ';') { break; } p++; } if (!*p) { /* 2.01: default to empty */ if (space) { *value = '\0'; } return cgiFormNotFound; } p++; /* Allow whitespace after semicolon */ while ((*p) && isspace(*p)) { p++; } } } /* 2.01: actually the above loop never terminates except with a return, but do this to placate gcc */ if (space) { *value = '\0'; } return cgiFormNotFound;}cgiFormResultType cgiCookieInteger( char *name, int *result, int defaultV){ char buffer[256]; cgiFormResultType r = cgiCookieString(name, buffer, sizeof(buffer)); if (r != cgiFormSuccess) { *result = defaultV; } else { *result = atoi(buffer); } return r;}void cgiHeaderCookieSetInteger(char *name, int value, int secondsToLive, char *path, char *domain){ char svalue[256]; sprintf(svalue, "%d", value); cgiHeaderCookieSetString(name, svalue, secondsToLive, path, domain);}char *days[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"};char *months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};void cgiHeaderCookieSetString(char *name, char *value, int secondsToLive, char *path, char *domain){ /* cgic 2.02: simpler and more widely compatible implementation. Thanks to Chunfu Lai. cgic 2.03: yes, but it didn't work. Reimplemented by Thomas Boutell. ; after last element was a bug. Examples of real world cookies that really work: Set-Cookie: MSNADS=UM=; domain=.slate.com; expires=Tue, 26-Apr-2022 19:00:00 GMT; path=/ Set-Cookie: MC1=V=3&ID=b5bc08af2b8a43ff85fcb5efd8b238f0; domain=.slate.com; expires=Mon, 04-Oct-2021 19:00:00 GMT; path=/ */ time_t now; time_t then; struct tm *gt; time(&now); then = now + secondsToLive; gt = gmtime(&then); fprintf(cgiOut, "Set-Cookie: %s=%s; domain=%s; expires=%s, %02d-%s-%04d %02d:%02d:%02d GMT; path=%s\r\n", name, value, domain, days[gt->tm_wday], gt->tm_mday, months[gt->tm_mon], gt->tm_year + 1900, gt->tm_hour, gt->tm_min, gt->tm_sec, path);}void cgiHeaderLocation(char *redirectUrl) { fprintf(cgiOut, "Location: %s\r\n\r\n", redirectUrl);}void cgiHeaderStatus(int status, char *statusMessage) { fprintf(cgiOut, "Status: %d %s\r\n\r\n", status, statusMessage);}void cgiHeaderContentType(char *mimeType) { fprintf(cgiOut, "Content-type: %s\r\n\r\n", mimeType);}static int cgiWriteString(FILE *out, char *s);static int cgiWriteInt(FILE *out, int i);#define CGIC_VERSION "2.0"cgiEnvironmentResultType cgiWriteEnvironment(char *filename) { FILE *out; cgiFormEntry *e; /* Be sure to open in binary mode */ out = fopen(filename, "wb"); if (!out) { /* Can't create file */ return cgiEnvironmentIO; } if (!cgiWriteString(out, "CGIC2.0")) { goto error; } if (!cgiWriteString(out, cgiServerSoftware)) { goto error; } if (!cgiWriteString(out, cgiServerName)) { goto error; } if (!cgiWriteString(out, cgiGatewayInterface)) { goto error; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -