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: }

Defined functions

badentry defined in line 235; used 20 times
flagvalues defined in line 260; used 8 times
gentempname defined in line 61; used 3 times
linkit defined in line 162; used 3 times
lowerbnd defined in line 197; used 8 times
mktempname defined in line 43; used 4 times
newnode defined in line 95; used 4 times
pathcheck defined in line 16; used 2 times
removeleaf defined in line 140; used 7 times
removenode defined in line 116; used 1 times
renameit defined in line 80; used 2 times
reply defined in line 301; used 5 times
upperbnd defined in line 216; used 3 times

Defined variables

sccsid defined in line 8; never used
Last modified: 1985-08-06
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1768
Valid CSS Valid XHTML 1.0 Strict