home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / compsrcs / misc / volume10 / abcd12 < prev    next >
Encoding:
Internet Message Format  |  1991-08-27  |  30.7 KB

  1. From decwrl!shlump.nac.dec.com!decuac!haven!purdue!tut.cis.ohio-state.edu!cs.utexas.edu!uunet!allbery Fri Jan 19 13:49:27 PST 1990
  2. Article 1282 of comp.sources.misc:
  3. Path: decwrl!shlump.nac.dec.com!decuac!haven!purdue!tut.cis.ohio-state.edu!cs.utexas.edu!uunet!allbery
  4. From: richb@Aus.Sun.COM (Rich Burridge)
  5. Newsgroups: comp.sources.misc
  6. Subject: v10i012: abcd V1.2 - an automatic backup copy daemon (Part 1 of 1).
  7. Message-ID: <77010@uunet.UU.NET>
  8. Date: 16 Jan 90 00:04:51 GMT
  9. Sender: allbery@uunet.UU.NET
  10. Lines: 993
  11. Approved: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  12.  
  13. Posting-number: Volume 10, Issue 12
  14. Submitted-by: richb@Aus.Sun.COM (Rich Burridge)
  15. Archive-name: abcd12
  16.  
  17. Abcd - Version 1.2 January 1989.
  18.  
  19. Permission is given to distribute these sources, as long as the
  20. copyright messages are not removed, and no monies are exchanged.
  21.  
  22. This is the second general release of an automatic backup copy daemon, which
  23. copies files from one filestore area to another using either cp or rcp. Note
  24. the second filestore area could be on another machine if the file system is
  25. NFS mounted.
  26.  
  27. This means that the backup machine should have an identical copy of the
  28. filestore being monitored, give or take a little bit.
  29.  
  30. See the README file and the manual pages for more details.
  31.  
  32. I welcome bug reports and suggestions for improvements.
  33.  
  34. Rich Burridge,          DOMAIN: richb@sunaus.oz.au
  35. PHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  36.  
  37. ---- Cut Here and unpack ----
  38. #!/bin/sh
  39. # shar:    Shell Archiver  (v1.22)
  40. #    Packed Tue Jan  9 12:42:02 EST 1990 by stard!richb
  41. #    from directory /extra/richb/rich_stuff/abcd
  42. #
  43. #                                                                          
  44. #                                                                          
  45. #
  46. #    Run the following text with /bin/sh to create:
  47. #      README
  48. #      Makefile
  49. #      abcd.c
  50. #      ndir.c
  51. #      abcd.h
  52. #      ndir.h
  53. #      patchlevel.h
  54. #      abcd.1
  55. #
  56. if test -r s2_seq_.tmp
  57. then echo "Must unpack archives in sequence!"
  58.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  59.      exit 1; fi
  60. echo "x - extracting README (Text)"
  61. sed 's/^X//' << 'SHAR_EOF' > README &&
  62. X
  63. XREADME for abcd, an automatic backup copy daemon.
  64. X
  65. XVersion 1.2 January 1989.
  66. X
  67. XPermission is given to distribute these sources, as long as the
  68. Xcopyright messages are not removed, and no monies are exchanged.
  69. X
  70. XThis is the second general release of an automatic backup copy daemon, which
  71. Xcopies files from one filestore area to another using either cp or rcp. Note
  72. Xthe second filestore area could be on another machine if the file system is
  73. XNFS mounted.
  74. X
  75. XThis means that the backup machine should have an identical copy of the
  76. Xfilestore being monitored, give or take a little bit.
  77. X
  78. X
  79. XThe original version of this was written in November 1985, and the first
  80. Xgeneral release was made available in May 1988. This version contains a
  81. Xrewrite of the directory reading routines to try to make the code more
  82. Xportable, plus a general tidy up. It has been tested on SunOS v4.0, and
  83. XSCO Xenix 286 (v2.2.3).  I would be interested to here from people who port
  84. Xit to other Unix machines.
  85. X
  86. XI welcome bug reports and suggestions for improvements.
  87. X
  88. X
  89. XAcknowledgements.
  90. X
  91. XMany thanks go to Po Cheung Ng (Andrew) <pcng@cad.jmrc.eecs.unsw.oz> who
  92. Xported abcd to SCO Xenix 286 (v2.2.3), fixing several memory leaks in the
  93. Xprocess.
  94. X
  95. X      Rich.
  96. X
  97. XRich Burridge,          DOMAIN: richb@sunaus.oz.au
  98. XPHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  99. SHAR_EOF
  100. chmod 0444 README || echo "restore of README fails"
  101. set `wc -c README`;Sum=$1
  102. if test "$Sum" != "1345"
  103. then echo original size 1345, current size $Sum;fi
  104. echo "x - extracting Makefile (Text)"
  105. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  106. X#
  107. X#  Makefile for abcd, an automatic backup copy daemon.
  108. X#
  109. X#  @(#)Makefile 1.4 89/04/10
  110. X#
  111. X#  Copyright (c) Rich Burridge.
  112. X#                Sun Microsystems Australia - All rights reserved.
  113. X#
  114. X#  Permission is given to distribute these sources, as long as the
  115. X#  copyright messages are not removed, and no monies are exchanged.
  116. X#
  117. X#  No responsibility is taken for any errors inherent either in the comments
  118. X#  or the code of this program, but if reported to me then an attempt will
  119. X#  be made to fix them.
  120. X#
  121. X#-----------------------------------------------------------------------
  122. X#  Abcd has been written to work in both BSD and System V environments.
  123. X#  If you are running on a BSD4.[23] machine or under SunOS, then OSTYPE
  124. X#  should be commented out. If you are running under SysV, V7 or BSD4.1,
  125. X#  then OSTYPE should be set to -DSYSV (uncommented).
  126. X# 
  127. X#OSTYPE          = -DSYSV 
  128. X#-----------------------------------------------------------------------
  129. X#  If you are running abcd under SCO Xenix 286, then you should have
  130. X#  uncommented the OSTYPE declaration above. You also need to uncomment
  131. X#  the following two lines.
  132. X#
  133. X#X_CFLAGS        = -M21 -K
  134. X#X_LIBS          = -lx
  135. X#-----------------------------------------------------------------------
  136. X
  137. XBINARIES        = abcd
  138. XBINDIR          = /usr/local/bin
  139. XMANDIR          = /usr/man/man$(MANSECT)
  140. XMANSECT         = l
  141. XCFLAGS          = $(X_CFLAGS) -g $(OSTYPE) -DCP=\"$(CP)\" -DRCP=\"$(RCP)\"
  142. XOBJS            = abcd.o
  143. XSRCS            = abcd.c ndir.c
  144. XHDRS            = abcd.h ndir.h patchlevel.h
  145. XLIBS            = $(X_LIBS)
  146. XOTHERS          = Makefile README abcd.1
  147. X
  148. X#  Full pathnames for the cp and rcp commands.
  149. XCP              = /bin/cp
  150. XRCP             = /usr/ucb/rcp
  151. X
  152. Xall:            $(BINARIES)
  153. X
  154. Xabcd:           $(OBJS)
  155. X        cc -o abcd $(CFLAGS) $(OBJS) $(LIBS)
  156. X
  157. Xinstall:        $(BINARIES)
  158. X        install -s -m 751 abcd $(BINDIR)
  159. X        install -c -m 644 abcd.1 $(MANDIR)/abcd.$(MANSECT)
  160. X
  161. Xbackup:;        cp $(SRCS) $(HDRS) $(OTHERS) backdir
  162. X
  163. Xshar:;          shar.script $(SRCS) $(HDRS) $(OTHERS) > archive
  164. X
  165. Xclean:;        rm -f abcd *.o core
  166. X
  167. Xlint:;        lint abcd.c $(LIBS)
  168. X
  169. Xcreate:         SCCS
  170. X        -sccs create $(SRCS) $(HDRS) $(OTHERS)
  171. X
  172. XSCCS:
  173. X        mkdir SCCS
  174. X        chmod 755 SCCS
  175. X
  176. Xabcd.o:         abcd.c $(HDRS)
  177. SHAR_EOF
  178. chmod 0444 Makefile || echo "restore of Makefile fails"
  179. set `wc -c Makefile`;Sum=$1
  180. if test "$Sum" != "2237"
  181. then echo original size 2237, current size $Sum;fi
  182. echo "x - extracting abcd.c (Text)"
  183. sed 's/^X//' << 'SHAR_EOF' > abcd.c &&
  184. X#ifndef lint
  185. Xstatic char sccsid[] = "@(#)abcd.c 1.4 89/04/10" ;
  186. X#endif
  187. X
  188. X/*  This is an automatic backup copy daemon, which copies files from one
  189. X *  filestore area to another using either cp or rcp. Note the second
  190. X *  filestore area could be on another machine if the file system is NFS
  191. X *  mounted.
  192. X *
  193. X *  This means that the backup disk should have an identical copy of the
  194. X *  filestore being monitored, give or take a little bit.
  195. X *
  196. X *  Copyright (c) Rich Burridge.
  197. X *                Sun Microsystems Australia - All rights reserved.
  198. X *
  199. X *  Permission is given to distribute these sources, as long as the
  200. X *  copyright messages are not removed, and no monies are exchanged.
  201. X *
  202. X *  No responsibility is taken for any error in accuracies inherent
  203. X *  either to the comments or the code of this program, but if
  204. X *  reported to me then an attempt will be made to fix them.
  205. X */
  206. X
  207. X#include <stdio.h>
  208. X
  209. X#ifdef SYSV
  210. X#include <string.h>
  211. X#include <fcntl.h>
  212. X#else  SYSV
  213. X#include <strings.h>
  214. X#include <sys/file.h>
  215. X#endif SYSV
  216. X
  217. X#include <errno.h>
  218. X#include <signal.h>
  219. X#include <sys/types.h>
  220. X#include <sys/stat.h>
  221. X
  222. X#ifdef SYSV
  223. X#ifdef M_XENIX
  224. X#include <sys/ndir.h>
  225. X#define  dirent    direct
  226. X#define  d_fileno  d_ino
  227. X#else  M_XENIX
  228. X#include <sys/param.h>
  229. X#include "ndir.h"
  230. X#endif M_XENIX
  231. X#include <memory.h>
  232. X#define  bcopy(s1, s2, n)  memcpy(s2, s1, n)
  233. X#else  SYSV
  234. X#include <dirent.h>
  235. Xchar *sprintf() ;
  236. X#endif SYSV
  237. X
  238. X#include "patchlevel.h"
  239. X#include "abcd.h"
  240. X
  241. Xchar *malloc() ;
  242. X
  243. XDIR *dirp ;                      /* Stream for monitored directory. */
  244. X
  245. Xstruct finfo *cfile ;            /* Information on current file. */
  246. Xstruct finfo *files  = NULL ;    /* Files being monitored. */
  247. Xstruct dinfo *cdir ;             /* Pointer to current directory. */
  248. Xstruct dinfo *dirs = NULL ;      /* Directories being monitored. */
  249. Xstruct stat cstat ;              /* For statistics on current file. */
  250. Xstruct dirent *cur ;             /* Pointer to current directory record. */
  251. X
  252. Xextern int errno ;               /* Standard error reply. */
  253. X
  254. Xchar cname[MAXLINE] ;            /* Copy program to use. */
  255. Xchar coff[MAXLINE] ;             /* Name offset from initial start directory. */
  256. Xchar cp_name[MAXLINE] ;          /* Location of "cp" copy program. */
  257. Xchar curdir[MAXLINE] ;           /* Current directory being monitored. */
  258. Xchar fdir[MAXLINE] ;             /* Directory to start copying from. */
  259. Xchar flist[MAXFILES][MAXLINE] ;  /* Array of filenames to copy. */
  260. Xchar fname[MAXLINE] ;            /* Full pathname of current file. */
  261. Xchar pdir[MAXLINE] ;             /* Current directory for copy request. */
  262. Xchar progname[MAXLINE] ;         /* Name of this program. */
  263. Xchar rcp_name[MAXLINE] ;         /* Location of "rcp" copy program. */
  264. Xchar rhost[MAXLINE] ;            /* Name of remote host for use by rcp. */
  265. Xchar tdir[MAXLINE] ;             /* Directory to start copying to. */
  266. X
  267. Xint copy_found  = 0 ;            /* Whether copy done on this pass. */
  268. Xint debug = 0 ;                  /* If set, status information is given. */
  269. Xint delay = 300 ;                /* Sleep time for program in seconds. */
  270. Xint docopy = 1 ;                 /* Rcp files right from the beginning. */
  271. Xint loc = 0 ;                    /* Current location in the directory block. */
  272. Xint fcnt = 0 ;                   /* No. of files to copy in current request. */
  273. Xint fd ;                         /* File descriptor for various opens. */
  274. Xint no_dirs = 1 ;                /* Number of directories being monitored. */
  275. Xint usercp = 0 ;                 /* Backup method, cp or rcp. */
  276. X
  277. X
  278. Xmain(argc,argv)
  279. Xint argc ;
  280. Xchar *argv[] ;
  281. X{
  282. X  STRCPY(progname, argv[0]) ;    /* Save this programs name. */
  283. X  get_options(argc,argv) ;       /* Get command line options. */
  284. X  setup() ;                      /* Initialise parameters. */
  285. X  while (1)                      /* Do it forever. */
  286. X    {
  287. X      get_next_dir() ;           /* Is there another directory? */
  288. X      while (get_next_entry())   /* Is there another file in directory? */
  289. X        {
  290. X          if (!DOTS(cur->d_name))  /* Is it the . or .. entry? */
  291. X            {
  292. X              if (no_record())     /* Is this file already monitored? */
  293. X                {
  294. X                  if ((cstat.st_mode & S_IFMT) == DIRECTORY)  /* Directory? */
  295. X                    {
  296. X                      if (make_dir_entry())
  297. X                        {
  298. X                          copy(DIRECTORY) ;
  299. X                          free((char *) cur) ;
  300. X                        }
  301. X                    }
  302. X                  else
  303. X                    {
  304. X                      make_file_entry() ;   /* Make a file entry. */
  305. X                      copy(REGULAR) ;       /* Copy it to backup machine. */
  306. X                    }
  307. X                }     
  308. X              else if (file_modified())
  309. X                {
  310. X                  copy(REGULAR) ;           /* File been modified? */
  311. X                  free((char *) cur) ;
  312. X                }
  313. X              else free((char *) cur) ;
  314. X            }
  315. X          else free((char *) cur) ;
  316. X        }
  317. X    }
  318. X}
  319. X
  320. X
  321. X/*  Use the portable BSD directory emulation routines if this is System V. */
  322. X
  323. X#ifdef SYSV
  324. X#ifndef  M_XENIX
  325. X#include "ndir.c"
  326. X#endif   M_XENIX
  327. X#endif SYSV
  328. X
  329. X
  330. Xchar *
  331. XMalloc(n)
  332. Xint n ;
  333. X{
  334. X  char *val ;
  335. X
  336. X  if ((val = malloc((unsigned) n)) == NULL)
  337. X    FPRINTF(stderr,"%s: Out of memory.\n", progname) ;
  338. X  return val ;
  339. X}
  340. X
  341. X
  342. Xcopy(filetype)           /* Copy file to another directory. */
  343. Xint filetype ;
  344. X{
  345. X  char name[MAXLINE] ;
  346. X
  347. X  if (docopy)            /* Are we copying this time around. */
  348. X    {
  349. X      copy_found = 1 ;
  350. X      STRCPY(name, "") ;
  351. X      if (strlen(coff))
  352. X        {
  353. X          STRCAT(name, coff) ;
  354. X          STRCAT(name, "/") ;
  355. X        }
  356. X      STRCAT(name, cur->d_name) ;
  357. X      if (strcmp(curdir, pdir) != 0)  /* This directory != copy directory? */
  358. X        {
  359. X          if (fcnt) output(name, REGULAR) ;
  360. X          STRCPY(pdir, curdir) ;
  361. X        }
  362. X      if (filetype == DIRECTORY)
  363. X        {
  364. X          if (fcnt) output(name, REGULAR) ;
  365. X          output(name, DIRECTORY) ;
  366. X        }
  367. X      else if (fcnt >= MAXFILES)     /* Room in file list for this filename? */
  368. X        {
  369. X          output(name, REGULAR) ;
  370. X          STRCPY(flist[fcnt++], name) ;
  371. X        }
  372. X      else STRCPY(flist[fcnt++], name) ;   /* Save filename in file list. */
  373. X    }
  374. X}
  375. X
  376. X
  377. Xfile_modified()    /* Check if this file has been changed. */
  378. X{
  379. X  if (cfile->mtime == cstat.st_mtime) return(0) ;
  380. X  cfile->mtime = cstat.st_mtime ;
  381. X  return(1) ;
  382. X}
  383. X
  384. X
  385. Xget_next_dir()     /* Get next directory name to monitor. */
  386. X{
  387. X  struct dinfo *temp ;
  388. X  int dirfound ;
  389. X
  390. X  dirfound = 0 ;
  391. X  if (dirp)
  392. X    {
  393. X      CLOSEDIR(dirp) ;
  394. X      if (!strlen(cdir->next->d_name))     /* Complete pass done? */
  395. X        {
  396. X          docopy = 1 ;                     /* Always copy after first pass. */
  397. X          if (!copy_found)
  398. X            sleep((unsigned int) delay) ;  /* Nothing doing so go to sleep. */
  399. X          else copy_found = 0 ;
  400. X        }
  401. X      if (strcmp(curdir, cdir->next->d_name) != 0)
  402. X        if (fcnt) output("", REGULAR) ;
  403. X    }
  404. X  while (!dirfound)
  405. X    {
  406. X      STRCPY(curdir, fdir) ;
  407. X      if (strlen(cdir->next->d_name))
  408. X        {
  409. X          STRCAT(curdir, "/") ;
  410. X          STRCAT(curdir, cdir->next->d_name) ;
  411. X        }
  412. X      STRCPY(coff, cdir->next->d_name) ;
  413. X      if ((dirp = opendir(curdir)) == NULL)
  414. X        {
  415. X          if (EQUAL(curdir, fdir)) exit(0) ;  /* Nothing left to monitor. */
  416. X          else
  417. X            {
  418. X              temp = cdir->next ;
  419. X              if (cdir->next == dirs) dirs = cdir ;
  420. X              cdir->next = cdir->next->next ;
  421. X              free((char *) temp) ;           /* Lose this directory record. */
  422. X              no_dirs-- ;
  423. X            }
  424. X        }
  425. X      else dirfound = 1 ;     /* Directory found. */
  426. X    }
  427. X  cdir = cdir->next ;         /* Point to current directory. */
  428. X  loc = 0 ;                   /* Reset directory buffer pointer. */
  429. X}
  430. X
  431. X
  432. Xget_next_entry()         /* Get next directory filename entry. */
  433. X{
  434. X  struct dirent *temp ;  /* Pointer to next directory entry. */
  435. X
  436. X  for (;;)
  437. X    {
  438. X      if ((temp = readdir(dirp)) == NULL) return(0) ;
  439. X      if (temp->d_fileno == 0) return(0) ;
  440. X      SPRINTF(fname, "%s/%s", curdir, temp->d_name) ;
  441. X      if ((fd = open(fname, O_RDONLY)) != -1)
  442. X        {
  443. X          CLOSE(fd) ;
  444. X          cur = (struct dirent *) Malloc(sizeof(struct dirent)) ;
  445. X          bcopy((char *) temp, (char *) cur, (int) DIRSIZ(temp)) ;
  446. X          STAT(fname, &cstat) ;
  447. X          return(1) ;
  448. X        }
  449. X    }
  450. X}
  451. X
  452. X
  453. Xget_options(argc,argv)     /* Read and process command line options. */
  454. Xint argc ;
  455. Xchar *argv[] ;
  456. X{
  457. X  char next[MAXLINE] ;     /* The next command line parameter. */
  458. X
  459. X  STRCPY(fdir, "/usr") ;   /* Default directory to monitor. */
  460. X  STRCPY(tdir, "/usr2") ;  /* Default directory to copy to. */
  461. X  STRCPY(rhost, "") ;      /* Default is no remote host. */
  462. X
  463. X  INC ;
  464. X  while (argc > 0)
  465. X    {
  466. X      if (argv[0][0] == '-')
  467. X        switch (argv[0][1])
  468. X          {
  469. X            case 'c' : docopy = 0 ;        /* Don't copy files first time. */
  470. X                       break ;
  471. X            case 'd' : debug = 1 ;         /* Print status information. */
  472. X                       break ;
  473. X            case 'f' : INC ;               /* Start directory to monitor. */
  474. X                       getparam(fdir, argv, "-f needs start directory") ;
  475. X                       break ;
  476. X            case 'r' : INC ;               /* Name of remote host. */
  477. X                       getparam(rhost, argv, "-r needs remote host") ;
  478. X                       usercp = 1 ;
  479. X                       break ;
  480. X            case 's' : INC ;               /* Sleep period in seconds. */
  481. X                       getparam(next, argv, "-s needs sleep period") ;
  482. X                       delay = atoi(next) ;
  483. X                       break ;
  484. X            case 't' : INC ;               /* Directory to start copying to. */
  485. X                       getparam(tdir, argv, "-t needs directory to copy to") ;
  486. X                       break ;
  487. X            case 'v' : FPRINTF(stderr,"%s version 1.2.%1d\n",
  488. X                                      progname, PATCHLEVEL) ;
  489. X                       exit(1) ;
  490. X            default  : FPRINTF(stderr,"Usage: %s [-c] [-f fromdir]", progname) ;
  491. X                       FPRINTF(stderr," [-r hostname] [-s sleep] ") ;
  492. X                       FPRINTF(stderr," [-t todir] [-v]\n") ;
  493. X                       exit(1) ;
  494. X          }
  495. X      INC ;
  496. X    }
  497. X}
  498. X
  499. X
  500. Xgetparam(s, argv, errmes)
  501. Xchar *s, *argv[], *errmes ;
  502. X{
  503. X  if (*argv != NULL && argv[0][0] != '-') STRCPY(s, *argv) ;
  504. X  else
  505. X    { 
  506. X      FPRINTF(stderr,"%s: %s as next argument.\n", progname, errmes) ;
  507. X      exit(1) ;
  508. X    }
  509. X}
  510. X
  511. X
  512. Xmake_dir_entry()    /* If not there already, create a new directory record. */
  513. X{
  514. X  int i ;
  515. X  char tempdir[MAXLINE] ;          /* Temporary directory name. */
  516. X  struct dinfo *temp ;
  517. X
  518. X  temp = cdir ;
  519. X  for (i = 0; i < no_dirs; i++)    /* Directory already being monitored? */
  520. X    {
  521. X      temp = temp->next ;
  522. X      STRCPY(tempdir, fdir) ;
  523. X      if (strlen(temp->d_name))
  524. X        {
  525. X          STRCAT(tempdir, "/") ;
  526. X          STRCAT(tempdir, temp->d_name) ;
  527. X        }
  528. X      if (EQUAL(tempdir, fname)) return(0) ;
  529. X    }
  530. X
  531. X  temp = (struct dinfo *) Malloc(sizeof(struct dinfo)) ;
  532. X  temp->next = dirs->next ;
  533. X  dirs->next = temp ;
  534. X  dirs = temp ;
  535. X
  536. X  STRCPY(dirs->d_name, "") ;
  537. X  if (strlen(coff))
  538. X    {
  539. X      STRCAT(dirs->d_name, coff) ;
  540. X      STRCAT(dirs->d_name, "/") ;
  541. X    }
  542. X  STRCAT(dirs->d_name, cur->d_name) ;
  543. X  no_dirs++ ;
  544. X  return(1) ;
  545. X}
  546. X
  547. X
  548. Xmake_file_entry()      /* Make a record for this new file. */
  549. X{
  550. X  struct finfo *temp ;
  551. X
  552. X  if ((cstat.st_mode & S_IFMT) == REGULAR)
  553. X    {
  554. X      temp = (struct finfo *) Malloc(sizeof(struct finfo)) ;
  555. X      temp->next = files ;
  556. X      files = temp ;
  557. X
  558. X      files->dirent = cur ;
  559. X      files->mtime = cstat.st_mtime ;
  560. X    }
  561. X}
  562. X
  563. X
  564. Xno_record()     /* Check is this file is already being monitored. */
  565. X{
  566. X  if (files == NULL) return(1) ;
  567. X  cfile = files ;
  568. X  do
  569. X    if (cfile->dirent->d_fileno == cur->d_fileno) return(0) ;
  570. X  while ((cfile = cfile->next) != NULL) ;
  571. X  return(1) ;
  572. X}
  573. X
  574. X
  575. Xoutput(name,filetype)
  576. Xchar name[MAXLINE] ;
  577. Xint filetype ;
  578. X{
  579. X  char command[MAXLINE*7], rdirname[MAXLINE] ;
  580. X  int i ;
  581. X
  582. X  switch (filetype)
  583. X    {
  584. X      case DIRECTORY : if (usercp)
  585. X                         SPRINTF(command, "%s -r %s/%s %s:%s",
  586. X                                 cname, fdir, name, rhost, curdir) ;
  587. X                       else
  588. X                         {
  589. X                           SPRINTF(rdirname, "%s/%s", tdir, name) ;
  590. X                           if ((fd = open(rdirname, O_RDONLY)) == -1)
  591. X                             SPRINTF(command, "mkdir %s", rdirname) ;
  592. X                           else
  593. X                             {
  594. X                               CLOSE(fd) ;
  595. X                               return ;
  596. X                             }
  597. X                         }
  598. X                       break ;
  599. X      case REGULAR   : if (usercp) SPRINTF(rdirname, "%s:%s", rhost, curdir) ;
  600. X                       else
  601. X                         {
  602. X                           STRCPY(rdirname, tdir) ;
  603. X                           if (strlen(coff))
  604. X                             {
  605. X                               STRCAT(rdirname, "/") ;
  606. X                               STRCAT(rdirname, coff) ;
  607. X                             }
  608. X                         }
  609. X                       STRCPY(command, cname) ;
  610. X                       for (i = 0; i < fcnt; i++)
  611. X                         {
  612. X                           STRCAT(command, " ") ;
  613. X                           STRCAT(command, fdir) ;
  614. X                           STRCAT(command, "/") ;
  615. X                           STRCAT(command, flist[i]) ;
  616. X                         }
  617. X                       STRCAT(command, " ") ;
  618. X                       STRCAT(command, rdirname) ;
  619. X    }
  620. X  if (system(command))
  621. X    FPRINTF(stderr, "%s [FAILED]: %s\n\n", progname, command) ;
  622. X  else if (debug) FPRINTF(stderr, "%s succeeded: %s\n\n", progname, command) ;
  623. X
  624. X  fcnt = 0 ;
  625. X}
  626. X
  627. X
  628. Xsetup()
  629. X{
  630. X  dirs = (struct dinfo *) Malloc(sizeof(struct dinfo)) ;
  631. X  STRCPY(dirs->d_name, "") ;
  632. X  STRCPY(pdir, fdir) ;        /* Start directory for current cp request. */
  633. X  STRCPY(coff, "") ;          /* Name offset from start directory. */
  634. X
  635. X  STRCPY(cp_name, "/bin/cp") ;          /* Default names. */
  636. X  STRCPY(rcp_name, "/usr/ucb/rcp") ;
  637. X#ifdef CP
  638. X  if (access(CP, X_OK)) STRCPY(cp_name, CP) ;
  639. X#endif CP
  640. X#ifdef RCP
  641. X  if (access(RCP, X_OK)) STRCPY(rcp_name, RCP) ;
  642. X#endif RCP
  643. X
  644. X  if (usercp)                 /* Used by the output routine. */
  645. X    STRCPY(cname, rcp_name) ;
  646. X  else STRCPY(cname, cp_name) ;
  647. X  dirs->next = dirs ;
  648. X  cdir = dirs ;
  649. X}
  650. SHAR_EOF
  651. chmod 0444 abcd.c || echo "restore of abcd.c fails"
  652. set `wc -c abcd.c`;Sum=$1
  653. if test "$Sum" != "14484"
  654. then echo original size 14484, current size $Sum;fi
  655. echo "x - extracting ndir.c (Text)"
  656. sed 's/^X//' << 'SHAR_EOF' > ndir.c &&
  657. X
  658. X/*  @(#)ndir.c 1.2 89/01/10
  659. X *
  660. X *  4.2BSD directory access emulation for non-4.2 systems.
  661. X *  Based upon routines in appendix D of Portable C and Unix System
  662. X *  Programming by J. E. Lapin (Rabbit Software).
  663. X *
  664. X *  No responsibility is taken for any error in accuracies inherent
  665. X *  either to the comments or the code of this program, but if
  666. X *  reported to me then an attempt will be made to fix them.
  667. X */
  668. X
  669. X/*  Support for Berkeley directory reading routines on a V7/SysV file
  670. X *  system.
  671. X */
  672. X
  673. X/*  Open a directory. */
  674. X
  675. XDIR *
  676. Xopendir(name)
  677. Xchar *name ;
  678. X{
  679. X  register DIR *dirp ;
  680. X  register int fd ;
  681. X
  682. X  if ((fd = open(name, 0)) == -1) return NULL ;
  683. X  if ((dirp = (DIR *) malloc(sizeof(DIR))) == NULL)
  684. X    {
  685. X      close(fd) ;
  686. X      return NULL ;
  687. X    }
  688. X  dirp->dd_fd = fd ;
  689. X  dirp->dd_loc = 0 ;
  690. X  return dirp ;
  691. X}
  692. X
  693. X
  694. X/*  Read an old style directory entry and present it as a new one. */
  695. X
  696. X#define  ODIRSIZ  14
  697. X
  698. Xstruct olddirent
  699. X{
  700. X  short  od_ino ;
  701. X  char   od_name[ODIRSIZ] ;
  702. X} ;
  703. X
  704. X
  705. X/*  Get next entry in a directory. */
  706. X
  707. Xstruct dirent *
  708. Xreaddir(dirp)
  709. Xregister DIR *dirp ;
  710. X{
  711. X  register struct olddirent *dp ;
  712. X  static struct dirent dir ;
  713. X
  714. X  for (;;)
  715. X    {
  716. X      if (dirp->dd_loc == 0)
  717. X        {
  718. X          dirp->dd_size = read(dirp->dd_fd, fd, dirp->dd_buf, DIRBLKSIZ) ;
  719. X          if (dirp->dd_size <= 0) return NULL ;
  720. X        }
  721. X      if (dirp->dd_loc >= dirp->dd_size)
  722. X        {
  723. X          dirp->dd_loc = 0 ;
  724. X          continue ;
  725. X        }
  726. X
  727. X      dp = (struct olddirent *)(dirp->dd_buf + dirp->dd_loc) ;
  728. X      dirp->dd_loc += sizeof(struct olddirent) ;
  729. X
  730. X      if (dp->od_ino == 0) continue ;
  731. X
  732. X      dir.d_fileno = dp->od_ino ;
  733. X      strncpy(dir.d_name, dp->od_name, ODIRSIZ) ;
  734. X      dir.d_name[ODIRSIZ] = ' ' ;       /* Ensure termination. */
  735. X      dir.d_namlen = strlen(dir.d_name) ;
  736. X      dir.d_reclen = DIRSIZ(&dir) ;
  737. X      return(&dir) ;
  738. X    }
  739. X}
  740. X
  741. X
  742. X/*  Close a directory. */
  743. X
  744. Xvoid
  745. Xclosedir(dirp)
  746. Xregister DIR *dirp ;
  747. X{
  748. X  close(dirp->dd_fd) ;
  749. X  dirp->dd_fd = -1 ;
  750. X  dirp->dd_loc = 0 ;
  751. X  free(dirp) ;
  752. X} 
  753. SHAR_EOF
  754. chmod 0444 ndir.c || echo "restore of ndir.c fails"
  755. set `wc -c ndir.c`;Sum=$1
  756. if test "$Sum" != "1998"
  757. then echo original size 1998, current size $Sum;fi
  758. echo "x - extracting abcd.h (Text)"
  759. sed 's/^X//' << 'SHAR_EOF' > abcd.h &&
  760. X
  761. X/*  @(#)abcd.h 1.2 89/01/08
  762. X *
  763. X *  Definitions used by abcd, the automatic backup copy daemon.
  764. X *
  765. X *  Copyright (c) Rich Burridge.
  766. X *                Sun Microsystems Australia - All rights reserved.
  767. X * 
  768. X *  Permission is given to distribute these sources, as long as the
  769. X *  copyright messages are not removed, and no monies are exchanged.
  770. X *
  771. X *  No responsibility is taken for any error in accuracies inherent
  772. X *  either to the comments or the code of this program, but if
  773. X *  reported to me then an attempt will be made to fix them.
  774. X */
  775. X
  776. X#define  CLOSE       (void) close     /* To make lint happy. */
  777. X#define  CLOSEDIR    (void) closedir
  778. X#define  FPRINTF     (void) fprintf
  779. X#define  SPRINTF     (void) sprintf
  780. X#define  SIGNAL      (void) signal
  781. X#define  STAT        (void) stat
  782. X#define  STRCAT      (void) strcat
  783. X#define  STRCPY      (void) strcpy
  784. X
  785. X#define  DIRECTORY   S_IFDIR          /* Type of files being monitored. */
  786. X#define  REGULAR     S_IFREG
  787. X
  788. X#define  DOTS(A)     (A[0] == '.' && (A[1] == 0 || (A[1] == '.' && A[2] == 0)))
  789. X#define  EQUAL(a,b)  !strcmp(a,b)     /* Test for string equality. */
  790. X#define  INC         argc-- ; argv++ ;
  791. X#define  MAXFILES    5                /* Max no of files to copy in one go. */
  792. X#define  MAXLINE     MAXNAMLEN+1      /* Maximum length of path names. */
  793. X
  794. X
  795. Xstruct dinfo         /* Info record for directories being monitored. */
  796. X         {
  797. X           struct dinfo *next ;
  798. X           char d_name[MAXLINE] ;
  799. X         } ;
  800. X
  801. Xstruct finfo         /* Information record for monitored files. */
  802. X         {
  803. X           struct finfo *next ;
  804. X           struct dirent *dirent ;
  805. X           time_t mtime ;
  806. X          } ;
  807. SHAR_EOF
  808. chmod 0444 abcd.h || echo "restore of abcd.h fails"
  809. set `wc -c abcd.h`;Sum=$1
  810. if test "$Sum" != "1650"
  811. then echo original size 1650, current size $Sum;fi
  812. echo "x - extracting ndir.h (Text)"
  813. sed 's/^X//' << 'SHAR_EOF' > ndir.h &&
  814. X
  815. X/*  @(#)ndir.h 1.2 89/01/10
  816. X *
  817. X *  4.2BSD directory access emulation for non-4.2 systems.
  818. X *  Based upon routines in appendix D of Portable C and Unix System
  819. X *  Programming by J. E. Lapin (Rabbit Software).
  820. X *
  821. X *  No responsibility is taken for any error in accuracies inherent
  822. X *  either to the comments or the code of this program, but if
  823. X *  reported to me then an attempt will be made to fix them.
  824. X */
  825. X
  826. X#ifndef  DEV_BSIZE
  827. X#define  DEV_BSIZE  512           /* Device block size. */
  828. X#endif
  829. X
  830. X#define  DIRBLKSIZ  DEV_BSIZE
  831. X#define  MAXNAMLEN  255           /* Name must be no longer than this. */
  832. X
  833. Xstruct dirent
  834. X{
  835. X  long  d_fileno ;                /* Inode number of entry. */
  836. X  short d_reclen ;                /* Length of this record. */
  837. X  short d_namlen ;                /* Length of d_name string. */
  838. X  char  d_name[MAXNAMLEN + 1] ;   /* Directory name. */
  839. X} ;
  840. X
  841. X
  842. X/*  The DIRSIZ macro gives the minimum record length that will hold the
  843. X *  directory entry. This requires the amount of space in struct direct
  844. X *  without the d_name field, plus enough space for the name with a
  845. X *  terminating null byte (dp->d_namlen+1), rounded up to a 4 byte
  846. X *  boundary.
  847. X */
  848. X
  849. X#undef   DIRSIZ
  850. X#define  DIRSIZ(dp)                                \
  851. X         ((sizeof (struct dirent) - (MAXNAMLEN+1)) \
  852. X         + (((dp)->d_namlen+1 + 3) &~ 3))
  853. X
  854. X/*  Definitions for library routines operating on directories. */
  855. X
  856. Xtypedef struct _dirdesc
  857. X{
  858. X  int    dd_fd ;
  859. X  long   dd_loc ;
  860. X  long   dd_size ;
  861. X  char   dd_buf[DIRBLKSIZ] ;
  862. X} DIR ;
  863. X
  864. X#ifndef  NULL
  865. X#define  NULL  0
  866. X#endif
  867. X
  868. Xextern  DIR              *opendir() ;
  869. Xextern  struct dirent    *readdir() ;
  870. Xextern  long             telldir() ;
  871. Xextern  void             seekdir() ;
  872. X#define rewinddir(dirp)  seekdir((dirp), (long) 0)
  873. Xextern  void             closedir() ;
  874. SHAR_EOF
  875. chmod 0444 ndir.h || echo "restore of ndir.h fails"
  876. set `wc -c ndir.h`;Sum=$1
  877. if test "$Sum" != "1795"
  878. then echo original size 1795, current size $Sum;fi
  879. echo "x - extracting patchlevel.h (Text)"
  880. sed 's/^X//' << 'SHAR_EOF' > patchlevel.h &&
  881. X
  882. X/*  @(#)patchlevel.h 1.3 89/04/10
  883. X *
  884. X *  This is the current patch level for this version of abcd.
  885. X *
  886. X *  Copyright (c) Rich Burridge.
  887. X *                Sun Microsystems, Australia - All rights reserved.
  888. X *
  889. X *  Permission is given to distribute these sources, as long as the
  890. X *  copyright messages are not removed, and no monies are exchanged.
  891. X *
  892. X *  No responsibility is taken for any errors or inaccuracies inherent
  893. X *  either to the comments or the code of this program, but if
  894. X *  reported to me then an attempt will be made to fix them.
  895. X */
  896. X
  897. X#define  PATCHLEVEL  1
  898. SHAR_EOF
  899. chmod 0444 patchlevel.h || echo "restore of patchlevel.h fails"
  900. set `wc -c patchlevel.h`;Sum=$1
  901. if test "$Sum" != "571"
  902. then echo original size 571, current size $Sum;fi
  903. echo "x - extracting abcd.1 (Text)"
  904. sed 's/^X//' << 'SHAR_EOF' > abcd.1 &&
  905. X.\" @(#)abcd.1 1.3 89/04/10
  906. X.TH ABCD 1L "9 January 1989"
  907. X.SH NAME
  908. Xabcd \- automatic backup copy daemon
  909. X.SH SYNOPSIS
  910. X.B "abcd
  911. X[
  912. X.B \-c
  913. X]
  914. X[
  915. X.B \-d
  916. X]
  917. X[
  918. X.B \-f
  919. X.I directory
  920. X]
  921. X[
  922. X.B \-r
  923. X.I hostname
  924. X]
  925. X[
  926. X.B \-s
  927. X.I seconds
  928. X]
  929. X[
  930. X.B \-t
  931. X.I directory
  932. X]
  933. X[
  934. X.B \-v
  935. X]
  936. X.SH DESCRIPTION
  937. X.I Abcd
  938. Xis an automatic backup copy daemon, which copies files from one
  939. Xfilestore area to another using either cp or rcp. Note the second filestore
  940. Xarea could be on another machine if the file system is NFS mounted.
  941. X.LP
  942. XThis means that the backup machine should have an almost identical copy
  943. Xof the filestore being monitored.
  944. X.LP
  945. XA start directory for monitoring is given. All the files including
  946. Xsub-directories and their files are monitored. Whenever any one of
  947. Xthem is changed it is automatically copied to another machine as
  948. Xspecified by the initial parameters to the program.
  949. X.LP
  950. XIf it finds a new directory, then it will make that new directory
  951. Xin the other area if not present.
  952. X.LP
  953. XIf a sub-directory is deleted, then that directory is removed from
  954. Xthe list of directories being monitored. If the original start directory
  955. Xis removed, then the program terminates because there is nothing left
  956. Xto monitor.
  957. X.LP
  958. XIf nothing has changed in one complete pass of all the directories
  959. Xbeen monitored, then the program puts itself to sleep for a specified
  960. Xperiod.
  961. X.LP
  962. XThere is a restart facility whereby if the machine has crashed, then it
  963. Xis possible to tell the program not to copy anything for the first pass,
  964. Xbut to start copying changed files from the second pass onwards.
  965. X.SH OPTIONS
  966. X.TP
  967. X.B -c
  968. XIf given, then abcd won't copy the first time through.
  969. X.TP
  970. X.B -d
  971. XIf used, the more status information will be displayed.
  972. X.TP
  973. X.BI \-f " directory"
  974. XDirectory to start copying from. Defaults to /usr.
  975. X.TP 
  976. X.BI \-r " hostname"
  977. XThis is an alternative form of backup. Uses rcp and copies to
  978. Xhostname supplied.
  979. X.TP 
  980. X.BI \-s " seconds"
  981. XSpecifies the sleep period in seconds for when the program puts
  982. Xitself to sleep. Default is 5 minutes.
  983. X.TP
  984. X.BI \-t " directory"
  985. XDirectory to start copying to. Defaults to /usr2.
  986. X.TP
  987. X.B \-v
  988. XPrint the version number of this release of the
  989. X.B abcd
  990. Xprogram.
  991. X.SH BUGS
  992. XThis program is currently totally inpractical for monitoring filestore
  993. Xareas containing large files which are being continuously updated, such
  994. Xas databases.
  995. X.SH AUTHOR
  996. XRich Burridge,        DOMAIN: richb@sunaus.oz.au
  997. X.nf
  998. XPHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  999. X.fi
  1000. SHAR_EOF
  1001. chmod 0444 abcd.1 || echo "restore of abcd.1 fails"
  1002. set `wc -c abcd.1`;Sum=$1
  1003. if test "$Sum" != "2452"
  1004. then echo original size 2452, current size $Sum;fi
  1005. exit 0
  1006.  
  1007.  
  1008.