home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sbin / restore / main.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-30  |  7.9 KB  |  374 lines

  1. /*
  2.  * Copyright (c) 1983 The Regents of the University of California.
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  * 1. Redistributions of source code must retain the above copyright
  9.  *    notice, this list of conditions and the following disclaimer.
  10.  * 2. Redistributions in binary form must reproduce the above copyright
  11.  *    notice, this list of conditions and the following disclaimer in the
  12.  *    documentation and/or other materials provided with the distribution.
  13.  * 3. All advertising materials mentioning features or use of this software
  14.  *    must display the following acknowledgement:
  15.  *    This product includes software developed by the University of
  16.  *    California, Berkeley and its contributors.
  17.  * 4. Neither the name of the University nor the names of its contributors
  18.  *    may be used to endorse or promote products derived from this software
  19.  *    without specific prior written permission.
  20.  *
  21.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  22.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  23.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  24.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  25.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  26.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  27.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  28.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  29.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  30.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  31.  * SUCH DAMAGE.
  32.  */
  33.  
  34. #ifndef lint
  35. char copyright[] =
  36. "@(#) Copyright (c) 1983 The Regents of the University of California.\n\
  37.  All rights reserved.\n";
  38. #endif /* not lint */
  39.  
  40. #ifndef lint
  41. static char sccsid[] = "@(#)main.c    5.11 (Berkeley) 10/16/92";
  42. #endif /* not lint */
  43.  
  44. #include <sys/param.h>
  45. #include <sys/time.h>
  46.  
  47. #include <ufs/ffs/fs.h>
  48. #include <ufs/ufs/dinode.h>
  49. #include <protocols/dumprestore.h>
  50.  
  51. #include <errno.h>
  52. #include <signal.h>
  53. #include <stdio.h>
  54. #include <stdlib.h>
  55. #include <string.h>
  56.  
  57. #include "pathnames.h"
  58. #include "restore.h"
  59. #include "extern.h"
  60.  
  61. int    bflag = 0, cvtflag = 0, dflag = 0, vflag = 0, yflag = 0;
  62. int    hflag = 1, mflag = 1, Nflag = 0;
  63. char    command = '\0';
  64. long    dumpnum = 1;
  65. long    volno = 0;
  66. long    ntrec;
  67. char    *dumpmap;
  68. char    *clrimap;
  69. ino_t    maxino;
  70. time_t    dumptime;
  71. time_t    dumpdate;
  72. FILE     *terminal;
  73.  
  74. static void err __P((const char *, ...));
  75. static void obsolete __P((int *, char **[]));
  76. static void usage __P((void));
  77.  
  78. int
  79. main(argc, argv)
  80.     int argc;
  81.     char *argv[];
  82. {
  83.     int ch;
  84.     ino_t ino;
  85.     char *inputdev = _PATH_DEFTAPE;
  86.     char *symtbl = "./restoresymtable";
  87.     char *p, name[MAXPATHLEN];
  88.  
  89.     if (argc < 2)
  90.         usage();
  91.  
  92.     obsolete(&argc, &argv);
  93.     while ((ch = getopt(argc, argv, "b:cdf:himNRrs:tvxy")) != EOF)
  94.         switch(ch) {
  95.         case 'b':
  96.             /* Change default tape blocksize. */
  97.             bflag = 1;
  98.             ntrec = strtol(optarg, &p, 10);
  99.             if (*p)
  100.                 err("illegal blocksize -- %s", optarg);
  101.             if (ntrec <= 0)
  102.                 err("block size must be greater than 0");
  103.             break;
  104.         case 'c':
  105.             cvtflag = 1;
  106.             break;
  107.         case 'd':
  108.             dflag = 1;
  109.             break;
  110.         case 'f':
  111.             inputdev = optarg;
  112.             break;
  113.         case 'h':
  114.             hflag = 0;
  115.             break;
  116.         case 'i':
  117.         case 'R':
  118.         case 'r':
  119.         case 't':
  120.         case 'x':
  121.             if (command != '\0')
  122.                 err("%c and %c options are mutually exclusive",
  123.                     ch, command);
  124.             command = ch;
  125.             break;
  126.         case 'm':
  127.             mflag = 0;
  128.             break;
  129.         case 'N':
  130.             Nflag = 1;
  131.             break;
  132.         case 's':
  133.             /* Dumpnum (skip to) for multifile dump tapes. */
  134.             dumpnum = strtol(optarg, &p, 10);
  135.             if (*p)
  136.                 err("illegal dump number -- %s", optarg);
  137.             if (dumpnum <= 0)
  138.                 err("dump number must be greater than 0");
  139.             break;
  140.         case 'v':
  141.             vflag = 1;
  142.             break;
  143.         case 'y':
  144.             yflag = 1;
  145.             break;
  146.         default:
  147.             usage();
  148.         }
  149.     argc -= optind;
  150.     argv += optind;
  151.  
  152.     if (command == '\0')
  153.         err("none of i, R, r, t or x options specified");
  154.  
  155.     if (signal(SIGINT, onintr) == SIG_IGN)
  156.         (void) signal(SIGINT, SIG_IGN);
  157.     if (signal(SIGTERM, onintr) == SIG_IGN)
  158.         (void) signal(SIGTERM, SIG_IGN);
  159.     setlinebuf(stderr);
  160.  
  161.     setinput(inputdev);
  162.  
  163.     if (argc == 0) {
  164.         argc = 1;
  165.         *--argv = ".";
  166.     }
  167.  
  168.     switch (command) {
  169.     /*
  170.      * Interactive mode.
  171.      */
  172.     case 'i':
  173.         setup();
  174.         extractdirs(1);
  175.         initsymtable(NULL);
  176.         runcmdshell();
  177.         break;
  178.     /*
  179.      * Incremental restoration of a file system.
  180.      */
  181.     case 'r':
  182.         setup();
  183.         if (dumptime > 0) {
  184.             /*
  185.              * This is an incremental dump tape.
  186.              */
  187.             vprintf(stdout, "Begin incremental restore\n");
  188.             initsymtable(symtbl);
  189.             extractdirs(1);
  190.             removeoldleaves();
  191.             vprintf(stdout, "Calculate node updates.\n");
  192.             treescan(".", ROOTINO, nodeupdates);
  193.             findunreflinks();
  194.             removeoldnodes();
  195.         } else {
  196.             /*
  197.              * This is a level zero dump tape.
  198.              */
  199.             vprintf(stdout, "Begin level 0 restore\n");
  200.             initsymtable((char *)0);
  201.             extractdirs(1);
  202.             vprintf(stdout, "Calculate extraction list.\n");
  203.             treescan(".", ROOTINO, nodeupdates);
  204.         }
  205.         createleaves(symtbl);
  206.         createlinks();
  207.         setdirmodes(FORCE);
  208.         checkrestore();
  209.         if (dflag) {
  210.             vprintf(stdout, "Verify the directory structure\n");
  211.             treescan(".", ROOTINO, verifyfile);
  212.         }
  213.         dumpsymtable(symtbl, (long)1);
  214.         break;
  215.     /*
  216.      * Resume an incremental file system restoration.
  217.      */
  218.     case 'R':
  219.         initsymtable(symtbl);
  220.         skipmaps();
  221.         skipdirs();
  222.         createleaves(symtbl);
  223.         createlinks();
  224.         setdirmodes(FORCE);
  225.         checkrestore();
  226.         dumpsymtable(symtbl, (long)1);
  227.         break;
  228.     /*
  229.      * List contents of tape.
  230.      */
  231.     case 't':
  232.         setup();
  233.         extractdirs(0);
  234.         initsymtable((char *)0);
  235.         while (argc--) {
  236.             canon(*argv++, name);
  237.             ino = dirlookup(name);
  238.             if (ino == 0)
  239.                 continue;
  240.             treescan(name, ino, listfile);
  241.         }
  242.         break;
  243.     /*
  244.      * Batch extraction of tape contents.
  245.      */
  246.     case 'x':
  247.         setup();
  248.         extractdirs(1);
  249.         initsymtable((char *)0);
  250.         while (argc--) {
  251.             canon(*argv++, name);
  252.             ino = dirlookup(name);
  253.             if (ino == 0)
  254.                 continue;
  255.             if (mflag)
  256.                 pathcheck(name);
  257.             treescan(name, ino, addfile);
  258.         }
  259.         createfiles();
  260.         createlinks();
  261.         setdirmodes(0);
  262.         if (dflag)
  263.             checkrestore();
  264.         break;
  265.     }
  266.     done(0);
  267.     /* NOTREACHED */
  268. }
  269.  
  270. void
  271. usage()
  272. {
  273.     (void)fprintf(stderr, "usage:\t%s%s%s%s%s",
  274.         "restore tfhsvy [file ...]\n",
  275.         "\trestore xfhmsvy [file ...]\n",
  276.         "\trestore ifhmsvy\n",
  277.         "\trestore rfsvy\n",
  278.         "\trestore Rfsvy\n");
  279.     done(1);
  280. }
  281.  
  282. /*
  283.  * obsolete --
  284.  *    Change set of key letters and ordered arguments into something
  285.  *    getopt(3) will like.
  286.  */
  287. static void
  288. obsolete(argcp, argvp)
  289.     int *argcp;
  290.     char **argvp[];
  291. {
  292.     int argc, flags;
  293.     char *ap, **argv, *flagsp, **nargv, *p;
  294.  
  295.     /* Setup. */
  296.     argv = *argvp;
  297.     argc = *argcp;
  298.  
  299.     /* Return if no arguments or first argument has leading dash. */
  300.     ap = argv[1];
  301.     if (argc == 1 || *ap == '-')
  302.         return;
  303.  
  304.     /* Allocate space for new arguments. */
  305.     if ((*argvp = nargv = malloc((argc + 1) * sizeof(char *))) == NULL ||
  306.         (p = flagsp = malloc(strlen(ap) + 2)) == NULL)
  307.         err("%s", strerror(errno));
  308.  
  309.     *nargv++ = *argv;
  310.     argv += 2;
  311.  
  312.     for (flags = 0; *ap; ++ap) {
  313.         switch(*ap) {
  314.         case 'b':
  315.         case 'f':
  316.         case 's':
  317.             if ((nargv[0] = malloc(strlen(*argv) + 2 + 1)) == NULL)
  318.                 err("%s", strerror(errno));
  319.             nargv[0][0] = '-';
  320.             nargv[0][1] = *ap;
  321.             (void)strcpy(&nargv[0][2], *argv);
  322.             if (*argv != NULL)
  323.                 ++argv;
  324.             ++nargv;
  325.             break;
  326.         default:
  327.             if (!flags) {
  328.                 *p++ = '-';
  329.                 flags = 1;
  330.             }
  331.             *p++ = *ap;
  332.             break;
  333.         }
  334.     }
  335.  
  336.     /* Terminate flags. */
  337.     if (flags) {
  338.         *p = '\0';
  339.         *nargv++ = flagsp;
  340.     }
  341.  
  342.     /* Copy remaining arguments. */
  343.     while (*nargv++ = *argv++);
  344. }
  345.  
  346. #if __STDC__
  347. #include <stdarg.h>
  348. #else
  349. #include <varargs.h>
  350. #endif
  351.  
  352. void
  353. #if __STDC__
  354. err(const char *fmt, ...)
  355. #else
  356. err(fmt, va_alist)
  357.     char *fmt;
  358.         va_dcl
  359. #endif
  360. {
  361.     va_list ap;
  362. #if __STDC__
  363.     va_start(ap, fmt);
  364. #else
  365.     va_start(ap);
  366. #endif
  367.     (void)fprintf(stderr, "restore: ");
  368.     (void)vfprintf(stderr, fmt, ap);
  369.     va_end(ap);
  370.     (void)fprintf(stderr, "\n");
  371.     exit(1);
  372.     /* NOTREACHED */
  373. }
  374.