Newsgroups: alt.sources
From: ken@bitsko.slc.ut.us (Ken MacLeod)
Subject: Unidel 1.0, a Citadel-style news/mail reader and BBS, part 06 of 09
Message-ID: <1992May3.013014.18896@bitsko.slc.ut.us>
Date: Sun, 3 May 1992 01:30:14 GMT

Submitted-by: ken@bitsko.slc.ut.us
Archive-name: unidel-1.0/part06

---- Cut Here and unpack ----
#!/bin/sh
# This is part 06 of unidel-1.0
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= unidel/ToDo ==============
echo "x - extracting unidel/ToDo (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/ToDo &&
X#
X#  ToDo -- Unidel Things To Do list
X#
X#  SCCS
X#      @(#) ToDo  1.1 02 May 1992 11:08:07 
X#
X# @PRT egrep -v "(^#|done)" {} | more
X# @PRT-v egrep -v "(^#|done)" {} | egrep "(^[^	]|1.0|bug)" | more
X# @PRT-f egrep -v "(^#|done)" {} | egrep -v "(1.0|bug)" | more
X#
XMail
X	done; Don't unbatch mail for shell users
X	done; Multiple recipients on mail
X	mail files
X	done; subjects
X	done; Cancel
X	done; Reply doesn't handle "Full Name <address>" form
X	return-receipt
X	done; multiple rooms for receiving mail lists
X	mail lists/aliases
X	done; Bcc: poster
X	site and user look-up, soundex (directory services)
X	remind/tracking mods
XFiles
X	Compile option for using/not using files.
X	bug; Download security flakiness
X	done; Y/Z modem upload
X	done; No echo after "Ready?"
X	done, keep; Rid of D(ownload)/U(pload)
X	DOS '\n' to '\r\n' translation.
X	uudecode and other filters
XStats
X	done; user lists
X	newsgroup lists
XMessages
X	1.0; Upload message(s)
X	1.0; Hold message, dead.article, dead.letter
X	done; Reply-To: and Followup-To:
X	bug; Verify global read/download options
X	bug; G(oto) rooms with 0 messages, not saved
X	bug; message pointers seem to be off by one or two (old really is new)
X	bug; Followup/reply can't find file
X	Better handling of floor vs. room controls
X	1.0; Cancel
X	1.0; headers options, full headers on download
X	1.0?; short header index on downloads
X	short header scrolling/selecting vn-style.
X	1.0?; mixed read modes
X	kill files
X	threading
X	done; Bring postnews/mail function into Unidel
X	done; Convert dates to local time (user's time)
X	done; can't forget pre-known floors
XSystem
X	1.0; #define remoteXfer
X	1.0; #define fileRooms
X	1.0; #define guest
X	bug; DoMenu/More doesn't erase --More-- on bad char; return a 'bad' status and let caller take care of bad chars?
X	novice/experienced modes
X	done; Get rid of calling routine name in AllocString
X	1.0; xmalloc, xrealloc, xfree, xfopen, xfclose, etc.
X	1.0; Better handling of .unidelrc fields and locking
X	1.0; no restrictions on shell users
X	bug; Interrupts, hang-ups
X	done; Error log
X	Better init memory handling
X	done; Better integrity on mail, loses track on dumps
X	done; Tear mail unbatching out of Unidel, use Deliver or external
X	1.0; Use message pager for "Help"
X	1.0; implement PAGER next to internal pager
X	done; Better parsing of strings, instead of strtok.
X	done; New editor
X	guest login
X	Twit control/Aide(co-sysop) priveleges
X	messages moderators
X	re-load new messages/mail
X	move strings to outside file, languages?
X	done; re-do E(nter) C(onfiguration)
X	Trash fsed for something that works
X		^A
X		incomprehensible command set
X		novice mode, help-notice at top of screen
X		truncates long lines
X		termcap/terminfo
X	flush buffer after modes
X	Better modularization
X	better "objectness", Simplify, simplify!
X	Full screen
X	1.0; better input string handling
X	done; SCCS
X	done; Lint
XCommands
X	Easier command set
X	Finish docs
X	create room
X	shell escapes (doors)
X	done; "S(kip)" "G(oto)"s
XUtilities
X	Tool to change/update .fileList entry
X	rmuser shell
X	bbsmaint shell
SHAR_EOF
$TOUCH -am 0502135492 unidel/ToDo &&
chmod 0444 unidel/ToDo ||
echo "restore of unidel/ToDo failed"
set `wc -c unidel/ToDo`;Wc_c=$1
if test "$Wc_c" != "3023"; then
	echo original size 3023, current size $Wc_c
fi
# ============= unidel/Unidel.h ==============
echo "x - extracting unidel/Unidel.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/Unidel.h &&
X/*
X * NAME
X *     Unidel.h -- Basic, global definitions used all over Unidel
X *
X * AUTHOR
X *     Ken MacLeod
X *
X * SCCS
X *     @(#) Unidel.h  1.2 02 May 1992 09:21:04 
X */
X
X/*----------------------------------------------------------------------------
X * Define general things used everywhere.
X */
X
X#define LOG_COMMANDS (0x00000100l)
X#define _outOfMemory outOfMemoryMsg
Xextern char outOfMemoryMsg[];
X 
X#define _findPartial 0x00000001l
X#define _findExact 0x00000000l
X
X#define _normal 0x0000
X#define _noEcho 0x0001
X#define _upperCase 0x0002
X#define _lowerCase 0x0004
X#define _defaultAnswer 0x0008
X#define _defaultYes 0x0010
X
X#define _keyLeft 0x100
X#define _keyRight 0x101
X#define _keyUp 0x102
X#define _keyDown 0x103
X#define _keyAbort 0x104
X
X#define _true 1
X#define _false 0
X
X/* Modes of various sorts */
Xextern int more;		/* 1 = PrintArticle stops at the end of
X				   screens and pages, 2 = stops after title */
Xextern int local;		/* _true = local logon, _false = remote */
Xextern int floorMode;
Xextern int expertMode;
Xextern int guest;
Xextern int finished;
Xextern FILE *dumpFile;		/* file where output is going, usually
X				   'stdout' */
X
Xextern char *months[12], *days[7];
X
Xtypedef struct {
X  char command[4];
X  char *printString[4];
X  long selector;
X  int (*function) ();
X} Menu;
X
Xextern Menu mainMenu[];
Xextern char *selectorStrings[];
X
X/*----------------------------------------------------------------------------
X * Declare functions that are not declared in any standard header file but
X * are used often.
X */
X
Xchar *getenv ();
Xchar *KeepString (/* char *string */);
Xvoid exit ();
SHAR_EOF
$TOUCH -am 0502135492 unidel/Unidel.h &&
chmod 0444 unidel/Unidel.h ||
echo "restore of unidel/Unidel.h failed"
set `wc -c unidel/Unidel.h`;Wc_c=$1
if test "$Wc_c" != "1589"; then
	echo original size 1589, current size $Wc_c
fi
# ============= unidel/User.h ==============
echo "x - extracting unidel/User.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/User.h &&
X/*
X * NAME
X *     User.h -- user definitions
X *
X * AUTHOR
X *     Ken MacLeod
X *
X * SCCS
X *     @(#) User.h  1.4 02 May 1992 09:21:39 
X */
X
Xextern char *homeDir, *logname, *longname;
X
X/* User information */
Xextern int moreDefault;			/* default for more */
Xextern char *terminalType;
Xextern int columns, lines;
Xextern int showSig, seperMsg, jokes;
X
X#define _userMailDirectory 0
X#define _userTerm 1
X#define _userEditor 2
X#define _userMore 3
X#define _userFloorMode 4
X#define _userExpertMode 5
X#define _userTermWidth 6
X#define _userTermHeight 7
X#define _userProtocol 8
X#define _userFloors 9
X#define _userPager 10
X
X#define _controlInvited 0
SHAR_EOF
$TOUCH -am 0502135492 unidel/User.h &&
chmod 0444 unidel/User.h ||
echo "restore of unidel/User.h failed"
set `wc -c unidel/User.h`;Wc_c=$1
if test "$Wc_c" != "635"; then
	echo original size 635, current size $Wc_c
fi
# ============= unidel/defs.dist ==============
echo "x - extracting unidel/defs.dist (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/defs.dist &&
X/*
X * NAME
X *     defs.dist -- template for defs.h
X *
X * AUTHOR
X *     Ken MacLeod
X *
X * SCCS
X *     @(#) defs.dist  1.3 02 May 1992 09:22:29 
X */
X
X/* These should be changed to reflect your site */
X#define _siteName "frobozz"
X#define _siteDomain "uucp"	/* lower case only */
X#define _siteSize 40		/* In free megabytes, used only by .R(ead) S(tatus) */
X#define _organization "Frobozz Inc., St. Louis"
X
X/* These are used when printing =)Headers headers */
X#define _whoLength 18
X
X/* _maxRooms can be changed without problem, though News also needs to be recompiled for more rooms */
X#define _maxRooms 768
X
X#define _version "alpha2"
X#define _bufSize 512
X#define _stringBlockAllocation 1000
X#define _maxFloors 30
X#define _recallName ".newsrc"
X/* _maxMailTransferSize is 58k for compatability with mailers and shouldn't
X	go higher, though lower's OK.  At some later time if file-splitting is
X	implemented then it can go higher.  This is the decision factor on
X	whether an upload article is 'local' or not. */
X#define _maxMailServerSize 58000l
X
X/* BSD type things */
X/*#define strchr index		/* define for BSD */
X/*#define strrchr rindex		/* define for BSD */
X
X/* Programs that Unidel uses to work with */
X#define _mailDelivery "rmail"
X#define _newsDelivery "inews -h"
X#define _listUsersCommand "who -uH"
X#define _chatCommand "talk"
X
X/* these are standard things for Unidel */
X#define _local "/etc/terms"				/* Where tty lines are described	*/
X#define _isLocal "local"				/* String to match for local		*/
X#define _libDir "/usr/lib/citadel/lib"
X#define _docDir "/usr/lib/citadel/doc"
X#define _binDir "/usr/lib/citadel"
X
X/* these are all 'standard' places for these things */
X#define _newsLibDir "/usr/lib/news"
X#define _spoolDir "/usr/spool/news"
X#define _passwdFileName "/etc/passwd"
X#define _aliasFileName "/usr/lib/uucp/aliases"
X#define _pathsFileName "/usr/lib/uucp/paths"
X#define _defaultPath ":/usr/lib/citadel:/usr/local/bin:/usr/acct/bin:/usr/ucb:/usr/bin:/bin"
X#define _defaultShell "/bin/sh"
X
X/* L.sys is Systems in Honey-DanBer */
X#define _systemsFileName "/usr/lib/uucp/L.sys"
X
X/* This is the username of the guest account (not implemented yet) */
X#define _guestName "guest"
X/* adminName is the mail address of the person who supports the message
X   system.  Citadel usage in local and net mail uses "sysop" */
X#define _adminName "sysop"
X
X/* defaultDistribution is the default distribution added to newsgroups with
X   '.' (period) in their name */
X#define _defaultDistribution "local"
X
X/* defaultTerm is the terminal most new unkown users will work with */
X#define _defaultTerm "ansi"
X
X#define _aliasLength 30
X#define _defaultPager "/usr/bin/pg -e -n -p \"Press _\10Q to Quit, _\10R_\10E_\10T_\10U_\10R_\10N to continue.\""
X
X/* Signature mark is the mark that News adds just before the signature, we use
X   it to remove them during display */
X#define _signatureMark "\n-- \n"
SHAR_EOF
$TOUCH -am 0502135492 unidel/defs.dist &&
chmod 0444 unidel/defs.dist ||
echo "restore of unidel/defs.dist failed"
set `wc -c unidel/defs.dist`;Wc_c=$1
if test "$Wc_c" != "2880"; then
	echo original size 2880, current size $Wc_c
fi
# ============= unidel/fgetmfs.3 ==============
echo "x - extracting unidel/fgetmfs.3 (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/fgetmfs.3 &&
X.\"
X.\"  SCCS
X.\"      @(#) fgetmfs.3  1.1 02 May 1992 11:14:21 
X.\"
X.TH FGETMFS 3 local
X.DA 23 May 1989
X.SH NAME
Xfgetmfs \- read an arbitrarily long, possibly continued line
X.SH SYNOPSIS
X.B "#include <stdio.h>
X.br
X.B "#include <fgetmfs.h>
X.PP
X.B "char *fgetmfs(stream, limit, cont)"
X.br
X.B "FILE *stream;"
X.br
X.B "int limit, cont;"
X.PP
X.B "char *fgetms(stream)
X.br
X.B "FILE *stream;"
X.PP
X.B "char *cfgetms(stream)
X.br
X.B "FILE *stream;"
X.SH DESCRIPTION
X.I Fgetmfs
Xreads an arbitrarily long line from
X.IR stream ,
Xallocating memory via
X.IR malloc (3)
Xas needed.
XIf
X.I limit
Xis non-negative,
X.I fgetmfs
Xwill read no more than
X.I limit
Xbytes from
X.IR stream .
XFor efficiency,
Xif
X.I cont
Xis not
X.IR CONT_NO ,
Xsuch as
X.I CONT_NOSPC
Xor
X.IR CONT_SPC ,
Xoccurrences of a backslash and a newline together
Xand in that order
Xwill be deleted from the input stream;
Xif
X.I cont
Xis
X.IR CONT_NOSPC ,
Xany whitespace after the newline
Xin the input stream will also be deleted from it.
X.PP
XThe macros
X.I fgetms
X(to read without continuations)
Xand
X.I cfgetms
X(to read with continuations and remove leading whitespace)
Xshould be used instead when the
X.I limit
Xis not needed.
X.PP
X.I Fgetmfs
Xis intended to provide a reliable mechanism for reading
Xinput containing lines of arbitrary length,
Xrather than trusting that no line with be longer than some
Xarbitrary tolerance.
X.PP
XThe memory returned by
X.I fgetmfs
Xshould be returned when no longer needed via
X.IR free (3).
X.\" .SH FILES
X.SH SEE ALSO
X.IR malloc (3),
X.IR fgets (3)
X.SH DIAGNOSTICS
XReturns NULL (0) if memory cannot be allocated or upon reading end-of-file;
Xuse
X.I feof(stream)
Xto distinguish.
X.SH HISTORY
XWritten by Geoff Collyer
Xat the University of Toronto
Xas part of the C news project.
X.SH BUGS
XIt's too slow.
X.br
XThe meaning of the
X.I cont
Xflag is ugly,
Xbut layering this form of continuation on top is even slower.
SHAR_EOF
$TOUCH -am 0502135492 unidel/fgetmfs.3 &&
chmod 0444 unidel/fgetmfs.3 ||
echo "restore of unidel/fgetmfs.3 failed"
set `wc -c unidel/fgetmfs.3`;Wc_c=$1
if test "$Wc_c" != "1859"; then
	echo original size 1859, current size $Wc_c
fi
# ============= unidel/fgetmfs.c ==============
echo "x - extracting unidel/fgetmfs.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/fgetmfs.c &&
X/*
X * NAME
X *     fgetmfs -- read an arbitrarily long, possibly continued line;
X *                return a pointer to it, in malloced memory.
X */
X/*
X * Copyright (c) University of Toronto 1985, 1986, 1987, 1988, 1989, 1990.
X * All rights reserved.
X * Written mostly by Geoffrey Collyer and Henry Spencer.
X * This software is not subject to any license of the American Telephone
X * and Telegraph Company or of the Regents of the University of California.
X *
X * Permission is granted to anyone to use this software for any purpose on
X * any computer system, and to alter it and redistribute it freely, subject
X * to the following restrictions:
X *
X * 1. The authors are not responsible for the consequences of use of this
X *    software, no matter how awful, even if they arise from flaws in it.
X *
X * 2. The origin of this software must not be misrepresented, either by
X *    explicit claim or by omission.  Since few users ever read sources,
X *    credits must appear in the documentation.
X *
X * 3. Altered versions must be plainly marked as such, and must not be
X *    misrepresented as being the original software.  Since few users
X *    ever read sources, credits must appear in the documentation.
X *
X * 4. This notice may not be removed or altered.
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) fgetmfs.c  1.3 02 May 1992 09:23:12\n\t";
X#endif
X
X#include <stdio.h>
X#include <ctype.h>
X#include <sys/types.h>
X#include <fgetmfs.h>
X#include <malloc.h>
X#include <string.h>
X
Xstatic int getseg ();
Xstatic int ismore ();
X
X#define max(a,b) ((a) > (b)? (a): (b))
X#define min(a,b) ((a) < (b)? (a): (b))
X
X/* One could make these arguments, with defaults. */
X#define INITLN 90		/* initial allocation per line */
X#define GROWLN 200		/* additional allocation size */
X
X/* getseg returns */
X#define FAILED 0
X#define HITLIMIT 1
X#define OKAY 2
X
Xstatic int sz;		/* bytes currently allocated (in line) */
Xstatic int incr;		/* for sz */
Xstatic char *line;		/* current allocation */
Xstatic char *segment;		/* start of line segment in "line" */
Xstatic char *morep;		/* last byte possibly containing input */
X
X/*
X * `fget malloced, flagged string' with continuations and limit on bytes.
X * The limit is like fgets's; limit-1 bytes can be read.  -1 means "no limit".
X */
Xchar *
Xfgetmfs(fp, limit, cont)
XFILE *fp;
Xregister int limit;
Xregister int cont;		/* honour \ continuations? */
X{
X	/* allocate room for an initial segment of a line */
X	sz = INITLN;
X	incr = GROWLN;
X	if (limit >= 0 && sz > limit)
X		sz = limit;
X	line = (char *)malloc((size_t) sz);
X	if (line == NULL)
X		return NULL;		/* no memory, can't go on */
X	segment = line;
X	morep = line + sz - 2;
X
X	/* read all lines, including continuations */
X	do {
X		/* read the first segment of a line */
X		*morep = '\0';			/* mark end of segment */
X		if (fgets(segment, (int)sz-(segment-line), fp) == NULL) {
X			free((malloc_t)line);		/* EOF: give up */
X			return NULL;
X		}
X
X		/* read more of this line, if it didn't fit */
X		while (*morep != '\0' && *morep != '\n') {
X			register int code = getseg(fp, limit);
X
X			if (code == FAILED)
X				return NULL;
X			else if (code == HITLIMIT)
X				break;
X		}
X	} while (cont && ismore(fp, cont));
X	return (char *)realloc((malloc_t)line, (size_t)(strlen(line)+1));	/* save space */
X}
X
Xstatic int
Xgetseg(fp, limit)
XFILE *fp;
Xregister int limit;
X{
X	register int oldsz = sz;
X
X	/* extend the allocation, within limit */
X	incr = GROWLN;
X	sz += incr;
X	if (limit >= 0 && sz > limit) {
X		sz = limit;
X		incr = sz - oldsz;
X	}
X	if (incr <= 0)			/* hit the limit? */
X		return HITLIMIT;
X	line = (char *)realloc((malloc_t)line, (size_t) sz);
X	if (line == NULL)
X		return FAILED;		/* no memory, can't go on */
X	/* -1 starts on the terminating NUL of the prev. segment */
X	segment = line + oldsz - 1;
X	morep = line + sz - 2;		/* recompute for new line, sz */
X
X	/* read the next segment */
X	*morep = '\0';
X	/* +1 because segment includes terminating NUL of the prev. segment */
X	if (fgets(segment, incr+1, fp) == NULL) {
X	  free((malloc_t)line);		/* EOF: give up */
X		return FAILED;
X	}
X	return OKAY;
X}
X
Xstatic int
Xismore(fp, cont)
Xregister FILE *fp;
Xint cont;
X{
X	register char *nlp;
X
X	/* got a whole line: is it to be continued? */
X	if (incr > 0 && cont && (nlp = strrchr(line, '\n')) != NULL &&
X	    nlp > line && *--nlp == '\\') {
X		*nlp = '\0';			/* delete "\\\n" */
X		segment = nlp;
X	    	if (cont == CONT_NOSPC) {
X			register int c;
X
X			/* discard leading whitespace */
X			while ((c = getc(fp)) != EOF && c != '\n' &&
X			   isascii(c) && isspace(c))
X				;
X			if (c != EOF)
X				(void) ungetc(c, fp);
X	    	}
X		return 1;			/* read next line */
X	} else
X		return 0;
X}
SHAR_EOF
$TOUCH -am 0502135492 unidel/fgetmfs.c &&
chmod 0444 unidel/fgetmfs.c ||
echo "restore of unidel/fgetmfs.c failed"
set `wc -c unidel/fgetmfs.c`;Wc_c=$1
if test "$Wc_c" != "4612"; then
	echo original size 4612, current size $Wc_c
fi
# ============= unidel/fgetmfs.h ==============
echo "x - extracting unidel/fgetmfs.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/fgetmfs.h &&
X/*
X * NAME
X *     fgetmfs.h -- definitions for fgetmfs
X *
X * AUTHOR
X *     Ken MacLeod
X *
X * SCCS
X *     @(#) fgetmfs.h  1.1 11 Nov 1990 07:43:54 
X */
X
X/* values for fgetmfs flag */
X#define CONT_NO 0		/* no continuations */
X#define CONT_NOSPC 1		/* continue & remove leading whitespace */
X#define CONT_SPC 2		/* continue & keep leading whitespace */
X
Xextern char *fgetmfs();			/* internal interface */
X
X/* external interfaces */
X#define fgetms(fp) fgetmfs(fp, -1, CONT_NO)	/* unbounded read */
X#define cfgetms(fp) fgetmfs(fp, -1, CONT_NOSPC)	/* unbounded read w continuation */
SHAR_EOF
$TOUCH -am 0502135492 unidel/fgetmfs.h &&
chmod 0444 unidel/fgetmfs.h ||
echo "restore of unidel/fgetmfs.h failed"
set `wc -c unidel/fgetmfs.h`;Wc_c=$1
if test "$Wc_c" != "578"; then
	echo original size 578, current size $Wc_c
fi
# ============= unidel/ftime.c ==============
echo "x - extracting unidel/ftime.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/ftime.c &&
X/*
X * NAME
X *     ftime.c -- bsd ftime for use in sys v systems
X *
X * AUTHOR
X *     Ken MacLeod
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) ftime.c  1.2 02 May 1992 09:24:38\n\t";
X#endif
X
X#include <sys/types.h>
X#include <sys/timeb.h>
X
Xextern long timezone;
Xextern int  daylight;
X
Xvoid
Xftime(tp)
Xstruct timeb *tp;
X{
X	long t, time();
X
X	(void) time(&t);
X	tp->time = t;
X	tp->millitm = 0;
X	tp->timezone = timezone/60;
X	tp->dstflag = (char) daylight;
X}
SHAR_EOF
$TOUCH -am 0502135492 unidel/ftime.c &&
chmod 0444 unidel/ftime.c ||
echo "restore of unidel/ftime.c failed"
set `wc -c unidel/ftime.c`;Wc_c=$1
if test "$Wc_c" != "451"; then
	echo original size 451, current size $Wc_c
fi
# ============= unidel/getdate.y ==============
echo "x - extracting unidel/getdate.y (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/getdate.y &&
X%token ID MONTH DAY MERIDIAN NUMBER UNIT MUNIT SUNIT ZONE DAYZONE AGO
X%{
X/*
X * NAME
X *     getdate.y -- parser for converting ASCII dates and times to seconds
X *
X * AUTHOR
X * 	Steven M. Bellovin (unc!smb)
X *	Dept. of Computer Science
X *	University of North Carolina at Chapel Hill
X *	@(#)getdate.y	2.15	12/16/86
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) getdate.y  1.2 06 Jun 1991 18:02:34\n\t";
X#endif
X
X
X#include <sys/types.h>
X#include <sys/timeb.h>
X#include <ctype.h>
X
X#if defined(BSD4_2) || defined (BSD4_1C)
X#include <sys/time.h>
X#else /* sane */
X#include <time.h>
X#endif /* sane */
X
X#define	NULL	0
X#define daysec (24L*60L*60L)
X	static int timeflag, zoneflag, dateflag, dayflag, relflag;
X	static time_t relsec, relmonth;
X	static int hh, mm, ss, merid, daylite;
X	static int dayord, dayreq;
X	static int month, day, year;
X	static int ourzone;
X#define AM 1
X#define PM 2
X#define DAYLIGHT 1
X#define STANDARD 2
X#define MAYBE    3
X%}
X
X%%
Xtimedate: 		/* empty */
X	| timedate item;
X
Xitem:	tspec =
X		{timeflag++;}
X	| zone =
X		{zoneflag++;}
X	| dtspec =
X		{dateflag++;}
X	| dyspec =
X		{dayflag++;}
X	| rspec =
X		{relflag++;}
X	| nspec;
X
Xnspec:	NUMBER =
X		{if (timeflag && dateflag && !relflag) year = $1;
X		else {timeflag++;hh = $1/100;mm = $1%100;ss = 0;merid = 24;}};
X
Xtspec:	NUMBER MERIDIAN =
X		{hh = $1; mm = 0; ss = 0; merid = $2;}
X	| NUMBER ':' NUMBER =
X		{hh = $1; mm = $3; merid = 24;}
X	| NUMBER ':' NUMBER MERIDIAN =
X		{hh = $1; mm = $3; merid = $4;}
X	| NUMBER ':' NUMBER NUMBER =
X		{hh = $1; mm = $3; merid = 24;
X		daylite = STANDARD; ourzone = -($4%100 + 60*($4/100));}
X	| NUMBER ':' NUMBER ':' NUMBER =
X		{hh = $1; mm = $3; ss = $5; merid = 24;}
X	| NUMBER ':' NUMBER ':' NUMBER MERIDIAN =
X		{hh = $1; mm = $3; ss = $5; merid = $6;}
X	| NUMBER ':' NUMBER ':' NUMBER NUMBER =
X		{hh = $1; mm = $3; ss = $5; merid = 24;
X		daylite = STANDARD; ourzone = -($6%100 + 60*($6/100));};
X
Xzone:	ZONE =
X		{ourzone = $1; daylite = STANDARD;}
X	| DAYZONE =
X		{ourzone = $1; daylite = DAYLIGHT;};
X
Xdyspec:	DAY =
X		{dayord = 1; dayreq = $1;}
X	| DAY ',' =
X		{dayord = 1; dayreq = $1;}
X	| NUMBER DAY =
X		{dayord = $1; dayreq = $2;};
X
Xdtspec:	NUMBER '/' NUMBER =
X		{month = $1; day = $3;}
X	| NUMBER '/' NUMBER '/' NUMBER =
X		{month = $1; day = $3; year = $5;}
X	| MONTH NUMBER =
X		{month = $1; day = $2;}
X	| MONTH NUMBER ',' NUMBER =
X		{month = $1; day = $2; year = $4;}
X	| NUMBER MONTH =
X		{month = $2; day = $1;}
X	| NUMBER MONTH NUMBER =
X		{month = $2; day = $1; year = $3;};
X
X
Xrspec:	NUMBER UNIT =
X		{relsec +=  60L * $1 * $2;}
X	| NUMBER MUNIT =
X		{relmonth += $1 * $2;}
X	| NUMBER SUNIT =
X		{relsec += $1;}
X	| UNIT =
X		{relsec +=  60L * $1;}
X	| MUNIT =
X		{relmonth += $1;}
X	| SUNIT =
X		{relsec++;}
X	| rspec AGO =
X		{relsec = -relsec; relmonth = -relmonth;};
X%%
X
Xstatic int mdays[12] =
X	{31, 0, 31,  30, 31, 30,  31, 31, 30,  31, 30, 31};
X#define epoch 1970
X
Xextern struct tm *localtime();
X
Xtime_t
Xdateconv(mm, dd, yy, h, m, s, mer, zone, dayflag)
Xint mm, dd, yy, h, m, s, mer, zone, dayflag;
X{
X	time_t tod, jdate;
X	register int i;
X	time_t timeconv();
X
X	if (yy < 0) yy = -yy;
X	if (yy < 100) yy += 1900;
X	mdays[1] = 28 + (yy%4 == 0 && (yy%100 != 0 || yy%400 == 0));
X	if (yy < epoch || yy > 1999 || mm < 1 || mm > 12 ||
X		dd < 1 || dd > mdays[--mm]) return (-1);
X	jdate = dd-1;
X        for (i=0; i<mm; i++) jdate += mdays[i];
X	for (i = epoch; i < yy; i++) jdate += 365 + (i%4 == 0);
X	jdate *= daysec;
X	jdate += zone * 60L;
X	if ((tod = timeconv(h, m, s, mer)) < 0) return (-1);
X	jdate += tod;
X	if (dayflag==DAYLIGHT || (dayflag==MAYBE&&localtime(&jdate)->tm_isdst))
X		jdate += -1*60*60;
X	return (jdate);
X}
X
Xtime_t
Xdayconv(ord, day, now)
Xint ord, day; time_t now;
X{
X	register struct tm *loctime;
X	time_t tod;
X	time_t daylcorr();
X
X	tod = now;
X	loctime = localtime(&tod);
X	tod += daysec * ((day - loctime->tm_wday + 7) % 7);
X	tod += 7*daysec*(ord<=0?ord:ord-1);
X	return daylcorr(tod, now);
X}
X
Xtime_t
Xtimeconv(hh, mm, ss, mer)
Xregister int hh, mm, ss, mer;
X{
X	if (mm < 0 || mm > 59 || ss < 0 || ss > 59) return (-1);
X	switch (mer) {
X		case AM: if (hh < 1 || hh > 12) return(-1);
X			 return (60L * ((hh%12)*60L + mm)+ss);
X		case PM: if (hh < 1 || hh > 12) return(-1);
X			 return (60L * ((hh%12 +12)*60L + mm)+ss);
X		case 24: if (hh < 0 || hh > 23) return (-1);
X			 return (60L * (hh*60L + mm)+ss);
X		default: return (-1);
X	}
X}
Xtime_t
Xmonthadd(sdate, relmonth)
Xtime_t sdate, relmonth;
X{
X	struct tm *ltime;
X	time_t dateconv();
X	time_t daylcorr();
X	int mm, yy;
X
X	if (relmonth == 0) return 0;
X	ltime = localtime(&sdate);
X	mm = 12*ltime->tm_year + ltime->tm_mon + relmonth;
X	yy = mm/12;
X	mm = mm%12 + 1;
X	return daylcorr(dateconv(mm, ltime->tm_mday, yy, ltime->tm_hour,
X		ltime->tm_min, ltime->tm_sec, 24, ourzone, MAYBE), sdate);
X}
X
Xtime_t
Xdaylcorr(future, now)
Xtime_t future, now;
X{
X	int fdayl, nowdayl;
X
X	nowdayl = (localtime(&now)->tm_hour+1) % 24;
X	fdayl = (localtime(&future)->tm_hour+1) % 24;
X	return (future-now) + 60L*60L*(nowdayl-fdayl);
X}
X
Xstatic char *lptr;
X
Xyylex()
X{
X	extern int yylval;
X	int sign;
X	register char c;
X	register char *p;
X	char idbuf[20];
X	int pcnt;
X
X	for (;;) {
X		while (isspace(*lptr))
X			lptr++;
X
X		if (isdigit(c = *lptr) || c == '-' || c == '+') {
X			if (c== '-' || c == '+') {
X				if (c=='-') sign = -1;
X				else sign = 1;
X				if (!isdigit(*++lptr)) {
X					/* yylval = sign; return (NUMBER); */
X					return yylex();	/* skip the '-' sign */
X				}
X			} else sign = 1;
X			yylval = 0;
X			while (isdigit(c = *lptr++))
X				yylval = 10*yylval + c - '0';
X			yylval *= sign;
X			lptr--;
X			return (NUMBER);
X
X		} else if (isalpha(c)) {
X			p = idbuf;
X			while (isalpha(c = *lptr++) || c=='.')
X				*p++ = c;
X			*p = '\0';
X			lptr--;
X			return (lookup(idbuf));
X		}
X
X		else if (c == '(') {
X			pcnt = 0;
X			do {
X				c = *lptr++;
X				if (c == '\0') return(c);
X				else if (c == '(') pcnt++;
X				else if (c == ')') pcnt--;
X			} while (pcnt > 0);
X		}
X
X		else return (*lptr++);
X	}
X}
X
Xstruct table {
X	char *name;
X	int type, value;
X};
X
Xstruct table mdtab[] = {
X	{"january", MONTH, 1},
X	{"february", MONTH, 2},
X	{"march", MONTH, 3},
X	{"april", MONTH, 4},
X	{"may", MONTH, 5},
X	{"june", MONTH, 6},
X	{"july", MONTH, 7},
X	{"august", MONTH, 8},
X	{"september", MONTH, 9},
X	{"sept", MONTH, 9},
X	{"october", MONTH, 10},
X	{"november", MONTH, 11},
X	{"december", MONTH, 12},
X
X	{"sunday", DAY, 0},
X	{"monday", DAY, 1},
X	{"tuesday", DAY, 2},
X	{"tues", DAY, 2},
X	{"wednesday", DAY, 3},
X	{"wednes", DAY, 3},
X	{"thursday", DAY, 4},
X	{"thur", DAY, 4},
X	{"thurs", DAY, 4},
X	{"friday", DAY, 5},
X	{"saturday", DAY, 6},
X	{0, 0, 0}};
X
X#define HRS *60
X#define HALFHR 30
Xstruct table mztab[] = {
X	{"a.m.", MERIDIAN, AM},
X	{"am", MERIDIAN, AM},
X	{"p.m.", MERIDIAN, PM},
X	{"pm", MERIDIAN, PM},
X	{"nst", ZONE, 3 HRS + HALFHR},		/* Newfoundland */
X	{"n.s.t.", ZONE, 3 HRS + HALFHR},
X	{"ast", ZONE, 4 HRS},		/* Atlantic */
X	{"a.s.t.", ZONE, 4 HRS},
X	{"adt", DAYZONE, 4 HRS},
X	{"a.d.t.", DAYZONE, 4 HRS},
X	{"est", ZONE, 5 HRS},		/* Eastern */
X	{"e.s.t.", ZONE, 5 HRS},
X	{"edt", DAYZONE, 5 HRS},
X	{"e.d.t.", DAYZONE, 5 HRS},
X	{"cst", ZONE, 6 HRS},		/* Central */
X	{"c.s.t.", ZONE, 6 HRS},
X	{"cdt", DAYZONE, 6 HRS},
X	{"c.d.t.", DAYZONE, 6 HRS},
X	{"mst", ZONE, 7 HRS},		/* Mountain */
X	{"m.s.t.", ZONE, 7 HRS},
X	{"mdt", DAYZONE, 7 HRS},
X	{"m.d.t.", DAYZONE, 7 HRS},
X	{"pst", ZONE, 8 HRS},		/* Pacific */
X	{"p.s.t.", ZONE, 8 HRS},
X	{"pdt", DAYZONE, 8 HRS},
X	{"p.d.t.", DAYZONE, 8 HRS},
X	{"yst", ZONE, 9 HRS},		/* Yukon */
X	{"y.s.t.", ZONE, 9 HRS},
X	{"ydt", DAYZONE, 9 HRS},
X	{"y.d.t.", DAYZONE, 9 HRS},
X	{"hst", ZONE, 10 HRS},		/* Hawaii */
X	{"h.s.t.", ZONE, 10 HRS},
X	{"hdt", DAYZONE, 10 HRS},
X	{"h.d.t.", DAYZONE, 10 HRS},
X
X	{"gmt", ZONE, 0 HRS},
X	{"g.m.t.", ZONE, 0 HRS},
X	{"bst", DAYZONE, 0 HRS},		/* British Summer Time */
X	{"b.s.t.", DAYZONE, 0 HRS},
X	{"eet", ZONE, 0 HRS},		/* European Eastern Time */
X	{"e.e.t.", ZONE, 0 HRS},
X	{"eest", DAYZONE, 0 HRS},	/* European Eastern Summer Time */
X	{"e.e.s.t.", DAYZONE, 0 HRS},
X	{"met", ZONE, -1 HRS},		/* Middle European Time */
X	{"m.e.t.", ZONE, -1 HRS},
X	{"mest", DAYZONE, -1 HRS},	/* Middle European Summer Time */
X	{"m.e.s.t.", DAYZONE, -1 HRS},
X	{"wet", ZONE, -2 HRS },		/* Western European Time */
X	{"w.e.t.", ZONE, -2 HRS },
X	{"west", DAYZONE, -2 HRS},	/* Western European Summer Time */
X	{"w.e.s.t.", DAYZONE, -2 HRS},
X
X	{"jst", ZONE, -9 HRS},		/* Japan Standard Time */
X	{"j.s.t.", ZONE, -9 HRS},	/* Japan Standard Time */
X					/* No daylite savings time */
X
X	{"aest", ZONE, -10 HRS},	/* Australian Eastern Time */
X	{"a.e.s.t.", ZONE, -10 HRS},
X	{"aesst", DAYZONE, -10 HRS},	/* Australian Eastern Summer Time */
X	{"a.e.s.s.t.", DAYZONE, -10 HRS},
X	{"acst", ZONE, -(9 HRS + HALFHR)},	/* Australian Central Time */
X	{"a.c.s.t.", ZONE, -(9 HRS + HALFHR)},
X	{"acsst", DAYZONE, -(9 HRS + HALFHR)},	/* Australian Central Summer */
X	{"a.c.s.s.t.", DAYZONE, -(9 HRS + HALFHR)},
X	{"awst", ZONE, -8 HRS},		/* Australian Western Time */
X	{"a.w.s.t.", ZONE, -8 HRS},	/* (no daylite time there, I'm told */
X	{0, 0, 0}};
X
Xstruct table unittb[] = {
X	{"year", MUNIT, 12},
X	{"month", MUNIT, 1},
X	{"fortnight", UNIT, 14*24*60},
X	{"week", UNIT, 7*24*60},
X	{"day", UNIT, 1*24*60},
X	{"hour", UNIT, 60},
X	{"minute", UNIT, 1},
X	{"min", UNIT, 1},
X	{"second", SUNIT, 1},
X	{"sec", SUNIT, 1},
X	{0, 0, 0}};
X
Xstruct table othertb[] = {
X	{"tomorrow", UNIT, 1*24*60},
X	{"yesterday", UNIT, -1*24*60},
X	{"today", UNIT, 0},
X	{"now", UNIT, 0},
X	{"last", NUMBER, -1},
X	{"this", UNIT, 0},
X	{"next", NUMBER, 2},
X	{"first", NUMBER, 1},
X	/* {"second", NUMBER, 2}, */
X	{"third", NUMBER, 3},
X	{"fourth", NUMBER, 4},
X	{"fifth", NUMBER, 5},
X	{"sixth", NUMBER, 6},
X	{"seventh", NUMBER, 7},
X	{"eigth", NUMBER, 8},
X	{"ninth", NUMBER, 9},
X	{"tenth", NUMBER, 10},
X	{"eleventh", NUMBER, 11},
X	{"twelfth", NUMBER, 12},
X	{"ago", AGO, 1},
X	{0, 0, 0}};
X
Xstruct table milzone[] = {
X	{"a", ZONE, 1 HRS},
X	{"b", ZONE, 2 HRS},
X	{"c", ZONE, 3 HRS},
X	{"d", ZONE, 4 HRS},
X	{"e", ZONE, 5 HRS},
X	{"f", ZONE, 6 HRS},
X	{"g", ZONE, 7 HRS},
X	{"h", ZONE, 8 HRS},
X	{"i", ZONE, 9 HRS},
X	{"k", ZONE, 10 HRS},
X	{"l", ZONE, 11 HRS},
X	{"m", ZONE, 12 HRS},
X	{"n", ZONE, -1 HRS},
X	{"o", ZONE, -2 HRS},
X	{"p", ZONE, -3 HRS},
X	{"q", ZONE, -4 HRS},
X	{"r", ZONE, -5 HRS},
X	{"s", ZONE, -6 HRS},
X	{"t", ZONE, -7 HRS},
X	{"u", ZONE, -8 HRS},
X	{"v", ZONE, -9 HRS},
X	{"w", ZONE, -10 HRS},
X	{"x", ZONE, -11 HRS},
X	{"y", ZONE, -12 HRS},
X	{"z", ZONE, 0 HRS},
X	{0, 0, 0}};
X
Xlookup(id)
Xchar *id;
X{
X#define gotit (yylval=i->value,  i->type)
X
X	char idvar[128], *strcpy ();
X	register char *j, *k;
X	register struct table *i;
X	int abbrev;
X
X	(void) strcpy(idvar, id);
X	j = idvar;
X	k = id - 1;
X	while (*++k)
X		*j++ = isupper(*k) ? tolower(*k) : *k;
X	*j = '\0';
X
X	if (strlen(idvar) == 3)
X		abbrev = 1;
X	else
X		if (strlen(idvar) == 4 && idvar[3] == '.') {
X			abbrev = 1;
X			idvar[3] = '\0';
X		}
X	else
X		abbrev = 0;
X
X	for (i = mdtab; i->name; i++) {
X		k = idvar;
X		for (j = i->name; *j++ == *k++;) {
X			if (abbrev && j == i->name+3)
X				return gotit;
X			if (j[-1] == 0)
X				return gotit;
X		}
X	}
X
X	for (i = mztab; i->name; i++)
X		if (strcmp(i->name, idvar) == 0)
X			return gotit;
X
X	for (i=mztab; i->name; i++)
X		if (strcmp(i->name, idvar) == 0)
X			return gotit;
X
X	for (i=unittb; i->name; i++)
X		if (strcmp(i->name, idvar) == 0)
X			return gotit;
X
X	if (idvar[strlen(idvar)-1] == 's')
X		idvar[strlen(idvar)-1] = '\0';
X
X	for (i=unittb; i->name; i++)
X		if (strcmp(i->name, idvar) == 0)
X			return gotit;
X
X	for (i = othertb; i->name; i++)
X		if (strcmp(i->name, idvar) == 0)
X			return gotit;
X
X	if (strlen(idvar) == 1 && isalpha(*idvar)) {
X		for (i = milzone; i->name; i++)
X			if (strcmp(i->name, idvar) == 0)
X				return gotit;
X	}
X
X	return ID;
X}
X
Xtime_t
Xparsedate(p, now)
Xchar *p;
Xstruct timeb *now;
X{
X#define mcheck(f)	if (f>1) err++
X	time_t monthadd();
X	int err;
X	struct tm *lt;
X	struct timeb ftz;
X
X	time_t sdate, tod;
X
X	lptr = p;
X	if (now == ((struct timeb *) NULL)) {
X		now = &ftz;
X		ftime(&ftz);
X	}
X	lt = localtime(&now->time);
X	year = lt->tm_year;
X	month = lt->tm_mon+1;
X	day = lt->tm_mday;
X	relsec = 0; relmonth = 0;
X	timeflag=zoneflag=dateflag=dayflag=relflag=0;
X	ourzone = now->timezone;
X	daylite = MAYBE;
X	hh = mm = ss = 0;
X	merid = 24;
X
X	if (err = yyparse()) return (-1);
X
X	mcheck(timeflag);
X	mcheck(zoneflag);
X	mcheck(dateflag);
X	mcheck(dayflag);
X
X	if (err) return (-1);
X	if (dateflag || timeflag || dayflag) {
X		sdate = dateconv(month,day,year,hh,mm,ss,merid,ourzone,daylite);
X		if (sdate < 0) return -1;
X	}
X	else {
X		sdate = now->time;
X		if (relflag == 0)
X			sdate -= (lt->tm_sec + lt->tm_min*60 +
X				lt->tm_hour*(60L*60L));
X	}
X
X	sdate += relsec;
X	sdate += monthadd(sdate, relmonth);
X
X	if (dayflag && !dateflag) {
X		tod = dayconv(dayord, dayreq, sdate);
X		sdate += tod;
X	}
X
X	return sdate;
X}
X
Xyyerror(s) char *s;
X{}
SHAR_EOF
$TOUCH -am 0502135492 unidel/getdate.y &&
chmod 0444 unidel/getdate.y ||
echo "restore of unidel/getdate.y failed"
set `wc -c unidel/getdate.y`;Wc_c=$1
if test "$Wc_c" != "12625"; then
	echo original size 12625, current size $Wc_c
fi
# ============= unidel/getdefs.c ==============
echo "x - extracting unidel/getdefs.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/getdefs.c &&
X/*
X * NAME:
X *     getdefs  --  retreive defaults from the default file.
X *
X * SYNOPSIS
X *     #include <getenvs.h>
X *
X *     int getdefs (char *progName, char *fileName, Envs *envs)
X *
X * DESCRIPTION
X *    getdefs will go through the file fileName, picking up default
X *    values for program progName that correspond with values in
X *    envs.  getdefs places the name and value pair into the
X *    environment.
X *
X *    Lines not beginning with progName are ignored.
X *
X * DIAGNOSTICS
X *     Returns -1 on fatal failure (out of memory), 0 otherwise.
X *
X * AUTHOR
X *     Ken MacLeod
X *
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) getdefs.c  1.2 02 May 1992 09:25:23\n\t";
X#endif
X
X
X#include <stdio.h>
X#include <string.h>
X#include <malloc.h>
X#include <getenvs.h>
X#include <fgetmfs.h>
X
Xextern int putenvs ();
X
Xint
Xgetdefs (progName, fileName, envs)
X     char *progName, *fileName;
X     Envs *envs;
X{
X  FILE *file;
X  char *pp, *fileLine, *name, *value;
X
X  file = fopen (fileName, "r");
X  if (file == NULL)
X    return (0);			/* Don't let a little misunderstanding
X				   get us down. */
X
X  while ((fileLine = cfgetms (file)) != NULL) {
X    /* Get program name */
X    pp = strtok (fileLine, " \t");
X    if ((pp == NULL) || (strcmp (pp, progName) != 0))
X      goto cleanUpAndContinue;	/* Not our program */
X
X    /* Get environment name and value */
X    name = strtok ((char *)NULL, "=");
X    if (name == NULL)
X      goto cleanUpAndContinue;	/* no valid name */
X    value = strtok ((char *)NULL, "\n");
X    if (value == NULL)
X      goto cleanUpAndContinue;	/* no valid value (actually, cgetms failed) */
X
X    if (putenvs (envs, name, value) == -1) {
X      /* out of memory */
X      free ((malloc_t)fileLine);
X      (void)fclose (file);
X      return (-1);
X    }
X
XcleanUpAndContinue:
X    free ((malloc_t) fileLine);
X  }
X  /* if not end of file, then it's out of memory */
X  if (!feof (file)) {
X    (void)fclose (file);
X    return (-1);
X  }
X
X  (void)fclose (file);
X
X  return (0);
X}
SHAR_EOF
$TOUCH -am 0502135492 unidel/getdefs.c &&
chmod 0444 unidel/getdefs.c ||
echo "restore of unidel/getdefs.c failed"
set `wc -c unidel/getdefs.c`;Wc_c=$1
if test "$Wc_c" != "1977"; then
	echo original size 1977, current size $Wc_c
fi
# ============= unidel/getenvs.c ==============
echo "x - extracting unidel/getenvs.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/getenvs.c &&
X/*
X * NAME:
X *     getenvs -- get a list of environment variables
X *
X * SYNOPSIS
X *     #include <getenvs.h>
X *
X *     int getenvs (Envs *envs)
X *
X * DESCRIPTION
X *    getenvs will go through the array pointed to by envs checking
X *    for the existence of each environment variable, or using the
X *    firm-coded value.
X *
X * DIAGNOSTICS
X *     Returns -1 on failure (out of memory), 0 otherwise.
X *
X * AUTHOR
X *      Ken MacLeod
X *
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) getenvs.c  1.3 02 May 1992 09:25:48\n\t";
X#endif
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <malloc.h>
X#include <getenvs.h>
X#include <string.h>
X
Xint putenv ();
X
Xint
Xgetenvs (envs)
X     Envs *envs;
X{
X  char *pp, *getenv();
X  int nameLen;
X  
X  while (envs -> name != NULL) {
X    pp = getenv (envs -> name);
X    if (pp == NULL) {		/* No env variable */
X      if (envs -> def != NULL) { /* Have default */
X	nameLen = strlen(envs -> name);
X	envs -> env = (char *)malloc (nameLen + strlen(envs -> def) + 2);
X	if (envs -> env == NULL)
X	  return (-1);
X	(void) sprintf (envs -> env, "%s=%s", envs->name,
X			envs -> def);
X	envs -> valueStr = &envs -> env[nameLen + 1];
X	if (putenv (envs -> env) != 0)
X	  return (-1);
X      } else {			/* do not have default */
X	envs -> env = NULL;
X	envs -> valueStr = NULL;
X      }
X    } else {			/* have env variable */
X      envs -> env = NULL;
X      envs -> valueStr = pp;
X    }
X    if (envs -> valueStr != NULL && envs -> scan != NULL) {
X      /* we have a value and want to scan */
X      if (envs -> scan[0] == 'P') /* Copy string pointer only */
X	*((char **) envs -> value) = envs -> valueStr;
X      else			/* Scan value */
X        (void) sscanf (envs -> valueStr, envs -> scan, envs -> value);
X    }
X    envs ++;
X  }
X  return (0);
X}
X
Xint
Xputenvs (envs, name, value)
X     Envs *envs;
X     char *name, *value;
X{
X  char *pp;
X  int nameLen;
X  
X  while ((envs -> name != NULL) && (strcmp (name, envs -> name) != 0))
X    envs ++;
X
X  if (envs -> name == NULL) {	/* set up for temporary use of last entry */
X    envs -> env = NULL;		/* alloc new space */
X    envs -> scan = NULL;	/* don't scan */
X  }
X  
X  nameLen = strlen (name);
X  if (envs -> env != NULL)
X    pp = (char *)realloc ((malloc_t)envs -> env, (size_t) nameLen + strlen(value) + 2);
X  else
X    pp = (char *)malloc (nameLen + strlen(value) + 2);
X  if (pp == NULL)
X    return (-1);
X  (void) sprintf (pp, "%s=%s", name, value);
X  envs -> env = pp;
X  envs -> valueStr = &envs -> env[nameLen + 1];
X  if (envs -> scan != NULL) {	/* we have another place to put it */
X    if (envs -> scan[0] == 'P') /* Copy string pointer only */
X      *((char **) envs -> value) = envs -> valueStr;
X    else			/* Scan value */
X      (void) sscanf (envs -> valueStr, envs -> scan, envs -> value);
X  }
X  if (putenv (pp) != 0)
X    return (-1);
X
X  return (0);
X}
SHAR_EOF
$TOUCH -am 0502135492 unidel/getenvs.c &&
chmod 0444 unidel/getenvs.c ||
echo "restore of unidel/getenvs.c failed"
set `wc -c unidel/getenvs.c`;Wc_c=$1
if test "$Wc_c" != "2812"; then
	echo original size 2812, current size $Wc_c
fi
# ============= unidel/getenvs.h ==============
echo "x - extracting unidel/getenvs.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/getenvs.h &&
X/*
X * NAME
X *      getenvs.h  --  include file for getenvs and putenvs
X *
X * AUTHOR
X *     Ken MacLeod
X *
X * SCCS
X *     @(#) getenvs.h  1.1 11 Nov 1990 07:41:24 
X */
X
Xstruct _Envs {
X  char *name;	   /* The name of the environment value */
X  char *def;       /* it's default value, or NULL for none */
X  char *env;	   /* storage for malloc'ed env string, init NULL */
X  char *valueStr;  /* pointer into env or returned from getenv */
X  char *scan;	   /* scan format, "P"=pointer copy, NULL=no scan */
X  void *value;	   /* pointer to recipient of scan  */
X};
X
Xtypedef struct _Envs Envs;
SHAR_EOF
$TOUCH -am 0502135492 unidel/getenvs.h &&
chmod 0444 unidel/getenvs.h ||
echo "restore of unidel/getenvs.h failed"
set `wc -c unidel/getenvs.h`;Wc_c=$1
if test "$Wc_c" != "586"; then
	echo original size 586, current size $Wc_c
fi
# ============= unidel/protos.h ==============
echo "x - extracting unidel/protos.h (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/protos.h &&
X/*
X *   XXX This file sucks.  It shouldn't be here.  Yell at me for even
X * thinking it.
X *
X * SCCS
X *     @(#) protos.h  1.1 02 May 1992 11:13:07 
X */
X
Xvoid ScanNewArticles ();
Xvoid SetupTerminal ();
Xint IsIn ();
Xint getenvs ();
Xint access ();
Xint mkdir ();
Xint close ();
Xint creat ();
Xint putenvs ();
Xint atoi ();
Xvoid SetupTransferProtocol ();
Xvoid SetupEditor ();
Xint nstrip ();
Xint split ();
Xvoid PrintRoomsWithUnreadMessages ();
Xvoid Goto ();
Xint DoMenu ();
Xvoid GetString ();
Xint AnswerYesNo ();
Xvoid Columnize ();
Xint FindRoom ();
Xvoid MarkRead ();
Xvoid Goto ();
Xint IsIn ();
Xvoid AllocString ();
Xint Edit ();
Xint GetChar ();
Xint GetStringWDefault ();
Xvoid WriteHeader ();
Xint unlink ();
Xvoid BreakFrom ();
Xvoid PrintShortHeader ();
Xint UserCommand ();
Xvoid Help ();
Xint EnterMessage ();
Xint ValidAddresses ();
Xint PrintMessage ();
Xvoid ReadOneFile ();
Xint ReadHeader ();
SHAR_EOF
$TOUCH -am 0502135492 unidel/protos.h &&
chmod 0444 unidel/protos.h ||
echo "restore of unidel/protos.h failed"
set `wc -c unidel/protos.h`;Wc_c=$1
if test "$Wc_c" != "880"; then
	echo original size 880, current size $Wc_c
fi
# ============= unidel/localize.sh ==============
echo "x - extracting unidel/localize.sh (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/localize.sh &&
Xrm -f Makefile
Xcp Make.dist Makefile
Xchmod u+w Makefile
Xed - Makefile <<'EOF'
X/^CFLAGS/s/-O/-g -Dmalloc_t=\"char*\"/
Xw
Xq
XEOF
Xrm -f defs.h
Xcp defs.dist defs.h
Xchmod u+w defs.h
Xed - defs.h <<'EOF'
X/_siteName/s/frobozz/bitsko.slc.ut.us/
X/_organization/s/Frobozz Inc., St. Louis/Bitsko's Bar \& Grill, Public Access, Salt Lake City, Utah, USA/
X/_maxFloors/s/30/64/
X/_maxRooms 768/s/768/1000/
X/_aliasFileName/s;/usr/lib/uucp/aliases;/usr/local/lib/aliases;
X/_systemsFileName/s;/usr/lib/uucp/L.sys;/usr/local/lib/unidel/lib/Systems;
X/_newsDelivery/s;inews;/usr/local/bin/inews;
X/_libDir/s;/usr/lib/citadel/lib;/usr/local/lib/unidel/lib;
X/_docDir/s;/usr/lib/citadel/doc;/usr/local/lib/unidel/doc;
X/_binDir/s;/usr/lib/citadel;/usr/local/lib/unidel;
X/_spoolDir/s;/usr/spool/news;/var/spool/news;
X/_newsLibDir/s;/usr/lib/news;/usr/local/lib/news;
X/_local/s;/etc/terms;/usr/local/lib/unidel/lib/LocalTTYs;
Xw
Xq
XEOF
SHAR_EOF
$TOUCH -am 0502135792 unidel/localize.sh &&
chmod 0644 unidel/localize.sh ||
echo "restore of unidel/localize.sh failed"
set `wc -c unidel/localize.sh`;Wc_c=$1
if test "$Wc_c" != "903"; then
	echo original size 903, current size $Wc_c
fi
# ============= lib/Editors ==============
if test ! -d 'lib'; then
    echo "x - creating directory lib"
    mkdir 'lib'
fi
echo "x - extracting lib/Editors (Text)"
sed 's/^X//' << 'SHAR_EOF' > lib/Editors &&
X#
X#	NAME
X#		Editors  --  List of editors and their commands.
X#
X#	SYNOPSIS
X#		name:description:flags:command
X#
X#	DESCRIPTION
X#		Editors contains the list of editors available, the commands to use
X#		them, a user description, and flags to tell Unidel how to use the
X#		command.
X#
X#		Before calling the editor, Unidel will set SHELL to 'rsh', PATH
X#		to '/usr/rbin', and change directory to a temporary directory in
X#		which to edit files.
X#
X#		Unidel uses the first editor in the list as the default editor.
X#
X#		name	is the name of the editor, used to select or reference the
X#				editor.
X#		description	is the user description of the editor, used when
X#				selecting the editor.
X#		flags	are keywords that describe the editor to Unidel.  The
X#				available flags are:
X#			SIZE=n	There is a maximum file size n for this editor.
X#		command	the command to use, with a %s replaced by the filename.
X#
X#	SEE ALSO
X#		unidel(1), vi(1), jove(1), smile(1), fsed(1), emacs(1)
X#
XSMiLE:Simple Message Line Editor, the default editor: :/usr/local/lib/unidel/smile %s
X#fsed:Full Screen EDitor, MUST have VT100 or ANSI terminal: :/usr/local/bin/fsed +/usr/local/lib/wordstar.cfg %s
X#j:Not for mortals: :/usr/local/bin/jeditor %s
Xvi:Not for mortals: :/usr/bin/vi %s
X#jove:Not for mortals: :/usr/local/bin/jove %s
Xemacs:Not for mortals: :/usr/local/bin/emacs %s
SHAR_EOF
$TOUCH -am 0502132892 lib/Editors &&
chmod 0644 lib/Editors ||
echo "restore of lib/Editors failed"
set `wc -c lib/Editors`;Wc_c=$1
if test "$Wc_c" != "1344"; then
	echo original size 1344, current size $Wc_c
fi
# ============= lib/FileDirs ==============
echo "x - extracting lib/FileDirs (Text)"
sed 's/^X//' << 'SHAR_EOF' > lib/FileDirs &&
X#
X# NAME
X#     fileDirs  --  describes file areas for Unidel
X#
X# SYNOPSIS
X#     room flags directory
X#
X# DESCRIPTION
X#     fileDirs contains the list of rooms that are "File Rooms" or rooms
X#     that can contain uploaded files and/or files to download.
X#
X#     Currently 'flags' are ignored, but they would be used to allow
X#     up/download only, etc.
X#
X#     'room' is the room that is a file room.  'directory' is the
X#     directory that contains files that are in the room.
X#
Xbbg.unidel	RW	/usr/local/bbs-archives/bbg/unidel
Xalt.sources	R	/usr/local/bbs-archives/usenet/alt.src
Xcomp.sources.3b1	R	/usr/local/bbs/bbs-archives/usenet/c.s.3b1
Xcomp.sources.acorn	R	/usr/local/bbs/bbs-archives/usenet/c.s.acorn
Xcomp.sources.amiga	R	/usr/local/bbs/bbs-archives/usenet/c.s.amiga
Xcomp.sources.apple2	R	/usr/local/bbs/bbs-archives/usenet/c.s.apple2
Xcomp.sources.atari.st	R	/usr/local/bbs/bbs-archives/usenet/c.s.atari.st
Xcomp.sources.games	R	/usr/local/bbs/bbs-archives/usenet/c.s.games
Xcomp.sources.mac	R	/usr/local/bbs/bbs-archives/usenet/c.s.mac
Xcomp.sources.misc	R	/usr/local/bbs/bbs-archives/usenet/c.s.misc
Xcomp.sources.reviewed	R	/usr/local/bbs/bbs-archives/usenet/c.s.reviewed
Xcomp.sources.sun	R	/usr/local/bbs/bbs-archives/usenet/c.s.sun
Xcomp.sources.unix	R	/usr/local/bbs/bbs-archives/usenet/c.s.unix
Xcomp.sources.x	R	/usr/local/bbs/bbs-archives/usenet/c.s.x
SHAR_EOF
$TOUCH -am 0502132892 lib/FileDirs &&
chmod 0644 lib/FileDirs ||
echo "restore of lib/FileDirs failed"
set `wc -c lib/FileDirs`;Wc_c=$1
if test "$Wc_c" != "1366"; then
	echo original size 1366, current size $Wc_c
fi
# ============= lib/Floors ==============
echo "x - extracting lib/Floors (Text)"
sed 's/^X//' << 'SHAR_EOF' > lib/Floors &&
X#
X# Floors  --  list of floors
X#
X# Format:
X#   floorName flags description
X#
X# floorName
X#   This is the first part of a newsgroup name
X#
X# flags
X#   Describes the attributes of the room.  Must have at least one.
X#     -  --  No new rooms, shown to new users, public, not anonymous, writeable, not moderated and global
X#     D  --  Display message numbers
X#     S  --  Display/require Subjects/Summaries
X#     N  --  New rooms allowed
X#     F  --  Forgotten, not shown to new users
X#     P  --  Private, implies forgotten
X#     I  --  Invite only, only specific users are allowed in
X#     A  --  Anonymous, names are not displayed on messages
X#     R  --  Read only, no posts allowed
X#     M  --  Moderated, messages in this room are sent to the moderator
X#     L  --  Local only (significant only in networked rooms), distribution is 'local'
X#
X# description
X#   This is the displayed name of the room.  Everything after the 'flags'
X#   field up to the end of the line is the description.
X#
X#  Lobby should be first, your site name is a good description.
Xlobby. N Downstairs
Xmail. DS Personal Mail
Xbbg. N Bitsko's Bar & Grill
Xutah.comp. NS Computers (Networked)
Xutah. NS Miscellaneous (Networked)
X#cit. N Citadel Network
Xbionet. PDS Biotechnology
Xcomp.lang. PDS Computer Languages (UseNet)
Xcomp.mail. PDS Electronic Mail (UseNet)
Xcomp.os. PDS Operating Systems (UseNet)
Xcomp.sys. PDS Computer Systems (UseNet)
Xcomp.unix. PDS UN*X Operating System (UseNet)
Xcomp. PDS Computers (UseNet)
Xmisc. PDS Miscellaneous (UseNet)
Xnews. PDS News Software (UseNet)
Xrec.arts. PDS Arts (UseNet)
Xrec.games. PDS Games (UseNet)
Xrec.music. PDS Music (UseNet)
Xrec. PDS Recreation (UseNet)
Xsoc. PDS Socializing (UseNet)
Xsci. PDS Science (UseNet)
Xtalk. PDS Noise Channel (UseNet)
Xalt. PDS Miscellaneous (!UseNet)
Xgnu. PDS GNU's Not UN*X
Xpubnet. PDS Public Access Network
Xunix-pc. PDS UN*X for PCs Network
Xbiz. PDS Commercial Network
Xddn. PDS What's a DDN?
Xu3b. PDS AT&T 3B2 Computers
Xtrial. PDS Some kind of test of UseNetting
Xvmsnet. PDS Digital Equipment Corp. VAX VMS Network
SHAR_EOF
$TOUCH -am 0502132892 lib/Floors &&
chmod 0666 lib/Floors ||
echo "restore of lib/Floors failed"
set `wc -c lib/Floors`;Wc_c=$1
if test "$Wc_c" != "2056"; then
	echo original size 2056, current size $Wc_c
fi
# ============= lib/LocalTTYs ==============
echo "x - extracting lib/LocalTTYs (Text)"
sed 's/^X//' << 'SHAR_EOF' > lib/LocalTTYs &&
X#
X# NAME
X#     localTTYs -- labels tty's as to whether they are local or not
X#
X# DESCRIPTION
X#     Unidel checks this file to find out whether "this" terminal is a
X#     local login terminal and up/downloads should be cp'ed.
X#
X#     Anything _not_ in this file is considered remote.
X#
X/dev/console	local
X/dev/vt00	local
X/dev/vt01	local
X/dev/vt02	local
X/dev/vt03	local
X/dev/vt04	local
X/dev/vt05	local
X/dev/vt06	local
X/dev/vt07	local
X/dev/vt08	local
SHAR_EOF
$TOUCH -am 0502134092 lib/LocalTTYs &&
chmod 0644 lib/LocalTTYs ||
echo "restore of lib/LocalTTYs failed"
set `wc -c lib/LocalTTYs`;Wc_c=$1
if test "$Wc_c" != "448"; then
	echo original size 448, current size $Wc_c
fi
# ============= lib/Systems ==============
echo "x - extracting lib/Systems (Text)"
sed 's/^X//' << 'SHAR_EOF' > lib/Systems &&
X#
X# NAME
X#     Systems -- pseudo UUCP Systems file
X#
X# DESCRIPTION
X#     This file is normally the output of a uuname command and is used
X#     to mark which systems can be mailed directly from here via uucp.
X#
X#     This file is used because uucp/Systems is normally not readable,
X#     and some may wish to restrict mail through other systems.
X#
X#     List each system on a separate line AND THERE MUST BE A SPACE AFTER
X#     THE NAME. XXX
X#
Xuunet 
Xneb 
Xceaco 
SHAR_EOF
$TOUCH -am 0502134492 lib/Systems &&
chmod 0644 lib/Systems ||
echo "restore of lib/Systems failed"
set `wc -c lib/Systems`;Wc_c=$1
if test "$Wc_c" != "463"; then
	echo original size 463, current size $Wc_c
fi
echo "End of part 6, continue with part 7"
exit 0
