This is news.c in view mode; [Download] [Up]
/* * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved. * * Article header parsing. */ #include "config.h" #include "news.h" export int retry_on_error = 0; char *parse_header(f, hdr_field, modes, hdrbuf) FILE *f; char **(*hdr_field)(); int modes; news_header_buffer hdrbuf; { register char *bp, *cp, **fptr; int siz, all, date_only; off_t pos; pos = ftell(f); /* read first NEWS_HEADER_BUFFER bytes (should be more than enough) */ all = modes & GET_ALL_FIELDS; date_only = modes & GET_DATE_ONLY; siz = fread(hdrbuf, sizeof(char), NEWS_HEADER_BUFFER, f); if (siz <= 0) { hdrbuf[0] = NUL; return hdrbuf; } bp = hdrbuf; bp[siz-1] = NUL; /* decode subarticle header */ while (*bp) { if (*bp == NL) { /* empty line following header */ ++bp; fseek(f, pos + (bp - hdrbuf), 0); return bp; } if (*bp == SP) { /* for comp.ai.neural-nets digests */ bp++; /* which have <NL><space><NL> after header */ continue; } if (date_only && *bp != 'D') fptr = NULL; else if (fptr = (*hdr_field)(bp, all)) { while (*bp && *bp != ':' && isascii(*bp) && !isspace(*bp)) bp++; if (*bp) bp++; while (*bp && isascii(*bp) && isspace(*bp) && *bp != NL) bp++; *fptr = bp; } #ifdef NO_HEADER_SEPARATION_HACK else { for (cp = bp; *cp && *cp != ':'; cp++) { if (!isascii(*cp)) break; if (*cp == '_' || *cp == '-') continue; if (isalnum(*cp)) continue; break; } if (*cp != ':') { *bp = NL; pos--; continue; } } #endif while (*bp && *bp != NL) bp++; /* Assume that continued lines are never empty! */ if (fptr && bp == *fptr) *fptr = NULL; while (*bp) { /* look for continued lines */ cp = bp + 1; while (*cp && isascii(*cp) && isspace(*cp) && *cp != NL) cp++; if (cp == bp + 1) { /* next line is empty or not indented */ *bp++ = NUL; break; } if (*cp == NUL || *cp == NL) { /* next line is not empty, but blank line */ *bp = NUL; bp = cp; /* assume end of header */ break; } *bp = SP; /* substitute NL with SPACE */ bp = cp; while (*bp && *bp != NL) bp++; } } return bp; } static char **art_hdr_field(lp, all) register char *lp; int all; { #define check(name, lgt, field) \ if (isascii(lp[lgt]) && isspace(lp[lgt]) && strncmp(name, lp, lgt) == 0)\ return &news.field switch (*lp++) { case 'A': case 'a': if (!all) break; check("pproved:", 8, ng_appr); break; case 'B': case 'b': check("ack-References:", 15, ng_bref); break; case 'C': case 'c': check("ontrol:", 7, ng_control); break; case 'D': case 'd': check("ate:", 4, ng_date); if (!all) break; check("ate-Received:", 13, ng_rdate); check("istribution:", 12, ng_dist); break; case 'F': case 'f': check("rom:", 4, ng_from); if (!all) break; check("ollowup-To:", 11, ng_follow); check("ollowup-to:", 11, ng_follow); break; case 'K': case 'k': if (!all) break; check("eywords:", 8, ng_keyw); break; case 'L': case 'l': check("ines:", 5, ng_xlines); break; case 'M': case 'm': if (!all) break; if (strncmp(lp, "essage-", 7)) break; lp += 7; check("ID:", 3, ng_ident); check("Id:", 3, ng_ident); check("id:", 3, ng_ident); break; case 'N': case 'n': check("ewsgroups:", 10, ng_groups); break; case 'O': case 'o': if (!all) break; check("rganization:", 12, ng_org); check("rganisation:", 12, ng_org); break; case 'P': case 'p': if (!all) break; check("ath:", 4, ng_path); break; case 'R': case 'r': check("eferences:", 10, ng_ref); check("eply-To:", 8, ng_reply); check("eply-to:", 8, ng_reply); break; case 'S': case 's': check("ubject:", 7, ng_subj); check("ender:", 6, ng_sender); if (!all) break; check("ummary:", 7, ng_summ); break; case 'T': case 't': check("itle:", 5, ng_subj); break; } return NULL; #undef check } is_header_line(line) char *line; { return art_hdr_field(line, 0) != (char **)NULL; } FILE *open_news_article(art, modes, buffer1, buffer2) article_header *art; int modes; news_header_buffer buffer1, buffer2; { char *body; char *digest_buffer; char *parse_header(); struct stat statb; int retry; FILE *f; #ifdef NNTP int lazy; FILE *nntp_get_article(); #endif /* NNTP */ if (art->flag & A_FOLDER) { f = open_file(group_path_name, OPEN_READ); if (f == NULL) return NULL; fseek(f, art->hpos, 0); #ifdef NNTP } else if (use_nntp) { lazy = (current_group->master_flag & M_ALWAYS_DIGEST) == 0 && (modes & LAZY_BODY) ? 1 : 0; f = nntp_get_article(art->a_number, lazy); if (f == NULL) return NULL; #endif /* NNTP */ } else { sprintf(group_file_name, "%d", art->a_number); retry = retry_on_error; while ((f = open_file(group_path_name, OPEN_READ)) == NULL) if (--retry < 0) return NULL; /* necessary because empty files wreak havoc */ if (fstat(fileno(f), &statb) < 0 || statb.st_size < art->lpos || statb.st_size <= (off_t)0) { fclose(f); return who_am_i == I_AM_MASTER ? (FILE *)1 : NULL; } } digest_buffer = buffer1; if (modes & FILL_NEWS_HEADER) { news.ng_from = NULL; news.ng_reply = NULL; news.ng_name = NULL; news.ng_subj = NULL; news.ng_groups = NULL; news.ng_ref = NULL; news.ng_bref = NULL; news.ng_sender = NULL; news.ng_xlines = NULL; if (modes & GET_ALL_FIELDS) { news.ng_path = NULL; news.ng_reply = NULL; news.ng_ident = NULL; news.ng_follow = NULL; news.ng_keyw = NULL; news.ng_dist = NULL; news.ng_org = NULL; news.ng_appr = NULL; news.ng_summ = NULL; news.ng_control = NULL; news.ng_date = NULL; news.ng_rdate = NULL; } if (modes & GET_DATE_ONLY) news.ng_date = NULL; body = parse_header(f, art_hdr_field, modes, buffer1); news.ng_lines = news.ng_xlines ? atoi(news.ng_xlines) : -1; if (news.ng_from == NULL) news.ng_from = news.ng_sender; if (modes & FILL_OFFSETS) { art->fpos = news.ng_fpos = ftell(f); fseek(f, (off_t)0, 2); news.ng_lpos = ftell(f); } #ifdef NNTP else if (use_nntp && (art->flag & (A_DIGEST | A_FOLDER)) == 0) { fseek(f, (off_t)0, 2); art->lpos = ftell(f); } #endif news.ng_flag = 0; if (news.ng_appr) news.ng_flag |= N_MODERATED; if (modes & DIGEST_CHECK && is_digest()) news.ng_flag |= N_DIGEST; #ifdef NNTP if (use_nntp && lazy && news.ng_flag & N_DIGEST) { fclose(f); f = nntp_get_article(art->a_number, 2); if (f == NULL) return NULL; } #endif digest_buffer = buffer2; } #ifdef NNTP else if (use_nntp && (art->flag & (A_DIGEST | A_FOLDER)) == 0) { fseek(f, (off_t)0, 2); art->lpos = ftell(f); } #endif if (modes & FILL_DIGEST_HEADER) { fseek(f, art->hpos, 0); parse_digest_header(f, modes & GET_ALL_FIELDS, digest_buffer); } fseek(f, (modes & SKIP_HEADER) ? art->fpos : art->hpos, 0); return f; }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.