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

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

---- Cut Here and unpack ----
#!/bin/sh
# This is unidel-1.0, a shell archive (shar 3.32)
# made 05/03/1992 01:28 UTC by ken@bitsko.slc.ut.us
# Source directory /home/unidel/src
#
# existing files WILL be overwritten
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   2886 -rw-r--r-- README
#    565 -rw-r--r-- Makefile
#   6264 -r--r--r-- unidel/Make.dist
#    500 -r--r--r-- unidel/Columnize.c
#   2670 -r--r--r-- unidel/Data.c
#   7288 -r--r--r-- unidel/Enter.c
#   7515 -r--r--r-- unidel/EnterFile.c
#  21299 -r--r--r-- unidel/EnterMesg.c
#    493 -r--r--r-- unidel/File.h
#   3297 -r--r--r-- unidel/Floor.c
#   1240 -r--r--r-- unidel/FromNews.c
#   7236 -r--r--r-- unidel/General.c
#   2035 -r--r--r-- unidel/Headers.c
#   4249 -r--r--r-- unidel/INSTALL
#  21321 -r--r--r-- unidel/Init.c
#   3344 -r--r--r-- unidel/Input.c
#   4405 -r--r--r-- unidel/Log.c
#   1383 -r--r--r-- unidel/Log.h
#   1181 -r--r--r-- unidel/newvers.sh
#  10549 -r--r--r-- unidel/MenuDef.c
#   8028 -r--r--r-- unidel/Mesg.c
#   1505 -r--r--r-- unidel/Message.h
#   6873 -r--r--r-- unidel/Read.c
#  10722 -r--r--r-- unidel/ReadFile.c
#  21909 -r--r--r-- unidel/ReadMesg.c
#  14441 -r--r--r-- unidel/Room.c
#   3032 -r--r--r-- unidel/Room.h
#   4588 -r--r--r-- unidel/Strings.c
#   3023 -r--r--r-- unidel/ToDo
#   1589 -r--r--r-- unidel/Unidel.h
#    635 -r--r--r-- unidel/User.h
#   2880 -r--r--r-- unidel/defs.dist
#   1859 -r--r--r-- unidel/fgetmfs.3
#   4612 -r--r--r-- unidel/fgetmfs.c
#    578 -r--r--r-- unidel/fgetmfs.h
#    451 -r--r--r-- unidel/ftime.c
#  12625 -r--r--r-- unidel/getdate.y
#   1977 -r--r--r-- unidel/getdefs.c
#   2812 -r--r--r-- unidel/getenvs.c
#    586 -r--r--r-- unidel/getenvs.h
#    880 -r--r--r-- unidel/protos.h
#    903 -rw-r--r-- unidel/localize.sh
#   1344 -rw-r--r-- lib/Editors
#   1366 -rw-r--r-- lib/FileDirs
#   2056 -rw-rw-rw- lib/Floors
#    448 -rw-r--r-- lib/LocalTTYs
#    463 -rw-r--r-- lib/Systems
#   1591 -rw-r--r-- lib/Transfers
#    766 -rwxr-xr-x lib/unidelin
#    490 -rwxr-xr-x lib/unidelout
#    738 -rw-r--r-- doc/?.doc
#    258 -rw-r--r-- doc/answers.doc
#   3187 -rw-r--r-- doc/bbsinstall.doc
#     40 -rw-r--r-- doc/blurb.doc
#    273 -rw-r--r-- doc/community.doc
#    348 -rw-r--r-- doc/config.doc
#   3910 -rw-r--r-- doc/dates.doc
#   1205 -rw-r--r-- doc/edit.doc
#     45 -rw-r--r-- doc/enter.doc
#    274 -rw-r--r-- doc/extended.doc
#    652 -rw-r--r-- doc/floors.doc
#    698 -rw-r--r-- doc/floorsum.doc
#    567 -rw-r--r-- doc/help.doc
#   6297 -rw-r--r-- doc/history.doc
#   1694 -rw-r--r-- doc/install.doc
#    263 -rw-r--r-- doc/maillists.doc
#    660 -rw-r--r-- doc/mainmenu.doc
#    214 -rw-r--r-- doc/more.doc
#    144 -rw-r--r-- doc/motd.doc
#   1242 -rw-r--r-- doc/policy.doc
#    585 -rw-r--r-- doc/questions.doc
#   2624 -rw-r--r-- doc/read.doc
#   5617 -rw-r--r-- doc/regex.doc
#  27621 -rw-r--r-- doc/rsys0192.doc
#    245 -rw-r--r-- doc/rules.doc
#    254 -rw-r--r-- doc/style.doc
#   2639 -rw-r--r-- doc/summary.doc
#    726 -rw-r--r-- doc/topics.doc
#   1254 -rw-r--r-- doc/usenet.doc
#    361 -rw-r--r-- util/newslock.c
#    249 -rw-r--r-- util/newslock.sh
#   1291 -rw-r--r-- util/place.sh
#    109 -rw-r--r-- util/Makefile
#    360 -rw-r--r-- util/README
#     11 -rw------- skel/mail/active
#   1581 -rw-r----- skel/mail/mail/1
#     52 -rw-r--r-- skel/.unidelrc
#     17 -rw-r--r-- skel/.newsrc
#   4856 -rw-r--r-- misc/AutoVal.c
#    362 -rw-r--r-- misc/DoStat.sh
#    455 -rw-r--r-- misc/Makefile
#   4343 -rw-r--r-- misc/NewUser.sh
#   2291 -rw-r--r-- misc/NewUser2.sh
#    349 -rw-r--r-- misc/SetUp.sh
#   1555 -rw-r--r-- misc/adm-rmail.c
#    256 -rw-r--r-- misc/README
#    976 -rw-r--r-- misc/buseradd.c
#     81 -rw-r--r-- misc/defaultDeliver
#   1973 -rw-r--r-- misc/getpass.c
#   1374 -rw-r--r-- misc/new-mail.sh
#   2549 -rw-r--r-- misc/newUser.c
#   4988 -rw-r--r-- misc/unilogin.c
#
if touch 2>&1 | fgrep 'amc' > /dev/null
 then TOUCH=touch
 else TOUCH=true
fi
# ============= README ==============
echo "x - extracting README (Text)"
sed 's/^X//' << 'SHAR_EOF' > README &&
X  Unidel is a room-based UseNet newsreader, UseNet/UNIX/Internet
Xmailreader and BBS.
X
XWhat is a Room Based Citadel System
X-----------------------------------
X  Unidel is a Citadel style (more specifically, a STadel style)
Xroom-based system.  A room-based system is one that represents message
Xareas, conferences, newsgroups, etc. as 'rooms'.  At all times you are
X'in' a room, you can read messages on the wall :-), add your own
Xmessage, up/download files (if allowed) or messages, talk to other
Xusers, query information about yourself or the system, or go to
Xanother room.  There is no main-menu and no separate file areas.
XRooms can optionally be grouped into floors to provide continuity.
X
X  A Citadel style system is a room-based system that uses single
Xletter commands for basic navigation of rooms (read /N/ew messages,
X/E/nter a new message, /G/oto the next room with new messages, /L/ist
Xfiles, /D/ownload file, /C/hat, query /Y/our information, /T/erminate
Xthe session) and reading messages (/N/ext message, go /B/ack a
Xmessage, /D/ownload message, /S/top reading, add a /F/ollowup message,
X/R/eply to author).  There are extended commands that are preceded by
Xa '.' and usually are one or two letters that allow for less used
Xcommands (./E/nter /C/onfiguration, ./U/pload /M/essage, ./G/oto a
Xspecific room by name).
X
X  One of the basics of a Citadel is brevity and simplicity, get what
Xyou want quickly and with little fluff.  When you /G/o to a room with
Xnew messages you see this:
X
X  Miscellaneous information about Macintosh Systems.
X  [Computer Systems (UseNet)]
X    540 messages
X    84 new messages
X  comp.sys.mac.misc> 
X
XIf you had already been on the [Computer Systems (UseNet)] floor, that
Xline would not have been displayed, if there had been no new messages
X(i.e. you had asked to ./G/oto the room) that line would not have been
Xdisplayed.  As you read messages you are given the header of the
Xmessage like this:
X
X  463/540 -- 91Nov04 9:26 am from Ken MacLeod@Bitsko's Bar and Grill
X     Subject: A message to the masses
X     Summary: Citadel Systems
X  --More--(0%)
X
X
XWhat Can Unidel Do
X------------------
X  As a news reader Unidel supports a full set of newsgroups
X(thousands), Reply-To, Followup-To, header listing, read specific
Xmessages, goto to specific rooms.  Unidel does not yet support
Xthreading or kill files.
X
X  As a secure shell (for dial-in BBS) Unidel limits access to external
Xprograms and uses only 'rsh' when calling external programs.
X
X  As a mail reader Unidel supports separate mail rooms (based on
Xcontent or header using Chip Salzenberg's Deliver or similar), address
Xvalidation for better delivery, user-defined headers.
X
X  Unidel relies on the underlying news system (CNews or BNews) to
Xprovide message distribution, expiration, etc.
X
X  As a BBS Unidel supports Chat or CB, file transfer (external
Xprograms), full-screen editing (external), 
SHAR_EOF
$TOUCH -am 1117143291 README &&
chmod 0644 README ||
echo "restore of README failed"
set `wc -c README`;Wc_c=$1
if test "$Wc_c" != "2886"; then
	echo original size 2886, current size $Wc_c
fi
# ============= Makefile ==============
echo "x - extracting Makefile (Text)"
sed 's/^X//' << 'SHAR_EOF' > Makefile &&
Xall:
X	@echo "Please cd unidel and follow instructions in INSTALL"
X
Xclean:
X	cd unidel; make -f Make.dist clean
X	cd util; make clean
X	cd misc; make clean
X	find . -name \*~ -print -exec rm {} \;
X
Xclobber: clean
X	cd unidel; make -f Make.dist clobber
X	cd util; make clobber
X	cd misc; make clobber
X
XPIECES=README Makefile unidel lib doc util skel misc
Xshar: clobber
X	rm -f part.??
X	find ${PIECES} -type f -print \
X	  | shar -n unidel-1.0 -a -s "ken@bitsko.slc.ut.us" -c -o part -l50 -S
X
Xtar: clobber
X	tar cvf un`date +%y%m%d`.tar ${PIECES}
X	compress un`date +%y%m%d`.tar
SHAR_EOF
$TOUCH -am 0502192792 Makefile &&
chmod 0644 Makefile ||
echo "restore of Makefile failed"
set `wc -c Makefile`;Wc_c=$1
if test "$Wc_c" != "565"; then
	echo original size 565, current size $Wc_c
fi
# ============= unidel/Make.dist ==============
if test ! -d 'unidel'; then
    echo "x - creating directory unidel"
    mkdir 'unidel'
fi
echo "x - extracting unidel/Make.dist (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/Make.dist &&
X#
X# NAME
X#     Make.dist -- Makefile template, used to create 'Makefile'
X#
X# AUTHOR
X#     Ken MacLeod
X#
X# SCCS
X#     @(#) Make.dist  1.6 02 May 1992 17:56:12 
X#
X
XSRCS=Init.c Room.c Floor.c Enter.c EnterMesg.c Mesg.c EnterFile.c \
X	Read.c ReadFile.c ReadMesg.c General.c Data.c Headers.c \
X	Log.c Columnize.c MenuDef.c FromNews.c Input.c Strings.c \
X	fgetmfs.c ftime.c getdate.y getenvs.c getdefs.c
XCFILES=$(SRCS)
XINCS=Unidel.h Log.h Room.h User.h Message.h File.h fgetmfs.h getenvs.h
XETCS=Makefile defs.dist Make.dist fgetmfs.3
XOBJS=Init.o Room.o Floor.o Enter.o EnterMesg.o Mesg.o EnterFile.o \
X	Read.o ReadFile.o ReadMesg.o General.o Data.o Headers.o \
X	Log.o Columnize.o MenuDef.o FromNews.o Input.o Strings.o \
X	fgetmfs.o ftime.o getdate.o getenvs.o getdefs.o
X
XLOCALINC=/usr/local/include
XLOCALLIB=/usr/local/lib
XCFLAGS=-I$(LOCALINC) -O -I.
XLDFLAGS=-L$(LOCALLIB)
X
Xunidel: $(OBJS) vers.o
X	cc $(OBJS) vers.o $(LDFLAGS) -o unidel
X
Xvers.o: $(SRCS)
X	sh newvers.sh
X	${CC} ${CFLAGS} -c vers.c
X
Xgetpath.o:
X	@echo "getpath.o must be copied from smail." ; exit 1
X
XMakefile: Make.dist localize.sh
X	@echo "You need to run localize.sh" ; exit 1
X
Xdefs.h: defs.dist localize.sh
X	@echo "You need to run localize.sh" ; exit 1
X
Xgetdate.o:  getdate.y
X	@echo "expect 8 shift/reduce conflicts"
X	yacc getdate.y
X	mv y.tab.c getdate.c
X	$(CC) $(CFLAGS) -c getdate.c
X	-rm -f getdate.c
X
Xlint: $(SRCS)
X	lint $(CFLAGS) $(SRCS) >lint.out 2>&1
X
XTarFiles=$(SRCS) $(INCS) $(ETCS)
Xtar: $(TarFiles)
X	tar cvf un`date +%y%m%d`.tar $(TarFiles)
X	compress un`date +%y%m%d`.tar
X
Xclean:
X	rm -f *~ *.o
X
Xclobber: clean
X	rm -f unidel vers.c vers.o Makefile defs.h lint.out
X
Xdepend:
X	@echo '/^# DO NOT/+1,$$d\nw\nq' | ed - Makefile; \
X	echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile; \
X	for i in ${CFILES} ; \
X	do \
X	if [ -r $$i ]; \
X	then \
X	echo "Finding dependences for $$i ... \c"; \
X	for j in `grep '^#[     ]*include[     ]*"[^"]*"' < $$i | \
X	sed 's/^#[     ]*include[     ]*"\([^"]*\)".*/\1/'`; \
X	do \
X	if [ -r $$j ]; \
X	then \
X	echo "`basename $$i .c`.o: $$j" >> Makefile; \
X	echo "`basename $$i .c`.ln: $$j" >> Makefile; \
X	elif [ -r $(LOCALINC)/$$j ]; \
X	then \
X	echo "`basename $$i .c`.o: $(LOCALINC)/$$j" >> Makefile; \
X	echo "`basename $$i .c`.ln: $(LOCALINC)/$$j" >> Makefile; \
X	else \
X	echo "`basename $$i .c`.o: ${HEADERS}/$$j" \
X	>> Makefile; \
X	echo "`basename $$i .c`.ln: ${HEADERS}/$$j" \
X	>> Makefile; \
X	fi; \
X	done; \
X	echo "done."; \
X	else \
X	echo "Can not open $$i." 1>&2; \
X	fi; \
X	done; \
X	echo '# DEPENDENCIES MUST END AT END OF FILE' >> Makefile; \
X	echo '# IF YOU PUT STUFF HERE IT WILL GO AWAY' >> Makefile; \
X	echo '# see make depend above' >> Makefile
X
X# DO NOT DELETE THIS LINE -- make depend uses it
X# DEPENDENCIES MUST END AT END OF FILE
XInit.o: protos.h
XInit.ln: protos.h
XInit.o: Log.h
XInit.ln: Log.h
XInit.o: defs.h
XInit.ln: defs.h
XInit.o: Unidel.h
XInit.ln: Unidel.h
XInit.o: Message.h
XInit.ln: Message.h
XInit.o: User.h
XInit.ln: User.h
XInit.o: Room.h
XInit.ln: Room.h
XInit.o: File.h
XInit.ln: File.h
XRoom.o: protos.h
XRoom.ln: protos.h
XRoom.o: Log.h
XRoom.ln: Log.h
XRoom.o: defs.h
XRoom.ln: defs.h
XRoom.o: Unidel.h
XRoom.ln: Unidel.h
XRoom.o: User.h
XRoom.ln: User.h
XRoom.o: Message.h
XRoom.ln: Message.h
XRoom.o: Room.h
XRoom.ln: Room.h
XFloor.o: protos.h
XFloor.ln: protos.h
XFloor.o: defs.h
XFloor.ln: defs.h
XFloor.o: Unidel.h
XFloor.ln: Unidel.h
XFloor.o: Room.h
XFloor.ln: Room.h
XFloor.o: User.h
XFloor.ln: User.h
XEnter.o: protos.h
XEnter.ln: protos.h
XEnter.o: Log.h
XEnter.ln: Log.h
XEnter.o: defs.h
XEnter.ln: defs.h
XEnter.o: Unidel.h
XEnter.ln: Unidel.h
XEnter.o: Message.h
XEnter.ln: Message.h
XEnter.o: Room.h
XEnter.ln: Room.h
XEnter.o: User.h
XEnter.ln: User.h
XEnter.o: File.h
XEnter.ln: File.h
XEnterMesg.o: protos.h
XEnterMesg.ln: protos.h
XEnterMesg.o: defs.h
XEnterMesg.ln: defs.h
XEnterMesg.o: Unidel.h
XEnterMesg.ln: Unidel.h
XEnterMesg.o: Room.h
XEnterMesg.ln: Room.h
XEnterMesg.o: Message.h
XEnterMesg.ln: Message.h
XEnterMesg.o: User.h
XEnterMesg.ln: User.h
XEnterMesg.o: File.h
XEnterMesg.ln: File.h
XMesg.o: protos.h
XMesg.ln: protos.h
XMesg.o: Log.h
XMesg.ln: Log.h
XMesg.o: defs.h
XMesg.ln: defs.h
XMesg.o: Unidel.h
XMesg.ln: Unidel.h
XEnterFile.o: protos.h
XEnterFile.ln: protos.h
XEnterFile.o: Log.h
XEnterFile.ln: Log.h
XEnterFile.o: defs.h
XEnterFile.ln: defs.h
XEnterFile.o: Unidel.h
XEnterFile.ln: Unidel.h
XEnterFile.o: Room.h
XEnterFile.ln: Room.h
XEnterFile.o: User.h
XEnterFile.ln: User.h
XEnterFile.o: File.h
XEnterFile.ln: File.h
XRead.o: protos.h
XRead.ln: protos.h
XRead.o: Log.h
XRead.ln: Log.h
XRead.o: defs.h
XRead.ln: defs.h
XRead.o: Unidel.h
XRead.ln: Unidel.h
XRead.o: Room.h
XRead.ln: Room.h
XRead.o: User.h
XRead.ln: User.h
XRead.o: Message.h
XRead.ln: Message.h
XRead.o: File.h
XRead.ln: File.h
XReadFile.o: protos.h
XReadFile.ln: protos.h
XReadFile.o: defs.h
XReadFile.ln: defs.h
XReadFile.o: Unidel.h
XReadFile.ln: Unidel.h
XReadFile.o: Room.h
XReadFile.ln: Room.h
XReadFile.o: User.h
XReadFile.ln: User.h
XReadFile.o: File.h
XReadFile.ln: File.h
XReadFile.o: Log.h
XReadFile.ln: Log.h
XReadMesg.o: protos.h
XReadMesg.ln: protos.h
XReadMesg.o: Log.h
XReadMesg.ln: Log.h
XReadMesg.o: defs.h
XReadMesg.ln: defs.h
XReadMesg.o: Unidel.h
XReadMesg.ln: Unidel.h
XReadMesg.o: Room.h
XReadMesg.ln: Room.h
XReadMesg.o: User.h
XReadMesg.ln: User.h
XReadMesg.o: Message.h
XReadMesg.ln: Message.h
XGeneral.o: protos.h
XGeneral.ln: protos.h
XGeneral.o: Log.h
XGeneral.ln: Log.h
XGeneral.o: defs.h
XGeneral.ln: defs.h
XGeneral.o: Unidel.h
XGeneral.ln: Unidel.h
XGeneral.o: Room.h
XGeneral.ln: Room.h
XGeneral.o: User.h
XGeneral.ln: User.h
XGeneral.o: Message.h
XGeneral.ln: Message.h
XGeneral.o: File.h
XGeneral.ln: File.h
XData.o: getenvs.h
XData.ln: getenvs.h
XData.o: defs.h
XData.ln: defs.h
XData.o: Unidel.h
XData.ln: Unidel.h
XData.o: Room.h
XData.ln: Room.h
XData.o: Message.h
XData.ln: Message.h
XData.o: File.h
XData.ln: File.h
XData.o: User.h
XData.ln: User.h
XColumnize.o: User.h
XColumnize.ln: User.h
XMenuDef.o: protos.h
XMenuDef.ln: protos.h
XMenuDef.o: defs.h
XMenuDef.ln: defs.h
XMenuDef.o: Unidel.h
XMenuDef.ln: Unidel.h
XMenuDef.o: Message.h
XMenuDef.ln: Message.h
XMenuDef.o: Log.h
XMenuDef.ln: Log.h
XInput.o: protos.h
XInput.ln: protos.h
XStrings.o: defs.h
XStrings.ln: defs.h
XStrings.o: Unidel.h
XStrings.ln: Unidel.h
XStrings.o: Log.h
XStrings.ln: Log.h
X# DEPENDENCIES MUST END AT END OF FILE
X# IF YOU PUT STUFF HERE IT WILL GO AWAY
X# see make depend above
SHAR_EOF
$TOUCH -am 0502175692 unidel/Make.dist &&
chmod 0444 unidel/Make.dist ||
echo "restore of unidel/Make.dist failed"
set `wc -c unidel/Make.dist`;Wc_c=$1
if test "$Wc_c" != "6264"; then
	echo original size 6264, current size $Wc_c
fi
# ============= unidel/Columnize.c ==============
echo "x - extracting unidel/Columnize.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/Columnize.c &&
X/*
X * NAME
X *     Columnize.c -- format strings into columns and pause display
X *
X * AUTHOR
X *     Ken MacLeod
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) Columnize.c  1.2 02 May 1992 08:57:49\n\t";
X#endif
X
X#include <stdio.h>
X#include "User.h"
X
Xvoid
XColumnize (string)
Xchar *string;
X{
X  static int column;
X
X  if (string == 0)			/* reset */
X    column = 0;
X  else {
X    if (++column >= (columns/25)) {
X      column = 0;
X      (void) printf ("\n");
X    }
X    (void) printf ("%-25s", string);
X  }
X}
SHAR_EOF
$TOUCH -am 0502135492 unidel/Columnize.c &&
chmod 0444 unidel/Columnize.c ||
echo "restore of unidel/Columnize.c failed"
set `wc -c unidel/Columnize.c`;Wc_c=$1
if test "$Wc_c" != "500"; then
	echo original size 500, current size $Wc_c
fi
# ============= unidel/Data.c ==============
echo "x - extracting unidel/Data.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/Data.c &&
X/*
X * NAME
X *     Data.c -- global data
X *
X * AUTHOR
X *     Ken MacLeod
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) Data.c  1.4 02 May 1992 08:59:32\n\t";
X#endif
X
X#include <stdio.h>
X#include "getenvs.h"
X#include "defs.h"
X#include "Unidel.h"
X#include "Room.h"
X#include "Message.h"
X#include "File.h"
X#include "User.h"
X
Xchar *homeDir, *logname, *longname, *terminalType;
XRoom *rooms;
XFloor *floors;
Xchar signature[] = { _signatureMark };
X
Xchar outOfMemoryMsg[] = "Out of memory.";
X
X/* User information */
Xint moreDefault;		/* default for more */
Xint columns, lines;
Xint showSig = _false;		/* Print text after "-- \n" */
Xint seperMsg = _false;		/* Separate msgs with "--------" */
Xint jokes = _true;		/* Only if you appreciate humor. */
X
Xchar *transferProtocol, *transferDescription, *transferFlags, *transferReadCommand, *transferEnterCommand;
Xchar *editorName, *editorDescription, *editorFlags, *editorCommand;
Xchar *filePager;
Xint transferBatch;	/* True if transfer protocol is a batch protocol */
X
XEnvs envs[] = {
X  "HOME", NULL, NULL, NULL, "P", (void *)&homeDir,
X  "LOGNAME", NULL, NULL, NULL, "P", (void *)&logname,
X  "PATH", _defaultPath, NULL, NULL, NULL, (void *)NULL,
X  "SHELL", _defaultShell, NULL, NULL, NULL, (void *)NULL,
X  "PAGER", _defaultPager, NULL, NULL, "P", (void *)&filePager,
X  "ORGANIZATION", _organization, NULL, NULL, NULL, (void *)NULL,
X  "TERM", _defaultTerm, NULL, NULL, "P", (void *)&terminalType,
X  "EDITOR", NULL, NULL, NULL, "P", (void *)&editorCommand,
X  NULL, NULL, NULL, NULL, NULL, NULL,
X};
X
X/* Room by room information */
Xunsigned int currentFloor;
Xunsigned int currentRoom, previousRoom;
X
X/* Modes of various sorts */
Xint more;		/* 1 = PrintArticle stops at the end of screens and
X			   pages, 2 = stops after title */
Xint local;		/* on console, _false = remote */
Xint floorMode;
Xint expertMode;
Xint guest;		/* _true = no downloads, no uploads, no posting */
Xint finished;
XFILE *dumpFile;		/* file where output is going, usually 'stdout' */
X
Xchar *hdr[_hdrMax];
Xchar *hdrFieldNames[] = {
X  "From ",
X  "From: ",
X  "Path: ",
X  "Newsgroups: ",
X  "Subject: ",
X  "Message-ID: ",
X  "Reply-To: ",
X  "References: ",
X  "Date: ",
X  "Expires: ",
X  "Control: ",
X  "Sender: ",
X  "Followup-to: ",
X  "Distribution: ",
X  "Organization: ",
X  "Lines: ",
X  "Keywords: ",
X  "Summary: ",
X  "Approved: ",
X  "File: ",
X  "To: ",
X  "Priority: ",
X  "ContentType: ",
X  "Cc: ",
X  "Bcc: ",
X  NULL,
X};
X
Xchar *months[12] = {
X  "Jan", "Feb", "Mar", "Apr", "May", "Jun",
X  "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
X};
Xchar *days[7] = {
X  "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
X};
X
X/* File Listing information */
Xchar *flTempDir;
X
Xint linesLeft, numLines;
SHAR_EOF
$TOUCH -am 0502135492 unidel/Data.c &&
chmod 0444 unidel/Data.c ||
echo "restore of unidel/Data.c failed"
set `wc -c unidel/Data.c`;Wc_c=$1
if test "$Wc_c" != "2670"; then
	echo original size 2670, current size $Wc_c
fi
# ============= unidel/Enter.c ==============
echo "x - extracting unidel/Enter.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/Enter.c &&
X/*
X * NAME
X *     Enter.c -- General entering commands and functions
X *
X * AUTHOR
X *     Ken MacLeod
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) Enter.c  1.4 02 May 1992 09:01:33\n\t";
X#endif
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <fgetmfs.h>
X#include <malloc.h>
X#include <ctype.h>
X#include <string.h>
X#include <getenvs.h>
X#include "protos.h"
X#include "Log.h"
X#include "defs.h"
X#include "Unidel.h"
X#include "Message.h"
X#include "Room.h"
X#include "User.h"
X#include "File.h"
X
Xextern Envs envs[];
Xextern char *user[];
X
X/* ARGSUSED */
Xint
XEnterSignature (dummy)
Xlong dummy;
X{
X  char signatureFileName[_bufSize];
X
X  (void) sprintf (signatureFileName, "%s/.signature", homeDir);
X
X  (void) printf ("Signatures can only be FOUR lines.  The less the better.\n");
X  /* XXX We don't check size for now, but, mind you, 'inews' truncates. */
X  (void) Edit (signatureFileName);
X
X  return 0;
X}
X
X/* ARGSUSED */
Xint
XEnterFullName (dummy)
Xlong dummy;
X{
X  char fullNameFileName[_bufSize];
X
X  (void) sprintf (fullNameFileName, "%s/.name", homeDir);
X
X  (void) printf ("Names can only be ONE line.\n");
X  /* XXX Alas, we don't check */
X  (void) Edit (fullNameFileName);
X
X  return 0;
X}
X
X/* ARGSUSED */
Xint
XToggleExpertMode (dummy)
Xlong dummy;
X{
X  if (expertMode) {
X    (void) printf ("\n Now in Novice Mode\n");
X    AllocString (&user[_userExpertMode], "No");
X    expertMode = _false;
X  } else {
X    (void) printf ("\n Now in Expert Mode\n");
X    AllocString (&user[_userExpertMode], "Yes");
X    expertMode = _true;
X  }
X  return 0;
X}
X
X/* ARGSUSED */
Xint
XEnterPauseMode (dummy)
Xlong dummy;
X{
X  int aChar;
X
X  (void) printf ("Do you want to pause at the end of a screen ([Y]/N)? ");
X  aChar = GetChar (_upperCase | _noEcho);
X  if (aChar == 'N') {
X    (void) printf ("No\n");
X    AllocString (&user[_userMore], "0");
X    moreDefault = 0;
X  } else {
X    (void) printf ("Yes\n");
X    (void) printf ("Do you want to pause after a header ([Y]/N)? ");
X    aChar = GetChar (_upperCase | _noEcho);
X    if (aChar == 'N') {
X      (void) printf ("No\n");
X      AllocString (&user[_userMore], "1");
X      moreDefault = 1;
X    } else {
X      (void) printf ("Yes\n");
X      AllocString (&user[_userMore], "2");
X      moreDefault = 2;
X    }
X  }
X  return 0;
X}
X
X/* ARGSUSED */
Xint
XEnterTerminalType (dummy)
Xlong dummy;
X{
X  _FuncName ("EnterTerminalType");
X  char tempString[_bufSize];
X
X  if (user[_userTerm]) {
X    (void) strcpy (tempString, user[_userTerm]);
X  } else {
X    (void) strcpy (tempString, "none");
X  }
X  /* XXX Can we get a better list of terminal types, or a selection? */
X  (void) printf ("  Some popular terminal types are:  ansi  vt100  wyse60  none\n");
X  (void) printf ("What type of terminal are you using or emulating [%s]? ", tempString);
X  /* XXX should't we check terminal type? */
X  if (GetStringWDefault ("", tempString,
X			 (char *) NULL, _lowerCase) == _keyAbort)
X    return 0;
X  if (tempString[0] != '\0'
X      && (putenvs (envs, "TERM", tempString)) == -1) {
X    Log (funcName, __LINE__, LOG_ERROR, _outOfMemory);
X    exit (1);
X  }
X  return 0;
X}
X
X/* ARGSUSED */
XEnterTransferProtocol (dummy)
Xlong dummy;
X{
X  _FuncName ("EnterTransferProtocol");
X  /* About a screen-fulls worth, because I'm too lazy to make it limitless */
X# define _maxProtocols 22
X  FILE *protocolFile;
X  char protocolFileName[_bufSize], *fields[5], *protocols[_maxProtocols],
X  protocolNumber[_bufSize];
X  char *protocolLine;
X  int nf, protocol, newProtocol;
X
X  (void) sprintf (protocolFileName, "%s/Transfers", _libDir);
X  if ((protocolFile = fopen (protocolFileName, "r")) == NULL) {
X    Log (funcName, __LINE__, LOG_ERROR, "Could not open Transfers file '%s'.",
X	 protocolFileName);
X    return 0;
X  }
X
X  for (protocol = 0; protocol < _maxProtocols; protocol ++)
X    protocols[protocol] = NULL;
X  protocol = 0;
X  while (protocol < _maxProtocols
X	 && (protocolLine = fgetms (protocolFile)) != NULL) {
X    if (protocolLine[0] == '\0' || protocolLine[0] == '#'
X	|| isspace(protocolLine[0])) {
X      free ((malloc_t)protocolLine);
X      continue;
X    }
X    (void)nstrip (protocolLine);
X    nf = split (protocolLine, fields, 5, ":");
X    if (nf >= 5) {
X      protocols[protocol] = (char *)malloc ((size_t) strlen (fields[0]) + 1);
X      (void) strcpy (protocols[protocol], fields[0]);
X      (void) printf ("  %2d.  %-15s %s\n", ++protocol, fields[0], fields[1]);
X    }
X    free ((malloc_t)protocolLine);
X  }
X  (void)fclose (protocolFile);
X
X  if (protocol == 0) {
X    (void) printf ("Oops, there's no protocols defined, annoy sysop.");
X    return 0;
X  }
X
X  (void) printf ("\nSelect a transfer protocol:  \n");
X  GetString (protocolNumber, _lowerCase);
X  newProtocol = 0;
X  if (protocolNumber[0] != '\0' && isdigit (protocolNumber[0])) {
X    newProtocol = atoi (protocolNumber);
X  }
X  if (newProtocol < 1 || newProtocol > protocol) {
X    (void) printf ("Invalid protocol selected.\n");
X  } else {
X    SetupTransferProtocol (protocols[newProtocol - 1]);
X    if (!user[_userProtocol]
X	|| (strcmp (transferProtocol, user[_userProtocol]) != 0))
X      AllocString (&user[_userProtocol], transferProtocol);
X    (void) printf ("New protocol, %s, set.\n", transferProtocol);
X  }
X  for (newProtocol = 0; newProtocol < protocol; newProtocol ++)
X    free ((malloc_t)protocols[newProtocol]);
X
X  return 0;
X}
X
X/* ARGSUSED */
XEnterEditor (dummy)
Xlong dummy;
X{
X  _FuncName ("EnterEditor");
X  /* About a screen-fulls worth, because I'm too lazy to make it limitless */
X# define _maxEditors 22
X  FILE *editorFile;
X  char editorFileName[_bufSize], *fields[4], *editors[_maxEditors],
X  editorNumber[_bufSize];
X  char *editorLine;
X  int nf, editor, newEditor;
X
X  (void) sprintf (editorFileName, "%s/Editors", _libDir);
X  if ((editorFile = fopen (editorFileName, "r")) == NULL) {
X    Log (funcName, __LINE__, LOG_ERROR, "Could not open Editors file '%s'.",
X	 editorFileName);
X    return 0;
X  }
X
X  for (editor = 0; editor < _maxEditors; editor ++)
X    editors[editor] = NULL;
X  editor = 0;
X  while (editor < _maxEditors && (editorLine = fgetms (editorFile)) != NULL) {
X    if (editorLine[0] == '\0' || editorLine[0] == '#'
X	|| isspace(editorLine[0])) {
X      free ((malloc_t)editorLine);
X      continue;
X    }
X    (void)nstrip (editorLine);
X    nf = split (editorLine, fields, 4, ":");
X    if (nf >= 4) {
X      editors[editor] = (char *)malloc ((size_t) strlen (fields[0]) + 1);
X      (void) strcpy (editors[editor], fields[0]);
X      (void) printf ("  %2d.  %-15s %s\n", ++editor, fields[0], fields[1]);
X    }
X    free ((malloc_t)editorLine);
X  }
X  (void)fclose (editorFile);
X
X  if (editor == 0) {
X    (void) printf ("Oops, there's no editors defined, annoy sysop.");
X    return 0;
X  }
X
X  (void) printf ("\nSelect an editor:  \n");
X  GetString (editorNumber, _lowerCase);
X  newEditor = 0;
X  if (editorNumber[0] != '\0' && isdigit (editorNumber[0])) {
X    newEditor = atoi (editorNumber);
X  }
X  if (newEditor < 1 || newEditor > editor) {
X    (void) printf ("Invalid editor selected.\n");
X  } else {
X    SetupEditor (editors[newEditor - 1]);
X    if (!user[_userEditor] || (strcmp (editorName, user[_userEditor]) != 0))
X      AllocString (&user[_userEditor], editorName);
X    (void) printf ("New editor, %s, set.\n", editorName);
X  }
X  for (newEditor = 0; newEditor < editor; newEditor ++)
X    free ((malloc_t)editors[newEditor]);
X
X return 0;
X}
SHAR_EOF
$TOUCH -am 0502135492 unidel/Enter.c &&
chmod 0444 unidel/Enter.c ||
echo "restore of unidel/Enter.c failed"
set `wc -c unidel/Enter.c`;Wc_c=$1
if test "$Wc_c" != "7288"; then
	echo original size 7288, current size $Wc_c
fi
# ============= unidel/EnterFile.c ==============
echo "x - extracting unidel/EnterFile.c (Text)"
sed 's/^X//' << 'SHAR_EOF' > unidel/EnterFile.c &&
X/*
X * NAME
X *     EnterFile.c -- File entering (upload)
X *
X * AUTHOR
X *     Ken MacLeod
X */
X
X#ifndef lint
Xstatic char sccsId [] = "@(#) EnterFile.c  1.4 02 May 1992 09:02:27\n\t";
X#endif
X
X#include <sys/types.h>
X#include <stdio.h>
X#include <string.h>
X#include <errno.h>
X#include <dirent.h>
X#include <time.h>
X#include "protos.h"
X#include "Log.h"
X#include "defs.h"
X#include "Unidel.h"
X#include "Room.h"
X#include "User.h"
X#include "File.h"
X
Xstatic void PostFileDescription ();
Xstatic int EnterFile ();
X
X/* ARGSUSED */
Xint
XEnterFileCommand (type)
Xlong type;
X{
X  char fileName[_bufSize], fileDescription[_bufSize];
X
X  if (rooms[currentRoom].fileDir == NULL) {
X    (void) printf ("Files can be entered only in rooms that end with \"]\".\n");
X    return 0;
X  }
X
X  if (!transferBatch) {
X    (void) printf ("Enter filename:\n:");
X    GetString (fileName, _normal);
X    if (fileName[0] == '\0')
X      return 0;
X    if (strchr (fileName, '/') != NULL) {
X      (void) printf ("A file name cannot include a '/'.\n");
X      return 0;
X    }
X    (void) printf ("Enter description:\n:");
X    GetString (fileDescription, _normal);
X    if (fileDescription[0] == '\0')
X      return 0;
X  } else {
X    (void)strcpy (fileName, "");
X    (void)strcpy (fileDescription, "");
X  }
X
X  (void) EnterFile (fileName, fileDescription);
X  return 0;
X}
X
X/* fileName can be a path for multiple files, or a single filename */
Xstatic int
XEnterFile (fileName, fileDescription)
X/* XXX Some of the logic here leaves much to be desired */
Xchar *fileName, *fileDescription;
X{
X  _FuncName ("EnterFile");
X  FILE *aFile;
X  DIR *tempDir;
X  struct dirent *dirEnt;
X  char commandString[_bufSize], descriptionFileName[_bufSize],
X  readyQuestion[_bufSize];
X  char sourceFileName[_bufSize], commandString1[_bufSize];
X  int bad, n, i, answer;
X  time_t theTime;
X
X  bad = _false;
X  if (local) {
X    (void) printf ("Copy from: ");
X    GetString (sourceFileName, _normal);
X    if (sourceFileName[0] != '\0') {
X      (void) sprintf (commandString, "exec cp %s %s", sourceFileName,
X		      flTempDir);
X      bad = system (commandString);
X    }
X  } else {
X    if (transferProtocol == NULL) {
X      (void) printf ("\nYou have not selected a transfer protocol.\n");
X      return (_true);
X    }
X    if (transferEnterCommand == NULL) {
X      (void) printf ("\n%s transfer not implemented.\n", transferProtocol);
X      return (_true);
X    }
X    (void) sprintf (readyQuestion, "Ready for %s upload ([Y]/N)? ",
X		    transferProtocol);
X    answer = AnswerYesNo (readyQuestion, _defaultAnswer | _defaultYes);
X    if (answer == _true) {
X      SetupTerminal (_false);
X      (void) sprintf (commandString1, transferEnterCommand, fileName);
X      (void) sprintf (commandString, "export SHELL PATH ; SHELL=/bin/rsh PATH=/usr/rbin cd %s ; exec %s",
X		      flTempDir, commandString1);
X      bad = system (commandString);
X      SetupTerminal (_true);
X    }
X    if (bad || (answer != _true))
X      return _true;
X  }
X
X  (void) sprintf (descriptionFileName, "%s/.fileList",
X		  rooms[currentRoom].fileDir);
X  if (access (descriptionFileName, 0)) {	/* Is there a files file? */
X    if (close (creat (descriptionFileName, 0666))) {
X      /* No, we'll try to create it later */
X      Log (funcName, __LINE__, LOG_WARNING, "Cannot create '%s'.",
X	   descriptionFileName);
X    }
X  }
X  aFile = fopen (descriptionFileName, "a");
X  if (aFile == NULL) {
X    Log (funcName, __LINE__, LOG_ERROR, "Unable to open '%s'.",
X	 descriptionFileName);
X    return _true;
X  }
X
X  if ((tempDir = opendir (flTempDir)) == NULL) {
X    (void)fclose (aFile);
X    Log (funcName, __LINE__, LOG_ERROR, "Cannot open temp directory '%s'.",
X	 flTempDir);
X    return (_true);
X  }
X  /* slow way to count number of entries in dir */
X  for (n = 0; (dirEnt = readdir (tempDir)) != NULL;) {
X    if (strcmp (dirEnt -> d_name, ".") != 0
X	&& strcmp (dirEnt -> d_name, "..") != 0)
X      n ++;
X  }
X  rewinddir (tempDir);
X  for (i = 0; i < n && (dirEnt = readdir (tempDir)) != NULL;) {
X    if (strcmp (dirEnt -> d_name, ".") == 0
X	|| strcmp (dirEnt -> d_name, "..") == 0)
X      continue;
X    i ++;
X    (void) sprintf (commandString, "exec cp %s/%s %s", flTempDir,
X		    dirEnt -> d_name, rooms[currentRoom].fileDir);
X    if ((bad = system (commandString)) != 0) {
X      Log (funcName, __LINE__, LOG_ERROR,
X	   "Copying uploaded file '%s/%s' to '%s', cp returned %d.\n",
X	   flTempDir, dirEnt -> d_name, rooms[currentRoom].fileDir, bad);
X    }
X    (void) sprintf (commandString, "%s/%s", flTempDir, dirEnt -> d_name);
X    if (unlink (commandString) == -1) {
X      Log (funcName, __LINE__, LOG_ERROR,
X	   "Unlinking uploaded file '%s', errno %d.\n", commandString, errno);
X    }
X
X    (void) fprintf (aFile, "\nFile: %s\n", dirEnt -> d_name);
X    if (n == 1 && fileDescription != NULL && fileDescription[0] != '\0')
X      (void) fprintf (aFile, "Desc: %s\n", fileDescription);
X    (void) fprintf (aFile, "User: %s@%s (%s)\n", logname, _siteName, logname);
X    (void) time (&theTime);
X    (void) fprintf (aFile, "Date: %s", ctime (&theTime));
X  }
X  (void)closedir (tempDir);
X  (void)fclose (aFile);
X  if (n != 0)			/* Generate an article for this */
X    PostFileDescription (fileName, fileDescription, 0l);
X
X  return (_false);
X}
X
Xstatic void
XPostFileDescription (fileName, fileDescription, fileSize)
Xchar *fileName, *fileDescription;
Xlong fileSize;
X{
X  _FuncName ("PostFileDescription");
X  FILE *articlePipe;
X  char commandString[_bufSize];
X
X  (void) sprintf (commandString, "%s -t \"File '%s'.\" -n %s -f unidel",
X		  _newsDelivery, fileName, rooms[currentRoom].name);
X  articlePipe = popen (commandString, "w");
X  if (articlePipe == NULL) {
X    Log (funcName, __LINE__, LOG_ERROR,
X	 "Unable to open pipe to generate file uploaded article.");
X    return;
X  }
X
X  (void) fprintf (articlePipe, "Reply-To: unidel@%s (Unidel BBS Version %s)\n",
X		  _siteName, _version);
X  (void) fprintf (articlePipe, "Summary: %s\n", fileDescription);
X  (void) fprintf (articlePipe, "File: %s/%s@%s\n", rooms[currentRoom].name,
X		  fileName, _siteName);
X  if (fileSize >= _maxMailServerSize) {
X    (void) fprintf (articlePipe, "Distribution: local\n");
X  }
X  (void) fprintf (articlePipe, "\n");
X  if (fileSize < _maxMailServerSize) {
X    (void) fprintf (articlePipe, "#SENDME %s/%s\n", rooms[currentRoom].name,
X		    fileName);
X    (void) fprintf (articlePipe, "#ME user@site\n");
X    (void) fprintf (articlePipe, "\n");
X    (void) fprintf (articlePipe, "  To receive the file described in the Summary line, reply to this article\n");
X    (void) fprintf (articlePipe, "with the above '#SENDME' line intact.  The file will be sent to you by e-mail.\n");
X    (void) fprintf (articlePipe, "  To ensure prompt and reliable delivery, change 'user' and 'site' in the '#ME'\n");
X    (void) fprintf (articlePipe, "line to your login name and site name, do not add any spaces or '!' mail paths.\n");
X    (void) fprintf (articlePipe, "\n");
X    (void) fprintf (articlePipe, "  If your reply does not get through you can mail to the sysop of the system at\n");
X    (void) fprintf (articlePipe, "'sysop@%s'.  To receive a listing of files available, send e-mail\n", _siteName);
X    (void) fprintf (articlePipe, "to 'unidel@%s' with the line '#SENDME %s/.fileList'.\n", _siteName,
X		    rooms[currentRoom].name);
X    (void) fprintf (articlePipe, "  Other available files and information are available by requesting\n");
X    (void) fprintf (articlePipe, "'#SENDME AllList' and '#SENDME Info'.  Be sure to include a '#ME' line.\n");
X  }
X  (void) pclose (articlePipe);
X  return;
X}
SHAR_EOF
$TOUCH -am 0502135492 unidel/EnterFile.c &&
chmod 0444 unidel/EnterFile.c ||
echo "restore of unidel/EnterFile.c failed"
set `wc -c unidel/EnterFile.c`;Wc_c=$1
if test "$Wc_c" != "7515"; then
	echo original size 7515, current size $Wc_c
fi
echo "End of part 1, continue with part 2"
exit 0
