case 17: if (strncasecmp(tmpname, "Transfer-Encoding", 17) == 0) { log_d("convert_cgi_headers: script sent Transfer-Encoding!?!?"); return -1; } break;
static int convert_cgi_headers(struct pipe_params *pp, int *sp){	int addheader, c, s;	struct cgi_header headers[STUB_NHEADERS];	size_t i, nheaders, status, location;	const char *p, *tmpname, *tmpvalue;	int havestatus, havelocation, firstline;	size_t len, tmpnamelen, tmpvaluelen;	char sbuf[40], dbuf[50], gbuf[40], cbuf[30];	headers[nheaders = 0].len = sprintf(sbuf, "Server: %.30s", server_version);	headers[nheaders].name = sbuf;	headers[nheaders].namelen = 6;	headers[nheaders++].value = sbuf + 8;	headers[nheaders].len = sprintf(dbuf, "Date: %s", rfctime(current_time, gbuf));	headers[nheaders].name = dbuf;	headers[nheaders].namelen = 4;	headers[nheaders++].value = dbuf + 6;	tmpname = 0;	tmpnamelen = 0;	tmpvalue = 0;	havestatus = 0;	havelocation = 0;	status = 0;	location = 0;	s = 0;	len = 0;	addheader = 0;	firstline = 1;	for (i = 0, p = pp->pbuf; i < pp->pstart; i++, p++) {		c = *p;		switch (s) {		case 0:			switch (c) {			case '\r':			case '\n':				break;			default:				tmpname = p;				tmpnamelen = 0;				tmpvalue = 0;				len = 0;				s = 1;				break;			}			break;		case 1:			++len;			switch (c) {			case '\r':			case '\n':				addheader = 1;				s = 0;				break;			case ':':			case ' ':			case '\t':				if (tmpnamelen == 0)					tmpnamelen = len;				break;			default:				if (tmpnamelen && tmpvalue == 0)					tmpvalue = p;				break;			}			break;		}		if (addheader) {			if (tmpvalue == 0)				addheader = 0;			else if (firstline && tmpnamelen >= 8 && strncmp(tmpname, "HTTP/", 5) == 0) {				status = nheaders;				havestatus = 1;			} else				switch (tmpnamelen) {				case 4:					if (strncasecmp(tmpname, "Date", 4) == 0)						addheader = 0;					break;				case 6:					if (strncasecmp(tmpname, "Server", 6) == 0)						addheader = 0;					else if (strncasecmp(tmpname, "Status", 6) == 0) {						if (havestatus)							addheader = 0;						else {							status = nheaders;							havestatus = 1;						}					}					break;				case 8:					if (strncasecmp(tmpname, "Location", 8) == 0) {						if (havelocation)							addheader = 0;						else {							location = nheaders;							havelocation = 1;						}					}					break;				case 10:					if (strncasecmp(tmpname, "Connection", 10) == 0)						addheader = 0;					break;				case 14:					if (strncasecmp(tmpname, "Content-Length", 14) == 0)						addheader = 0;					break;				}			if (firstline)				firstline = 0;			if (addheader == 0) {				if (debug)					log_d("convert_cgi_headers: disallowing header \"%.*s\"", len, tmpname);			} else {				if (nheaders == STUB_NHEADERS) {					log_d("convert_cgi_headers: too many header lines");					return -1;				}				headers[nheaders].name = tmpname;				headers[nheaders].value = tmpvalue;				headers[nheaders].namelen = tmpnamelen;				headers[nheaders++].len = len;				addheader = 0;			}		}	}	if (s) {		log_d("convert_cgi_headers: s=%d!?", s);		return -1;	}	len = 0;	if (havelocation && havestatus == 0) {		if (len + 20 > pp->osize) {			log_d("convert_cgi_headers: no room to put Moved line");			return -1;		}		s = 302;		memcpy(pp->obuf + len, "HTTP/1.0 302 Moved\r\n", 20);		len += 20;	} else if (havestatus == 0) {		if (len + 17 > pp->osize) {			log_d("convert_cgi_headers: no room to put OK line");			return -1;		}		s = 200;		memcpy(pp->obuf + len, "HTTP/1.0 200 OK\r\n", 17);		len += 17;	} else {		s = atoi(headers[status].value);		if (s < 200 || s > 599) {			log_d("convert_cgi_headers: illegal header line \"%.*s\"", headers[status].len, headers[status].name);			return -1;		}		if (s == 204 || s == 304) {			pp->nocontent = 1;			pp->chunkit = 0;		}		tmpvaluelen = headers[status].len - (headers[status].value - headers[status].name);		if (len + tmpvaluelen + 11 > pp->osize) {			log_d("convert_cgi_headers: no room to put status line");			return -1;		}		memcpy(pp->obuf + len, "HTTP/1.0 ", 9);		len += 9;		memcpy(pp->obuf + len, headers[status].value, tmpvaluelen);		len += tmpvaluelen;		pp->obuf[len++] = '\r';		pp->obuf[len++] = '\n';	}	if (pp->chunkit) {		if (nheaders == STUB_NHEADERS) {			log_d("convert_cgi_headers: too many header lines");			return -1;		}		headers[nheaders].len = sprintf(cbuf, "Transfer-Encoding: chunked");		headers[nheaders].name = cbuf;		headers[nheaders].namelen = 17;		headers[nheaders++].value = cbuf + 19;	}	for (i = 0; i < nheaders; i++) {		if (havestatus == 0 || i != status) {			if (len + headers[i].len + 2 > pp->osize) {				log_d("convert_cgi_headers: no room to put header");				return -1;			}			memcpy(pp->obuf + len, headers[i].name, headers[i].len);			len += headers[i].len;			pp->obuf[len++] = '\r';			pp->obuf[len++] = '\n';		}	}	if (len + 2 > pp->osize) {		log_d("convert_cgi_headers: no room to put trailing newline");		return -1;	}	pp->obuf[len++] = '\r';	pp->obuf[len++] = '\n';	pp->otop = len;	*sp = s;	return 0;}