home *** CD-ROM | disk | FTP | other *** search
- Path: uunet!munnari!sources-request
- From: sources-request@munnari.oz
- Newsgroups: comp.sources.unix
- Subject: v15i011: abcd - Automatic Backup Copy Daemon, Part01/01
- Message-ID: <2147@munnari.oz>
- Date: 26 May 88 19:15:48 GMT
- Sender: kre@munnari.oz
- Lines: 771
- Approved: kre@munnari.oz.au
-
- Submitted by: richb@sunaus.sun.oz (Rich Burridge)
- Posting-number: Volume 15, Issue 11
- Archive-name: abcd/Part01
-
- [ this compiles OK on SunOS 3.4, but not on a 4.3 vax,
- so it probably contains 4.2 dependancies. I don't
- suppose they would be hard to fix. I wouldn't bother
- on SysV I think. ... kre ]
-
-
- This is an automatic backup copy daemon, which copies files from one
- filestore area to another using either cp or rcp. Note the second filestore
- area could be on another machine if the file system is NFS mounted.
-
- This means that the backup machine should have an identical copy of the
- filestore being monitored, give or take a little bit.
-
- With improvements and suggestions from various people, this program
- could be very useful. I can see a lot of drawbacks and limitations to
- this first version, but I'd like feedback before I work on any modifications.
-
- Rich.
-
- ------CUT HERE------CUT HERE------
- #! /bin/sh
- # this is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh to create the files:
- # abcd.c
- # abcd.h
- # patchlevel.h
- # Makefile
- # README
- # abcd.1
- # This archive created: Wed May 25 11:56:25 EST 1988
- #
- #
- export PATH; PATH=/bin:$PATH
- #
- if [ -f abcd.c ]
- then
- echo shar: will not over-write existing file abcd.c
- else
- echo shar: extracting 'abcd.c', 12906 characters
- cat > abcd.c <<'Funky_Stuff'
-
- /* abcd.c
- *
- * This is an automatic backup copy daemon, which copies files from one
- * filestore area to another using either cp or rcp. Note the second filestore
- * area could be on another machine if the file system is NFS mounted.
- *
- * This means that the backup disk should have an identical copy of the
- * filestore being monitored, give or take a little bit.
- *
- * SWITCHES
- *
- * -fdirectory Directory to start copying from. Defaults to /usr.
- *
- * -tdirectory Directory to start copying to. Defaults to /usr2.
- *
- * -rhostname This is an alternative form of backup. Uses rcp and copies to
- * hostname supplied.
- *
- * -sseconds Specifies the sleep period in seconds for when the program puts
- * itself to sleep.
- *
- * -c If given, then abcd won't copy the first time through.
- *
- * Copyright (c) Rich Burridge - Sun Microsystems Australia (Melbourne).
- *
- * Version 1.1 - May 1988.
- *
- * No responsibility is taken for any error in accuracies inherent
- * either to the comments or the code of this program, but if
- * reported to me then an attempt will be made to fix them.
- */
-
- #include <stdio.h>
- #include <strings.h>
- #include <errno.h>
- #include <signal.h>
- #include <sys/file.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/dir.h>
- #include "patchlevel.h"
- #include "abcd.h"
-
- char *malloc(), *sprintf() ;
-
- struct finfo *cfile ; /* Information on current file. */
- struct finfo *files = NULL ; /* Files being monitored. */
- struct dinfo *cdir ; /* Pointer to current directory. */
- struct dinfo *dirs = NULL ; /* Directories being monitored. */
- struct stat cstat ; /* For statistics on current file. */
- struct direct *cur ; /* Pointer to current directory record. */
-
- extern int errno ; /* Standard error reply. */
-
- char cname[MAXLINE] ; /* Copy program to use. */
- char coff[MAXLINE] ; /* Name offset from initial start directory. */
- char curdir[MAXLINE] ; /* Current directory being monitored. */
- char dbuf[DIRBLKSIZ] ; /* Buffer for directory information. */
- char fdir[MAXLINE] ; /* Directory to start copying from. */
- char flist[MAXFILES][MAXLINE] ; /* Array of filenames to copy. */
- char fname[MAXLINE] ; /* Full pathname of current file. */
- char pdir[MAXLINE] ; /* Current directory for copy request. */
- char rhost[MAXLINE] ; /* Name of remote host for use by rcp. */
- char tdir[MAXLINE] ; /* Directory to start copying to. */
-
- int copy_found = 0 ; /* Whether copy done on this pass. */
- int delay = 300 ; /* Sleep time for abcd in seconds. */
- int docopy = 1 ; /* Rcp files right from the beginning. */
- int fd = 0 ; /* File id of the directory being monitored. */
- int loc = 0 ; /* Current location in the directory block. */
- int fcnt = 0 ; /* Number of files to copy in current request. */
- int no_dirs = 1 ; /* Number of directories being monitored. */
- int size ; /* Size of current directory block in bytes. */
- int usercp = 0 ; /* Backup method, cp or rcp. */
-
-
- get_options(argc,argv) /* Get abcd options from command line. */
- int argc ;
- char *argv[] ;
-
- {
- char *arg ;
- char *p ; /* Pointer to string following argument flag. */
-
- STRCPY(fdir,"/usr") ; /* Default directory to monitor. */
- STRCPY(tdir,"/usr2") ; /* Default directory to copy to. */
- STRCPY(rhost,"") ; /* Default is no remote host. */
-
- while (argc > 1 && (arg = argv[1])[0] == '-')
- {
- p = arg + 2 ;
- switch (arg[1])
- {
- case 'c' : docopy = 0 ; /* Don't copy files the first time. */
- break ;
- case 'f' : STRCPY(fdir,p) ; /* Directory to start monitoring from. */
- break ;
- case 'r' : STRCPY(rhost,p) ; /* Name of remote host. */
- usercp = 1 ;
- break ;
- case 's' : delay = atoi(p) ; /* Sleep period in seconds. */
- break ;
- case 't' : STRCPY(tdir,p) ; /* Directory to start copying to. */
- break ;
- default : FPRINTF(stderr,"USAGE: abcd [-c] [-ffromdir] [-rhostname]") ;
- FPRINTF(stderr," [-ssleep] [-ttodir]\n") ;
- exit(1) ;
- }
- argc-- ;
- argv++ ;
- }
- }
-
-
- setup()
-
- {
- dirs = (struct dinfo *) malloc(sizeof(struct dinfo)) ;
- STRCPY(dirs->d_name,"") ;
- STRCPY(pdir,fdir) ; /* Start directory for current cp request. */
- STRCPY(coff,"") ; /* Name offset from start directory. */
- if (usercp) STRCPY(cname,"/usr/ucb/rcp") ; /* Used by the output routine. */
- else STRCPY(cname,"/bin/cp") ;
- dirs->next = dirs ;
- cdir = dirs ;
- }
-
-
- get_next_dir() /* Get next directory name to monitor. */
-
- {
- struct dinfo *temp ;
- int dirfound ;
-
- dirfound = 0 ;
- if (fd)
- {
- CLOSE(fd) ;
- if (!strlen(cdir->next->d_name)) /* Complete pass done? */
- {
- docopy = 1 ; /* Always copy after first pass. */
- if (!copy_found)
- sleep((unsigned int) delay) ; /* Nothing happening, go to sleep. */
- else copy_found = 0 ;
- }
- if (strcmp(curdir,cdir->next->d_name) != 0)
- if (fcnt) output("",REGULAR) ;
- }
- do
- {
- STRCPY(curdir,fdir) ;
- if (strlen(cdir->next->d_name))
- {
- STRCAT(curdir,"/") ;
- STRCAT(curdir,cdir->next->d_name) ;
- }
- STRCPY(coff,cdir->next->d_name) ;
- if ((fd = open(curdir,0)) == -1)
- {
- if (EQUAL(curdir,fdir)) exit(0) ; /* Nothing left to monitor. */
- else
- {
- temp = cdir->next ;
- if (cdir->next == dirs) dirs = cdir ;
- cdir->next = cdir->next->next ;
- free((char *) temp) ; /* Lose this directory record. */
- no_dirs-- ;
- }
- }
- else dirfound = 1 ; /* Directory found. */
- }
- while (!dirfound) ;
- cdir = cdir->next ; /* Point to current directory. */
- loc = 0 ; /* Reset directory buffer pointer. */
- }
-
-
- make_dir_entry() /* If not there already, create a new directory record. */
-
- {
- int i ;
- char tempdir[MAXLINE] ; /* Temporary directory name. */
- struct dinfo *temp ;
-
- temp = cdir ;
- for (i = 0; i < no_dirs; i++) /* Is the directory already being monitored? */
- {
- temp = temp->next ;
- STRCPY(tempdir,fdir) ;
- if (strlen(temp->d_name))
- {
- STRCAT(tempdir,"/") ;
- STRCAT(tempdir,temp->d_name) ;
- }
- if (EQUAL(tempdir,fname)) return(0) ;
- }
-
- temp = (struct dinfo *) malloc(sizeof(struct dinfo)) ;
- temp->next = dirs->next ;
- dirs->next = temp ;
- dirs = temp ;
-
- STRCPY(dirs->d_name,"") ;
- if (strlen(coff))
- {
- STRCAT(dirs->d_name,coff) ;
- STRCAT(dirs->d_name,"/") ;
- }
- STRCAT(dirs->d_name,cur->d_name) ;
- no_dirs++ ;
- return(1) ;
- }
-
-
- get_next_entry(fd) /* Get next directory filename entry. */
- int fd ;
-
- {
- int tfd ; /* Temporary file descriptor for file entry. */
-
- for (;;)
- {
- if (!loc)
- if ((size = read(fd,dbuf,DIRBLKSIZ)) <= 0) return(0) ;
- if (loc >= size)
- {
- loc = 0 ;
- continue ;
- }
- cur = (struct direct *) (dbuf+loc) ;
- if (cur->d_fileno == 0) return(0) ;
- SPRINTF(fname,"%s/%s",curdir,cur->d_name) ;
- if ((tfd = open(fname,0)) == -1)
- {
- loc += cur->d_reclen ;
- continue ;
- }
- else
- {
- CLOSE(tfd) ;
- cur = (struct direct *) malloc(sizeof(struct direct)) ;
- bcopy(dbuf+loc,(char *) cur,(int) DIRSIZ((struct direct *)(dbuf+loc))) ;
- loc += cur->d_reclen ;
- STAT(fname,&cstat) ;
- return(1) ;
- }
- }
- }
-
-
- no_record() /* Check is this file is already being monitored. */
-
- {
- if (files == NULL) return(1) ;
- cfile = files ;
- do
- if (cfile->direct->d_fileno == cur->d_fileno) return(0) ;
- while ((cfile = cfile->next) != NULL) ;
- return(1) ;
- }
-
-
- make_file_entry() /* Make a record for this new file. */
-
- {
- struct finfo *temp ;
-
- if ((cstat.st_mode & S_IFMT) == REGULAR)
- {
- temp = (struct finfo *) malloc(sizeof(struct finfo)) ;
- temp->next = files ;
- files = temp ;
-
- files->direct = (struct direct *) malloc(sizeof(struct direct)) ;
- files->direct = cur ;
- files->mtime = cstat.st_mtime ;
- }
- }
-
-
- file_modified() /* Check if this file has been changed. */
-
- {
- if (cfile->mtime == cstat.st_mtime) return(0) ;
- cfile->mtime = cstat.st_mtime ;
- return(1) ;
- }
-
-
- copy(filetype) /* Copy file to another directory. */
- int filetype ;
-
- {
- char name[MAXLINE] ;
-
- if (docopy) /* Are we copying this time around. */
- {
- copy_found = 1 ;
- STRCPY(name,"") ;
- if (strlen(coff))
- {
- STRCAT(name,coff) ;
- STRCAT(name,"/") ;
- }
- STRCAT(name,cur->d_name) ;
- if (strcmp(curdir,pdir) != 0) /* Current dir. different from cp dir.? */
- {
- if (fcnt) output(name,REGULAR) ;
- STRCPY(pdir,curdir) ;
- }
- if (filetype == DIRECTORY)
- {
- if (fcnt) output(name,REGULAR) ;
- output(name,DIRECTORY) ;
- }
- else if (fcnt >= MAXFILES) /* Room in file list for this filename? */
- {
- output(name,REGULAR) ;
- STRCPY(flist[fcnt++],name) ;
- }
- else STRCPY(flist[fcnt++],name) ; /* Save filename in file list. */
- }
- }
-
-
- output(name,filetype)
- char name[MAXLINE] ;
- int filetype ;
-
- {
- char command[MAXLINE*7],rdirname[MAXLINE] ;
- int i ;
-
- switch (filetype)
- {
- case DIRECTORY : if (usercp)
- SPRINTF(command,"%s -r %s/%s %s:%s",cname,fdir,name,rhost,curdir) ;
- else
- {
- STRCPY(rdirname,tdir) ;
- STRCAT(rdirname,"/") ;
- STRCAT(rdirname,name) ;
- if ((fd = open(rdirname,0)) == -1)
- SPRINTF(command,"mkdir %s",rdirname) ;
- else return ;
- }
- break ;
- case REGULAR : if (usercp) SPRINTF(rdirname,"%s:%s",rhost,curdir) ;
- else
- {
- STRCPY(rdirname,tdir) ;
- if (strlen(coff))
- {
- STRCAT(rdirname,"/") ;
- STRCAT(rdirname,coff) ;
- }
- }
- STRCPY(command,cname) ;
- for (i = 0; i < fcnt; i++)
- {
- STRCAT(command," ") ;
- STRCAT(command,fdir) ;
- STRCAT(command,"/") ;
- STRCAT(command,flist[i]) ;
- }
- STRCAT(command," ") ;
- STRCAT(command,rdirname) ;
- }
- if (system(command))
- FPRINTF(stderr,"abcd failed: %s\n",command) ;
- else FPRINTF(stderr,"abcd succeeded: %s\n",command) ;
- FPRINTF(stderr,"\n\n\n") ;
-
- fcnt = 0 ;
- }
-
-
- main(argc,argv)
- int argc ;
- char *argv[] ;
-
- {
- get_options(argc,argv) ; /* Get command line options. */
- setup() ; /* Initialise parameters. */
- while (MACHINE_WORKING) /* Do it until the machine crashes. */
- {
- get_next_dir() ; /* Is there another directory? */
- while (get_next_entry(fd)) /* Is there another file in dir? */
- {
- if (!DOTS(cur->d_name)) /* Is it the . or .. entry? */
- {
- if (no_record()) /* Is this file already monitored? */
- {
- if ((cstat.st_mode & S_IFMT) == DIRECTORY) /* Directory? */
- {
- if (make_dir_entry()) copy(DIRECTORY) ;
- }
- else
- {
- make_file_entry() ; /* Make a file entry. */
- copy(REGULAR) ; /* Copy it to backup machine. */
- }
- }
- else if (file_modified()) copy(REGULAR) ; /* File been modified? */
- }
- else free((char *) cur) ;
- }
- }
- }
- Funky_Stuff
- len=`wc -c < abcd.c`
- if [ $len != 12906 ] ; then
- echo error: abcd.c was $len bytes long, should have been 12906
- fi
- fi # end of overwriting check
- if [ -f abcd.h ]
- then
- echo shar: will not over-write existing file abcd.h
- else
- echo shar: extracting 'abcd.h', 1645 characters
- cat > abcd.h <<'Funky_Stuff'
-
- /* abcd.h
- *
- * Definitions used by abcd, the automatic backup copy daemon.
- *
- * Copyright (c) Rich Burridge - Sun Microsystems Australia (Melbourne).
- *
- * Version 1.1 - May 1988.
- *
- * No responsibility is taken for any error in accuracies inherent
- * either to the comments or the code of this program, but if
- * reported to me then an attempt will be made to fix them.
- */
-
- #define CLOSE (void) close /* To make lint happy. */
- #define FPRINTF (void) fprintf
- #define SPRINTF (void) sprintf
- #define SIGNAL (void) signal
- #define STAT (void) stat
- #define STRCAT (void) strcat
- #define STRCPY (void) strcpy
-
- #define DIRECTORY S_IFDIR /* Type of files being monitored. */
- #define REGULAR S_IFREG
-
- #define DIRBLKSIZ 512 /* Block size for directory read. */
- #define DOTS(A) (A[0] == '.' && (A[1] == 0 || (A[1] == '.' && A[2] == 0)))
- #define EQUAL(a,b) !strcmp(a,b) /* Test for string equality. */
- #define MACHINE_WORKING 1 /* Forever and a day .... */
- #define MAXFILES 5 /* Max no of files to copy in one go. */
- #define MAXLINE MAXNAMLEN+1 /* Maximum length of path names. */
-
-
- struct dinfo /* Info record for directories being monitored. */
- {
- struct dinfo *next ;
- char d_name[MAXLINE] ;
- } ;
-
- struct finfo /* Information record for monitored files. */
- {
- struct finfo *next ;
- struct direct *direct ;
- time_t mtime ;
- } ;
- Funky_Stuff
- len=`wc -c < abcd.h`
- if [ $len != 1645 ] ; then
- echo error: abcd.h was $len bytes long, should have been 1645
- fi
- fi # end of overwriting check
- if [ -f patchlevel.h ]
- then
- echo shar: will not over-write existing file patchlevel.h
- else
- echo shar: extracting 'patchlevel.h', 443 characters
- cat > patchlevel.h <<'Funky_Stuff'
-
- /* patchlevel.h
- *
- * This is the current patch level for this version of abcd.
- *
- * Copyright (c) Rich Burridge - May 1988.
- * Sun Microsystems, Australia - All rights reserved.
- *
- * Version 1.1.
- *
- * No responsibility is taken for any errors or inaccuracies inherent
- * either to the comments or the code of this program, but if
- * reported to me then an attempt will be made to fix them.
- */
-
- #define PATCHLEVEL 0
- Funky_Stuff
- len=`wc -c < patchlevel.h`
- if [ $len != 443 ] ; then
- echo error: patchlevel.h was $len bytes long, should have been 443
- fi
- fi # end of overwriting check
- if [ -f Makefile ]
- then
- echo shar: will not over-write existing file Makefile
- else
- echo shar: extracting 'Makefile', 955 characters
- cat > Makefile <<'Funky_Stuff'
- #
- # Makefile for abcd, an automatic backup copy daemon.
- #
- # Copyright (c) Rich Burridge - Sun Microsystems Australia (Melbourne).
- #
- # Version 1.1 - May 1988.
- #
- # No responsibility is taken for any errors inherent either in the comments
- # or the code of this program, but if reported to me then an attempt will
- # be made to fix them.
- #
-
- BINARIES = abcd
- BINDIR = .
- CFLAGS = -g
- LDFLAGS = -g
- OBJS = abcd.o
- SRCS = abcd.c
- HDRS = abcd.h patchlevel.h
- LIBS =
- OTHERS = Makefile README abcd.1
-
- all: $(BINARIES)
-
- release: $(BINARIES)
- strip $(BINARIES)
- mv $(BINARIES) $(BINDIR)
-
- backup:
- cp abcd.c abcd.c~
- cp abcd.h abcd.h~
-
- shar:; shar.script $(SRCS) $(HDRS) $(OTHERS) > archive
-
- clean:
- rm -f abcd *.o *.c~ core
-
- lint:
- lint $(SRCS) $(LIBS)
-
- abcd: $(OBJS)
- cc $(LDFLAGS) -o abcd $(OBJS) $(LIBS)
-
- abcd.o: abcd.c $(HDRS)
- Funky_Stuff
- len=`wc -c < Makefile`
- if [ $len != 955 ] ; then
- echo error: Makefile was $len bytes long, should have been 955
- fi
- fi # end of overwriting check
- if [ -f README ]
- then
- echo shar: will not over-write existing file README
- else
- echo shar: extracting 'README', 2345 characters
- cat > README <<'Funky_Stuff'
-
- ABCD v1.1 - May 1988.
- ---------------------
-
- This is an automatic backup copy daemon, which copies files from one
- filestore area to another using either cp or rcp. Note the second filestore
- area could be on another machine if the file system is NFS mounted.
-
- This means that the backup machine should have an identical copy of the
- filestore being monitored, give or take a little bit.
-
- NOTES
-
- (1) A start directory for monitoring is given. All the files including
- sub-directories and their files are monitored. Whenever any one of
- them is changed it is automatically copied to another machine as
- specified by the initial parameters to the program.
-
- (2) If it finds a new directory, then it will make that new directory
- in the other area (on the other machine) if not present.
-
- (3) If a sub-directory is deleted, then that directory is removed from
- the list of directories being monitored. If the original start directory
- is removed, then the program terminates because there is nothing left
- to monitor.
-
- (4) If nothing has changed in one complete pass of all the directories
- been monitored, then the program puts itself to sleep for 5 minutes.
-
- (5) There is a restart facility whereby if the machine has crashed, then it
- is possible to tell the program not to copy anything for the first pass,
- but to start copying changed files from the second pass onwards.
-
- (6) Abcd uses the "system" system call to do its copying, so as to prevent
- hundreds or child processes being spawned.
-
- SWITCHES
-
- -fdirectory Directory to start copying from. Defaults to /usr.
-
- -tdirectory Directory to start copying to. Defaults to /usr2.
-
- -rhostname This is an alternative form of backup. Uses rcp and copies to
- hostname supplied.
-
- -sseconds Specifies the sleep period in seconds for when the program puts
- itself to sleep.
-
- -c If given, then abcd won't copy the first time through.
-
-
- Suggestions, comments, flames and bugs to me please.
-
- Rich.
-
- Rich Burridge, JANET richb%sunaus.oz@uk.ac.ucl.cs
- ACSnet richb@sunaus.oz UUCP {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
- PHONE: +61 2 436 4699 ARPAnet rburridge@Sun.COM
- Sun Microsystems, Unit 2, 49-53 Hotham Pde, Artarmon, N.S.W. 2164, AUSTRALIA.
- Funky_Stuff
- len=`wc -c < README`
- if [ $len != 2345 ] ; then
- echo error: README was $len bytes long, should have been 2345
- fi
- fi # end of overwriting check
- if [ -f abcd.1 ]
- then
- echo shar: will not over-write existing file abcd.1
- else
- echo shar: extracting 'abcd.1', 2407 characters
- cat > abcd.1 <<'Funky_Stuff'
- .\" @(#)abcd.1 1.1 25/05/88;
- .TH ABCD 1L "25 May 1988"
- .SH NAME
- abcd \- automatic backup copy daemon
- .SH SYNOPSIS
- .B "abcd
- [
- .B -f
- .I directory
- ]
- [
- .B -t
- .I directory
- ]
- [
- .B -r
- .I hostname
- ]
- [
- .B -s
- .I seconds
- ]
- [
- .B -c
- ]
- .SH DESCRIPTION
- .I Abcd
- is an automatic backup copy daemon, which copies files from one
- filestore area to another using either cp or rcp. Note the second filestore
- area could be on another machine if the file system is NFS mounted.
- .LP
- This means that the backup machine should have an almost identical copy
- of the filestore being monitored.
- .LP
- A start directory for monitoring is given. All the files including
- sub-directories and their files are monitored. Whenever any one of
- them is changed it is automatically copied to another machine as
- specified by the initial parameters to the program.
- .LP
- If it finds a new directory, then it will make that new directory
- in the other area if not present.
- .LP
- If a sub-directory is deleted, then that directory is removed from
- the list of directories being monitored. If the original start directory
- is removed, then the program terminates because there is nothing left
- to monitor.
- .LP
- If nothing has changed in one complete pass of all the directories
- been monitored, then the program puts itself to sleep for a specified
- period.
- .LP
- There is a restart facility whereby if the machine has crashed, then it
- is possible to tell the program not to copy anything for the first pass,
- but to start copying changed files from the second pass onwards.
- .SH OPTIONS
- .TP
- .BI -f "directory"
- Directory to start copying from. Defaults to /usr.
- .TP
- .BI -t "directory"
- Directory to start copying to. Defaults to /usr2.
- .TP
- .BI -r "hostname"
- This is an alternative form of backup. Uses rcp and copies to
- hostname supplied.
- .TP
- .BI -s "seconds"
- Specifies the sleep period in seconds for when the program puts
- itself to sleep. Default is 5 minutes.
- .TP
- .B -c
- If given, then abcd won't copy the first time through.
- .SH BUGS
- This program is currently totally inpractical for monitoring filestore
- areas containing large files which are being continuously updated, such
- as databases.
- .SH AUTHOR
- Rich Burridge, Sun Microsystems, Unit 2, 49-53 Hotham Pde, Artarmon, N.S.W.
- 2164, AUSTRALIA. PHONE: +61 2 436 4699
- .nf
- JANET: richb%sunaus.oz@uk.ac.ucl.cs
- ACSnet: richb@sunaus.oz
- UUCP: {uunet,hplabs,mcvax,ukc}!munnari!sunaus.oz!richb
- ARPAnet: rburridge@Sun.COM
- .fi
- Funky_Stuff
- len=`wc -c < abcd.1`
- if [ $len != 2407 ] ; then
- echo error: abcd.1 was $len bytes long, should have been 2407
- fi
- fi # end of overwriting check
-