Exemple #1
0
/* allocates and initializes an error response */
HttpReply *
errorBuildReply(ErrorState * err)
{
    HttpReply *rep = httpReplyCreate();
    const char *name = errorPageName(err->page_id);
    /* no LMT for error pages; error pages expire immediately */
    if (strchr(name, ':')) {
	/* Redirection */
	httpReplySetHeaders(rep, HTTP_MOVED_TEMPORARILY, NULL, "text/html", 0, -1, -1);
	if (err->request) {
	    char *quoted_url = rfc1738_escape_part(urlCanonical(err->request));
	    httpHeaderPutStrf(&rep->header, HDR_LOCATION, name, quoted_url);
	}
	httpHeaderPutStrf(&rep->header, HDR_X_SQUID_ERROR, "%d %s", err->http_status, "Access Denied");
    } else {
	MemBuf content = errorBuildContent(err);
	httpReplySetHeaders(rep, err->http_status, NULL, "text/html", content.size, -1, -1);
	/*
	 * include some information for downstream caches. Implicit
	 * replaceable content. This isn't quite sufficient. xerrno is not
	 * necessarily meaningful to another system, so we really should
	 * expand it. Additionally, we should identify ourselves. Someone
	 * might want to know. Someone _will_ want to know OTOH, the first
	 * X-CACHE-MISS entry should tell us who.
	 */
	httpHeaderPutStrf(&rep->header, HDR_X_SQUID_ERROR, "%s %d",
	    name, err->xerrno);
	httpBodySet(&rep->body, &content);
	/* do not memBufClean() the content, it was absorbed by httpBody */
    }
    return rep;
}
Exemple #2
0
/* Borrow part of code from libwww2 came with Mosaic distribution */
static void
gopherToHTML(GopherStateData * gopherState, char *inbuf, int len)
{
    char *pos = inbuf;
    char *lpos = NULL;
    char *tline = NULL;
    LOCAL_ARRAY(char, line, TEMP_BUF_SIZE);
    LOCAL_ARRAY(char, tmpbuf, TEMP_BUF_SIZE);
    String outbuf = StringNull;
    char *name = NULL;
    char *selector = NULL;
    char *host = NULL;
    char *port = NULL;
    char *escaped_selector = NULL;
    const char *icon_url = NULL;
    char gtype;
    StoreEntry *entry = NULL;

    memset(tmpbuf, '\0', TEMP_BUF_SIZE);
    memset(line, '\0', TEMP_BUF_SIZE);

    entry = gopherState->entry;

    if (gopherState->conversion == HTML_INDEX_PAGE) {
	char *html_url = html_quote(storeUrl(entry));
	gopherHTMLHeader(entry, "Gopher Index %s", html_url);
	storeAppendPrintf(entry,
	    "<p>This is a searchable Gopher index. Use the search\n"
	    "function of your browser to enter search terms.\n"
	    "<ISINDEX>\n");
	gopherHTMLFooter(entry);
	/* now let start sending stuff to client */
	storeBufferFlush(entry);
	gopherState->HTML_header_added = 1;
	return;
    }
    if (gopherState->conversion == HTML_CSO_PAGE) {
	char *html_url = html_quote(storeUrl(entry));
	gopherHTMLHeader(entry, "CSO Search of %s", html_url);
	storeAppendPrintf(entry,
	    "<P>A CSO database usually contains a phonebook or\n"
	    "directory.  Use the search function of your browser to enter\n"
	    "search terms.</P><ISINDEX>\n");
	gopherHTMLFooter(entry);
	/* now let start sending stuff to client */
	storeBufferFlush(entry);
	gopherState->HTML_header_added = 1;
	return;
    }
    inbuf[len] = '\0';

    if (!gopherState->HTML_header_added) {
	if (gopherState->conversion == HTML_CSO_RESULT)
	    gopherHTMLHeader(entry, "CSO Search Result", NULL);
	else
	    gopherHTMLHeader(entry, "Gopher Menu", NULL);
	strCat(outbuf, "<PRE>");
	gopherState->HTML_header_added = 1;
	gopherState->HTML_pre = 1;
    }
    while ((pos != NULL) && (pos < inbuf + len)) {

	if (gopherState->len != 0) {
	    /* there is something left from last tx. */
	    xstrncpy(line, gopherState->buf, gopherState->len + 1);
	    if (gopherState->len + len > TEMP_BUF_SIZE) {
		debug(10, 1) ("GopherHTML: Buffer overflow. Lost some data on URL: %s\n",
		    storeUrl(entry));
		len = TEMP_BUF_SIZE - gopherState->len;
	    }
	    lpos = (char *) memccpy(line + gopherState->len, inbuf, '\n', len);
	    if (lpos)
		*lpos = '\0';
	    else {
		/* there is no complete line in inbuf */
		/* copy it to temp buffer */
		if (gopherState->len + len > TEMP_BUF_SIZE) {
		    debug(10, 1) ("GopherHTML: Buffer overflow. Lost some data on URL: %s\n",
			storeUrl(entry));
		    len = TEMP_BUF_SIZE - gopherState->len;
		}
		xmemcpy(gopherState->buf + gopherState->len, inbuf, len);
		gopherState->len += len;
		return;
	    }

	    /* skip one line */
	    pos = (char *) memchr(pos, '\n', len);
	    if (pos)
		pos++;

	    /* we're done with the remain from last tx. */
	    gopherState->len = 0;
	    *(gopherState->buf) = '\0';
	} else {

	    lpos = (char *) memccpy(line, pos, '\n', len - (pos - inbuf));
	    if (lpos)
		*lpos = '\0';
	    else {
		/* there is no complete line in inbuf */
		/* copy it to temp buffer */
		if ((len - (pos - inbuf)) > TEMP_BUF_SIZE) {
		    debug(10, 1) ("GopherHTML: Buffer overflow. Lost some data on URL: %s\n",
			storeUrl(entry));
		    len = TEMP_BUF_SIZE;
		}
		if (len > (pos - inbuf)) {
		    xmemcpy(gopherState->buf, pos, len - (pos - inbuf));
		    gopherState->len = len - (pos - inbuf);
		}
		break;
	    }

	    /* skip one line */
	    pos = (char *) memchr(pos, '\n', len);
	    if (pos)
		pos++;

	}

	/* at this point. We should have one line in buffer to process */

	if (*line == '.') {
	    /* skip it */
	    memset(line, '\0', TEMP_BUF_SIZE);
	    continue;
	}
	switch (gopherState->conversion) {

	case HTML_INDEX_RESULT:
	case HTML_DIR:{
		tline = line;
		gtype = *tline++;
		name = tline;
		selector = strchr(tline, TAB);
		if (selector) {
		    *selector++ = '\0';
		    host = strchr(selector, TAB);
		    if (host) {
			*host++ = '\0';
			port = strchr(host, TAB);
			if (port) {
			    char *junk;
			    port[0] = ':';
			    junk = strchr(host, TAB);
			    if (junk)
				*junk++ = 0;	/* Chop port */
			    else {
				junk = strchr(host, '\r');
				if (junk)
				    *junk++ = 0;	/* Chop port */
				else {
				    junk = strchr(host, '\n');
				    if (junk)
					*junk++ = 0;	/* Chop port */
				}
			    }
			    if ((port[1] == '0') && (!port[2]))
				port[0] = 0;	/* 0 means none */
			}
			/* escape a selector here */
			escaped_selector = xstrdup(rfc1738_escape_part(selector));

			switch (gtype) {
			case GOPHER_DIRECTORY:
			    icon_url = mimeGetIconURL("internal-menu");
			    break;
			case GOPHER_HTML:
			case GOPHER_FILE:
			    icon_url = mimeGetIconURL("internal-text");
			    break;
			case GOPHER_INDEX:
			case GOPHER_CSO:
			    icon_url = mimeGetIconURL("internal-index");
			    break;
			case GOPHER_IMAGE:
			case GOPHER_GIF:
			case GOPHER_PLUS_IMAGE:
			    icon_url = mimeGetIconURL("internal-image");
			    break;
			case GOPHER_SOUND:
			case GOPHER_PLUS_SOUND:
			    icon_url = mimeGetIconURL("internal-sound");
			    break;
			case GOPHER_PLUS_MOVIE:
			    icon_url = mimeGetIconURL("internal-movie");
			    break;
			case GOPHER_TELNET:
			case GOPHER_3270:
			    icon_url = mimeGetIconURL("internal-telnet");
			    break;
			case GOPHER_BIN:
			case GOPHER_MACBINHEX:
			case GOPHER_DOSBIN:
			case GOPHER_UUENCODED:
			    icon_url = mimeGetIconURL("internal-binary");
			    break;
			case GOPHER_INFO:
			    icon_url = NULL;
			    break;
			default:
			    icon_url = mimeGetIconURL("internal-unknown");
			    break;
			}

			memset(tmpbuf, '\0', TEMP_BUF_SIZE);
			if ((gtype == GOPHER_TELNET) || (gtype == GOPHER_3270)) {
			    if (strlen(escaped_selector) != 0)
				snprintf(tmpbuf, TEMP_BUF_SIZE, "<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"telnet://%s@%s%s%s/\">%s</A>\n",
				    icon_url, escaped_selector, rfc1738_escape_part(host),
				    *port ? ":" : "", port, html_quote(name));
			    else
				snprintf(tmpbuf, TEMP_BUF_SIZE, "<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"telnet://%s%s%s/\">%s</A>\n",
				    icon_url, rfc1738_escape_part(host), *port ? ":" : "",
				    port, html_quote(name));

			} else if (gtype == GOPHER_INFO) {
			    snprintf(tmpbuf, TEMP_BUF_SIZE, "\t%s\n", html_quote(name));
			} else {
			    if (strncmp(selector, "GET /", 5) == 0) {
				/* WWW link */
				snprintf(tmpbuf, TEMP_BUF_SIZE, "<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"http://%s/%s\">%s</A>\n",
				    icon_url, host, rfc1738_escape_unescaped(selector + 5), html_quote(name));
			    } else {
				/* Standard link */
				snprintf(tmpbuf, TEMP_BUF_SIZE, "<IMG border=\"0\" SRC=\"%s\"> <A HREF=\"gopher://%s/%c%s\">%s</A>\n",
				    icon_url, host, gtype, escaped_selector, html_quote(name));
			    }
			}
			safe_free(escaped_selector);
			strCat(outbuf, tmpbuf);
		    } else {
			memset(line, '\0', TEMP_BUF_SIZE);
			continue;
		    }
		} else {
		    memset(line, '\0', TEMP_BUF_SIZE);
		    continue;
		}
		break;
	    }			/* HTML_DIR, HTML_INDEX_RESULT */


	case HTML_CSO_RESULT:{
		if (line[0] == '-') {
		    int code, recno;
		    char *s_code, *s_recno, *result;

		    s_code = strtok(line + 1, ":\n");
		    s_recno = strtok(NULL, ":\n");
		    result = strtok(NULL, "\n");

		    if (!result)
			break;

		    code = atoi(s_code);
		    recno = atoi(s_recno);

		    if (code != 200)
			break;

		    if (gopherState->cso_recno != recno) {
			snprintf(tmpbuf, TEMP_BUF_SIZE, "</PRE><HR noshade size=\"1px\"><H2>Record# %d<br><i>%s</i></H2>\n<PRE>", recno, html_quote(result));
			gopherState->cso_recno = recno;
		    } else {
			snprintf(tmpbuf, TEMP_BUF_SIZE, "%s\n", html_quote(result));
		    }
		    strCat(outbuf, tmpbuf);
		    break;
		} else {
		    int code;
		    char *s_code, *result;

		    s_code = strtok(line, ":");
		    result = strtok(NULL, "\n");

		    if (!result)
			break;

		    code = atoi(s_code);
		    switch (code) {

		    case 200:{
			    /* OK */
			    /* Do nothing here */
			    break;
			}

		    case 102:	/* Number of matches */
		    case 501:	/* No Match */
		    case 502:	/* Too Many Matches */
			{
			    /* Print the message the server returns */
			    snprintf(tmpbuf, TEMP_BUF_SIZE, "</PRE><HR noshade size=\"1px\"><H2>%s</H2>\n<PRE>", html_quote(result));
			    strCat(outbuf, tmpbuf);
			    break;
			}


		    }
		}

	    }			/* HTML_CSO_RESULT */
	default:
	    break;		/* do nothing */

	}			/* switch */

    }				/* while loop */

    if (strLen(outbuf) > 0) {
	storeAppend(entry, strBuf(outbuf), strLen(outbuf));
	/* now let start sending stuff to client */
	storeBufferFlush(entry);
    }
    stringClean(&outbuf);
    return;
}
Exemple #3
0
char *
internalRedirectProcessURL(clientHttpRequest * req, rewritetoken * head)
{
    char *dev = NULL;
    size_t len = 0;
    debug(85, 5) ("internalRedirectProcessURL: start\n");
    for (; head != NULL; head = head->next) {
	const char *str = NULL;	/* string to append */
	size_t str_len = 0;
	int do_ulong = 0;
	unsigned long ulong = 0;
	const char *ulong_fmt = "%lu";
	debug(85, 5) ("internalRedirectProcessURL: token=%s str=%s urlEncode=%s\n",
	    tokenNames[head->type], head->str, head->urlEncode ? "true" : "false");
	switch (head->type) {
	case RFT_STRING:
	    str = head->str;
	    str_len = head->str_len;
	    break;
	case RFT_CLIENT_IPADDRESS:
	    str = inet_ntoa(req->conn->peer.sin_addr);
	    break;
	case RFT_LOCAL_IPADDRESS:
	    str = inet_ntoa(req->conn->me.sin_addr);
	    break;
	case RFT_LOCAL_PORT:
	    ulong = ntohs(req->conn->me.sin_port);
	    do_ulong = 1;
	    break;
	case RFT_EPOCH_SECONDS:
	    ulong = current_time.tv_sec;
	    do_ulong = 1;
	    break;
	case RFT_TIME_SUBSECONDS:
	    ulong = current_time.tv_usec / 1000;
	    do_ulong = 1;
	    ulong_fmt = "%03lu";
	    break;
	case RFT_USERNAME:
	    if (req->request->auth_user_request)
		str = authenticateUserUsername(req->request->auth_user_request->auth_user);

	    if (!str || !*str)
		str = req->conn->rfc931;

#ifdef USE_SSL
	    if ((!str || !*str) && req->conn != NULL)
		str = sslGetUserEmail(fd_table[req->conn->fd].ssl);
#endif

	    if (!str || !*str)
		str = req->request->extacl_user;

	    break;
	case RFT_USERLOGIN:
	    str = req->request->login;
	    break;
	case RFT_USERIDENT:
	    str = req->conn->rfc931;
	    break;
	case RFT_USERSSL:
#ifdef USE_SSL
	    if (req->conn != NULL)
		str = sslGetUserEmail(fd_table[req->conn->fd].ssl);
#endif
	    break;
	case RFT_EXTERNALACL_USER:
	    str = req->request->extacl_user;
	    break;
	case RFT_METHOD:
	    str = req->request->method->string;
	    break;
	case RFT_PROTOCOL:
	    str = ProtocolStr[req->request->protocol];
	    break;
	case RFT_URL:
	    str = req->uri;
	    break;
	case RFT_URLPATH:
	    str = req->request->urlpath.buf;
	    break;
	case RFT_URLHOST:
	    str = req->request->host;
	    break;
	case RFT_HDRHOST:
	    str = httpHeaderGetStr(&req->request->header, HDR_HOST);
	    break;
	case RFT_EXTERNALACL_LOGSTR:
	    str = req->request->extacl_log.buf;
	    break;
	default:
	    assert(0 && "Invalid rewrite token type");
	    break;
	}

	if (do_ulong) {
	    char tmpstr[12];
	    int nbytes = snprintf(tmpstr, 12, ulong_fmt, ulong);
	    assert(nbytes > 0);
	    dev = xreacat(dev, &len, tmpstr, nbytes);
	} else {
	    if ((str == NULL) || (*str == '\0'))
		str = "-";

	    if (str_len == 0)
		str_len = strlen(str);

	    if (head->urlEncode) {
		str = rfc1738_escape_part(str);
		str_len = strlen(str);
	    }
	    dev = xreacat(dev, &len, str, str_len);
	}
    }
    debug(85, 5) ("internalRedirectProcessURL: done: %s\n", dev);
    return dev;
}
Exemple #4
0
/* Borrow part of code from libwww2 came with Mosaic distribution */
static void
gopherToHTML(GopherStateData * gopherState, char *inbuf, int len)
{
    char *pos = inbuf;
    char *lpos = NULL;
    char *tline = NULL;
    LOCAL_ARRAY(char, line, TEMP_BUF_SIZE);
    LOCAL_ARRAY(char, tmpbuf, TEMP_BUF_SIZE);
    LOCAL_ARRAY(char, outbuf, TEMP_BUF_SIZE << 4);
    char *name = NULL;
    char *selector = NULL;
    char *host = NULL;
    char *port = NULL;
    char *escaped_selector = NULL;
    const char *icon_url = NULL;
    char gtype;
    StoreEntry *entry = NULL;

    memset(outbuf, '\0', TEMP_BUF_SIZE << 4);
    memset(tmpbuf, '\0', TEMP_BUF_SIZE);
    memset(line, '\0', TEMP_BUF_SIZE);

    entry = gopherState->entry;

    if (gopherState->conversion == HTML_INDEX_PAGE) {
	storeAppendPrintf(entry,
	    "<HTML><HEAD><TITLE>Gopher Index %s</TITLE></HEAD>\n"
	    "<BODY><H1>%s<BR>Gopher Search</H1>\n"
	    "<p>This is a searchable Gopher index. Use the search\n"
	    "function of your browser to enter search terms.\n"
	    "<ISINDEX></BODY></HTML>\n",
	    storeUrl(entry), storeUrl(entry));
	/* now let start sending stuff to client */
	storeBufferFlush(entry);
	gopherState->data_in = 1;

	return;
    }
    if (gopherState->conversion == HTML_CSO_PAGE) {
	storeAppendPrintf(entry,
	    "<HTML><HEAD><TITLE>CSO Search of %s</TITLE></HEAD>\n"
	    "<BODY><H1>%s<BR>CSO Search</H1>\n"
	    "<P>A CSO database usually contains a phonebook or\n"
	    "directory.  Use the search function of your browser to enter\n"
	    "search terms.</P><ISINDEX></BODY></HTML>\n",
	    storeUrl(entry), storeUrl(entry));
	/* now let start sending stuff to client */
	storeBufferFlush(entry);
	gopherState->data_in = 1;

	return;
    }
    inbuf[len] = '\0';

    if (!gopherState->HTML_header_added) {
	if (gopherState->conversion == HTML_CSO_RESULT)
	    strcat(outbuf, "<HTML><HEAD><TITLE>CSO Searchs Result</TITLE></HEAD>\n"
		"<BODY><H1>CSO Searchs Result</H1>\n<PRE>\n");
	else
	    strcat(outbuf, "<HTML><HEAD><TITLE>Gopher Menu</TITLE></HEAD>\n"
		"<BODY><H1>Gopher Menu</H1>\n<PRE>\n");
	gopherState->HTML_header_added = 1;
    }
    while ((pos != NULL) && (pos < inbuf + len)) {

	if (gopherState->len != 0) {
	    /* there is something left from last tx. */
	    xstrncpy(line, gopherState->buf, gopherState->len);
	    lpos = (char *) memccpy(line + gopherState->len, inbuf, '\n', len);
	    if (lpos)
		*lpos = '\0';
	    else {
		/* there is no complete line in inbuf */
		/* copy it to temp buffer */
		if (gopherState->len + len > TEMP_BUF_SIZE) {
		    debug(10, 1) ("GopherHTML: Buffer overflow. Lost some data on URL: %s\n",
			storeUrl(entry));
		    len = TEMP_BUF_SIZE - gopherState->len;
		}
		xmemcpy(gopherState->buf + gopherState->len, inbuf, len);
		gopherState->len += len;
		return;
	    }

	    /* skip one line */
	    pos = (char *) memchr(pos, '\n', len);
	    if (pos)
		pos++;

	    /* we're done with the remain from last tx. */
	    gopherState->len = 0;
	    *(gopherState->buf) = '\0';
	} else {

	    lpos = (char *) memccpy(line, pos, '\n', len - (pos - inbuf));
	    if (lpos)
		*lpos = '\0';
	    else {
		/* there is no complete line in inbuf */
		/* copy it to temp buffer */
		if ((len - (pos - inbuf)) > TEMP_BUF_SIZE) {
		    debug(10, 1) ("GopherHTML: Buffer overflow. Lost some data on URL: %s\n",
			storeUrl(entry));
		    len = TEMP_BUF_SIZE;
		}
		if (len > (pos - inbuf)) {
		    xmemcpy(gopherState->buf, pos, len - (pos - inbuf));
		    gopherState->len = len - (pos - inbuf);
		}
		break;
	    }

	    /* skip one line */
	    pos = (char *) memchr(pos, '\n', len);
	    if (pos)
		pos++;

	}

	/* at this point. We should have one line in buffer to process */

	if (*line == '.') {
	    /* skip it */
	    memset(line, '\0', TEMP_BUF_SIZE);
	    continue;
	}
	switch (gopherState->conversion) {

	case HTML_INDEX_RESULT:
	case HTML_DIR:{
		tline = line;
		gtype = *tline++;
		name = tline;
		selector = strchr(tline, TAB);
		if (selector) {
		    *selector++ = '\0';
		    host = strchr(selector, TAB);
		    if (host) {
			*host++ = '\0';
			port = strchr(host, TAB);
			if (port) {
			    char *junk;
			    port[0] = ':';
			    junk = strchr(host, TAB);
			    if (junk)
				*junk++ = 0;	/* Chop port */
			    else {
				junk = strchr(host, '\r');
				if (junk)
				    *junk++ = 0;	/* Chop port */
				else {
				    junk = strchr(host, '\n');
				    if (junk)
					*junk++ = 0;	/* Chop port */
				}
			    }
			    if ((port[1] == '0') && (!port[2]))
				port[0] = 0;	/* 0 means none */
			}
			/* escape a selector here */
			escaped_selector = xstrdup(rfc1738_escape_part(selector));

			switch (gtype) {
			case GOPHER_DIRECTORY:
			    icon_url = mimeGetIconURL("internal-menu");
			    break;
			case GOPHER_FILE:
			    icon_url = mimeGetIconURL("internal-text");
			    break;
			case GOPHER_INDEX:
			case GOPHER_CSO:
			    icon_url = mimeGetIconURL("internal-index");
			    break;
			case GOPHER_IMAGE:
			case GOPHER_GIF:
			case GOPHER_PLUS_IMAGE:
			    icon_url = mimeGetIconURL("internal-image");
			    break;
			case GOPHER_SOUND:
			case GOPHER_PLUS_SOUND:
			    icon_url = mimeGetIconURL("internal-sound");
			    break;
			case GOPHER_PLUS_MOVIE:
			    icon_url = mimeGetIconURL("internal-movie");
			    break;
			case GOPHER_TELNET:
			case GOPHER_3270:
			    icon_url = mimeGetIconURL("internal-telnet");
			    break;
			case GOPHER_BIN:
			case GOPHER_MACBINHEX:
			case GOPHER_DOSBIN:
			case GOPHER_UUENCODED:
			    icon_url = mimeGetIconURL("internal-binary");
			    break;
			default:
			    icon_url = mimeGetIconURL("internal-unknown");
			    break;
			}


			memset(tmpbuf, '\0', TEMP_BUF_SIZE);
			if ((gtype == GOPHER_TELNET) || (gtype == GOPHER_3270)) {
			    if (strlen(escaped_selector) != 0)
				snprintf(tmpbuf, TEMP_BUF_SIZE, "<IMG BORDER=0 SRC=\"%s\"> <A HREF=\"telnet://%s@%s/\">%s</A>\n",
				    icon_url, escaped_selector, host, name);
			    else
				snprintf(tmpbuf, TEMP_BUF_SIZE, "<IMG BORDER=0 SRC=\"%s\"> <A HREF=\"telnet://%s/\">%s</A>\n",
				    icon_url, host, name);

			} else {
			    snprintf(tmpbuf, TEMP_BUF_SIZE, "<IMG BORDER=0 SRC=\"%s\"> <A HREF=\"gopher://%s/%c%s\">%s</A>\n",
				icon_url, host, gtype, escaped_selector, name);
			}
			safe_free(escaped_selector);
			strcat(outbuf, tmpbuf);
			gopherState->data_in = 1;
		    } else {
			memset(line, '\0', TEMP_BUF_SIZE);
			continue;
		    }
		} else {
		    memset(line, '\0', TEMP_BUF_SIZE);
		    continue;
		}
		break;
	    }			/* HTML_DIR, HTML_INDEX_RESULT */


	case HTML_CSO_RESULT:{
		int t;
		int code;
		int recno;
		LOCAL_ARRAY(char, result, MAX_CSO_RESULT);

		tline = line;

		if (tline[0] == '-') {
		    t = sscanf(tline, "-%d:%d:%[^\n]", &code, &recno, result);
		    if (t < 3)
			break;

		    if (code != 200)
			break;

		    if (gopherState->cso_recno != recno) {
			snprintf(tmpbuf, TEMP_BUF_SIZE, "</PRE><HR><H2>Record# %d<br><i>%s</i></H2>\n<PRE>", recno, result);
			gopherState->cso_recno = recno;
		    } else {
			snprintf(tmpbuf, TEMP_BUF_SIZE, "%s\n", result);
		    }
		    strcat(outbuf, tmpbuf);
		    gopherState->data_in = 1;
		    break;
		} else {
		    /* handle some error codes */
		    t = sscanf(tline, "%d:%[^\n]", &code, result);

		    if (t < 2)
			break;

		    switch (code) {

		    case 200:{
			    /* OK */
			    /* Do nothing here */
			    break;
			}

		    case 102:	/* Number of matches */
		    case 501:	/* No Match */
		    case 502:	/* Too Many Matches */
			{
			    /* Print the message the server returns */
			    snprintf(tmpbuf, TEMP_BUF_SIZE, "</PRE><HR><H2>%s</H2>\n<PRE>", result);
			    strcat(outbuf, tmpbuf);
			    gopherState->data_in = 1;
			    break;
			}


		    }
		}

	    }			/* HTML_CSO_RESULT */
	default:
	    break;		/* do nothing */

	}			/* switch */

    }				/* while loop */

    if ((int) strlen(outbuf) > 0) {
	storeAppend(entry, outbuf, strlen(outbuf));
	/* now let start sending stuff to client */
	storeBufferFlush(entry);
    }
    return;
}