Annotation of 43BSDReno/sbin/restore/utilities.c, revision 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.