[comp.sources.atari.st] v01i068: uupc -- UUCP clone

koreth@ssyx.ucsc.edu (Steven Grimm) (07/30/88)

Submitted-by: koreth@ssyx.ucsc.edu (Steven Grimm)
Posting-number: Volume 1, Issue 68
Archive-name: uupc/part04

#!/bin/sh
# this is part 4 of a multipart archive
# do not concatenate these parts, unpack them in order with /bin/sh
# file readme.por continued
#
CurArch=4
if test ! -r s2_seq_.tmp
then echo "Please unpack part 1 first!"
     exit 1; fi
( read Scheck
  if test "$Scheck" != $CurArch
  then echo "Please unpack part $Scheck next!"
       exit 1;
  else exit 0; fi
) < s2_seq_.tmp || exit 1
sed 's/^X//' << 'SHAR_EOF' >> readme.por
X   uu and mail are also here.
X
X   This generic main program is used to start up both uu and
X   mail, by having the preprocessor symbol MAIN #defined to
X   different procedure names in the files which include host.c.
X   This generic main program should perform all the necessary
X   start up and wrap up functions as required by the host
X   operating system and call the routine MAIN while the host
X   environment is established.
X
X   If the preprocessor symbol CWDSPOOL is #defined by the file
X   that #includes host.c, the main program should change the
X   current working directory to the spooling directory before
X   calling MAIN, and switch back to the orginal directory after
X   MAIN had returned.
X
X   The following are the other routines residing in host.c and
X   used by the others parts of both uu and mail:
X
X   importpath - A deterministic function which maps a canonical
X      file name to a local file name.  This function must be
X      deterministic (i.e. always return the same local name when
X      given the same canonical name) because it is used on each
X      canonical file name several times in various part of the
X      code to obtain the corresponding local file name.
X
X      A canonical file name has the same format as a UNIX
X      pathname, and the format of a local file name is defined by
X      your local file system.
X
X      This function should at least preserve the first 6 and last
X      2 characters of the canonical file name, since this parts
X      of the canonical file name usually contain the site name
X      and the sequence number, which is critical to the
X      successful operation of uupc.
X
X      Perferably the last 4 characters of the canonical file name
X      should be perserved, since that is the number of digits in
X      the sequence number, but if that is not possible, an
X      attempt should be made to preverse the last 3 characters
X      before resorting to only preserve the last 2 characters.
X      (With only the last 2 characters preserved, the spool file
X      sequence number cycle will become only 100 before it goes
X      around again.)
X
X   mkfilename - Build a local path name out of a given local
X      directory path and local base name pair.  It usually just
X      concatenates the two parts together with the local system's
X      directory path separator between them.
X
X   loadenv - Retrieve certain configuration parameters from the
X      user's "environment" and make them available to the
X      program.  This involves filling in the appropriate global
X      (char *) variables to point to the appropriate strings
X      which contains the character value of the desired
X      configuration parameters.
X
X   If your system requires the differentiation of text file and
X   binary files, you should also supply the following routine.
X
X   filemode() - If this routine is passed the character 't' as
X      parameter, any subsequently opened file in the program
X      should be opened in text mode.  Similarly, if the parameter
X      is the character 'b', all subsequently opened file should
X      be opened in binary mode.
X
X
Xmlib.c - Library of routines used only by the mail part.
X
X   Currently there is only one routine in this library.
X
X   get_one - Wait for a single character to be typed on the
X      console keyboard and return to the caller with the
X      character read as soon as it is pressed.  It short, this is
X      a routine that detects and returns a keypress.
X
X      This routine is used when you reach the bottom of a page
X      while paging through your mail.
X
X      The single character read by this routine should not be
X      echoed to the console screen.
X
X
Xulib.c - Library of routines used only by the uu part.
X
X   login - The logger which verifies logins and passwords for
X      incoming UUCP connections.  You only need to have this
X      routine functional if you plan to ever run your node in
X      slave mode.  i.e. Waiting on the phone line for other nodes
X      to call you to make UUCP connections.
X
X   shell - Perform an UNIX command sent from a remote site via
X      uux.  To support incoming remote mail you need to emulate
X      the UNIX 'rmail' command, which can be easily done using
X      the pcmail package (compiled as rmail) which is part of
X      this uupc distribution.  If you want to also support
X      incoming USENET news-feeds, the UNIX 'rnews' command will
X      need to be supported as well.
X
X      If your system is capable of invoking another program
X      within a program, you might want to dispatch rmail and
X      rnews as a separate program here.  Otherwise, you might
X      need to compile, or link, them into uu as routines.
X
X   sleep - Wait a specified number of seconds in real-time.  You
X      could either use a busy wait loop or a timer alarm here,
X      depending on if your system has other (e.g. background)
X      jobs competing for CPU time at the same time.  On mutli-
X      tasking or multi-users systems, you would likely *not* want
X      to busy wait even if that's easier to implement.
X
X   The rest of this library consists of routines to deal with the
X   communications line (serial port).
X
X   openline - Open a communications line as the active line.  The
X      name of the serial line device and the speed to open the
X      line at are *both* specified as (char *) type parameters.
X      These value are just the corresponding values in the
X      systems file entry of the site being called.
X
X   sread - Read a specified number of bytes from the active
X      serial line and return with *no* input characters consumed
X      *if* the specified number of bytes is not available after
X      the specified timeout period.  This is basically a non-
X      blocking read that waits up to an user-specified amount of
X      time before returning.
X
X   swrite - Write a specified number of bytes out to the active
X      serial line.  No timeout mechanism needs to be provided by
X      this routine.
X
X   closeline - Close the active communications line.
X
X   SIOSpeed - Change the line speed of the active communications
X      line on-the-fly.  The new line speed is given as (char *)
X      rather than (int).  Note the mixed-case nature of this
X      routine name.
X
X
Xndir.h - Header file for the directory scanning routines.
X
X   At least the following needs to be defined in this file.
X
X   -- The constant 'MAXNAMLEN' declared with "#define".  This is
X      the maximum length of a file name in your system.  Note
X      that a file name does not include a directory path prefix,
X      it is only the maximum length of a file name within a
X      directory.
X
X   -- The structure 'direct' declared with "struct".  This
X      structure is a public data structure and its fields are
X      examined directly by uu, so your declaration needs to
X      provide at least the following fields:
X
X      struct direct {
X         short d_reclen;
X         short d_namlen;
X         char  d_name[MAXNAMLEN + 1];
X      };
X
X      d_reclen is the length of the structure minus the size of
X      the unused portion of d_name at the end of the structure.
X
X      d_namelen is strlen(d_name).
X
X      d_name is the name of the next file in the scan, with a
X      terminating '\0'.
X
X      It is important for the structure 'direct' to be defined
X      using "struct" insted of "typedef".
X
X   -- The type 'DIR' declared with "typedef".  This is a private
X      structure used by the ndir routines and should contain all
X      the static data related to a single invocation of the ndir
X      routines.
X
X      It is important for 'DIR' to be defined using "typedef"
X      instead of "struct".  (Note this is the *reverse* of the
X      structure 'direct' above.)
X
X   -- The routines opendir(), readdir(), and closedir().  Which
X      opens a specified directory, read the next file entry from
X      an opened directory, and close an opened directory,
X      respectively.
X
X
Xndir.c - "Berkeley-style" directory scanning routines.
X
X   This file contains a set of routines similar in functions to
X   the Berkeley-style directory scanning routines.  These
X   routines are used only by uu, not mail, and only the
X   opendir(), readdir(), and closedir() routines are used, and
X   therefore need to be implemented.
X
X   Eventhough the ndir routines should be capable of mutliple
X   concurrent invocations using separate (DIR *)'s, uu only uses
X   one invocation of it at a time.
X
X   If your system's file name is mono-case, then your readdir()
X   routine should always return the file name field (d_name) in
X   all lowercase.
X
X
XAny questions about porting uupc to other machines/operating
Xsystems, and comments and suggestions about this writeup should
Xbe directed to one of the e-mail addresses listed at the end of
Xthis file.
X
XIf you do decide to start porting uupc to a new machine/operating
Xsystem, please drop us a line as well.  We might even be able to
Xsave each other some duplicated efforts!
X
X
XUUCP: {seismo,ihnp4!alberta,uw-beaver,uunet}!ubc-vision!van-bc!uupc
XInternet: uupc@van-bc.UUCP
X-------
X
X
X--
X{ihnp4!alberta!ubc-vision,uunet}!van-bc!Stuart.Lynne Vancouver,BC,604-937-7532
X
SHAR_EOF
chmod 0600 readme.por || echo "restore of readme.por fails"
sed 's/^X//' << 'SHAR_EOF' > readme.st &&
XThis file contains the Atari ST specific files.
X
XI have done all the compilation using the Alcyon C versin 4.14a compiler.
XThe disks were layed out with all the sources and objects on the A drive and
Xthe compiler on the D drive.
X
XProblems with the Atari ST code:
X
X	- there is a problem in the getsystem(), sysend() states such that
X	  if there is more than one system in the systems file then the
X	  program may bomb bomb (bus error?)
X
XFiles included in this shar script:
X
X		On the atari these files should be placed in the
X		\local directory or the .h files will need to be
X		edited.
X
X	  dirsubs.c	- file and directory name manipulation
X	  dmymath.c	- dummy floating point routines to fake out linker
X	  genv.c	- load enviroment strings
X	  getenv.c	- get and enviroment string
X	  getone.c	- get one character without echo
X	  host.c	- host specific main program
X	  inoutpth.c	- file name conversion
X	  ndir.c	- directory manipulation routines
X	  printmsg.c	- print message to log file
X	  time.c	- date/time conversion routines
X	  uusup.c	- uu support routines
X
X	  The following files belong in the ./local dirctory and should
X	  be moved there with the leading z stripped off.
X
X	  zdcp.h	- main include file for uu
X          zmailhost.c	- host specific mail main program
X          zuuhost.c	- host specific uu main program
X	  zgenv.h	- definitions for enviroment variables
X	  zhost.h	- host specific definitions
X	  zndir.h	- directory manipulation routines header
X	  ztime.h	- time routine header
X
XThe following script files are included as examples on how to compile
Xthe sources.  They are for the CM command shell.
X
X	  c.mm		- compile script for alcyon C (file is in A:\)
X	  cu.mm		- compile script for alcyon C (file is in A:\atari\)
X	  env.mm	- define enviroment script
X	  ldcp.mm	- link uu.prg
X	  lmail.mm	- link mail.prg
X	  uuar.mm	- create DCPLIB
X	  utar.mm	- create UTLLIB
X
XBasic procedure is to:
X	- compile all the .c files into .o files
X	- build the DCPLIB with uuar.mm
X	- build the UTLLIB with utar.mm
X	- link uu with ldcp.mm
X	- link mail with lmail.mm
X
XIf you have problems feel free to drop me a line.  Though I warn you I have
Xa slow turn around time on questions I will try to get back to you within
Xa day or two.
X
X------------------------------------------------------------------------------
XUUCP:  {alberta,uw-beaver,siesmo}!ubc-vision!van-bc!nvanbc!lawrence
XSNAIL: 733 Sylvan Ave., North Vancouver, B.C., Canada, V7R 2E8
XPHONE: 1-604-736-9241 (09:00-17:00 PDT)
X
SHAR_EOF
chmod 0600 readme.st || echo "restore of readme.st fails"
sed 's/^X//' << 'SHAR_EOF' > readme.uup &&
XJuly 29/87						Stuart Lynne
X
XUUPC is now running on Macintosh, Atari-ST, Amiga, and IBM-PC with MS-DOS.
X
XThese versions will constitute my first release of uupc and pcmail. Please 
Xsee the README files in each shar file for appropriate instructions.
X
XAs is, uupc sends and receives files quite well. Still unimplemented is
Xthe reverse direction file transfers, i.e. send a file to a remote host
Xwhile in slave mode, receive a file while in master mode. These are not 
Xneeded to support news and mail. A proper uucp command is need too.
X
XThe user agent mail program is a very simple hack to simply allow you to 
Xread and send mail. Hopefully someone will work on replacing this!
X
XThe message transfer agent pcmail program is fairly robust. It does need to
Xhave some more intelligence to allow for more intelligent routing of outgoing
Xmail. Currently ALL outgoing mail is forward to a single remote site for
Xprocessing. This will actually handle the needs of a large number of users
Xbut for those lucky ones who can actually get access to several large uucp
Xsites better routine would be nice.
X
X
XOther things which are needed:
X
X	news unbatcher
X	news reader
X
XCurrently the news is simply spooled to a directory with a unique file name.
XYou can read this with a normal text editor. If you wish to have outgoing mail
Xthe easiest way is to have your news feed set up alias's like:
X
X	comp.sys.amiga "| /usr/local/lib/news/recnews comp.sys.amiga"
X
XThen simply mail your article to:
X
X	comp.sys.amiga@newsfeedhost.uucp
X
X
XPlease feel free to port this code to other environments. I ask only that you
Xtry and limit changes to the machine independent code. Things have been setup
Xso that you shouldn't have to modify dcp, uupc, mail or pcmail if you are simply
Xporting to a new environment. 
X
XPlease send me any new versions, diff's to get old versions working better,
Xbug fixes etc.
X
XHave fun and enjoy.
X
XI would suggest that questions and comments about uupc/dcp/mail be directed
Xto comp.mail.uucp on Usenet. This group is about "Mail in the uucp network
Xenvironment." which describes uupc pretty well.
X
X
XQuestions, bug fixes etc
X
Xuupc, mac version, information
X
X	Stuart Lynne
X	stuart.lynne@van-bc.uucp
X	{{seismo,ihnp4!alberta}!ubc-vision,uunet}!van-bc!Stuart.Lynne  604-937-7532
X
XAmiga version
X
X	Jeff Lydiatt
X	jl@jlami.vnet.van-bc.uucp
X	{{seismo,ihnp4!alberta}!ubc-vision,uunet}!van-bc!jlami!jl
X
XAtari ST version
X
X	Lawrence Harris
X	lawrence@nvanbc.uucp
X	{{seismo,ihnp4!alberta}!ubc-vision,uunet}!van-bc!nvanbc!lawrence
X
XIBM PC - MS-DOS version
X
X	Samuel Lam
X	skl@sklpc.vnet.van-bc.uucp
X	{{seismo,ihnp4!alberta}!ubc-vision,uunet}!van-bc!skl
X
Xuupc mailing list 
X
X	uupc@van-bc.uucp			Automatically forwarded to mailing list
X	uupc-request@van-bc.uucp	For requests to be added to mailing list
X
X	{{seismo,ihnp4!alberta}!ubc-vision,uunet}!van-bc!nvanbc!uupc
X	{{seismo,ihnp4!alberta}!ubc-vision,uunet}!van-bc!nvanbc!uupc-request
X	
X
XNB. Rurrently UUNET is only polled twice per week, you may wish to send
Xany messages via both paths to ensure delivery. UUNET is probably more
Xreliable, ubc-vision may be faster if you can reach them from your site.
X
X
X
Xuupc 			June 8, 1987		Stuart Lynne
X
XFor Beta implementors only.
X
Xuupc incorporates a streamlined version of dcp to implement a uucp mail
Xand news delivery system. 
X
XSee README.DCP for dcp info.
X
XBy moving the host dependant code into one file the other four dcp files can 
Xhopefully be maintained easily. It should be possible to maintain one version
Xof them which compiles and runs on all machines without conditional compilation
Xflags.
X
XThe host file should contain:
X
X	- serial I/O
X	- BSD compatible directory routines
X	- system call stuff
X
XThis all goes to implement a command called uupc. It is similiar to the uucico
Xcommand under unix.
X
X	uupc [-xn] [-shost]
X
X
XThere is also two mail source files. Pcmail is the MTA part of the mail system.
XIt compiles in two ways, one for rmail (add only From and Received: headers), 
Xdefine a simple rnews; and for lmail (add all headers). Pcmail will effect
Xdelivery of mail to local and remote users. Currently all remote mail is 
Xdirected to one smart host for forwarding.
X
XMail is a simple UA. It allows you to send mail and read your mailbox. It needs
Xlots of work but is servicable.
X
X	mail -s "subject here" user user@remote.site.domain < message
X
X	mail -f =mailbox
X
X	mail
X
Xwill all do the obvious. Mail will append a .signature if it can find one, and
Xwill keep a copy of your outgoing mail in =mail.sent.
X
XToDo:
X
X	uucp command
X	mail improvements
X	bug fixes to uupc/dcp
X	ports to Atari, Amiga, IBM PC, VMS
X
X
XMakefile	- sample Makefile (Macintosh Aztec C)
Xgetargs.c 	- library routine
Xlmail.c 	- define LMAIL; include pcmail
Xmail.c  	- mail program (UA)
Xpcmail.c 	- mail program (MTA)
Xrmail.c 	- define RMAIL; include pcmail
Xlib.c		- misc library routines, FOPEN, CREAT, getargs, printmsg
X
Xhost.h 		- prototype for host.c, includes "local/host.h"
Xmailhost.c 	- ditto for mailhost.c, includes "local/host.c"
Xmlib.c 		- ditto for mlib.c, 	includes "local/mlib.c"
Xulib.c 		- ditto for ulib.c, 	includes "local/ulib.c"
Xuuhost.c 	- ditto for uuhost.c, 	includes "local/host.c"
X
X
Xpcmail in general
XPcmail provides MTA functionality. It delivers the mail. Currently it is
Xvery dumb about forwarding mail. Local deliveries always succeed if there
Xis room and the mail spooling directory exists. No "/etc/passwd" file list
Xof users is used to determine if there really is a mailbox for an incoming
Xmessage. Also outgoing mail is assumed to go to one smart host for 
Xprocessing. This is determined by scanning for "!" or "@" in the address.
X
XBoth local and remote delivery algorithms could be souped up. Locally we
Xshould maintain a list of mailboxes. For remote we should attempt to build
Xa path to the most reasonable host for forwarding a specific message. This
Xwill require a small version of the paths database most likely. If your 
Xonly talking to one host anyway the current scheme is not all that bad.
X
XPcmail has one additional capability which is not currently being exploited.
XIt can add additional message length header lines and spool mail into a 
Xmailbag. This mailbag could then be sent intact to your host for processing.
XThe host must run rpcmail (availble from sl@van-bc.uucp) to unbatch the
Xmessages to rmail. This corresponds to the AT&T Mail protocol for uploading
Xmail from PC's.
X
XMost likely the converse capability would be more suitable. Have the host 
Xbatch incoming mail and news. Unbatch it on this side. 
X
Xpcmail / LMAiL
XThe mail UA is composed of the mail.c program and pcmail.c compiled without
Xdefining RMAIL (LMAIL). The LMAIL version of pcmail adds rfc822 headers
Xto all mail, copies mail to =mail.sent etc.
X
Xpcmail / RMAIL
XThe uu program contains the RMAIL version of pcmail. It only adds the From 
XReceived: headers to incoming mail. 
X
X
X
XFor more information, bug fixes, more commands etc:
X
X		Stuart.Lynne@van-bc.uucp
X		604-937-7532
X
X
XDirectory tree
X
X/usr
X/usr/lib
X/usr/lib/uucp
X/usr/lib/uucp/SEQF			- sequence numbers
X/usr/lib/uucp/systems		- host connection information
X/usr/spool
X/usr/spool/mail				- mail directory
X/usr/spool/mail/XXXX		- user mail files
X/usr/spool/rnews			- rnews spool/file
X/usr/spool/uucp				- spool directory
X/usr/spool/uucp/C.YYYYYNNNN	- copy control files
X/usr/spool/uucp/D.YYYYYNNNN	- uucp data files
X/usr/spool/uucp/dcp.log		- log file
X/usr/spool/uucp/X.YYYYYNNNN	- execute control files
X/usr/XXXX					- user directories
X/usr/XXXX/.signature		- signature file
X/usr/XXXX/Mail				- user mail directory
X/usr/XXXX/Mail/mail.sent	- sent file
X/tmp						- temporary files
X
X
X
XSystems File 
X
XNB. I have split the lines, in the real file they should be one line for
Xeach entry.
X
XThis entry uses the built in Hayes dialer.
X
Xvan-bc Any a HAYES TD939-4782 g ogin:--ogin: uuslmac sword:-\c-sword: uuslmac
X
X	Connect to van-bc using HAYES dialer with phone number 939-4782 with
X	protocol g.
X	Wait for ogin: if timeout send \n and wait for ogin:.
X	Send uuslmac (login ID).
X	Wait for sword:, if timeout send nothing, wait for sword:
X	Send uuslamc (login ID).
X	
XI use this entry to connect via a DC Hayes Smartmodem 2400, dialing explicity.
X
Xvan-bc Any a DIR 2400 g "" ATZ OK-\d+++\dATZ-OK ATS7=12 OK ATTD939-4782 
X	CONNECT \d\c ogin:--ogin: uuslmac sword:-\c-sword: uuslmac
X
X	Connect to van-bc at 2400 on port a with protocol g. 
X	Expect nothing, send ATZ to reset the modem, 
X	Expect OK, if not received send pause +++ pause to try and get
X	modems attention and wait for OK.
X	When OK received, send ATS7=12 to shorten connect timeout on modem.
X	Expect OK, send ATTD939-74782.
X	Expect CONNECT, send nothing but pause (\c is needed).
X	Expect ogin:, if not received send newline.
X	Send login name.
X	Expect sword:, send password.
X
X
XThis entry is used to connect directly to my Callan at 9600. It is
Xcomplicated due to the Callan running a special mgetty program which
Xthinks it is talking to a Hayes Smartmodem. So we fake it out, then
Xtell it the connection has been made at 9600, then switch to 9600 
Xourselves.
X
Xvan-bc Any a DIR 2400 g "" OK\r\d\dRING\r\dCONNECT\s9600\d\z9600\ 
X	ogin:-\r\r-ogin: uuslmac sword:-\c-sword: uuslmac "" \d\d\d\d\d\d\c
X
X	Connect to van-bc at 2400 on port a.
X	Expect nothing, send OK, pause, RING, CONNECT, 9600, 
X	and change to 9600 bps.
X	Expect ogin: send login id.
X	Expect sword: send password.
X
X
X
SHAR_EOF
chmod 0600 readme.uup || echo "restore of readme.uup fails"
sed 's/^X//' << 'SHAR_EOF' > rmail.c &&
X/*			rmail.c
X
X*/
X
X#define NOMAIN
X#define RMAIL /* if defined we get rmail() else we get lmail() */
X
X#include	"pcmail.c"
X
X
SHAR_EOF
chmod 0600 rmail.c || echo "restore of rmail.c fails"
sed 's/^X//' << 'SHAR_EOF' > shell.c &&
X
X
SHAR_EOF
chmod 0600 shell.c || echo "restore of shell.c fails"
sed 's/^X//' << 'SHAR_EOF' > systems &&
Xssyx Evening a HAYES DT1112222 g ogin:--ogin:--ogin:--ogin:--ogin: uholo sword:-\c-sword: [password]
Xdaver Evening a HAYES DT9876543 g "" \d\r ogin:-\r-ogin: Uholodek ord: [password]
Xsmegma Any a HAYES DT3141592 g "" \r\r\r\r ogin:~1-\r-ogin:~1-\r-ogin:~1-\r-ogin: Uholodek ord: [password]
SHAR_EOF
chmod 0600 systems || echo "restore of systems fails"
sed 's/^X//' << 'SHAR_EOF' > time.c &&
X/*
X * time(), ctime(), localtime(), sleep()
X *
X */
X#include <osbind.h>
X#include "time.h"
X#define NULL 0
X
Xlong *_hz200 = (long *)0x0004ba;	/* address of system 200 hz clk	*/
Xlong _prtime;
X
X/*
X * read200hz() - read the system 200hz clock
X *
X * Must be a separate routine since it is called in supervisor mode
X */
Xvoid _read200hz()
X{
X	_prtime = *_hz200;
X}
X
Xlong time( tloc )
Xlong *tloc;
X{
X	long t;
X	Supexec( _read200hz );
X	t = _prtime / 200L;
X	if ( tloc != (long *)NULL ) *tloc = t;
X	return( t );
X}
X/*
X * ctime(clock) - Return the time as DDD MMM dd hh:mm:ss YYYY\n\0
X *
X * Since I don't have a working time() call just now I ignore the clock
X * and simply return the current date and time.  This is all that this
X * program requires anyway.
X *
X * This routine was rewritten by Steven Grimm, since it didn't work too
X * well as supplied (in fact, it didn't work at all!)
X */
Xchar _timearr[26];
Xchar *_Months[12] = {
X	"Jan", "Feb", "Mar", "Apr", "May", "Jun",
X	"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
X};
X/* Days of the week.  Start with Tuesday so we eliminate one addition. */
Xchar *_Days[7] = { "Tue", "Wed", "Thu", "Fri", "Sat", "Sun", "Mon" };
X
X/* Offset into the year for 1st of each month (disregarding leap years) */
Xint monthoff[12]={ 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334 };
X
Xtypedef struct {
X	unsigned day:5;
X	unsigned month:4;
X	unsigned year:7;
X} GDATE;
Xtypedef struct {
X	unsigned second:5;
X	unsigned minute:6;
X	unsigned hour:5;
X} GTIME;
X
Xchar *ctime( clock )
Xlong *clock;
X{
X	unsigned date;
X	unsigned time;
X	long dayno;
X	GDATE gdate;
X	GTIME gtime;
X
X	date = Tgetdate() & 0xffffL;	/* Get date from DOS */
X	time = Tgettime() & 0xffffL;	/* Get time from DOS */
X	gdate = *(GDATE *)&date;
X	gtime = *(GTIME *)&time;
X
X/*
X * Now we have to figure out the day of the week.  We do this by starting
X * at a known date -- in this case Tuesday, January 1, 1980 -- and counting
X * days from there.  This formula is optimized a bit, so may look somewhat
X * cockeyed.
X */
X	dayno = gdate.year * 365 +	/* 365 days per year since '80 */
X		gdate.year / 4 +	/* add leap days */
X		monthoff[gdate.month-1]+ /* and offset to this month */
X		gdate.day;		/* and the day */
X	if (((gdate.year % 4)==0) && (gdate.month < 3))
X		dayno--;
X	dayno %= 7;
X
X	sprintf( _timearr, "%s %s %02d %02d:%02d:%02d PDT %04d\n",
X			_Days[dayno],
X			_Months[gdate.month - 1],
X			gdate.day, gtime.hour, gtime.minute,
X			gtime.second * 2, gdate.year + 1980);
X	return( _timearr );
X}
X
X/*
X * localtime() - Return tm structure (for current time/date, oh well).
X */
X
Xstruct tm _TMstruct;
X
Xstruct tm *localtime( clock )
Xlong *clock;
X{
X	unsigned date;
X	unsigned time;
X	long dayno;
X	GDATE gdate;
X	GTIME gtime;
X
X	date = Tgetdate() & 0xffffL;	/* Get date from DOS */
X	time = Tgettime() & 0xffffL;	/* Get time from DOS */
X	gdate = *(GDATE *)&date;
X	gtime = *(GTIME *)&time;
X
X	dayno = gdate.year * 365 +	/* 365 days per year since '80 */
X		gdate.year / 4 +	/* add leap days */
X		monthoff[gdate.month-1]+ /* and offset to this month */
X		gdate.day;		/* and the day */
X	if (((gdate.year % 4)==0) && (gdate.month < 3))
X		dayno--;
X	dayno = (dayno + 5) % 7;
X
X	_TMstruct.tm_sec = gtime.second * 2;
X	_TMstruct.tm_min = gtime.minute;
X	_TMstruct.tm_hour= gtime.hour;
X	_TMstruct.tm_mday= gdate.day;
X	_TMstruct.tm_mon = gdate.month;
X	_TMstruct.tm_year= gdate.year + 80;
X	_TMstruct.tm_wday= dayno;
X	_TMstruct.tm_yday= monthoff[gdate.month-1]+gdate.day;
X	_TMstruct.tm_isdst= 0;
X	return( &_TMstruct );
X}
X
X/*
X * sleep() - wait n seconds
X *
X * Simply delay until n seconds have passed
X *
X */
X
Xvoid sleep(n)
Xunsigned int n;
X{
X	unsigned long i;
X
X	i = (unsigned long)time((long *)NULL);
X	while ( ( (unsigned long)time((long *)NULL) - i ) < n ) ;
X}
SHAR_EOF
chmod 0600 time.c || echo "restore of time.c fails"
sed 's/^X//' << 'SHAR_EOF' > time.h &&
X/* time.h */
X
Xstruct tm {
X	int	tm_sec;		/* time of day, seconds */
X	int	tm_min;		/* time of day, minutes */
X	int	tm_hour;	/* time of day, hours (24 hour clock) */
X	int	tm_mday;	/* day of month (1-31) */
X	int	tm_mon;		/* month of year (0-11) */
X	int	tm_year;	/* year - 1900 */
X	int	tm_wday;	/* day of week (Sunday = 0) */
X	int	tm_yday;	/* day of year (0-365) */
X	int	tm_isdst;	/* non-0 if DST in effect */
X};
Xextern struct tm *localtime();
Xextern char *ctime();
X
SHAR_EOF
chmod 0600 time.h || echo "restore of time.h fails"
sed 's/^X//' << 'SHAR_EOF' > ulib.c &&
X/* 		ulib.c
X
X*/
X
X#include	"local/ulib.c"
X
SHAR_EOF
chmod 0600 ulib.c || echo "restore of ulib.c fails"
sed 's/^X//' << 'SHAR_EOF' > uuhost.c &&
X/*		uuhost.c
X
X*/
X#define	MAIN	dcpmain
X#define CWDSPOOL
X#include	"host.c"
X
X
SHAR_EOF
chmod 0600 uuhost.c || echo "restore of uuhost.c fails"
sed 's/^X//' << 'SHAR_EOF' > uusup.c &&
X/*
X * atari st system specific subroutines for uu
X *
X * these are included into uuhost.c during compile
X */
X#include "dcp.h"
X
Xstruct
X   {
X      char	*baud;
X      int	baudidx;
X   } BaudStr[] = { "300", B300,
X		   "1200", B1200,
X		   "2400", B2400,
X		   "4800", B4800,
X		   "9600", B9600,
X		   "19200", B19200,
X		   "-1", -1
X		 };
X
X/* some global variables */
X
Xchar st_ibuf[IBUFSIZ];			/* our own input buffer		*/
Xchar st_obuf[OBUFSIZ];			/* and our own output buffer	*/
X
X/* most of the Iorec() stuff was redone by Martin Minow (thanks) */
X
XIOREC *st_sysr;				/* ptr to system rs232 record	*/
XIOREC st_savr;				/* to save system rs232 record	*/
XIOREC st_myiorec;
X
Xunsigned long	old_rsconf;
Xint		old_ucr, old_rsr, old_tsr, old_scr;
Xint		st_baud = B9600;	/* default baud rate */
X
X/*
X * r_count_remaining() - Access the i/o structures and find out how many
X * characters there are in the input ring buffer.
X */
X
Xint r_count_remaining()
X{
X	IOREC *ReadPort;
X	int Diff;
X
X	ReadPort = (IOREC *)Iorec(0);
X	Diff = ReadPort->in.ibuftl - ReadPort->in.ibufhd;
X	if ( Diff < 0 )
X	  Diff = IBUFSIZ - abs( Diff );
X	return( Diff );
X}
X
X/*
X *                      Read/Write I/O processing
X */
X
X/*
X * openline - Open the communication line for use with dcp.
X */
X
Xopenline( name, baud )
X    char	*name, *baud;
X{
X
X     register int i;
X
X
X     st_myiorec.in.ibuf = st_ibuf;
X     st_myiorec.in.ibufsize = IBUFSIZ;
X     st_myiorec.in.ibufhd = st_myiorec.in.ibuftl = 0;
X     st_myiorec.in.ibuflow = IBUFSIZ / 4;
X     st_myiorec.in.ibuflow = (IBUFSIZ / 4 ) * 3;
X
X     st_myiorec.out.ibuf = st_ibuf;
X     st_myiorec.out.ibufsize = OBUFSIZ;
X     st_myiorec.out.ibufhd = st_myiorec.out.ibuftl = 0;
X     st_myiorec.out.ibuflow = OBUFSIZ / 4;
X     st_myiorec.out.ibuflow = (OBUFSIZ / 4 ) * 3;
X
X     for (i=0; 	BaudStr[i].baudidx != -1; i++ )
X       if ( strcmp( baud, BaudStr[i].baud) == 0 )
X	 {
X	   st_baud = BaudStr[i].baudidx;
X	   break;
X	  }
X/* 
X *	set up our own rs232 input and output buffers
X */
X    st_sysr = (IOREC *)Iorec(0);
X    st_savr = *st_sysr;			/* Save system buffer	*/
X    *st_sysr = st_myiorec;		/* Set my io buffer	*/
X
X/*
X * Saving the old Rsconf() parameters, and
X * adding the 2 Vsync() calls was done by Martin Minow.
X *
X * Rsconf(baud, ctrl, usr, rsr, tsr, scr):
X * baud	New line speed
X * ctrl	UART control register: 2 stop bits, match speed
X * rsr	Receiver on
X * tsr	Transmitter on
X * scr	Synchronous register ignored.
X * Rsconf returns the "old" values.
X */
X
X    printf("Setting Com port - speed = %d\n", st_baud);
X    old_rsconf = Rsconf(st_baud, NOFLOW, UCR, RSR, TSR, SCR);
X    old_ucr = (old_rsconf >> RS_UCR_SHIFT) & 0xFF;
X    old_rsr = (old_rsconf >> RS_RSR_SHIFT) & 0xFF;
X    old_tsr = (old_rsconf >> RS_TSR_SHIFT) & 0xFF;
X    old_scr = (old_rsconf >> RS_SCR_SHIFT) & 0xFF;
X/*
X * Magic.
X */
X    Vsync();			/* Short delay while	*/
X    Vsync();			/* The UART settles	*/
X    return ( 0 );
X}
X
X/*
X * closeline - Restore the communication line to the way we found it.
X */
X
Xvoid closeline()
X{
X/*
X * Drop DTR for a second so we hang up.
X */
X	Ongibit(0x10);
X	sleep(1);
X	Offgibit(0xffef);
X	/* restore the system's i/o record				*/
X	*st_sysr = st_savr;
X
X	/* Replace old RS232 parameters				
X	Rsconf(B9600, 1, old_ucr, old_rsr, old_tsr, old_scr);*/
X}
X
X/*
X * sread( buf, num, timeout ) - Read num characters within timeout
X */
X
Xint sread( buf, num, timeout )
Xunsigned char *buf;
Xint  num, timeout;
X{
X	int count,test;
X	unsigned char *cp;
X
X	if (debuglevel > 13)
X	  fputc( '[', stderr );
X	printmsg(15, "sread: num: %d  timeout: %d", num, timeout );
X
X	count = xread( buf, num, timeout );
X
X	printmsg(15, "sread: read: %d ", count);
X
X	if (debuglevel > 13 && count > 0)
X	{
X	  test = count;
X	  cp = buf;
X	  while (test--)
X	    fprintf( stderr, isprint(*cp)? "[%c]":"[%02x]", *cp++ );
X	}
X	if (debuglevel > 13)
X	  fputc( ']', stderr );
X	return( count );
X}
X
X/*
X * swrite( buf, num ) - Write num characters to the output port
X */
X
Xint swrite( buf, num )
Xint  num;
Xchar *buf;
X{
X	int  count;
X	char *cp;
X
X	if (debuglevel > 14)
X	{
X	  fputc( '{', stderr );
X	  count = num;
X	  cp = buf;
X	  while ( count-- )
X	    fprintf( stderr, isprint(*cp)? "{%c}":"{%02x}", *cp++ );
X	  fputc( '}', stderr );
X	}
X	count = xwrite( buf, num );
X	return( count );
X}
X
X/*
X * read buffer - low level
X */
X
Xint xread( buf, num, timeout )
Xchar buf[];
Xint  num, timeout;
X{
X	long jtime;
X	int i,jj,jd;
X
X	jtime = time((long *)NULL);
X	while (TRUE)
X	{
X	  jj = r_count_remaining();
X	  if ( jj >= num )
X	  {
X	    for ( i=0; i < num; i++ )
X	    {
X	      buf[i] = Bconin(AUX) & 0xFF;
X	    }
X	  return( jj );
X	  }
X	  else
X	  {
X	    jd = time((long *)NULL) - jtime;
X	    if ( jd >= timeout )
X	      return( jj );
X	  }
X	}
X}
X
X/*
X * xwrite( buf, n ) - Write n bytes froum the buffer to the port
X */
X
Xint xwrite( buf, n )
Xchar buf[];
Xint  n;
X{
X	register int i;
X
X	for ( i=0; i<n; i++ )
X	{
X	  Bconout( AUX, buf[i] );
X	}
X	return( n );
X}
X
X/*
X * Set I/O port to a certain baud rate.
X * Steven Grimm, 7-88
X */
Xvoid SIOSpeed( s )
Xchar *s;
X{
X	int i;
X
X	for (i=0; BaudStr[i].baudidx != -1; i++ )
X		if ( strcmp( s, BaudStr[i].baud) == 0 )
X		{
X			Rsconf(BaudStr[i].baudidx, -1, -1, -1, -1, -1);
X			break;
X		}
X	return;
X}
X/*
X *                  Command shell processing
X *
X * Pass a command the the host operating system to execute.
X *
X */
X/* 		shell
X
X
X*/
Xnotimp( argc, argv )
Xint argc;
Xchar **argv;
X{
X	printf( "%s not implemented\n", argv[0]);
X}
X
Xchar *getcwd();
X
Xshell( command, inname, outname, errname )
Xchar * command;
Xchar * inname;
Xchar * outname;
Xchar * errname;
X{
X
X	char	*argvec[50];	/* array of pointers to make up arg list */
X	char	hostname[32];	/* place to put munged file name */
X	char	curdir[64];	/* place to remember current directory */
X
X	int	rmail();	/* mail program */
X	int	rnews();	/* news program */
X	int	(*proto)();	/* variable containing program pointer */
X	
X	int 	argc;		/* will contain the number of args */
X	char	**argv;		/* will contain pointer to arg vector */
X
X	int	args;		/* temporary for copy of argc */
X	
X	/*
X	 * Break up the command line into an argument vector
X	 */
X	argc = getargs( command, argvec );
X	argv = argvec;
X
X	if ( debuglevel > 5 )
X	{
X	   args = argc;
X	   while ( args ) 
X	      fprintf( stderr, "arg: %d  %s\n", args--, *argv++ );
X	   argv = argvec;
X	}
X	/*
X	 * Initialize to function which will print 'not implemented
X	 * then see if the command is one we know about and if so set
X	 * up out function pointer.
X	 */
X	proto = notimp;
X
X	if ( strcmp( *argv, "rmail" ) == SAME )
X	   proto = rmail;
X	else if ( strcmp( *argv, "rnews" ) == SAME ) {
X	   proto = rnews;
X	}
X
X	*hostname = '\0';
X	if ( *inname != '\0' )
X	   importpath( hostname, inname );
X		
X	if ( *hostname != '\0' ) {
X	   fprintf( stderr, "reopening stdin as %s\n", hostname);
X	   getcwd(curdir, 0);
X	   fclose( stdin );
X	   if ( fopen( hostname, "r" ) == (FILE *)NULL ) /* */
X/*	   if ( freopen( hostname, "r", stdin ) == (FILE *)NULL ) /* */
X	   {
X	      fprintf( stderr, "Couldn't open %s, %d\n", hostname, errno );
X	      exit(-1);
X	   }
X	}
X	(*proto)( argc, argv );
X
X	chdir( curdir );
X
X	fclose( stdin );
X	if ( fopen(  "CON:", "r" ) == (FILE *)NULL )
X	{
X	   fprintf( stderr, "Couldn't reopen CON:" );
X	}
X/*	freopen( "CON:", "r", stdin ); /* */
X
X}
X
X
X/* */
X/*
X *
X *      login (for slave in PC mode)
X * Real dumb login handshake
X*/
Xlogin()
X{
X	char	logmsg[132];
Xlretry:
X	msgtime = 9999;
X	rmsg(logmsg, 0); /* wait for a <CR> or <NL> */
X	msgtime = 2 * MSGTIME;
X	wmsg("Username:", 0);
X	rmsg(logmsg, 0);
X	printmsg( 0, "Username = %s", logmsg );
X	wmsg("Password:", 0);
X	rmsg(logmsg, 0);
X	printmsg( 14, "Password = %s", logmsg );
X	if (strcmp(logmsg, "uucp") != 0) 
X		goto lretry;
X	return('I');
X}
X
X
SHAR_EOF
chmod 0600 uusup.c || echo "restore of uusup.c fails"
rm -f s2_seq_.tmp
echo "You have unpacked the last part"
exit 0