Path: utzoo!attcan!uunet!wuarchive!zaphod.mps.ohio-state.edu!samsung!umich!vela!schemers From: schemers@vela.acs.oakland.edu (Roland Schemers III) Newsgroups: comp.lang.c++ Subject: Transport Part01/03 Message-ID: <3521@vela.acs.oakland.edu> Date: 25 Oct 90 19:51:34 GMT References: <3520@vela.acs.oakland.edu> Reply-To: schemers@vela.acs.oakland.edu (Roland Schemers III) Organization: Oakland University, Rochester MI Lines: 944 #! /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 'Transport/src/InetDatagram.C' <<'END_OF_FILE' X#include X#include X#include X#include X#include X#include X#include X X#include "Transport.h" X#include "Util.h" X X Xint InetDatagram::socket() X{ X InetAddress temp(InetAddress::Any,0); X X if (inuse()) close(); X if (Socket::socket() && bind(temp)) { X status=0; X sex=Unknown; X return 1; X } X X if (!return_on_error) X Util::crash_and_burn("InetDatagram","open",sys_errlist[status]); X return 0; X} X Xint InetDatagram::socket_client() X{ X int stat=InetDatagram::socket(); X sex=Client; X return stat; X} X Xint InetDatagram::socket_server(const InetAddress &is) X{ X if (inuse()) close(); X if (Socket::socket() && bind(is)) { X status=0; X sex=Server; X return 1; X } X if (!return_on_error) X Util::crash_and_burn("InetDatagram","open",sys_errlist[status]); X return 0; X X} X X END_OF_FILE if test 824 -ne `wc -c <'Transport/src/InetDatagram.C'`; then echo shar: \"'Transport/src/InetDatagram.C'\" unpacked with wrong size! fi # end of 'Transport/src/InetDatagram.C' fi if test -f 'Transport/src/InetStream.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/src/InetStream.C'\" else echo shar: Extracting \"'Transport/src/InetStream.C'\" \(863 characters\) sed "s/^X//" >'Transport/src/InetStream.C' <<'END_OF_FILE' X#include X#include X#include X#include X#include X#include X#include X X#include "Transport.h" X#include "Util.h" X Xint InetStream::socket_client(const InetAddress &ia) X{ X if (!ia.ok()) { X status=errno; X if (return_on_error) return 0; X Util::crash_and_burn("InetStream","open","host not found"); X } X if (inuse()) close(); X if (socket() && connect(ia)) { X status=0; X sex=Client; X return 1; X } X X if (!return_on_error) X Util::crash_and_burn("InetStream","socket_client",sys_errlist[status]); X return 0; X} X Xint InetStream::socket_server(const InetAddress &is) X{ X if (inuse()) close(); X if (socket() && bind(is) && listen(SOMAXCONN)) { X status=0; X sex=Server; X return 1; X } X X if (!return_on_error) X Util::crash_and_burn("InetStream","socket_server",sys_errlist[status]); X return 0; X X} X X X END_OF_FILE if test 863 -ne `wc -c <'Transport/src/InetStream.C'`; then echo shar: \"'Transport/src/InetStream.C'\" unpacked with wrong size! fi # end of 'Transport/src/InetStream.C' fi if test -f 'Transport/src/UnixAddress.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/src/UnixAddress.C'\" else echo shar: Extracting \"'Transport/src/UnixAddress.C'\" \(1213 characters\) sed "s/^X//" >'Transport/src/UnixAddress.C' <<'END_OF_FILE' X X#include X#include X#include X#include X#include X#include X#include X X#include "Transport.h" X Xextern "C" { X unsigned long htonl(unsigned long); X unsigned short htons(unsigned short); X unsigned short ntohs(unsigned short); X struct hostent *gethostbyname(const char *host); X} X Xchar *UnixAddress::Temp=""; X Xostream &operator<<(ostream &os, const UnixAddress &ia) X{ X os << "(" << ia.pathname() << ")"; X return os; X} X XUnixAddress::UnixAddress() X{ X// stat=NoPathGiven; X addrlen=sizeof(address); X bzero((char *) &address, sizeof(address)); X address.sun_family = Socket::AfUnix; X strcpy(address.sun_path,""); X addrlen = sizeof(address.sun_family); X} X XUnixAddress::UnixAddress(const char *pathname) X{ Xset(pathname); X} X Xvoid UnixAddress::set(const char *pathname) X{ X bzero((char *) &address, sizeof(address)); X address.sun_family = Socket::AfUnix; X if (pathname==Temp) { X strcpy(address.sun_path,tmpnam(NULL)); X } else strcpy(address.sun_path,pathname); X X addrlen = strlen(pathname) + sizeof(address.sun_family); X X} X Xconst char *UnixAddress::pathname() const X{ X address.sun_path[addrlen-sizeof(address.sun_family)] = 0; X return address.sun_path; X} X END_OF_FILE if test 1213 -ne `wc -c <'Transport/src/UnixAddress.C'`; then echo shar: \"'Transport/src/UnixAddress.C'\" unpacked with wrong size! fi # end of 'Transport/src/UnixAddress.C' fi if test -f 'Transport/src/UnixAddress.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/src/UnixAddress.h'\" else echo shar: Extracting \"'Transport/src/UnixAddress.h'\" \(741 characters\) sed "s/^X//" >'Transport/src/UnixAddress.h' <<'END_OF_FILE' X#ifndef UNIXADDRESS_CLASS_H X#define UNIXADDRESS_CLASS_H X X#include X#include X#include X#include X#include X Xclass UnixAddress { X friend ostream &operator<<(ostream &os, const UnixAddress &ia); Xpublic: X static char *Temp; // any address X UnixAddress(); X UnixAddress(const char *pathname); X set(const char *pathname); X const char *pathname() const; X int size() const { return sizeof(address); } X typedef struct sockaddr *SOCKADDR_PTR; X typedef const struct sockaddr *CONST_SOCKADDR_PTR; X operator SOCKADDR_PTR() { return (SOCKADDR_PTR) &address; } X operator CONST_SOCKADDR_PTR() const { return (SOCKADDR_PTR) &address; } X X struct sockaddr_un address; X int addrlen; X}; X#endif END_OF_FILE if test 741 -ne `wc -c <'Transport/src/UnixAddress.h'`; then echo shar: \"'Transport/src/UnixAddress.h'\" unpacked with wrong size! fi # end of 'Transport/src/UnixAddress.h' fi if test -f 'Transport/src/Util.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/src/Util.h'\" else echo shar: Extracting \"'Transport/src/Util.h'\" \(176 characters\) sed "s/^X//" >'Transport/src/Util.h' <<'END_OF_FILE' X#ifndef UTIL_H X#define UTIL_H X Xclass Util { X public: X static void crash_and_burn(char *module,char *func, char *mess); X static void daemon_start(int ignore_sigcld); X}; X X#endif END_OF_FILE if test 176 -ne `wc -c <'Transport/src/Util.h'`; then echo shar: \"'Transport/src/Util.h'\" unpacked with wrong size! fi # end of 'Transport/src/Util.h' fi if test -f 'Transport/src/makefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/src/makefile'\" else echo shar: Extracting \"'Transport/src/makefile'\" \(713 characters\) sed "s/^X//" >'Transport/src/makefile' <<'END_OF_FILE' X# X# X# Makefile X# X XCC=CC XYFLAGS = -d X X.SUFFIXES: .o .c .y .l .s .C X# XPROG=qtest X# X# C++ rules X# X.C.o: X $(CC) $(CFLAGS) -c $*.C X X.C.a: X $(CC) -c $(CFLAGS) $< X ar rv $@ $*.o X rm -f $*.o X X X# Uncomment below if you want DECnet support X# X# CFLAGS= -DUSE_DECNET X# XCFLAGS= X# X XRJSDIR=../../RJS XRLIB = $(RJSDIR)/$(MACHINE)/libRJS.a X X.PRECIOUS: $(RLIB) X X$(RLIB) : $(RLIB)(Transport.o) \ X $(RLIB)(Socket.o) \ X $(RLIB)(Util.o) \ X $(RLIB)(UnixSocket.o) \ X $(RLIB)(UnixAddress.o) \ X $(RLIB)(DECnetSocket.o) \ X $(RLIB)(InetSocket.o) \ X $(RLIB)(InetStream.o) \ X $(RLIB)(InetDatagram.o) \ X $(RLIB)(InetAddress.o) \ X $(RJSDIR)/Transport.h X ranlib $(RLIB) X X$(RJSDIR)/Transport.h: Transport.h X cp Transport.h $(RJSDIR) END_OF_FILE if test 713 -ne `wc -c <'Transport/src/makefile'`; then echo shar: \"'Transport/src/makefile'\" unpacked with wrong size! fi # end of 'Transport/src/makefile' fi if test -f 'Transport/src/makefile.dist' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/src/makefile.dist'\" else echo shar: Extracting \"'Transport/src/makefile.dist'\" \(595 characters\) sed "s/^X//" >'Transport/src/makefile.dist' <<'END_OF_FILE' X# X# X# Makefile X# X XCC=CC XYFLAGS = -d X X.SUFFIXES: .o .c .y .l .s .C X# XPROG=qtest X# X# C++ rules X# X.C.o: X $(CC) $(CFLAGS) -c $*.C X X.C.a: X $(CC) -c $(CFLAGS) $< X ar rv $@ $*.o X rm -f $*.o X X X# Uncomment below if you want DECnet support X# X# CFLAGS= -DUSE_DECNET X# XCFLAGS= X# X XRLIB = libTransport.a X X.PRECIOUS: $(RLIB) X X$(RLIB) : $(RLIB)(Transport.o) \ X $(RLIB)(Socket.o) \ X $(RLIB)(Util.o) \ X $(RLIB)(UnixSocket.o) \ X $(RLIB)(UnixAddress.o) \ X $(RLIB)(DECnetSocket.o) \ X $(RLIB)(InetSocket.o) \ X $(RLIB)(InetStream.o) \ X $(RLIB)(InetDatagram.o) \ X $(RLIB)(InetAddress.o) X ranlib $(RLIB) X END_OF_FILE if test 595 -ne `wc -c <'Transport/src/makefile.dist'`; then echo shar: \"'Transport/src/makefile.dist'\" unpacked with wrong size! fi # end of 'Transport/src/makefile.dist' fi if test ! -d 'Transport/tests' ; then echo shar: Creating directory \"'Transport/tests'\" mkdir 'Transport/tests' fi if test -f 'Transport/tests/dclient.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/dclient.C'\" else echo shar: Extracting \"'Transport/tests/dclient.C'\" \(402 characters\) sed "s/^X//" >'Transport/tests/dclient.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X Xextern "C" { X void nerror(const char *s); X} X Xvoid test() X{ Xchar buffer[10]; X X DECnetSocket server("VELA",140); X X server.linger(); X server.read(buffer,6); // read from server X X cout << "client: read ==> '" << buffer << "'" << endl; X X} X Xint main(int argc, char *argv[]) X{ X test(); X exit(0); X} END_OF_FILE if test 402 -ne `wc -c <'Transport/tests/dclient.C'`; then echo shar: \"'Transport/tests/dclient.C'\" unpacked with wrong size! fi # end of 'Transport/tests/dclient.C' fi if test -f 'Transport/tests/dserver.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/dserver.C'\" else echo shar: Extracting \"'Transport/tests/dserver.C'\" \(369 characters\) sed "s/^X//" >'Transport/tests/dserver.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X Xvoid test() X{ X X DECnetSocket server(140),client; // create server X server.linger(); X server.accept(client); // accept a client X X client.linger(); X client.write("hello",6); // write to client X sleep(5); X} X X Xint main(int argc, char *argv[]) X{ X test(); X exit(0); X} END_OF_FILE if test 369 -ne `wc -c <'Transport/tests/dserver.C'`; then echo shar: \"'Transport/tests/dserver.C'\" unpacked with wrong size! fi # end of 'Transport/tests/dserver.C' fi if test -f 'Transport/tests/dserver_fork.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/dserver_fork.C'\" else echo shar: Extracting \"'Transport/tests/dserver_fork.C'\" \(396 characters\) sed "s/^X//" >'Transport/tests/dserver_fork.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X Xint main(int argc, char *argv[]) X{ XDECnetSocket server(140),client; X X X X server.accept(client); // accept a client X X if (fork()==0) { // child X server.close(); // don't need this anymore! X client.linger(); X client.write("hello",6); // write to client X } X X exit(0); X} END_OF_FILE if test 396 -ne `wc -c <'Transport/tests/dserver_fork.C'`; then echo shar: \"'Transport/tests/dserver_fork.C'\" unpacked with wrong size! fi # end of 'Transport/tests/dserver_fork.C' fi if test -f 'Transport/tests/iclient.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/iclient.C'\" else echo shar: Extracting \"'Transport/tests/iclient.C'\" \(558 characters\) sed "s/^X//" >'Transport/tests/iclient.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X Xchar buffer[10]; X X Xvoid Transport_Test(Transport &server) X{ X server.read(buffer,6); // read from server X cout << "Transport client: read ==> '" << buffer << "'" << endl; X server.write("goodbye",8); X} X X Xint main(int argc, char *argv[]) X{ X X X if (argc!=3) { X cerr << "usage: " << argv[0] << " server port" << endl; X exit(1); X } X X InetStream server; X server.socket_client(InetAddress(argv[1],atoi(argv[2]))); X Transport_Test(server); X X exit(0); X} X END_OF_FILE if test 558 -ne `wc -c <'Transport/tests/iclient.C'`; then echo shar: \"'Transport/tests/iclient.C'\" unpacked with wrong size! fi # end of 'Transport/tests/iclient.C' fi if test -f 'Transport/tests/iserver.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/iserver.C'\" else echo shar: Extracting \"'Transport/tests/iserver.C'\" \(714 characters\) sed "s/^X//" >'Transport/tests/iserver.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X Xint main(int argc, char *argv[]) X{ X char buffer[32]; X int nbr; X X if (argc!=2) { X cerr << "usage: " << argv[0] << " port" << endl; X exit(1); X } X X InetStream server,client; X InetAddress local(atoi(argv[1])),remote; X server.socket_server(local); X X// server.getsockname(local); X X cout << "Server: local ==> " << local << endl; X X while (server.accept(client)) { // accept a client X client.getpeername(remote); X cout << "Server: remote ==> " << remote << endl; X client.write("hello",6); // write to client X nbr=client.read(buffer,10); X cout << "Server: read '" <'Transport/tests/qtest.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X X Xint main(int argc, char *argv[]) X{ X X X UnixAddress server("/tmp/unix.dg"); X X cout << "pathname = " << server.pathname() << endl; X X UnixAddress server2(UnixAddress::Temp); X X cout << "pathname = " << server2.pathname() << endl; X X exit(0); X} X END_OF_FILE if test 349 -ne `wc -c <'Transport/tests/qtest.C'`; then echo shar: \"'Transport/tests/qtest.C'\" unpacked with wrong size! fi # end of 'Transport/tests/qtest.C' fi if test -f 'Transport/tests/rchargen.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/rchargen.C'\" else echo shar: Extracting \"'Transport/tests/rchargen.C'\" \(539 characters\) sed "s/^X//" >'Transport/tests/rchargen.C' <<'END_OF_FILE' X#include X#include "Transport.h" X#include X#include X Xint main(int argc, char *argv[]) X{ X if (argc!=2) { X cerr << "usage: " << argv[0] << " host" << endl; X exit(1); X } X X InetAddress daytime_address(argv[1],"chargen","udp"); X InetDatagram daytime_server; X X daytime_server.socket_client(); X daytime_server.send("time please",12); // send to server X X char buffer[512]; X int nbr=daytime_server.recv(buffer,512); // get reply X buffer[nbr]=0; X X cout << "rdaytime => " << buffer << endl; X exit(0); X} X END_OF_FILE if test 539 -ne `wc -c <'Transport/tests/rchargen.C'`; then echo shar: \"'Transport/tests/rchargen.C'\" unpacked with wrong size! fi # end of 'Transport/tests/rchargen.C' fi if test -f 'Transport/tests/rdaytime.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/rdaytime.C'\" else echo shar: Extracting \"'Transport/tests/rdaytime.C'\" \(554 characters\) sed "s/^X//" >'Transport/tests/rdaytime.C' <<'END_OF_FILE' X#include X#include "Transport.h" X#include X#include X Xint main(int argc, char *argv[]) X{ X if (argc!=2) { X cerr << "usage: " << argv[0] << " host" << endl; X exit(1); X } X X InetAddress daytime_address(argv[1],"daytime","udp"); X InetDatagram daytime_server; X X daytime_server.socket_client(); X daytime_server.sendto("time please",12,daytime_address); // send to server X X char buffer[512]; X int nbr=daytime_server.recv(buffer,512); // get reply X buffer[nbr]=0; X X cout << "rdaytime => " << buffer << endl; X exit(0); X} X END_OF_FILE if test 554 -ne `wc -c <'Transport/tests/rdaytime.C'`; then echo shar: \"'Transport/tests/rdaytime.C'\" unpacked with wrong size! fi # end of 'Transport/tests/rdaytime.C' fi if test -f 'Transport/tests/rstats.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/rstats.C'\" else echo shar: Extracting \"'Transport/tests/rstats.C'\" \(534 characters\) sed "s/^X//" >'Transport/tests/rstats.C' <<'END_OF_FILE' X#include X#include "Transport.h" X#include X#include X Xint main(int argc, char *argv[]) X{ X if (argc!=2) { X cerr << "usage: " << argv[0] << " host" << endl; X exit(1); X } X X InetAddress statsrv_address(argv[1],"statsrv","udp"); X InetDatagram stat_server; X X stat_server.socket_client(); X stat_server.sendto("loadav",7,statsrv_address); // send to server X X char buffer[512]; X int nbr=stat_server.recv(buffer,512); // get reply X buffer[nbr]=0; X X cout << "loadav => " << buffer << endl; X exit(0); X} X END_OF_FILE if test 534 -ne `wc -c <'Transport/tests/rstats.C'`; then echo shar: \"'Transport/tests/rstats.C'\" unpacked with wrong size! fi # end of 'Transport/tests/rstats.C' fi if test -f 'Transport/tests/sclient.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/sclient.C'\" else echo shar: Extracting \"'Transport/tests/sclient.C'\" \(895 characters\) sed "s/^X//" >'Transport/tests/sclient.C' <<'END_OF_FILE' X#include X#include X#include X#include X#include X X#include "Transport.h" X X Xint main(int argc, char *argv[]) X{ Xchar buffer[512]; X X if (argc!=3) { X cerr << "usage: " << argv[0] << " broadcast_port message" << endl; X exit(1); X } X X InetAddress to(InetAddress::Broadcast,atoi(argv[1])),from,local; X InetDatagram server; X X server.socket_client(); X server.setsockopt(Socket::Broadcast,Socket::On); X server.getsockname(local); X X cout << "client: local address is " << local << endl; X cout << "client: message to " << to << endl; X X int nbw=server.sendto(argv[2],strlen(argv[2])+1,to); // send to server X X cout << "client: sent " << nbw << " bytes"< '" << buffer << "'" << endl; X cout << "client: from ==> " << from << endl; X X X exit(0); X} X END_OF_FILE if test 895 -ne `wc -c <'Transport/tests/sclient.C'`; then echo shar: \"'Transport/tests/sclient.C'\" unpacked with wrong size! fi # end of 'Transport/tests/sclient.C' fi if test -f 'Transport/tests/sserver.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/sserver.C'\" else echo shar: Extracting \"'Transport/tests/sserver.C'\" \(659 characters\) sed "s/^X//" >'Transport/tests/sserver.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X X Xint main(int argc, char *argv[]) X{ X X if (argc!=2) { X cerr << "usage: " << argv[0] << " port" << endl; X exit(1); X } X X InetAddress port(atoi(argv[1])); X InetDatagram dg; X InetAddress from; X char buffer[10]; X X X dg.socket_server(port); X dg.getsockname(port); X cout << "server: port ==> " << port << endl; X dg.recvfrom(buffer,10,from); X X cout << "server: read ==> '" << buffer << "'" << endl; X cout << "server: from ==> " << from << endl; X int nbw=dg.sendto("bye",4,from); X cout << "server: sent ==> " << nbw << " bytes" << endl; X exit(0); X} X END_OF_FILE if test 659 -ne `wc -c <'Transport/tests/sserver.C'`; then echo shar: \"'Transport/tests/sserver.C'\" unpacked with wrong size! fi # end of 'Transport/tests/sserver.C' fi if test -f 'Transport/tests/uclient.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/uclient.C'\" else echo shar: Extracting \"'Transport/tests/uclient.C'\" \(386 characters\) sed "s/^X//" >'Transport/tests/uclient.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X Xvoid test () X{ X char buffer[10]; X UnixStream server; X X server.open("./sock",Socket::Client); // open connection to server X server.read(buffer,6); // read from server X cout << "Client read: " << buffer<< endl; X X} X Xint main(int argc, char *argv[]) X{ X test(); X exit(0); X} END_OF_FILE if test 386 -ne `wc -c <'Transport/tests/uclient.C'`; then echo shar: \"'Transport/tests/uclient.C'\" unpacked with wrong size! fi # end of 'Transport/tests/uclient.C' fi if test -f 'Transport/tests/userver.C' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Transport/tests/userver.C'\" else echo shar: Extracting \"'Transport/tests/userver.C'\" \(358 characters\) sed "s/^X//" >'Transport/tests/userver.C' <<'END_OF_FILE' X#include X#include X#include X#include X X#include "Transport.h" X Xvoid test() X{ XUnixStream server,client; X X server.open("./sock",Socket::Server); // create server X server.accept(client); // accept a client X client.write("hello",6); // write to client X X} X Xint main(int argc, char *argv[]) X{ X test(); X exit(0); X} END_OF_FILE if test 358 -ne `wc -c <'Transport/tests/userver.C'`; then echo shar: \"'Transport/tests/userver.C'\" unpacked with wrong size! fi # end of 'Transport/tests/userver.C' fi if test ! -d 'Transport/tests/vax' ; then echo shar: Creating directory \"'Transport/tests/vax'\" mkdir 'Transport/tests/vax' 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 -- Roland J. Schemers III Systems Programmer schemers@vela.acs.oakland.edu (Ultrix) Oakland University schemers@argo.acs.oakland.edu (VMS) Rochester, MI 48309-4401 "As long as the systems are up, I get to sleep in!" (313)-370-4323