static unsigned int __stdcall ipc_thread_2(void *in_params) { int x; struct thread_params *params = (struct thread_params *) in_params; int type = params->type; int rfd = params->rfd; int send_fd = params->send_fd; char *prog = xstrdup(params->prog); pid_t pid = params->pid; char *buf2 = xcalloc(1, 8192); for (;;) { if (type == IPC_TCP_SOCKET) x = read(rfd, buf2, 8192); else x = recv(rfd, buf2, 8192, 0); if ((x <= 0 && type == IPC_TCP_SOCKET) || (x < 0 && type == IPC_UDP_SOCKET)) { debug(54, 3) ("ipc(%s,%d): %d bytes read from %s. Exiting...\n", prog, pid, x, prog); break; } buf2[x] = '\0'; if (type == IPC_UDP_SOCKET && !strcmp(buf2, shutdown_string)) { debug(54, 3) ("ipc(%s,%d): request for shutdown received. Exiting...\n", prog, pid); break; } if (x >= 2) { if ((buf2[x - 1] == '\n') && (buf2[x - 2] == '\r')) { buf2[x - 2] = '\n'; buf2[x - 1] = '\0'; x--; } } debug(54, 5) ("ipc(%s,%d): received from child : %s\n", prog, pid, rfc1738_escape_unescaped(buf2)); x = send(send_fd, buf2, x, 0); if ((x <= 0 && type == IPC_TCP_SOCKET) || (x < 0 && type == IPC_UDP_SOCKET)) { debug(54, 3) ("ipc(%s,%d): %d bytes sent to parent. Exiting...\n", prog, pid, x); break; } } xfree(prog); xfree(buf2); return 0; }
void storeLog(int tag, const StoreEntry * e) { MemObject *mem = e->mem_obj; HttpReply *reply; if (NULL == storelog) return; #if UNUSED_CODE if (EBIT_TEST(e->flags, ENTRY_DONT_LOG)) return; #endif if (mem != NULL) { reply = mem->reply; /* * XXX Ok, where should we print the dir number here? * Because if we print it before the swap file number, it'll break * the existing log format. */ logfileLineStart(storelog); logfilePrintf(storelog, "%9ld.%03d %-7s %02d %08X %s %4d %9ld %9ld %9ld %s %" PRINTF_OFF_T "/%" PRINTF_OFF_T " %s %s\n", (long int) current_time.tv_sec, (int) current_time.tv_usec / 1000, storeLogTags[tag], e->swap_dirn, e->swap_filen, storeKeyText(e->hash.key), reply->sline.status, (long int) reply->date, (long int) reply->last_modified, (long int) reply->expires, strLen(reply->content_type) ? strBuf(reply->content_type) : "unknown", reply->content_length, mem->inmem_hi - mem->reply->hdr_sz, RequestMethods[mem->method].str, rfc1738_escape_unescaped(mem->url)); logfileLineEnd(storelog); } else { /* no mem object. Most RELEASE cases */ logfileLineStart(storelog); logfilePrintf(storelog, "%9ld.%03d %-7s %02d %08X %s ? ? ? ? ?/? ?/? ? ?\n", (long int) current_time.tv_sec, (int) current_time.tv_usec / 1000, storeLogTags[tag], e->swap_dirn, e->swap_filen, storeKeyText(e->hash.key)); logfileLineEnd(storelog); } }
static unsigned int __stdcall ipc_thread_1(void *in_params) { int t1, t2, t3, retval = -1; int p2c[2] = {-1, -1}; int c2p[2] = {-1, -1}; HANDLE hProcess = NULL, thread = NULL; pid_t pid = -1; struct thread_params thread_params; int x, tmp_s, fd = -1; char *str; #if HAVE_PUTENV char *env_str = NULL; #endif STARTUPINFO si; PROCESS_INFORMATION pi; long F; int prfd_ipc = -1, pwfd_ipc = -1, crfd_ipc = -1, cwfd_ipc = -1; char *prog = NULL, *buf1 = NULL; struct sockaddr_in CS_ipc, PS_ipc; struct ipc_params *params = (struct ipc_params *) in_params; int type = params->type; int crfd = params->crfd; int cwfd = params->cwfd; char **args = params->args; struct sockaddr_in PS = params->PS; buf1 = xcalloc(1, 8192); strcpy(buf1, params->prog); prog = strtok(buf1, w_space); if ((str = strrchr(prog, '/'))) prog = ++str; if ((str = strrchr(prog, '\\'))) prog = ++str; prog = xstrdup(prog); if (type == IPC_TCP_SOCKET) { debug(54, 3) ("ipcCreate: calling accept on FD %d\n", crfd); if ((fd = accept(crfd, NULL, NULL)) < 0) { debug(54, 0) ("ipcCreate: FD %d accept: %s\n", crfd, xstrerror()); goto cleanup; } debug(54, 3) ("ipcCreate: CHILD accepted new FD %d\n", fd); comm_close(crfd); snprintf(buf1, 8191, "%s CHILD socket", prog); fd_open(fd, FD_SOCKET, buf1); fd_table[fd].flags.ipc = 1; cwfd = crfd = fd; } else if (type == IPC_UDP_SOCKET) { if (comm_connect_addr(crfd, &PS) == COMM_ERROR) goto cleanup; } x = send(cwfd, hello_string, strlen(hello_string) + 1, 0); if (x < 0) { debug(54, 0) ("sendto FD %d: %s\n", cwfd, xstrerror()); debug(54, 0) ("ipcCreate: CHILD: hello write test failed\n"); goto cleanup; } #if HAVE_PUTENV env_str = xcalloc((tmp_s = strlen(Config.debugOptions) + 32), 1); snprintf(env_str, tmp_s, "SQUID_DEBUG=%s", Config.debugOptions); putenv(env_str); #endif memset(buf1, '\0', sizeof(buf1)); x = recv(crfd, buf1, 8191, 0); if (x < 0) { debug(54, 0) ("ipcCreate: CHILD: OK read test failed\n"); debug(54, 0) ("--> read: %s\n", xstrerror()); goto cleanup; } else if (strcmp(buf1, ok_string)) { debug(54, 0) ("ipcCreate: CHILD: OK read test failed\n"); debug(54, 0) ("--> read returned %d\n", x); debug(54, 0) ("--> got '%s'\n", rfc1738_escape(hello_buf)); goto cleanup; } /* assign file descriptors to child process */ if (_pipe(p2c, 1024, _O_BINARY | _O_NOINHERIT) < 0) { debug(54, 0) ("ipcCreate: CHILD: pipe: %s\n", xstrerror()); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } if (_pipe(c2p, 1024, _O_BINARY | _O_NOINHERIT) < 0) { debug(54, 0) ("ipcCreate: CHILD: pipe: %s\n", xstrerror()); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } if (type == IPC_UDP_SOCKET) { snprintf(buf1, 8192, "%s(%ld) <-> ipc CHILD socket", prog, -1L); crfd_ipc = cwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1); if (crfd_ipc < 0) { debug(54, 0) ("ipcCreate: CHILD: Failed to create child FD for %s.\n", prog); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } snprintf(buf1, 8192, "%s(%ld) <-> ipc PARENT socket", prog, -1L); prfd_ipc = pwfd_ipc = comm_open(SOCK_DGRAM, IPPROTO_UDP, local_addr, 0, 0, buf1); if (pwfd_ipc < 0) { debug(54, 0) ("ipcCreate: CHILD: Failed to create server FD for %s.\n", prog); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } tmp_s = sizeof(PS_ipc); memset(&PS_ipc, '\0', tmp_s); if (getsockname(pwfd_ipc, (struct sockaddr *) &PS_ipc, &tmp_s) < 0) { debug(54, 0) ("ipcCreate: getsockname: %s\n", xstrerror()); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n", pwfd_ipc, inet_ntoa(PS_ipc.sin_addr), ntohs(PS_ipc.sin_port)); tmp_s = sizeof(CS_ipc); memset(&CS_ipc, '\0', tmp_s); if (getsockname(crfd_ipc, (struct sockaddr *) &CS_ipc, &tmp_s) < 0) { debug(54, 0) ("ipcCreate: getsockname: %s\n", xstrerror()); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } debug(54, 3) ("ipcCreate: FD %d sockaddr %s:%d\n", crfd_ipc, inet_ntoa(CS_ipc.sin_addr), ntohs(CS_ipc.sin_port)); if (comm_connect_addr(pwfd_ipc, &CS_ipc) == COMM_ERROR) { ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } fd = crfd; if (comm_connect_addr(crfd_ipc, &PS_ipc) == COMM_ERROR) { ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } } /* IPC_UDP_SOCKET */ t1 = dup(0); t2 = dup(1); t3 = dup(2); dup2(c2p[0], 0); dup2(p2c[1], 1); dup2(fileno(debug_log), 2); close(c2p[0]); close(p2c[1]); commUnsetNonBlocking(fd); memset(&si, 0, sizeof(STARTUPINFO)); si.cb = sizeof(STARTUPINFO); si.hStdInput = (HANDLE) _get_osfhandle(0); si.hStdOutput = (HANDLE) _get_osfhandle(1); si.hStdError = (HANDLE) _get_osfhandle(2); si.dwFlags = STARTF_USESTDHANDLES; /* Make sure all other valid handles are not inerithable */ for (x = 3; x < Squid_MaxFD; x++) { if ((F = _get_osfhandle(x)) == -1) continue; SetHandleInformation((HANDLE) F, HANDLE_FLAG_INHERIT, 0); } *buf1 = '\0'; strcpy(buf1 + 4096, params->prog); str = strtok(buf1 + 4096, w_space); do { strcat(buf1, str); strcat(buf1, " "); } while ((str = strtok(NULL, w_space))); x = 1; while (args[x]) { strcat(buf1, args[x++]); strcat(buf1, " "); } if (CreateProcess(buf1 + 4096, buf1, NULL, NULL, TRUE, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)) { pid = pi.dwProcessId; hProcess = pi.hProcess; } else { pid = -1; WIN32_maperror(GetLastError()); x = errno; } dup2(t1, 0); dup2(t2, 1); dup2(t3, 2); close(t1); close(t2); close(t3); if (pid == -1) { errno = x; debug(54, 0) ("ipcCreate: CHILD: %s: %s\n", params->prog, xstrerror()); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } if (type == IPC_UDP_SOCKET) { WSAPROTOCOL_INFO wpi; memset(&wpi, 0, sizeof(wpi)); if (SOCKET_ERROR == WSADuplicateSocket(crfd_ipc, pid, &wpi)) { debug(54, 0) ("ipcCreate: CHILD: WSADuplicateSocket: %s\n", xstrerror()); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } x = write(c2p[1], (const char *) &wpi, sizeof(wpi)); if (x < sizeof(wpi)) { debug(54, 0) ("ipcCreate: CHILD: write FD %d: %s\n", c2p[1], xstrerror()); debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n", prog); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } x = read(p2c[0], buf1, 8192); if (x < 0) { debug(54, 0) ("ipcCreate: CHILD: read FD %d: %s\n", p2c[0], xstrerror()); debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n", prog); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } else if (strncmp(buf1, ok_string, strlen(ok_string))) { debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n", prog); debug(54, 0) ("--> read returned %d\n", x); buf1[x] = '\0'; debug(54, 0) ("--> got '%s'\n", rfc1738_escape(buf1)); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } x = write(c2p[1], (const char *) &PS_ipc, sizeof(PS_ipc)); if (x < sizeof(PS_ipc)) { debug(54, 0) ("ipcCreate: CHILD: write FD %d: %s\n", c2p[1], xstrerror()); debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n", prog); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } x = read(p2c[0], buf1, 8192); if (x < 0) { debug(54, 0) ("ipcCreate: CHILD: read FD %d: %s\n", p2c[0], xstrerror()); debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n", prog); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } else if (strncmp(buf1, ok_string, strlen(ok_string))) { debug(54, 0) ("ipcCreate: CHILD: %s: socket exchange failed\n", prog); debug(54, 0) ("--> read returned %d\n", x); buf1[x] = '\0'; debug(54, 0) ("--> got '%s'\n", rfc1738_escape(buf1)); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } x = send(pwfd_ipc, ok_string, strlen(ok_string), 0); x = recv(prfd_ipc, buf1 + 200, 8191 - 200, 0); assert((size_t) x == strlen(ok_string) && !strncmp(ok_string, buf1 + 200, strlen(ok_string))); } /* IPC_UDP_SOCKET */ snprintf(buf1, 8191, "%s(%ld) CHILD socket", prog, (long int) pid); fd_note(fd, buf1); if (prfd_ipc != -1) { snprintf(buf1, 8191, "%s(%ld) <-> ipc CHILD socket", prog, (long int) pid); fd_note(crfd_ipc, buf1); snprintf(buf1, 8191, "%s(%ld) <-> ipc PARENT socket", prog, (long int) pid); fd_note(prfd_ipc, buf1); } /* else { IPC_TCP_SOCKET */ /* commSetNoLinger(fd); */ /* } */ thread_params.prog = prog; thread_params.send_fd = cwfd; thread_params.pid = pid; if ((thread_params.type = type) == IPC_TCP_SOCKET) thread_params.rfd = p2c[0]; else thread_params.rfd = prfd_ipc; thread = (HANDLE) _beginthreadex(NULL, 0, ipc_thread_2, &thread_params, 0, NULL); if (!thread) { debug(54, 0) ("ipcCreate: CHILD: _beginthreadex: %s\n", xstrerror()); ipcSend(cwfd, err_string, strlen(err_string)); goto cleanup; } snprintf(buf1, 8191, "%ld\n", (long int) pid); if (-1 == ipcSend(cwfd, buf1, strlen(buf1))) goto cleanup; debug(54, 2) ("ipc(%s,%ld): started successfully\n", prog, (long int) pid); /* cycle */ for (;;) { x = recv(crfd, buf1, 8192, 0); if (x <= 0) { debug(54, 3) ("ipc(%s,%d): %d bytes received from parent. Exiting...\n", prog, pid, x); break; } buf1[x] = '\0'; if (type == IPC_UDP_SOCKET && !strcmp(buf1, shutdown_string)) { debug(54, 3) ("ipc(%s,%d): request for shutdown received from parent. Exiting...\n", prog, pid); TerminateProcess(hProcess, 0); break; } debug(54, 5) ("ipc(%s,%d): received from parent: %s\n", prog, pid, rfc1738_escape_unescaped(buf1)); if (type == IPC_TCP_SOCKET) x = write(c2p[1], buf1, x); else x = send(pwfd_ipc, buf1, x, 0); if (x <= 0) { debug(54, 3) ("ipc(%s,%d): %d bytes written to %s. Exiting...\n", prog, pid, x, prog); break; } } retval = 0; cleanup: if (c2p[1] != -1) close(c2p[1]); if (fd_table[crfd].flags.open) ipcCloseAllFD(-1, -1, crfd, cwfd); if (prfd_ipc != -1) { send(crfd_ipc, shutdown_string, strlen(shutdown_string), 0); shutdown(crfd_ipc, SD_BOTH); shutdown(prfd_ipc, SD_BOTH); } ipcCloseAllFD(prfd_ipc, pwfd_ipc, crfd_ipc, cwfd_ipc); if (hProcess && WAIT_OBJECT_0 != WaitForSingleObject(hProcess, type == IPC_UDP_SOCKET ? 12000 : 5000)) { getCurrentTime(); debug(54, 0) ("ipc(%s,%d): WARNING: %s didn't exit in %d seconds.\n", prog, pid, prog, type == IPC_UDP_SOCKET ? 12 : 5); } if (thread && WAIT_OBJECT_0 != WaitForSingleObject(thread, 3000)) { getCurrentTime(); debug(54, 0) ("ipc(%s,%d): WARNING: ipc_thread_2 didn't exit in 3 seconds.\n", prog, pid); } getCurrentTime(); if (!retval) debug(54, 2) ("ipc(%s,%d): normal exit\n", prog, pid); if (buf1) xfree(buf1); if (prog) xfree(prog); if (env_str) xfree(env_str); if (thread) CloseHandle(thread); if (hProcess) CloseHandle(hProcess); if (p2c[0] != -1) close(p2c[0]); return retval; }
/* 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; }