📄 htgopher.c
字号:
/* ** Check status, ignore any non-success. */ if (p[1] != '2' ) continue; /* ** Parse fields within returned line into status, ndx, name, ** data. */ indx = NULL; name = NULL; for (i = 0; p[i]; i++) { if (p[i] == ':' ) { p[i] = '\0'; if (!indx) { indx = (char *)&p[i+1]; code = atoi (indx); } else if (!name) { name = (char *)&p[i+1]; } else { i++; break; } } } /* ** Add data to field structure. */ if (name) { if (code == prev_code) { /* ** Remaining data are description. ** Save in current info block. */ alen = strlen((char *)&p[i]) + 1; if (alen > sizeof(last->desc_buf)) { if (last->description != last->desc_buf) FREE(last->description); if (!(last->description = (char *)malloc(alen))) { outofmem(__FILE__, "HTLoadCSO"); } } strcpy(last->description, (char *)&p[i]); } else { /* ** Initialize new block, append to end of list ** to preserve order. */ new = typecalloc(CSOfield_info); if (!new) { outofmem(__FILE__, "HTLoadCSO"); } if (last) last->next = new; else CSOfields = new; last = new; new->next = (CSOfield_info *) 0; new->name = new->name_buf; alen = strlen(name) + 1; if (alen > sizeof(new->name_buf)) { if (!(new->name = (char *)malloc(alen))) { outofmem(__FILE__, "HTLoadCSO"); } } strcpy (new->name, name); new->attributes = new->attr_buf; alen = strlen((char *)&p[i]) + 2; if (alen > sizeof(new->attr_buf)) { if (!(new->attributes = (char *)malloc(alen))) { outofmem(__FILE__, "HTLoadCSO"); } } strcpy(new->attributes, (char *)&p[i]); strcpy((char *)&new->attributes[alen-2], " "); new->description = new->desc_buf; new->desc_buf[0] = '\0'; new->id = atoi(indx); /* ** Scan for keywords. */ parse_cso_field_info(new); } prev_code = code; } else break; } /* end if *p == '-' */ } /* if end of line */ } /* Loop over characters */ /* end the text block */ if (buf[0] == '\0') { return -1; /* no response */ } buf[0] = '\0'; return 0; /* all done */} /* end of procedure *//* Generate a form for submitting CSO/PH searches. - FM** ====================================================*/PRIVATE int generate_cso_form ARGS4( char *, host, int, port, char *, buf, HTStream *, Target){ int i, j, length; size_t out; int full_flag = 1; char *key, *line; CSOformgen_context ctx; static char *template[] = { "<HTML>\n<HEAD>\n<TITLE>CSO/PH Query Form for $(HOST)</TITLE>\n</HEAD>\n<BODY>", "<H2><I>CSO/PH Query Form</I> for <EM>$(HOST)</EM></H2>", "To search the database for a name, fill in one or more of the fields", "in the form below and activate the 'Submit query' button. At least", "one of the entered fields must be flagged as indexed.", "<HR><FORM method=\"POST\" action=\"cso://$(HOST)/\">", "[ <input type=\"submit\" value=\"Submit query\"> | ", "<input type=\"reset\" value=\"Clear fields\"> ]", "<P><DL>", " <DT>Search parameters (* indicates indexed field):", " <DD>", "$(NAMEFLD) <DL COMPACT>\n <DT><I>$(FDESC)</I>$(FNDX)", " <DD>Last: <input name=\"q_$(FID)\" type=\"text\" size=49$(FSIZE2)>", " <DD>First: <input name=\"q_$(FID)\" type=\"text\" size=48$(FSIZE2)>", "$(QFIELDS) <DT><I>$(FDESC)</I>$(FNDX)", " <DD><input name=\"q_$(FID)\" type=\"text\" $(FSIZE)>\n$(NEXTFLD)", " </DL>", " </DL>\n<P><DL>", " <DT>Output format:", " <DD>Returned data option: <select name=\"return\">", " <option>default<option selected>all<option>selected</select><BR>", "$(RFIELDS) <input type=\"checkbox\" name=\"r_$(FID)\"$(FDEF)> $(FDESC)<BR>", "$(NEXTFLD) ", " </DL></FORM><HR>\n</BODY>\n</HTML>", (char *) 0 }; out = 0; ctx.host = host; ctx.seek = (char *) 0; ctx.port = port; ctx.fld = (CSOfield_info *) 0; ctx.public_override = full_flag; /* ** Parse the strings in the template array to produce HTML document ** to send to client. First line is skipped for 'full' lists. */ out = 0; buf[out] = '\0'; for (i = full_flag ? /***1***/ 0 : 0; template[i]; i++) { /* ** Search the current string for substitution, flagged by $( */ for (line=template[i], j = 0; line[j]; j++) { if ((line[j] == '$') && (line[j+1] == '(')) { /* ** Command detected, flush output buffer and find closing ')' ** that delimits the command. */ buf[out] = '\0'; if (out > 0) (*Target->isa->put_block)(Target, buf, strlen(buf)); out = 0; for (key = &line[j]; line[j+1] && (line[j] != ')'); j++) ; /* ** Save context, interpet command and restore updated context. */ ctx.cur_line = i; ctx.cur_off = j; interpret_cso_key(key, buf, &length, &ctx, Target); i = ctx.cur_line; j = ctx.cur_off; line = template[i]; out = length; if (ctx.seek) { /* ** Command wants us to skip (forward) to indicated token. ** Start at current position. */ int slen = strlen(ctx.seek); for (; template[i]; i++) { for (line = template[i]; line[j]; j++) { if (line[j] == '$') if (0 == strncmp(ctx.seek, &line[j], slen)) { if (j == 0) j = strlen(template[--i])-1; else --j; line = template[i]; ctx.seek = (char *) 0; break; } } if (!ctx.seek) break; j = 0; } if (ctx.seek) { char *temp = 0; HTSprintf0(&temp, GOPHER_CSO_SEEK_FAILED, ctx.seek); (*Target->isa->put_block)(Target, temp, strlen(temp)); FREE(temp); } } } else { /* ** Non-command text, add to output buffer. */ buf[out++] = line[j]; if (out > (sizeof(buf)-3)) { buf[out] = '\0'; (*Target->isa->put_block)(Target, buf, strlen(buf)); out = 0; } } } buf[out++] = '\n'; buf[out] = '\0'; } if (out > 0) (*Target->isa->put_block)(Target, buf, strlen(buf)); return 0;}/* Generate a results report for CSO/PH form-based searches. - FM** ==============================================================*/PRIVATE int generate_cso_report ARGS1( HTStream *, Target){ int ich; char line[BIG]; char *buf = 0; char *p = line, *href = NULL; int len, i, prev_ndx, ndx; char *rcode, *ndx_str, *fname, *fvalue, *l; CSOfield_info *fld; BOOL stop = FALSE; /* ** Read lines until non-negative status. */ prev_ndx = -100; /* ** Start grabbing chars from the network. */ while (!stop && (ich = NEXT_CHAR) != EOF) { if (interrupted_in_htgetcharacter) { CTRACE((tfp, "HTLoadCSO: Interrupted in HTGetCharacter, apparently.\n")); _HTProgress (CONNECTION_INTERRUPTED); goto end_CSOreport; } if ((char)ich != LF) { *p = (char) ich; /* Put character in line */ if (p < &line[BIG-1]) { p++; } } else { *p = '\0'; /* Terminate line */ /* ** OK we now have a line. ** Load it as 'p' and parse it. */ p = line; if (p[0] != '-' && p[0] != '1') { stop = TRUE; } rcode = (p[0] == '-') ? &p[1] : p; ndx_str = fname = NULL; len = strlen(p); for (i = 0; i < len; i++) { if (p[i] == ':') { p[i] = '\0'; if (!ndx_str) { fname = ndx_str = &p[i+1]; } else { fname = &p[i+1]; break; } } } if (ndx_str) { ndx = atoi(ndx_str); if (prev_ndx != ndx) { if (prev_ndx != -100) { HTSprintf0(&buf, "</DL></DL>\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); } if (ndx == 0) { HTSprintf0(&buf, "<HR><DL><DT>Information/status<DD><DL><DT>\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); } else { HTSprintf0(&buf, "<HR><DL><DT>Entry %d:<DD><DL COMPACT><DT>\n", ndx); (*Target->isa->put_block)(Target, buf, strlen(buf)); } prev_ndx = ndx; } } else { HTSprintf0(&buf, "<DD>%s\n", rcode); (*Target->isa->put_block)(Target, buf, strlen(buf)); continue; } if ((*rcode >= '2') && (*rcode <= '5') && (fname != ndx_str)) { while (*fname == ' ') { fname++; /* trim leading spaces */ } for (fvalue = fname; *fvalue; fvalue++) { if (*fvalue == ':') { *fvalue++ = '\0'; i = strlen(fname) - 1; while (i >= 0 && fname[i] == ' ') { fname[i--] = '\0'; /* trim trailing */ } break; } } if (fvalue) { while (*fvalue == ' ') { fvalue++; /* trim leading spaces */ } } if (*fname) { for (fld = CSOfields; fld; fld = fld->next) { if (!strcmp(fld->name, fname)) { if (fld->description) { fname = fld->description; } break; } } if (fld && fld->url) { HTSprintf0(&buf, "<DT><I>%s</I><DD><A HREF=\"%s\">%s</A>\n", fname, fvalue, fvalue); (*Target->isa->put_block)(Target, buf, strlen(buf)); } else { HTSprintf0(&buf, "<DT><I>%s</I><DD>", fname); (*Target->isa->put_block)(Target, buf, strlen(buf)); buf[0] = '\0'; l = fvalue; while (*l) { if (*l == '<') { StrAllocCat(buf, "<"); l++; } else if (*l == '>') { StrAllocCat(buf, ">"); l++; } else if (strncmp(l, STR_NEWS_URL, LEN_NEWS_URL) && strncmp(l, "snews://", 8) && strncmp(l, "nntp://", 7) && strncmp(l, "snewspost:", 10) && strncmp(l, "snewsreply:", 11) && strncmp(l, "newspost:", 9) && strncmp(l, "newsreply:", 10) && strncmp(l, "ftp://", 6) && strncmp(l, "file:/", 6) && strncmp(l, "finger://", 9) && strncmp(l, "http://", 7) && strncmp(l, "https://", 8) && strncmp(l, "wais://", 7) && strncmp(l, STR_MAILTO_URL, LEN_MAILTO_URL) && strncmp(l, "cso://", 6) && strncmp(l, "gopher://", 9)) { HTSprintf(&buf, "%c", *l++); } else { StrAllocCat(buf, "<a href=\""); StrAllocCopy(href, l); StrAllocCat(buf, strtok(href, " \r\n\t,>)\"")); StrAllocCat(buf, "\">"); while (*l && !strchr(" \r\n\t,>)\"", *l)) { HTSprintf(&buf, "%c", *l++); } StrAllocCat(buf, "</a>"); FREE(href); } } StrAllocCat(buf, "\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); } } else { HTSprintf0(&buf, "<DD>"); (*Target->isa->put_block)(Target, buf, strlen(buf)); buf[0] = '\0'; l = fvalue; while (*l) { if (*l == '<') { StrAllocCat(buf, "<"); l++; } else if (*l == '>') { StrAllocCat(buf, ">"); l++; } else if (strncmp(l, STR_NEWS_URL, LEN_NEWS_URL) && strncmp(l, "snews://", 8) && strncmp(l, "nntp://", 7) && strncmp(l, "snewspost:", 10) && strncmp(l, "snewsreply:", 11) && strncmp(l, "newspost:", 9) && strncmp(l, "newsreply:", 10) && strncmp(l, "ftp://", 6) && strncmp(l, "file:/", 6) && strncmp(l, "finger://", 9) && strncmp(l, "http://", 7) && strncmp(l, "https://", 8) && strncmp(l, "wais://", 7) && strncmp(l, STR_MAILTO_URL, LEN_MAILTO_URL) && strncmp(l, "cso://", 6) && strncmp(l, "gopher://", 9)) { HTSprintf(&buf, "%c", *l++); } else { StrAllocCat(buf, "<a href=\""); StrAllocCopy(href, l); StrAllocCat(buf, strtok(href, " \r\n\t,>)\"")); StrAllocCat(buf, "\">"); while (*l && !strchr(" \r\n\t,>)\"", *l)) { HTSprintf(&buf, "%c", *l++); } StrAllocCat(buf, "</a>"); FREE(href); } } StrAllocCat(buf, "\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); } } else { HTSprintf0(&buf, "<DD>%s\n", fname ? fname : rcode ); (*Target->isa->put_block)(Target, buf, strlen(buf)); } } }end_CSOreport: if (prev_ndx != -100) { HTSprintf0(&buf, "</DL></DL>\n"); (*Target->isa->put_block)(Target, buf, strlen(buf)); } FREE(buf); return 0;}/* CSO/PH form-based search gateway - FM HTLoadCSO** =====================================*/PRIVATE int HTLoadCSO ARGS4( CONST char *, arg, HTParentAnchor *, anAnchor, HTFormat, format_out, HTStream*, sink){ static CONST char end_form[] = "</BODY>\n</HTML>\n"; char *host, *cp, *data; int port = CSO_PORT; int status; /* tcp return */ bstring *command = NULL; bstring *content = NULL; int len, i, j, start, finish, flen, ndx; int return_type, has_indexed; CSOfield_info *fld; char buf[2048]; HTFormat format_in = WWW_HTML; HTStream *Target = NULL; 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, "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) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -