home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / unix / volume15 / abcd next >
Encoding:
Text File  |  1989-01-13  |  23.7 KB  |  782 lines

  1. Path: uunet!munnari!sources-request
  2. From: sources-request@munnari.oz
  3. Newsgroups: comp.sources.unix
  4. Subject: v15i011:  abcd - Automatic Backup Copy Daemon, Part01/01
  5. Message-ID: <2147@munnari.oz>
  6. Date: 26 May 88 19:15:48 GMT
  7. Sender: kre@munnari.oz
  8. Lines: 771
  9. Approved: kre@munnari.oz.au
  10.  
  11. Submitted by: richb@sunaus.sun.oz (Rich Burridge)
  12. Posting-number: Volume 15, Issue 11
  13. Archive-name: abcd/Part01
  14.  
  15.         [ this compiles OK on SunOS 3.4, but not on a 4.3 vax,
  16.           so it probably contains 4.2 dependancies.  I don't
  17.           suppose they would be hard to fix.  I wouldn't bother
  18.           on SysV I think.                ... kre ]
  19.  
  20.  
  21. This is an automatic backup copy daemon, which copies files from one
  22. filestore area to another using either cp or rcp. Note the second filestore
  23. area could be on another machine if the file system is NFS mounted.
  24.  
  25. This means that the backup machine should have an identical copy of the
  26. filestore being monitored, give or take a little bit.
  27.  
  28. With improvements and suggestions from various people, this program
  29. could be very useful. I can see a lot of drawbacks and limitations to
  30. this first version, but I'd like feedback before I work on any modifications.
  31.  
  32.     Rich.
  33.  
  34. ------CUT HERE------CUT HERE------
  35. #! /bin/sh
  36. # this is a shell archive, meaning:
  37. # 1. Remove everything above the #! /bin/sh line
  38. # 2. Save the resulting text in a file.
  39. # 3. Execute the file with /bin/sh to create the files:
  40. #    abcd.c
  41. #    abcd.h
  42. #    patchlevel.h
  43. #    Makefile
  44. #    README
  45. #    abcd.1
  46. # This archive created: Wed May 25 11:56:25 EST 1988
  47. #
  48. #
  49. export PATH; PATH=/bin:$PATH
  50. #
  51. if [ -f abcd.c ]
  52. then
  53. echo shar: will not over-write existing file abcd.c
  54. else
  55. echo shar: extracting 'abcd.c',    12906 characters
  56. cat > abcd.c <<'Funky_Stuff'
  57.  
  58. /*  abcd.c
  59.  *
  60.  *  This is an automatic backup copy daemon, which copies files from one
  61.  *  filestore area to another using either cp or rcp. Note the second filestore
  62.  *  area could be on another machine if the file system is NFS mounted.
  63.  *
  64.  *  This means that the backup disk should have an identical copy of the
  65.  *  filestore being monitored, give or take a little bit.
  66.  *
  67.  *  SWITCHES
  68.  *
  69.  *  -fdirectory  Directory to start copying from. Defaults to /usr.
  70.  *
  71.  *  -tdirectory  Directory to start copying to. Defaults to /usr2.
  72.  *
  73.  *  -rhostname   This is an alternative form of backup. Uses rcp and copies to
  74.  *               hostname supplied.
  75.  *
  76.  *  -sseconds    Specifies the sleep period in seconds for when the program puts
  77.  *               itself to sleep.
  78.  *
  79.  *  -c           If given, then abcd won't copy the first time through.
  80.  *
  81.  *  Copyright (c) Rich Burridge - Sun Microsystems Australia (Melbourne).
  82.  *
  83.  *  Version 1.1 - May 1988.
  84.  *
  85.  *  No responsibility is taken for any error in accuracies inherent
  86.  *  either to the comments or the code of this program, but if
  87.  *  reported to me then an attempt will be made to fix them.
  88.  */
  89.  
  90. #include <stdio.h>
  91. #include <strings.h>
  92. #include <errno.h>
  93. #include <signal.h>
  94. #include <sys/file.h>
  95. #include <sys/types.h>
  96. #include <sys/stat.h>
  97. #include <sys/dir.h>
  98. #include "patchlevel.h"
  99. #include "abcd.h"
  100.  
  101. char *malloc(), *sprintf() ;
  102.  
  103. struct finfo *cfile ;             /* Information on current file. */
  104. struct finfo *files  = NULL ;     /* Files being monitored. */
  105. struct dinfo *cdir ;              /* Pointer to current directory. */
  106. struct dinfo *dirs = NULL ;       /* Directories being monitored. */
  107. struct stat cstat ;               /* For statistics on current file. */
  108. struct direct *cur ;              /* Pointer to current directory record. */
  109.  
  110. extern int errno ;                /* Standard error reply. */
  111.  
  112. char cname[MAXLINE] ;             /* Copy program to use. */
  113. char coff[MAXLINE] ;              /* Name offset from initial start directory. */
  114. char curdir[MAXLINE] ;            /* Current directory being monitored. */
  115. char dbuf[DIRBLKSIZ] ;            /* Buffer for directory information. */
  116. char fdir[MAXLINE] ;              /* Directory to start copying from. */
  117. char flist[MAXFILES][MAXLINE] ;   /* Array of filenames to copy. */
  118. char fname[MAXLINE] ;             /* Full pathname of current file. */
  119. char pdir[MAXLINE] ;              /* Current directory for copy request. */
  120. char rhost[MAXLINE] ;             /* Name of remote host for use by rcp. */
  121. char tdir[MAXLINE] ;              /* Directory to start copying to. */
  122.  
  123. int copy_found  = 0 ;             /* Whether copy done on this pass. */
  124. int delay = 300 ;                 /* Sleep time for abcd in seconds. */
  125. int docopy = 1 ;                  /* Rcp files right from the beginning. */
  126. int fd = 0 ;                      /* File id of the directory being monitored. */
  127. int loc = 0 ;                     /* Current location in the directory block. */
  128. int fcnt = 0 ;                    /* Number of files to copy in current request. */
  129. int no_dirs = 1 ;                 /* Number of directories being monitored. */
  130. int size ;                        /* Size of current directory block in bytes. */ 
  131. int usercp = 0 ;                  /* Backup method, cp or rcp. */
  132.  
  133.  
  134. get_options(argc,argv)            /* Get abcd options from command line. */
  135. int argc ;
  136. char *argv[] ;
  137.  
  138. {
  139.   char *arg ;
  140.   char *p ;                  /* Pointer to string following argument flag. */
  141.  
  142.   STRCPY(fdir,"/usr") ;      /* Default directory to monitor. */
  143.   STRCPY(tdir,"/usr2") ;     /* Default directory to copy to. */
  144.   STRCPY(rhost,"") ;         /* Default is no remote host. */
  145.  
  146.   while (argc > 1 && (arg = argv[1])[0] == '-')
  147.     {
  148.       p = arg + 2 ;
  149.       switch (arg[1])
  150.         {
  151.           case 'c' : docopy = 0 ;           /* Don't copy files the first time. */
  152.                      break ;
  153.           case 'f' : STRCPY(fdir,p) ;       /* Directory to start monitoring from. */
  154.                      break ;
  155.           case 'r' : STRCPY(rhost,p) ;      /* Name of remote host. */
  156.                      usercp = 1 ;
  157.                      break ;
  158.           case 's' : delay = atoi(p) ;      /* Sleep period in seconds. */
  159.                      break ;
  160.           case 't' : STRCPY(tdir,p) ;       /* Directory to start copying to. */
  161.                      break ;
  162.           default  : FPRINTF(stderr,"USAGE: abcd [-c] [-ffromdir] [-rhostname]") ;
  163.                      FPRINTF(stderr," [-ssleep] [-ttodir]\n") ;
  164.                      exit(1) ;
  165.         }
  166.       argc-- ;
  167.       argv++ ;
  168.     }
  169. }
  170.  
  171.  
  172. setup()
  173.  
  174. {
  175.   dirs = (struct dinfo *) malloc(sizeof(struct dinfo)) ;
  176.   STRCPY(dirs->d_name,"") ;
  177.   STRCPY(pdir,fdir) ;                          /* Start directory for current cp request. */
  178.   STRCPY(coff,"") ;                            /* Name offset from start directory. */
  179.   if (usercp) STRCPY(cname,"/usr/ucb/rcp") ;   /* Used by the output routine. */
  180.   else STRCPY(cname,"/bin/cp") ;
  181.   dirs->next = dirs ;
  182.   cdir = dirs ;
  183. }
  184.  
  185.  
  186. get_next_dir()        /* Get next directory name to monitor. */
  187.  
  188. {
  189.   struct dinfo *temp ;
  190.   int dirfound ;
  191.  
  192.   dirfound = 0 ;
  193.   if (fd)
  194.     {
  195.       CLOSE(fd) ;
  196.       if (!strlen(cdir->next->d_name))     /* Complete pass done? */
  197.         {
  198.           docopy = 1 ;                     /* Always copy after first pass. */
  199.           if (!copy_found)
  200.             sleep((unsigned int) delay) ;  /* Nothing happening, go to sleep. */
  201.           else copy_found = 0 ;
  202.         }
  203.       if (strcmp(curdir,cdir->next->d_name) != 0)
  204.         if (fcnt) output("",REGULAR) ;
  205.     }
  206.   do
  207.     {
  208.       STRCPY(curdir,fdir) ;
  209.       if (strlen(cdir->next->d_name))
  210.         {
  211.           STRCAT(curdir,"/") ;
  212.           STRCAT(curdir,cdir->next->d_name) ;
  213.         }
  214.       STRCPY(coff,cdir->next->d_name) ;
  215.       if ((fd = open(curdir,0)) == -1)
  216.         {
  217.           if (EQUAL(curdir,fdir)) exit(0) ;  /* Nothing left to monitor. */
  218.           else
  219.             {
  220.               temp = cdir->next ;
  221.               if (cdir->next == dirs) dirs = cdir ;
  222.               cdir->next = cdir->next->next ;
  223.               free((char *) temp) ;                /* Lose this directory record. */
  224.               no_dirs-- ;
  225.             }
  226.         }
  227.       else dirfound = 1 ;     /* Directory found. */
  228.     }
  229.   while (!dirfound) ;
  230.   cdir = cdir->next ;         /* Point to current directory. */
  231.   loc = 0 ;                   /* Reset directory buffer pointer. */
  232. }
  233.  
  234.  
  235. make_dir_entry()       /* If not there already, create a new directory record. */
  236.  
  237. {
  238.   int i ;
  239.   char tempdir[MAXLINE] ;          /* Temporary directory name. */
  240.   struct dinfo *temp ;
  241.  
  242.   temp = cdir ;
  243.   for (i = 0; i < no_dirs; i++)    /* Is the directory already being monitored? */
  244.     {
  245.       temp = temp->next ;
  246.       STRCPY(tempdir,fdir) ;
  247.       if (strlen(temp->d_name))
  248.         {
  249.           STRCAT(tempdir,"/") ;
  250.           STRCAT(tempdir,temp->d_name) ;
  251.         }
  252.       if (EQUAL(tempdir,fname)) return(0) ;
  253.     }
  254.  
  255.   temp = (struct dinfo *) malloc(sizeof(struct dinfo)) ;
  256.   temp->next = dirs->next ;
  257.   dirs->next = temp ;
  258.   dirs = temp ;
  259.  
  260.   STRCPY(dirs->d_name,"") ;
  261.   if (strlen(coff))
  262.     {
  263.       STRCAT(dirs->d_name,coff) ;
  264.       STRCAT(dirs->d_name,"/") ;
  265.     }
  266.   STRCAT(dirs->d_name,cur->d_name) ;
  267.   no_dirs++ ;
  268.   return(1) ;
  269. }
  270.  
  271.  
  272. get_next_entry(fd)     /* Get next directory filename entry. */
  273. int fd ;
  274.  
  275. {
  276.   int tfd ;            /* Temporary file descriptor for file entry. */
  277.  
  278.   for (;;)
  279.     {
  280.       if (!loc)
  281.         if ((size = read(fd,dbuf,DIRBLKSIZ)) <= 0) return(0) ;
  282.       if (loc >= size)
  283.         {
  284.           loc = 0 ;
  285.           continue ;
  286.         }
  287.       cur = (struct direct *) (dbuf+loc) ;
  288.       if (cur->d_fileno == 0) return(0) ;
  289.       SPRINTF(fname,"%s/%s",curdir,cur->d_name) ;
  290.       if ((tfd = open(fname,0)) == -1)
  291.         {
  292.           loc += cur->d_reclen ;
  293.           continue ;
  294.         }
  295.       else
  296.         {
  297.           CLOSE(tfd) ;
  298.           cur = (struct direct *) malloc(sizeof(struct direct)) ;
  299.           bcopy(dbuf+loc,(char *) cur,(int) DIRSIZ((struct direct *)(dbuf+loc))) ;
  300.           loc += cur->d_reclen ;
  301.           STAT(fname,&cstat) ;
  302.           return(1) ;
  303.         }
  304.     }
  305. }
  306.  
  307.  
  308. no_record()     /* Check is this file is already being monitored. */
  309.  
  310. {
  311.   if (files == NULL) return(1) ;
  312.   cfile = files ;
  313.   do
  314.     if (cfile->direct->d_fileno == cur->d_fileno) return(0) ;
  315.   while ((cfile = cfile->next) != NULL) ;
  316.   return(1) ;
  317. }
  318.  
  319.  
  320. make_file_entry()      /* Make a record for this new file. */
  321.  
  322. {
  323.   struct finfo *temp ;
  324.  
  325.   if ((cstat.st_mode & S_IFMT) == REGULAR)
  326.     {
  327.       temp = (struct finfo *) malloc(sizeof(struct finfo)) ;
  328.       temp->next = files ;
  329.       files = temp ;
  330.  
  331.       files->direct = (struct direct *) malloc(sizeof(struct direct)) ;
  332.       files->direct = cur ;
  333.       files->mtime = cstat.st_mtime ;
  334.     }
  335. }
  336.  
  337.  
  338. file_modified()    /* Check if this file has been changed. */
  339.  
  340. {
  341.   if (cfile->mtime == cstat.st_mtime) return(0) ;
  342.   cfile->mtime = cstat.st_mtime ;
  343.   return(1) ;
  344. }
  345.  
  346.  
  347. copy(filetype)                     /* Copy file to another directory. */
  348. int filetype ;
  349.  
  350. {
  351.   char name[MAXLINE] ;
  352.  
  353.   if (docopy)     /* Are we copying this time around. */
  354.     {
  355.       copy_found = 1 ;
  356.       STRCPY(name,"") ;
  357.       if (strlen(coff))
  358.         {
  359.           STRCAT(name,coff) ;
  360.           STRCAT(name,"/") ;
  361.         }
  362.       STRCAT(name,cur->d_name) ;
  363.       if (strcmp(curdir,pdir) != 0)        /* Current dir. different from cp dir.? */
  364.         {
  365.           if (fcnt) output(name,REGULAR) ;
  366.           STRCPY(pdir,curdir) ;
  367.         }
  368.       if (filetype == DIRECTORY)
  369.         {
  370.           if (fcnt) output(name,REGULAR) ;
  371.           output(name,DIRECTORY) ;
  372.         }
  373.       else if (fcnt >= MAXFILES)           /* Room in file list for this filename? */
  374.         {
  375.           output(name,REGULAR) ;
  376.           STRCPY(flist[fcnt++],name) ;
  377.         }
  378.       else STRCPY(flist[fcnt++],name) ;   /* Save filename in file list. */
  379.     }
  380. }
  381.  
  382.  
  383. output(name,filetype)
  384. char name[MAXLINE] ;
  385. int filetype ;
  386.  
  387. {
  388.   char command[MAXLINE*7],rdirname[MAXLINE] ;
  389.   int i ;
  390.  
  391.   switch (filetype)
  392.     {
  393.       case DIRECTORY : if (usercp)
  394.                          SPRINTF(command,"%s -r %s/%s %s:%s",cname,fdir,name,rhost,curdir) ;
  395.                        else
  396.                          {
  397.                            STRCPY(rdirname,tdir) ;
  398.                            STRCAT(rdirname,"/") ;
  399.                            STRCAT(rdirname,name) ;
  400.                            if ((fd = open(rdirname,0)) == -1)
  401.                              SPRINTF(command,"mkdir %s",rdirname) ;
  402.                            else return ;
  403.                          }
  404.                        break ;
  405.       case REGULAR   : if (usercp) SPRINTF(rdirname,"%s:%s",rhost,curdir) ;
  406.                        else
  407.                          {
  408.                            STRCPY(rdirname,tdir) ;
  409.                            if (strlen(coff))
  410.                              {
  411.                                STRCAT(rdirname,"/") ;
  412.                                STRCAT(rdirname,coff) ;
  413.                              }
  414.                          }
  415.                        STRCPY(command,cname) ;
  416.                        for (i = 0; i < fcnt; i++)
  417.                          {
  418.                            STRCAT(command," ") ;
  419.                            STRCAT(command,fdir) ;
  420.                            STRCAT(command,"/") ;
  421.                            STRCAT(command,flist[i]) ;
  422.                          }
  423.                        STRCAT(command," ") ;
  424.                        STRCAT(command,rdirname) ;
  425.     }
  426.   if (system(command))
  427.     FPRINTF(stderr,"abcd failed: %s\n",command) ;
  428.   else FPRINTF(stderr,"abcd succeeded: %s\n",command) ;
  429.   FPRINTF(stderr,"\n\n\n") ;
  430.  
  431.   fcnt = 0 ;
  432. }
  433.  
  434.  
  435. main(argc,argv)
  436. int argc ;
  437. char *argv[] ;
  438.  
  439. {
  440.   get_options(argc,argv) ;               /* Get command line options. */
  441.   setup() ;                              /* Initialise parameters. */
  442.   while (MACHINE_WORKING)                /* Do it until the machine crashes. */
  443.     {
  444.       get_next_dir() ;                   /* Is there another directory? */
  445.         while (get_next_entry(fd))       /* Is there another file in dir? */
  446.           {
  447.             if (!DOTS(cur->d_name))      /* Is it the . or .. entry? */
  448.               {
  449.                 if (no_record())         /* Is this file already monitored? */
  450.                   {
  451.                     if ((cstat.st_mode & S_IFMT) == DIRECTORY)      /* Directory? */
  452.                       {
  453.                         if (make_dir_entry()) copy(DIRECTORY) ;
  454.                       }
  455.                     else
  456.                       {
  457.                         make_file_entry() ;      /* Make a file entry. */
  458.                         copy(REGULAR) ;          /* Copy it to backup machine. */
  459.                       }
  460.                   }
  461.                 else if (file_modified()) copy(REGULAR) ;   /* File been modified? */
  462.               }
  463.             else free((char *) cur) ;
  464.           }
  465.     }
  466. }
  467. Funky_Stuff
  468. len=`wc -c < abcd.c`
  469. if [ $len !=    12906 ] ; then
  470. echo error: abcd.c was $len bytes long, should have been    12906
  471. fi
  472. fi # end of overwriting check
  473. if [ -f abcd.h ]
  474. then
  475. echo shar: will not over-write existing file abcd.h
  476. else
  477. echo shar: extracting 'abcd.h',     1645 characters
  478. cat > abcd.h <<'Funky_Stuff'
  479.  
  480. /*  abcd.h
  481.  *
  482.  *  Definitions used by abcd, the automatic backup copy daemon.
  483.  *
  484.  *  Copyright (c) Rich Burridge - Sun Microsystems Australia (Melbourne).
  485.  * 
  486.  *  Version 1.1 - May 1988.
  487.  *
  488.  *  No responsibility is taken for any error in accuracies inherent
  489.  *  either to the comments or the code of this program, but if
  490.  *  reported to me then an attempt will be made to fix them.
  491.  */
  492.  
  493. #define  CLOSE            (void) close     /* To make lint happy. */
  494. #define  FPRINTF          (void) fprintf
  495. #define  SPRINTF          (void) sprintf
  496. #define  SIGNAL           (void) signal
  497. #define  STAT             (void) stat
  498. #define  STRCAT           (void) strcat
  499. #define  STRCPY           (void) strcpy
  500.  
  501. #define  DIRECTORY        S_IFDIR          /* Type of files being monitored. */
  502. #define  REGULAR          S_IFREG
  503.  
  504. #define  DIRBLKSIZ        512              /* Block size for directory read. */
  505. #define  DOTS(A)          (A[0] == '.' && (A[1] == 0 || (A[1] == '.' && A[2] == 0)))
  506. #define  EQUAL(a,b)       !strcmp(a,b)     /* Test for string equality. */
  507. #define  MACHINE_WORKING  1                /* Forever and a day .... */
  508. #define  MAXFILES         5                /* Max no of files to copy in one go. */
  509. #define  MAXLINE          MAXNAMLEN+1      /* Maximum length of path names. */
  510.  
  511.  
  512. struct dinfo             /* Info record for directories being monitored. */
  513.          {
  514.            struct dinfo *next ;
  515.            char d_name[MAXLINE] ;
  516.          } ;
  517.  
  518. struct finfo            /* Information record for monitored files. */
  519.          {
  520.            struct finfo *next ;
  521.            struct direct *direct ;
  522.            time_t mtime ;
  523.           } ;
  524. Funky_Stuff
  525. len=`wc -c < abcd.h`
  526. if [ $len !=     1645 ] ; then
  527. echo error: abcd.h was $len bytes long, should have been     1645
  528. fi
  529. fi # end of overwriting check
  530. if [ -f patchlevel.h ]
  531. then
  532. echo shar: will not over-write existing file patchlevel.h
  533. else
  534. echo shar: extracting 'patchlevel.h',      443 characters
  535. cat > patchlevel.h <<'Funky_Stuff'
  536.  
  537. /*  patchlevel.h
  538.  *
  539.  *  This is the current patch level for this version of abcd.
  540.  *
  541.  *  Copyright (c) Rich Burridge - May 1988.
  542.  *              Sun Microsystems, Australia - All rights reserved.
  543.  *
  544.  *  Version 1.1.
  545.  *
  546.  *  No responsibility is taken for any errors or inaccuracies inherent
  547.  *  either to the comments or the code of this program, but if
  548.  *  reported to me then an attempt will be made to fix them.
  549.  */
  550.  
  551. #define  PATCHLEVEL  0
  552. Funky_Stuff
  553. len=`wc -c < patchlevel.h`
  554. if [ $len !=      443 ] ; then
  555. echo error: patchlevel.h was $len bytes long, should have been      443
  556. fi
  557. fi # end of overwriting check
  558. if [ -f Makefile ]
  559. then
  560. echo shar: will not over-write existing file Makefile
  561. else
  562. echo shar: extracting 'Makefile',      955 characters
  563. cat > Makefile <<'Funky_Stuff'
  564. #
  565. #  Makefile for abcd, an automatic backup copy daemon.
  566. #
  567. #  Copyright (c) Rich Burridge - Sun Microsystems Australia (Melbourne).
  568. #
  569. #  Version 1.1 - May 1988.
  570. #
  571. #  No responsibility is taken for any errors inherent either in the comments
  572. #  or the code of this program, but if reported to me then an attempt will
  573. #  be made to fix them.
  574. #
  575.  
  576. BINARIES        = abcd
  577. BINDIR          = .
  578. CFLAGS          = -g
  579. LDFLAGS         = -g
  580. OBJS            = abcd.o
  581. SRCS            = abcd.c
  582. HDRS            = abcd.h patchlevel.h
  583. LIBS            =
  584. OTHERS          = Makefile README abcd.1
  585.  
  586. all:            $(BINARIES)
  587.  
  588. release:        $(BINARIES)
  589.         strip $(BINARIES)
  590.         mv $(BINARIES) $(BINDIR)
  591.  
  592. backup:
  593.         cp abcd.c abcd.c~
  594.         cp abcd.h abcd.h~
  595.  
  596. shar:;          shar.script $(SRCS) $(HDRS) $(OTHERS) > archive
  597.  
  598. clean:
  599.         rm -f abcd *.o *.c~ core
  600.  
  601. lint:
  602.         lint $(SRCS) $(LIBS)
  603.  
  604. abcd:           $(OBJS)
  605.         cc $(LDFLAGS) -o abcd $(OBJS) $(LIBS)
  606.  
  607. abcd.o:         abcd.c $(HDRS)
  608. Funky_Stuff
  609. len=`wc -c < Makefile`
  610. if [ $len !=      955 ] ; then
  611. echo error: Makefile was $len bytes long, should have been      955
  612. fi
  613. fi # end of overwriting check
  614. if [ -f README ]
  615. then
  616. echo shar: will not over-write existing file README
  617. else
  618. echo shar: extracting 'README',     2345 characters
  619. cat > README <<'Funky_Stuff'
  620.  
  621.   ABCD v1.1 - May 1988.
  622.   ---------------------
  623.  
  624.   This is an automatic backup copy daemon, which copies files from one
  625.   filestore area to another using either cp or rcp. Note the second filestore
  626.   area could be on another machine if the file system is NFS mounted.
  627.  
  628.   This means that the backup machine should have an identical copy of the
  629.   filestore being monitored, give or take a little bit.
  630.  
  631.   NOTES
  632.  
  633.   (1) A start directory for monitoring is given. All the files including
  634.       sub-directories and their files are monitored. Whenever any one of
  635.       them is changed it is automatically copied to another machine as
  636.       specified by the initial parameters to the program.
  637.  
  638.   (2) If it finds a new directory, then it will make that new directory
  639.       in the other area (on the other machine) if not present.
  640.  
  641.   (3) If a sub-directory is deleted, then that directory is removed from
  642.       the list of directories being monitored. If the original start directory
  643.       is removed, then the program terminates because there is nothing left
  644.       to monitor.
  645.  
  646.   (4) If nothing has changed in one complete pass of all the directories
  647.       been monitored, then the program puts itself to sleep for 5 minutes.
  648.  
  649.   (5) There is a restart facility whereby if the machine has crashed, then it
  650.       is possible to tell the program not to copy anything for the first pass,
  651.       but to start copying changed files from the second pass onwards.
  652.  
  653.   (6) Abcd uses the "system" system call to do its copying, so as to prevent
  654.       hundreds or child processes being spawned.
  655.  
  656.   SWITCHES
  657.  
  658.   -fdirectory  Directory to start copying from. Defaults to /usr.
  659.  
  660.   -tdirectory  Directory to start copying to. Defaults to /usr2.
  661.  
  662.   -rhostname   This is an alternative form of backup. Uses rcp and copies to
  663.                hostname supplied.
  664.  
  665.   -sseconds    Specifies the sleep period in seconds for when the program puts
  666.                itself to sleep.
  667.  
  668.   -c           If given, then abcd won't copy the first time through.
  669.  
  670.  
  671.   Suggestions, comments, flames and bugs to me please.
  672.  
  673.       Rich.
  674.  
  675. Rich Burridge,           JANET richb%sunaus.oz@uk.ac.ucl.cs
  676. ACSnet  richb@sunaus.oz  UUCP {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  677. PHONE: +61 2 436 4699    ARPAnet rburridge@Sun.COM
  678. Sun Microsystems, Unit 2, 49-53 Hotham Pde, Artarmon, N.S.W. 2164, AUSTRALIA.
  679. Funky_Stuff
  680. len=`wc -c < README`
  681. if [ $len !=     2345 ] ; then
  682. echo error: README was $len bytes long, should have been     2345
  683. fi
  684. fi # end of overwriting check
  685. if [ -f abcd.1 ]
  686. then
  687. echo shar: will not over-write existing file abcd.1
  688. else
  689. echo shar: extracting 'abcd.1',     2407 characters
  690. cat > abcd.1 <<'Funky_Stuff'
  691. .\" @(#)abcd.1 1.1 25/05/88;
  692. .TH ABCD 1L "25 May 1988"
  693. .SH NAME
  694. abcd \- automatic backup copy daemon
  695. .SH SYNOPSIS
  696. .B "abcd
  697. [
  698. .B -f
  699. .I directory
  700. ]
  701. [
  702. .B -t
  703. .I directory
  704. ]
  705. [
  706. .B -r
  707. .I hostname
  708. ]
  709. [
  710. .B -s
  711. .I seconds
  712. ]
  713. [
  714. .B -c
  715. ]
  716. .SH DESCRIPTION
  717. .I Abcd
  718. is an automatic backup copy daemon, which copies files from one
  719. filestore area to another using either cp or rcp. Note the second filestore
  720. area could be on another machine if the file system is NFS mounted.
  721. .LP
  722. This means that the backup machine should have an almost identical copy
  723. of the filestore being monitored.
  724. .LP
  725. A start directory for monitoring is given. All the files including
  726. sub-directories and their files are monitored. Whenever any one of
  727. them is changed it is automatically copied to another machine as
  728. specified by the initial parameters to the program.
  729. .LP
  730. If it finds a new directory, then it will make that new directory
  731. in the other area if not present.
  732. .LP
  733. If a sub-directory is deleted, then that directory is removed from
  734. the list of directories being monitored. If the original start directory
  735. is removed, then the program terminates because there is nothing left
  736. to monitor.
  737. .LP
  738. If nothing has changed in one complete pass of all the directories
  739. been monitored, then the program puts itself to sleep for a specified
  740. period.
  741. .LP
  742. There is a restart facility whereby if the machine has crashed, then it
  743. is possible to tell the program not to copy anything for the first pass,
  744. but to start copying changed files from the second pass onwards.
  745. .SH OPTIONS
  746. .TP
  747. .BI -f "directory"
  748. Directory to start copying from. Defaults to /usr.
  749. .TP
  750. .BI -t "directory"
  751. Directory to start copying to. Defaults to /usr2.
  752. .TP
  753. .BI -r "hostname"
  754. This is an alternative form of backup. Uses rcp and copies to
  755. hostname supplied.
  756. .TP
  757. .BI -s "seconds"
  758. Specifies the sleep period in seconds for when the program puts
  759. itself to sleep. Default is 5 minutes.
  760. .TP
  761. .B -c
  762. If given, then abcd won't copy the first time through.
  763. .SH BUGS
  764. This program is currently totally inpractical for monitoring filestore
  765. areas containing large files which are being continuously updated, such
  766. as databases.
  767. .SH AUTHOR
  768. Rich Burridge, Sun Microsystems, Unit 2, 49-53 Hotham Pde, Artarmon, N.S.W.
  769. 2164, AUSTRALIA.  PHONE: +61 2 436 4699
  770. .nf
  771. JANET: richb%sunaus.oz@uk.ac.ucl.cs
  772. ACSnet:  richb@sunaus.oz
  773. UUCP: {uunet,hplabs,mcvax,ukc}!munnari!sunaus.oz!richb
  774. ARPAnet: rburridge@Sun.COM
  775. .fi
  776. Funky_Stuff
  777. len=`wc -c < abcd.1`
  778. if [ $len !=     2407 ] ; then
  779. echo error: abcd.1 was $len bytes long, should have been     2407
  780. fi
  781. fi # end of overwriting check
  782.