Annotation of 43BSD/etc/restore/utilities.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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