|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.