home *** CD-ROM | disk | FTP | other *** search
- /* $Id: head.c,v 4.4.4.1 1992/02/23 21:25:39 sob PATCH_4 sob $
- *
- * $Log: head.c,v $
- * Revision 4.4.4.1 1992/02/23 21:25:39 sob
- * Patch level 4
- *
- * Revision 4.4.3.1 1992/02/01 03:09:32 sob
- * Release 4.4 Patchlevel 3
- *
- * Revision 4.4 1991/09/09 20:18:23 sob
- * release 4.4
- *
- *
- *
- */
- /* This software is Copyright 1991 by Stan Barber.
- *
- * Permission is hereby granted to copy, reproduce, redistribute or otherwise
- * use this software as long as: there is no monetary profit gained
- * specifically from the use or reproduction of this software, it is not
- * sold, rented, traded or otherwise marketed, and this copyright notice is
- * included prominently in any copy made.
- *
- * The author make no claims as to the fitness or correctness of this software
- * for any use whatsoever, and it is provided as is. Any use of this software
- * is at the user's own risk.
- */
-
- #include "EXTERN.h"
- #include "common.h"
- #include "artio.h"
- #include "bits.h"
- #ifdef SERVER
- #include "server.h"
- #endif
- #include "util.h"
- #include "INTERN.h"
- #include "head.h"
-
- bool first_one; /* is this the 1st occurance of this header line? */
-
- static char htypeix[26] =
- {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
-
- void
- head_init()
- {
- register int i;
-
- for (i=HEAD_FIRST+1; i<HEAD_LAST; i++)
- htypeix[*htype[i].ht_name - 'a'] = i;
- }
-
- #ifdef DEBUGGING
- void
- dumpheader(where)
- char *where;
- {
- register int i;
-
- printf("header: %d %s", parsed_art, where);
-
- for (i=0; i<HEAD_LAST; i++) {
- printf("%15s %4d %4d %03o\n",htype[i].ht_name,
- htype[i].ht_minpos,
- htype[i].ht_maxpos,
- htype[i].ht_flags) ; FLUSH;
- }
- }
- #endif
-
- int
- set_line_type(bufptr,colon)
- char *bufptr;
- register char *colon;
- {
- char lc[LONGKEY+3];
- register char *t, *f;
- register int i, len;
-
- if (colon-bufptr > LONGKEY+2)
- return SOME_LINE;
-
- for (t=lc,f=bufptr; f<colon; f++, t++) {
- if (isspace(*f))
- /* guard against space before : */
- break;
- *t = isupper(*f) ? tolower(*f) : *f;
- }
- *t = '\0';
- f = lc; /* get lc into register */
- len = t - f;
-
- /* now scan the headtype table, backwards so we don't have to supply an
- * extra terminating value, using first letter as index, and length as
- * optimization to avoid calling subroutine strEQ unnecessarily. Hauls.
- */
-
- if (islower(*f)) {
- for (i = htypeix[*f - 'a']; *htype[i].ht_name == *f; --i) {
- if (len == htype[i].ht_length && strEQ(f, htype[i].ht_name)) {
- return i;
- }
- }
- }
- return SOME_LINE;
- }
-
- void
- start_header(artnum)
- ART_NUM artnum;
- {
- register int i;
-
- #ifdef DEBUGGING
- if (debug & 4)
- dumpheader("start_header\n");
- #endif
- for (i=0; i<HEAD_LAST; i++) {
- htype[i].ht_minpos = -1;
- htype[i].ht_maxpos = 0;
- }
- in_header = SOME_LINE;
- first_one = FALSE;
- #ifdef ASYNC_PARSE
- parsed_art = artnum;
- #endif
- }
-
- bool
- parseline(art_buf,newhide,oldhide)
- char *art_buf;
- int newhide, oldhide;
- {
- if (*art_buf == ' ' || *art_buf == '\t')
- /* header continuation line? */
- return oldhide;
- else { /* maybe another header line */
- char *s;
-
- if (first_one) { /* did we just pass 1st occurance? */
- first_one = FALSE;
- htype[in_header].ht_maxpos = artpos;
- /* remember where line left off */
- }
- s = index(art_buf,':');
- if (s == Nullch) {
- /* is it the end of the header? */
- htype[PAST_HEADER].ht_minpos =
- (*art_buf == '\n') ? ftell(artfp) : artpos;
- /* remember where body starts */
- in_header = PAST_HEADER;
- }
- else { /* it is a new header line */
- in_header = set_line_type(art_buf,s);
- first_one = (htype[in_header].ht_minpos < 0);
- if (first_one)
- htype[in_header].ht_minpos = artpos;
- #ifdef DEBUGGING
- if (debug & 4)
- dumpheader(art_buf);
- #endif
- if (htype[in_header].ht_flags & HT_HIDE)
- return newhide;
- }
- }
- return FALSE; /* don't hide this line */
- }
-
- #ifdef ASYNC_PARSE
- int
- parse_maybe(artnum)
- ART_NUM artnum;
- {
- char tmpbuf[LBUFLEN];
-
- if (parsed_art == artnum)
- return 0;
- if (artnum > lastart)
- return -1;
- /* no maybe about it now */
- #ifdef SERVER
- if (nntpopen(artnum,GET_HEADER) == Nullfp) {
- #else
- if (artopen(artnum) == Nullfp) {
- #endif
- return -1;
- }
- start_header(artnum);
- while (in_header) {
- artpos = ftell(artfp);
- if (fgets(tmpbuf,LBUFLEN,artfp) == Nullch)
- break;
- parseline(tmpbuf,FALSE,FALSE);
- }
- in_header = PAST_HEADER;
- return 0;
- }
- #endif
-
- /* get the subject line for an article */
-
- char *
- fetchsubj(artnum,current_subject,copy)
- ART_NUM artnum; /* article to get subject from */
- bool_int current_subject; /* is it in a parsed header? */
- bool_int copy; /* do you want it savestr()ed? */
- {
- char *s = Nullch, *t;
- int counter; /*** OS2: License to kill CTRL-M ... */
- #ifdef SERVER
- static int xhdr = 1; /* Can we use xhdr command? */
- int eoo; /* End of server output */
- #endif /* SERVER */
-
- #ifdef CACHESUBJ
- if (!subj_list) {
- register ART_NUM i;
-
-
- #ifndef lint
- subj_list =
- (char**)safemalloc((MEM_SIZE)((OFFSET(lastart)+2)*sizeof(char *)));
- #endif /* lint */
- for (i=0; i<=OFFSET(lastart); i++)
- subj_list[i] = Nullch;
- }
- if (artnum < absfirst || artnum > lastart)
- s = nullstr;
- else
- s = subj_list[OFFSET(artnum)];
- #endif
- if (s == Nullch) {
- if (current_subject) {
- s = fetchlines(artnum,SUBJ_LINE);
- #ifdef CACHESUBJ
- subj_list[OFFSET(artnum)] = s;
- #endif
- }
- else {
- s = safemalloc((MEM_SIZE)LBUFLEN);
- *s = '\0';
- #ifdef SERVER
- if (xhdr) {
- sprintf(ser_line, "XHDR subject %ld", artnum);
- put_server(ser_line);
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf(">%s\n", ser_line) ; FLUSH;
- #endif
- if (nntp_get(ser_line, sizeof (ser_line)) >= 0) {
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf("<%s\n", ser_line) ; FLUSH;
- #endif
- if (ser_line[0] == CHAR_FATAL) {
- fprintf(stderr,"\nrrn: %s\n",ser_line);
- finalize(1);
- /* xhdr = 0; */
- } else {
- while (nntp_get(ser_line, sizeof (ser_line)) >= 0) {
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf("<%s\n", ser_line) ; FLUSH;
- #endif
- if (ser_line[0] == '.')
- break;
- else {
- t = index(ser_line, ' ');
- if (t++) {
- strcpy(s, t);
- if (t = index(s, '\r'))
- *t = '\0';
- }
- }
- }
- }
- } else {
- fprintf(stderr,
- "\nrrn: Unexpected close of server socket.\n");
- finalize(1);
- }
- }
-
- if (!xhdr) {
- sprintf(ser_line, "HEAD %ld", artnum);
- put_server(ser_line);
- #ifdef DEBUGGING
- if (debug & DEB_NNTP)
- printf(">%s\n", ser_line) ; FLUSH;
- #endif
- eoo = 0;
- if (nntp_get(ser_line, sizeof (ser_line)) >= 0 &&
- ser_line[0] == CHAR_OK) {
- do {
- if (nntp_get(s, LBUFLEN) < 0 || (*s == '.')) {
- strcpy(s, "Title: \n");
- eoo = 1;
- }
- } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
-
- if (!eoo)
- while (nntp_get(ser_line, sizeof (ser_line)) >= 0 &&
- ser_line[0] != '.');
- t = index(s,':')+1;
- while (*t == ' ') t++;
- strcpy(s, t);
- }
- }
- #else /* not SERVER */
- if (artopen(artnum) != Nullfp) {
- do {
- if (fgets(s,LBUFLEN,artfp) == Nullch)
- strcpy(s, "Title: \n");
- } while (strnNE(s,"Title:",6) && strnNE(s,"Subject:",8));
-
- /*** OS2: We need another CTRL-M-Killer. Please fix, when fseek works
- fine with text files ***/
-
- for (counter = 0; counter <= strlen(s); counter++)
- if ((s[counter] == '\r') &&
- (s[counter+1] == '\n')) {
- for (; s[counter] != '\0'; counter++)
- s[counter] = s[counter+1];
- }
-
- s[strlen(s)-1] = '\0';
- t = index(s,':')+1;
- while (*t == ' ') t++;
- strcpy(s, t);
- }
- #endif
- s = saferealloc(s, (MEM_SIZE)strlen(s)+1);
- #ifdef CACHESUBJ
- subj_list[OFFSET(artnum)] = s;
- #endif
- }
- }
- #ifdef CACHESUBJ
- if (copy) {
- t = savestr(s);
- return t;
- }
- else
- return s;
- #else
- if (copy)
- return s;
- else {
- safecpy(cmd_buf,s,CBUFLEN); /* hope this is okay--we're */
- free(s);
- return cmd_buf; /* really scraping for space here */
- }
- #endif
- }
-
- /* get header lines from an article */
-
- char *
- fetchlines(artnum,which_line)
- ART_NUM artnum; /* article to get line from */
- int which_line; /* type of line desired */
- {
- char *newbuf, *t, tmp_buf[LBUFLEN];
- register ART_POS curpos;
- int size;
- register ART_POS firstpos;
- register ART_POS lastpos;
-
- int counter; /*** OS2: License to kill CTRL-M ... */
-
- #ifdef ASYNC_PARSE
- if (parse_maybe(artnum))
- artnum = 0;
- #endif
- firstpos = htype[which_line].ht_minpos;
- lastpos = htype[which_line].ht_maxpos;
- #ifdef SERVER
- if (!artnum || firstpos < 0 || nntpopen(artnum,GET_HEADER) == Nullfp) {
- #else
- if (!artnum || firstpos < 0 || artopen(artnum) == Nullfp) {
- #endif
- newbuf = safemalloc((unsigned int)1);
- *newbuf = '\0';
- return newbuf;
- }
- #ifndef lint
- size = lastpos - firstpos + 1;
- #else
- size = Null(int);
- #endif /* lint */
- #ifdef DEBUGGING
- if (debug && (size < 1 || size > 1000)) {
- printf("Firstpos = %ld, lastpos = %ld\n",(long)firstpos,(long)lastpos);
- gets(tmp_buf);
- }
- #endif
- newbuf = safemalloc((unsigned int)size);
- *newbuf = '\0';
- fseek(artfp,firstpos,0);
- for (curpos = firstpos; curpos < lastpos; curpos = ftell(artfp)) {
- if (fgets(tmp_buf,LBUFLEN,artfp) == Nullch)
- break;
-
- /*** OS2: We need another CTRL-M-Killer. Please fix, when fseek works
- fine with text files ***/
-
- for (counter = 0; counter <= strlen(tmp_buf); counter++)
- if ((tmp_buf[counter] == '\r') &&
- (tmp_buf[counter+1] == '\n')) {
- for (; tmp_buf[counter] != '\0'; counter++)
- tmp_buf[counter] = tmp_buf[counter+1];
- }
-
- if (*tmp_buf == ' ' || *tmp_buf == '\t')
- t = tmp_buf;
- else {
- t = index(tmp_buf,':');
- if (t == Nullch)
- break;
- t++;
- }
- while (*t == ' ' || *t == '\t') t++;
- safecat(newbuf,t,size);
- }
- return newbuf;
- }
-
-