⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cgic.c

📁 一般的UNIX系统都支持ANSI C,增加相应的库函数(和相应的h文件)就可以实现CGI,用于CGI编程的ANSI C库
💻 C
📖 第 1 页 / 共 4 页
字号:
static cgiParseResultType getTempFileName(char *tfileName){#ifndef WIN32	/* Unix. Use the robust 'mkstemp' function to create		a temporary file that is truly unique, with		permissions that are truly safe. The 		fopen-for-write destroys any bogus information		written by potential hackers during the brief		window between the file's creation and the		chmod call (glibc 2.0.6 and lower might		otherwise have allowed this). */	int outfd; 	strcpy(tfileName, cgicTempDir "/cgicXXXXXX");	outfd = mkstemp(tfileName);	if (outfd == -1) {		return cgiParseIO;	}	close(outfd);	/* Fix the permissions */	if (chmod(tfileName, 0600) != 0) {		unlink(tfileName);		return cgiParseIO;	}#else	/* Non-Unix. Do what we can. */	if (!tmpnam(tfileName)) {		return cgiParseIO;	}#endif	return cgiParseSuccess;}#define APPEND(string, char) \	{ \		if ((string##Len + 1) < string##Space) { \			string[string##Len++] = (char); \		} \	}#define RAPPEND(string, ch) \	{ \		if ((string##Len + 1) == string##Space)  { \			char *sold = string; \			string##Space *= 2; \			string = (char *) realloc(string, string##Space); \			if (!string) { \				string = sold; \				goto outOfMemory; \			} \		} \		string[string##Len++] = (ch); \	}		#define BAPPEND(ch) \	{ \		if (outf) { \			putc(ch, outf); \			outLen++; \		} else if (out) { \			RAPPEND(out, ch); \		} \	}cgiParseResultType afterNextBoundary(mpStreamPtr mpp, FILE *outf, char **outP,	int *bodyLengthP, int first){	int outLen = 0;	int outSpace = 256;	char *out = 0;	cgiParseResultType result;	int boffset;	int got;	char d[2];		/* This is large enough, because the buffer into which the		original boundary string is fetched is shorter by more		than four characters due to the space required for		the attribute name */	char workingBoundaryData[1024];	char *workingBoundary = workingBoundaryData;	int workingBoundaryLength;	if ((!outf) && (outP)) {		out = (char *) malloc(outSpace);		if (!out) {			goto outOfMemory;		}	}	boffset = 0;	sprintf(workingBoundaryData, "\r\n--%s", cgiMultipartBoundary);	if (first) {		workingBoundary = workingBoundaryData + 2;	}	workingBoundaryLength = strlen(workingBoundary);	while (1) {		got = mpRead(mpp, d, 1);		if (got != 1) {			/* 2.01: cgiParseIO, not cgiFormIO */			result = cgiParseIO;			goto error;		}		if (d[0] == workingBoundary[boffset]) {			/* We matched the next byte of the boundary.				Keep track of our progress into the				boundary and don't emit anything. */			boffset++;			if (boffset == workingBoundaryLength) {				break;			} 		} else if (boffset > 0) {			/* We matched part, but not all, of the				boundary. Now we have to be careful:				put back all except the first				character and try again. The 				real boundary could begin in the				middle of a false match. We can				emit the first character only so far. */			BAPPEND(workingBoundary[0]);			mpPutBack(mpp, 				workingBoundary + 1, boffset - 1);			mpPutBack(mpp, d, 1);			boffset = 0;		} else {					/* Not presently in the middle of a boundary				match; just emit the character. */			BAPPEND(d[0]);		}		}	/* Read trailing newline or -- EOF marker. A literal EOF here		would be an error in the input stream. */	got = mpRead(mpp, d, 2);	if (got != 2) {		result = cgiParseIO;		goto error;	}		if ((d[0] == '\r') && (d[1] == '\n')) {		/* OK, EOL */	} else if (d[0] == '-') {		/* Probably EOF, but we check for			that later */		mpPutBack(mpp, d, 2);	}		if (out && outSpace) {		char *oout = out;		out[outLen] = '\0';		out = (char *) realloc(out, outLen + 1);		if (!out) {			/* Surprising if it happens; and not fatal! We were				just trying to give some space back. We can				keep it if we have to. */			out = oout;		}		*outP = out;	}	if (bodyLengthP) {		*bodyLengthP = outLen;	}	return cgiParseSuccess;outOfMemory:	result = cgiParseMemory;	if (outP) {		if (out) {			free(out);		}		*outP = '\0';		}error:	if (bodyLengthP) {		*bodyLengthP = 0;	}	if (out) {		free(out);	}	if (outP) {		*outP = 0;		}	return result;}static void decomposeValue(char *value,	char *mvalue, int mvalueSpace,	char **argNames,	char **argValues,	int argValueSpace){	char argName[1024];	int argNameSpace = sizeof(argName);	int argNameLen = 0;	int mvalueLen = 0;	char *argValue;	int argNum = 0;	while (argNames[argNum]) {		if (argValueSpace) {			argValues[argNum][0] = '\0';		}		argNum++;	}	while (isspace(*value)) {		value++;	}	/* Quoted mvalue */	if (*value == '\"') {		value++;		while ((*value) && (*value != '\"')) {			APPEND(mvalue, *value);			value++;		}		while ((*value) && (*value != ';')) {			value++;		}	} else {		/* Unquoted mvalue */		while ((*value) && (*value != ';')) {			APPEND(mvalue, *value);			value++;		}		}		if (mvalueSpace) {		mvalue[mvalueLen] = '\0';	}	while (*value == ';') {		int argNum;		int argValueLen = 0;		/* Skip the ; between parameters */		value++;		/* Now skip leading whitespace */		while ((*value) && (isspace(*value))) { 			value++;		}		/* Now read the parameter name */		argNameLen = 0;		while ((*value) && (isalnum(*value))) {			APPEND(argName, *value);			value++;		}		if (argNameSpace) {			argName[argNameLen] = '\0';		}		while ((*value) && isspace(*value)) {			value++;		}		if (*value != '=') {			/* Malformed line */			return;			}		value++;		while ((*value) && isspace(*value)) {			value++;		}		/* Find the parameter in the argument list, if present */		argNum = 0;		argValue = 0;		while (argNames[argNum]) {			if (cgiStrEqNc(argName, argNames[argNum])) {				argValue = argValues[argNum];				break;			}			argNum++;		}				/* Finally, read the parameter value */		if (*value == '\"') {			value++;			while ((*value) && (*value != '\"')) {				if (argValue) {					APPEND(argValue, *value);				}				value++;			}			while ((*value) && (*value != ';')) {				value++;			}		} else {			/* Unquoted value */			while ((*value) && (*value != ';')) {				if (argNames[argNum]) {					APPEND(argValue, *value);				}				value++;			}			}			if (argValueSpace) {			argValue[argValueLen] = '\0';		}	}	 	}static int readHeaderLine(	mpStreamPtr mpp,	char *attr,	int attrSpace,	char *value,	int valueSpace){		int attrLen = 0;	int valueLen = 0;	int valueFound = 0;	while (1) {		char d[1];		int got = mpRead(mpp, d, 1);		if (got != 1) {				return 0;		}		if (d[0] == '\r') {			got = mpRead(mpp, d, 1);			if (got == 1) {					if (d[0] == '\n') {					/* OK */				} else {					mpPutBack(mpp, d, 1);				}			}			break;		} else if (d[0] == '\n') {			break;		} else if ((d[0] == ':') && attrLen) {			valueFound = 1;			while (mpRead(mpp, d, 1) == 1) {				if (!isspace(d[0])) {					mpPutBack(mpp, d, 1);					break;				} 			}		} else if (!valueFound) {			if (!isspace(*d)) {				if (attrLen < (attrSpace - 1)) {					attr[attrLen++] = *d;				}			}				} else if (valueFound) {				if (valueLen < (valueSpace - 1)) {				value[valueLen++] = *d;			}		}	}	if (attrSpace) {		attr[attrLen] = '\0';	}	if (valueSpace) {		value[valueLen] = '\0';	}	if (attrLen && valueLen) {		return 1;	} else {		return 0;	}}static cgiParseResultType cgiParseGetFormInput() {	return cgiParseFormInput(cgiQueryString, cgiContentLength);}typedef enum {	cgiEscapeRest,	cgiEscapeFirst,	cgiEscapeSecond} cgiEscapeState;typedef enum {	cgiUnescapeSuccess,	cgiUnescapeMemory} cgiUnescapeResultType;static cgiUnescapeResultType cgiUnescapeChars(char **sp, char *cp, int len);static cgiParseResultType cgiParseFormInput(char *data, int length) {	/* Scan for pairs, unescaping and storing them as they are found. */	int pos = 0;	cgiFormEntry *n;	cgiFormEntry *l = 0;	while (pos != length) {		int foundEq = 0;		int foundAmp = 0;		int start = pos;		int len = 0;		char *attr;		char *value;		while (pos != length) {			if (data[pos] == '=') {				foundEq = 1;				pos++;				break;			}			pos++;			len++;		}		if (!foundEq) {			break;		}		if (cgiUnescapeChars(&attr, data+start, len)			!= cgiUnescapeSuccess) {			return cgiParseMemory;		}			start = pos;		len = 0;		while (pos != length) {			if (data[pos] == '&') {				foundAmp = 1;				pos++;				break;			}			pos++;			len++;		}		/* The last pair probably won't be followed by a &, but			that's fine, so check for that after accepting it */		if (cgiUnescapeChars(&value, data+start, len)			!= cgiUnescapeSuccess) {			free(attr);			return cgiParseMemory;		}			/* OK, we have a new pair, add it to the list. */		n = (cgiFormEntry *) malloc(sizeof(cgiFormEntry));			if (!n) {			free(attr);			free(value);			return cgiParseMemory;		}		n->attr = attr;		n->value = value;		n->valueLength = strlen(n->value);		n->fileName = (char *) malloc(1);		if (!n->fileName) {			free(attr);			free(value);			free(n);			return cgiParseMemory;		}			n->fileName[0] = '\0';		n->contentType = (char *) malloc(1);		if (!n->contentType) {			free(attr);			free(value);			free(n->fileName);			free(n);			return cgiParseMemory;		}			n->contentType[0] = '\0';		n->tfileName = (char *) malloc(1);		if (!n->tfileName) {			free(attr);			free(value);			free(n->fileName);			free(n->contentType);			free(n);			return cgiParseMemory;		}			n->tfileName[0] = '\0';		n->next = 0;		if (!l) {			cgiFormEntryFirst = n;		} else {			l->next = n;		}		l = n;		if (!foundAmp) {			break;		}				}	return cgiParseSuccess;}static int cgiHexValue[256];cgiUnescapeResultType cgiUnescapeChars(char **sp, char *cp, int len) {	char *s;	cgiEscapeState escapeState = cgiEscapeRest;	int escapedValue = 0;	int srcPos = 0;	int dstPos = 0;	s = (char *) malloc(len + 1);	if (!s) {		return cgiUnescapeMemory;	}	while (srcPos < len) {		int ch = cp[srcPos];		switch (escapeState) {			case cgiEscapeRest:			if (ch == '%') {				escapeState = cgiEscapeFirst;			} else if (ch == '+') {				s[dstPos++] = ' ';			} else {				s[dstPos++] = ch;				}			break;			case cgiEscapeFirst:			escapedValue = cgiHexValue[ch] << 4;				escapeState = cgiEscapeSecond;			break;			case cgiEscapeSecond:			escapedValue += cgiHexValue[ch];			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;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -