Article 2696 of comp.sources.unix: Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!bloom-beacon.mit.edu!news.kei.com!news.mathworks.com!newsfeed.internetmci.com!in1.uu.net!news1.digital.com!vixie!vixie!not-for-mail From: davison@borland.com (Wayne Davison) Newsgroups: comp.sources.unix Subject: v29i038: trn-3.6 - threaded newsreader based on RN, V3.6, Part01/14 Date: 29 Oct 1995 01:32:41 -0800 Organization: Vixie Enterprises Lines: 3209 Sender: vixie@vix.com Approved: vixie@gw.home.vix.com Message-ID: <1.814959141.29825@gw.home.vix.com> NNTP-Posting-Host: gw.home.vix.com Submitted-By: davison@borland.com (Wayne Davison) Posting-Number: Volume 29, Issue 38 Archive-Name: trn-3.6/part01 #!/bin/sh # This is a shell archive (produced by GNU sharutils 4.1). # To extract the files from this archive, save it to some FILE, remove # everything before the `!/bin/sh' line above, then type `sh FILE'. # # Made on 1995-10-29 01:27 PST by . # Source directory was `/tmp_mnt/fs/a3/CSU/New'. # # Existing files will *not* be overwritten unless `-c' is specified. # # This is part 1 of a multipart archive. # Do not concatenate these parts, unpack them in order with `/bin/sh'. # touch -am 1231235999 $$.touch >/dev/null 2>&1 if test ! -f 1231235999 && test -f $$.touch; then shar_touch=touch else shar_touch=: echo echo 'WARNING: not restoring timestamps. Consider getting and' echo "installing GNU \`touch', distributed in GNU File Utilities..." echo fi rm -f 1231235999 $$.touch # if test -r _sharseq.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _sharseq.tmp` next exit 1 fi # ============= trn-3.6/EXTERN.h ============== if test ! -d 'trn-3.6'; then echo 'x - creating directory trn-3.6' mkdir 'trn-3.6' fi if test -f 'trn-3.6/EXTERN.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/EXTERN.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/EXTERN.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/EXTERN.h' && X/* $Id: EXTERN.h,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#undef EXT X#define EXT extern X X#undef INIT X#define INIT(x) X X#undef DOINIT SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/EXTERN.h' && chmod 0644 'trn-3.6/EXTERN.h' || echo 'restore of trn-3.6/EXTERN.h failed' shar_count="`wc -c < 'trn-3.6/EXTERN.h'`" test 725 -eq "$shar_count" || echo "trn-3.6/EXTERN.h: original size 725, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/INTERN.h ============== if test -f 'trn-3.6/INTERN.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/INTERN.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/INTERN.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/INTERN.h' && X/* $Id: INTERN.h,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#undef EXT X#define EXT X X#undef INIT X#ifdef xenix X#define INIT(x) =x X#else X#define INIT(x) = x X#endif X X#define DOINIT SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/INTERN.h' && chmod 0644 'trn-3.6/INTERN.h' || echo 'restore of trn-3.6/INTERN.h failed' shar_count="`wc -c < 'trn-3.6/INTERN.h'`" test 768 -eq "$shar_count" || echo "trn-3.6/INTERN.h: original size 768, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/addng.c ============== if test -f 'trn-3.6/addng.c' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/addng.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/addng.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/addng.c' && X/* $Id: addng.c,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#include "EXTERN.h" X#include "common.h" X#include "trn.h" X#include "ngdata.h" X#include "last.h" X#include "util.h" X#include "intrp.h" X#include "only.h" X#include "rcstuff.h" X#include "nntp.h" X#include "final.h" X#include "INTERN.h" X#include "addng.h" X Xvoid Xaddng_init() X{ X ; X} X X#ifdef FINDNEWNG X/* generate a list of new newsgroups from active file */ X Xbool Xnewlist(munged,checkinlist) Xbool_int munged; /* are we scanning the whole file? */ Xbool_int checkinlist; X{ X char *tmpname; X register char *s, *status; X register NG_NUM ngnum; X X tmpname = filexp(RNEWNAME); X tmpfp = fopen(tmpname,"w+"); X if (tmpfp == Nullfp) { X printf(cantcreate,tmpname) FLUSH; X return FALSE; X } X UNLINK(tmpname); /* be nice to the world */ X X for (;;) { X#ifdef USE_NNTP X if (!actfp) { X if (NNTP_LIST_END(ser_line)) X break; X strcpy(buf, ser_line); X nntp_gets(ser_line, sizeof ser_line); X } X else X#endif X if (fgets(buf,LBUFLEN,actfp) == Nullch) X break; X /* Check if they want to break out of the new newsgroups search */ X if (int_count) { X int_count = 0; X fclose(tmpfp); X return FALSE; X } X if (s = index(buf,' ')) { X status=s; X while (isdigit(*status) || isspace(*status)) status++; X *s++ = '\0'; X if (strnEQ(buf,"to.",3) || *status == 'x' || *status == '=') X /* since = groups are refiling to another group, just X ignore their existence */ X continue; X#ifdef ACTIVE_TIMES X if (inlist(buf) && ((ngnum = find_ng(buf)) == nextrcline X || toread[ngnum] == TR_UNSUB) X#else X if (checkinlist ? X (inlist(buf) && ((ngnum = find_ng(buf)) == nextrcline X || toread[ngnum] == TR_UNSUB)) X : (find_ng(buf) == nextrcline X && birthof(buf,(ART_NUM)atol(s)) > lasttime) X#endif X ) { X /* if not in .newsrc and younger */ X /* than the last time we checked */ X fprintf(tmpfp,"%s\n",buf); X /* then remember said newsgroup */ X } X#ifdef FASTNEW X else { /* not really a new group */ X if (!munged) { /* did we assume not munged? */ X fclose(tmpfp); /* then go back, knowing that */ X return TRUE; /* active file was indeed munged */ X } X } X#endif X } X#ifdef DEBUG X else X printf("Bad active record: %s\n",buf) FLUSH; X#endif X } X X /* we have successfully generated the list */ X X fseek(tmpfp,0L,0); /* rewind back to the beginning */ X while (fgets(buf,LBUFLEN,tmpfp) != Nullch) { X buf[strlen(buf)-1] = '\0'; X get_ng(buf,GNG_RELOC); /* add newsgroup, maybe */ X } X fclose(tmpfp); /* be nice to ourselves */ X return FALSE; /* do not call us again */ X} X X#ifdef ACTIVE_TIMES X#ifdef USE_NNTP X Xbool Xfind_new_groups() X{ X char *tmpname; X register char *s; X time_t server_time; X NG_NUM oldnext = nextrcline; /* remember # lines in newsrc */ X X tmpname = filexp(RNEWNAME); X tmpfp = fopen(tmpname,"w+"); X if (tmpfp == Nullfp) { X printf(cantcreate,tmpname) FLUSH; X return FALSE; X } X UNLINK(tmpname); /* be nice to the world */ X X server_time = nntp_time(); X if (!nntp_newgroups(lastnewtime)) { X fclose(tmpfp); X printf("Can't get new groups from server:\n%s\n", ser_line); X return FALSE; X } X X while (1) { X nntp_gets(ser_line, sizeof ser_line); X#ifdef DEBUG X if (debug & DEB_NNTP) X printf("<%s\n", ser_line) FLUSH; X#endif X if (NNTP_LIST_END(ser_line)) X break; X if ((s = index(ser_line, ' ')) != Nullch) X *s++ = '\0'; X else if (findact(buf, ser_line, strlen(ser_line), 0L) >= 0) X s = buf + strlen(ser_line) + 1; X if (s) { X while (isdigit(*s) || isspace(*s)) s++; X if (*s == 'x' || *s == '=') X continue; X } X fprintf(tmpfp,"%s\n",ser_line); X } X X /* we have successfully generated the list */ X X if (ftell(tmpfp)) { X fputs("\nFinding new newsgroups:\n",stdout) FLUSH; X X fseek(tmpfp,0L,0); /* rewind back to the beginning */ X while (fgets(buf,LBUFLEN,tmpfp) != Nullch) { X buf[strlen(buf)-1] = '\0'; X get_ng(buf,0); /* add newsgroup, maybe */ X } X lastnewtime = server_time; /* remember when we found new groups */ X } /* (ends up back in .rnlast) */ X fclose(tmpfp); /* be nice to ourselves */ X X return oldnext != nextrcline; X} X#else /* !USE_NNTP */ X Xbool Xfind_new_groups() X{ X register char *s; X time_t lastone; X NG_NUM oldnext = nextrcline; /* remember # lines in newsrc */ X X fstat(fileno(actfp),&filestat); /* find active file size */ X lastactsiz = filestat.st_size; /* just to save it in .rnlast */ X X stat(ACTIVE_TIMES,&filestat); /* did active.times file grow? */ X if (filestat.st_size == lastnewsize) X return FALSE; X lastnewsize = filestat.st_size; X X fputs("\nChecking for new newsgroups...\n",stdout) FLUSH; X X s = filexp(ACTIVE_TIMES); X tmpfp = fopen(s,"r"); X if (tmpfp == Nullfp) { X printf(cantopen,s) FLUSH; X return FALSE; X } X lastone = time(Null(time_t*)) - 24L * 60 * 60 - 1; X while (fgets(buf,LBUFLEN,tmpfp) != Nullch) { X if ((s = index(buf, ' ')) != Nullch) X if ((lastone = atol(s+1)) >= lastnewtime) { X char tmpbuf[LBUFLEN]; X *s = '\0'; X if (findact(tmpbuf, buf, s - buf, 0L) >= 0) { X s = tmpbuf + (s-buf) + 1; X while (isdigit(*s) || isspace(*s)) s++; X if (*s != 'x' && *s != '=') { X get_ng(buf,0); /* add newsgroup, maybe */ X } X } X } X } X fclose(tmpfp); X lastnewtime = lastone+1; /* remember time of last new group */ X /* (ends up back in .rnlast) */ X return oldnext != nextrcline; X} X#endif /* !USE_NNTP */ X#else /* not ACTIVE_TIMES */ X Xbool Xfind_new_groups() X{ X long oldactsiz = lastactsiz; X NG_NUM oldnext = nextrcline; /* remember # lines in newsrc */ X X#ifdef USE_NNTP X if (!actfp) { X return 0; X } X#endif X X fstat(fileno(actfp),&filestat); /* did active file grow? */ X X if (filestat.st_size == lastactsiz) X return FALSE; X lastactsiz = filestat.st_size; /* remember new size */ X X#ifdef VERBOSE X IF(verbose) X fputs("\nChecking active file for new newsgroups...\n",stdout) FLUSH; X ELSE X#endif X#ifdef TERSE X fputs("\nNew newsgroups:\n",stdout) FLUSH; X#endif X X#ifdef FASTNEW /* bad soft ptrs -> edited active */ X if (!writesoft && oldactsiz) { /* maybe just do tail of file? */ X fseek(actfp,oldactsiz-NL_SIZE,0); X fgets(buf,LBUFLEN,actfp); X if (*buf == '\n' && !newlist(FALSE,FALSE)) X goto bugout; X } X#endif X fseek(actfp,0L,0); /* rewind active file */ X newlist(TRUE,FALSE); /* sure hope they use hashing... */ Xbugout: X return oldnext != nextrcline; X} X X/* return creation time of newsgroup */ X Xtime_t Xbirthof(ngnam,ngsize) Xchar *ngnam; XART_NUM ngsize; X{ X#ifdef USE_NNTP /* ngsize not used */ X long tot; X X if (!nntp_group(ngnam,-1)) X return 0; /* not a real group */ X (void) sscanf(ser_line,"%*d%ld",&tot); X if (tot > 0) X return time(Null(time_t*)); X return 0; X X#else /* !USE_NNTP */ X char tst[512]; X X sprintf(tst, ngsize ? "%s/%s/1" : "%s/%s" ,spool,getngdir(ngnam)); X if (stat(tst,&filestat) < 0) X return (ngsize ? 0L : time(Null(time_t*))); X /* not there, assume something good */ X return filestat.st_mtime; X X#endif /* !USE_NNTP */ X} X#endif /* ACTIVE_TIMES */ X Xbool Xscanactive() X{ X NG_NUM oldnext = nextrcline; /* remember # lines in newsrc */ X X if (actfp) { X fseek(actfp,0L,0); X newlist(TRUE,TRUE); X } X#ifdef USE_NNTP X else { X if (maxngtodo != 1) { X strcpy(buf, "*"); X } X else { X sprintf(buf,"*%s*", ngtodo[0]); X } X if (nntp_list("active", buf, strlen(buf)) == 1) { X newlist(TRUE,TRUE); X } X } X#endif X if (nextrcline != oldnext) { /* did we add any new groups? */ X return TRUE; X } X return FALSE; X} X X#endif /* FINDNEWNG */ X SHAR_EOF $shar_touch -am 1004153894 'trn-3.6/addng.c' && chmod 0644 'trn-3.6/addng.c' || echo 'restore of trn-3.6/addng.c failed' shar_count="`wc -c < 'trn-3.6/addng.c'`" test 8196 -eq "$shar_count" || echo "trn-3.6/addng.c: original size 8196, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/addng.h ============== if test -f 'trn-3.6/addng.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/addng.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/addng.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/addng.h' && X/* $Id: addng.h,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X Xvoid addng_init _((void)); X#ifdef FINDNEWNG Xbool newlist _((bool_int,bool_int)); X# ifdef ACTIVE_TIMES Xbool find_new_groups _((void)); X# else Xtime_t birthof _((char*,ART_NUM)); X# endif Xbool scanactive _((void)); X#endif SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/addng.h' && chmod 0644 'trn-3.6/addng.h' || echo 'restore of trn-3.6/addng.h failed' shar_count="`wc -c < 'trn-3.6/addng.h'`" test 868 -eq "$shar_count" || echo "trn-3.6/addng.h: original size 868, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/art.c ============== if test -f 'trn-3.6/art.c' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/art.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/art.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/art.c' && X/* $Id: art.c,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#include "EXTERN.h" X#include "common.h" X#include "trn.h" X#include "ngstuff.h" X#include "ngdata.h" X#include "cache.h" X#include "bits.h" X#include "head.h" X#include "help.h" X#include "search.h" X#include "artio.h" X#include "ng.h" X#include "final.h" X#include "artstate.h" X#include "rcstuff.h" X#include "term.h" X#include "sw.h" X#include "util.h" X#include "util2.h" X#include "nntp.h" X#include "backpage.h" X#include "intrp.h" X#include "rthread.h" X#include "rt-select.h" X#include "rt-util.h" X#include "rt-wumpus.h" X#include "charsubst.h" X#include "INTERN.h" X#include "art.h" X X/* page_switch() return values */ X X#define PS_NORM 0 X#define PS_ASK 1 X#define PS_RAISE 2 X#define PS_TOEND 3 X Xbool special = FALSE; /* is next page special length? */ Xint slines = 0; /* how long to make page when special */ Xchar *restart = Nullch; /* if nonzero, the place where last */ X /* line left off on line split */ Xchar *blinebeg; /* where in buffer current line began */ XART_POS alinebeg; /* where in file current line began */ X X#ifdef INNERSEARCH XART_LINE isrchline = 0; /* last line to display */ XCOMPEX gcompex; /* in article search pattern */ X#endif X Xbool firstpage; /* is this the 1st page of article? */ X Xchar art_buf[LBUFLEN]; /* place for article lines */ X Xvoid Xart_init() X{ X#ifdef INNERSEARCH X init_compex(&gcompex) X#endif X ; X} X X#ifdef MIMESHOW X#define VERY_LONG_STRING 200 Xint Xdisplay_mime() X{ X int code = 1; X X if (!getenv("NOMIME")) { X char oldmode = mode; X X fputs("Process MIME article? [yn]",stdout); X fflush(stdout); X eat_typeahead(); X#ifdef PENDING X cache_until_key(); X#endif X mode = 'p'; X getcmd(buf); X setdef(buf,"y"); X mode = oldmode; X#ifdef VERIFY X printcmd(); X#endif X carriage_return(); X erase_eol(); /* erase the prompt */ X carriage_return(); /* Resets kernel's tab column counter to 0 */ X if (*buf == 'y') { X putchar('\n'); X fflush(stdout); X#ifdef USE_NNTP X nntp_finishbody(FB_OUTPUT); X#endif X termlib_reset(); X resetty(); X interp(cmd_buf,(sizeof cmd_buf),getval("MIMESHOW",MIMESHOW)); X code = doshell(SH,cmd_buf); X noecho(); X crmode(); X termlib_init(); X } X } X return code; X} X#endif X X Xint Xdo_article() X{ X register char *s; X bool hide_this_line = FALSE; /* hidden header line? */ X ART_LINE linenum; /* line # on page, 1 origin */ X#ifdef ULSMARTS X bool under_lining = FALSE; /* are we underlining a word? */ X#endif X register char *bufptr = art_buf; /* pointer to input buffer */ X register int outpos; /* column position of output */ X static char prompt_buf[64]; /* place to hold prompt */ X bool notesfiles = FALSE; /* might there be notesfiles junk? */ X char oldmode = mode; X char *ctime(); X#ifdef MIMESHOW X bool tried_display_mime = FALSE; X#endif X#ifdef INNERSEARCH X register int outputok = TRUE; X#endif X X#if defined(MIMESHOW) || defined(MIMESTORE) X mime_article = FALSE; X#endif X X#ifndef USE_NNTP X if (fstat(fileno(artfp),&filestat)) /* get article file stats */ X return DA_CLEAN; X if (!S_ISREG(filestat.st_mode)) X return DA_NORM; X artsize = filestat.st_size; /* from that get article size */ X#endif X#ifdef CHARSUBST X sprintf(prompt_buf, X "%%sEnd of article %ld (of %ld) %%s-- what next? [%%s]", X (long)art,(long)lastart); /* format prompt string */ X#else X sprintf(prompt_buf, X "%%sEnd of article %ld (of %ld) -- what next? [%%s]", X (long)art,(long)lastart); /* format prompt string */ X#endif X prompt = prompt_buf; X int_count = 0; /* interrupt count is 0 */ X if ((firstpage = (topline < 0)) != 0) { X parseheader(art); X seekart(htype[PAST_HEADER].ht_minpos); X } X for (;;) { /* for each page */ X if (ThreadedGroup && max_tree_lines) X init_tree(); /* init tree display */ X assert(art == openart); X if (do_fseek) { X parseheader(art); /* make sure header is ours */ X artpos = vrdary(artline); X if (artpos < 0) X artpos = -artpos; /* labs(), anyone? */ X if (firstpage) X artpos = (ART_POS)0; X if (artpos < htype[PAST_HEADER].ht_minpos) { X in_header = SOME_LINE; X seekart(htype[PAST_HEADER].ht_minpos); X } else X seekart(artpos); X do_fseek = FALSE; X restart = Nullch; X } X linenum = 1; X if (firstpage) { X if (firstline) { X interp(art_buf, (sizeof art_buf), firstline); X linenum += tree_puts(art_buf,linenum+topline,0); X } else X { X ART_NUM i; X int selected, unseen; X X selected = (curr_artp->flags & AF_SEL); X unseen = !was_read(art); X sprintf(art_buf,"%s%s #%ld",ngname,moderated,(long)art); X if (selected_only) { X i = selected_count - (unseen && selected); X sprintf(art_buf+strlen(art_buf)," (%ld + %ld more)", X (long)i,(long)toread[ng] - selected_count X - (!selected && unseen)); X } X else if ((i = (ART_NUM)(toread[ng] - unseen)) != 0 X || (!ThreadedGroup && dmcount)) X sprintf(art_buf+strlen(art_buf)," (%ld more)",(long)i); X if (!ThreadedGroup && dmcount) X sprintf(art_buf+strlen(art_buf)-1," + %ld Marked to return)", X (long)dmcount); X linenum += tree_puts(art_buf,linenum+topline,0); X } X start_header(art); X forcelast = FALSE; /* we will have our day in court */ X restart = Nullch; X artline = 0; /* start counting lines */ X artpos = 0; X vwtary(artline,artpos); /* remember pos in file */ X } X for (; /* linenum already set */ X in_header || ( X#ifdef INNERSEARCH X innersearch ? innermore() : X#endif X linenum<(firstpage?initlines:(special?slines:LINES)) ); X linenum++) { /* for each line on page */ X if (int_count) { /* exit via interrupt? */ X putchar('\n') FLUSH; /* get to left margin */ X int_count = 0; /* reset interrupt count */ X mode = oldmode; X special = FALSE; X#ifdef USE_NNTP X nntp_finishbody(FB_OUTPUT); X#endif X return DA_NORM; /* skip out of loops */ X } X if (restart) { /* did not finish last line? */ X bufptr = restart; /* then start again here */ X restart = Nullch; /* and reset the flag */ X } X else if (in_header && headbuf[artpos] != '\0') { X bufptr = index(headbuf+artpos,'\n') + 1; X bcopy(headbuf+artpos,art_buf,bufptr-headbuf-artpos); X art_buf[bufptr-headbuf-artpos] = '\0'; X bufptr = art_buf; X } else { X if (readart(art_buf,LBUFLEN) == Nullch) { X break; X } X bufptr = art_buf; /* so start at beginning */ X art_buf[LBUFLEN-1] = '\0'; X /* make sure string ends */ X } X blinebeg = bufptr; /* remember where we began */ X alinebeg = artpos; /* both in buffer and file */ X if (in_header && bufptr == art_buf) { X hide_this_line = X parseline(art_buf,do_hiding,hide_this_line); X if (!in_header) { X linenum += finish_tree(linenum+topline); X end_header(); X } X } else if (notesfiles && do_hiding && X bufptr == art_buf && *art_buf == '#' && X isupper(art_buf[1]) && art_buf[2] == ':' ) { X readart(art_buf,sizeof(art_buf)); X if (index(art_buf,'!') != Nullch) X readart(art_buf,sizeof(art_buf)); X htype[PAST_HEADER].ht_minpos = tellart(); X /* exclude notesfiles droppings */ X hide_this_line = TRUE; /* and do not print either */ X notesfiles = FALSE; X } X#ifdef CUSTOMLINES X if (hideline && bufptr == art_buf && X execute(&hide_compex,art_buf) ) X hide_this_line = TRUE; X#endif X if (in_header && htype[in_header].ht_flags & HT_MAGIC) { X if (in_header == NGS_LINE) { X if ((s = index(art_buf,'\n')) != Nullch) X *s = '\0'; X hide_this_line = (index(art_buf,',') == Nullch) X && strEQ(art_buf+12, ngname); X if (s != Nullch) X *s = '\n'; X } X else if (in_header == EXPIR_LINE) { X if (!(htype[EXPIR_LINE].ht_flags & HT_HIDE)) X hide_this_line = ((int)strlen(art_buf) < 10); X } X else if (in_header == FROM_LINE) { X if (do_hiding && (s = extract_name(art_buf+6)) != Nullch) X strcpy(art_buf+6,s); X } X#ifdef HAS_STRFTIME X else if (in_header == DATE_LINE) { X if (do_hiding && curr_artp->date != -1) X strftime(art_buf+6, sizeof(art_buf)-6, X getval("LOCALTIMEFMT", LOCALTIMEFMT), X localtime(&curr_artp->date)); X } X#endif X#if defined(MIMESHOW) || defined(MIMESTORE) X else if (!isspace(*art_buf)) { X int nontext _((char *)); X int nonprint _((char *)); X if (in_header == CONTENT_LINE) X mime_article = mime_article || nontext(art_buf+14); X else if (in_header == CONTXFER_LINE) X mime_article = mime_article || nonprint(art_buf+27); X } X#endif X } X if (in_header == SUBJ_LINE && X htype[SUBJ_LINE].ht_flags & HT_MAGIC) { X /* is this the subject? */ X int length; X X length = strlen(art_buf)-1; X artline++; X art_buf[length] = '\0'; /* wipe out newline */ X#ifdef NOFIREWORKS X no_ulfire(); X#endif X notesfiles = X (instr(&art_buf[length-10]," - (nf", TRUE) != Nullch); X /* tree_puts(, ,1) underlines subject */ X linenum += tree_puts(art_buf,linenum+topline,1)-1; X } X else if (hide_this_line && do_hiding) { X /* do not print line? */ X linenum--; /* compensate for linenum++ */ X if (!in_header) X hide_this_line = FALSE; X } X else if (in_header) { X artline++; X linenum += tree_puts(art_buf,linenum+topline,0)-1; X } X else { /* just a normal line */ X#ifdef MIMESHOW X if (mime_article && do_hiding && !tried_display_mime) { X if (display_mime() == 0) X return DA_NORM; X tried_display_mime = TRUE; X } X#endif X#ifdef CLEAREOL X#ifdef INNERSEARCH X if (outputok) X#endif X if (can_home_clear) erase_eol(); X#endif /* CLEAREOL */ X if (highlight==artline) { /* this line to be highlit? */ X if (marking == STANDOUT) { X#ifdef NOFIREWORKS X if (erase_screen) X no_sofire(); X#endif X standout(); X } X else { X#ifdef NOFIREWORKS X if (erase_screen) X no_ulfire(); X#endif X underline(); X } X if (*bufptr == '\n') X putchar(' '); X } X#ifdef INNERSEARCH X outputok = !hide_everything; X /* get it into register, hopefully */ X#endif X#ifdef CUSTOMLINES X if (pagestop && bufptr == art_buf && X execute(&page_compex,art_buf) ) X linenum = 32700; X#endif X for (outpos = 0; outpos < COLS; ) { X /* while line has room */ X if (*(unsigned char*)bufptr >= ' ') { /* normal char? */ X#ifdef ULSMARTS X if (*bufptr == '_') { X if (bufptr[1] == '\b') { X#ifdef INNERSEARCH X if (outputok) X#endif X if (!under_lining && highlight != artline) { X under_lining++; X if (UG) { X if (bufptr != buf && bufptr[-1]==' ') { X outpos--; X backspace(); X } X } X underline(); X } X bufptr += 2; X } X } X else { X if (under_lining) { X under_lining = 0; X un_underline(); X if (UG) { X outpos++; X if (*bufptr == ' ') X goto skip_put; X } X } X } X#endif X#ifdef ROTATION X if (rotate && !in_header && isalpha(*bufptr)) { X# ifdef INNERSEARCH X if (outputok) X# endif X if ((*bufptr & 31) <= 13) X putchar(*bufptr+13); X else X putchar(*bufptr-13); X outpos++; X } X else X#endif X { X#ifdef CHARSUBST X register int i; X# ifdef INNERSEARCH X i = putsubstchar(*bufptr, COLS - outpos, outputok); X# else X i = putsubstchar(*bufptr, COLS - outpos, TRUE); X# endif X if (i < 0) { X outpos += -i - 1; X break; X } X outpos += i; X#else X# ifdef INNERSEARCH X if (outputok) X# endif X putchar(*bufptr); X outpos++; X#endif /* CHARSUBST */ X } X if (*UC && ((highlight==artline && marking == STANDOUT) X#ifdef ULSMARTS X || under_lining X#endif X )) { X backspace(); X underchar(); X } X skip_put: X bufptr++; X } X else if (*bufptr == '\n' || !*bufptr) { X /* newline? */ X#ifdef ULSMARTS X if (under_lining) { X under_lining = 0; X un_underline(); X } X#endif X#ifdef DEBUG X if (debug & DEB_INNERSRCH && outpos < COLS - 6) { X standout(); X printf("%4d",artline); X un_standout(); X } X#endif X#ifdef INNERSEARCH X if (outputok) X#endif X putchar('\n') FLUSH; X restart = 0; X outpos = 1000; /* signal normal \n */ X } X else if (*bufptr == '\t') { /* tab? */ X int incpos = 8 - outpos % 8; X#ifdef INNERSEARCH X if (outputok) X#endif X if (GT) X putchar(*bufptr); X else X while (incpos--) putchar(' '); X bufptr++; X outpos += 8 - outpos % 8; X } X else if (*bufptr == '\f') { /* form feed? */ X if (outpos+2 > COLS) X break; X#ifdef INNERSEARCH X if (outputok) X#endif X fputs("^L",stdout); X if (bufptr == blinebeg && highlight != artline) X linenum = 32700; X /* how is that for a magic number? */ X bufptr++; X outpos += 2; X } X else { /* other control char */ X if (dont_filter_control) { X#ifdef INNERSEARCH X if (outputok) X#endif X putchar(*bufptr); X outpos++; X } X else if (*bufptr != '\r' || bufptr[1] != '\n') { X if (outpos+2 > COLS) X break; X#ifdef INNERSEARCH X if (outputok) X#endif X { X putchar('^'); X if (highlight == artline && *UC X && marking == STANDOUT) { X backspace(); X underchar(); X putchar(*bufptr+64); X backspace(); X underchar(); X } X else X putchar(*bufptr+64); X } X outpos += 2; X } X bufptr++; X } X X } /* end of column loop */ X X if (outpos < 1000) { /* did line overflow? */ X restart = bufptr; /* restart here next time */ X if (!AM || XN || outpos < COLS) { X#ifdef INNERSEARCH X if (outputok) X#endif X putchar('\n') FLUSH; X } X if (*bufptr == '\n') /* skip the newline */ X restart = 0; X } X X /* handle normal end of output line formalities */ X X if (highlight == artline) { X /* were we highlighting line? */ X if (marking == STANDOUT) X un_standout(); X else X un_underline(); X highlight = -1; /* no more we are */ X /* in case terminal highlighted rest of line earlier */ X /* when we did an eol with highlight turned on: */ X if (can_home_clear) erase_eol(); X } X artline++; /* count the line just printed */ X if (artline - LINES + 1 > topline) X /* did we just scroll top line off? */ X topline = artline - LINES + 1; X /* then recompute top line # */ X } X X /* determine actual position in file */ X X if (restart) /* stranded somewhere in the buffer? */ X artpos += restart - blinebeg; X /* just calculate position */ X else if (in_header) X artpos = index(headbuf+artpos, '\n') - headbuf + 1; X else /* no, ftell will do */ X artpos = tellart(); X vwtary(artline,artpos); /* remember pos in file */ X } /* end of line loop */ X X#ifdef INNERSEARCH X innersearch = 0; X if (hide_everything) { X *buf = hide_everything; X hide_everything = 0; X goto fake_command; X } X#endif X if (linenum >= 32700)/* did last line have formfeed? */ X vwtary(artline-1,-vrdary(artline-1)); X /* remember by negating pos in file */ X X special = FALSE; /* end of page, so reset page length */ X firstpage = FALSE; /* and say it is not 1st time thru */ X highlight = -1; X X /* extra loop bombout */ X X#ifdef USE_NNTP X artsize = nntp_artsize(); Xrecheck_pager: X#endif X if (artpos == artsize) {/* did we just now reach EOF? */ X mode = oldmode; X return DA_NORM; /* avoid --MORE--(100%) */ X } X X/* not done with this article, so pretend we are a pager */ X Xreask_pager: X unflush_output(); /* disable any ^O in effect */ X standout(); /* enter standout mode */ X#ifdef USE_NNTP X if (artsize == -1) X strcpy(buf,"?"); X else X#endif X sprintf(buf,"%ld",(long)(artpos*100/artsize)); X#ifdef CHARSUBST X printf("%s--MORE--(%s%%)",current_charsubst(),buf); X#else X printf("--MORE--(%s%%)",buf); X#endif X un_standout(); /* leave standout mode */ X#ifdef CLEAREOL X maybe_eol(); X#endif X fflush(stdout); X eat_typeahead(); X#ifdef DEBUG X if (debug & DEB_CHECKPOINTING) { X printf("(%d %d %d)",checkcount,linenum,artline); X fflush(stdout); X } X#endif X if (checkcount >= docheckwhen && X linenum == LINES && X (artline > 40 || checkcount >= docheckwhen+10) ) { X /* while he is reading a whole page */ X /* in an article he is interested in */ X checkcount = 0; X checkpoint_rc(); /* update .newsrc */ X } X cache_until_key(); X#ifdef USE_NNTP X if (artsize == -1 && (artsize = nntp_artsize()) != -1) { X carriage_return(); X goto recheck_pager; X } X#endif X mode = 'p'; X getcmd(buf); X if (errno) { X if (LINES < 100 && !int_count) X *buf = '\f';/* on CONT fake up refresh */ X else { X *buf = 'q'; /* on INTR or paper just quit */ X } X } X carriage_return(); X#ifdef CLEAREOL X if (erase_screen && can_home_clear) X clear_rest(); X else X#endif X erase_eol(); /* and erase the prompt */ X carriage_return(); /* Resets kernel's tab column counter to 0 */ X fflush(stdout); X X fake_command: /* used by innersearch */ X output_chase_phrase = TRUE; X X /* parse and process pager command */ X X switch (page_switch()) { X case PS_ASK: /* reprompt "--MORE--..." */ X goto reask_pager; X case PS_RAISE: /* reparse on article level */ X mode = oldmode; X return DA_RAISE; X case PS_TOEND: /* fast pager loop exit */ X mode = oldmode; X return DA_TOEND; X case PS_NORM: /* display more article */ X break; X } X } /* end of page loop */ X} X X/* process pager commands */ X Xint Xpage_switch() X{ X register char *s; X X switch (*buf) { X case '!': /* shell escape */ X escapade(); X return PS_ASK; X#ifdef INNERSEARCH X case Ctl('i'): { X ART_LINE i = artline; X ART_POS pos; X gline = 3; X s = blinebeg; X while (*s == '\n' && i >= topline) { X pos = vrdary(--i); X if (pos < 0) X pos = -pos; X if (pos < htype[PAST_HEADER].ht_minpos) X break; X seekart((long)pos); X if (readart(s = buf+1, sizeof buf - 1) == Nullch) { X s = blinebeg; X break; X } X } X sprintf(cmd_buf,"^[^%c\n]",*s); X compile(&gcompex,cmd_buf,TRUE,TRUE); X goto caseG; X } X case Ctl('g'): X gline = 3; X compile(&gcompex,"^Subject:",TRUE,TRUE); X goto caseG; X case 'g': /* in-article search */ X if (!finish_command(FALSE))/* get rest of command */ X return PS_ASK; X s = buf+1; X if (isspace(*s)) X s++; X if ((s = compile(&gcompex,s,TRUE,TRUE)) != Nullch) { X /* compile regular expression */ X printf("\n%s\n",s) FLUSH; X return PS_ASK; X } X carriage_return(); X erase_eol(); /* erase the prompt */ X carriage_return(); /* Resets kernel's tab column counter to 0 */ X /* FALL THROUGH */ X caseG: X case 'G': { X ART_POS start_where; X X if (gline < 0 || gline > LINES-2) X gline = LINES-2; X#ifdef DEBUG X if (debug & DEB_INNERSRCH) X printf("Start here? %d >=? %d\n",topline + gline + 1,artline) X FLUSH; X#endif X if (*buf == Ctl('i') || topline+gline+1 >= artline) X start_where = artpos; X /* in case we had a line wrap */ X else { X start_where = vrdary(topline+gline+1); X if (start_where < 0) X start_where = -start_where; X } X if (start_where < htype[PAST_HEADER].ht_minpos) X start_where = htype[PAST_HEADER].ht_minpos; X seekart((long)start_where); X innerlight = 0; X innersearch = 0; /* assume not found */ X while (readart(buf, sizeof buf) != Nullch) { X#ifdef DEBUG X if (debug & DEB_INNERSRCH) X printf("Test %s",buf) FLUSH; X#endif X if (execute(&gcompex,buf) != Nullch) { X innersearch = tellart(); X break; X } X } X if (!innersearch) { X seekart(artpos); X fputs("(Not found)",stdout) FLUSH; X return PS_ASK; X } X#ifdef DEBUG X if (debug & DEB_INNERSRCH) X printf("On page? %ld <=? %ld\n",(long)innersearch,(long)artpos) X FLUSH; X#endif X if (innersearch <= artpos) { /* already on page? */ X if (innersearch < artpos) { X artline = topline+1; X while (vrdary(artline) < innersearch) X artline++; X } X highlight = artline - 1; X#ifdef DEBUG X if (debug & DEB_INNERSRCH) X printf("@ %d\n",highlight) FLUSH; X#endif X topline = highlight - gline; X if (topline < -1) X topline = -1; X *buf = '\f'; /* fake up a refresh */ X innersearch = 0; X return page_switch(); X } X else { /* who knows how many lines it is? */ X do_fseek = TRUE; X hide_everything = Ctl('l'); X } X return PS_NORM; X } X#else X case 'g': case 'G': case Ctl('g'): X notincl("g"); X return PS_ASK; X#endif X case '\n': /* one line down */ X special = TRUE; X slines = 2; X return PS_NORM; X#ifdef ROTATION X case 'X': X rotate = !rotate; X /* FALL THROUGH */ X#endif X case 'l': X case '\f': /* refresh screen */ X refresh_screen: X#ifdef DEBUG X if (debug & DEB_INNERSRCH) { X printf("Topline = %d",topline) FLUSH; X fgets(buf, sizeof buf, stdin); X } X#endif X clear(); X carriage_return(); /* Resets kernel's tab column counter to 0 */ X do_fseek = TRUE; X artline = topline; X if (artline < 0) X artline = 0; X firstpage = (topline < 0); X return PS_NORM; X#ifdef INNERSEARCH X case Ctl('e'): X#ifdef USE_NNTP X nntp_finishbody(FB_OUTPUT); X artsize = nntp_artsize(); X#endif X innerlight = artline - 1; X innersearch = artsize; X gline = 0; X hide_everything = 'b'; X return PS_NORM; X#endif X case 'B': /* one line up */ X if (topline < 0) X break; X if (*IL && *HO) { X ART_POS pos; X home_cursor(); X insert_line(); X carriage_return(); /* Resets kernel's tab column counter to 0 */ X pos = vrdary(topline-1); X if (pos < 0) X pos = -pos; X if (pos >= htype[PAST_HEADER].ht_minpos) { X seekart((long)pos); X if (readart(s = buf, sizeof buf) != Nullch) { X fputs(buf, stdout) FLUSH; X topline--; X artpos = vrdary(--artline); X if (artpos < 0) X artpos = -artpos; X seekart(artpos); X goto_line(1, LINES-1); X erase_eol(); X carriage_return(); X return PS_ASK; X } X } X } X /* FALL THROUGH */ X case 'b': X case '\b': X case Ctl('b'): { /* back up a page */ X ART_LINE target; X X#ifdef CLEAREOL X if (can_home_clear) /* if we can let home do it */ X home_cursor(); X else X#endif X clear(); X carriage_return(); /* Resets kernel's tab column counter to 0 */ X X do_fseek = TRUE; /* reposition article file */ X if (*buf == 'B') X target = topline - 1; X else { X target = topline - (LINES - 2); X if (marking && (marking_areas & BACKPAGE_MARKING)) X highlight = topline; X } X artline = topline; X if (artline >= 0) do { X artline--; X } while(artline >= 0 && artline > target && vrdary(artline-1) >= 0); X topline = artline; X /* remember top line of screen */ X /* (line # within article file) */ X if (artline < 0) X artline = 0; X firstpage = (topline < 0); X return PS_NORM; X } X case 'h': { /* help */ X int cmd; X X if ((cmd = help_page()) > 0) X pushchar(cmd); X return PS_ASK; X } X case 't': /* output thread data */ X page_line = 1; X entire_tree(curr_artp); X return PS_ASK; X case '_': X if (!finish_dblchar()) X return PS_ASK; X switch (buf[1] & 0177) { X#ifdef CHARSUBST X case 'C': X if (!*(++charsubst)) X charsubst = charsets; X goto refresh_screen; X#endif X default: X goto leave_pager; X } X break; X case '\177': X case '\0': /* treat del,break as 'n' */ X *buf = 'n'; X /* FALL THROUGH */ X case 'k': case 'K': case 'J': X case 'n': case 'N': case Ctl('n'): X case 's': case 'S': X case 'e': X case 'u': X case 'w': case 'W': X case '|': X mark_as_read(); /* mark article as read */ X /* FALL THROUGH */ X case 'U': case ',': X case '<': case '>': X case '[': case ']': X case '{': case '}': X case '(': case ')': X case ':': X case '+': X case '#': X case '$': X case '&': X case '-': X case '.': X case '/': X case '1': case '2': case '3': case '4': case '5': X case '6': case '7': case '8': case '9': X case '=': X case '?': X case 'A': case 'T': X case 'c': case 'C': X#ifdef DEBUG X case 'D': X#endif X case 'E': X case 'f': case 'F': case Ctl('f'): X case 'j': X case Ctl('k'): X case 'm': case 'M': X case 'p': case 'P': case Ctl('p'): X case 'Q': X case 'r': case 'R': case Ctl('r'): X case 'v': X case 'Y': X#ifndef ROTATION X case 'x': case 'X': X#endif X case Ctl('x'): X case 'z': case 'Z': X case '^': case Ctl('^'): Xleave_pager: X#ifdef ROTATION X rotate = FALSE; X#endif X reread = FALSE; X do_hiding = TRUE; X#ifdef USE_NNTP X nntp_finishbody(FB_OUTPUT); X#endif X if (index("nNpP\016\020",*buf) == Nullch && X index("wWsSe:!&|/?123456789.",*buf) != Nullch) { X setdfltcmd(); X standout(); /* enter standout mode */ X interp(cmd_buf, sizeof cmd_buf, mailcall); X#ifdef CHARSUBST X printf(prompt,cmd_buf,current_charsubst(),dfltcmd); X#else X printf(prompt,cmd_buf,dfltcmd); X#endif X /* print prompt, whatever it is */ X un_standout(); /* leave standout mode */ X putchar(' '); X fflush(stdout); X } X return PS_RAISE; /* and pretend we were at end */ X#ifdef ROTATION X case 'x': X rotate = TRUE; X /* FALL THROUGH */ X#endif X case 'd': /* half page */ X case Ctl('d'): X special = TRUE; X slines = LINES / 2 + 1; X /* no divide-by-zero, thank you */ X if (LINES > 2 && (LINES & 1) && artline % (LINES-2) >= LINES/2 - 1) X slines++; X goto go_forward; X case 'y': X case Ctl('v'): /* Leaving it undocumented in case */ X /* I want to steal the key--LAW */ X case ' ': /* continue current article */ X if (erase_screen) { /* -e? */ X#ifdef CLEAREOL X if (can_home_clear) /* if we can let home do it */ X home_cursor(); X else X#endif X clear(); /* clear screen */ X carriage_return(); /* Resets kernel's tab column counter to 0 */ X fflush(stdout); X } X else { X special = TRUE; X slines = LINES; X } X go_forward: X if (*blinebeg != '\f' X#ifdef CUSTOMLINES X && (!pagestop || blinebeg != art_buf || X !execute(&page_compex,blinebeg)) X#endif X ) { X if (!special X || (marking && (*buf!='d' || (marking_areas&HALFPAGE_MARKING)))) { X restart = blinebeg; X artline--; /* restart this line */ X artpos = alinebeg; X if (special) X up_line(); X if (marking) X highlight = artline; X } X else X slines--; X } X return PS_NORM; X case 'q': /* quit this article? */ X do_hiding = TRUE; X#ifdef USE_NNTP X nntp_finishbody(FB_OUTPUT); X#endif X return PS_TOEND; X default: X fputs(hforhelp,stdout) FLUSH; X settle_down(); X return PS_ASK; X } X return PS_ASK; X} X X#ifdef INNERSEARCH Xbool Xinnermore() X{ X if (artpos < innersearch) { /* not even on page yet? */ X#ifdef DEBUG X if (debug & DEB_INNERSRCH) X printf("Not on page %ld < %ld\n",(long)artpos,(long)innersearch) X FLUSH; X#endif X return TRUE; X } X if (artpos == innersearch) { /* just got onto page? */ X isrchline = artline; /* remember first line after */ X if (innerlight) X highlight = innerlight; X else X highlight = artline - 1; X#ifdef DEBUG X if (debug & DEB_INNERSRCH) X printf("There it is %ld = %ld, %d @ %d\n",(long)artpos, X (long)innersearch,hide_everything,highlight) FLUSH; X#endif X if (hide_everything) { /* forced refresh? */ X topline = artline - gline - 1; X if (topline < -1) X topline = -1; X return FALSE; /* let refresh do it all */ X } X } X#ifdef DEBUG X if (debug & DEB_INNERSRCH) X printf("Not far enough? %d = s && isspace(*t)) X t--; X *++t = '\0'; X if (notplain(s)) X return 1; X return 0; X} X X/* return true if this isn't "text" or "text/plain" */ X Xint Xnotplain(s) Xchar *s; X{ X char *t; X if (!s) X return 1; X while (isspace(*s)) X s++; X t = s + strlen(s) - 1; X while (t >= s && isspace(*t)) X t--; X *++t = '\0'; X if (t - s == 4 && !strncasecmp(s, "text", 4)) X return 0; X if (strncasecmp(s, "text/plain", 10)) X return 1; X t = index(s, ';'); X while (t) { X t++; X while (isspace(*t)) X t++; X if (!strncasecmp(t, "charset", 7)) { X s = index(t, '='); X if (s) { X s++; X while (isspace(*s)) X s++; X if (!strncasecmp(s, "us-ascii", 8)) X return 0; X } X return 1; X } X t = index(t, ';'); X } X return 0; /* no charset, was text/plain */ X} X X/* return true if this isn't "7bit", "8bit", or "binary" */ X Xint Xnonprint(s) Xchar *s; X{ X while (isspace(*s)) X s++; X if (strncasecmp(s, "7bit", 4) == 0) X s += 4; X else if (strncasecmp(s, "8bit", 4) == 0) X s += 4; X else if (strncasecmp(s, "binary", 6) == 0) X s += 6; X else X return 1; X return !(*s == '\0' || isspace(*s) || *s == ';' || *s == '('); /*)*/ X} X#endif SHAR_EOF $shar_touch -am 1118220194 'trn-3.6/art.c' && chmod 0644 'trn-3.6/art.c' || echo 'restore of trn-3.6/art.c failed' shar_count="`wc -c < 'trn-3.6/art.c'`" test 28992 -eq "$shar_count" || echo "trn-3.6/art.c: original size 28992, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/art.h ============== if test -f 'trn-3.6/art.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/art.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/art.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/art.h' && X/* $Id: art.h,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X/* do_article() return values */ X X#define DA_NORM 0 X#define DA_RAISE 1 X#define DA_CLEAN 2 X#define DA_TOEND 3 X XEXT ART_LINE highlight INIT(-1);/* next line to be highlighted */ XEXT ART_POS artsize; /* size in bytes of article */ X X#ifdef INNERSEARCH XEXT ART_POS innersearch INIT(0); /* artpos of end of line we want to visit */ XEXT ART_LINE innerlight INIT(0); /* highlight position for innersearch or 0 */ XEXT char hide_everything INIT(0);/* if set, do not write page now, */ X#endif /* ...but execute char when done with page */ X Xvoid art_init _((void)); Xint do_article _((void)); Xint page_switch _((void)); Xbool innermore _((void)); SHAR_EOF $shar_touch -am 1007195794 'trn-3.6/art.h' && chmod 0644 'trn-3.6/art.h' || echo 'restore of trn-3.6/art.h failed' shar_count="`wc -c < 'trn-3.6/art.h'`" test 1286 -eq "$shar_count" || echo "trn-3.6/art.h: original size 1286, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/artio.c ============== if test -f 'trn-3.6/artio.c' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/artio.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/artio.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/artio.c' && X/* $Id: artio.c,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#include "EXTERN.h" X#include "common.h" X#include "cache.h" X#include "rthread.h" X#include "head.h" X#include "nntp.h" X#include "art.h" X#include "bits.h" X#include "final.h" X#include "ngdata.h" X#include "INTERN.h" X#include "artio.h" X Xvoid Xartio_init() X{ X ; X} X X/* open an article, unless it's already open */ X XFILE * Xartopen(artnum) XART_NUM artnum; X{ X#ifndef USE_NNTP X char artname[MAXFILENAME]; /* filename of current article */ X#endif X ARTICLE *ap = find_article(artnum); X X if (!ap || !artnum || (ap->flags & (AF_MISSING|AF_FAKE)) == AF_MISSING) { X errno = ENOENT; X return Nullfp; X } X if (openart == artnum) { /* this article is already open? */ X seekart(0L); /* just get to the beginning */ X return artfp; /* and say we succeeded */ X } X if (artfp != Nullfp) { /* it was somebody else? */ X fclose(artfp); /* put them out of their misery */ X openart = 0; /* and remember them no more */ X } Xretry_open: X#ifdef USE_NNTP X artfp = nntp_body(artnum); X#else X sprintf(artname,"%ld",(long)artnum); X artfp = fopen(artname,"r"); X#endif X if (!artfp) { X#ifdef ETIMEDOUT X if (errno == ETIMEDOUT) X goto retry_open; X#endif X if (errno == EINTR) X goto retry_open; X uncache_article(ap,FALSE); X } else { X#ifdef LINKART X char tmpbuf[256]; X char *s; X X if (!fstat(fileno(artfp),&filestat) X && filestat.st_size < sizeof tmpbuf) { X fgets(tmpbuf,sizeof tmpbuf,artfp); X if (*tmpbuf == '/') { /* is a "link" to another article */ X fclose(artfp); X if (s=index(tmpbuf,'\n')) X *s = '\0'; X if (!(artfp = fopen(tmpbuf,"r"))) { X uncache_article(ap,FALSE); X } else { X if (*linkartname) X free(linkartname); X linkartname = savestr(tmpbuf); X } X } else X seekart(0L); /* get back to the beginning */ X } X#endif X openart = artnum; /* remember what we did here */ X } X return artfp; /* and return either fp or NULL */ X} SHAR_EOF $shar_touch -am 1007195794 'trn-3.6/artio.c' && chmod 0644 'trn-3.6/artio.c' || echo 'restore of trn-3.6/artio.c failed' shar_count="`wc -c < 'trn-3.6/artio.c'`" test 2535 -eq "$shar_count" || echo "trn-3.6/artio.c: original size 2535, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/artio.h ============== if test -f 'trn-3.6/artio.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/artio.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/artio.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/artio.h' && X/* $Id: artio.h,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X XEXT ART_POS artpos INIT(0); /* byte position in article file */ X XEXT ART_LINE artline INIT(0); /* current line number in article file */ XEXT FILE *artfp INIT(Nullfp); /* current article file pointer */ XEXT ART_NUM openart INIT(0); /* the article number we have open */ X X#ifdef LINKART XEXT char *linkartname INIT(nullstr);/* real name of article for Eunice */ X#endif X Xvoid artio_init _((void)); XFILE *artopen _((ART_NUM)); /* open an article unless already opened */ X X#ifdef USE_NNTP X# define seekart(pos) nntp_seekart(pos) X# define readart(s,len) nntp_readart(s,len) X# define tellart() nntp_tellart() X#else X# define seekart(pos) fseek(artfp, pos, 0) X# define readart(s,len) fgets(s,len,artfp) X# define tellart() ftell(artfp) X#endif SHAR_EOF $shar_touch -am 1007195794 'trn-3.6/artio.h' && chmod 0644 'trn-3.6/artio.h' || echo 'restore of trn-3.6/artio.h failed' shar_count="`wc -c < 'trn-3.6/artio.h'`" test 1382 -eq "$shar_count" || echo "trn-3.6/artio.h: original size 1382, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/artsrch.c ============== if test -f 'trn-3.6/artsrch.c' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/artsrch.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/artsrch.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/artsrch.c' && X/* $Id: artsrch.c,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#include "EXTERN.h" X#include "common.h" X#include "search.h" X#include "term.h" X#include "util.h" X#include "intrp.h" X#include "cache.h" X#include "bits.h" X#include "kfile.h" X#include "head.h" X#include "final.h" X#include "nntp.h" X#include "ng.h" X#include "ngdata.h" X#include "ngstuff.h" X#include "artio.h" X#include "rthread.h" X#include "rt-select.h" X#include "INTERN.h" X#include "artsrch.h" X Xvoid Xartsrch_init() X{ X#ifdef ARTSEARCH X init_compex(&sub_compex); X init_compex(&art_compex); X#endif X} X X/* search for an article containing some pattern */ X X#ifdef ARTSEARCH Xint Xart_search(patbuf,patbufsiz,get_cmd) Xchar *patbuf; /* if patbuf != buf, get_cmd must */ Xint patbufsiz; Xint get_cmd; /* be set to FALSE!!! */ X{ X char *pattern; /* unparsed pattern */ X register char cmdchr = *patbuf; /* what kind of search? */ X register char *s; X bool backward = cmdchr == '?' || cmdchr == Ctl('p'); X /* direction of search */ X COMPEX *compex; /* which compiled expression */ X char *cmdlst = Nullch; /* list of commands to do */ X int normal_return = SRCH_NOTFOUND; /* assume no commands */ X bool saltaway = FALSE; /* store in KILL file? */ X char howmuch; /* search scope: subj/from/Hdr/head/art */ X char *srchhdr; /* header to search if Hdr scope */ X bool topstart = 0; X bool doread; /* search read articles? */ X bool foldcase = TRUE; /* fold upper and lower case? */ X int ignorethru = 0; /* should we ignore the thru line? */ X ART_NUM srchfirst; X X int_count = 0; X if (cmdchr == '/' || cmdchr == '?') { /* normal search? */ X if (get_cmd && buf == patbuf) X if (!finish_command(FALSE)) /* get rest of command */ X return SRCH_ABORT; X compex = &art_compex; X if (patbuf[1]) { X howmuch = ARTSCOPE_SUBJECT; X srchhdr = Nullch; X doread = FALSE; X } X else { X howmuch = art_howmuch; X srchhdr = art_srchhdr; X doread = art_doread; X } X s = cpytill(buf,patbuf+1,cmdchr);/* ok to cpy buf+1 to buf */ X pattern = buf; X if (*pattern) { X if (*lastpat) X free(lastpat); X lastpat = savestr(pattern); X } X if (*s) { /* modifiers or commands? */ X for (s++; *s && index("KabrcfhtBHIN",*s); s++) { X switch (*s) { X case 'f': /* scan the From line */ X howmuch = ARTSCOPE_FROM; X break; X case 'H': /* scan a specific header */ X howmuch = ARTSCOPE_ONEHDR; X srchhdr = s + 1; X if (!(s = index(srchhdr, ':'))) { X s = buf + strlen(buf); X *s++ = ':'; X *s = '\0'; X } X else X s++; X srchhdr = savestr(srchhdr); X goto loop_break; X case 'h': /* scan header */ X howmuch = ARTSCOPE_HEAD; X break; X case 'b': /* scan body sans signature */ X howmuch = ARTSCOPE_BODY_NOSIG; X break; X case 'B': /* scan body */ X howmuch = ARTSCOPE_BODY; X break; X case 'a': /* scan article */ X howmuch = ARTSCOPE_ARTICLE; X break; X case 't': /* start from the top */ X topstart = TRUE; X break; X case 'r': /* scan read articles */ X doread = TRUE; X break; X case 'K': /* put into KILL file */ X saltaway = TRUE; X break; X case 'c': /* make search case sensitive */ X foldcase = FALSE; X break; X case 'I': /* ignore the killfile thru line */ X ignorethru = 1; X break; X case 'N': /* override ignore if -k was used */ X ignorethru = -1; X break; X } X } X loop_break:; X } X while (isspace(*s) || *s == ':') X s++; X if (*s) { X#ifdef OLD_RN_WAY X if (*s == 'm' || *s == 'M') X#else X if (*s == 'm') X#endif X doread = TRUE; X if (*s == 'k') /* grandfather clause */ X *s = 'j'; X cmdlst = savestr(s); X normal_return = SRCH_DONE; X } X art_howmuch = howmuch; X if (art_srchhdr != srchhdr) { X if (art_srchhdr) X free(art_srchhdr); X art_srchhdr = srchhdr; X } X art_doread = doread; X if (srchahead) X srchahead = -1; X } X else { X register char *h; X X howmuch = ARTSCOPE_SUBJECT; /* just search subjects */ X srchhdr = Nullch; X doread = (cmdchr == Ctl('p')); X if (cmdchr == Ctl('n')) X normal_return = SRCH_SUBJDONE; X compex = &sub_compex; X pattern = patbuf+1; X strcpy(pattern,": *"); X h = pattern + strlen(pattern); X interp(h,patbufsiz - (h-patbuf),"%\\s"); /* fetch current subject */ X if (cmdchr == 'k' || cmdchr == 'K' || cmdchr == ',' X || cmdchr == '+' || cmdchr == '.') { X if (cmdchr != 'k') X saltaway = TRUE; X normal_return = SRCH_DONE; X if (cmdchr == '+') { X cmdlst = savestr("+"); X ignorethru = 1; X } X else if (cmdchr == '.') { X cmdlst = savestr("."); X ignorethru = 1; X } X else { X if (cmdchr == ',') X cmdlst = savestr(","); X mark_as_read(); /* this article has this subject */ X } X if (!*h) { X#ifdef VERBOSE X IF(verbose) X fputs("\nCannot process a null subject.\n",stdout) FLUSH; X ELSE X#endif X#ifdef TERSE X fputs("\nNull subject.\n",stdout) FLUSH; X#endif X return SRCH_ABORT; X } X#ifdef VERBOSE X else if (verbose) X if (cmdchr != '+' && cmdchr != '.') X printf("\nMarking subject \"%s\" as read.\n",h) FLUSH; X else X printf("\nSelecting subject \"%s\".\n",h) FLUSH; X#endif X } X else if (!srchahead) X srchahead = -1; X X { /* compensate for notesfiles */ X register int i; X for (i = 24; *h && i--; h++) X if (*h == '\\') X h++; X *h = '\0'; X } X#ifdef DEBUG X if (debug) { X printf("\npattern = %s\n",pattern) FLUSH; X } X#endif X } X if ((s = compile(compex,pattern,TRUE,foldcase)) != Nullch) { X /* compile regular expression */ X printf("\n%s\n",s) FLUSH; X return SRCH_ABORT; X } X#ifdef KILLFILES X if (saltaway) { X char saltbuf[LBUFLEN], *f; X X s = saltbuf; X f = pattern; X *s++ = '/'; X while (*f) { X if (*f == '/') X *s++ = '\\'; X *s++ = *f++; X } X *s++ = '/'; X if (doread) X *s++ = 'r'; X if (ignorethru) X *s++ = (ignorethru == 1 ? 'I' : 'N'); X if (howmuch != ARTSCOPE_SUBJECT) { X *s++ = scopestr[howmuch]; X if (howmuch == ARTSCOPE_ONEHDR) { X safecpy(s,srchhdr,LBUFLEN-(s-saltbuf)); X s = index(s,':'); X if (!s) X s = saltbuf+LBUFLEN-2; X } X } X *s++ = ':'; X if (!cmdlst) X cmdlst = savestr("j"); X safecpy(s,cmdlst,LBUFLEN-(s-saltbuf)); X kf_append(saltbuf); X } X#endif X if (cmdlst && index(cmdlst,'=')) X normal_return = SRCH_ERROR; /* listing subjects is an error? */ X if (get_cmd) { X fputs("\nSearching...\n",stdout) FLUSH; X /* give them something to read */ X } X if (mode == 't') { X if (!cmdlst) X if (sel_mode == SM_ARTICLE)/* set the selector's default command */ X cmdlst = savestr("+"); X else X cmdlst = savestr("++"); X if (sel_rereading) X doread = TRUE; X normal_return = SRCH_DONE; X } X if (ignorethru == 0 && kill_thru_kludge && cmdlst X && (*cmdlst == '+' || *cmdlst == '.')) X ignorethru = 1; X srchfirst = doread? absfirst X : (mode != 'k' || ignorethru > 0)? firstart : killfirst; X if (topstart || art == 0) { X art = lastart+1; X topstart = FALSE; X } X if (backward) { X if (cmdlst && art <= lastart) X art++; /* include current article */ X } X else { X if (art > lastart) X art = srchfirst-1; X else if (cmdlst && art >= absfirst) X art--; /* include current article */ X } X if (srchahead > 0) { X if (!backward) X art = srchahead - 1; X srchahead = -1; X } X assert(!cmdlst || *cmdlst); X perform_cnt = 0; X for (;;) { X /* check if we're out of articles */ X if (backward? (--art < srchfirst) : (++art > lastart)) { X if (cmdlst) X free(cmdlst); X return normal_return; X } X if (int_count) { X int_count = 0; X if (cmdlst) X free(cmdlst); X return SRCH_INTR; X } X artp = article_ptr(art); X if (doread || !(artp->flags & AF_READ)) { X if (wanted(compex,art,howmuch)) { X /* does the shoe fit? */ X if (cmdlst) { X if (perform(cmdlst,TRUE)) { X free(cmdlst); X return SRCH_INTR; X } X } X else X return SRCH_FOUND; X } X else if (!cmdlst && ! (art%50)) { X printf("...%ld",(long)art); X fflush(stdout); X } X } X } X} X X/* determine if article fits pattern */ X/* returns TRUE if it exists and fits pattern, FALSE otherwise */ X Xbool Xwanted(compex, artnum, scope) XCOMPEX *compex; XART_NUM artnum; Xchar_int scope; X{ X ARTICLE *ap = find_article(artnum); X X if (!ap || (ap->flags & AF_MISSING)) X return FALSE; X X switch (scope) { X case ARTSCOPE_SUBJECT: X strcpy(buf,"Subject: "); X strncpy(buf+9,fetchsubj(artnum,FALSE),256); X#ifdef DEBUG X if (debug & DEB_SEARCH_AHEAD) X printf("%s\n",buf) FLUSH; X#endif X break; X case ARTSCOPE_FROM: X strcpy(buf, "From: "); X strncpy(buf+6,fetchfrom(artnum,FALSE),256); X break; X case ARTSCOPE_ONEHDR: X { X int header_num; X char *s; X assert(art_srchhdr != Nullch); X s = index(art_srchhdr,':'); X header_num = set_line_type(art_srchhdr, s); X if (header_num == SOME_LINE) X return FALSE; /* FIX ME */ X untrim_cache = TRUE; X strcpy(buf, art_srchhdr); X sprintf(buf + (s-art_srchhdr), ": %s", X prefetchlines(artnum,header_num,FALSE)); X untrim_cache = FALSE; X break; X } X default: X if (scope != ARTSCOPE_BODY && scope != ARTSCOPE_BODY_NOSIG) { X if (!parseheader(artnum)) X return FALSE; X /* see if it's in the header */ X if (execute(compex,headbuf) != Nullch) /* does it match? */ X return TRUE; /* say, "Eureka!" */ X if (scope < ARTSCOPE_ARTICLE) X return FALSE; X } X if (!artopen(artnum)) /* ensure we have the body */ X return FALSE; X seekart(htype[PAST_HEADER].ht_minpos); X /* loop through each line of the article */ X while (readart(buf,LBUFLEN) != Nullch) { X if (scope == ARTSCOPE_BODY_NOSIG && *buf == '-' && buf[1] == '-' X && (buf[2] == '\n' || (buf[2] == ' ' && buf[3] == '\n'))) { X#ifdef USE_NNTP X nntp_finishbody(FB_SILENT); X#endif X break; X } X if (execute(compex,buf) != Nullch) {/* does it match? */ X#ifdef USE_NNTP X nntp_finishbody(FB_SILENT); X#endif X return TRUE; /* say, "Eureka!" */ X } X } X return FALSE; /* out of article, so no match */ X } X return execute(compex,buf) != Nullch; X} X#endif X SHAR_EOF $shar_touch -am 1107173594 'trn-3.6/artsrch.c' && chmod 0644 'trn-3.6/artsrch.c' || echo 'restore of trn-3.6/artsrch.c failed' shar_count="`wc -c < 'trn-3.6/artsrch.c'`" test 10580 -eq "$shar_count" || echo "trn-3.6/artsrch.c: original size 10580, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/artsrch.h ============== if test -f 'trn-3.6/artsrch.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/artsrch.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/artsrch.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/artsrch.h' && X/* $Id: artsrch.h,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#ifndef NBRA X#include "search.h" X#endif X X#ifdef ARTSEARCH X X#define SRCH_ABORT 0 X#define SRCH_INTR 1 X#define SRCH_FOUND 2 X#define SRCH_NOTFOUND 3 X#define SRCH_DONE 4 X#define SRCH_SUBJDONE 5 X#define SRCH_ERROR 6 X#endif X XEXT char *lastpat INIT(nullstr); /* last search pattern */ X#ifdef ARTSEARCH XEXT COMPEX sub_compex; /* last compiled subject search */ XEXT COMPEX art_compex; /* last compiled normal search */ X# ifdef CONDSUB XEXT COMPEX *bra_compex INIT(&(art_compex)); X /* current compex with brackets */ X# endif X X#define ARTSCOPE_SUBJECT 0 X#define ARTSCOPE_FROM 1 X#define ARTSCOPE_ONEHDR 2 X#define ARTSCOPE_HEAD 3 X#define ARTSCOPE_BODY_NOSIG 4 X#define ARTSCOPE_BODY 5 X#define ARTSCOPE_ARTICLE 6 X XEXT char scopestr[] INIT("sfHha"); XEXT char art_howmuch; /* search scope */ XEXT char *art_srchhdr; /* specific header to search or NULL */ XEXT bool art_doread; /* search read articles? */ X#endif X Xvoid artsrch_init _((void)); X#ifdef ARTSEARCH Xint art_search _((char*, int, int)); Xbool wanted _((COMPEX*, ART_NUM, char_int)); X /* return TRUE if current article matches pattern */ X#endif SHAR_EOF $shar_touch -am 1107173594 'trn-3.6/artsrch.h' && chmod 0644 'trn-3.6/artsrch.h' || echo 'restore of trn-3.6/artsrch.h failed' shar_count="`wc -c < 'trn-3.6/artsrch.h'`" test 1753 -eq "$shar_count" || echo "trn-3.6/artsrch.h: original size 1753, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/artstate.h ============== if test -f 'trn-3.6/artstate.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/artstate.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/artstate.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/artstate.h' && X/* $Id: artstate.h,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X XEXT bool reread INIT(FALSE); /* consider current art temporarily */ X /* unread? */ X XEXT bool do_fseek INIT(FALSE); /* should we back up in article file? */ X XEXT bool oldsubject INIT(FALSE); /* not 1st art in subject thread */ XEXT ART_LINE topline INIT(-1); /* top line of current screen */ XEXT bool do_hiding INIT(TRUE); /* hide header lines with -h? */ X#ifdef ROTATION XEXT bool rotate INIT(FALSE); /* has rotation been requested? */ X#endif XEXT char *prompt; /* pointer to current prompt */ X XEXT char *firstline INIT(Nullch); /* special first line? */ X#ifdef CUSTOMLINES XEXT char *hideline INIT(Nullch); /* custom line hiding? */ XEXT char *pagestop INIT(Nullch); /* custom page terminator? */ XEXT COMPEX hide_compex; XEXT COMPEX page_compex; X#endif SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/artstate.h' && chmod 0644 'trn-3.6/artstate.h' || echo 'restore of trn-3.6/artstate.h failed' shar_count="`wc -c < 'trn-3.6/artstate.h'`" test 1415 -eq "$shar_count" || echo "trn-3.6/artstate.h: original size 1415, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/autosub.c ============== if test -f 'trn-3.6/autosub.c' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/autosub.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/autosub.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/autosub.c' && X/* $Id: autosub.c,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#include "EXTERN.h" X#include "common.h" X#include "search.h" X#include "ngsrch.h" X#include "util.h" X#include "final.h" X#include "INTERN.h" X#include "autosub.h" X X/* Consider the newsgroup specified, and return: */ X/* : if we should autosubscribe to it */ X/* ! if we should autounsubscribe to it */ X/* \0 if we should ask the user. */ Xint Xauto_subscribe(ng) Xchar *ng; X{ X char *s; X X if((s = getval("AUTOSUBSCRIBE", (char *)NULL)) X && matchlist(s, ng)) return ':'; X if((s = getval("AUTOUNSUBSCRIBE", (char *)NULL)) X && matchlist(s, ng)) return '!'; X return 0; X} X Xbool Xmatchlist(patlist, s) Xchar *patlist; Xchar *s; X{ X COMPEX ilcompex; X char *p; X char *err; X bool result; X bool tmpresult; X X result = FALSE; X init_compex(&ilcompex); X while(patlist && *patlist) { X X if(*patlist == '!') { X patlist++; X tmpresult = FALSE; X } else tmpresult = TRUE; X X if(p = index(patlist, ',')) *p = '\0'; X /* compile regular expression */ X err = ng_comp(&ilcompex,patlist,TRUE,TRUE); X if(p) *p++ = ','; X X if(err != Nullch) { X printf("\n%s\n", err) FLUSH; X finalize(1); X } X X if (execute(&ilcompex,s) != Nullch) X result = tmpresult; X patlist = p; X } X free_compex(&ilcompex); X return result; X} SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/autosub.c' && chmod 0644 'trn-3.6/autosub.c' || echo 'restore of trn-3.6/autosub.c failed' shar_count="`wc -c < 'trn-3.6/autosub.c'`" test 1888 -eq "$shar_count" || echo "trn-3.6/autosub.c: original size 1888, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/autosub.h ============== if test -f 'trn-3.6/autosub.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/autosub.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/autosub.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/autosub.h' && X/* $Id: autosub.h,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X XEXT int auto_subscribe _((char*)); XEXT bool matchlist _((char*, char*)); SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/autosub.h' && chmod 0644 'trn-3.6/autosub.h' || echo 'restore of trn-3.6/autosub.h failed' shar_count="`wc -c < 'trn-3.6/autosub.h'`" test 725 -eq "$shar_count" || echo "trn-3.6/autosub.h: original size 725, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/backpage.c ============== if test -f 'trn-3.6/backpage.c' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/backpage.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/backpage.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/backpage.c' && X/* $Id: backpage.c,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#include "EXTERN.h" X#include "common.h" X#include "intrp.h" X#include "final.h" X#include "INTERN.h" X#include "backpage.h" X XART_LINE maxindx = -1; X Xvoid Xbackpage_init() X{ X char *varyname; X X varyname = filexp(VARYNAME); X close(creat(varyname,0600)); X varyfd = open(varyname,2); X UNLINK(varyname); X if (varyfd < 0) { X printf(cantopen,varyname) FLUSH; X sig_catcher(0); X } X X} X X/* virtual array read */ X XART_POS Xvrdary(indx) XART_LINE indx; X{ X int subindx; X long offset; X X#ifdef DEBUG X if (indx > maxindx) { X printf("vrdary(%ld) > %ld\n",(long)indx, (long)maxindx) FLUSH; X return 0; X } X#endif X if (indx < 0) X return 0; X subindx = indx % VARYSIZE; X offset = (indx - subindx) * sizeof(varybuf[0]); X if (offset != oldoffset) { X if (oldoffset >= 0) { X#ifndef lint X (void)lseek(varyfd,oldoffset,0); X write(varyfd, (char *)varybuf,sizeof(varybuf)); X#endif /* lint */ X } X#ifndef lint X (void)lseek(varyfd,offset,0); X read(varyfd,(char *)varybuf,sizeof(varybuf)); X#endif /* lint */ X oldoffset = offset; X } X return varybuf[subindx]; X} X X/* write to virtual array */ X Xvoid Xvwtary(indx,newvalue) XART_LINE indx; XART_POS newvalue; X{ X int subindx; X long offset; X X#ifdef DEBUG X if (indx < 0) X printf("vwtary(%ld)\n",(long)indx) FLUSH; X if (!indx) X maxindx = 0; X if (indx > maxindx) { X if (indx != maxindx + 1) X printf("indx skipped %d-%d\n",maxindx+1,indx-1) FLUSH; X maxindx = indx; X } X#endif X subindx = indx % VARYSIZE; X offset = (indx - subindx) * sizeof(varybuf[0]); X if (offset != oldoffset) { X if (oldoffset >= 0) { X#ifndef lint X (void)lseek(varyfd,oldoffset,0); X write(varyfd,(char *)varybuf,sizeof(varybuf)); X#endif /* lint */ X } X#ifndef lint X (void)lseek(varyfd,offset,0); X read(varyfd,(char *)varybuf,sizeof(varybuf)); X#endif /* lint */ X oldoffset = offset; X } X varybuf[subindx] = newvalue; X} X SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/backpage.c' && chmod 0644 'trn-3.6/backpage.c' || echo 'restore of trn-3.6/backpage.c failed' shar_count="`wc -c < 'trn-3.6/backpage.c'`" test 2542 -eq "$shar_count" || echo "trn-3.6/backpage.c: original size 2542, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/backpage.h ============== if test -f 'trn-3.6/backpage.h' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/backpage.h (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/backpage.h (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/backpage.h' && X/* $Id: backpage.h,v 3.0 1991/09/09 20:18:23 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X/* things for doing the 'back page' command */ X XEXT int varyfd INIT(0); /* virtual array file for storing */ X /* file offsets */ XEXT ART_POS varybuf[VARYSIZE]; /* current window onto virtual array */ X XEXT long oldoffset INIT(-1); /* offset to block currently in window */ X Xvoid backpage_init _((void)); XART_POS vrdary _((ART_LINE)); Xvoid vwtary _((ART_LINE,ART_POS)); SHAR_EOF $shar_touch -am 0711223593 'trn-3.6/backpage.h' && chmod 0644 'trn-3.6/backpage.h' || echo 'restore of trn-3.6/backpage.h failed' shar_count="`wc -c < 'trn-3.6/backpage.h'`" test 1030 -eq "$shar_count" || echo "trn-3.6/backpage.h: original size 1030, current size $shar_count" rm -f _sharnew.tmp fi # ============= trn-3.6/bits.c ============== if test -f 'trn-3.6/bits.c' && test X"$1" != X"-c"; then echo 'x - skipping trn-3.6/bits.c (file already exists)' rm -f _sharnew.tmp else > _sharnew.tmp echo 'x - extracting trn-3.6/bits.c (text)' sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/bits.c' && X/* $Id: bits.c,v 3.0 1992/02/01 03:09:32 davison Trn $ X */ X/* This software is Copyright 1991 by Stan Barber. X * X * Permission is hereby granted to copy, reproduce, redistribute or otherwise X * use this software as long as: there is no monetary profit gained X * specifically from the use or reproduction of this software, it is not X * sold, rented, traded or otherwise marketed, and this copyright notice is X * included prominently in any copy made. X * X * The authors make no claims as to the fitness or correctness of this software X * for any use whatsoever, and it is provided as is. Any use of this software X * is at the user's own risk. X */ X X#include "EXTERN.h" X#include "common.h" X#include "cache.h" X#include "INTERN.h" X#include "bits.h" X#include "EXTERN.h" X#include "rcstuff.h" X#include "head.h" X#include "term.h" X#include "util.h" X#include "util2.h" X#include "final.h" X#include "trn.h" X#include "ng.h" X#include "artio.h" X#include "intrp.h" X#include "ngdata.h" X#include "rcln.h" X#include "ndir.h" X#include "nntp.h" X#include "rthread.h" X#include "rt-select.h" X#include "rt-util.h" X X#ifdef DBM_XREFS X# ifdef NULL X# undef NULL X# endif X# include X#endif X Xstatic long chase_count = 0; X Xvoid Xbits_init() X{ X ; X} X Xvoid Xrc_to_bits() X{ X char *mybuf = buf; /* place to decode rc line */ X register char *s, *c, *h; X register long i; X register ART_NUM unread; X register ARTICLE *ap; X X /* modify the article flags to reflect what has already been read */ X X for (s = rcline[ng] + rcnums[ng]; *s == ' '; s++) ; X /* find numbers in rc line */ X i = strlen(s); X#ifndef lint X if (i >= LBUFLEN-2) /* bigger than buf? */ X mybuf = safemalloc((MEM_SIZE)(i+2)); X#endif X strcpy(mybuf,s); /* make scratch copy of line */ X mybuf[i++] = ','; /* put extra comma on the end */ X mybuf[i] = '\0'; X s = mybuf; /* initialize the for loop below */ X if (strnEQ(s,"1-",2)) { /* can we save some time here? */ X firstart = atol(s+2)+1; /* process first range thusly */ X if (firstart < absfirst) X firstart = absfirst; X s=index(s,',') + 1; X for (i = absfirst, ap = article_ptr(i); i < firstart; i++, ap++) X ap->flags |= AF_READ; X } else { X i = firstart = absfirst; X ap = article_ptr(i); X } X unread = lastart - firstart + 1; /* assume this range unread */ X#ifdef DEBUG X if (debug & DEB_CTLAREA_BITMAP) { X printf("\n%s\n",mybuf) FLUSH; X for (i = absfirst, ap = article_ptr(i); i < firstart; i++, ap++) X if (!(ap->flags & AF_READ)) X printf("%ld ",(long)i) FLUSH; X } X#endif X for ( ; (c = index(s,',')) != Nullch; s = ++c) { /* for each range */ X ART_NUM min, max; X X *c = '\0'; /* do not let index see past comma */ X h = index(s,'-'); X min = atol(s); X if (h) /* is there a dash? */ X max = atol(h+1); X else X max = min; X if (min < firstart) /* make sure range is in range */ X min = firstart; X if (min > lastart) X min = lastart+1; X for (; i < min; i++, ap++) X ap->flags &= ~AF_READ; X if (max > lastart) X max = lastart; X if (min <= max) { /* non-null range? */ X unread -= max - min + 1;/* adjust unread count */ X /* mark all arts in range as read */ X for (; i <= max; i++, ap++) X ap->flags |= AF_READ; X } X#ifdef DEBUG X if (debug & DEB_CTLAREA_BITMAP) { X printf("\n%s\n",s) FLUSH; X for (i=absfirst; i <= lastart; i++) X if (!was_read(i)) X printf("%ld ",(long)i) FLUSH; X } X#endif X } X for (; i <= lastart; i++, ap++) X ap->flags &= ~AF_READ; X#ifdef DEBUG X if (debug & DEB_CTLAREA_BITMAP) { X fputs("\n(hit CR)",stdout) FLUSH; X fgets(cmd_buf, sizeof cmd_buf, stdin); X } X#endif X if (mybuf != buf) X free(mybuf); X toread[ng] = unread; X} X X/* reconstruct the .newsrc line in a human readable form */ X Xvoid Xbits_to_rc() X{ X register char *s, *mybuf = buf; X register ART_NUM i; X ART_NUM count=0; X int safelen = LBUFLEN - 32; X X strcpy(buf,rcline[ng]); /* start with the newsgroup name */ X s = buf + rcnums[ng] - 1; /* use s for buffer pointer */ X *s++ = RCCHAR(rcchar[ng]); /* put the requisite : or !*/ X for (i=absfirst; i<=lastart; i++) X if (!was_read(i)) X break; X sprintf(s," 1-%ld,",(long)i-1); X s += strlen(s); X for (; i<=lastart; i++) { /* for each article in newsgroup */ X if (s-mybuf > safelen) { /* running out of room? */ X safelen *= 2; X if (mybuf == buf) { /* currently static? */ X *s = '\0'; X mybuf = safemalloc((MEM_SIZE)safelen + 32); X strcpy(mybuf,buf); /* so we must copy it */ X s = mybuf + (s-buf); X /* fix the pointer, too */ X } X else { /* just grow in place, if possible */ X char *newbuf; X X newbuf = saferealloc(mybuf,(MEM_SIZE)safelen + 32); X s = newbuf + (s-mybuf); X mybuf = newbuf; X } X } X if (!was_read(i)) /* still unread? */ X count++; /* then count it */ X else { /* article was read */ X ART_NUM oldi; X X sprintf(s,"%ld",(long)i); /* put out the min of the range */ X s += strlen(s); /* keeping house */ X oldi = i; /* remember this spot */ X do i++; while (i <= lastart && was_read(i)); X /* find 1st unread article or end */ X i--; /* backup to last read article */ X if (i > oldi) { /* range of more than 1? */ X sprintf(s,"-%ld,",(long)i); X /* then it out as a range */ X s += strlen(s); /* and housekeep */ X } X else X *s++ = ','; /* otherwise, just a comma will do */ X } X } X if (*(s-1) == ',') /* is there a final ','? */ X s--; /* take it back */ X *s++ = '\0'; /* and terminate string */ X#ifdef DEBUG X if (debug & DEB_NEWSRC_LINE && !panic) { X printf("%s: %s\n",rcline[ng],rcline[ng]+rcnums[ng]) FLUSH; X printf("%s\n",mybuf) FLUSH; X } X#endif X free(rcline[ng]); /* return old rc line */ X if (mybuf == buf) { X rcline[ng] = safemalloc((MEM_SIZE)(s-buf)+1); X /* grab a new rc line */ X strcpy(rcline[ng], buf); /* and load it */ X } X else { X mybuf = saferealloc(mybuf,(MEM_SIZE)(s-mybuf)+1); X /* be nice to the heap */ X rcline[ng] = mybuf; X } X *(rcline[ng] + rcnums[ng] - 1) = '\0'; X if (rcchar[ng] == NEGCHAR) { /* did they unsubscribe? */ X printf(unsubto,ngname) FLUSH; X toread[ng] = TR_UNSUB; /* make line invisible */ X } X else X /*NOSTRICT*/ X toread[ng] = (ART_UNREAD)count; /* remember how many unread there are */ X} X X#ifdef USE_NNTP X X/* Parse the LISTGROUP output and set anything not mentioned as missing. */ X Xvoid Xsetmissingbits() /* NNTP version */ X{ X register ART_NUM num, priornum; X register ARTICLE *ap; X X if (!nntp_listgroup()) X return; X for (priornum = absfirst-1, ap = article_ptr(absfirst);; ap++) { X nntp_gets(ser_line, sizeof ser_line); X if (NNTP_LIST_END(ser_line)) X break; X num = atol(ser_line); X while (++priornum < num) X uncache_article(ap++,FALSE); X } X} X X#else /* !USE_NNTP */ X X/* Scan the directory to find which articles are present. */ X Xvoid Xsetfoundbits() X{ X register ART_NUM first = lastart+1; X register DIR *dirp; X register Direntry_t *dp; X long an; X char ch; X X if (!(dirp = opendir("."))) X return; X X found_min = absfirst; X an = (lastart-found_min)/BITSPERBYTE+20; X found_bits = safemalloc((MEM_SIZE)an); X bzero(found_bits, an); X X while ((dp = readdir(dirp)) != Null(Direntry_t*)) { X if (sscanf(dp->d_name, "%ld%c", &an, &ch) == 1) { X if (an <= lastart && an >= found_min) { X if (an < first) X first = an; X foundart(an); X } X } X } X closedir(dirp); X abs1st[ng] = first; X if (first > absfirst) X checkexpired(ng,first); X absfirst = first; X} X Xvoid Xsetmissingbits() /* non-NNTP version */ X{ X register ARTICLE *ap; X register ART_NUM an; X X if (!found_bits) X return; X X for (an = absfirst, ap = article_ptr(an); an <= lastart; an++, ap++) { X if (artismissing(an)) X onemissing(ap); X } X free(found_bits); X found_bits = NULL; X} X#endif /* !USE_NNTP */ X X/* mark an article unread, keeping track of toread[] */ X Xvoid Xonemore(ap) XARTICLE *ap; X{ X if (ap->flags & AF_READ) { X register ART_NUM artnum = article_num(ap); X check_first(artnum); X ap->flags &= ~AF_READ; X ++toread[ng]; X ap->flags &= ~AF_DEL; X if (ap->subj) { X if (selected_only) { X if (ap->subj->flags & sel_mask) { X ap->flags |= sel_mask; X selected_count++; X } X } else X ap->subj->flags |= SF_VISIT; X } X } X} X X/* mark an article read, keeping track of toread[] */ X Xvoid Xoneless(ap) XARTICLE *ap; X{ X if (!(ap->flags & AF_READ)) { X ap->flags |= AF_READ; X /* Keep selected_count accurate */ X if (ap->flags & sel_mask) { X selected_count--; X ap->flags &= ~sel_mask; X } X if (toread[ng] > TR_NONE) X --toread[ng]; X } X} X Xvoid Xonemissing(ap) XARTICLE *ap; X{ SHAR_EOF : || echo 'restore of trn-3.6/bits.c failed' fi echo 'End of archive part 1' echo 'File trn-3.6/bits.c is continued in part 2' echo 2 > _sharseq.tmp exit 0