[comp.sources.unix] v21i084: File distribution alternative to rdist, Part01/03

rsalz@uunet.uu.net (Rich Salz) (04/10/90)

Submitted-by: Rich Salz <rsalz@bbn.com>
Posting-number: Volume 21, Issue 84
Archive-name: coda/part01

Coda, the code distribution aide, is a system to keep source distributions
current across a set of machines.  The model is that the master source
tree is kept on a server host, and client hosts run coda to get themselves
in sync with the server.  This is different from rdist where the server
"pushes" files out to its clients.

Coda is not as flexible as rdist, but it requires less of the client
machines in that they do not have to be running Berkeley networking
programs or even Unix at all.  The client is simple, and designed to be
easy to port.  It currently runs on these systems:
	BSD, Ultrix, Sun, Masscomp
	VMS with Wollongong networking
	ATT3B2 with Wollongong networking (might be slightly broken)
	ATT6386 with Interlan networking
	Xenix with Excelan networking
	We will probably do an MSDOS port in a couple of months

Coda was written to help us distribute our sources before we did our
system builds.  It replaced our ad-hoc collection of rdist, tar, rcp, ftp
and asphalt (a local tar-file reader ported for VMS).  It originally stood
for Cronus distribution aide.  We've been using it for many months now;
I hope others find it useful as well.
	/rich $alz

#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 1 (of 3)."
# Contents:  Codafile MANIFEST Makeatt386 Makeatt3b2 Makefile Makexen
#   README alloca.inc client.h coda.opt descrip.mms gram.y hostdb.c
#   lex.l libatt.c libbsd.c libxen.c log.c patchlevel.h version.c
#   vmsutime.inc
# Wrapped by rsalz@litchi.bbn.com on Mon Apr  9 16:49:02 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Codafile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Codafile'\"
else
echo shar: Extracting \"'Codafile'\" \(2542 characters\)
sed "s/^X//" >'Codafile' <<'END_OF_FILE'
X##
X##  Copyright 1989 BBN Systems and Technologies Corporation.
X##  All Rights Reserved.
X##  This is free software, and may be distributed under the terms of the
X##  GNU Public License; see the file COPYING for more details.
X##
X##  Codafile for Cronus source distribution.
X##  $Header: Codafile,v 2.0 90/04/02 16:55:56 rsalz Exp $
X##  $Revision: 2.0 $
X##
X
X##  Relative pathnames start from this directory, unless the client
X##  tells us otherwise.
Xdefine root	= /usr/cronus;
X
X##  Allow the client to specify a different root.
X#define rooted = YES;
X
X##  No binaries here.
Xdefine binaries = NO;
X
X##  The list of hosts we ship to and their types.
Xhost	citron.bbn.com		= VMS;
Xhost	doe.bbn.com		= sun4;
Xhost	prune.bbn.com		= sun3;
Xhost	gneiss.bbn.com		= sun386;
Xhost	grape.bbn.com		= sysv;
Xhost	guava.bbn.com		= masscomp;
Xhost	kiwi.bbn.com		= sysv;
Xhost	litchi.bbn.com		= sun3;
Xhost	melon.bbn.com		= mach;
Xhost	mentor.bbn.com		= sun2;
Xhost	papaya.bbn.com		= sun3;
Xhost	izar.bbn.com		= sun4;
Xhost	peach.bbn.com		= xenix;
Xhost	pineapple.bbn.com	= ultrix;
Xhost	vulcan.bbn.com		= sun2;
X
X##  Suns
Xclass	SUN	=
X    sun2, sun3, sun386, sun4;
X
X##  List of all UNIX types.
Xclass	UNIX	=
X    mach, masscomp, sun2, sun3, sun386, sun4, sysv, ultrix, xenix;
X
X##
X
Xinclude: _ALL {
X    include
X}
X
Xinstall: _ALL {
X    install
X	except	UNIX	"*.com";
X	except	VMS	addservice, await_mgr, catalog_host, do_authen,
X			do_bug, do_cm, do_config, do_cosdir, do_createprins,
X			do_diskless, do_install, do_mcs, do_motd, do_pf,
X			do_poller, do_pristine, do_repeater, do_typedef,
X			do_xenix, killmgr, readit, scrub, zap_file;
X}
X
X##  Random stuff
Xmisc: _ALL {
X    cbin
X	except	VMS	dcc, dlint;
X    clib
X	except 	_ALL	commandfile, "*.[oa]", "llib-l*";
X	except	UNIX	cronus.mms, cronus.opt;
X	except	directory VMS	lint, diamond;
X	except	directory mach	diamond;
X    directory cetc
X    cetc/hostfile		# Only these files
X    cetc/typefile		# named here
X    cetc/errors.8
X    cetc/errors.44
X    directory mgrs
X    public			# Everyone gets everything
X}
X
X##  Sources; raison d'etre.
Xsources: _ALL {
X    src
X	except VMS	Makefile, "*.sh", "*.s", "llib-l*";
X	except UNIX	descrip.mms,  "*.opt", "*.com", "*.mar";
X	except _ALL	"*.lo", "*.do", "*.[oa]", "*.ln";
X	except _ALL	a.out, core, foo, tags, make.out, lint;
X	except directory _ALL	testing;
X	except directory xenix	arctic, examine;
X	except directory xenix	dumpobject, fixobject, ping;
X	except directory VMS	arctic, examine, ping;
X}
X
X##  Testing; not given by default; you must ask for it.
Xonly_explicitly testing: _ALL {
X    src/testing
X}
END_OF_FILE
if test 2542 -ne `wc -c <'Codafile'`; then
    echo shar: \"'Codafile'\" unpacked with wrong size!
fi
# end of 'Codafile'
fi
if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'MANIFEST'\"
else
echo shar: Extracting \"'MANIFEST'\" \(1865 characters\)
sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
X   File Name		Archive #	Description
X-----------------------------------------------------------
X COPYING                    3	Licensing terms and restrictions
X Codafile                   1	Sample codafile (the one Cronus uses)
X MANIFEST                   1	This shipping list
X Makeatt386                 1	Makefile for ATT6386 with Interlan V.3 TCP
X Makeatt3b2                 1	Makefile for ATT3B2 with Wollongong TCP
X Makefile                   1	Makefile for server and BSD client
X Makexen                    1	Makefile for XENIX with Excelan TCP
X README                     1	What coda is all about
X adt.c                      2	Data abstractions for server
X alloca.inc                 1	An alloca() routine for Interlan on ATT6386
X client.c                   3	Main code for client
X client.h                   1	Header file for client
X coda.1                     3	Coda manual page
X coda.opt                   1	VMS linker options file for client
X codaserver.8               2	Server manual page
X descrip.mms                1	MMS file for VMS with Wollongong TCP
X file.c                     2	File routines for server
X gram.y                     1	Control file parser for server
X hostdb.c                   1	An implementation of the 4.2BSD hostdb routines
X lex.l                      1	Lexical analyzer for server
X libatt.c                   1	Library for ATT3B2 and ATT6386
X libbsd.c                   1	Library for BSD
X libvms.c                   2	Library routines for VMS 
X libxen.c                   1	Library routines for XENIX
X log.c                      1	Logging routines for server
X patchlevel.h               1	Misteak recorder
X server.c                   2	Main driver for server
X server.h                   2	Header file for server
X version.c                  1	Print copyright and version
X vmsutime.inc               1	A utime() routine for VMS
END_OF_FILE
if test 1865 -ne `wc -c <'MANIFEST'`; then
    echo shar: \"'MANIFEST'\" unpacked with wrong size!
fi
# end of 'MANIFEST'
fi
if test -f 'Makeatt386' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makeatt386'\"
else
echo shar: Extracting \"'Makeatt386'\" \(902 characters\)
sed "s/^X//" >'Makeatt386' <<'END_OF_FILE'
X##
X##  Copyright 1989 BBN Systems and Technologies Corporation.
X##  All Rights Reserved.
X##  This is free software, and may be distributed under the terms of the
X##  GNU Public License; see the file COPYING for more details.
X##
X##  Makefile for CODA client on ATT6386 with Interlan V.3 TCP.
X##  $Header: Makeatt386,v 2.0 90/03/23 14:40:43 rsalz Exp $
X##
XSHELL	= /bin/sh
XDEFS	= -DATTsysv -DATTI386 -I/usr/netinclude
XCFLAGS	= -g $(DEFS)
XLIBS	= -lnet -lnsl_s
X
X##  Client files.
XC_SRC	= client.c version.c libatt.c
XC_OBJ	= client.o version.o libatt.o
X
X
X##  Generic targets.
Xall:		coda
X
Xinstall:	all
X	@echo Install according to local convention
X
Xclean:
X	rm -f *.o y.* foo core lint? tags a.out coda
X
X
X##  Lint.
Xlint:		lintc
X
Xlintc:		coda
X	lint $(DEFS) -a -h -x $(C_SRC) >lintc
X
X
X##  Client.
Xcoda:		$(C_OBJ)
X	@rm -f coda
X	$(CC) $(CFLAGS) -o coda $(C_OBJ) $(LIBS)
X
X$(C_OBJ):	client.h
X
Xversion.o:	patchlevel.h
END_OF_FILE
if test 902 -ne `wc -c <'Makeatt386'`; then
    echo shar: \"'Makeatt386'\" unpacked with wrong size!
fi
# end of 'Makeatt386'
fi
if test -f 'Makeatt3b2' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makeatt3b2'\"
else
echo shar: Extracting \"'Makeatt3b2'\" \(916 characters\)
sed "s/^X//" >'Makeatt3b2' <<'END_OF_FILE'
X##
X##  Copyright 1989 BBN Systems and Technologies Corporation.
X##  All Rights Reserved.
X##  This is free software, and may be distributed under the terms of the
X##  GNU Public License; see the file COPYING for more details.
X##
X##  Makefile for CODA client on ATT3B2 with Wollongong TCP.
X##  $Header: Makeatt3b2,v 2.0 90/03/23 14:40:46 rsalz Exp $
X##
X
X##  THIS MAKEFILE MIGHT BE WRONG!
X
XSHELL	= /bin/sh
XDEFS	= -DATTsysv -DATT3B2
XCFLAGS	= -g $(DEFS)
XLIBS	= -lnet -lnsl_s
X
X##  Client files.
XC_SRC	= client.c version.c libatt.c
XC_OBJ	= client.o version.o libatt.o
X
X
X##  Generic targets.
Xall:		coda
X
Xinstall:	all
X	@echo Install according to local convention
X
Xclean:
X	rm -f *.o y.* foo core lint? tags a.out coda
X
X
X##  Lint.
Xlint:		lintc
X
Xlintc:		coda
X	lint $(DEFS) -a -h -x $(C_SRC) >lintc
X
X
X##  Client.
Xcoda:		$(C_OBJ)
X	@rm -f coda
X	$(CC) $(CFLAGS) -o coda $(C_OBJ) $(LIBS)
X
X$(C_OBJ):	client.h
X
Xversion.o:	patchlevel.h
END_OF_FILE
if test 916 -ne `wc -c <'Makeatt3b2'`; then
    echo shar: \"'Makeatt3b2'\" unpacked with wrong size!
fi
# end of 'Makeatt3b2'
fi
if test -f 'Makefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makefile'\"
else
echo shar: Extracting \"'Makefile'\" \(1674 characters\)
sed "s/^X//" >'Makefile' <<'END_OF_FILE'
X##
X##  Copyright 1989 BBN Systems and Technologies Corporation.
X##  All Rights Reserved.
X##  This is free software, and may be distributed under the terms of the
X##  GNU Public License; see the file COPYING for more details.
X##
X##  Makefile for CODA server and BSD client.
X##  This is the master Makefile.
X##  $Header: Makefile,v 2.0 90/04/02 16:46:30 rsalz Exp $
X##
XSHELL	= /bin/sh
XDEFS	= -DBSD
XCFLAGS	= -g $(DEFS)
X
X##  Server files.
XS_SRC	= server.c version.c gram.c lex.c adt.c log.c file.c
XS_OBJ	= server.o version.o gram.o lex.o adt.o log.o file.o
X
X##  Client files.
XC_SRC	= client.c version.c libbsd.c
XC_OBJ	= client.o version.o libbsd.o
X
X
X##  Generic targets.
Xall:		codaserver coda
X
Xinstall:	all
X	@echo Install according to local convention
X
Xclean:
X	rm -f *.o y.* foo core lint? tags a.out codaserver coda SHAR0?
Xrealclean:	clean
X	rm -f lex.c gram.c gram.h
X
X
X##  Lint.
Xlint:		lints lintc
X
Xlintc:		coda
X	lint $(DEFS) -a -h -z $(C_SRC) | fgrep -v 'pointer alignment' >lintc
Xlints:		codaserver
X	lint $(DEFS) -a -h -z $(S_SRC) | fgrep -v 'pointer alignment' >lints
X
X
X##  Publication.
Xshar:
X	makekit -n SHAR -m
X	@rm -f MANIFEST.BAK
X
X##  Server.
Xcodaserver:	$(S_OBJ)
X	@rm -f codaserver
X	$(CC) $(CFLAGS) -o codaserver $(S_OBJ)
X
X$(S_OBJ):	server.h
X
Xlex.c:			lex.l
Xlex.o gram.o:		gram.h
Xgram.h gram.c:		gram.y
X	@rm -f y.tab.c y.tab.h gram.c gram.h
X	yacc -d gram.y
X	@mv y.tab.c gram.c
X	@mv y.tab.h gram.h
X
X
X##  Client.
Xcoda:		$(C_OBJ)
X	@rm -f coda
X	$(CC) $(CFLAGS) -o coda $(C_OBJ)
X
X$(C_OBJ):	client.h
X
Xversion.o:	patchlevel.h
X
X
X##  Saber
X.SUFFIXES:		.c .src
X.c.src:
X	#load $(CFLAGS) $<
Xsabers:			$(S_SRC)
X	#load $(CFLAGS) $(S_SRC)
Xsaberc:			$(C_SRC)
X	#load $(CFLAGS) $(C_SRC)
END_OF_FILE
if test 1674 -ne `wc -c <'Makefile'`; then
    echo shar: \"'Makefile'\" unpacked with wrong size!
fi
# end of 'Makefile'
fi
if test -f 'Makexen' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Makexen'\"
else
echo shar: Extracting \"'Makexen'\" \(894 characters\)
sed "s/^X//" >'Makexen' <<'END_OF_FILE'
X##
X##  Copyright 1989 BBN Systems and Technologies Corporation.
X##  All Rights Reserved.
X##  This is free software, and may be distributed under the terms of the
X##  GNU Public License; see the file COPYING for more details.
X##
X##  Makefile for CODA client on XENIX with Excelan TCP.
X##  $Header: Makexen,v 2.0 90/03/23 14:40:51 rsalz Exp $
X##
XSHELL	= /bin/sh
XDEFS	= -DXENIX
XCFLAGS	= $(DEFS) -SEG 1000 -F 4000
XLIBS	= -lx -lsocket
X
X##  Client files.
XC_SRC	= client.c version.c libxen.c hostdb.c
XC_OBJ	= client.o version.o libxen.o hostdb.o
X
X
X##  Generic targets.
Xall:		coda
X
Xinstall:	all
X	@echo Install according to local convention
X
Xclean:
X	rm -f *.o y.* foo core lint? tags a.out coda
X
X
X##  Lint.
Xlint:		lintc
X
Xlintc:		coda
X	lint $(DEFS) -a -h -x $(C_SRC) >lintc
X
X
X##  Client.
Xcoda:		$(C_OBJ)
X	@rm -f coda
X	$(CC) $(CFLAGS) -o coda $(C_OBJ) $(LIBS)
X
X$(C_OBJ):	client.h
X
Xversion.o:	patchlevel.h
END_OF_FILE
if test 894 -ne `wc -c <'Makexen'`; then
    echo shar: \"'Makexen'\" unpacked with wrong size!
fi
# end of 'Makexen'
fi
if test -f 'README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README'\"
else
echo shar: Extracting \"'README'\" \(3697 characters\)
sed "s/^X//" >'README' <<'END_OF_FILE'
XCoda, the code distribution aide, is a system to keep source distributions
Xcurrent across a set of machines.  The model is that the master source
Xtree is kept on a server host, and client hosts run coda to get themselves
Xin sync with the server.  This is different from rdist where the server
X"pushes" files out to its clients.
X
XCoda is not as flexible as rdist(1), but it requires less of the client
Xmachines in that they do not have to be running Berkeley networking
Xprograms or even Unix at all.  The client is simple, and designed to be
Xeasy to port.  It currently runs on these systems:
X	BSD, Ultrix, Sun, Masscomp
X	VMS with Wollongong networking
X	ATT3B2 with Wollongong networking (might be slightly broken)
X	ATT6386 with Interlan networking
X	Xenix with Excelan networking
X
XThe server current runs under the INET daemon on a BSD-like system, but
Xcould be ported to other Unix systems, or even VMS, without too much
Xeffort.
X
XBecause of the coda model, a client has to be told several things:  where
Xthe server is, the user name on the host and where the sources are.  These
Xcan be specified on the command line, or a simple config file can be used
Xto any set of the necessary parameters.
X
XThe coda server uses a simple but powerful control file to determine what
Xfiles are appropriate for each client.  The client directs the server to
Xread the file when it connects, so that multiple source trees can be
Xeasily maintained on one server.  In the Codafile, hosts are grouped
Xinto classes.  Directories are grouped into blocks, and patterns are
Xused to exclude hosts from receiving certain files.  For example:
X	sources: _ALL {
X	    #  Everyone gets all the programs, but no object files
X	    src/programs
X		except	_ALL	"*.o", foo, core, tags a.out;
X		except	VMS	Makefile, "*.sh", "*.s", "llib-l*";
X		except	UNIX	descrip.mms,  "*.opt", "*.com", "*.mar";
X	}
X
X	##  VMS library
X	vmslib: VMS {
X	    src/libvms
X	}
X
X	##  Unix library
X	unixlib: UNIX {
X	    src/libunix
X		except	_ALL	"*.[oa]", "llib-l*.ln";
X	}
X
XInstallation
X------------
XPick a port number for the service to be running on; to use a port number
Xother than 1999, edit client.h and rebuild, or make sure to inform your
Xusers about the change.  (The server doesn't care what port it is running
Xon.)  Edit server.h to set the log file location.  and install the server
Xbinary in the appropriate directory.  (It's shown as ... in the paragraphs
Xbelow.)
X
XYou will have to add the server to any machines where you want to make
Xsources available.  Add a line like the following to /etc/services:
X	coda    1999/tcp     # code distribution
XIf you're using Yellow Pages don't forget to yppush(8).
X
XNext you will have to edit the inetd(8) configuration file.  On a
X4.2BSD-based system, add this line to /etc/inetd.conf:
X	coda stream tcp nowait .../codaserver codaserver
XOn a 4.3BSD-based system or SunOS4 add this line to /etc/inetd.conf:
X	coda stream tcp nowait root .../codaserver codaserver
XYou will then have to send a HUP signal to the inet daemon.
X
XOn a SunOS3 system, add this line to /etc/servers:
X	coda   tcp   .../codaserver
XYou will then have to kill and restart inetd.
X
XThe coda server requires the remote user to log in with a name and password
Xbefore sending any files.  It then does a setuid to that user.  In order to
Xdo this, it should start out running as root.
X
XEnjoy.
X
XCoda was written by Rich $alz <rsalz@bbn.com>.
X
XIt has the following copyright:
X    Copyright 1989 BBN Systems and Technologies Corporation.
X    All Rights Reserved.
X    This is free software, and may be distributed under the terms of the
X    GNU Public License; see the file COPYING for more details.
X    $Header: README,v 2.0 90/03/23 14:40:54 rsalz Exp $
END_OF_FILE
if test 3697 -ne `wc -c <'README'`; then
    echo shar: \"'README'\" unpacked with wrong size!
fi
# end of 'README'
fi
if test -f 'alloca.inc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'alloca.inc'\"
else
echo shar: Extracting \"'alloca.inc'\" \(1630 characters\)
sed "s/^X//" >'alloca.inc' <<'END_OF_FILE'
X/*
X**  This file is in the public domain.
X**
X**  This is a hacked-over and reformatted version of the public domain
X**  alloca routine written by Doug Gwyn <gwyn@brl.mil> for which I am
X**  very grateful.
X*/
X#ifdef	RCSID
Xstatic char RCS2[] =
X	"$Header: alloca.inc,v 2.0 90/03/23 14:41:01 rsalz Exp $";
X#endif	/* RCSID */
X
X
X#define ALIGN_SIZE	(sizeof (double))
X
Xtypedef union _HEADER {
X    char	align[ALIGN_SIZE];
X    struct {
X	union _HEADER	*Next;
X	char		*Depth;
X    }		h;
X} HEADER;
X
X
X/*
X**  Recurse once and compare the address of local variables to see
X**  which way the stack grows.
X*/
Xstatic int
XFindDirection()
X{
X    static char	*addr;
X    auto char	dummy;
X
X    if (addr == NULL) {
X	addr = &dummy;
X	return FindDirection();
X    }
X    return &dummy > addr ? 1 : -1;
X}
X
X
Xchar *
Xalloca(size)
X    unsigned int	size;
X{
X    static HEADER	*AllocationList;
X    static int		Direction;
X    register char	*Depth;
X    register HEADER	*hp;
X    register HEADER	*Next;
X    auto char		probe;
X
X    if (Direction == 0)
X	Direction = FindDirection();
X
X    /* Reclaim garbage, which is defined as all alloca()'d storage
X     * that was allocated deeper in the stack than we are now. */
X    for (Depth = &probe, hp = AllocationList; hp; )
X	if (Direction > 0 && hp->h.Depth > Depth
X	 || Direction < 0 && hp->h.Depth < Depth) {
X	    Next = hp->h.Next;
X	    free((char *)hp);
X	    hp = Next;
X	}
X	else
X	    break;
X    AllocationList = hp;
X
X    if (size == 0
X     || (hp = (HEADER *)malloc(sizeof (HEADER) + size)) == NULL)
X	return NULL;
X
X    hp->h.Next = AllocationList;
X    hp->h.Depth = Depth;
X    AllocationList = hp;
X    return (char *)(hp + 1);
X}
END_OF_FILE
if test 1630 -ne `wc -c <'alloca.inc'`; then
    echo shar: \"'alloca.inc'\" unpacked with wrong size!
fi
# end of 'alloca.inc'
fi
if test -f 'client.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'client.h'\"
else
echo shar: Extracting \"'client.h'\" \(2656 characters\)
sed "s/^X//" >'client.h' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Header file for CODA clients.
X**  $Header: client.h,v 2.0 90/03/23 14:41:08 rsalz Exp $
X*/
X/* SUPPRESS 223 *//* Nested comment */
X#include <stdio.h>
X
X#ifdef	XENIX
X/* Stupid, just plain stupid... */
X#undef	NULL
X#define NULL		0
X#endif	/* XENIX */
X
X/*
X**  Constants, compilation control, et cetera.
X*/
X
X/* Assorted constants. */
X#define TRUE		1		/* Any non-zero value		*/
X#define FALSE		0		/* Must be zero			*/
X#define NOBODY		-2		/* NFS's idea of root		*/
X#define PORTNUMBER	1999		/* Port to contact server on	*/
X#define SIZE		256		/* String buffer size		*/
X#define LINES_DELTA	50		/* Growth clump of line array	*/
X
X/*
X**  Set our exit codes; tell stupid VMS to shut up.  This goes away
X**  when ANSI C comes along.
X*/
X#ifndef	VMS
X#define CODA_INIT	"%s/.codarc"	/* Argument to %s is $HOME	*/
X#define EXITOK		0
X#define EXITERR		1
X#else
X#define CODA_INIT	"SYS$LOGIN:CODA.DAT"
X#define EXITOK		0x10000001
X#define EXITERR		0x10000002
X#endif	/* VMS */
X
X/* Comile in RCS id strings? */
X#ifndef	SABER
X#define RCSID
X#endif	/* SABER */
X
X/* Hide routines that can be hidden? */
X#define STATIC		static		/* .. */
X/*efine STATIC		/* NULL */	/* .. */
X
X/* Trust register allocations? */
X#define REGISTER	register	/* .. */
X/*efine REGISTER	/* NULL */	/* .. */
X
X/* Shut up, okay? */
X#ifdef	lint
X#undef putc
X#undef putchar
X#undef RCSID
X#endif	/* lint */
X
X/* Memory allocation. */
X#define NEW(T, c)		\
X	((T *)malloc((unsigned int)(sizeof (T) * (c))))
X#define GROW(p, T, c)		\
X	((T *)realloc((char *)p, (unsigned int)(sizeof (T) * (c))))
X#define COPY(p)			\
X	strcpy(NEW(char, strlen(p) + 1), p)
X
X#define WHITE(c)		((c) == ' ' || c == '\t')
X
Xtypedef int		BOOL;
X
X
X
X/*
X**  Data is declared everywhere, lives oncewhere.
X*/
X#ifdef	MAINLINE
X#define EXTERN		/* NULL */
X#else
X#define EXTERN		extern
X#endif	/* MAINLINE */
X
XEXTERN int	SRVtrace;		/* Trace server IO?		*/
X
Xvoid	Fatal();
Xvoid	GetPassword();
Xint	SRVcget();
Xint	SRVget();
Xint	SRVopen();
Xvoid	SRVclose();
Xvoid	SRVput();
X
X/* From the C library. */
Xextern int	errno;
Xextern int	optind;
Xextern char	*optarg;
X
Xextern long	atol();
Xextern char	*getenv();
Xextern char	*malloc();
Xextern char	*mktemp();
Xextern char	*realloc();
Xextern char	*strchr();
Xextern char	*strrchr();
Xextern char	*strcpy();
X
X#ifdef	BSD
Xextern char	*sprintf();		/* Too painful, my ass		*/
X#endif	/* BSD */
X
X#ifdef	ATTsysv
Xextern void	exit();
Xextern void	perror();
Xextern char	*memset();
Xextern char	*memcpy();
X#endif	/* ATTsysv */
END_OF_FILE
if test 2656 -ne `wc -c <'client.h'`; then
    echo shar: \"'client.h'\" unpacked with wrong size!
fi
# end of 'client.h'
fi
if test -f 'coda.opt' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'coda.opt'\"
else
echo shar: Extracting \"'coda.opt'\" \(531 characters\)
sed "s/^X//" >'coda.opt' <<'END_OF_FILE'
X!
X!  Copyright 1989 BBN Systems and Technologies Corporation.
X!  All Rights Reserved.
X!  This is free software, and may be distributed under the terms of the
X!  GNU Public License; see the file COPYING for more details.
X!
X!  VMS linker options file for CODA client.
X!  This should match with the "/INCLUDE" qualifier in descrip.mms.
X!  $Header: coda.opt,v 2.0 90/03/23 14:41:14 rsalz Exp $
X!
Xdua0:[netdist.lib]libnet.olb/lib, -
Xdua0:[netdist.lib]libnetacc.olb/lib, -
Xdua0:[netdist.lib]libnet.olb/lib, -
Xsys$share:vaxcrtl.exe/share
END_OF_FILE
if test 531 -ne `wc -c <'coda.opt'`; then
    echo shar: \"'coda.opt'\" unpacked with wrong size!
fi
# end of 'coda.opt'
fi
if test -f 'descrip.mms' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'descrip.mms'\"
else
echo shar: Extracting \"'descrip.mms'\" \(814 characters\)
sed "s/^X//" >'descrip.mms' <<'END_OF_FILE'
X##
X##  Copyright 1989 BBN Systems and Technologies Corporation.
X##  All Rights Reserved.
X##  This is free software, and may be distributed under the terms of the
X##  GNU Public License; see the file COPYING for more details.
X##
X##  VMS MMS file for CODA client.
X##  $Header: descrip.mms,v 2.0 90/04/09 16:23:37 rsalz Exp $
X##
X#DEBUG	= /DEBUG
XDEBUG	=
X
XCFLAGS	= $(DEBUG) /DEFINE=VMS /INCLUDE=DUA0:[NETDIST.INCLUDE.]
XOBJ	= client.obj version.obj libvms.obj
X
X
X##  Generic targets.
Xall		: coda.exe
X	@ write sys$output ""
X
Xinstall		: all
X	@ write sys$output "Install according to local convention"
X
Xclean		:
X	delete/noconfirm *.obj;*, *.exe;*, foo.txt;*
X
Xpurge		:
X	purge
X
X
X##  Client.
Xcoda.exe	: $(OBJ)
X	LINK $(DEBUG) $(LINKFLAGS) $+,coda.opt/opt
X
X$(OBJ)		: client.h
Xlibvms.obj	: vmsutime.inc
Xversion.obj	: patchlevel.h
END_OF_FILE
if test 814 -ne `wc -c <'descrip.mms'`; then
    echo shar: \"'descrip.mms'\" unpacked with wrong size!
fi
# end of 'descrip.mms'
fi
if test -f 'gram.y' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'gram.y'\"
else
echo shar: Extracting \"'gram.y'\" \(2660 characters\)
sed "s/^X//" >'gram.y' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Control file parser for CODA server.
X*/
X%{
X/* SUPPRESS 287 on yaccpar_sccsid *//* Unused static variable */
X/* SUPPRESS 288 on yyerrlab *//* Unused label */
X#include "server.h"
X#ifdef	RCSID
Xstatic char RCS[] =
X	"$Header: gram.y,v 2.0 90/03/23 14:41:27 rsalz Exp $";
X#endif	/* RCSID */
X%}
X
X%union {
X    BOOL	Boolean;
X    char	*String;
X    STRLIST	*Slist;
X    EXCEPTION	*Elist;
X    DIRLIST	*Flist;
X};
X
X%token	BINARIES CLASS DEFINE DIRECTORY EXCEPT HOST ID ONLY_EXPLICITLY
X%token	ROOT ROOTED
X
X%type	<Boolean>	opt_dir opt_exp
X%type	<String>	ID
X%type	<Elist>		elist
X%type	<Flist>		flist
X%type	<Slist>		slist
X
X%%
X
Xfile	: line
X	| line file
X	;
X
Xline	: DEFINE ROOT '=' ID ';' { 
X	    if (TheRoot)
X		free(TheRoot);
X	    TheRoot = $4;
X	}
X	| DEFINE BINARIES '=' ID ';' {
X	    AllowBinaries = $4[0] == 'Y' || $4[0] == 'y';
X	}
X	| DEFINE ROOTED '=' ID ';' {
X	    Rooted = $4[0] == 'Y' || $4[0] == 'y';
X	}
X	| CLASS ID '=' slist ';' {
X	    AddClassesToClass($2, $4);
X	}
X	| HOST ID '=' ID ';' {
X	    Uppercase($2);
X	    DefineHost($2, $4);
X	}
X	| opt_exp ID ':' ID '{' flist '}' {
X	    BLOCK	*B;
X
X	    if (FindBlock($2) != NULL)
X		yyerror("Block redefined");
X	    else {
X		B = NEW(BLOCK, 1);
X		B->Excluded = $1;
X		B->Name = $2;
X		B->Class = $4;
X		B->Directories = $6;
X		B->Next = BaseBlock.Next;
X		BaseBlock.Next = B;
X	    }
X	}
X	| error ';' {
X#ifdef	lint
X	    /* I am compulsive about lint, and probably know too much
X	     * about the way Yacc works... */
X	    YYERROR;
X#endif	/* lint */
X	}
X	;
X
Xopt_exp	: ONLY_EXPLICITLY {
X	    $$ = TRUE;
X	}
X	| /* NULL */ {
X	    $$ = FALSE;
X	}
X	;
X
Xflist	: /* NULL */ {
X	    $$ = NULL;
X	}
X	| opt_dir ID elist flist {
X	    $$ = NEW(DIRLIST, 1);
X	    $$->Directory = $1;
X	    $$->Value = $2;
X	    $$->Exceptions = $3;
X	    $$->Next = $4;
X	}
X	;
X
Xopt_dir	: DIRECTORY {
X	    $$ = TRUE;
X	}
X	| /* NULL */ {
X	    $$ = FALSE;
X	}
X	;
X
Xelist	: /* NULL */ {
X	    $$ = NULL;
X	}
X	| EXCEPT opt_dir ID slist ';' elist {
X	    STRLIST	*S;
X
X	    /* Make sure the user isn't confused. */
X	    for (S = $4; S; S = S->Next)
X		if (*S->Value != '^' && strchr(S->Value, '/'))
X		    yyerror("Illegal character (\"/\") in exception");
X
X	    $$ = NEW(EXCEPTION, 1);
X	    $$->Directory = $2;
X	    $$->Class = $3;
X	    $$->Value = $4;
X	    $$->Next = $6;
X	}
X	;
X
Xslist	: ID {
X	    $$ = NEW(STRLIST, 1);
X	    $$->Value = $1;
X	    $$->Next = NULL;
X	}
X	| ID ',' slist {
X	    $$ = NEW(STRLIST, 1);
X	    $$->Value = $1;
X	    $$->Next = $3;
X	}
X	;
X
X%%
END_OF_FILE
if test 2660 -ne `wc -c <'gram.y'`; then
    echo shar: \"'gram.y'\" unpacked with wrong size!
fi
# end of 'gram.y'
fi
if test -f 'hostdb.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'hostdb.c'\"
else
echo shar: Extracting \"'hostdb.c'\" \(4253 characters\)
sed "s/^X//" >'hostdb.c' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  An implementation of the 4.2BSD hostname lookup routines.
X**  Not based on licensed code.
X*/
X#include <stdio.h>
X#include <ctype.h>
X#ifdef	XENIX
X#include <netdb.h>
X#define HAVE_HOSTENT
X/* Stupid, just plain stupid... */
X#undef NULL
X#define NULL		0
X#endif	/* XENIX */
X#ifdef	RCSID
Xstatic char RCS[] =
X	"$Header: hostdb.c,v 2.0 90/03/23 14:41:30 rsalz Exp $";
X#endif	/* RCSID */
X
X/* Constants and shorthands. */
X#define TRUE		1
X#define FALSE		0
X#define MAXALIASES	10
X#define HOSTFILENAME	"/etc/hosts"
X#define ADDRLEN		4
X
X#define WHITE(c)	((c) == ' ' || (c) == '\t')
X
X#ifndef	AF_INET
X#define AF_INET		2
X#endif	/* AF_INET */
X
X
X#ifndef	HAVE_HOSTENT
Xstruct hostent {
X    char	*h_name;		/* The host's official name	*/
X    char	**h_aliases;		/* A/K/A list			*/
X    int		h_addrtype;		/* Address type			*/
X    int		h_length;		/* Size of the address		*/
X    char	*h_addr;		/* Pointer to the address	*/
X};
X#endif	/* HAVE_HOSTENT */
X
X
Xstatic FILE	*HostFile = NULL;	/* The open /etc/hosts file	*/
X
X
Xextern char	*strchr();
X
X
X/*
X**  Close the host file.
X*/
Xvoid
Xendhostent()
X{
X    if (HostFile) {
X	(void)fclose(HostFile);
X	HostFile = NULL;
X    }
X}
X
X
X/*
X**  Read the next line from the host file.
X*/
Xstatic struct hostent *
Xgethostent()
X{
X    static struct hostent	E;
X    static char			buff[200];
X    static char			*aliases[MAXALIASES];
X    static char			addr[ADDRLEN];
X    register int		i;
X    register char		*q;
X    register char		*p;
X
X    /* Open the file if necessary, reset state. */
X    if (HostFile == NULL) {
X	if ((HostFile = fopen(HOSTFILENAME, "r")) == NULL)
X	    return NULL;
X	E.h_addrtype = AF_INET;
X	E.h_length = ADDRLEN;
X	E.h_addr = addr;
X        E.h_aliases = aliases;
X    }
X
X    /* Loop until we get a good line. */
X    for ( ; ; ) {
X	if (fgets(buff, sizeof buff, HostFile) == NULL)
X	    return NULL;
X
X	/* Kill the comment and newline character, skip blank lines. */
X	if (p = strchr(buff, '#'))
X	    *p = '\0';
X	if (p = strchr(buff, '\n'))
X	    *p = '\0';
X	if (buff[0] == '\0')
X	    continue;
X
X	/* Parse the first field as a dotted quad. */
X	for (q = p = buff, i = 0; i < ADDRLEN; i++) {
X	    while (*p && *p != '.' && !WHITE(*p))
X		p++;
X	    if (*p == '\0')
X		break;
X	    *p = '\0';
X	    addr[i] = atoi(q);
X	    q = ++p;
X	}
X	if (i == ADDRLEN)
X	    break;
X    }
X
X    /* Skip whitespace, get the second field as the full name. */
X    while (*q && WHITE(*q))
X	q++;
X    for (E.h_name = q; *q && !WHITE(*q); )
X	q++;
X    if (*q)
X	*q++ = '\0';
X
X    /* Parse any aliases. */
X    for (i = 0; i < MAXALIASES - 1 && *q; i++) {
X        while (*q && WHITE(*q))
X	    q++;
X	for (aliases[i] = q; *q && !WHITE(*q); )
X	    q++;
X    	if (*q)
X	    *q++ = '\0';
X    }
X    aliases[i] = NULL;
X
X    return &E;
X}
X
X
X/*
X**  Compare two strings, ignoring case.
X*/
Xstatic int
Xsamehostname(n1, n2)
X    register char	*n1;
X    register char	*n2;
X{
X    register char	c1;
X    register char	c2;
X
X    for ( ; ; ) {
X	if ((c1 = *n1++) == (c2 = *n2++)) {
X	    if (c1 || c2)
X		continue;
X	    return TRUE;
X	}
X	if (islower(c1))
X	    c1 = toupper(c1);
X	if (islower(c2))
X	    c2 = toupper(c2);
X	if (c1 != c2)
X	    return FALSE;
X    }
X}
X
X
X/*
X**  Given a name, find the hostent structure.
X*/
Xstruct hostent *
Xgethostbyname(name)
X    register char		*name;
X{
X    register struct hostent	*E;
X    register int		i;
X
X    while (E = gethostent()) {
X	if (samehostname(name, E->h_name))
X	    break;
X	for (i = 0; E->h_aliases[i]; i++)
X	    if (samehostname(name, E->h_aliases[i]))
X		break;
X	if (E->h_aliases[i])
X	    break;
X    }
X    endhostent();
X
X    return E;
X}
X
X
X#if	0
X/*
X**  Given an address, find the hostent structure.
X*/
Xstruct hostent *
Xgethostbyaddr(p, length, type)
X    register char		*p;
X    int				length;
X    int				type;
X{
X    register struct hostent	*E;
X
X    /* We only handle Internet addresses here. */
X    if (length != ADDRLEN || type != AF_INET)
X	return NULL;
X
X    while (E = gethostent())
X	if (he->h_addr[0] == p[0] && he->h_addr[1] == p[1]
X	 && he->h_addr[2] == p[2] && he->h_addr[3] == p[3])
X	    break;
X    endhostent();
X
X    return E;
X}
X#endif	/* 0 */
END_OF_FILE
if test 4253 -ne `wc -c <'hostdb.c'`; then
    echo shar: \"'hostdb.c'\" unpacked with wrong size!
fi
# end of 'hostdb.c'
fi
if test -f 'lex.l' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lex.l'\"
else
echo shar: Extracting \"'lex.l'\" \(4117 characters\)
sed "s/^X//" >'lex.l' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Lexical analyzer for CODA server.
X*/
X%{
X/* SUPPRESS 11 in yylook *//* Pointer subtraction */
X/* SUPPRESS 14 on yycrank *//* Storing a bad pointer */
X/* SUPPRESS 15 on yyt *//* Copying a bad pointer */
X/* SUPPRESS 16 on yycrank *//* Initializing bad pointer */
X/* SUPPRESS 18 in yylook *//* Comparing bad pointer */
X/* SUPPRESS 287 on ncform_sccsid *//* Unused static variable */
X/* SUPPRESS 288 on yyfussy *//* Unused label */
X#include "server.h"
X#include <ctype.h>
X#include "gram.h"
X#ifdef	RCSID
Xstatic char RCS[] =
X	"$Header: lex.l,v 2.0 90/03/23 14:41:33 rsalz Exp $";
X#endif	/* RCSID */
X
X
X/* Key-value pair. */
Xtypedef struct _PAIR {
X    char	*name;
X    int		value;
X} PAIR;
X
X/* List of the keywords. */
XSTATIC PAIR	Keywords[] = {
X    {	"binaries",		BINARIES		},
X    {	"class",		CLASS			},
X    {	"define",		DEFINE			},
X    {	"directory",		DIRECTORY		},
X    {	"except",		EXCEPT			},
X    {	"host",			HOST			},
X    {	"only_explicitly",	ONLY_EXPLICITLY		},
X    {	"root",			ROOT			},
X    {	"rooted",		ROOTED			},
X    {	NULL,			0			}
X};
X
XSTATIC FILE	*F;			/* Input stream for LEX		*/
X
X#undef input
X#undef unput
X%}
X
X%%
X
X[a-z_]+		{
X		    /* A simple ID or keyword. */
X		    register PAIR	*p;
X
X		    for (p = Keywords; p->name; p++)
X			if (EQ(p->name, yytext))
X			    return p->value;
X		    yylval.String = COPY(yytext);
X		    return ID;
X		    /* NOTREACHED */
X		}
X
X[a-zA-Z0-9./_]+	{
X		    /* Most common filenames. */
X		    yylval.String = COPY(yytext);
X		    return ID;
X		    /* NOTREACHED */
X		}
X
X[{},;:=]	{
X		    /* Random special character. */
X		    return *yytext;
X		    /* NOTREACHED */
X		}
X
X[ \n\t\f]		{
X		    /* Tasty whitespace. */
X#ifdef	lint
X		    /* I am compulsive about lint natterings, and probably
X		     * know too much about the innards of LEX... */
X		    yyin = yyin;
X		    yytchar = yytchar;
X		    yyoutput(yyinput());
X		    yyunput(yyinput());
X		    REJECT;
X#endif	/* lint */
X		}
X
X\"[^"]*		{
X		    /* Quoted string. */
X		    int		c;
X
X		    /* See the Lex paper in Volume 2A or PS1:16
X		     * for details on this code. */
X		    if (yytext[yyleng - 1] == '\\')
X			yymore();
X		    else {
X			if ((c = input()) == '"') {
X			    yylval.String = COPY(&yytext[1]);
X			    return ID;
X			}
X			unput(c);
X			yyerror("Bad string");
X		    }
X		}
X
X#.*		{
X		    /* Comment. */
X		}
X
X
X.		{
X		    yyerror("Bad character");
X		}
X%%
X
X
X/*
X**  We found an error while parsing the file, report it.
X*/
Xvoid
Xyyerror(text)
X    char	*text;
X{
X    char	buff[SIZE];
X
X    /* Truncate string to fit. */
X    if (strlen(yytext) > SIZE / 2)
X	(void)strcpy(&yytext[SIZE / 2], "...");
X    (void)sprintf(buff, "ERROR %s near line %d (\"%s\").",
X		    text, yylineno, yytext);
X    Message(buff);
X    HaveErrors = TRUE;
X}
X
X
X/*
X**  Turn a string into all uppercase.
X*/
Xvoid
XUppercase(p)
X    register char	*p;
X{
X    for ( ; *p; p++)
X	if (isascii(*p) && islower(*p))
X	    *p = toupper(*p);
X}
X
X
X
X/*
X**  Called by lex at end-of-stream.  Return one if no more input.
X*/
XSTATIC int
Xyywrap()
X{
X    return 1;
X}
X
X
X/*
X**  Our input routine.
X*/
XSTATIC int
Xinput()
X{
X    int		c;
X
X    switch (c = getc(F)) {
X    case EOF:
X	return 0;
X    case '\n':
X	yylineno++;
X	break;
X    }
X    return c;
X}
X
X
X/*
X**  Our pushback routine.  If you have an input(), you gotta have an unput().
X*/
XSTATIC int
Xunput(c)
X    int		c;
X{
X    if (c == '\n')
X	yylineno--;
X    (void)ungetc(c, F);
X}
X
X
X/*
X**  Open file for LEX input.
X*/
Xint
Xyyopen(Checking, name)
X    BOOL	Checking;
X    char	*name;
X{
X    /* Open file.  The '-' is only when checking. */
X    if (Checking && EQ(name, "-"))
X	F = stdin;
X    else if ((F = fopen(name, "r")) == NULL)
X	return FALSE;
X
X    /* Reset our state. */
X    yylineno = 1;
X    HaveErrors = FALSE;
X
X    /* This is black magic to reset LEX, you might need it, might not.
X     * Why isn't there a yyreset()?
X    yysptr = yysbuf;
X     */
X
X    return TRUE;
X}
X
Xvoid
Xyyclose()
X{
X    if (F) {
X	(void)fclose(F);
X	F = NULL;
X    }
X}
END_OF_FILE
if test 4117 -ne `wc -c <'lex.l'`; then
    echo shar: \"'lex.l'\" unpacked with wrong size!
fi
# end of 'lex.l'
fi
if test -f 'libatt.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libatt.c'\"
else
echo shar: Extracting \"'libatt.c'\" \(3972 characters\)
sed "s/^X//" >'libatt.c' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Client library routines for an ATT3B2 with Wollongong TCP.
X**  Client library routines for an ATT6386 with Interlan V.3 TCP.
X*/
X#include "client.h"
X#ifdef	ATT3B2
X#include <sys/types.h>
X#include <sys/socket.h>
X#include <sys/in.h>
X#endif	/* ATT3B2 */
X#ifdef	ATTI386
X#include <sys/types.h>
X#include <sys/in.h>
X#include <sys/socket.h>
X#endif	/* ATTI386 */
X#include <netdb.h>
X#include <termio.h>
X#ifdef	RCSID
Xstatic char	 RCS[] =
X	"$Header: libatt.c,v 2.0 90/03/23 14:41:38 rsalz Exp $";
X#endif	/* RCSID */
X
X
XSTATIC int	 Channel;		/* Something to talk with	*/
X
X
X#ifdef	ATTI386
X/*
X**  Stupid Interlan software.  Why does their library need this routine,
X**  yet not provide it?
X*/
X#include "alloca.inc"
X#endif	/* ATTI386 */
X
X/*
X**  Do the grundge work of getting us a socket.
X*/
XSTATIC int
XGetSocket(machine, port)
X    char		 *machine;
X    int			  port;
X{
X    struct hostent	 *gethostbyname();
X    REGISTER int	  s;
X    struct hostent	 *hp;
X    struct sockaddr_in	  sin;
X
X    /* Get the address of the server. */
X    if ((hp = gethostbyname(machine)) == NULL) {
X	(void)fprintf(stderr, "%s: Unknown host.\n", machine);
X	return -1;
X    }
X
X    /* Set up the socket. */
X    (void)memset((char *)&sin, '\0', sizeof sin);
X    sin.sin_family = AF_INET;
X    sin.sin_port = htons(port);
X
X    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
X	perror("socket");
X	return -1;
X    }
X
X    (void)memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
X    if (connect(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
X	perror("connect");
X	(void)close(s);
X	return -1;
X    }
X
X    return s;
X}
X
X
X/*
X**  Open connection to server, return FALSE on error.
X*/
Xint
XSRVopen(machine, port)
X    char	*machine;
X    int		 port;
X{
X#ifdef	ATT3B2
X#ifdef	lint
X    /* Stupid SCCS strings in TWG library... */
X    S_netdb = S_netdb;
X    S_socket = S_socket;
X    S_in = S_in;
X#endif	/* lint */
X#endif	/* ATT3B2 */
X    return (Channel = GetSocket(machine, port)) >= 0;
X}
X
X
X/*
X**  Send a QUIT and shut down.
X*/
Xvoid
XSRVclose()
X{
X    SRVput("QUIT");
X    (void)close(Channel);
X}
X
X
X/*
X**  Send a line to the server.
X*/
Xvoid
XSRVput(p)
X    char	*p;
X{
X    if (SRVtrace)
X	(void)printf(">>>%s\n", p);
X    (void)write(Channel, p, (unsigned int)strlen(p));
X    (void)write(Channel, "\r\n", 2);
X}
X
X
X/*
X**  Get a line of text from the server.  Strip end-of-line characters.
X*/
Xint
XSRVget(buff, size)
X    char		*buff;
X    int			 size;
X{
X    REGISTER char	*p;
X    REGISTER char	*bend;
X    REGISTER int	 c;
X
X    for (bend = &buff[size - 1]; ; ) {
X	for (p = buff; ((c = SRVcget()) != '\n'); ) {
X	    if (c == EOF)
X		return FALSE;
X	    if (c != '\r' && p < bend)
X		*p++ = c;
X	}
X	*p = '\0';
X	if (SRVtrace)
X	    (void)printf("<<<%s\n", buff);
X	if (strncmp(buff, "INF ", 4))
X	    return TRUE;
X	(void)printf("Server message:\n\t%s\n", &buff[4]);
X	(void)fflush(stdout);
X    }
X}
X
X
X/*
X**  Get a character from the server.
X*/
Xint
XSRVcget()
X{
X    static char	 buff[1024];
X    static int	 count;
X    static int	 max;
X
X    if (count == max) {
X	while ((max = read(Channel, buff, sizeof buff)) == 0)
X	    ;
X	if (max < 0)
X	    return EOF;
X	if (max > sizeof buff)
X	    (void)abort();
X	count = 0;
X    }
X    return buff[count++];
X}
X
X
X/*
X**  Get a password, without echoing it.
X*/
Xvoid
XGetPassword(buff, size)
X    char		*buff;
X    int			 size;
X{
X    struct termio	 Modes;
X    char		*p;
X    int			 ok;
X    int			 flags;
X
X    if (ok = ioctl(fileno(stdin), TCGETA, &Modes) >= 0) {
X	flags = Modes.c_lflag;
X	Modes.c_lflag &= ~(ECHO | ECHOE | ECHONL);
X	(void)ioctl(fileno(stdin), TCSETA, &Modes);
X    }
X
X    if (fgets(buff, size, stdin) == NULL)
X	Fatal("No password!?");
X    if (p = strchr(buff, '\n'))
X	*p = '\0';
X
X    if (ok) {
X	Modes.c_lflag = flags;
X	(void)ioctl(fileno(stdin), TCSETA, &Modes);
X	(void)printf("\n");
X    }
X}
END_OF_FILE
if test 3972 -ne `wc -c <'libatt.c'`; then
    echo shar: \"'libatt.c'\" unpacked with wrong size!
fi
# end of 'libatt.c'
fi
if test -f 'libbsd.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libbsd.c'\"
else
echo shar: Extracting \"'libbsd.c'\" \(4312 characters\)
sed "s/^X//" >'libbsd.c' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Client library routines for BSD-derived systems.
X*/
X#include "client.h"
X#include <sys/types.h>
X#include <sgtty.h>
X#include <netdb.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#ifdef	RCSID
Xstatic char	 RCS[] =
X	"$Header: libbsd.c,v 2.0 90/03/23 14:41:41 rsalz Exp $";
X#endif	/* RCSID */
X
X
XSTATIC FILE	*WriteStream;		/* Something to write to	*/
XSTATIC FILE	*ReadStream;		/* Something to read from	*/
X
X
X/*
X**  Do the grundge work of getting us a socket.  Thanks to the NNTP folks
X**  for the trick of using h_addr to see if we're running with a 4.3
X**  multiple address netdb, or a 4.2 single address netdb.
X*/
XSTATIC int
XGetSocket(machine, port)
X    char		 *machine;
X    int			  port;
X{
X    struct hostent	 *gethostbyname();
X#ifdef	h_addr
X    REGISTER char	**addr;
X#endif	/* h_addr */
X    REGISTER int	  s;
X    struct hostent	 *hp;
X    struct sockaddr_in	  sin;
X
X    /* Get the address of the server. */
X    if ((hp = gethostbyname(machine)) == NULL) {
X	(void)fprintf(stderr, "%s: Unknown host.\n", machine);
X	return -1;
X    }
X
X    /* Set up the socket. */
X    bzero((char *)&sin, sizeof sin);
X    sin.sin_family = AF_INET;
X    sin.sin_port = htons((unsigned short)port);
X
X#ifdef	h_addr
X    /* get a socket and initiate connection -- use multiple addresses */
X    for (addr = hp->h_addr_list; addr && *addr; addr++) {
X	if ((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
X	    perror("socket");
X	    return -1;
X	}
X	    
X	bcopy(*addr, (char *)&sin.sin_addr, hp->h_length);
X	if (connect(s, (struct sockaddr *)&sin, sizeof sin) == 0)
X	    break;
X	(void)close(s);
X    }
X    if (addr == NULL || *addr == '\0') {
X	perror("no connection possible");
X	return -1;
X    }
X#else
X    if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
X	perror("socket");
X	return -1;
X    }
X
X    bcopy(hp->h_addr, (char *)&sin.sin_addr, hp->h_length);
X    if (connect(s, (struct sockaddr *)&sin, sizeof sin) < 0) {
X	perror("connect");
X	(void)close(s);
X	return -1;
X    }
X#endif	/* h_addr */
X
X    return s;
X}
X
X
X/*
X**  Open connection to server, return FALSE on error.
X*/
Xint
XSRVopen(machine, port)
X    char	*machine;
X    int		 port;
X{
X    int		 i;
X
X    if ((i = GetSocket(machine, port)) < 0)
X	return FALSE;
X
X    if ((ReadStream = fdopen(i, "r")) == NULL) {
X	perror("OpenServerChannel: fdopen #1");
X	return FALSE;
X    }
X
X    if ((i = dup(i)) < 0) {
X	perror("OpenServerChannel: dup");
X	return FALSE;
X    }
X    if ((WriteStream = fdopen(i, "w")) == NULL) {
X	perror("OpenServerChannel: fdopen #2");
X	(void)fclose(ReadStream);
X	return FALSE;
X    }
X    return TRUE;
X}
X
X
X/*
X**  Send a QUIT and shut down.
X*/
Xvoid
XSRVclose()
X{
X    if (WriteStream == NULL || ReadStream == NULL)
X	return;
X
X    SRVput("QUIT");
X    (void)fclose(WriteStream);
X    (void)fclose(ReadStream);
X}
X
X
X/*
X**  Send a line to the server.
X*/
Xvoid
XSRVput(p)
X    char	*p;
X{
X    if (SRVtrace)
X	(void)printf(">>>%s\n", p);
X    (void)fprintf(WriteStream, "%s\r\n", p);
X    (void)fflush(WriteStream);
X}
X
X
X/*
X**  Get a line of text from the server.  Strip end-of-line characters.
X*/
Xint
XSRVget(buff, size)
X    char		*buff;
X    int			 size;
X{
X    REGISTER char	*p;
X
X    while (fgets(buff, size, ReadStream)) {
X	if ((p = strchr(buff, '\r')) || (p = strchr(buff, '\n')))
X	    *p = '\0';
X	if (SRVtrace)
X	    (void)printf("<<<%s\n", buff);
X	if (strncmp(buff, "INF ", 4))
X	    return TRUE;
X	(void)printf("Server message:\n\t%s\n", &buff[4]);
X	(void)fflush(stdout);
X    }
X    return FALSE;
X}
X
X
X/*
X**  Get a character from the server.
X*/
Xint
XSRVcget()
X{
X    return getc(ReadStream);
X}
X
X
X/*
X**  Get a password, without echoing it.
X*/
Xvoid
XGetPassword(buff, size)
X    char		*buff;
X    int			 size;
X{
X    struct sgttyb	 Modes;
X    char		*p;
X    int			 ok;
X    int			 flags;
X
X    if (ok = ioctl(fileno(stdin), TIOCGETP, &Modes) >= 0) {
X	flags = Modes.sg_flags;
X	Modes.sg_flags &= ~ECHO;
X	(void)ioctl(fileno(stdin), TIOCSETP, &Modes);
X    }
X
X    if (fgets(buff, size, stdin) == NULL)
X	Fatal("No password!?");
X    if (p = strchr(buff, '\n'))
X	*p = '\0';
X
X    if (ok) {
X	Modes.sg_flags = flags;
X	(void)ioctl(fileno(stdin), TIOCSETP, &Modes);
X	(void)printf("\n");
X    }
X}
END_OF_FILE
if test 4312 -ne `wc -c <'libbsd.c'`; then
    echo shar: \"'libbsd.c'\" unpacked with wrong size!
fi
# end of 'libbsd.c'
fi
if test -f 'libxen.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'libxen.c'\"
else
echo shar: Extracting \"'libxen.c'\" \(4034 characters\)
sed "s/^X//" >'libxen.c' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Client library routines for XENIX with Excelan TCP.
X*/
X#include "client.h"
X#include <sys/types.h>
X#include <sgtty.h>
X#include <netdb.h>
X#include <sys/socket.h>
X#include <netinet/in.h>
X#ifdef	RCSID
Xstatic char	 RCS[] =
X	"$Header: libxen.c,v 2.0 90/03/23 14:41:47 rsalz Exp $";
X#endif	/* RCSID */
X
X
XSTATIC FILE	*WriteStream;		/* Something to write to	*/
XSTATIC FILE	*ReadStream;		/* Something to read from	*/
X
X
X/*
X**  Make a directory.
X*/
Xint
Xmkdir(dir, mode)
X    char	*dir;
X    int		 mode;
X{
X    char	buff[SIZE];
X
X    (void)sprintf(buff, "exec mkdir %s\n", dir);
X    if (system(buff))
X	return -1;
X    (void)sprintf(buff, "exec chmod %d %s", mode, dir);
X    return system(buff) ? -1 : 0;
X}
X
X
X/*
X**  Rename a file.
X*/
Xint
Xrename(from, to)
X    char	*from;
X    char	*to;
X{
X    (void)unlink(to);
X    return link(from, to) < 0 ? -1 : unlink(from);
X}
X
X
X/*
X**  Do the grundge work of getting us a socket.
X*/
XSTATIC int
XGetSocket(machine, port)
X    char		 *machine;
X    int			  port;
X{
X    REGISTER int	  s;
X    struct hostent	 *hp;
X    struct sockaddr_in	  sin;
X
X    /* Set up the socket. */
X    (void)memset((char *)&sin, '\0', sizeof sin);
X    sin.sin_family = AF_INET;
X    sin.sin_port = htons(port);
X    if ((s = socket(SOCK_STREAM, (struct sockproto *)NULL, &sin, 0)) < 0) {
X	experror("socket");
X	return -1;
X    }
X
X    /* Get the address of the server. */
X    if ((hp = gethostbyname(machine)) == NULL) {
X	(void)fprintf(stderr, "%s: Unknown host.\n", machine);
X	return -1;
X    }
X    (void)memcpy((char *)&sin.sin_addr, hp->h_addr, hp->h_length);
X
X    /* Connect to the server. */
X    if (connect(s, (struct sockaddr *)&sin) < 0) {
X	experror("connect");
X	(void)close(s);
X	return -1;
X    }
X
X    return s;
X}
X
X
X/*
X**  Open connection to server, return FALSE on error.
X*/
Xint
XSRVopen(machine, port)
X    char	*machine;
X    int		 port;
X{
X    int		 i;
X
X    if ((i = GetSocket(machine, port)) < 0)
X	return FALSE;
X
X    if ((ReadStream = fdopen(i, "r")) == NULL) {
X	perror("OpenServerChannel: fdopen #1");
X	return FALSE;
X    }
X
X    if ((i = dup(i)) < 0) {
X	perror("OpenServerChannel: dup");
X	return FALSE;
X    }
X    if ((WriteStream = fdopen(i, "w")) == NULL) {
X	perror("OpenServerChannel: fdopen #2");
X	(void)fclose(ReadStream);
X	return FALSE;
X    }
X    return TRUE;
X}
X
X
X/*
X**  Send a QUIT and shut down.
X*/
Xvoid
XSRVclose()
X{
X    if (WriteStream == NULL || ReadStream == NULL)
X	return;
X
X    SRVput("QUIT");
X    (void)fclose(WriteStream);
X    (void)fclose(ReadStream);
X}
X
X
X/*
X**  Send a line to the server.
X*/
Xvoid
XSRVput(p)
X    char	*p;
X{
X    if (SRVtrace)
X	(void)printf(">>>%s\n", p);
X    (void)fprintf(WriteStream, "%s\r\n", p);
X    (void)fflush(WriteStream);
X}
X
X
X/*
X**  Get a line of text from the server.  Strip end-of-line characters.
X*/
Xint
XSRVget(buff, size)
X    char		*buff;
X    int			 size;
X{
X    REGISTER char	*p;
X
X    while (fgets(buff, size, ReadStream)) {
X	if ((p = strchr(buff, '\r')) || (p = strchr(buff, '\n')))
X	    *p = '\0';
X	if (SRVtrace)
X	    (void)printf("<<<%s\n", buff);
X	if (strncmp(buff, "INF ", 4))
X	    return TRUE;
X	(void)printf("Server message:\n\t%s\n", &buff[4]);
X	(void)fflush(stdout);
X    }
X    return FALSE;
X}
X
X
X/*
X**  Get a character from the server.
X*/
Xint
XSRVcget()
X{
X    return getc(ReadStream);
X}
X
X
X/*
X**  Get a password, without echoing it.
X*/
Xvoid
XGetPassword(buff, size)
X    char		*buff;
X    int			 size;
X{
X    struct sgttyb	 Modes;
X    char		*p;
X    int			 ok;
X    int			 flags;
X
X    if (ok = ioctl(fileno(stdin), TIOCGETP, &Modes) >= 0) {
X	flags = Modes.sg_flags;
X	Modes.sg_flags &= ~ECHO;
X	(void)ioctl(fileno(stdin), TIOCSETP, &Modes);
X    }
X
X    if (fgets(buff, size, stdin) == NULL)
X	Fatal("No password!?");
X    if (p = strchr(buff, '\n'))
X	*p = '\0';
X
X    if (ok) {
X	Modes.sg_flags = flags;
X	(void)ioctl(fileno(stdin), TIOCSETP, &Modes);
X	(void)printf("\n");
X    }
X}
END_OF_FILE
if test 4034 -ne `wc -c <'libxen.c'`; then
    echo shar: \"'libxen.c'\" unpacked with wrong size!
fi
# end of 'libxen.c'
fi
if test -f 'log.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'log.c'\"
else
echo shar: Extracting \"'log.c'\" \(2123 characters\)
sed "s/^X//" >'log.c' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Logging routines for CODA server.
X*/
X#include "server.h"
X#include <time.h>
X#ifdef	RCSID
Xstatic char RCS[] =
X	"$Header: log.c,v 2.0 90/03/23 14:41:50 rsalz Exp $";
X#endif	/* RCSID */
X
X
XSTATIC int	 PID;			/* Our process ID		*/
XSTATIC int	 Sequence;		/* Log message sequence number	*/
XSTATIC char	*LogTerm = "\n";	/* Message terminator		*/
XSTATIC FILE	*Log;			/* Logfile stream		*/
X
X
XSTATIC char *
XTimeString()
X{
X    time_t	 now;
X    char	*p;
X
X    (void)time(&now);
X    p = ctime(&now);
X    /* Kill the newline, skip the day. */
X    p[24] = '\0';
X    return p + 4;
X}
X
X
Xvoid
XLogOpen()
X{
X    PID = getpid();
X    Sequence = 0;
X
X    /* Open a log file somewhere. */
X    if (EQ(LogFile, "-"))
X	Log = stdout;
X    else if ((Log = fopen(LogFile, "a")) == NULL) {
X	if (Log = fopen("/dev/console", "w"))
X	    LogTerm = "\r\n";
X	else if ((Log = fopen("/dev/null", "w")) == NULL) {
X	    perror("Can't open any logfiles");
X	    abort();
X	}
X    }
X
X    (void)fprintf(Log, "%d %d %s StartedWith %s%s",
X		    PID, Sequence++, TimeString(),
X		    TheHost,
X		    LogTerm);
X    (void)fflush(Log);
X}
X
X
Xvoid
XLogClose(p)
X    char	*p;
X{
X    (void)fprintf(Log, "%d %d %s Exit %s%s",
X		    PID, Sequence++, TimeString(),
X		    p,
X		    LogTerm);
X    (void)fflush(Log);
X}
X
X
Xvoid
XLogText(p)
X    char	*p;
X{
X    (void)fprintf(Log, "%d %d %s Message %s%s",
X		    PID, Sequence++, TimeString(),
X		    p,
X		    LogTerm);
X    (void)fflush(Log);
X}
X
X
Xvoid
XLogReadfile(p)
X    char	*p;
X{
X    char	 buff[SIZE * 2];
X
X    (void)fprintf(Log, "%d %d %s Readfile %s %s%s",
X		    PID, Sequence++, TimeString(),
X		    p, getwd(buff),
X		    LogTerm);
X    (void)fflush(Log);
X}
X
X
X#ifdef	VERBOSE_LOG
Xvoid
XLogSentItem(I)
X    ITEM	*I;
X{
X    (void)fprintf(Log, "%d %d %s Sentitem %s%s%s",
X		    PID, Sequence++, TimeString(),
X		    I->Name[0] == '/' ? "" : TheRoot,
X		    I->Name,
X		    LogTerm);
X    (void)fflush(Log);
X}
X#endif	/* VERBOSE_LOG */
END_OF_FILE
if test 2123 -ne `wc -c <'log.c'`; then
    echo shar: \"'log.c'\" unpacked with wrong size!
fi
# end of 'log.c'
fi
if test -f 'patchlevel.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'patchlevel.h'\"
else
echo shar: Extracting \"'patchlevel.h'\" \(381 characters\)
sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  It is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Misteak recorder.
X**  $Log:	patchlevel.h,v $
X**  Revision 2.0  90/03/23  14:41:53  rsalz
X**  Baseline for Usenet release.
X**  
X*/
X#define PATCHLEVEL	0
END_OF_FILE
if test 381 -ne `wc -c <'patchlevel.h'`; then
    echo shar: \"'patchlevel.h'\" unpacked with wrong size!
fi
# end of 'patchlevel.h'
fi
if test -f 'version.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'version.c'\"
else
echo shar: Extracting \"'version.c'\" \(1296 characters\)
sed "s/^X//" >'version.c' <<'END_OF_FILE'
X/*
X**  Copyright 1989 BBN Systems and Technologies Corporation.
X**  All Rights Reserved.
X**  This is free software, and may be distributed under the terms of the
X**  GNU Public License; see the file COPYING for more details.
X**
X**  Print copyright and version.
X*/
X#include <stdio.h>
X#include "patchlevel.h"
X
X#define LINE1	\
X    "Copyright 1989 BBN Systems and Technologies Corporation."
X#define LINE2	\
X    "All Rights Reserved."
X#define LINE3	\
X    "This is free software, and may be distributed under the terms of the"
X#define LINE4	\
X    "GNU Public License; see the file COPYING for more details."
X
X/*
X**  Sigh, I wish I didn't have to do this stuff -- both the copyright,
X**  and having to crack the RCS string are a pain in the neck.
X*/
XCopyright()
X{
X    static char	REVISION[] = "$Revision: 2.0 $";
X    char	buff[sizeof REVISION + 2];
X    char	*p;
X    char	*q;
X
X    /* Skip to the first space. */
X    for (p = REVISION; *p && *p != ' '; p++)
X	;
X
X    /* If we found it, take everything up to the next space. */
X    if (*p) {
X	for (q = buff, p++; *p && *p != ' '; )
X	    *q++ = *p++;
X	*q = '\0';
X    }
X    else {
X	buff[0] = '?';
X	buff[1] = '\0';
X    }
X
X    (void)printf("This is CODA, Version %s.%d.\n", buff, PATCHLEVEL);
X    (void)printf("%s\n%s\n%s\n%s\n", LINE1, LINE2, LINE3, LINE4);
X}
END_OF_FILE
if test 1296 -ne `wc -c <'version.c'`; then
    echo shar: \"'version.c'\" unpacked with wrong size!
fi
# end of 'version.c'
fi
if test -f 'vmsutime.inc' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'vmsutime.inc'\"
else
echo shar: Extracting \"'vmsutime.inc'\" \(2280 characters\)
sed "s/^X//" >'vmsutime.inc' <<'END_OF_FILE'
X/*
X**  This file is in the public domain.
X**
X**  This is a hacked-over and reformatted version of the public domain
X**  utime routine written by Larry Jones <scjones@sdrc.uu.net> for which
X**  I am very grateful.
X*/
X/*#include <iodef.h>*/
X#include <unixio.h>
X#include <descrip.h>
X#include <fibdef.h>
X#include <atrdef.h>
X#include <stsdef.h>
X
X/*
X**  Change the modification time (VMS doesn't keep access time); to
X**  change the creation time, use ATR$C_CREDATE in the Attributes
X**  definition, below.
X*/
Xint
Xutime(file, time)
X    char				*file;
X    time_t				time[2];
X{
X    static struct fibdef		Fib;
X    static unsigned long		TheTime[2];
X    static const long			TicksPerSeck = 10000000;
X    static const long			Zero = 0;
X    static const unsigned long		Epoch[2] = {
X	0x4beb4000, 0x007c9567
X    };
X    static struct dsc$descriptor	D = {
X	0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL
X    };
X    static const struct dsc$descriptor	F = {
X	sizeof Fib, DSC$K_DTYPE_T, DSC$K_CLASS_S, (char *)&Fib
X    };
X    static const struct atrdef		Attributes[] = {
X	{ sizeof TheTime, ATR$C_REVDATE, (unsigned long)TheTime },
X	{ 0, 0, 0 }
X    };
X    struct stat				Sbuf;
X    unsigned short			Channel;
X    unsigned short			IOBlock[4];
X    unsigned long			status;
X
X    /* Get the current statistics on the file. */
X    if (stat(file, &Sbuf) < 0)
X	return -1;
X
X    /* Convert to clock ticks, and add in base ignoring overflow. */
X    LIB$EMUL(&time[1], &TicksPerSeck, &Zero, TheTime);
X    LIB$ADDX(Epoch, TheTime, TheTime);
X
X    /* Build up a channel pointing to that file. */
X    D.dsc$w_length = strlen(Sbuf.st_dev);
X    D.dsc$a_pointer = Sbuf.st_dev;
X    status = SYS$ASSIGN(&D, &Channel, 0, 0);
X    if ((status & STS$M_SUCCESS) == 0)
X	return -1;
X    Fib.fib$r_fid_overlay.fib$w_fid[0] = Sbuf.st_ino[0];
X    Fib.fib$r_fid_overlay.fib$w_fid[1] = Sbuf.st_ino[1];
X    Fib.fib$r_fid_overlay.fib$w_fid[2] = Sbuf.st_ino[2];
X
X    /* Modify the attributes to have the new timestamp. */
X    status = SYS$QIOW(0, Channel, IO$_MODIFY, IOBlock, 0, 0,
X		&F, 0, 0, 0, Attributes, 0);
X    if ((status & STS$M_SUCCESS) == 0)
X	return -1;
X    if ((IOBlock[0] & STS$M_SUCCESS) == 0)
X	return -1;
X
X    /* Close the channel. */
X    status = SYS$DASSGN(Channel);
X    if ((status & STS$M_SUCCESS) == 0)
X	return -1;
X    return 0;
X}
END_OF_FILE
if test 2280 -ne `wc -c <'vmsutime.inc'`; then
    echo shar: \"'vmsutime.inc'\" unpacked with wrong size!
fi
# end of 'vmsutime.inc'
fi
echo shar: End of archive 1 \(of 3\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 3 archives.
    rm -f ark[1-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0
exit 0 # Just in case...
-- 
Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
Use a domain-based address or give alternate paths, or you may lose out.