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