📄 htgopher.c
字号:
PUTS(arg); PUTS(GOPHER_SEARCH_RESULTS); } END(HTML_H1); PUTC('\n'); START(HTML_PRE); /* ** Start grabbing chars from the network. */ while ((ich=NEXT_CHAR) != EOF) { if ((char)ich != LF) { *p = (char) ich; /* Put character in line */ if (p< &line[BIG-1]) p++; } else { *p = '\0'; /* Terminate line */ p = line; /* Scan it to parse it */ /* ** OK we now have a line in 'p'. ** Lets parse it and print it. */ /* ** Break on line that begins with a 2. ** It's the end of data. */ if (*p == '2') break; /* ** Lines beginning with 5 are errors. ** Print them and quit. */ if (*p == '5') { START(HTML_H2); PUTS(p+4); END(HTML_H2); break; } if (*p == '-') { /* ** Data lines look like -200:#: ** where # is the search result number and can be ** multiple digits (infinite?). ** Find the second colon and check the digit to the ** left of it to see if they are diferent. ** If they are then a different person is starting. ** Make this line an <h2>. */ /* ** Find the second_colon. */ second_colon = strchr( strchr(p,':')+1, ':'); if(second_colon != NULL) { /* error check */ if (*(second_colon-1) != last_char) /* print seperator */ { END(HTML_PRE); START(HTML_H2); } /* ** Right now the record appears with the alias ** (first line) as the header and the rest as ** <pre> text. ** It might look better with the name as the ** header and the rest as a <ul> with <li> tags. ** I'm not sure whether the name field comes in ** any special order or if its even required in ** a record, so for now the first line is the ** header no matter what it is (it's almost ** always the alias). ** A <dl> with the first line as the <DT> and ** the rest as some form of <DD> might good also? */ /* ** Print data. */ PUTS(second_colon+1); PUTC('\n'); if (*(second_colon-1) != last_char) /* end seperator */ { END(HTML_H2); START(HTML_PRE); } /* ** Save the char before the second colon ** for comparison on the next pass. */ last_char = *(second_colon-1) ; } /* end if second_colon */ } /* end if *p == '-' */ } /* if end of line */ } /* Loop over characters */ /* end the text block */ PUTC('\n'); END(HTML_PRE); PUTC('\n'); FREE_TARGET; return; /* all done */} /* end of procedure *//* Display a Gopher CSO ISINDEX cover page.** ========================================*/PRIVATE void display_cso ARGS2( CONST char *, arg, HTParentAnchor *, anAnchor){ CONST char * title; START(HTML_HEAD); PUTC('\n'); START(HTML_TITLE); if ((title = HTAnchor_title(anAnchor))) PUTS(title); else PUTS(GOPHER_CSO_INDEX); END(HTML_TITLE); PUTC('\n'); START(HTML_ISINDEX); PUTC('\n'); END(HTML_HEAD); PUTC('\n'); START(HTML_H1); if ((title = HTAnchor_title(anAnchor))) PUTS(title); else { PUTS(arg); PUTS(INDEX_SEGMENT); } END(HTML_H1); PUTS(GOPHER_CSO_INDEX_SUBTITLE); START(HTML_P); PUTS(GOPHER_CSO_SOLICIT_KEYWORDS); START(HTML_P); PUTS(SEGMENT_KEYWORDS_WILL); PUTS(SEGMENT_PERSONS_DB_NAME); if (!HTAnchor_title(anAnchor)) HTAnchor_setTitle(anAnchor, arg); FREE_TARGET; return;}/* Display a Gopher Index document.** ================================*/PRIVATE void display_index ARGS2( CONST char *, arg, HTParentAnchor *,anAnchor){ CONST char * title; START(HTML_HEAD); PUTC('\n'); PUTC('\n'); START(HTML_TITLE); if ((title = HTAnchor_title(anAnchor))) PUTS(title); else PUTS(GOPHER_INDEX_TITLE); END(HTML_TITLE); PUTC('\n'); START(HTML_ISINDEX); PUTC('\n'); END(HTML_HEAD); PUTC('\n'); START(HTML_H1); if ((title = HTAnchor_title(anAnchor))) PUTS(title); else { PUTS(arg); PUTS(INDEX_SEGMENT); } END(HTML_H1); PUTS(GOPHER_INDEX_SUBTITLE); START(HTML_P); PUTS(GOPHER_SOLICIT_KEYWORDS); if (!HTAnchor_title(anAnchor)) HTAnchor_setTitle(anAnchor, arg); FREE_TARGET; return;}/* De-escape a selector into a command.** ====================================**** The % hex escapes are converted. Otheriwse, the string is copied.*/PRIVATE void de_escape ARGS2(char *, command, CONST char *, selector){ CONST char * p = selector; char * q = command; if (command == NULL) outofmem(__FILE__, "HTLoadGopher"); while (*p) { /* Decode hex */ if (*p == HEX_ESCAPE) { char c; unsigned int b; p++; c = *p++; b = from_hex(c); c = *p++; if (!c) break; /* Odd number of chars! */ *q++ = (char) FROMASCII((b<<4) + from_hex(c)); } else { *q++ = *p++; /* Record */ } } *q++ = '\0'; /* Terminate command */}/* Free the CSOfields structures. - FM** ===================================*/PRIVATE void free_CSOfields NOPARAMS{ CSOfield_info *cur = CSOfields; CSOfield_info *prev; while (cur) { if (cur->name != cur->name_buf) FREE(cur->name); if (cur->attributes != cur->attr_buf) FREE(cur->attributes); if (cur->description != cur->desc_buf) FREE(cur->description); prev = cur; cur = cur->next; FREE(prev); } return;}/* Interpret CSO/PH form template keys. - FM** =========================================*/PRIVATE void interpret_cso_key ARGS5( char *, key, char *, buf, int *, length, CSOformgen_context *, ctx, HTStream *, Target){ CSOfield_info *fld; if ((fld = ctx->fld) != 0) { /* ** Most substitutions only recognized inside of loops. */ int error = 0; if (0 == strncmp(key, "$(FID)", 6)) { sprintf(buf, "%d", fld->id); } else if (0 == strncmp(key, "$(FDESC)", 8)) { sprintf(buf, "%.2046s", fld->description); } else if (0 == strncmp(key, "$(FDEF)", 7)) { strcpy(buf, fld->defreturn ? " checked" : ""); } else if (0 == strncmp(key, "$(FNDX)", 7)) { strcpy(buf, fld->indexed ? "*" : ""); } else if (0 == strncmp(key, "$(FSIZE)", 8)) { sprintf(buf, " size=%d maxlength=%d", fld->max_size > 55 ? 55 : fld->max_size, fld->max_size); } else if (0 == strncmp(key, "$(FSIZE2)", 9)) { sprintf(buf, " maxlength=%d", fld->max_size); } else { error = 1; } if (!error) { *length = strlen(buf); return; } } buf[0] = '\0'; if (0 == strncmp(key, "$(NEXTFLD)", 10)) { if (!ctx->fld) fld = CSOfields; else fld = ctx->fld->next; switch (ctx->field_select) { case 0: /* ** 'Query' fields, public and lookup attributes. */ for (; fld; fld = fld->next) if (fld->public && (fld->lookup==1)) break; break; case 1: /* ** 'Query' fields, accept lookup attribute. */ for (; fld; fld = fld->next) if (fld->lookup == 1) break; break; case 2: /* ** 'Return' fields, public only. */ for (; fld; fld = fld->next) if (fld->public) break; break; case 3: /* ** All fields. */ break; } if (fld) { ctx->cur_line = ctx->rep_line; ctx->cur_off = ctx->rep_off; } ctx->fld = fld; } else if ((0 == strncmp(key, "$(QFIELDS)", 10)) || (0 == strncmp(key, "$(RFIELDS)", 10))) { /* ** Begin iteration sequence. */ ctx->rep_line = ctx->cur_line; ctx->rep_off = ctx->cur_off; ctx->fld = (CSOfield_info *) 0; ctx->seek = "$(NEXTFLD)"; ctx->field_select = (key[2] == 'Q') ? 0 : 2; if (ctx->public_override) ctx->field_select++; } else if (0 == strncmp(key, "$(NAMEFLD)", 10)) { /* ** Special, locate name field. Flag lookup so QFIELDS will skip it. */ for (fld = CSOfields; fld; fld = fld->next) if (strcmp(fld->name, "name") == 0 || strcmp(fld->name, "Name") == 0) { if (fld->lookup) fld->lookup = 2; break; } ctx->fld = fld; } else if (0 == strncmp (key, "$(HOST)", 7)) { strcpy (buf, ctx->host); } else if (0 == strncmp (key, "$(PORT)", 7)) { sprintf(buf, "%d", ctx->port); } else { /* ** No match, dump key to buffer so client sees it for debugging. */ size_t out = 0; while (*key && (*key != ')')) { buf[out++] = (*key++); if (out > sizeof(buf)-2) { buf[out] = '\0'; (*Target->isa->put_block)(Target, buf, strlen(buf)); out = 0; } } buf[out++] = ')'; buf[out] = '\0'; *length = strlen(buf); return; } *length = strlen(buf); return;}/* Parse the elements in a CSO/PH fields structure. - FM** =====================================================*/PRIVATE int parse_cso_field_info ARGS1( CSOfield_info *, blk){ char *info, *max_spec; /* ** Initialize all fields to default values. */ blk->indexed = blk->lookup = blk->reserved = blk->max_size = blk->url = 0; blk->defreturn = blk->explicit_return = blk->public = 0; /* ** Search for keywords in info string and set values. Attributes ** are converted to all lower-case for comparison. */ info = blk->attributes; LYLowerCase(info); if (strstr(info, "indexed ")) blk->indexed = 1; if (strstr(info, "default ")) blk->defreturn = 1; if (strstr(info, "public ")) blk->public = 1; if (strstr(info, "lookup ")) blk->lookup = 1; if (strstr(info, "url ")) { blk->url = 1; blk->defreturn = 1; } max_spec = strstr(info, "max "); if (max_spec) { sscanf(&max_spec[4], "%d", &blk->max_size); } else { blk->max_size = 32; } return 0;}/* Parse a reply from a CSO/PH fields request. - FM** ================================================*/PRIVATE int parse_cso_fields ARGS2( char *, buf, int, size){ int ich; char *p = buf; int i, code = 0, prev_code; size_t alen; char *indx, *name; CSOfield_info *last, *new; last = CSOfields = (CSOfield_info *) 0; prev_code = -2555; buf[0] = '\0'; /* ** Start grabbing chars from the network. */ while ((ich = NEXT_CHAR) != EOF) { if (interrupted_in_htgetcharacter) { CTRACE((tfp, "HTLoadCSO: Interrupted in HTGetCharacter, apparently.\n")); free_CSOfields(); buf[0] = '\0'; return HT_INTERRUPTED; } if ((char)ich != LF) { *p = (char) ich; /* Put character in buffer */ if (p < &buf[size-1]) { p++; } } else { *p = '\0'; /* Terminate line */ p = buf; /* Scan it to parse it */ /* OK we now have a line in 'p' lets parse it. */ /* ** Break on line that begins with a 2. ** It's the end of data. */ if (*p == '2') break; /* ** Lines beginning with 5 are errors. ** Print them and quit. */ if (*p == '5') {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -