home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume3 / mdump2 < prev    next >
Internet Message Format  |  1986-11-30  |  25KB

  1. From: genrad!ihnp4!uiucdcs!uiucuxc.Uiuc.ARPA!paul (Paul Pomes - the Wonder Llama)
  2. Subject: Revised mdump (multiple dump per tape utility)
  3. Newsgroups: mod.sources
  4. Approved: jpn@panda.UUCP
  5.  
  6. Mod.sources:  Volume 3, Issue 12
  7. Submitted by: ihnp4!uiucdcs!uiucuxc.Uiuc.ARPA!paul (Paul Pomes)
  8.  
  9. [ I have included part of the description from the original release of
  10.   mdump for those who may not have seen the first release.  Note that this
  11.   is an UPDATE, there are files and programs that are not included with
  12.   this module - contact me to obtain the original distribution.
  13.     -  John P. Nelson, Moderator (decvax!genrad!panda!sources-request)
  14. ]
  15.  
  16. > Mdump and st were written to ease the pain of UNIX backups for our
  17. > operations staff.  It's compressed the clock time needed to run a
  18. > daily set of backups by almost two thirds.  The time savings are due
  19. > to eliminating most of the tape mounts and waiting for tape rewinds.
  20. > Listings are generated automatically though they can be suppressed.
  21. > It's been in use here for about two months in its present form.
  22. > VAX backups are done on local drives, the Pyramid 90x goes over an
  23. > Ethernet to the VAX drives.
  24. >
  25. >         ...
  26. >                                                          Anyway I
  27. > think this will be extremely useful for some sites, handy at others,
  28. > and pretty window dressing at the rest.
  29.  
  30. This revision incorporates suggestions contributed from the net as
  31. well as some code cleanup engendered from a fresh look at the 
  32. program.
  33.  
  34. The dump level for dailies and weeklies can now be specified with the
  35. dl or wl switches.  Omitting them causes 5 and 4 to be used as the 
  36. default level (set by #define's).
  37.  
  38. The somewhat awkward use of #define's to group printf strings together
  39. has been eliminated in preference for moving the strings to where they're
  40. used.  The comment  /* EDIT THIS */  now flags the location of site-
  41. dependent strings.
  42.  
  43. Re-structuring the code inflated the patch file to be larger than the
  44. original.  Included is the new mdump.c and mdump.8 man page.
  45.  
  46. Release 2.5 of OSx for the Pyramid 90x has changed the exit code of a
  47. successful dump from 1 to 0.  Either revise dump.h and recompile dump,
  48. or change mdump to check for 0 rather than 1.
  49.  
  50.  
  51.          Paul Pomes
  52.  
  53. UUCP:     {ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!paul
  54. ARPANET: paul%uiucuxc@uiuc.arpa
  55. CSNET:     paul%uiucuxc@uiuc.csnet
  56. ICBM:     40 07 N / 88 13 W
  57. US Mail: Univ of Illinois, CSO, 1304 W Springfield Ave, Urbana, IL  61801
  58.  
  59. ------ cut here ------
  60. #!/bin/sh
  61. # shar:    Shell Archiver
  62. #    Run the following text with /bin/sh to create:
  63. #    mdump.c
  64. #    mdump.8
  65. sed 's/^X//' << 'SHAR_EOF' > mdump.c
  66. X/*
  67. X * mdump -- put daily/weekly backups onto a single tape
  68. X *
  69. X * Mdump simplifies the tedious process of daily and weekly backups by
  70. X * putting all daily backups onto a single tape.  Weekly backups are
  71. X * performed the same way.  The /etc/dumptab file defines the file
  72. X * position on the tape each filesystem is written at and the day of
  73. X * the week the weekly backup is done.  Filesystems that are scheduled
  74. X * for a weekly backup are marked with a dummy file on the daily tape
  75. X * so that file numbering remains constant.  The same is done for dailies
  76. X * on a weekly tape.
  77. X *
  78. X * usage: mdump [-d] [-w] [-dl n] [-wl n] [-l] [-e] [-t day] [-f [host:]/dev/rmtx] [-db]
  79. X *
  80. X * -d    write daily backups with default dump level of DAILY
  81. X *
  82. X * -w    write weekly backups with default dump level of WEEKLY
  83. X *
  84. X * -dl n    write daily backups at dump level n
  85. X *
  86. X * -wl n    write weekly backups at dump level n
  87. X *
  88. X * -l    suppress generation of the listing file
  89. X *
  90. X * -e    run listing code after an error exit
  91. X *
  92. X * -t day    run mdump for day (sun - sat) instead of today
  93. X *
  94. X * -f [host:]/dev/rmtx    tape device name.  If the host: prefix
  95. X *    is used, the backup tape will be written over the network to
  96. X *    the tape drive on the named host.
  97. X *
  98. X * -db    Write debug information to stderr
  99. X *
  100. X * NOTE to installers:  Site dependent commands have been flagged in the
  101. X * code with the comment "EDIT THIS".
  102. X *
  103. X * Written by Paul Pomes, University of Illinois, Computing Services Office.
  104. X * Copyright 1985 by Paul Pomes and University of Illinois Board of Trustees
  105. X *
  106. X * This program may be freely reproduced and distributed provided the
  107. X * copyright notice above is included in all copies.  It may not be
  108. X * included in any software product or distribution sold for profit
  109. X * without the permission of the author.
  110. X *
  111. X * UUCP:    {ihnp4,pur-ee,convex}!uiucdcs!uiucuxc!paul
  112. X * ARPANET:    paul%uiucuxc@uiuc.arpa
  113. X * CSNET:    paul%uiucuxc@uiuc.csnet
  114. X * ICBM:    40 07 N / 88 13 W
  115. X * US Mail:    Univ of Illinois, CSO, 1304 W Springfield Ave, Urbana, IL  61801
  116. X *
  117. X * $Log:    mdump.c,v $
  118. X * Revision 1.10  85/09/11  14:06:08  root
  119. X * Changed pr command to use two column printing instead of three.  -pbp
  120. X * 
  121. X * Revision 1.9  85/08/14  16:25:52  root
  122. X * Threats of mayhem from operators induced me to re-insert -d and -w flags.
  123. X * -pbp
  124. X * 
  125. X * Revision 1.8  85/08/14  13:45:47  paul
  126. X * Revamped dump level selection with inclusion of wl and dl switches,
  127. X * removed w and d as superfluous.  Moved commands back to the sprintfs
  128. X * that use them.
  129. X * 
  130. X * Revision 1.7  85/08/07  16:30:08  paul
  131. X * Added bare-bones System 5 defines (index -> strchr, etc).  Large hacks
  132. X * needed to do the same for the mag tape ioctls.  Another day, far away.
  133. X * 
  134. X * Revision 1.6  85/08/07  16:03:57  root
  135. X * Added n switch to dump command so that operators are notified.
  136. X * Extremely effective annoyance feature.   -pbp
  137. X * 
  138. X * Revision 1.5  85/07/11  14:44:07  paul
  139. X * Added recovery question for restore listings of filesystems with no files.
  140. X * pbp
  141. X * 
  142. X * Revision 1.4  85/07/09  21:18:09  root
  143. X * *** empty log message ***
  144. X * 
  145. X * Revision 1.3  85/07/05  17:13:39  root
  146. X * Added -t day-of-week flag for enhanced error recovery.   -pbp
  147. X * 
  148. X * Revision 1.2  85/07/03  23:23:04  root
  149. X * Added -e flag to force listings after "rsh mt" errors.   -pbp
  150. X * 
  151. X * Revision 1.1  85/07/02  13:47:46  root
  152. X * Initial revision
  153. X */
  154. X
  155. X#ifndef lint
  156. Xstatic char    RcsId[] = "$Header: mdump.c,v 1.10 85/09/11 14:06:08 root Exp $";
  157. X#endif
  158. X
  159. X#include    <stdio.h>
  160. X#ifdef    SYS5
  161. X#include    <string.h>
  162. X#define        index        strchr
  163. X#define        rindex        strrchr
  164. X#else
  165. X#include    <strings.h>
  166. X#endif
  167. X#include    <ctype.h>
  168. X#include    <sys/time.h>
  169. X#include    <sys/file.h>
  170. X#include    <sys/types.h>
  171. X#include    <sys/mtio.h>
  172. X#include    <sys/ioctl.h>
  173. X#include    <dumptab.h>
  174. X
  175. X#define        equal(s1, s2)    (strcmp(s1, s2) == 0)
  176. X
  177. X/* default dump levels */
  178. X#define        DAILY        5
  179. X#define        WEEKLY        4
  180. X
  181. X/* default output devices */
  182. X#define        DEF_DEV        "/dev/rmt0"
  183. X#define        DEF_NRDEV    "/dev/nrmt0"
  184. X
  185. X/* dumptab file.  must be the same as referenced by getdtent() functions */
  186. X#define        DUMPTAB        "/etc/dumptab"
  187. X
  188. X/* temp file for listings */
  189. X#define        DLIST        "/tmp/mdumpXXXXXX"
  190. X
  191. X/* maximum number of filesystems */
  192. X#define        MAX_FS        30
  193. X
  194. X/* size of shorter strings, e.g., rhost[] */
  195. X#define        SSTR_SIZE    12
  196. X
  197. X/* size of longer strings, e.g., command[] */
  198. X#define        LSTR_SIZE    160
  199. X
  200. X/* copy of argv[0] for error messages */
  201. Xchar        *self;
  202. X
  203. X/* resident host name */
  204. Xchar        myname[SSTR_SIZE];
  205. X
  206. X/* debug messages printed if set */
  207. Xint        debug;
  208. X
  209. X/* run listing code only */
  210. Xint        elist;
  211. X
  212. X/* state table of tape files.  if dump_state[0] is set, then there's a dump
  213. X * file there.  If zero, there's a dummy file on the tape instead.  If -1
  214. X * then EOT has been reached or some other dump(8) error.  Typical usage
  215. X * would be dump_state[dt->dt_position].
  216. X */
  217. Xint        dump_state[MAX_FS];
  218. X
  219. X/* mag tape stuff */
  220. Xstruct mt_cmds {
  221. X    char    *c_name;
  222. X    int    c_code;
  223. X    int    c_ronly;
  224. X} com[] = {
  225. X    { "eof",    MTWEOF,    0 },
  226. X    { "fsf",    MTFSF,    1 },
  227. X    { "bsf",    MTBSF,    1 },
  228. X    { "rew",    MTREW,    1 },
  229. X    { 0 }
  230. X};
  231. X
  232. Xextern time_t    time();
  233. X
  234. Xmain(argc, argv)
  235. Xint    argc;
  236. Xchar    **argv;
  237. X{
  238. X    /* a useful counter */
  239. X    int        i;
  240. X
  241. X    /* flags set for default dump levels and types */
  242. X    int        daily = 0;
  243. X    int        weekly = 0;
  244. X
  245. X    /* dump level (0 to 9).  -1 indicates not selected */
  246. X    int        dlevel = -1;    /* daily */
  247. X    int        wlevel = -1;    /* weekly */
  248. X
  249. X    /* create a compact listing if set */
  250. X    int        dlist = 1;
  251. X
  252. X    /* run mdump for day argument instead of today of set */
  253. X    char        newday[4];
  254. X
  255. X    /* listing file */
  256. X    char        *list_file = DLIST;
  257. X
  258. X    /* backup device */
  259. X    char        *device, *nrdevice;
  260. X
  261. X    /* remote host name */
  262. X    char        rhost[SSTR_SIZE];
  263. X
  264. X    /* time stuff */
  265. X    struct tm    *tm;
  266. X    time_t        clock;
  267. X
  268. X    /* dumptab info */
  269. X    struct dumptab    *dt;
  270. X
  271. X    /* library routines */
  272. X    char        *malloc(), *mktemp();
  273. X
  274. X    /* routine to set new tm->tm_wday value for -t argument */
  275. X    struct tm    *setday();
  276. X
  277. X    /* squirrel a copy of *argv[0] away for use in error messages */
  278. X    self = malloc((unsigned) (strlen(*argv) + 1));
  279. X    (void) strcpy(self, *argv);
  280. X
  281. X    newday[0] = rhost[0] = '\0';
  282. X    device = DEF_DEV;
  283. X    nrdevice = DEF_NRDEV;
  284. X    (void) gethostname(myname, SSTR_SIZE-1);
  285. X    /*
  286. X     * parse arguments
  287. X     */
  288. X    i = 1;
  289. X    while (i < argc && *argv[i] == '-') {
  290. X        if (equal(argv[i]+1, "db")) {
  291. X            /* db - set debug level */
  292. X            debug++;
  293. X            i++;
  294. X            fprintf(stderr, "%s: debug option enabled\n", self);
  295. X        }
  296. X        else if (equal(argv[i]+1, "d")) {
  297. X            /* d - dailies of default dump level */
  298. X            daily++;
  299. X            i++;
  300. X        }
  301. X        else if (equal(argv[i]+1, "w")) {
  302. X            /* w- weeklies of default dump level */
  303. X            weekly++;
  304. X            i++;
  305. X        }
  306. X        else if (equal(argv[i]+1, "dl")) {
  307. X            /* dl - read daily dump level from next argument */
  308. X            i++;
  309. X            if ((dlevel = atoi(argv[i])) > 9) {
  310. X                fprintf(stderr, "%s: invalid daily dump level (%d)\n", self, dlevel);
  311. X                exit(1);
  312. X            }
  313. X            i++;
  314. X        }
  315. X        else if (equal(argv[i]+1, "wl")) {
  316. X            /* wl - read weekly dump level from next argument */
  317. X            i++;
  318. X            if ((wlevel = atoi(argv[i])) > 9) {
  319. X                fprintf(stderr, "%s: invalid weekly dump level (%d)\n", self, wlevel);
  320. X                exit(1);
  321. X            }
  322. X            i++;
  323. X        }
  324. X        else if (equal(argv[i]+1, "l")) {
  325. X            /* l - suppress listings of files */
  326. X            dlist = 0;
  327. X            i++;
  328. X        }
  329. X        else if (equal(argv[i]+1, "e")) {
  330. X            /* e - run listing code only */
  331. X            printf("Listings only - nothing will be written to tape\n");
  332. X            elist++;
  333. X            i++;
  334. X        }
  335. X        else if (equal(argv[i]+1, "t")) {
  336. X            /* t - read new dump day-of-week from next argument */
  337. X            i++;
  338. X            (void) strncpy(newday, argv[i], 3);
  339. X            i++;
  340. X        }
  341. X        else if (equal(argv[i]+1, "f"))
  342. X        {
  343. X            /*
  344. X             * f - read backup device from next argument
  345. X             * turn /dev/rmt names into /dev/nrmt
  346. X             */
  347. X            char    temp[40], *p1, *p2;
  348. X
  349. X            i++;
  350. X            p2 = (char *) NULL;
  351. X            if ((p1 = index(argv[i], ':')) != 0) {
  352. X                (void) strncpy(rhost, argv[i], p1-argv[i]+1);
  353. X                *(index(rhost, ':')) = '\0';
  354. X                p1++;
  355. X            }
  356. X            if (p1 == 0)
  357. X                p1 = argv[i];
  358. X            device = malloc((unsigned) (strlen(p1) + 1));
  359. X            (void) strcpy(device, p1);
  360. X            if ((p2 = rindex(argv[i], '/')) == 0) {
  361. X                fprintf(stderr, "%s: Output device must be a tape drive, e.g., /dev/rmt1, uxc:/dev/rmt2\n", self);
  362. X                exit(1);
  363. X            }
  364. X            p2++;
  365. X            (void) strncpy(temp, p1, p2-p1);
  366. X            *(temp + (p2-p1)) = '\0';
  367. X            nrdevice = malloc((unsigned) (strlen(argv[i])+2));
  368. X            if (*p2 == 'n')
  369. X                (void) sprintf(nrdevice, "%s%s", temp, p2);
  370. X            else
  371. X                (void) sprintf(nrdevice, "%sn%s", temp, p2);
  372. X            if (debug)
  373. X                fprintf(stderr, "rhost %s, device %s, nrdevice %s\n", rhost, device, nrdevice);
  374. X            i++;
  375. X        }
  376. X        else
  377. X        {
  378. X            /* command line errors */
  379. X            fprintf(stderr, "%s: %s - bad flag\n", self, argv[i]+1);
  380. X            fprintf(stderr, "Usage: %s [-d] [-w] [-dl n] [-wl n] [-l] [-e] [-t day] [-f [host:]/dev/rmtx] [-db]\n", self);
  381. X            exit(1);
  382. X        }
  383. X    }
  384. X    if (daily && dlevel < 0)
  385. X        dlevel = DAILY;
  386. X    if (weekly && wlevel < 0)
  387. X        wlevel = WEEKLY;
  388. X    if (wlevel < 0 && dlevel < 0) {
  389. X        fprintf(stderr, "%s: No action specified.\n", self);
  390. X        fprintf(stderr, "Invoke %s with at least one of the following: -d, -w, -dl n, -wl n\n", self);
  391. X        exit(1);
  392. X    }
  393. X    clock = time((time_t *) 0);
  394. X    if (*newday)
  395. X        tm = setday(newday);
  396. X    else
  397. X        tm = localtime(&clock);
  398. X    mtio(rhost, device, "rew");
  399. X    wrt_dtinfo(rhost, nrdevice);
  400. X    setdtent();
  401. X    for (i = 1; (dt = getdtpos(i)); i++) {
  402. X        if (dt->dt_weekly == tm->tm_wday) {
  403. X            if (wlevel > -1) {
  404. X                if (wrt_dmp(rhost, nrdevice, dt, wlevel))
  405. X                    break;
  406. X            }
  407. X            else
  408. X                wrt_dummy(rhost, nrdevice, dt);
  409. X        }
  410. X        else {
  411. X            if (dlevel > -1) {
  412. X                if (wrt_dmp(rhost, nrdevice, dt, dlevel))
  413. X                    break;
  414. X            }
  415. X            else
  416. X                wrt_dummy(rhost, nrdevice, dt);
  417. X        }
  418. X    }
  419. X    /* write the last EOF to form EOT and rewind the tape
  420. X     * by using the rewind-on-close device.
  421. X     */
  422. X    if (! elist) {
  423. X        printf("Really rewinding tape\n");
  424. X        mtio(rhost, device, "eof");
  425. X    }
  426. X    if (dlist) {
  427. X        char    command[LSTR_SIZE];
  428. X
  429. X        (void) mktemp(list_file);
  430. X        mtio(rhost, device, "rew");
  431. X
  432. X        /* skip over the zero'th file of /etc/dumptab */
  433. X        mtio(rhost, nrdevice, "fsf");
  434. X        setdtent();
  435. X        for (i = 1; (dt = getdtpos(i)); i++)
  436. X            if (list_tape(rhost, nrdevice, dt, list_file))
  437. X                break;
  438. X        /* EDIT THIS for preferred print command */
  439. X        (void) sprintf(command, 
  440. X#ifdef vax
  441. X            "ibmprint -f -h \"%s Dlist\" %s",   /* uiucuxc */
  442. X#else
  443. X            "lpr -r -s -J %s_Dlist %s",    /* osiris */
  444. X#endif
  445. X            myname, list_file);
  446. X        if (debug)
  447. X            fprintf(stderr, "print command: %s\n", command);
  448. X        if (i = (system(command) >> 8))
  449. X            fprintf(stderr, "%s: %s exitted abnormally (%d).\n", self, command, i);
  450. X        printf("Last rewind of tape\n");
  451. X        mtio(rhost, device, "rew");
  452. X    }
  453. X    exit(0);
  454. X}
  455. X
  456. X/*
  457. X * mtio -- perform a local/remote tape operation
  458. X *
  459. X *    for local tapes (host[0] == '\0') use the ioctl calls.
  460. X *    remote tapes use an rsh command.
  461. X *
  462. X *    parameters:
  463. X *        host (IN) -- name of remote host, if host[0] != '\0'
  464. X *        dev (IN) -- tape drive name
  465. X *        cp (IN) -- tape opcode
  466. X *    returns:
  467. X *        none
  468. X *    side effects:
  469. X *        none
  470. X *    deficiencies:
  471. X *        any error causes an error exit from the program
  472. X */
  473. Xmtio(host, dev, cp)
  474. Xchar    *host, *dev, *cp;
  475. X{
  476. X    struct mt_cmds    *comp;
  477. X
  478. X    /* tape file descriptor */
  479. X    int        mtfd;
  480. X
  481. X    /* return code from system() call */
  482. X    int        status;
  483. X
  484. X    /* from sys/mtio.h */
  485. X    struct mtop    mt_com;
  486. X
  487. X    /* buffer for rsh command */
  488. X    char        command[LSTR_SIZE];
  489. X
  490. X    if (*host == '\0') {
  491. X        for (comp = com; comp->c_name != NULL; comp++)
  492. X            if (strncmp(cp, comp->c_name, strlen(cp)) == 0)
  493. X                break;
  494. X        if (comp->c_name == NULL) {
  495. X            fprintf(stderr, "%s: mtio: don't grok \"%s\"\n", self, cp);
  496. X            exit(1);
  497. X        }
  498. X        if ((mtfd = open(dev, comp->c_ronly ? 0 : 2)) < 0) {
  499. X            fprintf(stderr, "%s: mtio: open of ", self);
  500. X            perror(dev);
  501. X            exit(1);
  502. X        }
  503. X        mt_com.mt_op = comp->c_code;
  504. X        mt_com.mt_count = 1;
  505. X        if (ioctl(mtfd, MTIOCTOP, &mt_com) < 0) {
  506. X            fprintf(stderr, "%s: mtio: %s %s %d ", self, dev,
  507. X                comp->c_name, mt_com.mt_count);
  508. X            perror("failed");
  509. X            exit(1);
  510. X        }
  511. X        (void) close(mtfd);
  512. X    }
  513. X    else {
  514. X        (void) sprintf(command, "rsh %s mt -t %s %s", host, dev, cp);
  515. X        if (debug)
  516. X            fprintf(stderr, "tape command %s\n", command);
  517. X        if (status = (system(command) >> 8)) {
  518. X            fprintf(stderr, "%s: %s exitted abnormally (%d).  Restart %s\n", self, command, status, self);
  519. X            exit(1);
  520. X        }
  521. X    }
  522. X}
  523. X
  524. X/*
  525. X * wrt_dmp -- write a filesystem dump on the dump tape
  526. X *
  527. X *    for local tapes (host[0] == '\0') use dump
  528. X *    remote tapes use rdump
  529. X *
  530. X *    parameters:
  531. X *        host (IN) -- name of remote host if host[0] != '\0'
  532. X *        dev (IN) -- tape drive name
  533. X *        dt (IN) -- dumptab pointer
  534. X *        level (IN) -- dump level (0-9)
  535. X *    returns:
  536. X *        0 if dump command successful, 1 if not
  537. X *    side effects:
  538. X *        alters dump_state table
  539. X *    deficiencies:
  540. X *        any error causes an error exit from the program
  541. X */
  542. Xwrt_dmp(host, dev, dt, level)
  543. Xchar        *host, *dev;
  544. Xint        level;
  545. Xstruct dumptab    *dt;
  546. X{
  547. X    char    command[LSTR_SIZE];
  548. X    int    status;
  549. X
  550. X    if (elist) {
  551. X        dump_state[dt->dt_position] = 1;
  552. X        return(0);
  553. X    }
  554. X    /* EDIT THIS for preferred dump command */
  555. X    (void) sprintf(command, " dump nuf%d %s%c%s %s",
  556. X            level, host, (*host ? ':' : ' '), dev, dt->dt_name);
  557. X    if (*host)
  558. X        command[0] = 'r';
  559. X    if (debug)
  560. X        fprintf(stderr, "dump command %s\n", command);
  561. X    printf("Dumping %s\n", dt->dt_name);
  562. X
  563. X    /* dump(8) exits with 1 if all is well */
  564. X    if ((status = (system(command) >> 8)) != 1) {
  565. X        fprintf(stderr, "%s: %s exitted abnormally (%d).\n", self, command, status);
  566. X        fprintf(stderr, "\tTape will rewind and create listings of the successful dumps.\n");
  567. X        dump_state[dt->dt_position] = -1;
  568. X        mtio(host, dev, "bsf");
  569. X        return(1);
  570. X    }
  571. X    dump_state[dt->dt_position] = 1;
  572. X    return(0);
  573. X}
  574. X
  575. X/*
  576. X * list_tape -- generate a "restore tf" listing for the current tape file
  577. X *
  578. X *    list_tape creates a command line to be executed by system() and
  579. X *    re-directs the output to a listing file.
  580. X *
  581. X *    parameters:
  582. X *        host (IN) -- name of remote host if host[0] != '\0'
  583. X *        dev (IN) -- tape drive name
  584. X *        dt (IN) -- dumptab pointer
  585. X *        lfile (IN) -- name of listing file
  586. X *    returns:
  587. X *        0 for normal results, 1 if at end of tape
  588. X *    side effects:
  589. X *        none
  590. X *    deficiencies:
  591. X *        any error causes an error exit from the program
  592. X */
  593. Xlist_tape(host, dev, dt, lfile)
  594. Xchar        *host, *dev, *lfile;
  595. Xstruct dumptab    *dt;
  596. X{
  597. X    FILE        *fp;
  598. X    int        status;
  599. X    char        command[LSTR_SIZE];
  600. X
  601. X    if (dump_state[dt->dt_position] == 0) {
  602. X        /* no file here so write a message on the dump listing */
  603. X        if ((fp = fopen(lfile, "a")) == NULL) {
  604. X            fprintf(stderr, "%s: list_tape ", self);
  605. X            perror(lfile);
  606. X            exit(1);
  607. X        }
  608. X        fprintf(fp, "\n\n\tNo dump file for %s on this tape.\n\f",
  609. X            dt->dt_name);
  610. X        (void) fclose(fp);
  611. X        /* advance the tape by one tape mark */
  612. X        printf("Skipping dummy file for %s\n", dt->dt_name);
  613. X        mtio(host, dev, "fsf");
  614. X        return(0);
  615. X    }
  616. X    else if (dump_state[dt->dt_position] == 1) {
  617. X        /* build the appropriate restore tf command and execute it */
  618. X        /* EDIT THIS for preferred listing command */
  619. X        (void) sprintf(command, " restore tf %s%c%s | sort +1 | pr -2 -w132 -f -h \"%s Dump Listing of %s\" >> %s",
  620. X            host, (*host ? ':' : ' '), dev, myname, dt->dt_name, lfile);
  621. X        if (*host)
  622. X            command[0] = 'r';
  623. X        if (debug)
  624. X            fprintf(stderr, "list command %s\n", command);
  625. X        printf("Listing %s\n", dt->dt_name);
  626. X        if (status = (system(command) >> 8)) {
  627. X            char    c,d;
  628. X
  629. X            fprintf(stderr, "%s: %s exitted abnormally (%d).  Continue? [yn] ", self, command, status);
  630. X            while ((d = getc(stdin)) != '\n')
  631. X                c = d;
  632. X            if (c != 'y')
  633. X                exit(1);
  634. X        }
  635. X        /* advance the tape to end of file */
  636. X        mtio(host, dev, "fsf");
  637. X        return(0);
  638. X    }
  639. X    return(1);
  640. X}
  641. X
  642. X/*
  643. X * wrt_dtinfo -- write /etc/dumptab onto the tape
  644. X *
  645. X *    writing a copy of /etc/dumptab onto the tape as file #0 provides
  646. X *    a catalogue of the tape files and insulates backup volumes from
  647. X *    changes in /etc/dumptab.  Elsewhere on the tape it acts as a 
  648. X *    place holder for a non-selected dump, e.g., daily on a weekly-only
  649. X *    tape.
  650. X *
  651. X *    parameters:
  652. X *        host (IN) -- name of remote host
  653. X *        dev (IN) -- tape drive name
  654. X *    returns:
  655. X *        none
  656. X *    side effects:
  657. X *        none
  658. X *    deficiencies:
  659. X *        any error causes an error exit from the program
  660. X */
  661. Xwrt_dtinfo(host, dev)
  662. Xchar    *host, *dev;
  663. X{
  664. X    char    command[LSTR_SIZE];
  665. X    int    status;
  666. X
  667. X    if (elist)
  668. X        return;
  669. X    if (*host)
  670. X        /* EDIT THIS for preferred method */
  671. X        (void) sprintf(command, "rcp %s %s:/tmp/xyzzy.mdump; rsh %s \"dd if=/tmp/xyzzy.mdump of=%s bs=512; rm /tmp/xyzzy.mdump\"",
  672. X            DUMPTAB, host, host, dev);
  673. X    else
  674. X        (void) sprintf(command, "dd if=%s of=%s bs=512",
  675. X            DUMPTAB, dev);
  676. X    printf("Copying %s to tape\n", DUMPTAB);
  677. X    if (status = (system(command) >> 8)) {
  678. X        fprintf(stderr, "%s: %s exitted abnormally (%d).  Restart %s\n", self, command, status, self);
  679. X        exit(1);
  680. X    }
  681. X}
  682. X
  683. X/*
  684. X * wrt_dummy -- write a dummy file onto the tape
  685. X *
  686. X *    write a dummy file onto the tape to take the place of a non-
  687. X *    scheduled backup.  this preserves tape order.
  688. X *
  689. X *    parameters:
  690. X *        host (IN) -- name of remote host
  691. X *        dev (IN) -- tape drive name
  692. X *        dt (IN) -- dumptab pointer
  693. X *    returns:
  694. X *        none
  695. X *    side effects:
  696. X *        alters dump_state table
  697. X *    deficiencies:
  698. X *        any error causes an error exit from the program
  699. X */
  700. Xwrt_dummy(host, dev, dt)
  701. Xchar        *host, *dev;
  702. Xstruct dumptab    *dt;
  703. X{
  704. X    char    command[LSTR_SIZE];
  705. X    int    status;
  706. X
  707. X    if (elist)
  708. X        return;
  709. X    if (*host)
  710. X        /* EDIT THIS for preferred method */
  711. X        (void) sprintf(command, "rcp %s %s:/tmp/xyzzy.mdump; rsh %s \"dd if=/tmp/xyzzy.mdump of=%s bs=512; rm /tmp/xyzzy.mdump\"",
  712. X            DUMPTAB, host, host, dev);
  713. X    else
  714. X        (void) sprintf(command, "dd if=%s of=%s bs=512",
  715. X            DUMPTAB, dev);
  716. X    printf("Writing place holder file for %s to tape\n", dt->dt_name);
  717. X    if (status = (system(command) >> 8)) {
  718. X        fprintf(stderr, "%s: %s exitted abnormally (%d).  Restart %s\n", self, command, status, self);
  719. X        exit(1);
  720. X    }
  721. X}
  722. X
  723. X/*
  724. X * setday -- set tm.tm_wday to value consistent with argument
  725. X *
  726. X *    tm.tm_wday has a legal range of 0 (for Sunday) to 6 (for Saturday).
  727. X *    day is a three character string ("sun", "mon", etc) used to determine
  728. X *    the value of tm.tm_wday.
  729. X *
  730. X *    parameters:
  731. X *        day (IN/OUT) -- day of week string
  732. X *    returns:
  733. X *        pointer to static tm struct
  734. X *    side effects:
  735. X *        changes day string to all lower case
  736. X *    deficiencies:
  737. X *        any error causes an error exit from the program
  738. X */
  739. Xstruct tm *
  740. Xsetday(day)
  741. Xchar    *day;
  742. X{
  743. X    static struct tm    mtm;
  744. X    char            *p;
  745. X
  746. X    for (p = day; *p; p++)
  747. X        if (isupper(*p))
  748. X            *p += ('a' - 'A');
  749. X    if (equal(day, "sun"))
  750. X        mtm.tm_wday = 0;
  751. X    else if (equal(day, "mon"))
  752. X        mtm.tm_wday = 1;
  753. X    else if (equal(day, "tue"))
  754. X        mtm.tm_wday = 2;
  755. X    else if (equal(day, "wed"))
  756. X        mtm.tm_wday = 3;
  757. X    else if (equal(day, "thu"))
  758. X        mtm.tm_wday = 4;
  759. X    else if (equal(day, "fri"))
  760. X        mtm.tm_wday = 5;
  761. X    else if (equal(day, "sat"))
  762. X        mtm.tm_wday = 6;
  763. X    else {
  764. X        fprintf(stderr, "%s: setday: illegal day of week (%s)\n", self, day);
  765. X        fprintf(stderr, "\tLegal values are sun, mon, tue, etc.\n");
  766. X        exit(1);
  767. X    }
  768. X    return(&mtm);
  769. X}
  770. SHAR_EOF
  771. sed 's/^X//' << 'SHAR_EOF' > mdump.8
  772. X.TH MDUMP 8 "UofI CSO"
  773. X.SH NAME
  774. Xmdump \- multiple dump per tape utility
  775. X.SH SYNOPSIS
  776. X.B mdump
  777. X[
  778. X.B \-d
  779. X] [
  780. X.B \-w
  781. X] [
  782. X\fB\-wl \fIn\fR
  783. X] [
  784. X\fB\-dl \fIn\fR
  785. X] [
  786. X.B \-l
  787. X] [
  788. X.B \-e
  789. X] [
  790. X\fB\-t \fIday-of-week\fR
  791. X] [
  792. X\fB\-f \fI[host:]/dev/rmtx\fR
  793. X]
  794. X.SH DESCRIPTION
  795. X.I Mdump
  796. Xsimplifies the backup procedure for systems with multiple filesystems
  797. Xby putting all daily and/or weekly backups onto a single tape.
  798. X.PP
  799. XThe order and selection of filesystems to be dumped is determined by
  800. X.I /etc/dumptab 
  801. Xand by the options
  802. X.BR \-d ,
  803. X.BR \-w ,
  804. X\fB\-dl \fIn\fR and
  805. X\fB\-wl \fIn\fR.
  806. X.B \-d
  807. Xselects daily backups to be done at the default daily dump level of 5;
  808. X.B \-w
  809. Xselects weekly backups with a default dump level of 4.
  810. XThe
  811. X.B \-wl
  812. Xand
  813. X.B \-dl
  814. Xswitches respectively take the weekly and daily dump level from the following
  815. Xargument
  816. X.IR n .
  817. XSpecifying both of (
  818. X.B \-d
  819. Xand
  820. X.B \-w
  821. X) or (
  822. X.B \-dl
  823. Xand
  824. X.B \-wl
  825. X)
  826. Xcauses daily and weekly backups to be selected.
  827. XA dummy file is inserted on the tape for non-selected filesystems
  828. Xto preserve file ordering.
  829. X.PP
  830. XThe
  831. X.IR st (8)
  832. Xcommand (set tape) will position the backup tape to the correct tape
  833. Xfile for restores.
  834. X.PP
  835. XThe backup device is selected with the
  836. X.B \-f
  837. Xoption.
  838. XRemote backup over the network is accomplished by specifying the device
  839. Xname in the same manner as
  840. X.IR rdump (8),
  841. Xe.g., uiucuxc:/dev/rmt0.
  842. X.PP
  843. XAfter
  844. X.I mdump
  845. Xhas finished writing the dump files,
  846. Xa listing of each dump will be created and sent to the \s-1IBM\s0 printers
  847. Xunless the
  848. X.B \-l
  849. Xoption is given to suppress the listings.
  850. X.PP
  851. XIn the case of positioning errors during the listing phase of
  852. X.IR mdump ,
  853. Xhanging rsh commands are the usual cause,
  854. X.B \-e
  855. Xwill execute the listing phase of
  856. X.I mdump
  857. Xonly.
  858. XAt least one of the flags
  859. X.B \-d
  860. Xand/or
  861. X.B \-w
  862. Xmust be specified in addition to the
  863. X.B \-e
  864. Xflag.
  865. X.PP
  866. XTo run
  867. X.I mdump
  868. Xas though it were a different day of the week, e.g.,
  869. Xcreate or list a Monday tape on Wednesday, the 
  870. X\fB\-t \fIday-of-week\fR
  871. Xflag is supplied where
  872. X.I day-of-week
  873. Xis one of mon, tue, wed, etc.
  874. X.SH NOTES
  875. XIn the case where
  876. X.I mdump
  877. Xfound no files to dump,
  878. Xthe subsequent listing phase will complain that
  879. Xit "Cannot find file dump list".
  880. X.I Mdump
  881. Xwill print a message saying that the list command exitted abnormally
  882. Xand ask whether to continue.
  883. XEntering 'y' directs
  884. X.I mdump
  885. Xto continue listing the other filesystems.
  886. XAny other response causes an exit.
  887. X.SH FILES
  888. X/etc/dumptab, /etc/dump
  889. X.SH "SEE ALSO"
  890. Xdumptab(5), dump(8), rdump(8), st(8)
  891. X.SH BUGS
  892. XNo provision is made for tape overflow.
  893. XThis is an incentive to use 6250 bpi drives.
  894. X.PP
  895. XAny tape error means restarting
  896. X.I mdump
  897. Xfrom the beginning.
  898. SHAR_EOF
  899. exit 0
  900.  
  901.