Article 2694 of comp.sources.unix:
Path: nntpd.lkg.dec.com!crl.dec.com!crl.dec.com!bloom-beacon.mit.edu!spool.mu.edu!howland.reston.ans.net!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: v29i048: trn-3.6 - threaded newsreader based on RN, V3.6, Part11/14
Date: 29 Oct 1995 01:33:02 -0800
Organization: Vixie Enterprises
Lines: 3045
Sender: vixie@vix.com
Approved: vixie@gw.home.vix.com
Message-ID: <46vhoe$t5b@gw.home.vix.com>
References: <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 48
Archive-Name: trn-3.6/part11

#!/bin/sh
# This is `part11' (part 11 of a multipart archive).
# Do not concatenate these parts, unpack them in order with `/bin/sh'.
# File `trn-3.6/uudecode.c' is being continued...
#
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 'Please unpack part 1 first!'
  exit 1
fi
shar_sequence=`cat _sharseq.tmp`
if test "$shar_sequence" != 11; then
  echo "Please unpack part $shar_sequence next!"
  exit 1
fi
if test ! -f _sharnew.tmp; then
  echo 'x - still skipping trn-3.6/uudecode.c'
else
  echo 'x - continuing file trn-3.6/uudecode.c'
  sed 's/^X//' << 'SHAR_EOF' >> 'trn-3.6/uudecode.c' &&
X}
X
X
X
X/*
X * Install the table in memory for later use.
X */
Xstatic void
Xinittbls()
X{
X    register int i, j;
X
X    /*
X     * Set up the default translation table.
X     */
X    for (i = 0; i < ' '; i++)
X	chtbl[i] = -1;
X    for (i = ' ', j = 0; i < ' ' + 64; i++, j++)
X	chtbl[i] = j;
X    for (i = ' ' + 64; i < MAXCHAR; i++)
X	chtbl[i] = -1;
X    chtbl['`'] = chtbl[' '];	/* common mutation */
X    chtbl['~'] = chtbl['^'];	/* another common mutation */
X    blank = ' ';
X    /*
X     * set up the line length table, to avoid computing lotsa * and / ...
X     */
X    cdlen[0] = 1;
X    for (i = 1, j = 5; i <= NORMLEN; i += 3, j += 4)
X	cdlen[i] = (cdlen[i + 1] = (cdlen[i + 2] = j));
X}
X
Xstatic void
Xgettable(in)
XFILE *in;
X{
X    char buff[LBUFLEN];
X    register int c, n = 0;
X    register char *cpt;
X
X    for (c = 0; c < MAXCHAR; c++)
X	chtbl[c] = -1;
X
X    for (;;) {
X	if (fgets(buff, sizeof buff, in) == Nullch) {
X	    printf("EOF while in translation table.\n");
X	    return;
X	}
X	numl++;
X	if (strnEQ(buff, "begin", 5)) {
X	    printf("Incomplete translation table.\n");
X	    return;
X	}
X	cpt = buff + strlen(buff) - 1;
X	*cpt = ' ';
X	while (*cpt == ' ') {
X	    *cpt = 0;
X	    cpt--;
X	}
X	cpt = buff;
X	while (c = *cpt) {
X	    if (chtbl[c] != -1) {
X		printf("Duplicate char in translation table.\n");
X		return;
X	    }
X	    if (n == 0)
X		blank = c;
X	    chtbl[c] = n++;
X	    if (n >= 64)
X		return;
X	    cpt++;
X	}
X    }
X}
X
SHAR_EOF
  echo 'File trn-3.6/uudecode.c is complete' &&
  $shar_touch -am 0410010094 'trn-3.6/uudecode.c' &&
  chmod 0644 'trn-3.6/uudecode.c' ||
  echo 'restore of trn-3.6/uudecode.c failed'
  shar_count="`wc -c < 'trn-3.6/uudecode.c'`"
  test 9603 -eq "$shar_count" ||
    echo "trn-3.6/uudecode.c: original size 9603, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/config.h.SH ==============
if test -f 'trn-3.6/config.h.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/config.h.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/config.h.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/config.h.SH' &&
Xcase $CONFIG in
X'') . ./config.sh ;;
Xesac
Xecho "Extracting config.h (with variable substitutions)"
Xsed <<!GROK!THIS! >config.h -e 's!^#undef\(.*\)/\*!/\*#define\1\*//\*!'
X/*
X * This file was produced by running the config.h.SH script, which
X * gets its values from config.sh, which is generally produced by
X * running Configure.
X *
X * Feel free to modify any of this as the need arises.  Note, however,
X * that running config.h.SH again will wipe out any changes you've made.
X * For a more permanent change edit config.sh and rerun config.h.SH.
X *
X * \$Id: Config_h.U,v 3.0.1.2 1993/08/24 12:13:20 ram Exp $
X */
X
X/* Configuration time: $cf_time
X * Configured by: $cf_by
X * Target system: $myuname
X */
X
X#ifndef _config_h_
X#define _config_h_
X
X/* EUNICE:
X *	This symbol, if defined, indicates that the program is being compiled
X *	under the EUNICE package under VMS.  The program will need to handle
X *	things like files that don't go away the first time you unlink them,
X *	due to version numbering.  It will also need to compensate for lack
X *	of a respectable link() command.
X */
X/* VMS:
X *	This symbol, if defined, indicates that the program is running under
X *	VMS.  It is currently only set in conjunction with the EUNICE symbol.
X */
X#$d_eunice EUNICE		/**/
X#$d_eunice VMS		/**/
X
X/* HAS_GETPWENT:
X *	This symbol, if defined, indicates that the getpwent() routine
X *	should be used instead of the getpw() routine.
X */
X#$d_getpwent HAS_GETPWENT	/**/
X
X/* HAS_TERMLIB:
X *	This symbol, when defined, indicates that termlib-style routines
X *	are available.  There is nothing to include.
X */
X#$d_havetlib	HAS_TERMLIB	/**/
X
X/* INTERNET:
X *	This symbol, if defined, indicates that there is a mailer available
X *	which supports internet-style addresses (user@site.domain).
X */
X#$d_internet	INTERNET	/**/
X
X/* HAS_MEMCMP:
X *	This symbol, if defined, indicates that the memcmp routine is available
X *	to compare blocks of memory.
X */
X#$d_memcmp HAS_MEMCMP	/**/
X
X/* HAS_MEMCPY:
X *	This symbol, if defined, indicates that the memcpy routine is available
X *	to copy blocks of memory.
X */
X#$d_memcpy HAS_MEMCPY	/**/
X
X/* HAS_MEMSET:
X *	This symbol, if defined, indicates that the memset routine is available
X *	to set blocks of memory.
X */
X#$d_memset HAS_MEMSET	/**/
X
X/* NEWS_ADMIN:
X *	This symbol, if defined, contains the login name of the news
X *	administrator.
X */
X#$d_newsadm NEWS_ADMIN "$newsadmin"		/**/
X
X/* NOLINEBUF:
X *	This symbol, if defined, indicates that stdout is not buffered, so that
X *	the program can call setbuf() or setlinebuf() for efficiency.
X */
X#$d_nolnbuf	NOLINEBUF	/**/
X
X/* NORMSIG:
X *	This symbol, if defined, indicates that normal signal handling routines
X *	should be used, as opposed to the ones in 4.1bsd (sigset, etc.).
X */
X#$d_normsig NORMSIG		/**/
X
X/* HAS_RDCHK:
X *	This symbol, if defined, indicates that the rdchk routine is available
X *	to find out if there is input pending on an IO channel.  Generally
X *	the routine is used only if FIONREAD and O_NDELAY aren't available.
X */
X#$d_rdchk HAS_RDCHK		/**/
X
X/* HAS_RENAME:
X *	This symbol, if defined, indicates that the rename routine is available
X *	to rename files.  Otherwise you should do the unlink(), link(), unlink()
X *	trick.
X */
X#$d_rename HAS_RENAME	/**/
X
X/* HAS_SIGBLOCK:
X *	This symbol, if defined, indicates that the sigblock routine is
X *	available to block signal reception.
X */
X#$d_sigblock HAS_SIGBLOCK	/**/
X
X/* HAS_SIGHOLD:
X *	This symbol, if defined, indicates that the sighold routine is
X *	available to hold signals.
X */
X#$d_sighold HAS_SIGHOLD	/**/
X
X/* HAS_STRCASECMP:
X *	This symbol, if defined, indicates that the strcasecmp() routine is
X *	available for case-insensitive string compares.
X */
X#$d_strccmp HAS_STRCASECMP	/**/
X
X/* HAS_VFORK:
X *	This symbol, if defined, indicates that vfork() exists.
X */
X#$d_vfork HAS_VFORK	/**/
X
X/* Signal_t:
X *	This symbol's value is either "void" or "int", corresponding to the
X *	appropriate return type of a signal handler.  Thus, you can declare
X *	a signal handler using "Signal_t (*handler)()", and define the
X *	handler using "Signal_t handler(sig)".
X */
X#define Signal_t $signal_t	/* Signal handler's return type */
X
X/* DEFEDITOR:
X *	This symbol contains the full pathname of the default editor.
X */
X#define DEFEDITOR "$defeditor"		/**/
X
X/* I_DIRENT:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <dirent.h>. Using this symbol also triggers the definition
X *	of the Direntry_t define which ends up being 'struct dirent' or
X *	'struct direct' depending on the availability of <dirent.h>.
X */
X#$i_dirent I_DIRENT		/**/
X#ifdef I_DIRENT
X#define Direntry_t struct dirent
X#else
X#define Direntry_t struct direct
X#endif
X
X/* I_STDLIB:
X *	This symbol, if defined, indicates that <stdlib.h> exists and should
X *	be included.
X */
X#$i_stdlib I_STDLIB		/**/
X
X/* I_STRING:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <string.h> (USG systems) instead of <strings.h> (BSD systems).
X */
X#$i_string I_STRING		/**/
X
X/* I_SYS_DIR:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <sys/dir.h>.
X */
X#$i_sysdir I_SYS_DIR		/**/
X
X/* I_SYS_IOCTL:
X *	This symbol, if defined, indicates that <sys/ioctl.h> exists and should
X *	be included. Otherwise, include <sgtty.h> or <termio.h>.
X */
X/* I_SYS_FILIO:
X *	This symbol, if defined, indicates that <sys/filio.h> exists and
X *	should be included instead of <sys/ioctl.h>.
X */
X#$i_sysioctl	I_SYS_IOCTL		/**/
X#$i_sysfilio	I_SYS_FILIO		/**/
X
X/* I_SYS_NDIR:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <sys/ndir.h>.
X */
X#$i_sysndir I_SYS_NDIR	/**/
X
X/* I_TERMIO:
X *	This symbol, if defined, indicates that the program should include
X *	<termio.h> rather than <sgtty.h>.  There are also differences in
X *	the ioctl() calls that depend on the value of this symbol.
X */
X/* I_TERMIOS:
X *	This symbol, if defined, indicates that the program should include
X *	the POSIX termios.h rather than sgtty.h or termio.h.
X *	There are also differences in the ioctl() calls that depend on the
X *	value of this symbol.
X */
X/* I_SGTTY:
X *	This symbol, if defined, indicates that the program should include
X *	<sgtty.h> rather than <termio.h>.  There are also differences in
X *	the ioctl() calls that depend on the value of this symbol.
X */
X#$i_termio I_TERMIO		/**/
X#$i_termios I_TERMIOS		/**/
X#$i_sgtty I_SGTTY		/**/
X
X/* I_UNISTD:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <unistd.h>.
X */
X#$i_unistd I_UNISTD		/**/
X
X/* I_VFORK:
X *	This symbol, if defined, indicates to the C program that it should
X *	include vfork.h.
X */
X#$i_vfork I_VFORK	/**/
X
X/* MAILFILE:
X *	This symbol contains the interpretable name of the mail spool file
X *	for the current user.  The program must be prepared to substitute
X *	the HOME directory for %~, and the login id for %L.
X */
X#define MAILFILE "$mailfile"		/**/
X
X/* MBOXCHAR:
X *	This symbol contains a character which will match the beginning
X *	of a mailbox file.
X */
X#define MBOXCHAR '$mboxchar'		/**/
X
X/* PASSNAMES:
X *	This symbol, if defined, indicates that full names are stored in
X *	the /etc/passwd file.
X */
X/* BERKNAMES:
X *	This symbol, if defined, indicates that full names are stored in
X *	the /etc/passwd file in Berkeley format (name first thing, everything
X *	up to first comma, with & replaced by capitalized login id, yuck).
X */
X#$d_passnames PASSNAMES /*  (undef to take name from ~/.fullname) */
X#$d_berknames BERKNAMES /* (that is, ":name,stuff:") */
X
X/* ORGNAME:
X *	This symbol contains either the organizaton name or the full pathname
X *	of a file containing the organization name, which the program must
X *	be prepared to open and substitute the contents of.
X */
X#define ORGNAME "$orgname"		/**/
X
X/* PREFSHELL:
X *	This symbol contains the full name of the preferred user shell on this
X *	system.  Usual values are /bin/csh, /bin/ksh, /bin/sh.
X */
X#define PREFSHELL "$prefshell"		/**/
X
X/* ROOTID:
X *	This symbol contains the uid of root, normally 0.
X */
X#define ROOTID $rootid		/**/
X
X/* ACTIVE:
X *	The name of the active file for the news system.  This file contains
X *	the list of active newsgroups.  The name may have ~ on the front.
X */
X/* ACTIVE_TIMES:
X *	The name of the active.times file for the news system.
X */
X#define ACTIVE "$active"		/**/
X#$d_acttimes ACTIVE_TIMES "$acttimes"		/**/
X
X/* HAS_FTIME:
X *	This symbol, if defined, indicates that the ftime() routine exists.
X *	It is basically a sub-second accuracy clock, but is less accurate
X *	than gettimeofday(2) anyway. The type "Timeval" should be used to
X *	refer to "struct timeb".
X */
X#$d_ftime HAS_FTIME		/**/
X
X/* HAS_GETHOSTNAME:
X *	This symbol, if defined, indicates that the C program may use the
X *	gethostname() routine to derive the host name.  See also HAS_UNAME
X *	and PHOSTCMD.
X */
X/* HAS_UNAME:
X *	This symbol, if defined, indicates that the C program may use the
X *	uname() routine to derive the host name.  See also HAS_GETHOSTNAME
X *	and PHOSTCMD.
X */
X/* PHOSTCMD:
X *	This symbol, if defined, indicates that the C program may use the
X *	contents of PHOSTCMD as a command to feed to the popen() routine
X *	to derive the host name.  See also HAS_GETHOSTNAME and HAS_UNAME.
X *	Note that the command uses a fully qualified path, so that it is safe
X *	even if used by a process with super-user privileges.
X */
X#$d_gethname HAS_GETHOSTNAME	/**/
X#$d_uname HAS_UNAME		/**/
X#$d_phostcmd PHOSTCMD "$aphostcmd"	/* How to get the host name */
X
X/* HAS_GETWD:
X *	This symbol, if defined, indicates that the getwd routine is
X *	available to get the working directory.
X */
X/* HAS_GETCWD:
X *	This symbol, if defined, indicates that the getcwd routine is
X *	available.  This is never defined if getwd is found first.
X */
X#$d_getwd HAS_GETWD		/**/
X#$d_getcwd HAS_GETCWD		/**/
X
X/* IGNOREORG:
X *	This symbol, if defined, indicates that the ORGANIZATION environment
X *	variable does not contain an organization name.
X */
X#$d_ignoreorg IGNOREORG		/**/
X
X/* MIMESHOW:
X *	This symbol points to the program to run to show a mime article.
X */
X/* MIMESTORE:
X *	This symbol points to the program to run to store a mime article.
X */
X#$d_mimeshow MIMESHOW "$mimeshow"	/**/
X#$d_mimestore MIMESTORE "$mimestore"	/**/
X
X/* USE_NNTP:
X *	This symbol, if defined, indicates that NNTP should be used.
X */
X/* USE_GENAUTH:
X *	This symbol, if defined, indicates that authinfo generic
X *	authentication is to be supported.
X */
X/* SERVER_NAME:
X *	When using NNTP, this symbol indicates the server name or a
X *	file to open to read the server name.
X */
X/* USE_XTHREAD:
X *	This symbol, if defined, indicates that .thread files can be
X *	gotten via NNTP.  It is never defined if USE_NNTP is undefined.
X */
X/* USE_XOVER:
X *	This symbol, if defined, indicates that .overview files can be
X *	gotten via NNTP.  It is never defined if USE_NNTP is undefined.
X */
X#$d_nntp USE_NNTP	/**/
X#$d_genauth USE_GENAUTH	/**/
X#define SERVER_NAME "$servername"  	/**/
X#$d_xdata USE_XTHREAD  	/**/
X#$d_xdata USE_XOVER	/**/
X
X/* void:
X *	This symbol is used for void functions.  On implementations which
X *	support void appropriately, its value is "void".  Otherwise, its
X *	value should be set to "int".
X */
X#$d_novoid void int	/**/
X
X/* size_t:
X *	This symbol is defined as an int if no size_t definition exists.
X */
X#$d_sizet	size_t int		/**/
X
X/* HAS_STRCHR:
X *	This symbol is defined to indicate that the strchr()/strrchr()
X *	functions are available for string searching. If not, try the
X *	index()/rindex() pair.
X */
X#$d_strchr HAS_STRCHR	/**/
X
X/* HAS_STRFTIME:
X *	This symbol, if defined, indicates that the strftime routine is
X *	available to format locale-specific times.
X */
X#$d_strftime	HAS_STRFTIME		/**/
X
X/* EMULATE_NDIR:
X *	This symbol, if defined, indicates that the program should compile
X *	the ndir.c code provided with the package.
X */
X/* I_NDIR:
X *	This symbol, if defined, indicates that the program should include the
X *	system's version of ndir.h, rather than the one with this package.
X */
X#$d_usendir	EMULATE_NDIR		/**/
X#$d_libndir	I_NDIR		/**/
X
X/* I_PTEM:
X *	This symbol, if defined, indicates to the C program that it should
X *	include ptem.h.
X */
X#$i_ptem I_PTEM		/**/
X
X/* I_TIME:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <time.h>.
X */
X/* I_SYS_TIME:
X *	This symbol, if defined, indicates to the C program that it should
X *	include <sys/time.h>.
X */
X#$i_time I_TIME		/**/
X#$i_systime I_SYS_TIME		/**/
X
X/* NEWSLIB:
X *	This symbol contains the name of the directory serving as the news
X *	library.  The program must be prepared to do ~ expansion on it.
X */
X#define NEWSLIB "$newslib"		/**/
X
X/* NEWSSPOOL:
X *	This symbol contains the directory name where news articles are
X *	spooled.  The program must be prepared to do ~ expansion on it.
X */
X#define NEWSSPOOL "$newsspool"		/**/
X
X/* PHOSTNAME:
X *	This symbol contains the posting host's name or a file from which
X *	to read its name.
X */
X#define PHOSTNAME "$phost"		/**/
X
X/* PRIVLIB:
X *	This symbol contains the name of the private library for this package.
X *	The library is private in the sense that it needn't be in anyone's
X *	execution path, but it should be accessible by the world.  The program
X *	should be prepared to do ~ expansion.
X */
X#define PRIVLIB "$privlib"		/**/
X
X/* THREAD_DIR:
X *	This symbol indicates where the thread files go.
X */
X/* OVERVIEW_DIR:
X *	This symbol indicates where the overview files go.
X */
X/* USE_MT:
X *	This symbol indicates if thread file support is desired.
X */
X/* USE_OV:
X *	This symbol indicates if overview file support is desired.
X */
X#define THREAD_DIR	"$threaddir"		/**/
X#define OVERVIEW_DIR	"$overviewdir"		/**/
X#$d_usemt USE_MT		/**/
X#$d_useov USE_OV		/**/
X
X/* THREAD_INIT:
X *	This symbol indicates we act like trn no matter what our name is.
X */
X/* SELECT_INIT:
X *	This symbol indicates we default to the selector for group entry.
X */
X#define THREAD_INIT	$trn_init
X#define SELECT_INIT	$trn_select
X
X/*#define LONG_THREAD_NAMES	*//**/
X
X#define CANCEL	"$inewsloc -h <%h"
X#define SPEED_OVER_MEM	/* use more memory to run faster */
X/*#define ANCIENT_NEWS	*//* if your B news system is <= 2.10.1 */
X
X#endif
X!GROK!THIS!
SHAR_EOF
  $shar_touch -am 1028161994 'trn-3.6/config.h.SH' &&
  chmod 0644 'trn-3.6/config.h.SH' ||
  echo 'restore of trn-3.6/config.h.SH failed'
  shar_count="`wc -c < 'trn-3.6/config.h.SH'`"
  test 14153 -eq "$shar_count" ||
    echo "trn-3.6/config.h.SH: original size 14153, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/Rnmail.SH ==============
if test -f 'trn-3.6/Rnmail.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/Rnmail.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/Rnmail.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/Rnmail.SH' &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting Rnmail (with variable substitutions)"
X$spitshell >Rnmail <<!GROK!THIS!
X$startsh
X# $Id: Rnmail.SH,v 3.0 1992/02/23 21:25:39 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 author 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# syntax: Rnmail -h headerfile [oldart]		or
X#         Rnmail destination-list 		or just
X#         Rnmail
X
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X# System dependencies
X
Xmailer="\${RNMAILER-${mailer-/bin/mail}}"
X# if you change this to something that does signatures, take out signature code
X
X# your organization name
Xorgname="$orgname"
X# what pager you use--if you have kernal paging use cat
Xpager="\${PAGER-$pager}"
X# how you derive full names, bsd, usg, or other
Xnametype="$nametype"
X# default editor
Xdefeditor="$defeditor"
X# where the non-publics are
Xcase $d_portable in
Xdefine)  rnlib=\`$filexp $privlib\` ;;
Xundef)   rnlib="$privlib" ;;
Xesac
X# how not to do a newline with echo
Xn="$n"
Xc="$c"
X
Xtest=${test-test}
Xsed=${sed-sed}
Xecho=${echo-echo}
Xcat=${cat-cat}
Xgrep=${grep-grep}
Xrm=${rm-rm}
Xsleep=${sleep-sleep}
Xwho=${who-who}
X
X!GROK!THIS!
Xcase "$d_ignoreorg" in
Xdefine) $spitshell >>Rnmail <<'!NO!SUBS!'
Xorgname=${NEWSORG-$orgname}
X!NO!SUBS!
X	;;
X*)	$spitshell >>Rnmail <<'!NO!SUBS!'
Xorgname=${NEWSORG-${ORGANIZATION-$orgname}}
X!NO!SUBS!
X	;;
Xesac
X$spitshell >>Rnmail <<'!NO!SUBS!'
Xdotdir=${DOTDIR-${HOME-$LOGDIR}}
Xtmpart=$dotdir/.letter
Xspeller=$rnlib/Speller
Xmail_sig=${MAILSIGNATURE-$dotdir/.mail_sig}
X
Xheaderfile=""
Xcase $# in
X0) ;;
X*)  case $1 in
X    -h)
X	headerfile="$2"
X	case $# in
X	3) oldart=$3 ;;
X	esac
X	;;
X    esac
X    ;;
Xesac
X
Xcase $headerfile in
X'')
X    case $# in
X    0)
X	to=h
X	while $test "X$to" = Xh ; do
X	    $echo ""
X	    $echo $n "To: $c"
X	    read to
X	    case $to in
X	    h)
X		$cat <<'EOH'
X
XType the net address of those people to whom you wish the message sent.
XAdditional recipients may be added on the Cc: line when you edit.
X
XSeparate multiple addresses with spaces.
X
XEOH
X		;;
X	    esac
X	done
X	;;
X    *)
X	to="$*"
X	;;
X    esac
X    to=`$echo "$to" | $sed 's/  */ /g'`
X
X    title=h
X    while $test "X$title" = Xh ; do
X	$echo ""
X	$echo $n "Title/Subject: $c"
X	read title
X	case $title in
X	h)
X	    $cat <<'EOH'
X
XType the title for your message.  
XEOH
X	    ;;
X	esac
X    done
X
X# now build a file with a header for them to edit
X    
X    case $orgname in
X    /*) orgname=`$cat $orgname` ;;
X    esac
X
X    $sed -e '/^Reply-To: $/d' > $tmpart <<EOHeader
XTo: $to
XSubject: $title
XOrganization: $orgname
XReply-To: $REPLYTO
XCc:
XBcc:
X
XEOHeader
X
X    ;;
X*)
X    $cat < $headerfile  > $tmpart
X    ;;
Xesac
X
X
Xfile=h
Xwhile $test X$file = Xh ; do
X    $echo ""
X    $echo $n "Prepared file to include [none]: $c"
X    read file
X    case $file in
X    h)
X	$cat <<'EOH'
X
XIf you have already produced the body of your message, type the filename
Xfor it here.  If you just want to proceed directly to the editor, type a
XRETURN.  In any event, you will be allowed to edit as many times as you
Xwant before you send off the message.
XEOH
X	;;
X    '')
X	$echo "" >> $tmpart
X	state=edit
X	;;
X    *)
X	$cat $file >>$tmpart
X	state=ask
X	;;
X    esac
Xdone
X
X$echo ""
X
Xif $test -r $mail_sig; then
X    $echo "-- " >> $tmpart
X    $cat $mail_sig >> $tmpart
Xfi
X
Xwhile : ; do
X    case $state in
X    edit)
X	rescue="$sleep 1; $cat $tmpart >>${HOME-$LOGDIR}/dead.letter ; $echo Message appended to ${HOME-$LOGDIR}/dead.letter ; exit"
X	trap "$rescue" 1
X	trap : 2
X	case "${VISUAL-${EDITOR-}}" in
X	'')
X	    tmp=h
X	    ;;
X	*)
X	    tmp=''
X	    ;;
X	esac
X	while $test "X$tmp" = Xh ; do
X	    $echo $n "Editor [${VISUAL-${EDITOR-$defeditor}}]: $c"
X	    read tmp
X	    case $tmp in
X	    h)
X		$cat <<'EOH'
X
XType a return to get the default editor, or type the name of the editor you
Xprefer.  The default editor depends on the VISUAL and EDITOR environment
Xvariables.
X
XEOH
X		;;
X	    '')
X		;;
X	    *)
X		VISUAL=$tmp
X		export VISUAL
X		;;
X	    esac
X	done
X	${VISUAL-${EDITOR-$defeditor}} $tmpart $oldart
X	trap "$rescue" 2
X	state=ask
X	;;
X	
X    ask)
X	$echo ""
X	$echo $n "Check spelling, Send, Abort, Edit, or List? $c"
X	read ans
X
X	case $ans in
X	[aA]*)
X	    state=rescue
X	    ;;
X	[eE]*)
X	    set $ans
X	    case $# in
X	    2)  VISUAL="$2" ;;
X	    esac
X	    state=edit
X	    ;;
X	[lL]*)
X	    $pager $tmpart
X	    state=ask
X	    ;;
X	[cC]*|[sS][pP]*)
X	    $speller $tmpart
X	    state=ask
X	    ;;
X	[sS]*)
X	    state=send
X	    ;;
X	[hH]*)
X	    $cat <<'EOH'
X
XType c to check the message's spelling, s to send the message, a to abort
Xand append the message to dead.letter, e to edit the message again, or l
Xto list the message with your pager.
X
XTo invoke an alternate editor, type 'e editor'.
XEOH
X	esac
X	;;
X    
X    send)
X	if $test -f $dotdir/.signature; then
X	    $echo $n "Append .signature file? [y] $c"
X	    read ans
X	    case $ans in
X	    ''|y*)
X		$echo "-- " >> $tmpart
X		cat $dotdir/.signature >> $tmpart
X		;;
X	    esac
X	fi
X	case $mailer in
X	*sendmail)
X	    $mailer -t <$tmpart
X	    ;;
X# but recmail does not know about Bcc, alas
X	*recmail)
X	    $mailer <$tmpart
X	    ;;
X	*)
X	    set X `$sed <$tmpart -n -e '/^To:/{' -e 's/To: *//p' -e q -e '}'`
X	    shift
X	    set X "$@" `$sed <$tmpart -n -e '/^Cc:/{' -e 's/Cc: *//p' -e q -e '}'`
X	    shift
X	    set X "$@" `$sed <$tmpart -n -e '/^Bcc:/{' -e 's/Bcc: *//p' -e q -e '}'`
X	    shift
X	    $grep -v "^Bcc:"  <$tmpart | $mailer "$@"
X	    ;;
X	esac
X	case $? in
X	0)
X	    state=cleanup
X	    ;;
X	*)
X	    state=rescue
X	    ;;
X	esac
X	;;
X    rescue)
X	$cat $tmpart >> ${HOME-$LOGDIR}/dead.letter
X	$echo "Message appended to ${HOME-$LOGDIR}/dead.letter"
X	$echo "A copy may be temporarily found in $tmpart"
X	exit
X	;;
X    cleanup)
X	case "${MAILRECORD-none}" in
X	none)
X	    ;;
X	*)
X	    set X ${USER-${LOGNAME-`$who am i`}} unknown
X	    shift
X	    $rnlib/mbox.saver $tmpart "." "." 0 0 Pnews $MAILRECORD "From $1 `LANG= date`"
X	    if $test $? -eq 0 ; then
X		$echo "Message appended to $MAILRECORD"
X	    else
X		$echo "Cannot append to $MAILRECORD"
X	    fi
X	    ;;
X	esac
X	exit
X	;;
X    esac
Xdone
X!NO!SUBS!
X$eunicefix Rnmail
Xchmod 755 Rnmail
SHAR_EOF
  $shar_touch -am 0327202394 'trn-3.6/Rnmail.SH' &&
  chmod 0644 'trn-3.6/Rnmail.SH' ||
  echo 'restore of trn-3.6/Rnmail.SH failed'
  shar_count="`wc -c < 'trn-3.6/Rnmail.SH'`"
  test 6563 -eq "$shar_count" ||
    echo "trn-3.6/Rnmail.SH: original size 6563, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/rt-page.c ==============
if test -f 'trn-3.6/rt-page.c' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/rt-page.c (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/rt-page.c (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/rt-page.c' &&
X/* $Id: rt-page.c,v 3.0 1992/12/14 00:14:12 davison Trn $
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 "term.h"
X#include "ngdata.h"
X#include "trn.h"
X#include "util.h"
X#include "rthread.h"
X#include "rt-select.h"
X#include "rt-util.h"
X#include "INTERN.h"
X#include "rt-page.h"
X
Xextern char *display_mode;
Xextern char sel_disp_char[];
X
Xbool
Xset_sel_mode(ch)
Xchar_int ch;
X{
X    switch (ch) {
X    case 'a':
X	set_selector(SM_ARTICLE, sel_artsort);
X	break;
X    case 's':
X	set_selector(SM_SUBJECT, sel_threadsort);
X	break;
X    case 't':
X	if (in_ng && !ThreadedGroup) {
X	    bool always_save = thread_always;
X	    ThreadedGroup = TRUE;
X	    thread_always = TRUE;
X	    if (sel_rereading)
X		firstart = absfirst;
X	    printf("\nThreading the group. "), fflush(stdout);
X	    thread_open();
X	    thread_always = always_save;
X	    if (last_cached < lastart)
X		ThreadedGroup = FALSE;
X	}
X	/* FALL THROUGH */
X    case 'T':
X	set_selector(SM_THREAD, sel_threadsort);
X	break;
X    default:
X	return FALSE;
X    }
X    return TRUE;
X}
X
Xbool
Xset_sel_sort(ch)
Xchar_int ch;
X{
X    if (isupper(ch)) {
X	sel_direction = -1;
X	ch = tolower(ch);
X    } else
X	sel_direction = 1;
X    switch (ch) {
X    case 'd':
X	sel_sort = SS_DATE;
X	break;
X    case 's':
X	sel_sort = SS_SUBJECT;
X	break;
X    case 'a':
X	sel_sort = SS_AUTHOR;
X	break;
X    case 'c':
X	sel_sort = SS_COUNT;
X	break;
X    case 'n':
X	sel_sort = SS_NUMBER;
X	break;
X    case 'g':
X	sel_sort = SS_GROUPS;
X	break;
X    default:
X	return FALSE;
X    }
X    if (sel_mode == SM_ARTICLE)
X	set_selector(sel_mode, sel_sort);
X    else
X	set_selector(sel_threadmode, sel_sort);
X    return TRUE;
X}
X
Xvoid
Xset_selector(smode, ssort)
Xint smode;
Xint ssort;
X{
X    sel_mode = smode;
X    sel_sort = ssort;
X
X    if (!ThreadedGroup && sel_mode == SM_THREAD)
X	sel_mode = SM_SUBJECT;
X
X    if (sel_mode == SM_ARTICLE) {
X	if (sel_sort == SS_COUNT)
X	    sel_sort = SS_DATE;
X    } else if (sel_sort == SS_AUTHOR || sel_sort == SS_GROUPS
X	    || sel_sort == SS_NUMBER)
X	sel_sort = SS_DATE;
X
X    switch (sel_mode) {
X    case SM_THREAD:
X	sel_mode_string = "threads";
X	sel_threadmode = smode;
X	sel_threadsort = ssort;
X	break;
X    case SM_SUBJECT:
X	sel_mode_string = "subjects";
X	sel_threadmode = smode;
X	sel_threadsort = ssort;
X	break;
X    case SM_ARTICLE:
X	sel_mode_string = "articles";
X	sel_artsort = ssort;
X	break;
X    }
X
X    switch (sel_sort) {
X    case SS_DATE:
X	sel_sort_string = "date";
X	break;
X    case SS_SUBJECT:
X	sel_sort_string = "subject";
X	break;
X    case SS_AUTHOR:
X	sel_sort_string = "author";
X	break;
X    case SS_COUNT:
X	sel_sort_string = "count";
X	break;
X    case SS_NUMBER:
X	sel_sort_string = "number";
X	break;
X    case SS_GROUPS:
X	sel_sort_string = "SubjDate";
X	break;
X    }
X}
X
Xvoid sel_page_init()
X{
X    sel_chars = getval("SELECTCHARS", SELECTCHARS);
X    sel_max_cnt = strlen(sel_chars);
X    if (sel_max_cnt > MAX_SEL)
X	sel_max_cnt = MAX_SEL;
X    if (sel_max_cnt > LINES-5)
X	sel_max_cnt = LINES-5;
X    sel_line = 2;
X    sel_page_arts = 0;
X    sel_item_cnt = 0;
X}
X
Xvoid
Xinit_pages(fill_last_page)
Xbool_int fill_last_page;
X{
Xtry_again:
X    sel_prior_arts = sel_total_arts = 0;
X
X    if (sel_mode == SM_ARTICLE) {
X	ARTICLE *ap, **app, **limit;
X
X	if (sel_page_app) {
X	    int desired_flags = (sel_rereading? AF_READ : 0);
X	    limit = artptr_list + artptr_list_size;
X	    ap = Nullart;
X	    for (app = sel_page_app; app < limit; app++) {
X		ap = *app;
X		if ((ap->flags & (AF_MISSING|AF_READ)) == desired_flags)
X		    break;
X	    }
X	    sort_articles();
X	    if (ap == Nullart)
X		sel_page_app = artptr_list + artptr_list_size;
X	    else {
X		for (app = artptr_list; app < limit; app++) {
X		    if (*app == ap) {
X			sel_page_app = app;
X			break;
X		    }
X		}
X	    }
X	} else
X	    sort_articles();
X
X	while (sel_page_sp && sel_page_sp->misc == 0)
X	    sel_page_sp = sel_page_sp->next;
X	/* The artptr_list contains only unread or read articles, never both */
X	limit = artptr_list + artptr_list_size;
X	for (app = artptr_list; app < limit; app++) {
X	    ap = *app;
X	    if (sel_rereading && !(ap->flags & sel_mask))
X		ap->flags |= AF_DEL;
X	    if (sel_page_app == app
X	     || (!sel_page_app && ap->subj == sel_page_sp)) {
X		sel_page_app = app;
X		sel_prior_arts = sel_total_arts;
X	    }
X	    if (!sel_exclusive || (ap->flags & sel_mask)) {
X		sel_total_arts++;
X		ap->flags |= AF_INCLUDED;
X	    } else
X		ap->flags &= ~AF_INCLUDED;
X	}
X	if (sel_exclusive && !sel_total_arts) {
X	    sel_exclusive = FALSE;
X	    goto try_again;
X	}
X	if (!sel_page_app)
X	    (void) first_page();
X	else if (sel_page_app >= limit)
X	    (void) last_page();
X	else if (sel_prior_arts && fill_last_page) {
X	    sel_page_init();
X	    app = sel_page_app;
X	    do {
X		if (!((*app)->flags & AF_INCLUDED))
X		    continue;
X		sel_page_arts++;
X		sel_item_cnt++;
X	    } while (++app < limit && sel_item_cnt < sel_max_cnt);
X	    if (sel_prior_arts + sel_page_arts == sel_total_arts) {
X		(void) last_page();
X	    }
X	}
X    } else {
X	SUBJECT *sp, *group_sp;
X	int group_arts;
X
X	if (sel_page_sp) {
X	    while (sel_page_sp && sel_page_sp->misc == 0)
X		sel_page_sp = sel_page_sp->next;
X	    sort_subjects();
X	    if (!sel_page_sp)
X		sel_page_sp = last_subject;
X	} else
X	    sort_subjects();
X	for (sp = first_subject; sp; sp = sp->next) {
X	    if (sel_rereading && !(sp->flags & sel_mask))
X		sp->flags |= SF_DEL;
X
X	    group_sp = sp;
X	    group_arts = sp->misc;
X
X	    if (!sel_exclusive || (sp->flags & sel_mask))
X		sp->flags |= SF_INCLUDED;
X	    else
X		sp->flags &= ~SF_INCLUDED;
X
X	    if (sel_page_sp == group_sp)
X		sel_prior_arts = sel_total_arts;
X	    if (sel_mode == SM_THREAD) {
X		while (sp->next && sp->next->thread == sp->thread) {
X		    sp = sp->next;
X		    if (sp == sel_page_sp) {
X			sel_prior_arts = sel_total_arts;
X			sel_page_sp = group_sp;
X		    }
X		    sp->flags &= ~SF_INCLUDED;
X		    if (sp->flags & sel_mask)
X			group_sp->flags |= SF_INCLUDED;
X		    else if (sel_rereading)
X			sp->flags |= SF_DEL;
X		    group_arts += sp->misc;
X		}
X	    }
X	    if (group_sp->flags & SF_INCLUDED)
X		sel_total_arts += group_arts;
X	}
X	if (sel_exclusive && !sel_total_arts) {
X	    sel_exclusive = FALSE;
X	    goto try_again;
X	}
X	if (!sel_page_sp)
X	    (void) first_page();
X	else if (sel_page_sp == last_subject)
X	    (void) last_page();
X	else if (sel_prior_arts && fill_last_page) {
X	    int line_cnt, sel;
X	    sel_page_init();
X	    sp = sel_page_sp;
X	    do {
X		if (sp->flags & SF_INCLUDED) {
X		    if (sel_mode == SM_THREAD)
X			line_cnt = count_thread_lines(sp, &sel);
X		    else
X			line_cnt = count_subject_lines(sp, &sel);
X		    if (line_cnt) {
X			if (line_cnt > LINES - 5)
X			    line_cnt = LINES - 5;
X			if (sel_line + line_cnt > LINES - 3)
X			    break;
X			sel_page_arts += sp->misc;
X			sel_item_cnt++;
X		    }
X		} else
X		    line_cnt = 0;
X		if (sel_mode == SM_THREAD) {
X		    while (sp->next && sp->next->thread == sp->thread) {
X			sp = sp->next;
X			if (!line_cnt || !sp->misc)
X			    continue;
X			sel_page_arts += sp->misc;
X		    }
X		}
X	    } while ((sp=sp->next)!=Nullsubj && sel_item_cnt<sel_max_cnt);
X	    if (sel_prior_arts + sel_page_arts == sel_total_arts) {
X		(void) last_page();
X	    }
X	}
X    }
X}
X
Xbool
Xfirst_page()
X{
X    sel_prior_arts = 0;
X
X    if (sel_mode == SM_ARTICLE) {
X	ARTICLE **app, **limit;
X
X	limit = artptr_list + artptr_list_size;
X	for (app = artptr_list; app < limit; app++) {
X	    if ((*app)->flags & AF_INCLUDED) {
X		if (sel_page_app != app) {
X		    sel_page_app = app;
X		    return TRUE;
X		}
X		break;
X	    }
X	}
X    } else {
X	SUBJECT *sp;
X
X	for (sp = first_subject; sp; sp = sp->next) {
X	    if (sp->flags & SF_INCLUDED) {
X		if (sel_page_sp != sp) {
X		    sel_page_sp = sp;
X		    return TRUE;
X		}
X		break;
X	    }
X	}
X    }
X    return FALSE;
X}
X
Xbool
Xlast_page()
X{
X    sel_prior_arts = sel_total_arts;
X
X    if (sel_mode == SM_ARTICLE) {
X	ARTICLE **app = sel_page_app;
X	sel_page_app = artptr_list + artptr_list_size;
X	if (!prev_page())
X	    sel_page_app = app;
X	else if (app != sel_page_app)
X	    return TRUE;
X    } else {
X	SUBJECT *sp = sel_page_sp;
X	sel_page_sp = Nullsubj;
X	if (!prev_page())
X	    sel_page_sp = sp;
X	else if (sp != sel_page_sp)
X	    return TRUE;
X    }
X    return FALSE;
X}
X
Xbool
Xnext_page()
X{
X    if (sel_mode == SM_ARTICLE) {
X	if (sel_next_app < artptr_list + artptr_list_size) {
X	    sel_page_app = sel_next_app;
X	    sel_prior_arts += sel_page_arts;
X	    return TRUE;
X	}
X    } else {
X	if (sel_next_sp) {
X	    sel_page_sp = sel_next_sp;
X	    sel_prior_arts += sel_page_arts;
X	    return TRUE;
X	}
X    }
X    return FALSE;
X}
X
Xbool
Xprev_page()
X{
X    int item_cnt = 0;
X
X    /* Scan the items in reverse to go back a page */
X    if (sel_mode == SM_ARTICLE) {
X	ARTICLE *ap, **app, **page_app = sel_page_app;
X
X	for (app = sel_page_app; --app >= artptr_list; ) {
X	    ap = *app;
X	    if (ap->flags & AF_INCLUDED) {
X		page_app = app;
X		sel_prior_arts--;
X		if (++item_cnt >= sel_max_cnt)
X		    break;
X	    }
X	}
X	if (sel_page_app != page_app) {
X	    sel_page_app = page_app;
X	    return TRUE;
X	}
X    } else {
X	SUBJECT *sp, *page_sp = sel_page_sp;
X	int line_cnt, item_arts, line;
X
X	line = 2;
X	for (sp = (!page_sp? last_subject : page_sp->prev); sp; sp=sp->prev) {
X	    item_arts = sp->misc;
X	    if (sel_mode == SM_THREAD) {
X		while (sp->prev && sp->prev->thread == sp->thread) {
X		    sp = sp->prev;
X		    item_arts += sp->misc;
X		}
X		line_cnt = count_thread_lines(sp, NULL);
X	    } else
X		line_cnt = count_subject_lines(sp, NULL);
X	    if (!(sp->flags & SF_INCLUDED) || !line_cnt)
X		continue;
X	    if (line_cnt > LINES - 5)
X		line_cnt = LINES - 5;
X	    line += line_cnt;
X	    if (line > LINES - 3) {
X		sp = page_sp;
X		break;
X	    }
X	    sel_prior_arts -= item_arts;
X	    page_sp = sp;
X	    if (++item_cnt >= sel_max_cnt)
X		break;
X	}
X	if (sel_page_sp != page_sp) {
X	    sel_page_sp = (page_sp? page_sp : first_subject);
X	    return TRUE;
X	}
X    }
X    return FALSE;
X}
X
Xvoid
Xdisplay_page()
X{
X    int sel;
X
X#ifdef CLEAREOL
X    if (can_home_clear) {
X	home_cursor();
X	maybe_eol();
X    } else
X#endif
X	clear();
X    carriage_return();
X
X#ifdef NOFIREWORKS
X    no_sofire();
X#endif
X    standout();
X    fputs(ngname, stdout);
X    un_standout();
X    printf("          %ld %sarticle%s", (long)sel_total_arts,
X	   sel_rereading? "read " : nullstr,
X	   article_count == 1 ? nullstr : "s");
X    if (sel_exclusive)
X	printf(" out of %ld", (long)article_count);
X    printf("%s\n", moderated);
X#ifdef CLEAREOL
X    maybe_eol();
X#endif
X    if (redirected && redirected != nullstr)
X	printf("\t** Please start using %s **", redirected);
X    putchar('\n') FLUSH;
Xtry_again:
X    sel_page_init();
X
X    if (!sel_total_arts)
X	;
X    else if (sel_mode == SM_ARTICLE) {
X	ARTICLE *ap, **app, **limit;
X
X	limit = artptr_list + artptr_list_size;
X	app = sel_page_app;
X	do {
X	    ap = *app;
X	    if (ap == sel_last_ap)
X		sel_item_index = sel_item_cnt;
X	    if (!(ap->flags & AF_INCLUDED))
X		continue;
X	    sel = !!(ap->flags & sel_mask) + (ap->flags & AF_DEL);
X	    sel_items[sel_item_cnt].ptr = (VOIDPTR*)ap;
X	    sel_items[sel_item_cnt].line = sel_line;
X	    sel_items[sel_item_cnt].sel = sel;
X	    sel_page_arts++;
X	    /* Output the article, with optional author */
X	    display_article(ap, sel_chars[sel_item_cnt], sel);
X	    sel_item_cnt++;
X	} while (++app < limit && sel_item_cnt < sel_max_cnt);
X	if (!sel_page_arts) {
X	    if (last_page())
X		goto try_again;
X	}
X	sel_next_app = app;
X    } else {
X	SUBJECT *sp;
X	int line_cnt;
X	bool etc;
X	char ch = ' ';
X
X	sp = sel_page_sp;
X	do {
X	    if (sp == sel_last_sp)
X		sel_item_index = sel_item_cnt;
X
X	    etc = FALSE;
X	    if (sp->flags & SF_INCLUDED) {
X		/* Compute how many lines we need to display this group */
X		if (sel_mode == SM_THREAD)
X		    line_cnt = count_thread_lines(sp, &sel);
X		else
X		    line_cnt = count_subject_lines(sp, &sel);
X		if (line_cnt) {
X		    /* If this item is too long to fit on the screen all by
X		    ** itself, trim it to fit and set the "etc" flag.
X		    */
X		    if (line_cnt > LINES - 5) {
X			line_cnt = LINES - 5;
X			etc = TRUE;
X		    }
X		    /* If it doesn't fit, save it for the next page */
X		    if (sel_line + line_cnt > LINES - 3)
X			break;
X		    sel_items[sel_item_cnt].ptr = (VOIDPTR*)sp;
X		    sel_items[sel_item_cnt].line = sel_line;
X		    sel_items[sel_item_cnt].sel = sel;
X		    sel_page_arts += sp->misc;
X
X		    ch = sel_chars[sel_item_cnt];
X		    sel = sel_items[sel_item_cnt].sel;
X		    sel_item_cnt++;
X		    if (sp->misc) {
X			display_subject(sp, ch, sel);
X			ch = ' ';
X		    }
X		}
X	    } else
X		line_cnt = 0;
X	    if (sel_mode == SM_THREAD) {
X		while (sp->next && sp->next->thread == sp->thread) {
X		    sp = sp->next;
X		    if (!line_cnt || !sp->misc)
X			continue;
X		    if (sel_line < LINES - 3)
X			display_subject(sp, ch, sel);
X		    ch = ' ';
X		    sel_page_arts += sp->misc;
X		}
X	    }
X	    if (etc)
X		fputs("      ...etc.", stdout);
X	} while ((sp=sp->next)!=Nullsubj && !etc && sel_item_cnt<sel_max_cnt);
X	if (!sel_page_arts) {
X	    if (last_page())
X		goto try_again;
X	}
X	sel_next_sp = sp;
X    }
X    sel_last_line = sel_line+1;
X    sel_last_ap = Nullart;
X    sel_last_sp = Nullsubj;
X    sel_at_end = (sel_prior_arts + sel_page_arts == sel_total_arts);
X#ifdef CLEAREOL
X    maybe_eol();
X#endif
X    putchar('\n') FLUSH;
X}
X
Xvoid
Xupdate_page()
X{
X    int sel;
X    int j;
X
X    for (j = 0; j < sel_item_cnt; j++) {
X	sel = sel_items[j].sel;
X	if (sel_mode == SM_ARTICLE) {
X	    ARTICLE *ap = (ARTICLE*)sel_items[j].ptr;
X	    if (sel == !!(ap->flags & sel_mask) + (ap->flags & AF_DEL))
X		continue;
X	} else {
X	    SUBJECT *sp = (SUBJECT*)sel_items[j].ptr;
X	    int real_sel;
X	    if (sel_mode == SM_THREAD)
X		(void) count_thread_lines(sp, &real_sel);
X	    else
X		(void) count_subject_lines(sp, &real_sel);
X	    if (sel == real_sel)
X		continue;
X	}
X	goto_line(sel_line, sel_items[j].line);
X	sel_line = sel_items[j].line;
X	sel_item_index = j;
X	output_sel(!sel);
X    }
X    if (++sel_item_index == sel_item_cnt)
X	sel_item_index = 0;
X}
X
Xvoid
Xoutput_sel(sel)
Xint sel;
X{
X    putchar(sel_chars[sel_item_index]);
X    putchar(sel_disp_char[sel]);
X    sel_items[sel_item_index].sel = sel;
X}
X
X/* Counts the number of lines needed to output a subject, including
X** optional authors.
X*/
Xstatic int
Xcount_subject_lines(subj, selptr)
XSUBJECT *subj;
Xint *selptr;
X{
X    register ARTICLE *ap;
X    register int sel;
X
X    if (subj->flags & SF_DEL)
X	sel = 2;
X    else if (subj->flags & sel_mask) {
X	sel = 1;
X	for (ap = subj->articles; ap; ap = ap->subj_next) {
X	    if ((!(ap->flags&AF_READ) ^ sel_rereading)
X	      && !(ap->flags & sel_mask)) {
X		sel = 3;
X		break;
X	    }
X	}
X    } else
X	sel = 0;
X    if (selptr)
X	*selptr = sel;
X    if (*display_mode == 'l')
X	return subj->misc;
X    if (*display_mode == 'm')
X	return (subj->misc <= 4? subj->misc : (subj->misc - 4) / 3 + 4);
X    return (subj->misc != 0);
X}
X
X/* Counts the number of lines needed to output a thread, including
X** optional authors.
X*/
Xstatic int
Xcount_thread_lines(subj, selptr)
XSUBJECT *subj;
Xint *selptr;
X{
X    register int total = 0;
X    register ARTICLE *thread = subj->thread;
X    int sel = -1, subj_sel;
X
X    do {
X	if (subj->misc) {
X	    total += count_subject_lines(subj, &subj_sel);
X	    if (sel < 0)
X		sel = subj_sel;
X	    else if (sel != subj_sel)
X		sel = 3;
X	}
X    } while ((subj = subj->next) != Nullsubj && subj->thread == thread);
X    if (selptr)
X	*selptr = (sel < 0? 0 : sel);
X    return total;
X}
X
X/* Display an article, perhaps with its author.
X*/
Xstatic void
Xdisplay_article(ap, ch, sel)
Xregister ARTICLE *ap;
Xchar_int ch;
Xint sel;
X{
X    int subj_width = COLS - 5;
X    int from_width = COLS / 5;
X
X#ifdef CLEAREOL
X    maybe_eol();
X#endif
X    if (subj_width < 32)
X	subj_width = 32;
X    
X    putchar(ch);
X    putchar(sel_disp_char[sel]);
X    if (*display_mode == 's' || from_width < 8)
X	printf("  %s\n",compress_subj(ap->subj->articles,subj_width)) FLUSH;
X    else {
X	printf("%s  %s\n",
X	   compress_from(ap, from_width),
X	   compress_subj(ap, subj_width - from_width)) FLUSH;
X    }
X    sel_line++;
X}
X
X/* Display the given subject group, with optional authors.
X*/
Xstatic void
Xdisplay_subject(subj, ch, sel)
XSUBJECT *subj;
Xchar_int ch;
Xint sel;
X{
X    register ARTICLE *ap;
X    register int j, i;
X    int subj_width = COLS - 8;
X    int from_width = COLS / 5;
X
X#ifdef CLEAREOL
X    maybe_eol();
X#endif
X    if (subj_width < 32)
X	subj_width = 32;
X
X    j = subj->misc;
X
X    putchar(ch);
X    if (ch != ' ')
X	putchar(sel_disp_char[sel]);
X    else
X	putchar(' ');
X    if (*display_mode == 's' || from_width < 8)
X	printf("%3d  %s\n",j,compress_subj(subj->articles,subj_width)) FLUSH;
X    else {
X	/* Find the first unread article so we get the author right */
X	for (ap = subj->articles; ap; ap = ap->subj_next) {
X	    if (!(ap->flags&AF_READ) ^ sel_rereading)
X		break;
X	}
X	printf("%s%3d  %s\n",
X	   compress_from(ap, from_width), j,
X	   compress_subj(ap, subj_width - from_width)) FLUSH;
X	i = -1;
X	if (--j && ap) {
X	    for (ap = ap->subj_next; ap && j; ap = ap->subj_next) {
X		if (!(!(ap->flags&AF_READ) ^ sel_rereading))
X		    continue;
X		j--;
X		if (i < 0)
X		    i = 0;
X		else if (*display_mode == 'm') {
X		    if (!j) {
X			if (i)
X			    putchar('\n');
X		    } else {
X			if (i == 3 || !i) {
X			    if (i)
X				putchar('\n');
X			    if (++sel_line >= LINES - 3)
X				return;
X#ifdef CLEAREOL
X			    maybe_eol();
X#endif
X			    i = 1;
X			} else
X			    i++;
X			printf("  %s      ",
X			       compress_from(ap, from_width)) FLUSH;
X			continue;
X		    }
X		}
X		if (++sel_line >= LINES - 3)
X		    return;
X#ifdef CLEAREOL
X		maybe_eol();
X#endif
X		printf("  %s\n", compress_from(ap, from_width)) FLUSH;
X	    }
X	}
X    }
X    sel_line++;
X}
SHAR_EOF
  $shar_touch -am 1028161994 'trn-3.6/rt-page.c' &&
  chmod 0644 'trn-3.6/rt-page.c' ||
  echo 'restore of trn-3.6/rt-page.c failed'
  shar_count="`wc -c < 'trn-3.6/rt-page.c'`"
  test 17611 -eq "$shar_count" ||
    echo "trn-3.6/rt-page.c: original size 17611, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/INSTALL ==============
if test -f 'trn-3.6/INSTALL' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/INSTALL (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/INSTALL (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/INSTALL' &&
XInstallation Instructions for trn 3.0:
X
X1)  Decide what package you want to use to solve your news database
X    needs.  There's currently two supported by trn:  mthreads and
X    news overview.  Mthreads creates smaller files that load faster
X    each time you enter a group, however it is more taxing on your
X    cpu and disk bandwidth because it keeps the files in thread order.
X    Overview files are larger, but they are less taxing on your system
X    because the format is pretty "raw" and the files are maintained by
X    your news software (either a modified C news or INN 1.3 and above).
X    Though they load slower than .thread files, they have subject and
X    author headers that are not truncated (unlike mthreads headers)
X    which means that trn won't have to "freshen" these headers during
X    its idle time.  The final choice is to not store a database.  If
X    you go this route it will take significantly longer to start up
X    a group in threaded mode, but you could chose to read one or more
X    groups unthreaded.
X
X2)  If you are going to make a version of trn that uses NNTP to get its
X    news remotely, be sure you have installed some version of inews that
X    sends articles to your news server.  The reference NNTP (v1.5.11)
X    comes with a version of inews that you can use, and C news and INN
X    both have versions that can be used remotely.
X
X3)  Run Configure.  This will figure out various things about your system.
X    Some things Configure will figure out for itself, other things it will
X    ask you about.  It will then proceed to make config.h, config.sh, the
X    Makefile, and a bunch of shell scripts.  You might possibly have to
X    trim # comments from the front of Configure if your sh doesn't handle
X    them, but all other # comments will be taken care of.
X
X    NOTE: This package allows the build to be performed in a directory
X    other than where the sources are.  You will need a "make" that supports
X    VPATH to do this.  Just create a directory where you want to do the
X    build, cd into it, and run "path/Configure" from there where "path" is
X    either a relative or absolute path reference to the trn source directory.
X
X4)  Glance through config.h and common.h to make sure system dependencies
X    are correct.  Most of them should have been taken care of by running
X    the Configure script.
X
X    If you have any additional changes to make to the C definitions, they
X    can be done in the Makefile, in config.h, or in common.h.  If you have
X    strange mailboxes on your system you should modify mbox.saver to correctly
X    append an article to a mailbox or folder.
X
X    If you are on a machine with limited address space, you probably don't
X    want to be using trn.  Feel free to give it a try, though -- there are
X    some defines in common.h that can be turned off to try to make trn fit
X    (see the System Dependencies section).  You might run a "make depend"
X    afterward just to be safe.
X
X5)  make
X
X    This will attempt to make trn in the current directory.
X
X6)  make install
X
X    This will put trn, newsetup, newsgroups, Pnews, Rnmail, trn-artchk, and
X    nntplist into a public directory (normally /usr/local/bin), and put a
X    number of files into the private trn library (e.g. /usr/local/lib/trn).
X    It also tries to put the trn man page in a reasonable place.  One of
X    the installed scripts is "newsetup", which creates a .newsrc for a
X    user that doesn't have one.  This script reads the subscriptions
X    file from your news library directory or sends a LIST SUBSCRIPTIONS
X    command to your server to get the default list of newsgroups for a
X    new user.  If you don't like this, customize the script as desired.
X
X    NOTE: if you have an old installation of trn that put artcheck and
X    getactive into the trn library directory, once you ensure that all
X    your installed scripts are using the new files (trn-artchk and
X    nntplist) you can delete the old ones from the lib directory.
X
X7)  Read the manual entry before running trn, or at least read the file
X    NEW if you are already familiar with trn.  Those that are brand new
X    to trn can get a quick idea of what's different from rn by reading
X    the WHAT'S NEW section of the man page.  Also check out the HINTS
X    file for some ways to get the most out of using trn.
X
X8)  Try trn, and play with some of the switches (use -x and -X if you told
X    Configure to leave these options off by default).  Any options you find
X    that you want to make the default for everyone can be placed into the
X    INIT file in the trn library.  Personal defaults can be put in a file
X    and the environment variable TRNINIT defined to point to it.
X
X9)  Once trn is running ok, make sure any database software you've installed
X    is going ok and interfacing properly with trn.  Read the documentation
X    that comes with the package of your choosing.
X
X10) IMPORTANT!  Help save the world!  Communicate any problems and suggested
X    patches to Wayne Davison <davison@borland.com> so we can keep the world
X    in sync.  If you have a problem, there's someone else out there who
X    either has had or will have the same problem.  If the problem affects
X    regular rn, code, I will pass it on to Stan Barber.
X
X    If possible, send in patches such that the patch program will apply them.
X    Unified or regular context diffs are the best, then normal diffs.  Don't
X    send ed scripts--I've probably changed my copy since the version you have.
X
X    Watch for trn patches in news.software.readers.  Patches will always be
X    in the unified context diff format, for application by the patch program.
X    If you don't have a patch program that handles unified context diffs,
X    you'll probably want to get one (such as patch version 12g8).  Otherwise,
X    you can use the (included) filter "unipatch", which can be generated with
X    the command "make unipatch".  To apply patches, use the command:
X
X	unipatch <patchfile | patch -p
X
X11) If you are going to hack on trn, please refer to rn's HACKERSGUIDE first.
SHAR_EOF
  $shar_touch -am 0425130394 'trn-3.6/INSTALL' &&
  chmod 0644 'trn-3.6/INSTALL' ||
  echo 'restore of trn-3.6/INSTALL failed'
  shar_count="`wc -c < 'trn-3.6/INSTALL'`"
  test 6039 -eq "$shar_count" ||
    echo "trn-3.6/INSTALL: original size 6039, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/makedepend.SH ==============
if test -f 'trn-3.6/makedepend.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/makedepend.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/makedepend.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/makedepend.SH' &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting makedepend (with variable substitutions)"
Xcase "$srcdir" in
X'') srcdir='.';;
Xesac
X$spitshell >makedepend <<!GROK!THIS!
X$startsh
X# $Id: makedepend.SH,v 3.0 1991/09/09 20:23:31 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 author 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. 
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
Xsrcdir=$srcdir
Xobjdir=`pwd`
Xdeptmp=\$objdir/.deptmp
X$cat /dev/null >\$deptmp
X$echo "(Note: this is going to take a while.)"
Xcd \$srcdir
Xfor file in *.[cy]; do
X    case "\$file" in
X    *.c) filebase=\`basename \$file .c\`;;
X    *.y) filebase=\`basename \$file .y\`;;
X    esac
X    $echo "Finding dependencies for \$filebase.o."
X    $sed -n <\$file \\
X	-e "/^\${filebase}_init(/q" \\
X	-e '/^#/{' \\
X	-e 's|/\*.*$||' \\
X	-e 's/\\\\[ 	]*$//' \\
X	-e p \\
X	-e '}' | $cppstdin -I\$objdir -I$usrinc $cppminus | $sed \\
X	-e '/^# *line/s/line//' \
X	-e '/^# *[0-9]/!d' \\
X	-e 's/^.*"\(.*\)".*\$/'\$filebase'.o: \1/' \\
X	-e 's|: \./|: |' \\
X	-e "s|\$objdir/||" \\
X	-e 's/: .*\.c/: '\$file'/' | \\
X	$uniq | $sort | $uniq >>\$deptmp
Xdone
X
Xfor file in *.SH; do
X    $echo \`basename \$file .SH\`: \$file config.sh \; /bin/sh "\\\$(srcdir)/\$file" >>\$deptmp
Xdone
X
Xcd \$objdir
X
X$sed <Makefile >Makefile.new -e '1,/^# AUTOMATICALLY/!d'
X
Xif $test -s \$deptmp; then
X    echo "Updating Makefile..."
X    $sed -e 's/\\\$[^(]/\$\$/g' \$deptmp | $egrep -v $usrinc >dependencies
Xelse
X    $echo "You don't seem to have a proper C preprocessor.  Using grep instead."
X    cd \$srcdir
X    $egrep '^#include ' *.[cyh] ?.[cyh] >\$deptmp
X    cd \$objdir
X    echo "Updating Makefile..."
X    <\$deptmp $sed -n 's|c:#include "\(.*\)".*\$\$|o: \1|p' > dependencies
X    <\$deptmp $sed -n 's|y:#include "\(.*\)".*\$\$|o: \1|p' >> dependencies
X    <\$deptmp $sed -n 's|h:#include "\(.*\)".*\$\$|h: \1|p' >> dependencies
Xfi
X$echo "# WARNING: Put nothing here or make depend will gobble it up!" >> dependencies
X$mv Makefile Makefile.old
X$mv Makefile.new Makefile
X$cat dependencies >>Makefile
Xrm \$deptmp
X!GROK!THIS!
X$eunicefix makedepend
Xchmod 755 makedepend
SHAR_EOF
  $shar_touch -am 0820134794 'trn-3.6/makedepend.SH' &&
  chmod 0644 'trn-3.6/makedepend.SH' ||
  echo 'restore of trn-3.6/makedepend.SH failed'
  shar_count="`wc -c < 'trn-3.6/makedepend.SH'`"
  test 2655 -eq "$shar_count" ||
    echo "trn-3.6/makedepend.SH: original size 2655, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/makedir.SH ==============
if test -f 'trn-3.6/makedir.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/makedir.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/makedir.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/makedir.SH' &&
Xcase $CONFIG in
X'') . ./config.sh ;;
Xesac
Xecho "Extracting makedir (with variable substitutions)"
X$spitshell >makedir <<!GROK!THIS!
X$startsh
X# $Id: makedir.SH,v 2.11 90/09/17 17:03:55 hokey Exp Locker: hokey $
X# 
X# $Log:	makedir.SH,v $
X# Revision 2.11  90/09/17  17:03:55  hokey
X# 2.11 alpha baseline
X# 
X
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
Xcase \$# in
X  0)
X    $echo "makedir pathname filenameflag"
X    exit 1
X    ;;
Xesac
X
X: guarantee one slash before 1st component
Xcase \$1 in
X  /*) ;;
X  *)  set ./\$1 \$2 ;;
Xesac
X
X: strip last component if it is to be a filename
Xcase X\$2 in
X  X1) set \`$echo \$1 | $sed 's:\(.*\)/[^/]*\$:\1:'\` ;;
X  *)  set \$1 ;;
Xesac
X
X: return reasonable status if nothing to be created
Xif $test -d "\$1" ; then
X    exit 0
Xfi
X
Xlist=''
Xwhile : ; do
X    case \$1 in
X    */*)
X	list="\$1 \$list"
X	set \`echo \$1 | $sed 's:\(.*\)/:\1 :'\`
X	;;
X    *)
X	break
X	;;
X    esac
Xdone
X
Xset \$list
X
Xfor dir do
X    $mkdir \$dir >/dev/null 2>&1
Xdone
X!GROK!THIS!
X$eunicefix makedir
Xchmod +x makedir
SHAR_EOF
  $shar_touch -am 0327202494 'trn-3.6/makedir.SH' &&
  chmod 0644 'trn-3.6/makedir.SH' ||
  echo 'restore of trn-3.6/makedir.SH failed'
  shar_count="`wc -c < 'trn-3.6/makedir.SH'`"
  test 1079 -eq "$shar_count" ||
    echo "trn-3.6/makedir.SH: original size 1079, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/mbox.saver.SH ==============
if test -f 'trn-3.6/mbox.saver.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/mbox.saver.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/mbox.saver.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/mbox.saver.SH' &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting mbox.saver (with variable substitutions)"
X$spitshell >mbox.saver <<!GROK!THIS!
X$startsh
X# $Id: mbox.saver.SH,v 3.0 1991/09/09 20:23:31 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 author 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#	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#	8 First line of message, normally From...
X#
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X!GROK!THIS!
Xcase $mboxchar in
X"$CTRLA")
X    $spitshell >>mbox.saver <<!GROK!THIS!
X( $echo "$CTRLA$CTRLA$CTRLA$CTRLA"
X  if $test "\$5" = 0 -a ! "\$4" = 0 ; then
X    $echo "Article: \$4 of \$6"
X  fi
X  $tail +\$5c \$1
X  $echo ""
X  $echo ""
X  $echo "$CTRLA$CTRLA$CTRLA$CTRLA" ) >> \$7
X!GROK!THIS!
X    ;;
X*)
X    $spitshell >>mbox.saver <<!GROK!THIS!
X ( $echo "\$8"
X  if $test "\$5" = 0 -a ! "\$4" = 0 ; then
X    $echo "Article: \$4 of \$6"
X  fi
X  $tail +\$5c \$1 | $sed "s/^[Ff]rom />& /"
X  $echo ""
X  $echo "" ) >> \$7
X!GROK!THIS!
X    ;;
Xesac
X$eunicefix mbox.saver
Xchmod 755 mbox.saver
SHAR_EOF
  $shar_touch -am 0327202494 'trn-3.6/mbox.saver.SH' &&
  chmod 0644 'trn-3.6/mbox.saver.SH' ||
  echo 'restore of trn-3.6/mbox.saver.SH failed'
  shar_count="`wc -c < 'trn-3.6/mbox.saver.SH'`"
  test 1759 -eq "$shar_count" ||
    echo "trn-3.6/mbox.saver.SH: original size 1759, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/newsetup.SH ==============
if test -f 'trn-3.6/newsetup.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/newsetup.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/newsetup.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/newsetup.SH' &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting newsetup (with variable substitutions)"
X$spitshell >newsetup <<!GROK!THIS!
X$startsh
X# $Id: newsetup.SH,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 author 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
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X: syntax: newsetup
X
Xcase $d_portable in
Xdefine)
X    # where recordings, distributions and moderators are kept
X    lib=\`$filexp $newslib\`
X    # where important rn things are kept
X    rnlib=\`$filexp $privlib\`
X    nntplist=nntplist
X    ;;
Xundef)
X    # where recordings, distributions and moderators are kept
X    lib="$newslib"
X    # where important rn things are kept
X    rnlib="$privlib"
X    nntplist=$bin/nntplist
X    ;;
Xesac
X
Xtest=${test-test}
Xecho=${echo-echo}
Xcat=${cat-cat}
Xmv=${mv-mv}
Xrm=${rm-rm}
Xcp=${cp-cp}
X
X!GROK!THIS!
X$cat >>newsetup <<'!NO!SUBS!'
Xdotdir="${DOTDIR-${HOME-$LOGDIR}}"
Xnewsrc="$dotdir/.newsrc"
Xtmp="${TMPDIR-/tmp}"
X
Xsubs="$lib/subscriptions"
Xtmpsubs="$tmp/trnsubs.$$"
X
X$cat <<'EOH'
X
XWelcome to trn.  Here's some important things to remember:
X
X  o  Trn is an extension of rn and has a similar command syntax.
X  o  To access all the new features, specify the options -x and -X.  These
X     options MAY be on by default, but it won't hurt to be redundant.
X  o  Single-character commands don't require a carriage return -- only
X     commands that let you type in an argument.
X  o  At ANY prompt, you may type 'h' for help.  There are many different help
X     menus, depending on the context.  Also, typing <esc>h in the middle of a
X     multi-character command will list escape substitutions.
X  o  Typing a space to any prompt means to do the normal thing.  You could
X     spend all day reading news and never hit anything but the space bar.
X  o  If you have never used the news system before, you may find the articles
X     in news.announce.newusers to be helpful.
X  o  Please consult the man page for complete information.
X
XEOH
X
X$rm -f $newsrc-old
X$echo "Creating $newsrc to be used by news programs."
X
Xif $test -s "$newsrc"; then
X    $echo "Saving your current one as $newsrc-old..."
X    $mv -f $newsrc $newsrc-old
Xfi
X
Xif $test -r $subs; then
X    $cp $subs $newsrc
Xelse
X    ($nntplist -o $tmpsubs subscriptions) >/dev/null 2>&1
X    if $test -s $tmpsubs; then
X	$cp $tmpsubs $newsrc
X    else
X	$cat <<EOM >$newsrc
Xnews.announce.newusers: 
XEOM
X    fi
X    $rm -f $tmpsubs
Xfi
X
X$cat <<'EOH'
XDone.
X
XTo add new group use "a pattern" or "g newsgroup.name".  To get rid of
Xnewsgroups you aren't interested in, use the 'u' command.
XEOH
X!NO!SUBS!
X$eunicefix newsetup
Xchmod 755 newsetup
SHAR_EOF
  $shar_touch -am 0831164294 'trn-3.6/newsetup.SH' &&
  chmod 0644 'trn-3.6/newsetup.SH' ||
  echo 'restore of trn-3.6/newsetup.SH failed'
  shar_count="`wc -c < 'trn-3.6/newsetup.SH'`"
  test 3192 -eq "$shar_count" ||
    echo "trn-3.6/newsetup.SH: original size 3192, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/newsgroups.SH ==============
if test -f 'trn-3.6/newsgroups.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/newsgroups.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/newsgroups.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/newsgroups.SH' &&
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting newsgroups (with variable substitutions)"
X$spitshell >newsgroups <<!GROK!THIS!
X$startsh
X# $Id: newsgroups.SH,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 author 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
Xexport PATH || (echo "OOPS, this isn't sh.  Desperation time.  I will feed myself to sh."; sh \$0; kill \$\$)
X
X: syntax: newsgroups [pattern] [pipeflag]
X
X: System Dependencies
X
X: You might want to change pager to a "make column" program if you have one.
X: On the other hand, if your kernel does paging, cat would probably do.
Xpager="${pager-/usr/ucb/more}"
X#NORMALactive="${active-/usr/lib/news/active}"
X
X#NORMALcase \$active in
X#NORMAL~*) active=\`$filexp \$active\` ;;
X#NORMALesac
X#NNTP
X#NNTPactive="/tmp/active.\$\$"
X#NNTPrnlib=$privlib
X#NNTPcase \$rnlib in
X#NNTP~*) rnlib=\`$filexp \$rnlib\` ;;
X#NNTPesac
X#NNTPnntplist=$bin/nntplist
X
X: End of system dependencies, hopefully
X#NNTP
X#NNTPif \$nntplist -o \$active ACTIVE; then
X#NNTP    : nothing
X#NNTPelse
X#NNTP    exit 1
X#NNTPfi
X
Xif $test \$# -ge 2 ; then
X    pager=$cat
Xelse
X    $echo "Completely unsubscribed newsgroups:"
Xfi
X
Xdotdir=\${DOTDIR-\${HOME-\$LOGDIR}}
Xnewsrc=\$dotdir/.newsrc
X
X: Throwing .newsrc into the pot twice is a lovely hack to prevent
X: bogus newsgroups from showing up as unsubscribed.
X
X$cat \$newsrc \$newsrc \$active | \\
X$sed -n	-e '/^options/d' \\
X	-e '/^[	 ]/d' \\
X	-e '/^control/d' \\
X	-e '/^to\./d' \\
X 	-e '/ x\$/d' \\
X	-e 's/^\([^ !:]*\)[ !:].*\$/\1/' \\
X	-e "/.*\$1/p" | \\
X$sort | $uniq -u | \$pager
X#NNTP$rm -f \$active
Xif $test \$# -ge 2 ; then
X    exit
Xfi
X$echo $n "[Type return to continue] $c"
Xread tmp
X$echo ""
X$echo "Unsubscribed but mentioned in \$newsrc:"
X$sed -n < \$newsrc \\
X	-e "/\$1.*!/"'s/^\([^!]*\)!.*\$/\1/p' | \\
X$sort | \$pager
X!GROK!THIS!
Xcase "$d_nntp" in
Xdefine)  sed < newsgroups -e '/^#NNTP/s/^#NNTP//' -e '/^#NORMAL/d' > newsgroups.new ;;
X*) sed < newsgroups -e '/^#NNTP/d' -e '/^#NORMAL/s/^#NORMAL//' > newsgroups.new ;;
Xesac
Xmv newsgroups.new newsgroups
X$eunicefix newsgroups
Xchmod 755 newsgroups
SHAR_EOF
  $shar_touch -am 0831164294 'trn-3.6/newsgroups.SH' &&
  chmod 0644 'trn-3.6/newsgroups.SH' ||
  echo 'restore of trn-3.6/newsgroups.SH failed'
  shar_count="`wc -c < 'trn-3.6/newsgroups.SH'`"
  test 2597 -eq "$shar_count" ||
    echo "trn-3.6/newsgroups.SH: original size 2597, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/newsnews.SH ==============
if test -f 'trn-3.6/newsnews.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/newsnews.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/newsnews.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/newsnews.SH' &&
X: see end of file for revision information
Xcase $CONFIG in
X    '') . ./config.sh ;;
Xesac
Xecho "Extracting newsnews (with variable substitutions)"
Xcat >newsnews <<!GROK!THIS!
X			*** NEWS NEWS ***
X
XWelcome to trn 3.6, which continues on the feature trail, adding support
Xfor slow net connections, and squashing some bugs.  Trn is "threaded read
Xnews", based on rn.
X
XYou can type 'h' at any prompt to display a summary of the commands that
Xare available.
X
XThis message will not be displayed again unless it is updated with new
Xinformation.
X
XWayne Davison  <davison@borland.com>
X!GROK!THIS!
X$eunicefix newsnews
X#
X# $Id: newsnews.SH,v 3.0 1991/09/09 20:23:31 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 author 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
SHAR_EOF
  $shar_touch -am 1104132094 'trn-3.6/newsnews.SH' &&
  chmod 0644 'trn-3.6/newsnews.SH' ||
  echo 'restore of trn-3.6/newsnews.SH failed'
  shar_count="`wc -c < 'trn-3.6/newsnews.SH'`"
  test 1244 -eq "$shar_count" ||
    echo "trn-3.6/newsnews.SH: original size 1244, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/nntp.h ==============
if test -f 'trn-3.6/nntp.h' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/nntp.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/nntp.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/nntp.h' &&
X/* $Id: nntp.h,v 3.0 1992/12/14 00:14:55 davison Trn $
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#ifdef USE_NNTP
X
X#define FB_BACKGROUND	0
X#define FB_OUTPUT	1
X#define FB_SILENT	2
X
Xint	nntp_list _((char*,char*,int));
Xbool	nntp_group _((char*,NG_NUM));
Xbool	nntp_stat _((ART_NUM));
XART_NUM	nntp_stat_id _((char*));
Xbool	nntp_header _((ART_NUM));
XFILE	*nntp_body _((ART_NUM));
Xlong	nntp_artsize _((void));
Xint	nntp_finishbody _((int));
Xvoid	nntp_seekart _((long));
Xlong	nntp_tellart _((void));
Xchar	*nntp_readart _((char*,int));
Xtime_t	nntp_time _((void));
Xbool	nntp_newgroups _((time_t));
Xbool	nntp_listgroup _((void));
Xchar	*nntp_artname _((void));
Xchar	nntp_handle_timeout _((bool_int));
Xvoid	nntp_cleanup _((void));
X
X#ifdef USE_XTHREAD
Xlong	nntp_readcheck _((void));
Xlong	nntp_read _((char*,long));
X#endif
X
X#include "nntpclient.h"
X
X#endif /* USE_NNTP */
SHAR_EOF
  $shar_touch -am 1009235694 'trn-3.6/nntp.h' &&
  chmod 0644 'trn-3.6/nntp.h' ||
  echo 'restore of trn-3.6/nntp.h failed'
  shar_count="`wc -c < 'trn-3.6/nntp.h'`"
  test 1010 -eq "$shar_count" ||
    echo "trn-3.6/nntp.h: original size 1010, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/norm.saver.SH ==============
if test -f 'trn-3.6/norm.saver.SH' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/norm.saver.SH (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/norm.saver.SH (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/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# $Id: norm.saver.SH,v 3.0 1991/09/09 20:23:31 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 author 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#	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
  $shar_touch -am 0101034593 'trn-3.6/norm.saver.SH' &&
  chmod 0644 'trn-3.6/norm.saver.SH' ||
  echo 'restore of trn-3.6/norm.saver.SH failed'
  shar_count="`wc -c < 'trn-3.6/norm.saver.SH'`"
  test 1296 -eq "$shar_count" ||
    echo "trn-3.6/norm.saver.SH: original size 1296, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/README ==============
if test -f 'trn-3.6/README' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/README (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/README (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/README' &&
X			  Trn Kit, Version 3.5
X
X		    Copyright (c) 1993, Wayne Davison
X
X			Based on rn, Version 4.4
X
X		     Copyright (c) 1985, Larry Wall
X                     Copyright (c) 1991, Stan Barber
X
XYou may copy the trn kit in whole or in part as long as you don't try to
Xmake money off it, or pretend that you wrote it.
X--------------------------------------------------------------------------
X
XSee the file INSTALL for installation instructions.  Failure to do so
Xmay void your warranty. :-)
X
XAfter you have unpacked your kit, you should have all the files listed
Xin MANIFEST (Configure checks this for you).
X
XIf you're unsure if you have the latest release, check ftp.uu.net:
X
X    ftp.uu.net:networking/news/readers/trn/trn.tar.gz -> [latest.version].gz
X
X[A .Z version is also available and mthreads resides in the same spot,
Xif you need it.]
X
XWhat is trn?
X------------
XTrn is Threaded RN -- a newsreader that uses an article's references to
Xorder the discussions in a very natural, reply-ordered sequence called
Xthreads.  Having the replies associated with their parent articles not
Xonly makes following the discussion easier, but also makes it easy to back-
Xtrack and (re-)read a specific discussion from the beginning.  Trn also
Xhas a visual representation of the current thread in the upper right corner
Xof the header, which will give you a feel for how the discussion is going
Xand how the current article is related to the last one you read.
X
XIn addition, a thread selector makes it easy to browse through a large
Xgroup looking for interesting articles.  You can even browse through the
Xarticles you've already read and select the one(s) you wish to read again.
XOther nice features include the extract commands for the source and binary
Xgroups, thread-oriented kill directives, a better newgroup finding strategy,
Xand lots more.  See the file NEW for a list of the things that are new to
Xtrn 3.0 from previous versions.
X
XTo make trn work faster you will probably want to create an auxiliary news
Xdatabase that summarises the available articles.  Trn know how to use two
Xdifferent kinds (so far):  thread files, which are maintained by the mthreads
Xpackage and typically requires 3-5% of your newsspool size in disk storage;
Xand overview files, which are maintained by INN v1.3 (or greater) or a
Xmodified version of C news and typically requires 8-10% of your newsspool
Xsize in disk storage.  (Note that the space that mthreads saves you on your
Xdisk is paid for by a higher demand on your cpu and disks while updating
Xthe files.)  See the package of your choice for details on how to setup
Xthe adjunct database, but it is not necessary to do this before trying
Xout trn.
X
XTrn supports local news groups and news accessed remotely via NNTP.  If you
Xopt for remote access you will probably want to make the adjunct database
Xavailable too.  You can do this in a variety of way, but I recommend that
Xyou send the database from the server to the client via NNTP.  To do this
Xyou either need to use INN or a modified reference NNTP -- version 1.5.11-t5
Xis the latest as of this writing.  See ftp.uu.net:networking/news/nntp for
Xthe file nntp-t5.tar.gz. This version supports the XOVER command (to send
Xoverview files), the XTHREAD command (to send thread files), and the XINDEX
Xcommand (though trn doesn't support using it).  The alternative is to either
Xmount the disk containing your database via NFS, or build it locally.  See
Xthe mthreads package for details on how to do this.
X
XNote that trn is based on rn, and so it does a great job of pretending to
Xbe rn for those people that simply don't like to change their newsreading
Xhabits.  It is possible to install trn as both rn and trn linked together
Xand have it act as both newsreaders, thus saving you the hassle of maint-
Xaining two separate newsreaders.  A Configuration question will ask you if
Xyou want trn to check its name on startup.
X
XWhere to send bug reports
X-------------------------
XMail your bug reports to Wayne Davison <davison@borland.com>.  If you use
Xthe 'v'ersion command from the newsgroup selection level of trn you will
Xbe reminded of this address should you forget.
SHAR_EOF
  $shar_touch -am 0607113294 'trn-3.6/README' &&
  chmod 0644 'trn-3.6/README' ||
  echo 'restore of trn-3.6/README failed'
  shar_count="`wc -c < 'trn-3.6/README'`"
  test 4136 -eq "$shar_count" ||
    echo "trn-3.6/README: original size 4136, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/nntpclient.h ==============
if test -f 'trn-3.6/nntpclient.h' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/nntpclient.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/nntpclient.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/nntpclient.h' &&
X/* $Id: nntpclient.h,v 3.0 1992/12/14 00:14:55 davison Trn $
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#ifdef USE_NNTP
X
Xint	server_init _((char*));
X
Xint	nntp_connect _((bool_int));
Xvoid	nntp_command _((char*));
Xchar	nntp_check _((bool_int));
Xint	nntp_gets _((char*, int));
Xvoid	nntp_close _((bool_int));
X
X#define NNTP_LIST_END(s)  ((s)[0]=='.' && ((s)[1]=='\0' || (s)[1]=='\r'))
X
X#define nntp_get_a_line(buf,len,realloc) get_a_line(buf,len,realloc,ser_rd_fp)
X
X/* RFC 977 defines these, so don't change them */
X
X#define	NNTP_CLASS_INF  	'1'
X#define NNTP_CLASS_OK   	'2'
X#define	NNTP_CLASS_CONT 	'3'
X#define	NNTP_CLASS_ERR  	'4'
X#define	NNTP_CLASS_FATAL	'5'
X
X#define	NNTP_POSTOK_VAL 	200	/* Hello -- you can post */
X#define	NNTP_NOPOSTOK_VAL	201	/* Hello -- you can't post */
X#define NNTP_LIST_FOLLOWS_VAL	215	/* There's a list a-comin' next */
X
X#define NNTP_GOODBYE_VAL	400	/* Have to hang up for some reason */
X#define	NNTP_NOSUCHGROUP_VAL	411	/* No such newsgroup */
X
X#define	NNTP_AUTH_NEEDED_VAL 	480	/* Authorization Failed */
X#define	NNTP_AUTH_REJECT_VAL	482	/* Authorization data rejected */
X
X#define	NNTP_BAD_COMMAND_VAL	500	/* Command not recognized */
X#define	NNTP_SYNTAX_VAL		501	/* Command syntax error */
X#define	NNTP_ACCESS_VAL 	502	/* Access to server denied */
X#define	NNTP_TMPERR_VAL  	503	/* Program fault, command not performed */
X#define	NNTP_AUTH_BAD_VAL 	580	/* Authorization Failed */
X
X#define	NNTP_STRLEN	512
X
XEXT FILE *ser_rd_fp INIT(NULL);
XEXT FILE *ser_wr_fp INIT(NULL);
XEXT char ser_line[NNTP_STRLEN];
X
X#if defined(NNTP_HANDLE_TIMEOUT) || defined(USE_GENAUTH)
XEXT char last_command[NNTP_STRLEN];
X#endif
X
XEXT bool CompliantServer INIT(FALSE);
X
X#endif /* USE_NNTP */
SHAR_EOF
  $shar_touch -am 1118220194 'trn-3.6/nntpclient.h' &&
  chmod 0644 'trn-3.6/nntpclient.h' ||
  echo 'restore of trn-3.6/nntpclient.h failed'
  shar_count="`wc -c < 'trn-3.6/nntpclient.h'`"
  test 1847 -eq "$shar_count" ||
    echo "trn-3.6/nntpclient.h: original size 1847, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/INIT ==============
if test -f 'trn-3.6/INIT' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/INIT (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/INIT (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/INIT' &&
X+Hfrom
SHAR_EOF
  $shar_touch -am 0418122394 'trn-3.6/INIT' &&
  chmod 0644 'trn-3.6/INIT' ||
  echo 'restore of trn-3.6/INIT failed'
  shar_count="`wc -c < 'trn-3.6/INIT'`"
  test 7 -eq "$shar_count" ||
    echo "trn-3.6/INIT: original size 7, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/cache.h ==============
if test -f 'trn-3.6/cache.h' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/cache.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/cache.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/cache.h' &&
X/* $Id: cache.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/* Subjects get their own structure */
X
Xtypedef struct rt_subj {
X    struct rt_subj *next;
X    struct rt_subj *prev;
X    struct rt_art *articles;
X    struct rt_art *thread;
X    struct rt_subj *thread_link;
X    char *str;
X    time_t date;
X    short flags;
X    short misc;		/* used for temporary totals and subject numbers */
X} SUBJECT;
X
X/* subject flags */
X
X#define SF_SEL		0x0001
X#define SF_DEL		0x0002
X#define SF_DELSEL	0x0004
X#define SF_OLDSEL	0x0008
X#define SF_INCLUDED	0x0010
X
X#define SF_VISIT	0x0200
X#define SF_WASSELECTED  0x0400
X#define SF_SUBJTRUNCED	0x1000
X
X/* This is our article-caching structure */
X
Xtypedef struct rt_art {
X    time_t date;
X    SUBJECT *subj;
X    char *from;
X    char *msgid;
X    char *xrefs;
X    struct rt_art *parent;	/* parent article */
X    struct rt_art *child1;	/* first child of a chain */
X    struct rt_art *sibling;	/* our next sibling */
X    struct rt_art *subj_next;	/* next article in subject order */
X    short flags;		/* state flags */
X    short autofl;		/* auto-processing flags */
X} ARTICLE;
X
X/* article flags */
X
X#define AF_SEL		0x0001
X#define AF_DEL		0x0002
X#define AF_DELSEL	0x0004
X#define AF_OLDSEL	0x0008
X#define AF_INCLUDED	0x0010
X
X#define AF_READ		0x0020
X#define AF_CACHED	0x0040
X#define AF_THREADED	0x0080
X#define AF_MISSING	0x0100
X#define AF_HAS_RE	0x0200
X#define AF_KCHASE	0x0400
X#define AF_MCHASE	0x0800
X#define AF_YANKBACK	0x1000
X#define AF_FROMTRUNCED	0x2000
X#define AF_TMPMEM	(0x4000|AF_MISSING)
X#define AF_FAKE 	(0x8000|AF_MISSING)
X
X#define AUTO_KILL	0x0001
X#define AUTO_KILLALL	0x0002
X#define AUTO_SELECT	0x0004
X#define AUTO_SELECT1	0x0008
X#define AUTO_SELECTALL	0x0010
X
X/* The following define is only valid as a flag to the select_article call */
X#define AUTO_ECHO	0x8000
X
X#define Nullart Null(ARTICLE*)
X#define Nullsubj Null(SUBJECT*)
X
X#define was_read(a)     ((a) < absfirst || (article_ptr(a)->flags & AF_READ))
X
X/* These must never use their args more than once in the definition */
X#define article_num(ap)      (((ap)-article_list)+absfirst)
X#define article_ptr(an)      (article_list+((an)-absfirst))
X#define find_article(an)     ((an < absfirst || an > lastart)? \
X			      Nullart : article_ptr(an))
X
XEXT ARTICLE *article_list INIT(Nullart);
XEXT ARTICLE **artptr_list INIT(0);
XEXT ARTICLE **artptr;
XEXT ART_NUM artptr_list_size INIT(0);
X
X#ifdef ARTSEARCH
XEXT ART_NUM srchahead INIT(0); 	/* are we in subject scan mode? */
X				/* (if so, contains art # found or -1) */
X#endif
X
XEXT ART_NUM first_cached;
XEXT ART_NUM last_cached;
XEXT bool cached_all_in_range;
XEXT ARTICLE *sentinel_artp;
X
X#define DONT_FILL_CACHE	0
X#define FILL_CACHE	1
X
XEXT struct rt_subj *first_subject INIT(0);
XEXT struct rt_subj *last_subject INIT(0);
X
XEXT bool untrim_cache INIT(FALSE);
X
X#ifdef PENDING
XEXT ART_NUM subj_to_get;
XEXT ART_NUM xref_to_get;
X#endif
X
Xvoid	cache_init _((void));
Xvoid	build_cache _((void));
Xvoid	grow_cache _((ART_NUM));
Xvoid	close_cache _((void));
Xvoid	cache_article _((ARTICLE*));
Xvoid	check_for_near_subj _((ARTICLE*));
Xvoid	change_join_subject_len _((int));
Xvoid	check_poster _((ARTICLE*));
Xvoid	uncache_article _((ARTICLE*,bool_int));
Xchar	*fetchcache _((ART_NUM,int,bool_int));
Xchar	*get_cached_line _((ARTICLE*, int, bool_int));
Xvoid	set_subj_line _((ARTICLE*, char*, int));
Xvoid	set_cached_line _((ARTICLE*, int, char*));
Xvoid	look_ahead _((void));
Xvoid	cache_until_key _((void));
Xbool	cache_subjects _((void));
Xbool	cache_xrefs _((void));
Xbool	cache_all_arts _((void));
Xbool	cache_unread_arts _((void));
Xbool	art_data _((ART_NUM,ART_NUM,bool_int,bool_int));
Xbool	cache_range _((ART_NUM,ART_NUM));
Xvoid	clear_article _((ARTICLE*));
Xvoid	free_subject _((SUBJECT*));
SHAR_EOF
  $shar_touch -am 1118220194 'trn-3.6/cache.h' &&
  chmod 0644 'trn-3.6/cache.h' ||
  echo 'restore of trn-3.6/cache.h failed'
  shar_count="`wc -c < 'trn-3.6/cache.h'`"
  test 4287 -eq "$shar_count" ||
    echo "trn-3.6/cache.h: original size 4287, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/overview.h ==============
if test -f 'trn-3.6/overview.h' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/overview.h (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/overview.h (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/overview.h' &&
X/* $Id: overview.h,v 3.0 1992/12/14 00:14:09 davison Trn $
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/* The order of the overview file fields */
X#define OV_NUM  	0
X#define OV_SUBJ 	1
X#define OV_FROM 	2
X#define OV_DATE 	3
X#define OV_MSGID	4
X#define OV_REFS 	5
X#define OV_BYTES	6
X#define OV_LINES	7
X#define OV_OTHERS	8	/* this catch-all field must be last */
X#undef	OV_OTHERS_HAS_XREFS	/* forces trn to assume xrefs always exist */
X
X/* If ALL the overview files trn will be accessing have xrefs in the OTHERS
X** field you may choose to define OV_OTHERS_HAS_XREFS.  This may save some
X** article accessing during the time that it would take trn to determine
X** this for itself. */
X
X/* NOTE that you must NOT define OV_XREFS unless you have opted to create
X** a new (non-standard) overview field for xrefs instead of placing them
X** in the OTHERS field.  If you have included the xref header without its
X** prefix into a field of its own, define OV_XREFS with the appropriate
X** field number in the list above.  If it has the "Xref:" prefix and you
X** didn't want to point the OV_OTHERS field at it (for some reason) you
X** can define both OV_XREFS and OV_LAX_XREFS and trn accepts a field with
X** or without the "Xref:" prefix. */
X
X/*#define OV_XREFS   8	*//* only define when using non-standard .overview */
X/*#define OV_LAX_XREFS	*//* allow xref field to have a header-prefix */
X
X/* What name to append to the directory name to read an overview file.
X** This REQUIRES a leading slash unless you're getting fancy.
X*/
X#define OV_FILE_NAME	"/.overview"
X
X/* How many overview lines to read with one NNTP call */
X#define OV_CHUNK_SIZE	40
SHAR_EOF
  $shar_touch -am 0327202494 'trn-3.6/overview.h' &&
  chmod 0644 'trn-3.6/overview.h' ||
  echo 'restore of trn-3.6/overview.h failed'
  shar_count="`wc -c < 'trn-3.6/overview.h'`"
  test 1787 -eq "$shar_count" ||
    echo "trn-3.6/overview.h: original size 1787, current size $shar_count"
  rm -f _sharnew.tmp
fi
# ============= trn-3.6/HACKERSGUIDE ==============
if test -f 'trn-3.6/HACKERSGUIDE' && test X"$1" != X"-c"; then
  echo 'x - skipping trn-3.6/HACKERSGUIDE (file already exists)'
  rm -f _sharnew.tmp
else
  > _sharnew.tmp
  echo 'x - extracting trn-3.6/HACKERSGUIDE (text)'
  sed 's/^X//' << 'SHAR_EOF' > 'trn-3.6/HACKERSGUIDE' &&
XHacking Notes from the hand of Larry Wall with respect to rn, trn's ancestor,
Xmodified by Wayne Davison to reflect the current state of trn.
X
XIf you aren't interested in mucking with the innards of trn, don't read this.
X
XIn the interests of both space and time optimization, things are done inside
Xtrn that don't always conform to the highest ideals of programming.  To the
Xextent I felt it was practical, I've tried to conform to good programming
Xpractice, but you must realize that my goal was to make a better mousetrap,
Xso certain conscious tradeoffs were made in the design of trn right from the
Xstart.  In particular, if you want to hack on trn (and I wouldn't blame you,
Xit's fun), beware of the following:
X  
X  * buf and cmd_buf are reused all over the place.  11-squishing is a good
X    term for it.  No, I'm on a Vax now, but I've been there.
X
X  * The article header is parsed on the fly, while it is being displayed.
X    In fact, practically everything is done on the fly within the article
X    display loop, and there are plenty of state variables.  The information
X    required to backup pages is not stored in memory, except for 1 buffer's
X    worth.
X
X  * Lots of contortions are gone through to avoid using static memory, or
X    allocating unnecessary memory, or losing track of allocated memory,
X    while at the same time allowing .newsrc lines and header lines to be
X    ANY length up to the amount of memory you have.  Trn spends a great deal
X    of effort being lazy.  Do not use a static buffer when you can use
X    growstr(). 
X
X  * Lots of contortions are gone through to try to do things when people
X    aren't waiting, or have only been waiting a very short time.  Guessing
X    the next article to be opened and opening it, searching ahead for the
X    next article with the same subject, delaying the look up of the number
X    of articles in a newsgroup, writing the rest of the page while the
X    reader is examining the header, cacheing up subjects while the user
X    is reading, checkpointing the .newsrc only while the reader is in the
X    middle of an interesting article, are some of the strategies employed.
X  
X  * There are plenty of goto's.  Most of them involve going back to reprompt,
X    to reask for input, or to just plain do the unstructured things people
X    want to do when they are glaring at a terminal.  If they bother you
X    too much, just think of trn as a big state machine.  If they don't bother
X    you at all, I don't want you hacking on trn.
X
X  * Put all includes at the front of the file, before the first function,
X    or makedepend will not work right.  I could relax this, but makedepend
X    would take about 5 times longer to run.
X
XIn general then, feel free to hack on trn.  Just don't broadcast untested
Xpatches to the net.  Remember that there are people with limited address
Xspaces and limited cpu cycles.  If you add a wonderful new feature and
Xwant to publish a patch, put #ifdef's around it so that people who don't
Xwant it or can't afford it can work around it.  THIS MEANS YOU.  We don't
Xneed 57 varieties of mutually incompatible and incomprehensible trn floating
Xabout the net.  Consider telling me about your patch so that I can consider
Xincluding it in the standard version.  A COMPLETE PATCH TAKES INTO ACCOUNT
XSYSTEM DEPENDENCIES AS DETERMINED BY THE CONFIGURE SCRIPT.
X
X* Don't use ints where trn uses typedefs, in particular, for article numbers.
X* Don't use %d anywhere that someone might need a %ld.  (Just because YOU
X    typedefed it as an int doesn't mean someone else won't need a long.)
X* Don't use %D, that's archaic.
SHAR_EOF
  : || echo 'restore of trn-3.6/HACKERSGUIDE failed'
fi
echo 'End of archive part 11'
echo 'File trn-3.6/HACKERSGUIDE is continued in part 12'
echo 12 > _sharseq.tmp
exit 0


