Annotation of 43BSDReno/sbin/restore/utilities.c, revision 1.1.1.1

1.1       root        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 are permitted
                      6:  * provided that: (1) source distributions retain this entire copyright
                      7:  * notice and comment, and (2) distributions including binaries display
                      8:  * the following acknowledgement:  ``This product includes software
                      9:  * developed by the University of California, Berkeley and its contributors''
                     10:  * in the documentation or other materials provided with the distribution
                     11:  * and in all advertising materials mentioning features or use of this
                     12:  * software. Neither the name of the University nor the names of its
                     13:  * contributors may be used to endorse or promote products derived
                     14:  * from this software without specific prior written permission.
                     15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     18:  */
                     19: 
                     20: #ifndef lint
                     21: static char sccsid[] = "@(#)utilities.c        5.6 (Berkeley) 6/1/90";
                     22: #endif /* not lint */
                     23: 
                     24: #include "restore.h"
                     25: 
                     26: /*
                     27:  * Insure that all the components of a pathname exist.
                     28:  */
                     29: pathcheck(name)
                     30:        char *name;
                     31: {
                     32:        register char *cp;
                     33:        struct entry *ep;
                     34:        char *start;
                     35: 
                     36:        start = index(name, '/');
                     37:        if (start == 0)
                     38:                return;
                     39:        for (cp = start; *cp != '\0'; cp++) {
                     40:                if (*cp != '/')
                     41:                        continue;
                     42:                *cp = '\0';
                     43:                ep = lookupname(name);
                     44:                if (ep == NIL) {
                     45:                        ep = addentry(name, psearch(name), NODE);
                     46:                        newnode(ep);
                     47:                }
                     48:                ep->e_flags |= NEW|KEEP;
                     49:                *cp = '/';
                     50:        }
                     51: }
                     52: 
                     53: /*
                     54:  * Change a name to a unique temporary name.
                     55:  */
                     56: mktempname(ep)
                     57:        register struct entry *ep;
                     58: {
                     59:        char oldname[MAXPATHLEN];
                     60: 
                     61:        if (ep->e_flags & TMPNAME)
                     62:                badentry(ep, "mktempname: called with TMPNAME");
                     63:        ep->e_flags |= TMPNAME;
                     64:        (void) strcpy(oldname, myname(ep));
                     65:        freename(ep->e_name);
                     66:        ep->e_name = savename(gentempname(ep));
                     67:        ep->e_namlen = strlen(ep->e_name);
                     68:        renameit(oldname, myname(ep));
                     69: }
                     70: 
                     71: /*
                     72:  * Generate a temporary name for an entry.
                     73:  */
                     74: char *
                     75: gentempname(ep)
                     76:        struct entry *ep;
                     77: {
                     78:        static char name[MAXPATHLEN];
                     79:        struct entry *np;
                     80:        long i = 0;
                     81: 
                     82:        for (np = lookupino(ep->e_ino); np != NIL && np != ep; np = np->e_links)
                     83:                i++;
                     84:        if (np == NIL)
                     85:                badentry(ep, "not on ino list");
                     86:        (void) sprintf(name, "%s%d%d", TMPHDR, i, ep->e_ino);
                     87:        return (name);
                     88: }
                     89: 
                     90: /*
                     91:  * Rename a file or directory.
                     92:  */
                     93: renameit(from, to)
                     94:        char *from, *to;
                     95: {
                     96:        if (!Nflag && rename(from, to) < 0) {
                     97:                fprintf(stderr, "Warning: cannot rename %s to %s", from, to);
                     98:                (void) fflush(stderr);
                     99:                perror("");
                    100:                return;
                    101:        }
                    102:        vprintf(stdout, "rename %s to %s\n", from, to);
                    103: }
                    104: 
                    105: /*
                    106:  * Create a new node (directory).
                    107:  */
                    108: newnode(np)
                    109:        struct entry *np;
                    110: {
                    111:        char *cp;
                    112: 
                    113:        if (np->e_type != NODE)
                    114:                badentry(np, "newnode: not a node");
                    115:        cp = myname(np);
                    116:        if (!Nflag && mkdir(cp, 0777) < 0) {
                    117:                np->e_flags |= EXISTED;
                    118:                fprintf(stderr, "Warning: ");
                    119:                (void) fflush(stderr);
                    120:                perror(cp);
                    121:                return;
                    122:        }
                    123:        vprintf(stdout, "Make node %s\n", cp);
                    124: }
                    125: 
                    126: /*
                    127:  * Remove an old node (directory).
                    128:  */
                    129: removenode(ep)
                    130:        register struct entry *ep;
                    131: {
                    132:        char *cp;
                    133: 
                    134:        if (ep->e_type != NODE)
                    135:                badentry(ep, "removenode: not a node");
                    136:        if (ep->e_entries != NIL)
                    137:                badentry(ep, "removenode: non-empty directory");
                    138:        ep->e_flags |= REMOVED;
                    139:        ep->e_flags &= ~TMPNAME;
                    140:        cp = myname(ep);
                    141:        if (!Nflag && rmdir(cp) < 0) {
                    142:                fprintf(stderr, "Warning: ");
                    143:                (void) fflush(stderr);
                    144:                perror(cp);
                    145:                return;
                    146:        }
                    147:        vprintf(stdout, "Remove node %s\n", cp);
                    148: }
                    149: 
                    150: /*
                    151:  * Remove a leaf.
                    152:  */
                    153: removeleaf(ep)
                    154:        register struct entry *ep;
                    155: {
                    156:        char *cp;
                    157: 
                    158:        if (ep->e_type != LEAF)
                    159:                badentry(ep, "removeleaf: not a leaf");
                    160:        ep->e_flags |= REMOVED;
                    161:        ep->e_flags &= ~TMPNAME;
                    162:        cp = myname(ep);
                    163:        if (!Nflag && unlink(cp) < 0) {
                    164:                fprintf(stderr, "Warning: ");
                    165:                (void) fflush(stderr);
                    166:                perror(cp);
                    167:                return;
                    168:        }
                    169:        vprintf(stdout, "Remove leaf %s\n", cp);
                    170: }
                    171: 
                    172: /*
                    173:  * Create a link.
                    174:  */
                    175: linkit(existing, new, type)
                    176:        char *existing, *new;
                    177:        int type;
                    178: {
                    179: 
                    180:        if (type == SYMLINK) {
                    181:                if (!Nflag && symlink(existing, new) < 0) {
                    182:                        fprintf(stderr,
                    183:                                "Warning: cannot create symbolic link %s->%s: ",
                    184:                                new, existing);
                    185:                        (void) fflush(stderr);
                    186:                        perror("");
                    187:                        return (FAIL);
                    188:                }
                    189:        } else if (type == HARDLINK) {
                    190:                if (!Nflag && link(existing, new) < 0) {
                    191:                        fprintf(stderr,
                    192:                                "Warning: cannot create hard link %s->%s: ",
                    193:                                new, existing);
                    194:                        (void) fflush(stderr);
                    195:                        perror("");
                    196:                        return (FAIL);
                    197:                }
                    198:        } else {
                    199:                panic("linkit: unknown type %d\n", type);
                    200:                return (FAIL);
                    201:        }
                    202:        vprintf(stdout, "Create %s link %s->%s\n",
                    203:                type == SYMLINK ? "symbolic" : "hard", new, existing);
                    204:        return (GOOD);
                    205: }
                    206: 
                    207: /*
                    208:  * find lowest number file (above "start") that needs to be extracted
                    209:  */
                    210: ino_t
                    211: lowerbnd(start)
                    212:        ino_t start;
                    213: {
                    214:        register struct entry *ep;
                    215: 
                    216:        for ( ; start < maxino; start++) {
                    217:                ep = lookupino(start);
                    218:                if (ep == NIL || ep->e_type == NODE)
                    219:                        continue;
                    220:                if (ep->e_flags & (NEW|EXTRACT))
                    221:                        return (start);
                    222:        }
                    223:        return (start);
                    224: }
                    225: 
                    226: /*
                    227:  * find highest number file (below "start") that needs to be extracted
                    228:  */
                    229: ino_t
                    230: upperbnd(start)
                    231:        ino_t start;
                    232: {
                    233:        register struct entry *ep;
                    234: 
                    235:        for ( ; start > ROOTINO; start--) {
                    236:                ep = lookupino(start);
                    237:                if (ep == NIL || ep->e_type == NODE)
                    238:                        continue;
                    239:                if (ep->e_flags & (NEW|EXTRACT))
                    240:                        return (start);
                    241:        }
                    242:        return (start);
                    243: }
                    244: 
                    245: /*
                    246:  * report on a badly formed entry
                    247:  */
                    248: badentry(ep, msg)
                    249:        register struct entry *ep;
                    250:        char *msg;
                    251: {
                    252: 
                    253:        fprintf(stderr, "bad entry: %s\n", msg);
                    254:        fprintf(stderr, "name: %s\n", myname(ep));
                    255:        fprintf(stderr, "parent name %s\n", myname(ep->e_parent));
                    256:        if (ep->e_sibling != NIL)
                    257:                fprintf(stderr, "sibling name: %s\n", myname(ep->e_sibling));
                    258:        if (ep->e_entries != NIL)
                    259:                fprintf(stderr, "next entry name: %s\n", myname(ep->e_entries));
                    260:        if (ep->e_links != NIL)
                    261:                fprintf(stderr, "next link name: %s\n", myname(ep->e_links));
                    262:        if (ep->e_next != NIL)
                    263:                fprintf(stderr, "next hashchain name: %s\n", myname(ep->e_next));
                    264:        fprintf(stderr, "entry type: %s\n",
                    265:                ep->e_type == NODE ? "NODE" : "LEAF");
                    266:        fprintf(stderr, "inode number: %ld\n", ep->e_ino);
                    267:        panic("flags: %s\n", flagvalues(ep));
                    268: }
                    269: 
                    270: /*
                    271:  * Construct a string indicating the active flag bits of an entry.
                    272:  */
                    273: char *
                    274: flagvalues(ep)
                    275:        register struct entry *ep;
                    276: {
                    277:        static char flagbuf[BUFSIZ];
                    278: 
                    279:        (void) strcpy(flagbuf, "|NIL");
                    280:        flagbuf[0] = '\0';
                    281:        if (ep->e_flags & REMOVED)
                    282:                (void) strcat(flagbuf, "|REMOVED");
                    283:        if (ep->e_flags & TMPNAME)
                    284:                (void) strcat(flagbuf, "|TMPNAME");
                    285:        if (ep->e_flags & EXTRACT)
                    286:                (void) strcat(flagbuf, "|EXTRACT");
                    287:        if (ep->e_flags & NEW)
                    288:                (void) strcat(flagbuf, "|NEW");
                    289:        if (ep->e_flags & KEEP)
                    290:                (void) strcat(flagbuf, "|KEEP");
                    291:        if (ep->e_flags & EXISTED)
                    292:                (void) strcat(flagbuf, "|EXISTED");
                    293:        return (&flagbuf[1]);
                    294: }
                    295: 
                    296: /*
                    297:  * Check to see if a name is on a dump tape.
                    298:  */
                    299: ino_t
                    300: dirlookup(name)
                    301:        char *name;
                    302: {
                    303:        ino_t ino;
                    304: 
                    305:        ino = psearch(name);
                    306:        if (ino == 0 || BIT(ino, dumpmap) == 0)
                    307:                fprintf(stderr, "%s is not on tape\n", name);
                    308:        return (ino);
                    309: }
                    310: 
                    311: /*
                    312:  * Elicit a reply.
                    313:  */
                    314: reply(question)
                    315:        char *question;
                    316: {
                    317:        char c;
                    318: 
                    319:        do      {
                    320:                fprintf(stderr, "%s? [yn] ", question);
                    321:                (void) fflush(stderr);
                    322:                c = getc(terminal);
                    323:                while (c != '\n' && getc(terminal) != '\n')
                    324:                        if (feof(terminal))
                    325:                                return (FAIL);
                    326:        } while (c != 'y' && c != 'n');
                    327:        if (c == 'y')
                    328:                return (GOOD);
                    329:        return (FAIL);
                    330: }
                    331: 
                    332: /*
                    333:  * handle unexpected inconsistencies
                    334:  */
                    335: /* VARARGS1 */
                    336: panic(msg, d1, d2)
                    337:        char *msg;
                    338:        long d1, d2;
                    339: {
                    340: 
                    341:        fprintf(stderr, msg, d1, d2);
                    342:        if (yflag)
                    343:                return;
                    344:        if (reply("abort") == GOOD) {
                    345:                if (reply("dump core") == GOOD)
                    346:                        abort();
                    347:                done(1);
                    348:        }
                    349: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.