📄 cgi.c
字号:
s[dstPos++] = escapedValue;
escapeState = cgiEscapeRest;
break;
}
srcPos++;
}
s[dstPos] = '\0';
*sp = s;
return cgiUnescapeSuccess;
}
static void cgiSetupConstants() {
int i;
for (i=0; (i < 256); i++) {
cgiHexValue[i] = 0;
}
cgiHexValue['0'] = 0;
cgiHexValue['1'] = 1;
cgiHexValue['2'] = 2;
cgiHexValue['3'] = 3;
cgiHexValue['4'] = 4;
cgiHexValue['5'] = 5;
cgiHexValue['6'] = 6;
cgiHexValue['7'] = 7;
cgiHexValue['8'] = 8;
cgiHexValue['9'] = 9;
cgiHexValue['A'] = 10;
cgiHexValue['B'] = 11;
cgiHexValue['C'] = 12;
cgiHexValue['D'] = 13;
cgiHexValue['E'] = 14;
cgiHexValue['F'] = 15;
cgiHexValue['a'] = 10;
cgiHexValue['b'] = 11;
cgiHexValue['c'] = 12;
cgiHexValue['d'] = 13;
cgiHexValue['e'] = 14;
cgiHexValue['f'] = 15;
}
static void cgiFreeResources() {
cgiFormEntry *c = cgiFormEntryFirst;
cgiFormEntry *n;
while (c) {
n = c->next;
free(c->attr);
free(c->value);
free(c->fileName);
free(c->contentType);
if (strlen(c->tfileName)) {
unlink(c->tfileName);
}
free(c->tfileName);
free(c);
c = n;
}
/* If the cgi environment was restored from a saved environment,
then these are in allocated space and must also be freed */
if (cgiRestored) {
free(cgiServerSoftware);
free(cgiServerName);
free(cgiGatewayInterface);
free(cgiServerProtocol);
free(cgiServerPort);
free(cgiRequestMethod);
free(cgiPathInfo);
free(cgiPathTranslated);
free(cgiScriptName);
free(cgiQueryString);
free(cgiRemoteHost);
free(cgiRemoteAddr);
free(cgiAuthType);
free(cgiRemoteUser);
free(cgiRemoteIdent);
free(cgiContentType);
free(cgiAccept);
free(cgiUserAgent);
free(cgiReferrer);
}
/* 2.0: to clean up the environment for cgiReadEnvironment,
we must set these correctly */
cgiFormEntryFirst = 0;
cgiRestored = 0;
}
static cgiFormResultType cgiFormEntryString(
cgiFormEntry *e, char *result, int max, int newlines);
static cgiFormEntry *cgiFormEntryFindFirst(char *name);
static cgiFormEntry *cgiFormEntryFindNext();
cgiFormResultType cgiFormString(
char *name, char *result, int max) {
cgiFormEntry *e;
e = cgiFormEntryFindFirst(name);
if (!e) {
strcpy(result, "");
return cgiFormNotFound;
}
return cgiFormEntryString(e, result, max, 1);
}
cgiFormResultType cgiFormFileName(
char *name, char *result, int resultSpace)
{
cgiFormEntry *e;
int resultLen = 0;
char *s;
e = cgiFormEntryFindFirst(name);
if (!e) {
strcpy(result, "");
return cgiFormNotFound;
}
s = e->fileName;
while (*s) {
APPEND(result, *s);
s++;
}
if (resultSpace) {
result[resultLen] = '\0';
}
if (!strlen(e->fileName)) {
return cgiFormNoFileName;
} else if (((int) strlen(e->fileName)) > (resultSpace - 1)) {
return cgiFormTruncated;
} else {
return cgiFormSuccess;
}
}
cgiFormResultType cgiFormFileContentType(
char *name, char *result, int resultSpace)
{
cgiFormEntry *e;
int resultLen = 0;
char *s;
e = cgiFormEntryFindFirst(name);
if (!e) {
if (resultSpace) {
result[0] = '\0';
}
return cgiFormNotFound;
}
s = e->contentType;
while (*s) {
APPEND(result, *s);
s++;
}
if (resultSpace) {
result[resultLen] = '\0';
}
if (!strlen(e->contentType)) {
return cgiFormNoContentType;
} else if (((int) strlen(e->contentType)) > (resultSpace - 1)) {
return cgiFormTruncated;
} else {
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)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -