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

📄 cgi.c

📁 goahead,一个非常好用的web服务器,支持html和cgi,可以运行在多个平台之上.
💻 C
📖 第 1 页 / 共 5 页
字号:
			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;
	}
	if (!cgiWriteString(out, cgiServerProtocol)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiServerPort)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiRequestMethod)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiPathInfo)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiPathTranslated)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiScriptName)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiQueryString)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiRemoteHost)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiRemoteAddr)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiAuthType)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiRemoteUser)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiRemoteIdent)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiContentType)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiAccept)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiUserAgent)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiReferrer)) {
		goto error;
	}
	if (!cgiWriteString(out, cgiCookie)) {
		goto error;
	}
	if (!cgiWriteInt(out, cgiContentLength)) {
		goto error;
	}
	e = cgiFormEntryFirst;
	while (e) {
		cgiFilePtr fp;
		if (!cgiWriteString(out, e->attr)) {
			goto error;
		}
		if (!cgiWriteString(out, e->value)) {
			goto error;
		}
		/* New 2.0 fields and file uploads */
		if (!cgiWriteString(out, e->fileName)) {
			goto error;
		}
		if (!cgiWriteString(out, e->contentType)) {
			goto error;
		}
		if (!cgiWriteInt(out, e->valueLength)) {
			goto error;
		}
		if (cgiFormFileOpen(e->attr, &fp) == cgiFormSuccess) {
			char buffer[1024];
			int got;
			if (!cgiWriteInt(out, 1)) {
				cgiFormFileClose(fp);
				goto error;
			}
			while (cgiFormFileRead(fp, buffer, 
				sizeof(buffer), &got) == cgiFormSuccess)
			{
				if (((int) fwrite(buffer, 1, got, out)) != got) {
					cgiFormFileClose(fp);
					goto error;
				}
			}
			if (cgiFormFileClose(fp) != cgiFormSuccess) {
				goto error;
			}
		} else {
			if (!cgiWriteInt(out, 0)) {
				goto error;
			}
		}
		e = e->next;
	}
	fclose(out);
	return cgiEnvironmentSuccess;
error:
	fclose(out);
	/* If this function is not defined in your system,
		you must substitute the appropriate 
		file-deletion function. */
	unlink(filename);
	return cgiEnvironmentIO;
}

static int cgiWriteString(FILE *out, char *s) {
	int len = (int) strlen(s);
	cgiWriteInt(out, len);
	if (((int) fwrite(s, 1, len, out)) != len) {
		return 0;
	}
	return 1;
}

static int cgiWriteInt(FILE *out, int i) {
	if (!fwrite(&i, sizeof(int), 1, out)) {
		return 0;
	}
	return 1;
}

static int cgiReadString(FILE *out, char **s);

static int cgiReadInt(FILE *out, int *i);

cgiEnvironmentResultType cgiReadEnvironment(char *filename) {
	FILE *in;
	cgiFormEntry *e = 0, *p;
	char *version;
	/* Prevent compiler warnings */
	cgiEnvironmentResultType result = cgiEnvironmentIO;
	/* Free any existing data first */
	cgiFreeResources();
	/* Be sure to open in binary mode */
	in = fopen(filename, "rb");
	if (!in) {
		/* Can't access file */
		return cgiEnvironmentIO;
	}
	if (!cgiReadString(in, &version)) {
		goto error;
	}
	if (strcmp(version, "CGIC" CGIC_VERSION)) {
		/* 2.02: Merezko Oleg */
		free(version);
		return cgiEnvironmentWrongVersion;
	}	
	/* 2.02: Merezko Oleg */
	free(version);
	if (!cgiReadString(in, &cgiServerSoftware)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiServerName)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiGatewayInterface)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiServerProtocol)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiServerPort)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiRequestMethod)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiPathInfo)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiPathTranslated)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiScriptName)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiQueryString)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiRemoteHost)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiRemoteAddr)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiAuthType)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiRemoteUser)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiRemoteIdent)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiContentType)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiAccept)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiUserAgent)) {
		goto error;
	}
	if (!cgiReadString(in, &cgiReferrer)) {
		goto error;
	}
	/* 2.0 */
	if (!cgiReadString(in, &cgiCookie)) {
		goto error;
	}
	if (!cgiReadInt(in, &cgiContentLength)) {
		goto error;
	}
	p = 0;
	while (1) {
		int fileFlag;
		e = (cgiFormEntry *) calloc(1, sizeof(cgiFormEntry));
		if (!e) {
			cgiFreeResources();
			fclose(in);
			return cgiEnvironmentMemory;
		}
		memset(e, 0, sizeof(cgiFormEntry));
		if (!cgiReadString(in, &e->attr)) {
			/* This means we've reached the end of the list. */
			/* 2.02: thanks to Merezko Oleg */
			free(e);
			break;
		}
		if (!cgiReadString(in, &e->value)) {
			goto outOfMemory;
		}
		if (!cgiReadString(in, &e->fileName)) {
			goto outOfMemory;
		}
		if (!cgiReadString(in, &e->contentType)) {
			goto outOfMemory;
		}
		if (!cgiReadInt(in, &e->valueLength)) {
			goto outOfMemory;
		}
		if (!cgiReadInt(in, &fileFlag)) {
			goto outOfMemory;
		}
		if (fileFlag) {
			char buffer[1024];
			FILE *out;
			char tfileName[1024];
			int got;
			int len = e->valueLength;
			if (getTempFileName(tfileName)
				!= cgiParseSuccess)
			{
				result = cgiEnvironmentIO;
				goto error;
			}
			out = fopen(tfileName, "w+b");
			if (!out) {
				result = cgiEnvironmentIO;
				goto error;
			}
			while (len > 0) {		
				/* 2.01: try is a bad variable name in
					C++, and it wasn't being used
					properly either */
				int tryr = len;
				if (tryr > ((int) sizeof(buffer))) {
					tryr = sizeof(buffer);
				}
				got = fread(buffer, 1, tryr, in);
				if (got <= 0) {
					result = cgiEnvironmentIO;
					fclose(out);
					unlink(tfileName);
					goto error;
				}
				if (((int) fwrite(buffer, 1, got, out)) != got) {
					result = cgiEnvironmentIO;
					fclose(out);
					unlink(tfileName);
					goto error;
				}
				len -= got;
			}
			/* cgic 2.05: should be fclose not rewind */
			fclose(out);
			e->tfileName = (char *) malloc((int) strlen(tfileName) + 1);
			if (!e->tfileName) {
				result = cgiEnvironmentMemory;
				unlink(tfileName);
				goto error;
			}
			strcpy(e->tfileName, tfileName);
		} else {
			e->tfileName = (char *) malloc(1);
			if (!e->tfileName) {
				result = cgiEnvironmentMemory;
				goto error;
			}
		}	
		e->next = 0;
		if (p) {
			p->next = e;
		} else {
			cgiFormEntryFirst = e;
		}	
		p = e;
	}
	fclose(in);
	cgiRestored = 1;
	return cgiEnvironmentSuccess;
outOfMemory:
	result = cgiEnvironmentMemory;
error:

⌨️ 快捷键说明

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