REPOST v23i069: TRN, version of RN that follows conversation threads, Part10/14
Rich Salz
rsalz at bbn.com
Fri Dec 7 00:53:41 AEST 1990
Submitted-by: Wayne Davison <davison at dri.com>
Posting-number: Volume 23, Issue 69
Archive-name: trn/part10
[ The reposted part09 didn't clean things up for the original part10.
Now you know why I dislike this style of shar. Sorry for the
inconvenience. --r$ ]
#!/bin/sh
# this is part 10 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file ng.c continued
#
echo "x - extracting ng.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > ng.h &&
X/* $Header: ng.h,v 4.3 85/05/01 11:44:29 lwall Exp $
X *
X * $Log: ng.h,v $
X * Revision 4.3 85/05/01 11:44:29 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
XEXT ART_NUM art INIT(0); /* current or prospective article # */
X
XEXT int checkcount INIT(0); /* how many articles have we read */
X /* in the current newsgroup since */
X /* the last checkpoint? */
XEXT int docheckwhen INIT(20); /* how often to do checkpoint */
X
X#ifdef MAILCALL
XEXT int mailcount INIT(0); /* check for mail when 0 mod 10 */
X#endif
XEXT char *mailcall INIT(nullstr);
X
XEXT bool forcelast INIT(FALSE); /* ought we show "End of newsgroup"? */
XEXT bool forcegrow INIT(FALSE); /* do we want to recalculate size */
X /* of newsgroup, e.g. after posting? */
X
X#define NG_ERROR -1
X#define NG_NORM 0
X#define NG_ASK 1
X#define NG_MINUS 2
X
Xvoid ng_init();
Xint do_newsgroup();
Xint art_switch();
X#ifdef MAILCALL
X void setmail();
X#endif
Xvoid setdfltcmd();
SHAR_EOF
chmod 0660 ng.h || echo "restore of ng.h fails"
echo "x - extracting ngdata.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ngdata.c &&
X/* $Header: ngdata.c,v 4.3.3.1 90/07/21 20:28:27 davison Trn $
X *
X * $Log: ngdata.c,v $
X * Revision 4.3.3.1 90/07/21 20:28:27 davison
X * Initial Trn Release
X *
X * Revision 4.3.2.10 90/04/14 22:05:15 sob
X * Removed redundant declaration of active_name
X *
X * Revision 4.3.2.9 90/03/22 23:04:55 sob
X * Fixes provided by Wayne Davison <drivax!davison>
X *
X * Revision 4.3.2.8 90/03/17 20:50:51 sob
X * Fixes provided by stewart at netxcom.iad-nxe.global-mis.dhl.com to handle
X * flaky transfers of the active file from the server.
X *
X * Revision 4.3.2.7 90/03/17 17:11:08 sob
X * Added support for CNEWS active file flags.
X *
X * Revision 4.3.2.6 89/12/08 22:42:04 sob
X * Corrected typo in an #ifdef statement pointed out by
X * jik at pit-manager.mit.edu
X *
X * Revision 4.3.2.5 89/11/28 01:51:14 sob
X * Removed redundant #include directive.
X *
X * Revision 4.3.2.4 89/11/27 01:31:07 sob
X * Altered NNTP code per ideas suggested by Bela Lubkin
X * <filbo at gorn.santa-cruz.ca.us>
X *
X * Revision 4.3.2.3 89/11/08 02:41:40 sob
X * Removed unneeded subroutine.
X *
X * Revision 4.3.2.2 89/11/08 02:24:31 sob
X * Integrated modifications from other RRN patches colleceted from USENET
X *
X * Revision 4.3.2.1 89/11/06 00:42:43 sob
X * Added RRN support from NNTP 1.5
X *
X * Revision 4.3 85/05/01 11:44:38 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "ndir.h"
X#include "rcstuff.h"
X#include "rn.h"
X#include "intrp.h"
X#include "final.h"
X#include "rcln.h"
X#include "util.h"
X#ifdef SERVER
X#include "server.h"
X#endif
X#include "INTERN.h"
X#include "ngdata.h"
X
Xvoid
Xngdata_init()
X{
X#ifdef SERVER
X char ser_line[256];
X int entries;
X#endif
X char *cp;
X
X/* The following is only for systems that do not zero globals properly */
X#ifdef ZEROGLOB
X# ifdef CACHEFIRST
X for (i=0; i<MAXRCLINE; i++)
X abs1st[i] = 0;
X# endif
X#endif /* ZEROGLOB */
X
X /* open the active file */
X
X#ifdef SERVER
X
X#ifdef USETHREADS
X if (use_threads) {
X cp = filexp(ACTIVE2);
X actfp = fopen(cp,"r");
X if (actfp == Nullfp) {
X printf(cantopen,cp) FLUSH;
X finalize(1);
X }
X return;
X }
X#endif
X
X put_server("LIST"); /* tell server we want the active file */
X get_server(ser_line, sizeof(ser_line));
X if (*ser_line != CHAR_OK) { /* and then see if that's ok */
X fprintf(stdout, "Can't get active file from server: \n%s\n", ser_line);
X finalize(1);
X }
X
X cp = filexp("/tmp/rrnact.%$"); /* make a temporary name */
X strcpy(active_name, cp);
X actfp = fopen(active_name, "w+"); /* and get ready */
X if (actfp == Nullfp) {
X printf(cantopen,active_name) FLUSH;
X finalize(1);
X }
X
X entries = 0;
X while (1) {
X if (get_server(ser_line, sizeof(ser_line)) < 0) {
X printf("Can't get active file from server:\ntransfer failed after %d entries\n", entries);
X finalize(1);
X }
X if (ser_line[0] == '.') /* while there's another line */
X break; /* get it and write it to */
X entries++;
X fputs(ser_line, actfp);
X putc('\n', actfp);
X }
X
X fseek(actfp,0L,0); /* just get to the beginning */
X
X#else /* not SERVER */
X
X#ifdef USETHREADS
X if (use_threads)
X cp = filexp(ACTIVE2);
X else
X#endif
X cp = filexp(ACTIVE);
X actfp = fopen(cp,"r");
X if (actfp == Nullfp) {
X printf(cantopen,cp) FLUSH;
X finalize(1);
X }
X#endif
X}
X
X/* find the maximum article number of a newsgroup */
X
XART_NUM
Xgetngsize(num)
Xregister NG_NUM num;
X{
X register int len;
X register char *nam;
X char tmpbuf[80];
X ART_POS oldsoft;
X
X nam = rcline[num];
X len = rcnums[num] - 1;
X softtries++;
X#ifdef DEBUGGING
X if (debug & DEB_SOFT_POINTERS)
X printf("Softptr = %ld\n",(long)softptr[num]) FLUSH;
X#endif
X oldsoft = softptr[num];
X if ((softptr[num] = findact(tmpbuf, nam, len, (long)oldsoft)) >= 0) {
X if (softptr[num] != oldsoft) {
X softmisses++;
X writesoft = TRUE;
X }
X }
X else {
X softptr[num] = 0;
X if (rcchar[num] == ':') /* unsubscribe quietly */
X rcchar[num] = NEGCHAR;
X return TR_BOGUS; /* well, not so quietly, actually */
X }
X
X#ifdef DEBUGGING
X if (debug & DEB_SOFT_POINTERS) {
X printf("Should be %ld\n",(long)softptr[num]) FLUSH;
X }
X#endif
X#ifdef MININACT
X {
X register char *s, ch;
X ART_NUM tmp;
X
X for (s=tmpbuf+len+1; isdigit(*s); s++) ;
X if (tmp = atol(s))
X#ifdef CACHEFIRST
X abs1st[num] = tmp;
X#else
X abs1st = tmp;
X#endif
X if (!in_ng) {
X for (s++; isdigit(*s); s++) ;
X while (isspace(*s)) s++;
X ch = *s;
X#ifdef USETHREADS
X if (isupper(ch)) {
X ch = tolower(ch);
X ThreadedGroup = FALSE;
X } else
X ThreadedGroup = use_threads;
X#endif
X switch (ch) {
X case 'n': moderated = getval("NOPOSTRING"," (no posting)"); break;
X case 'm': moderated = getval("MODSTRING", " (moderated)"); break;
X /* This shouldn't even occur. What are we doing in a non-existent
X group? Disallow it. */
X case 'x': return TR_BOGUS;
X /* what should be done about refiled groups? rn shouldn't even
X be in them (ie, if sci.aquaria is refiled to rec.aquaria, then
X get the news there) */
X case '=': return TR_BOGUS;
X default: moderated = nullstr;
X }
X }
X }
X#endif
X return atol(tmpbuf+len+1);
X}
X
XACT_POS
Xfindact(outbuf,nam,len,suggestion)
Xchar *outbuf;
Xchar *nam;
Xint len;
Xlong suggestion;
X{
X ACT_POS retval;
X
X fseek(actfp,100000L,1); /* hopefully this forces a reread */
X if (suggestion == 0L || fseek(actfp,suggestion,0) < 0 ||
X fgets(outbuf,80,actfp) == Nullch ||
X outbuf[len] != ' ' ||
X strnNE(outbuf,nam,len)) {
X#ifdef DEBUGGING
X if (debug & DEB_SOFT_POINTERS)
X printf("Missed, looking for %s in %sLen = %d\n",nam,outbuf,len)
X FLUSH;
X#endif
X fseek(actfp,0L,0);
X#ifndef lint
X retval = (ACT_POS)ftell(actfp);
X#else
X retval = Null(ACT_POS);
X#endif /* lint */
X while (fgets(outbuf,80,actfp) != Nullch) {
X if (outbuf[len] == ' ' && strnEQ(outbuf,nam,len))
X return retval;
X#ifndef lint
X retval = (ACT_POS) ftell(actfp);
X#endif /* lint */
X }
X return (ACT_POS) -1; /* well, not so quietly, actually */
X }
X else
X#ifndef lint
X return (ACT_POS) suggestion;
X#else
X return retval;
X#endif /* lint */
X /*NOTREACHED*/
X}
X
X/* determine the absolutely first existing article number */
X#ifdef SERVER
XART_NUM
Xgetabsfirst(ngnum,ngsize)
Xregister NG_NUM ngnum;
XART_NUM ngsize;
X{
X register ART_NUM a1st;
X#ifndef MININACT
X char ser_line[256];
X ART_NUM x,y;
X#endif
X
X#ifdef CACHEFIRST
X if (a1st = abs1st[ngnum])
X return a1st;
X#endif
X#ifdef MININACT
X getngsize(ngnum);
X# ifdef CACHEFIRST
X return abs1st[ngnum];
X# else
X return abs1st;
X# endif
X#else
X sprintf(cp,"GROUP %s",rcline[ngnum]);
X put_server(cp);
X if (get_server(ser_line, sizeof(ser_line)) < 0) {
X fprintf(stderr, "rrn: Unexpected close of server socket.\n");
X finalize(1);
X }
X if (*ser_line != CHAR_OK) { /* and then see if that's ok */
X a1st = ngsize+1; /* nothing there */
X }
X (void) sscanf(ser_line,"%d%d%d",&x,&y,&a1st);
X# ifdef CACHEFIRST
X abs1st[ngnum] = a1st;
X# endif
X return a1st;
X#endif
X}
X/* we already know the lowest article number with NNTP */
XART_NUM
Xgetngmin(dirname,floor)
Xchar *dirname;
XART_NUM floor;
X{
X return(floor);
X}
X#else
XART_NUM
Xgetabsfirst(ngnum,ngsize)
Xregister NG_NUM ngnum;
XART_NUM ngsize;
X{
X register ART_NUM a1st;
X#ifndef MININACT
X char dirname[MAXFILENAME];
X#endif
X
X#ifdef CACHEFIRST
X if (a1st = abs1st[ngnum])
X return a1st;
X#endif
X#ifdef MININACT
X getngsize(ngnum);
X# ifdef CACHEFIRST
X return abs1st[ngnum];
X# else
X return abs1st;
X# endif
X#else /* not MININACT */
X sprintf(dirname,"%s/%s",spool,getngdir(rcline[ngnum]));
X a1st = getngmin(dirname,0L);
X if (!a1st) /* nothing there at all? */
X a1st = ngsize+1; /* aim them at end of newsgroup */
X# ifdef CACHEFIRST
X abs1st[ngnum] = a1st;
X# endif
X return a1st;
X#endif /* MININACT */
X}
X
X/* scan a directory for minimum article number greater than floor */
X
XART_NUM
Xgetngmin(dirname,floor)
Xchar *dirname;
XART_NUM floor;
X{
X register DIR *dirp;
X register struct DIRTYPE *dp;
X register ART_NUM min = 1000000;
X register ART_NUM maybe;
X register char *p;
X char tmpbuf[128];
X
X dirp = opendir(dirname);
X if (!dirp)
X return 0;
X while ((dp = readdir(dirp)) != Null(struct DIRTYPE *)) {
X if ((maybe = atol(dp->d_name)) < min && maybe > floor) {
X for (p = dp->d_name; *p; p++)
X if (!isdigit(*p))
X goto nope;
X if (*dirname == '.' && !dirname[1])
X stat(dp->d_name, &filestat);
X else {
X sprintf(tmpbuf,"%s/%s",dirname,dp->d_name);
X stat(tmpbuf, &filestat);
X }
X if (! (filestat.st_mode & S_IFDIR))
X min = maybe;
X }
X nope:
X ;
X }
X closedir(dirp);
X return min==1000000 ? 0 : min;
X}
X#endif
SHAR_EOF
chmod 0660 ngdata.c || echo "restore of ngdata.c fails"
echo "x - extracting ngdata.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > ngdata.h &&
X/* $Header: ngdata.h,v 4.3.3.1 90/06/20 22:38:50 davison Trn $
X *
X * $Log: ngdata.h,v $
X * Revision 4.3.3.1 90/06/20 22:38:50 davison
X * Initial Trn Release
X *
X * Revision 4.3.2.1 89/11/06 00:41:21 sob
X * Added RRN support from NNTP 1.5
X *
X * Revision 4.3 85/05/01 11:44:48 lwall
X * added to local RCS
X *
X * Revision 4.3 85/05/01 11:44:48 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
XEXT FILE *actfp INIT(Nullfp); /* the active file */
XEXT bool writesoft INIT(FALSE); /* rewrite the soft pointer file? */
XEXT int softtries INIT(0), softmisses INIT(0);
X
X#ifdef SERVER
X EXT char active_name[256];
X#endif
X
X#ifdef CACHEFIRST
X EXT ART_NUM abs1st[MAXRCLINE]; /* 1st real article in newsgroup */
X#else
X# ifdef MININACT
X EXT ART_NUM abs1st INIT(0);
X# endif
X#endif
X
XEXT char *moderated;
X#ifdef USETHREADS
XEXT bool ThreadedGroup;
X#endif
X
Xvoid ngdata_init();
XART_NUM getngsize();
XACT_POS findact();
XART_NUM getabsfirst();
XART_NUM getngmin();
SHAR_EOF
chmod 0660 ngdata.h || echo "restore of ngdata.h fails"
echo "x - extracting ngsrch.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ngsrch.c &&
X/* $Header: ngsrch.c,v 4.3 85/05/01 11:44:51 lwall Exp $
X *
X * $Log: ngsrch.c,v $
X * Revision 4.3 85/05/01 11:44:51 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "rcstuff.h"
X#include "final.h"
X#include "search.h"
X#include "rn.h"
X#include "util.h"
X#include "term.h"
X#include "rcln.h"
X#include "INTERN.h"
X#include "ngsrch.h"
X
X#ifdef NGSORONLY
X COMPEX ngcompex;
X#endif
X
Xvoid
Xngsrch_init()
X{
X#ifdef ZEROGLOB
X init_compex(&ngcompex);
X#endif /* ZEROGLOB */
X ;
X}
X
X#ifdef NGSEARCH
Xint
Xng_search(patbuf,get_cmd)
Xchar *patbuf; /* if patbuf != buf, get_cmd must */
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 == '?'; /* direction of search */
X
X int_count = 0;
X if (get_cmd && buf == patbuf)
X if (!finish_command(FALSE)) /* get rest of command */
X return NGS_ABORT;
X for (pattern = patbuf+1; *pattern == ' '; pattern++) ;
X if (*pattern) {
X ng_doread = FALSE;
X }
X s = rindex(pattern,cmdchr);
X if (s != Nullch && *(s-1) != '\\') {
X *s++ = '\0';
X if (index(s,'r') != Nullch)
X ng_doread = TRUE;
X }
X if ((s = ng_comp(&ngcompex,pattern,TRUE,TRUE)) != Nullch) {
X /* compile regular expression */
X printf("\n%s\n",s) FLUSH;
X return NGS_ABORT;
X }
X fputs("\nSearching...",stdout) FLUSH; /* give them something to read */
X fflush(stdout);
X for (;;) {
X if (int_count) {
X int_count = 0;
X return NGS_INTR;
X }
X if (backward) {
X if (ng > 0)
X --ng;
X else
X ng = nextrcline;
X }
X else {
X if (ng >= nextrcline)
X ng = 0;
X else
X ++ng;
X }
X if (ng == current_ng)
X return NGS_NOTFOUND;
X if (ng == nextrcline || toread[ng] < TR_NONE || !ng_wanted())
X continue;
X if (toread[ng] == TR_NONE)
X set_toread(ng);
X
X if (toread[ng] > TR_NONE)
X return NGS_FOUND;
X else if (toread[ng] == TR_NONE)
X if (ng_doread)
X return NGS_FOUND;
X else
X printf("\n[0 unread in %s--skipping]",rcline[ng]) FLUSH;
X }
X}
X
Xbool
Xng_wanted()
X{
X return execute(&ngcompex,rcline[ng]) != Nullch;
X}
X#endif
X
X#ifdef NGSORONLY
Xchar *
Xng_comp(compex,pattern,RE,fold)
XCOMPEX *compex;
Xchar *pattern;
Xbool RE;
Xbool fold;
X{
X char ng_pattern[128];
X register char *s = pattern, *d = ng_pattern;
X
X if (!*s)
X return Nullch; /* reuse old pattern */
X for (; *s; s++) {
X if (*s == '.') {
X *d++ = '\\';
X *d++ = *s;
X }
X else if (*s == '?') {
X *d++ = '.';
X }
X else if (*s == '*') {
X *d++ = '.';
X *d++ = *s;
X }
X else if (strnEQ(s,"all",3)) {
X *d++ = '.';
X *d++ = '*';
X s += 2;
X }
X else
X *d++ = *s;
X }
X *d = '\0';
X return compile(compex,ng_pattern,RE,fold);
X}
X#endif
X
SHAR_EOF
chmod 0660 ngsrch.c || echo "restore of ngsrch.c fails"
echo "x - extracting ngsrch.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > ngsrch.h &&
X/* $Header: ngsrch.h,v 4.3 85/05/01 11:44:56 lwall Exp $
X *
X * $Log: ngsrch.h,v $
X * Revision 4.3 85/05/01 11:44:56 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#ifdef NGSEARCH
X#define NGS_ABORT 0
X#define NGS_FOUND 1
X#define NGS_INTR 2
X#define NGS_NOTFOUND 3
X
XEXT bool ng_doread INIT(FALSE); /* search read newsgroups? */
X#endif
X
Xvoid ngsrch_init();
X#ifdef NGSEARCH
X int ng_search();
X bool ng_wanted();
X#endif
X#ifdef NGSORONLY
X char *ng_comp();
X#endif
SHAR_EOF
chmod 0660 ngsrch.h || echo "restore of ngsrch.h fails"
echo "x - extracting ngstuff.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > ngstuff.c &&
X/* $Header: ngstuff.c,v 4.3.3.1 90/07/21 20:29:12 davison Trn $
X *
X * $Log: ngstuff.c,v $
X * Revision 4.3.3.1 90/07/21 20:29:12 davison
X * Initial Trn Release
X *
X * Revision 4.3.2.2 90/04/14 19:40:02 sob
X * Fixed small syntax problem that generates errors with particular C
X * preprocessors.
X *
X * Revision 4.3.1.2 85/05/10 14:31:52 lwall
X * Prevented "Junked" or "Marked unread" when no state change.
X *
X * Revision 4.3.1.1 85/05/10 11:36:45 lwall
X * Branch for patches.
X *
X * Revision 4.3 85/05/01 11:45:03 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "term.h"
X#include "util.h"
X#include "ng.h"
X#include "bits.h"
X#include "intrp.h"
X#include "cheat.h"
X#include "head.h"
X#include "final.h"
X#include "sw.h"
X#ifdef USETHREADS
X#include "rthreads.h"
X#include "rn.h"
X#include "rcstuff.h"
X#endif
X#include "uudecode.h"
X#include "INTERN.h"
X#include "ngstuff.h"
X
Xvoid
Xngstuff_init()
X{
X ;
X}
X
X/* do a shell escape */
X
Xint
Xescapade()
X{
X register char *s;
X bool interactive = (buf[1] == FINISHCMD);
X bool docd;
X char whereiam[256];
X
X if (!finish_command(interactive)) /* get remainder of command */
X return -1;
X s = buf+1;
X docd = *s != '!';
X if (!docd) {
X s++;
X }
X else {
X getwd(whereiam);
X if (chdir(cwd)) {
X printf(nocd,cwd) FLUSH;
X sig_catcher(0);
X }
X }
X while (*s == ' ') s++;
X /* skip leading spaces */
X interp(cmd_buf, (sizeof cmd_buf), s);/* interpret any % escapes */
X resetty(); /* make sure tty is friendly */
X doshell(Nullch,cmd_buf); /* invoke the shell */
X noecho(); /* and make terminal */
X crmode(); /* unfriendly again */
X if (docd) {
X if (chdir(whereiam)) {
X printf(nocd,whereiam) FLUSH;
X sig_catcher(0);
X }
X }
X#ifdef MAILCALL
X mailcount = 0; /* force recheck */
X#endif
X return 0;
X}
X
X/* process & command */
X
Xint
Xswitcheroo()
X{
X if (!finish_command(TRUE)) /* get rest of command */
X return -1; /* if rubbed out, try something else */
X if (!buf[1])
X pr_switches();
X#ifdef PUSHBACK
X else if (buf[1] == '&') {
X if (!buf[2]) {
X page_init();
X show_macros();
X }
X else {
X char tmpbuf[LBUFLEN];
X register char *s;
X
X for (s=buf+2; isspace(*s); s++);
X mac_line(s,tmpbuf,(sizeof tmpbuf));
X }
X }
X#endif
X else {
X bool docd = (instr(buf,"-d") != Nullch);
X char whereami[256];
X
X if (docd)
X getwd(whereami);
X sw_list(buf+1);
X if (docd) {
X cwd_check();
X if (chdir(whereami)) { /* -d does chdirs */
X printf(nocd,whereami) FLUSH;
X sig_catcher(0);
X }
X }
X }
X return 0;
X}
X
X/* process range commands */
X
Xint
Xnumnum()
X{
X ART_NUM min, max;
X char *cmdlst = Nullch;
X register char *s, *c;
X ART_NUM oldart = art;
X char tmpbuf[LBUFLEN];
X bool justone = TRUE; /* assume only one article */
X
X perform_cnt = 0;
X if (!finish_command(TRUE)) /* get rest of command */
X return NN_INP;
X if (lastart < 1) {
X fputs("\nNo articles\n",stdout) FLUSH;
X return NN_ASK;
X }
X#ifdef ARTSRCH
X if (srchahead)
X srchahead = -1;
X#endif
X for (s=buf; *s && (isdigit(*s) || index(" ,-.$",*s)); s++)
X if (!isdigit(*s))
X justone = FALSE;
X if (*s) {
X cmdlst = savestr(s);
X justone = FALSE;
X }
X else if (!justone)
X cmdlst = savestr("m");
X *s++ = ',';
X *s = '\0';
X safecpy(tmpbuf,buf,LBUFLEN);
X for (s = tmpbuf; c = index(s,','); s = ++c) {
X *c = '\0';
X if (*s == '.')
X min = oldart;
X else
X min = atol(s);
X#ifdef USETHREADS
X if (min<absfirst && justone) {
X int r;
X
X /* Check if this is a root number */
X for (r = 0; r < total.root; r++) {
X if (p_roots[r].root_num == min) {
X p_art = p_articles + p_roots[r].articles;
X art = p_art->num;
X if (p_art->subject == -1) {
X follow_thread('N');
X }
X return NN_REREAD;
X }
X }
X }
X#endif
X if (min<absfirst) { /* make sure it is reasonable */
X min = absfirst;
X printf("(First article is %ld)\n",(long)absfirst) FLUSH;
X pad(just_a_sec/3);
X }
X if ((s=index(s,'-')) != Nullch) {
X s++;
X if (*s == '$')
X max = lastart;
X else if (*s == '.')
X max = oldart;
X else
X max = atol(s);
X }
X else
X max = min;
X if (max>lastart) {
X max = lastart;
X if (min > max)
X min = max;
X printf("(Last article is %ld)\n",(long)lastart) FLUSH;
X pad(just_a_sec/3);
X }
X if (max < min) {
X fputs("\nBad range\n",stdout) FLUSH;
X if (cmdlst)
X free(cmdlst);
X return NN_ASK;
X }
X if (justone) {
X art = min;
X return NN_REREAD;
X }
X check_first(min);
X for (art=min; art<=max; art++) {
X if (perform(cmdlst,TRUE)) {
X#ifdef VERBOSE
X IF(verbose)
X printf("\n(Interrupted at article %ld)\n",(long)art)
X FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X printf("\n(Intr at %ld)\n",(long)art) FLUSH;
X#endif
X if (cmdlst)
X free(cmdlst);
X return NN_ASK;
X }
X }
X }
X art = oldart;
X if (cmdlst)
X free(cmdlst);
X return NN_NORM;
X}
X
X#ifdef USETHREADS
Xint
Xuse_selected()
X{
X PACKED_ARTICLE *root_limit;
X register char *s, ch;
X register int r;
X char *cmdstr;
X int ret = 1, orig_root_cnt = selected_root_cnt;
X
X if (!finish_command(TRUE)) /* get rest of command */
X return 0;
X if (!(ch = buf[1]))
X return -1;
X cmdstr = savestr(buf+1);
X
X perform_cnt = 0;
X page_line = 1;
X
X /* Multiple commands and commands that operate on individual articles
X ** use the article loop.
X */
X if (strlen(cmdstr) > 1 || index("ejmMsSwW|=", ch)) {
X bool want_unread = (unread_selector || ch == 'm');
X
X for (r = 0; r < total.root; r++) {
X if (scan_all_roots
X || (!orig_root_cnt&&root_article_cnts[r]&&!(selected_roots[r]&4))
X || (selected_roots[r] & (unread_selector+1))) {
X p_art = p_articles + p_roots[r].articles;
X root_limit = upper_limit( p_art, 0 );
X for (; p_art < root_limit; p_art++) {
X art = p_art->num;
X if (p_art->subject != -1
X && (!was_read(art) ^ want_unread)) {
X if (perform(cmdstr, TRUE)) {
X fputs("\nInterrupted\n", stdout) FLUSH;
X goto break_out;
X }
X }
X if (p_art == Nullart)
X break;
X }/* for all articles */
X }/* if selected */
X }/* for all threads */
X } /* other commands get the root loop */
X else if (ch == '+' || ch == '-' || ch == 'J' || ch == 'T' || ch == 't') {
X for (r = 0; r < total.root; r++) {
X if (scan_all_roots
X || (!orig_root_cnt&&root_article_cnts[r]&&!(selected_roots[r]&4))
X || (selected_roots[r] & (unread_selector+1))) {
X if (mode != 't' && ch != 't') {
X printf("T%-5ld ", (long)p_roots[r].root_num);
X }
X p_art = p_articles + p_roots[r].articles;
X art = p_art->num;
X if (perform(cmdstr, FALSE)) {
X fputs("\nInterrupted\n", stdout) FLUSH;
X goto break_out;
X }
X#ifdef VERBOSE
X IF(verbose)
X if (mode != 't' && ch != 't' && ch != 'T')
X putchar('\n') FLUSH;
X#endif
X }
X }
X }
X else if (ch == 'E') { /* one command needs no looping at all */
X if (uu_out != Nullfp) {
X uud_end();
X } else {
X ret = 2;
X }
X }
X else {
X printf("???%s\n",cmdstr);
X ret = -1;
X }
X break_out:
X free(cmdstr);
X return ret;
X}
X#endif
X
Xint
Xperform(cmdlst,toplevel)
Xregister char *cmdlst;
Xint toplevel;
X{
X register int ch;
X
X if (toplevel) {
X printf("%-6ld ",art);
X fflush(stdout);
X }
X perform_cnt++;
X for (; ch = *cmdlst; cmdlst++) {
X if (isspace(ch) || ch == ':')
X continue;
X if (ch == 'j') {
X if (!was_read(art)) {
X mark_as_read();
X#ifdef VERBOSE
X IF(verbose)
X fputs("\tJunked",stdout);
X#endif
X }
X }
X#ifdef USETHREADS
X else if (ch == '+') {
X find_article(art);
X if (p_art && !(selected_roots[p_art->root] & (unread_selector+1))) {
X selected_roots[p_art->root] |= (unread_selector+1);
X selected_root_cnt++;
X if (mode == 't') {
X selected_count += root_article_cnts[p_art->root];
X } else {
X selected_count += count_one_root(p_art->root);
X#ifdef VERBOSE
X IF(verbose)
X fputs("\tSelected",stdout);
X#endif
X }
X }
X }
X else if (ch == '-') {
X find_article(art);
X if (p_art && selected_root_cnt
X && (selected_roots[p_art->root] & (unread_selector+1))) {
X selected_roots[p_art->root] &= ~(unread_selector+1);
X selected_root_cnt--;
X if (mode == 't') {
X selected_count -= root_article_cnts[p_art->root];
X } else {
X selected_count -= count_one_root(p_art->root);
X#ifdef VERBOSE
X IF(verbose)
X fputs("\tDeselected",stdout);
X#endif
X }
X }
X }
X else if (ch == 't') {
X find_article(art);
X entire_tree();
X }
X else if (ch == 'J' || ch == 'T') {
X char tmpbuf[128];
X ART_NUM oldart = art;
X
X find_article(art);
X if (p_art) {
X if (ch == 'T') {
X sprintf(tmpbuf,"T%ld\t# %s",
X (long)p_roots[p_art->root].root_num,
X subject_ptrs[p_art->subject]);
X fputs(tmpbuf,stdout);
X kf_append(tmpbuf);
X }
X follow_thread('J');
X art = oldart;
X }
X }
X#endif
X else if (ch == 'm') {
X if (was_read(art)) {
X unmark_as_read();
X#ifdef VERBOSE
X IF(verbose)
X fputs("\tMarked unread",stdout);
X#endif
X }
X }
X else if (ch == 'M') {
X#ifdef DELAYMARK
X delay_unmark(art);
X#ifdef VERBOSE
X IF(verbose)
X fputs("\tWill return",stdout);
X#endif
X#else
X notincl("M");
X return -1;
X#endif
X }
X else if (ch == '=') {
X printf("\t%s",fetchsubj(art,FALSE,FALSE));
X#ifdef VERBOSE
X IF(verbose)
X ;
X ELSE
X#endif
X putchar('\n') FLUSH; /* ghad! */
X }
X else if (ch == 'C') {
X#ifdef ASYNC_PARSE
X printf("\t%sancelled",(cancel_article() ? "Not c" : "C"));
X#else
X notincl("C");
X return -1;
X#endif
X }
X else if (ch == '%') {
X#ifdef ASYNC_PARSE
X char tmpbuf[512];
X
X if (one_command)
X interp(tmpbuf, (sizeof tmpbuf), cmdlst);
X else
X cmdlst = dointerp(tmpbuf, (sizeof tmpbuf), cmdlst, ":") - 1;
X perform_cnt--;
X if (perform(tmpbuf,FALSE))
X return -1;
X#else
X notincl("%");
X return -1;
X#endif
X }
X else if (index("!&sSwWe|",ch)) {
X if (one_command)
X strcpy(buf,cmdlst);
X else
X cmdlst = cpytill(buf,cmdlst,':') - 1;
X /* we now have the command in buf */
X if (ch == '!') {
X escapade();
X#ifdef VERBOSE
X IF(verbose)
X fputs("\tShell escaped",stdout);
X#endif
X }
X else if (ch == '&') {
X switcheroo();
X#ifdef VERBOSE
X IF(verbose)
X if (buf[1] && buf[1] != '&')
X fputs("\tSwitched",stdout);
X#endif
X }
X else {
X putchar('\t');
X save_article();
X#ifdef VERBOSE
X IF(verbose)
X ;
X ELSE
X#endif
X putchar('\n') FLUSH;
X }
X }
X else {
X printf("\t???%s\n",cmdlst);
X return -1;
X }
X#ifdef VERBOSE
X fflush(stdout);
X#endif
X if (one_command)
X break;
X }
X if (toplevel) {
X#ifdef VERBOSE
X IF(verbose)
X putchar('\n') FLUSH;
X#endif
X }
X if( int_count ) {
X int_count = 0;
X return -1;
X }
X return 0;
X}
SHAR_EOF
chmod 0660 ngstuff.c || echo "restore of ngstuff.c fails"
echo "x - extracting ngstuff.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > ngstuff.h &&
X/* $Header: ngstuff.h,v 4.3.3.1 90/06/20 22:39:07 davison Trn $
X *
X * $Log: ngstuff.h,v $
X * Revision 4.3.3.1 90/06/20 22:39:07 davison
X * Initial Trn Release
X *
X * Revision 4.3 85/05/01 11:45:12 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#define NN_NORM 0
X#define NN_INP 1
X#define NN_REREAD 2
X#define NN_ASK 3
X
XEXT bool one_command INIT(FALSE); /* no ':' processing in perform() */
X
Xvoid ngstuff_init();
Xint escapade();
Xint switcheroo();
Xint numnum();
Xint perform();
SHAR_EOF
chmod 0660 ngstuff.h || echo "restore of ngstuff.h fails"
echo "x - extracting norm.saver.SH (Text)"
sed 's/^X//' << 'SHAR_EOF' > norm.saver.SH &&
Xcase $CONFIG in
X '') . ./config.sh ;;
Xesac
Xecho "Extracting norm.saver (with variable substitutions)"
X$spitshell >norm.saver <<!GROK!THIS!
X$startsh
X# $Header: norm.saver.SH,v 4.3.2.1 89/11/28 00:08:01 sob Locked $
X#
X# $Log: norm.saver.SH,v $
X# Revision 4.3.2.1 89/11/28 00:08:01 sob
X# Branch for RN/RRN combo.
X#
X# Revision 4.3.1.2 85/05/20 15:56:24 lwall
X# Turned $5 into \$5.
X#
X# Revision 4.3.1.1 85/05/10 11:36:52 lwall
X# Branch for patches.
X#
X# Revision 4.3 85/05/01 11:45:16 lwall
X# Baseline for release with 4.3bsd.
X#
X#
X# Arguments:
X# 1 Full name of article (%A)
X# 2 Public news spool directory (%P)
X# 3 Directory of current newsgroup (%c)
X# 4 Article number (%a)
X# 5 Where in article to start (%B)
X# 6 Newsgroup name (%C)
X# 7 Save destination (%b)
X#
Xexport PATH || (echo "OOPS, this isn't sh. Desperation time. I will feed myself to sh."; sh \$0; kill \$\$)
X
X( case "\$5" in
X 0) $echo "Article \$4 of \$6:" ;;
X esac
X $tail +\$5c \$1
X $echo ""
X $echo "" ) >> \$7
X!GROK!THIS!
X$eunicefix norm.saver
Xchmod 755 norm.saver
SHAR_EOF
chmod 0770 norm.saver.SH || echo "restore of norm.saver.SH fails"
echo "x - extracting only.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > only.c &&
X/* $Header: only.c,v 4.3.3.1 90/06/20 22:39:13 davison Trn $
X *
X * $Log: only.c,v $
X * Revision 4.3.3.1 90/06/20 22:39:13 davison
X * Initial Trn Release
X *
X * Revision 4.3 85/05/01 11:45:21 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "search.h"
X#include "util.h"
X#include "final.h"
X#include "ngsrch.h"
X#include "INTERN.h"
X#include "only.h"
X
Xvoid
Xonly_init()
X{
X ;
X}
X
Xvoid
Xsetngtodo(pat)
Xchar *pat;
X{
X char *s;
X
X#ifdef ONLY
X if (!*pat)
X return;
X if (maxngtodo < NGMAX) {
X ngtodo[maxngtodo] = savestr(pat);
X#ifdef SPEEDOVERMEM
X#ifndef lint
X compextodo[maxngtodo] = (COMPEX*)safemalloc(sizeof(COMPEX));
X#endif /* lint */
X init_compex(compextodo[maxngtodo]);
X compile(compextodo[maxngtodo],pat,TRUE,TRUE);
X if ((s = ng_comp(compextodo[maxngtodo],pat,TRUE,TRUE)) != Nullch) {
X /* compile regular expression */
X printf("\n%s\n",s) FLUSH;
X finalize(1);
X }
X#endif
X maxngtodo++;
X }
X#else
X notincl("o");
X#endif
X}
X
X/* if command line list is non-null, is this newsgroup wanted? */
X
Xbool
Xinlist(ngnam)
Xchar *ngnam;
X{
X#ifdef ONLY
X register int i;
X#ifdef SPEEDOVERMEM
X
X if (maxngtodo == 0)
X return TRUE;
X for (i=0; i<maxngtodo; i++) {
X if (execute(compextodo[i],ngnam))
X return TRUE;
X }
X return FALSE;
X#else
X COMPEX ilcompex;
X char *s;
X
X if (maxngtodo == 0)
X return TRUE;
X init_compex(&ilcompex);
X for (i=0; i<maxngtodo; i++) {
X if ((s = ng_comp(&ilcompex,ngtodo[i],TRUE,TRUE)) != Nullch) {
X /* compile regular expression */
X printf("\n%s\n",s) FLUSH;
X finalize(1);
X }
X
X if (execute(&ilcompex,ngnam) != Nullch) {
X free_compex(&ilcompex);
X return TRUE;
X }
X }
X free_compex(&ilcompex);
X return FALSE;
X#endif
X#else
X return TRUE;
X#endif
X}
X
X#ifdef ONLY
Xvoid
Xend_only()
X{
X if (maxngtodo) { /* did they specify newsgroup(s) */
X int whicharg;
X
X#ifdef VERBOSE
X IF(verbose)
X printf("\nRestriction %s%s removed.\n",ngtodo[0],
X maxngtodo > 1 ? ", etc." : nullstr) FLUSH;
X ELSE
X#endif
X#ifdef TERSE
X fputs("\nExiting \"only\".\n",stdout) FLUSH;
X#endif
X for (whicharg = 0; whicharg < maxngtodo; whicharg++) {
X free(ngtodo[whicharg]);
X#ifdef SPEEDOVERMEM
X free_compex(compextodo[whicharg]);
X#ifndef lint
X free((char*)compextodo[whicharg]);
X#endif /* lint */
X#endif
X }
X maxngtodo = 0;
X }
X}
X#endif
SHAR_EOF
chmod 0660 only.c || echo "restore of only.c fails"
echo "x - extracting only.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > only.h &&
X/* $Header: only.h,v 4.3 85/05/01 11:45:27 lwall Exp $
X *
X * $Log: only.h,v $
X * Revision 4.3 85/05/01 11:45:27 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#ifndef NBRA
X#include "search.h"
X#endif
X
X#ifdef ONLY
X EXT char *ngtodo[NGMAX]; /* restrictions in effect */
X# ifdef SPEEDOVERMEM
X EXT COMPEX *compextodo[NGMAX]; /* restrictions in compiled form */
X# endif
X#endif
X
XEXT int maxngtodo INIT(0); /* 0 => no restrictions */
X /* >0 => # of entries in ngtodo */
X
Xvoid only_init();
Xbool inlist(); /* return TRUE if ngname is in command line list */
X /* or if there was no list */
Xvoid setngtodo();
X#ifdef ONLY
X void end_only();
X#endif
SHAR_EOF
chmod 0660 only.h || echo "restore of only.h fails"
echo "x - extracting rcln.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > rcln.c &&
X/* $Header: rcln.c,v 4.3.3.1 90/06/20 22:39:19 davison Trn $
X *
X * $Log: rcln.c,v $
X * Revision 4.3.3.1 90/06/20 22:39:19 davison
X * Initial Trn Release
X *
X * Revision 4.3.2.1 90/04/23 00:22:22 sob
X * Changed atoi to atol and fixed RCS information.
X *
X * Revision 4.3.1.2 85/07/23 17:39:08 lwall
X * Oops, was freeing a static buf on -c in checkexpired.
X *
X * Revision 4.3.1.1 85/05/10 11:37:08 lwall
X * Branch for patches.
X *
X * Revision 4.3 85/05/01 11:45:36 lwall
X * Baseline for release with 4.3bsd.
X *
X */
X
X#include "EXTERN.h"
X#include "common.h"
X#include "util.h"
X#include "rcstuff.h"
X#include "ngdata.h"
X#include "INTERN.h"
X#include "rcln.h"
X
Xvoid
Xrcln_init()
X{
X ;
X}
X
X#ifdef CATCHUP
Xvoid
Xcatch_up(ngx)
XNG_NUM ngx;
X{
X char tmpbuf[128];
X char *tmpp;
SHAR_EOF
echo "End of part 10"
echo "File rcln.c is continued in part 11"
echo "11" > s2_seq_.tmp
exit 0
exit 0 # Just in case...
--
Please send comp.sources.unix-related mail to rsalz at uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.
More information about the Comp.sources.unix
mailing list