samperi@dasys1.UUCP (Dominick Samperi) (11/30/87)
The following shell archive contains a floppy backup program for
System V UNIX systems. It is based on cpio and find. It has been
tested with Xenix and Microport's System V/AT.
Delete the header to the cut line, and shell the rest.
----- cut ------- cut -------- cut -----------
#!/bin/sh
# to extract, remove the header and type "sh filename"
if `test ! -s ./README`
then
echo "writing ./README"
cat > ./README << '\Rogue\Monster\'
dbackup/drestore - Multi-floppy Directory Backup/Restore Utility.
(For UNIX System V and XENIX)
Copyright 1987 Dominick Samperi
LISCENSE AGREEMENT. This software may be freely copied and distributed
for personal use only.
DISCLAIMER OF WARRANTY. This software is distributed "as is" and
without warranties as to performance of merchantability or any
other warranties whether expressed or implied. In no event shall the
author (the copyright holder) be held liable for any loss of profit
or any other commercial damage resulting from the use or misuse of
this software, including but not limited to special, incidental,
consequential or other damages. No warranty of fitness for a
particular purpose is offered. The user must assume the entire
risk of using the program.
INTRODUCTION. These utilities can be used to backup and restore directory
hierarchies, typically by copying them to a set of floppy diskettes. They
were designed to facilitate the process of backing up selected files and
directories, so that a complete file system backup (requiring many
floppies) is rarely needed (if you keep backup copies of the distribution
floppies, then it may not be necessary to do a complete file system
backup at all). Floppies are prompted for automatically, as they are
needed.
NOTE: This program is based on the versions of find and cpio that are
shipped with AT&T/Microport System V UNIX, Release 2.0. It will
also work with SCO Xenix. A version for PC's running MS-DOS is
also available.
FILES.
README - This file.
dbackup.c - dbackup source.
dbackup.doc - Formatted man page.
dbackup.conf - Sample local configuration file list.
dbackup.bu - Used to backup dbackup and drestore.
backup - Sample backup shell script.
makefile - Makefile for compilation/installation.
INSTALLATION. After setting the variable BIN in makefile equal to
the full path name of your local binary directory, select the
appropriate CFLAGS line, and type make.
NOTE: In order for the program to be able to restore the default
operation of special function key F1, the default string that is
emitted when this key is pressed must be assigned to the
preprocessor symbol F1_str. If you are running SCO XENIX or
Microport's System V/AT, then this is done automatically, provided
that you choose the correct CFLAGS definition in makefile. Another
parameter that may need to be changed is BU_dev, which should
equal the default device file to use for backups (it is
/dev/rdsk/fd for Microport, and /dev/rfd096 for XENIX).
USAGE. In order to enjoy the benefits of these utilities, you should
partition all files that need to be backed up into a collection of
directories of moderate size (say, 5-7 megs). For example, many
systems have a /usr/src directory that may contain 10 Megs or more
of source files. In this situation the source directory should be
partitioned into subdirectories of moderate size that can be backed
up separately (e.g., /usr/src/news, /usr/src/misc, etc.). You can
use the command 'du -s dirname' to determine the size of dirname in
blocks (twice the number of megs).
All files under /usr/src/news can then be backed up (onto one or more
high-density floppies) by using:
dbackup /usr/src/news
You will be prompted for floppies as they are needed; be sure to
label them, and number them so they can be restored in the correct
order.
Several smaller directory hierarchies can be backed up onto one
floppy set by supplying the full path names of the root directories
on the command line. For example, user directories /usr/smith,
/usr/james, and /usr/rogers can be backed up with:
dbackup /usr/smith /usr/james /usr/rogers
Dbackup writes a time stamp file named .dbackup_time into the
first directory that appears on the command line (/usr/smith in
the last example). This file can be used to display the names of
all files in the directory hierarchies that have changed since
the last dbackup. For example, all files under /usr/smith and
/usr/james that have changed since the dbackup command above was
executed can be displayed with:
find /usr/smith /usr/james -newer /usr/smith/.dbackup_time -print
You can use this information to decide whether or not a new dbackup
is necessary (a shell script can be used to save some typing here).
The time stamp file is also used by dbackup to do incremental
backups (see the man page for more information).
Essential local configuration files that would need to be restored after
a hard disk crash or system reinstallation can be backed up as follows.
First, put the names of files like /etc/passwd, /etc/group, /etc/profile,
/usr/lib/uucp/L.sys, /usr/lib/uucp/USERFILE, etc. into a file named
/etc/dbackup.conf. Place each file name on a separate line, and use
full path names (beginning with /). Don't forget to include the name
/etc/dbackup.conf! Look at the sample dbackup.conf that is included
with this software.
Now, assuming that your local binary directory is named /usr/lbin, you
can backup your essential configuration files, as well as your local
binary directory, as follows:
dbackup /etc/dbackup.conf /usr/lbin
Be sure to label the floppy set, and number the floppies. You can
backup other local directories (like /usr/src/news) as we did above.
Remember that each dbackup command generates a new floppy set, and
that the floppies in each set must be restored in the correct order.
The process of backing up multiple directories onto one or more
dbackup floppy sets can be automated by using a shell script. An
example of such a shell script is included with this software. It
is named backup.
All files in a dbackup set of floppies can be restored by typing:
drestore
You will be prompted for floppies by number as they are needed.
Since drestore is not included on your distribution floppies, dbackup
and drestore should be (d)backed up separately onto a dedicated floppy
as follows. First insert the names /usr/lbin/dbackup and
/usr/lbin/drestore (change /usr/lbin to your local binary directory)
into a file named /etc/dbackup.bu. Then dump dbackup and drestore to a
dedicated floppy as follows:
dbackup /etc/dbackup.bu
Now, if you must do a complete restore, first reload the system from
your distribution floppies, and then restore dbackup and drestore from
the dedicated floppy by typing (as root, with Microport):
cd /
cpio -icvduma < /dev/rdsk/fd
For SCO Xenix, replace the cpio command line above with
cpio -icvdumaB < /dev/rfd096
(a different cpio command line may have to be used for other systems).
Once you have restored dbackup and drestore, you can proceed to restore
each of your dbackup floppy sets by using drestore, as we did above.
If you only want to list the names of the files in a dbackup floppy set
(without restoring the files), use:
drestore -l
You can also use drestore to restore a dbackup floppy set under an
user-specified root directory (other than the default, /). See the
man page for more information.
Please send comments, enhancements, etc., to:
Dominick Samperi
430 East 13th Street
New York, N.Y. 10009
UUCP: ...!ihnp4!cmcl2!manhat!samperi
ARPA: manhat!samperi@NYU.EDU
\Rogue\Monster\
else
echo "will not over write ./README"
fi
if `test ! -s ./backup`
then
echo "writing ./backup"
cat > ./backup << '\Rogue\Monster\'
#
# File backup script. D. Samperi, September 1987.
#
if [ $# -eq 0 ]
then
echo "\n\tUsage: backup class ..."
echo "\n\t(class can be: conf, src, samperi, or all)\n"
exit
fi
for class in $*
do
case $class in
conf | all) \
echo "\n\007Starting backup of conf. files...\n" ; \
dbackup /etc/dbackup.conf /usr/lbin ;;
src | all) \
echo "\n\007Starting backup of /usr/src...\n" ; \
dbackup /usr/src ;;
samperi | all) \
echo "\n\007Starting backup of /usr/samperi...\n" ; \
dbackup /usr/samperi ;;
esac
done
\Rogue\Monster\
else
echo "will not over write ./backup"
fi
if `test ! -s ./dbackup.bu`
then
echo "writing ./dbackup.bu"
cat > ./dbackup.bu << '\Rogue\Monster\'
/usr/lbin/dbackup
/usr/lbin/drestore
\Rogue\Monster\
else
echo "will not over write ./dbackup.bu"
fi
if `test ! -s ./dbackup.c`
then
echo "writing ./dbackup.c"
cat > ./dbackup.c << '\Rogue\Monster\'
/*
* dbackup.c - Multi-floppy Directory Backup/Restore Utility
* (For UNIX System V and XENIX)
*
* Copyright 1987 Dominick Samperi
*
* INSTALLATION. Compile and install the program in your local binary
* directory as follows:
*
* cc -O dbackup.c -o dbackup
* mv dbackup /usr/lbin (or whatever you call your local binary dir.)
* ln /usr/lbin/dbackup /usr/lbin/drestore
*
* XENIX users should replace the cc command line above with
*
* cc -O -DXENIX dbackup.c -o dbackup
*
* USAGE.
*
* dbackup Full-pathname(s) [-nh] [-t Template] [-d Bkup-device] [-f listing]
* drestore [-hl] [-r Root-dir] [-t Template] [-d Bkup-device] [-f listing]
*
* WARNING: Typing ENTER while a backup or restore is in progress will
* probably terminate the program prematurely! This is due to
* a bug in cpio. For this reason, all user input (while the
* program is running) is through special function key F1.
* Extra keystrokes other than ENTER may cause the program to
* prompt again for a new floppy, but with the incorrect floppy
* number. This shouldn't cause any problems, provided it is kept
* in mind that the correct floppy sequence number is determined
* by the order in which floppies are written or read.
*
* NOTES. Dbackup pipes the output of find into cpio, and monitors the
* standard error output of the resulting pipeline to provide a more
* user-friendly backup procedure than the one based on find and
* cpio alone.
*
* Note that zero-length (empty) files are copied, but their names
* are not displayed.
*
* F1_defstr is the default value of the string that is generated
* by pressing special function key F1.
*
* Finally, note that the final blocks count that is printed after
* a drestore is equal to the total number of blocks in the cpio
* backup set, so it may not equal the number of blocks restored
* if the -t flag is used.
*
* Please send any comments, enhancements, etc. to:
*
* Dominick Samperi
* 430 East 13th Street
* New York, N.Y. 10009
*
* UUCP: ...!{ihnp4|rutgers|philabs}!cmcl2!manhat!samperi
* ...!ihnp4!{pur-ee|iuvax}!bsu-cs!zoo-hq!magpie!samperi
*
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/signal.h>
#define TRUE 1
#define FALSE 0
#define not !
#define BACKUP 1
#define RESTORE 0
/* Set the default backup device to use. */
#ifdef BU_dev
static char bu_dev[40] = BU_dev ;
#else
#ifdef XENIX
static char bu_dev[40] = "/dev/rfd096" ;
#else
static char bu_dev[40] = "/dev/rdsk/fd" ;
#endif
#endif
/* Set special function key F1 default string. */
#ifdef F1_str
static char *F1_defstr = F1_str ;
#else
#ifdef XENIX
static char *F1_defstr = "\033[M" ;
#else
static char *F1_defstr = "^[OP" ;
#endif
#endif
/*
* There is probably a system call to fetch F1_defstr, but it is not
* documented? Using the shell to fetch it via `setkey f1` and a temporary
* file seems too clumsy (this method was used in an earlier version of
* this program).
*/
/* Globals... */
static int mode, pid ; /* mode = BACKUP or RESTORE, pid = child process id. */
static int list_files = FALSE ; /* Only list file names if TRUE. */
static FILE *listing = NULL ; /* Listing file. */
static FILE *keybrd ; /* Used to flush the keyboard buffer. */
main(argc, argv)
int argc ;
char *argv[] ;
{
char cmd[512], cmd2[80], root_dir[80] ;
char *fname = NULL, *progname, *param, *template = NULL ;
char bu_dirs[256], bu_misc[256], bu_dir1[80] ;
char *strrchr(), *ctime() ;
long unix_time, time() ;
extern char *optarg ;
int i, c, p[2], fstatus, ftype ;
int newer = FALSE, bad_arg = FALSE, first_dir = TRUE ;
int print_help = FALSE ;
struct stat Buf ;
void watch_stderr(), clean_up() ;
/* Get name part of program path. */
progname = strrchr(argv[0], '/') ;
if(progname == NULL)
progname = argv[0] ;
else
progname++ ;
/* How was program invoked? As dbackup or drestore? */
if(strcmp(progname, "drestore") == 0)
mode = RESTORE ;
else if(strcmp(progname, "dbackup") == 0)
mode = BACKUP ;
else
{
fprintf(stderr,
"\nMust name program dbackup, or drestore.\n\n") ;
exit(1) ;
}
bu_dirs[0] = '\0' ; /* Directories to backup. */
bu_misc[0] = '\0' ; /* Miscellaneous files to backup. */
/* If BACKUP mode, is Full-pathname a directory or an ordinary file? */
if(mode == BACKUP)
{
if(argc < 2)
bad_arg = TRUE ;
else if(strcmp(argv[1], "-h") == 0)
print_help = TRUE ;
else
{
while(not bad_arg && argc > 1 && argv[1][0] != '-')
{
param = *++argv ; argc-- ;
if(param[0] != '/')
{
fprintf(stderr, "\nMust specify full path names") ;
fprintf(stderr, " (starting with /).\n\n") ;
exit(1) ;
}
fstatus = stat(param, &Buf) ;
if(fstatus == -1)
bad_arg = TRUE ;
else if((ftype = (Buf.st_mode & 0170000)) == 0
|| ftype == 0100000)
{
/* Ordinary file. */
strcat(bu_misc, param) ;
strcat(bu_misc, " ") ;
}
else if(ftype == 040000)
{
/* Directory. */
strcat(bu_dirs, ".") ;
strcat(bu_dirs, param) ;
strcat(bu_dirs, " ") ;
if(first_dir)
{
strcpy(bu_dir1, param) ;
first_dir = FALSE ;
}
}
else
{
bad_arg == TRUE ;
break ;
}
}
}
}
strcpy(root_dir, "/") ; /* Default drestore root directory. */
/* Look for command line flags. */
while((c = getopt(argc, argv, "lhnf:r:t:d:")) != EOF)
{
switch(c)
{
case 'h': /* Print some help. */
print_help = TRUE ;
break ;
case 'l': /* Just list file names. */
if(mode == RESTORE)
list_files = TRUE ;
else
bad_arg = TRUE ;
break ;
case 'f': /* Generate a listing file. */
fname = optarg ;
break ;
case 'n': /* Only backup if newer than last dbackup. */
if(mode == BACKUP)
newer = TRUE ;
else
bad_arg = TRUE ;
break ;
case 'r': /* Restore under this root directory. */
if(mode == RESTORE)
strcpy(root_dir, optarg) ;
else
bad_arg = TRUE ;
break ;
case 'd': /* Alternative backup device file. */
strcpy(bu_dev, optarg) ;
break ;
case 't': /* Backup/Restore using template. */
template = optarg ;
break ;
case '?':
bad_arg = TRUE ;
break ;
}
}
if(list_files && fname)
{
fprintf(stderr, "\nMust use I/O redirection to send -l ") ;
fprintf(stderr, "output to a file.\n\n") ;
exit(1) ;
}
else if(fname)
{
listing = fopen(fname, "w") ;
if(listing == NULL)
bad_arg = TRUE ;
}
/* Check for bad arguments. */
if((bad_arg || print_help) && mode == BACKUP)
{
fprintf(stderr, "\nUsage: %s Full-pathname(s) %s\n\n", progname,
"[-hn] [-t template] [-d backup-dev] [-f listing]") ;
exit(1) ;
}
else if(bad_arg || print_help)
{
fprintf(stderr, "\nUsage: %s %s\n\n", progname,
"[-hl] [-r root-dir] [-t template] [-d backup-dev] [-f listing]") ;
exit(1) ;
}
/* Build find/cpio command... */
strcpy(cmd, "trap 'exit 1' 1 2 3 ; cd ") ;
if(mode == BACKUP)
{
/* do_both is TRUE when there are directories AND
miscellaneous files to backup... */
int do_both = (bu_dirs[0] != '\0' && bu_misc[0] != '\0') ;
strcat(cmd, "/ ; ") ;
if(do_both)
strcat(cmd, "(") ;
if(bu_misc[0] != '\0') /* Miscellaneous files to backup. */
{
/* Make sure all paths are of the form ./... */
strcat(cmd, " sed ") ;
strcat(cmd, "-e \"s/^\\//\\.\\//\" ") ;
strcat(cmd, "-e \"s/^[^/.]/\\.\\/&/\" ") ;
strcat(cmd, bu_misc) ;
}
if(do_both)
strcat(cmd, " ; ") ;
if(bu_dirs[0] != '\0') /* Directories to backup. */
{
strcat(cmd, " find ") ;
strcat(cmd, bu_dirs) ;
strcat(cmd, " -depth ") ;
if(newer)
{
strcat(cmd, " -newer .") ;
strcat(cmd, bu_dir1) ;
strcat(cmd, "/.dbackup_time ") ;
}
if(template != NULL)
{
strcat(cmd, " -name ") ;
strcat(cmd, "'") ;
strcat(cmd, template) ;
strcat(cmd, "' ") ;
}
strcat(cmd, " -print ") ;
}
if(do_both)
strcat(cmd, ")") ;
#ifdef XENIX
strcat(cmd, " | cpio -ocdvB > ") ;
#else
strcat(cmd, " | cpio -ocdv > ") ;
#endif
strcat(cmd, bu_dev) ;
}
else /* RESTORE */
{
strcat(cmd, root_dir) ;
if(list_files)
#ifdef XENIX
strcat(cmd, " ; cpio -ictvB ") ;
#else
strcat(cmd, " ; cpio -ictv ") ;
#endif
else
#ifdef XENIX
strcat(cmd, " ; cpio -icdumvaB ") ;
#else
strcat(cmd, " ; cpio -icdumva ") ;
#endif
if(template != NULL)
strcat(cmd, template) ;
strcat(cmd, " < ") ;
strcat(cmd, bu_dev) ;
}
#ifdef XENIX
strcat(cmd, " ; setkey 1 \"") ;
#else
strcat(cmd, " ; /etc/setkey f1 \"") ;
#endif
strcat(cmd, F1_defstr) ;
strcat(cmd, "\" ; stty echo ") ;
if(mode == BACKUP && not newer && bu_dirs[0] != '\0')
{
strcat(cmd, " ; touch ") ;
strcat(cmd, bu_dir1) ; strcat(cmd, "/.dbackup_time") ;
}
/* Arrange for the standard error output from the command to
go to the standard input of a spawned child process... */
pipe(p) ;
pid = fork() ;
if(pid < 0)
{
perror("fork error") ;
exit(1) ;
}
else if(pid == 0) /* The child. */
{
/* Child process monitors stderr output from parent... */
close(0) ;
dup(p[0]) ;
close(p[0]) ;
close(p[1]) ;
watch_stderr() ;
}
/* Parent code. */
/* Catch interrupts and hangups. */
signal(SIGINT, clean_up) ;
signal(SIGHUP, clean_up) ;
/*
* A system call equivalent to setkey would have avoided the need to
* shell a command here...
*/
/* Set string for special function key F1. */
#ifdef XENIX
strcpy(cmd2, "setkey 1 \"") ;
strcat(cmd2, bu_dev) ;
strcat(cmd2, "\n\" ; stty -echo") ;
#else
strcpy(cmd2, "/etc/setkey f1 \"") ;
strcat(cmd2, bu_dev) ;
strcat(cmd2, "^M\" ; stty -echo") ;
#endif
system(cmd2) ;
/* Send ready message to console, wait for F1. */
if(mode == BACKUP)
{
fprintf(stderr, "\nReady to begin backup of \n") ;
if(bu_dirs[0] != '\0')
fprintf(stderr, "Directories: %s\n", bu_dirs) ;
if(bu_misc[0] != '\0')
fprintf(stderr, "Miscellaneous files: %s\n", bu_misc) ;
if(template != NULL)
fprintf(stderr, "Template: %s\n", template) ;
}
else
{
if(list_files)
fprintf(stderr, "\nReady to list files") ;
else
fprintf(stderr, "\nReady to restore") ;
if(template != NULL)
fprintf(stderr, " (%s)", template) ;
if(list_files)
fprintf(stderr, ".\n") ;
else
fprintf(stderr, " under %s.\n", root_dir) ;
}
fprintf(stderr, "\n\tInsert floppy #1.\n\n\tHit F1 when ready,") ;
fprintf(stderr, " or CTRL-C to quit...\n\n") ;
while(getchar() != '\n') ;
time(&unix_time) ;
if(mode == BACKUP)
{
printf("\ndbackup started on %s\n", ctime(&unix_time)) ;
if(listing)
{
fprintf(listing, "\ndbackup started on %s\n",
ctime(&unix_time)) ;
if(bu_dirs[0] != '\0')
fprintf(listing, "Directories: %s\n", bu_dirs) ;
if(bu_misc[0] != '\0')
fprintf(listing, "Miscellaneous files: %s\n", bu_misc) ;
fprintf(listing, "\n") ;
}
}
else if(not list_files)
{
printf("\ndrestore started on %s\n", ctime(&unix_time)) ;
if(listing)
fprintf(listing, "\ndrestore started on %s\n",
ctime(&unix_time)) ;
}
else
printf("\nListing started on %s\n", ctime(&unix_time)) ;
fflush(stdout) ;
if(listing)
fflush(listing) ;
/* Send stderr to child's stdin. */
close(2) ;
dup(p[1]) ;
close(p[0]) ;
close(p[1]) ;
/* Shell the command, and call clean_up() if there is a problem. */
if(system(cmd) != 0)
clean_up() ;
}
void watch_stderr()
/*
* Monitors the stderr output from the cpio command, prompting
* for a new floppy when the string " ready\n" is found, and terminating when
* the string " blocks\n" is found. The strange error number information that
* is printed by cpio when the floppy is full is suppressed.
*/
{
char buf[2][80], *cp ; /* Output is "double buffered." */
static char *edge = " ready\nblocks\n" ; /* Used to drive automaton. */
int state, nfiles, bufp, k, c, fcount ;
void flush_keybrd() ; /* Flushes the keyboard buffer. */
state = 0 ; /* State of automaton used to recognize strings. */
fcount = 1 ; /* Number of current floppy. */
nfiles = 0 ; /* Number of files copied to floppy. */
bufp = 0 ; /* Points to current buffer containing file name. */
k = 0 ; /* Current position in this buffer. */
keybrd = fopen("/dev/tty", "r") ;
if(keybrd == NULL)
{
fprintf("Can't open your tty\n") ;
exit(1) ;
}
/* Begin automaton... */
while((c = getchar()) != NULL)
{
switch(state)
{
case 0:
if(c == ' ') state = 1 ;
break ;
case 1:
if(c == 'r') state = 2 ;
else if(c == 'b') state = 8 ;
else if(c != ' ') state = 0 ;
break ;
case 2:
case 3:
case 4:
case 5:
case 8:
case 9:
case 10:
case 11:
case 12:
if(c == edge[state]) state++ ;
else state = 0 ;
break ;
case 6:
if(c == '\n')
{
fcount++ ; /* New floppy number. */
nfiles = 0 ; /* Number files written so far. */
fflush(stdout) ;
if(listing)
fflush(listing) ;
fprintf(stderr,
"\n\t\007Done with floppy #%d, insert",
fcount-1) ;
fprintf(stderr,
" floppy #%d.\n\n\tHit F1 when ready,",
fcount) ;
fprintf(stderr, " or CTRL-C to quit...\n") ;
buf[0][0] = buf[1][0] = '\0' ;
k = 0 ;
}
else state = 0 ;
break ;
case 13:
if(c == '\n')
{
buf[bufp][k] = '\0' ;
cp = buf[!bufp] ;
if(*cp != '\0')
{
printf("%s\n", cp) ;
fflush(stdout) ;
if(listing)
{
fprintf(listing, "%s\n", cp) ;
fflush(listing) ;
}
}
if(mode == BACKUP)
fprintf(stderr,
"\n\007Backup done, %s total.\n",
buf[bufp]) ;
else
fprintf(stderr,
"\n\007Restore done, %s total.\n",
buf[bufp]) ;
exit(0) ;
}
else state = 0 ;
}
if(c == '\n')
{
if(state != 6)
{
buf[bufp][k] = '\0' ;
cp = buf[!bufp] ;
if(*cp != '\0')
{
printf("%s\n", cp) ;
if(nfiles == 0)
flush_keybrd() ;
if(listing)
fprintf(listing, "%s\n", cp) ;
nfiles++ ;
}
bufp = !bufp ;
k = 0 ;
}
}
else
buf[bufp][k++] = c ;
}
}
static int done ; /* Used for communication between the
following two functions. */
void flush_keybrd()
{
void handler() ;
done = FALSE ;
signal(SIGALRM, handler) ;
alarm(1) ;
while(not done)
fgetc(keybrd) ;
}
void handler(sig)
int sig ;
{
done = TRUE ;
}
void clean_up(sig)
int sig ;
{
char cmd[80] ;
signal(SIGINT, SIG_IGN) ;
signal(SIGHUP, SIG_IGN) ;
kill(pid, SIGKILL) ;
/*
* A system call equivalent to setkey would have avoided the need to
* shell a command here...
*/
/* Set string for special function key F1. */
strcpy(cmd, "echo \"\\nBackup or Restore Aborted, Cleaning up...\"") ;
#ifdef XENIX
strcat(cmd, " | cat > /dev/tty ; stty echo ; setkey 1 \"") ;
#else
strcat(cmd, " | cat > /dev/tty ; stty echo ; /etc/setkey f1 \"") ;
#endif
strcat(cmd, F1_defstr) ;
strcat(cmd, "\" ; echo \"Done, Goodbye!\" | cat > /dev/tty") ;
system(cmd) ;
exit(1) ;
}
\Rogue\Monster\
else
echo "will not over write ./dbackup.c"
fi
if `test ! -s ./dbackup.conf`
then
echo "writing ./dbackup.conf"
cat > ./dbackup.conf << '\Rogue\Monster\'
/etc/dbackup.conf
/etc/dbackup.bu
/etc/passwd
/etc/group
/etc/profile
/etc/inittab
/etc/gettydefs
/etc/bsetdate
/etc/fstab
/etc/checklist
/.profile
\Rogue\Monster\
else
echo "will not over write ./dbackup.conf"
fi
if `test ! -s ./dbackup.doc`
then
echo "writing ./dbackup.doc"
cat > ./dbackup.doc << '\Rogue\Monster\'
DBACKUP(1) UNIX 5.0 (SAMPERI) DBACKUP(1)
NAME
dbackup, drestore - directory backup and restore utilities
SYNOPSIS
dbackup Path(s) [-hn] [-t Temp] [-d Bu-Dev] [-f Lsfile]
drestore [-hl] [-r Root] [-t Temp] [-d Bu-Dev] [-f Lsfile]
DESCRIPTION
These utilities can be used to backup and restore directory
hierarchies, typically by copying them to a set of floppy
diskettes. They were designed to facilitate the process of
backing up selected files and directories, so that a
complete file system backup (requiring many floppies) is
rarely needed (if you keep backup copies of the distribution
floppies, then it may not be necessary to do a complete file
system backup at all). Dbackup and drestore will prompt for
floppies as they are needed.
Dbackup is used to backup one or more directory hierarchies,
and/or to backup files whose names are contained in one or
more text files. The parameter Path(s) represents one or
more full pathnames, each of which may correspond to a
directory, or to a text file. Each directory that appears is
taken to be the root of a directory hierarchy to be backed
up, and each text file that appears must contain a list of
(full) pathnames of files to be backed up, one per line.
The -t flag can be used to back up only those files in a
directory hierarchy with names that that match the file name
template Temp, and the -n flag can be used to backup only
those files in a directory hierarchy that have changed since
the last full (d)backup (that is, one for which the -n flag
was NOT used). Note that if more than one directory appears
in Path(s), a time stamp file named .dbackup_time is written
to the FIRST directory that appears, and this directory must
appear first if you want this time stamp file to be used for
a subsequent incremental backup (one for which the -n flag
is used). ALL files whose names are contained in text files
will be backed up (the -t and -n flags only effect directory
backups), and no time stamp file is written when Path(s)
does not include any directories.
Drestore can be used to restore files from a (numbered) set
of floppies that was created by a previous dbackup. By
default, files will be restored under /, which will cause
them to have the same full pathnames that they had when they
were backed up. The -r flag can be used to restore files
under an alternative root directory. For example, if "-r
/tmp" is specified, then a file that had the full path name
/usr/joe when it was backed up will be restored as
/tmp/usr/joe.
Page 1 (printed 11/30/87)
DBACKUP(1) UNIX 5.0 (SAMPERI) DBACKUP(1)
Files may be restored only if their names match a template
that is specified with the -t flag. The -l drestore flag
can be used to generate an "ls -l" style listing of the
files in a backup set generated by dbackup (no files are
copied).
An alternative backup device may be specified by means of
the -d flag. The default backup device file for Microport is
/dev/rdsk/fd, corresponding to the (first) high density
floppy drive. For example, in order to backup onto low
density floppies using the high density drive, use "-d
/dev/rdsk/fd048". (Warning: backing up onto low density
floppies is very slow.)
The -f flag may be used to generate a listing file
containing a log of the backup or restore. Note that the -f
flag may not be used with the -l drestore flag; if you want
a printed listing of the output from drestore -l, use I/O
redirection, as in: drestore -l > files.ls.
The -h flag will cause a (very terse) help message to be
printed.
EXAMPLES
In order to backup all files (and recursively, all
subdirectories) in the directories /usr/joe and /usr/lbin,
use:
dbackup /usr/joe /usr/lbin
To backup only files with names that end in .c or .h, use:
dbackup /usr/joe /usr/lbin -t '*.[ch]'
To backup only the files that have changed since the last
dbackup:
dbackup /usr/joe /usr/lbin -n
Assuming that the file /etc/dbackup.misc contains the full
pathnames of miscellaneous files (like /etc/passwd,
/etc/group, /usr/lib/uucp/L.sys, /usr/spool/lp/interface/lp,
etc.) to be backed up, important system-level files might be
backed up as follows:
dbackup /etc/dbackup.misc
All files can be restored from a dbackup floppy set to their
original locations by using:
Page 2 (printed 11/30/87)
DBACKUP(1) UNIX 5.0 (SAMPERI) DBACKUP(1)
drestore
The names of all C source files in a dbackup floppy set can
be written to a file named cfiles.ls as follows:
drestore -l -t '*.c' > cfiles.ls
No files are actually restored in this example.
BUGS
Typing ENTER while a backup or restore is in progress will
probably terminate the program prematurely. This is due to a
bug in cpio. For this reason, all user input (while the
program is running) is through special function key F1.
Extra keystrokes other than ENTER may cause the program to
prompt for a floppy again, before writing anything, and the
floppy sequence number displayed will no longer be correct.
This should not cause any problems, provided it is kept in
mind that the correct sequence number is determined by the
order in which floppies are written or read.
Empty files are backed up by dbackup, but their names are
not displayed during the backup procedure. (They are
displayed via drestore -l.)
Page 3 (printed 11/30/87)
\Rogue\Monster\
else
echo "will not over write ./dbackup.doc"
fi
if `test ! -s ./makefile`
then
echo "writing ./makefile"
cat > ./makefile << '\Rogue\Monster\'
#
# Makefile for dbackup/drestore. By Dominick J. Samperi, November 1987.
#
# Insure that your local binary directory appears below.
BIN=/usr/lbin
# Now choose the appropriate CFLAGS definition below.
#
# C flags for Microport System V/AT:
CFLAGS=-O -DF1_str=\"`/etc/setkey f1`\" -DBU_dev=\"/dev/rdsk/fd\"
#
# C flags for SCO XENIX:
# CFLAGS=-O -DXENIX -DF1_str=\"\\033[M\" -DBU_dev=\"/dev/rfd096\"
#
# C flags for generic System V (F1_str and BU_dev should be defined here):
# CFLAGS=-O (F1_str and BU_dev should be defined here)
#
# OK, now type 'make install'.
install: dbackup
strip dbackup
mv dbackup $(BIN)
chmod 0755 $(BIN)/dbackup
ln $(BIN)/dbackup $(BIN)/drestore
dbackup: dbackup.o
cc dbackup.o -o dbackup
\Rogue\Monster\
else
echo "will not over write ./makefile"
fi
echo "Finished archive 1 of 1"
exit
--
Dominick Samperi, Manhattan College, New York, NY
...!ihnp4!cmcl2!manhat!samperi
...!ihnp4!cmcl2!phri!dasys1!samperi