📄 htgopher.c
字号:
init_acceptable(); if (!arg) return -3; /* Bad if no name sepcified */ if (!*arg) return -2; /* Bad if name had zero length */ CTRACE((tfp, "HTLoadCSO: Looking for %s\n", arg)); /* ** Set up a socket to the server for the data. */ status = HTDoConnect (arg, "cso", CSO_PORT, &s); if (status == HT_INTERRUPTED) { /* ** Interrupt cleanly. */ CTRACE((tfp, "HTLoadCSO: Interrupted on connect; recovering cleanly.\n")); _HTProgress (CONNECTION_INTERRUPTED); return HT_NOT_LOADED; } if (status < 0) { CTRACE((tfp, "HTLoadCSO: Unable to connect to remote host for `%s'.\n", arg)); return HTInetStatus("connect"); } HTInitInput(s); /* Set up input buffering */ HTSprintf0(&command, "fields%c%c", CR, LF); CTRACE((tfp, "HTLoadCSO: Connected, writing command `%s' to socket %d\n", command, s)); _HTProgress (GOPHER_SENDING_CSO_REQUEST); status = NETWRITE(s, command, (int)strlen(command)); FREE(command); if (status < 0) { CTRACE((tfp, "HTLoadCSO: Unable to send command.\n")); return HTInetStatus("send"); } _HTProgress (GOPHER_SENT_CSO_REQUEST); /* ** Now read the data from the socket. */ status = parse_cso_fields(buf, sizeof(buf)); if (status) { NETCLOSE(s); if (status == HT_INTERRUPTED) { _HTProgress (CONNECTION_INTERRUPTED); } else if (buf[0] != '\0') { HTAlert(buf); } else { HTAlert(FAILED_NO_RESPONSE); } return HT_NOT_LOADED; } Target = HTStreamStack(format_in, format_out, sink, anAnchor); if (!Target || Target == NULL) { char *temp = 0; HTSprintf0(&temp, CANNOT_CONVERT_I_TO_O, HTAtom_name(format_in), HTAtom_name(format_out)); HTAlert(temp); FREE(temp); NETCLOSE(s); return HT_NOT_LOADED; } host = HTParse(arg, "", PARSE_HOST); if ((cp=strchr(host, ':')) != NULL) { if (cp[1] >= '0' && cp[1] <= '9') { port = atoi((cp+1)); if (port == CSO_PORT) { *cp = '\0'; } } } anAnchor->safe = TRUE; if (!(anAnchor->post_data && *anAnchor->post_data)) { generate_cso_form(host, port, buf, Target); (*Target->isa->_free)(Target); FREE(host); NETCLOSE(s); free_CSOfields(); return HT_LOADED; } HTSprintf0(&command, "<HTML>\n<HEAD>\n<TITLE>CSO/PH Results on %s</TITLE>\n</HEAD>\n<BODY>\n", host); (*Target->isa->put_block)(Target, command, strlen(command)); FREE(command); FREE(host); StrAllocCopy(content, anAnchor->post_data); if (content[strlen(content)-1] != '&') StrAllocCat(content, "&"); len = strlen(content); for (i = 0; i < len; i++) { if (content[i] == '+') { content[i] = ' '; } } HTUnEscape(content); len = strlen(content); return_type = 0; has_indexed = 0; start = finish = 0; for (i = 0; i < len; i++) { if (!content[i] || content[i] == '&') { /* ** Value parsed. Unescape characters and look for first '=' ** to delimit field name from value. */ flen = i - start; finish = start + flen; content[finish] = '\0'; for (j = start; j < finish; j++) { if (content[j] == '=') { /* ** content[start..j-1] is field name, ** [j+1..finish-1] is value. */ if ((content[start+1] == '_') && ((content[start] == 'r') || (content[start] == 'q'))) { /* ** Decode fields number and lookup field info. */ sscanf (&content[start+2], "%d=", &ndx); for (fld = CSOfields; fld; fld = fld->next) { if (ndx==fld->id) { if ((j+1) >= finish) break; /* ignore nulls */ if (content[start] == 'q') { /* * Append field to query line. */ if (fld->lookup) { if (fld->indexed) has_indexed = 1; if (command == 0 || *command == 0) { StrAllocCopy(command, "query "); } else { StrAllocCat(command, " "); } HTSprintf(&command, "%s=\"%s\"", fld->name, &content[j+1]); } else { strcpy(buf, "Warning: non-lookup field ignored<BR>\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); } } else if (content[start] == 'r') { fld->explicit_return = 1; } break; } } } else if (!strncmp(&content[start],"return=",7)) { if (!strcmp(&content[start+7],"all")) { return_type = 1; } else if (!strcmp(&content[start+7],"selected")) { return_type = 2; } } } } start = i + 1; } } FREE(content); if ((command == 0 || *command == 0) || !has_indexed) { NETCLOSE(s); strcpy(buf, "<EM>Error:</EM> At least one indexed field value must be specified!\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); strcpy(buf, "</BODY>\n</HTML>\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); (*Target->isa->_free)(Target); free_CSOfields(); return HT_LOADED; } /* ** Append return fields. */ if (return_type == 1) { StrAllocCat(command, " return all"); } else if (return_type == 2) { StrAllocCat(command, " return"); for (fld = CSOfields; fld; fld = fld->next) { if (fld->explicit_return) { HTSprintf(&command, " %s", fld->name); } } } HTSprintf(&command, "%c%c", CR, LF); strcpy(buf, "<H2>\n<EM>CSO/PH command:</EM> "); (*Target->isa->put_block)(Target, buf, strlen(buf)); (*Target->isa->put_block)(Target, command, strlen(command)); strcpy(buf, "</H2>\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); CTRACE((tfp, "HTLoadCSO: Writing command `%s' to socket %d\n", command, s)); status = NETWRITE(s, command, strlen(command)); FREE(command); if (status < 0) { CTRACE((tfp, "HTLoadCSO: Unable to send command.\n")); free_CSOfields(); return HTInetStatus("send"); } generate_cso_report(Target); NETCLOSE(s); (*Target->isa->put_block)(Target, end_form, sizeof(end_form)-1); (*Target->isa->_free)(Target); FREE(host); free_CSOfields(); return HT_LOADED;}/* Load by name. HTLoadGopher** =============**** Bug: No decoding of strange data types as yet.***/PRIVATE int HTLoadGopher ARGS4( CONST char *, arg, HTParentAnchor *, anAnchor, HTFormat, format_out, HTStream*, sink){ char *command; /* The whole command */ int status; /* tcp return */ char gtype; /* Gopher Node type */ char * selector; /* Selector string */ if (!acceptable_inited) init_acceptable(); if (!arg) return -3; /* Bad if no name sepcified */ if (!*arg) return -2; /* Bad if name had zero length */ CTRACE((tfp, "HTGopher: Looking for %s\n", arg)); /* ** If it's a port 105 GOPHER_CSO gtype with no ISINDEX token ('?'), ** use the form-based CSO gateway (otherwise, return an ISINDEX ** cover page or do the ISINDEX search). - FM */ { int len; if ((len = strlen(arg)) > 5) { if (0 == strcmp((CONST char *)&arg[len-6], ":105/2")) { /* Use CSO gateway. */ CTRACE((tfp, "HTGopher: Passing to CSO/PH gateway.\n")); return HTLoadCSO(arg, anAnchor, format_out, sink); } } } /* ** If it's a port 79/0[/...] URL, use the finger gateway. - FM */ if (strstr(arg, ":79/0") != NULL) {#ifndef DISABLE_FINGER CTRACE((tfp, "HTGopher: Passing to finger gateway.\n")); return HTLoadFinger(arg, anAnchor, format_out, sink);#else /* finger is disabled */ HTAlert(COULD_NOT_ACCESS_DOCUMENT); return HT_NOT_LOADED;#endif /* DISABLE_FINGER */ } /* ** Get entity type, and selector string. */ { char * p1 = HTParse(arg, "", PARSE_PATH|PARSE_PUNCTUATION); gtype = '1'; /* Default = menu */ selector = p1; if ((*selector++=='/') && (*selector)) { /* Skip first slash */ gtype = *selector++; /* Pick up gtype */ } if (gtype == GOPHER_INDEX) { char * query; /* ** Search is allowed. */ HTAnchor_setIndex(anAnchor, anAnchor->address); query = strchr(selector, '?'); /* Look for search string */ if (!query || !query[1]) { /* No search required */ target = HTML_new(anAnchor, format_out, sink); targetClass = *target->isa; display_index(arg, anAnchor); /* Display "cover page" */ return HT_LOADED; /* Local function only */ } *query++ = '\0'; /* Skip '?' */ command = (char *)malloc(strlen(selector)+ 1 + strlen(query)+ 2 + 1); if (command == NULL) outofmem(__FILE__, "HTLoadGopher"); de_escape(command, selector); /* Bug fix TBL 921208 */ strcat(command, "\t"); { /* Remove plus signs 921006 */ char *p; for (p=query; *p; p++) { if (*p == '+') *p = ' '; } } de_escape(&command[strlen(command)], query);/* bug fix LJM 940415 */ } else if (gtype == GOPHER_CSO) { char * query; /* ** Search is allowed. */ query = strchr(selector, '?'); /* Look for search string */ if (!query || !query[1]) { /* No search required */ target = HTML_new(anAnchor, format_out, sink); targetClass = *target->isa; display_cso(arg, anAnchor); /* Display "cover page" */ return HT_LOADED; /* Local function only */ } HTAnchor_setIndex(anAnchor, anAnchor->address); *query++ = '\0'; /* Skip '?' */ command = (char *)malloc(strlen("query")+1 + strlen(query)+2+1); if (command == NULL) outofmem(__FILE__, "HTLoadGopher"); de_escape(command, selector); /* Bug fix TBL 921208 */ strcpy(command, "query "); { /* Remove plus signs 921006 */ char *p; for (p=query; *p; p++) { if (*p == '+') *p = ' '; } } de_escape(&command[strlen(command)], query);/* bug fix LJM 940415 */ } else { /* Not index */ command = (char *)malloc(strlen(selector)+2+1); if (command == NULL) outofmem(__FILE__, "HTLoadGopher"); de_escape(command, selector); } FREE(p1); } { char * p = command + strlen(command); *p++ = CR; /* Macros to be correct on Mac */ *p++ = LF; *p++ = '\0'; } /* ** Set up a socket to the server for the data. */ status = HTDoConnect (arg, "gopher", GOPHER_PORT, &s); if (status == HT_INTERRUPTED) { /* ** Interrupt cleanly. */ CTRACE((tfp, "HTGopher: Interrupted on connect; recovering cleanly.\n")); _HTProgress (CONNECTION_INTERRUPTED); FREE(command); return HT_NOT_LOADED; } if (status < 0) { CTRACE((tfp, "HTGopher: Unable to connect to remote host for `%s'.\n", arg)); FREE(command); return HTInetStatus("connect"); } HTInitInput(s); /* Set up input buffering */ CTRACE((tfp, "HTGopher: Connected, writing command `%s' to socket %d\n", command, s));#ifdef NOT_ASCII { char * p; for (p = command; *p; p++) { *p = TOASCII(*p); } }#endif _HTProgress (GOPHER_SENDING_REQUEST); status = NETWRITE(s, command, (int)strlen(command)); FREE(command); if (status < 0) { CTRACE((tfp, "HTGopher: Unable to send command.\n")); return HTInetStatus("send"); } _HTProgress (GOPHER_SENT_REQUEST); /* ** Now read the data from the socket. */ switch (gtype) { case GOPHER_TEXT : HTParseSocket(WWW_PLAINTEXT, format_out, anAnchor, s, sink); break; case GOPHER_HTML : case GOPHER_CHTML : HTParseSocket(WWW_HTML, format_out, anAnchor, s, sink); break; case GOPHER_GIF: case GOPHER_IMAGE: case GOPHER_PLUS_IMAGE: HTParseSocket(HTAtom_for("image/gif"), format_out, anAnchor, s, sink); break; case GOPHER_MENU : case GOPHER_INDEX : target = HTML_new(anAnchor, format_out, sink); targetClass = *target->isa; parse_menu(arg, anAnchor); break; case GOPHER_CSO: target = HTML_new(anAnchor, format_out, sink); targetClass = *target->isa; parse_cso(arg, anAnchor); break; case GOPHER_SOUND : case GOPHER_PLUS_SOUND : HTParseSocket(WWW_AUDIO, format_out, anAnchor, s, sink); break; case GOPHER_PLUS_MOVIE: HTParseSocket(HTAtom_for("video/mpeg"), format_out, anAnchor, s, sink); break; case GOPHER_PLUS_PDF: HTParseSocket(HTAtom_for("application/pdf"), format_out, anAnchor, s, sink); break; case GOPHER_MACBINHEX: case GOPHER_PCBINARY: case GOPHER_UUENCODED: case GOPHER_BINARY: default: /* ** Specifying WWW_UNKNOWN forces dump to local disk. */ HTParseSocket (WWW_UNKNOWN, format_out, anAnchor, s, sink); break; } /* switch(gtype) */ NETCLOSE(s); return HT_LOADED;}#ifdef GLOBALDEF_IS_MACRO#define _HTGOPHER_C_1_INIT { "gopher", HTLoadGopher, NULL }GLOBALDEF (HTProtocol, HTGopher, _HTGOPHER_C_1_INIT);#define _HTCSO_C_1_INIT { "cso", HTLoadCSO, NULL }GLOBALDEF (HTProtocol, HTCSO, _HTCSO_C_1_INIT);#elseGLOBALDEF PUBLIC HTProtocol HTGopher = { "gopher", HTLoadGopher, NULL };GLOBALDEF PUBLIC HTProtocol HTCSO = { "cso", HTLoadCSO, NULL };#endif /* GLOBALDEF_IS_MACRO */#endif /* not DISABLE_GOPHER */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -