|
|
1.1 ! root 1: /*- ! 2: * Copyright (c) 1989 The Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted provided ! 6: * that: (1) source distributions retain this entire copyright notice and ! 7: * comment, and (2) distributions including binaries display the following ! 8: * acknowledgement: ``This product includes software developed by the ! 9: * University of California, Berkeley and its contributors'' in the ! 10: * documentation or other materials provided with the distribution and in ! 11: * all advertising materials mentioning features or use of this software. ! 12: * Neither the name of the University nor the names of its contributors may ! 13: * be used to endorse or promote products derived from this software without ! 14: * specific prior written permission. ! 15: * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED ! 16: * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF ! 17: * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ! 18: */ ! 19: ! 20: #ifndef lint ! 21: static char sccsid[] = "@(#)spec.c 5.12 (Berkeley) 5/25/90"; ! 22: #endif /* not lint */ ! 23: ! 24: #include <sys/types.h> ! 25: #include <pwd.h> ! 26: #include <grp.h> ! 27: #include <stdio.h> ! 28: #include <errno.h> ! 29: #include <ctype.h> ! 30: #include "mtree.h" ! 31: ! 32: extern NODE *root; /* root of the tree */ ! 33: ! 34: static int lineno; /* current spec line number */ ! 35: ! 36: spec() ! 37: { ! 38: register NODE *centry, *last; ! 39: register char *p; ! 40: NODE ginfo, *emalloc(); ! 41: char buf[2048]; ! 42: ! 43: bzero((void *)&ginfo, sizeof(ginfo)); ! 44: for (lineno = 1; fgets(buf, sizeof(buf), stdin); ++lineno) { ! 45: if (!(p = index(buf, '\n'))) { ! 46: (void)fprintf(stderr, ! 47: "mtree: line %d too long, ignored.\n", lineno); ! 48: exit(1); ! 49: } ! 50: *p = '\0'; ! 51: for (p = buf; *p && isspace(*p); ++p); ! 52: if (!*p || *p == '#') ! 53: continue; ! 54: ! 55: /* grab file name, "$", "set", or "unset" */ ! 56: if (!(p = strtok(p, "\n\t "))) ! 57: specerr(); ! 58: ! 59: if (p[0] == '/') ! 60: switch(p[1]) { ! 61: case 's': ! 62: if (strcmp(p + 1, "set")) ! 63: break; ! 64: set(&ginfo); ! 65: continue; ! 66: case 'u': ! 67: if (strncmp(p + 1, "unset")) ! 68: break; ! 69: unset(&ginfo); ! 70: continue; ! 71: } ! 72: ! 73: if (index(p, '/')) { ! 74: (void)fprintf(stderr, ! 75: "mtree: file names may not contain slashes.\n"); ! 76: specerr(); ! 77: } ! 78: ! 79: if (!strcmp(p, "..")) { ! 80: /* don't go up, if haven't gone down */ ! 81: if (!root) ! 82: noparent(); ! 83: if (last->type != F_DIR || last->flags & F_DONE) { ! 84: if (last == root) ! 85: noparent(); ! 86: last = last->parent; ! 87: } ! 88: last->flags |= F_DONE; ! 89: continue; ! 90: } ! 91: ! 92: centry = emalloc(sizeof(NODE) + strlen(p)); ! 93: *centry = ginfo; ! 94: (void)strcpy(centry->name, p); ! 95: #define MAGIC "?*[" ! 96: if (strpbrk(p, MAGIC)) ! 97: centry->flags |= F_MAGIC; ! 98: set(centry); ! 99: ! 100: if (!root) { ! 101: last = root = centry; ! 102: root->parent = root; ! 103: } else if (last->type == F_DIR && !(last->flags & F_DONE)) { ! 104: centry->parent = last; ! 105: last = last->child = centry; ! 106: } else { ! 107: centry->parent = last->parent; ! 108: centry->prev = last; ! 109: last = last->next = centry; ! 110: } ! 111: } ! 112: } ! 113: ! 114: set(ip) ! 115: register NODE *ip; ! 116: { ! 117: register int type; ! 118: register char *kw, *val; ! 119: gid_t getgroup(); ! 120: uid_t getowner(); ! 121: long atol(), strtol(); ! 122: ! 123: while (kw = strtok((char *)NULL, "= \t\n")) { ! 124: ip->flags |= type = key(kw); ! 125: val = strtok((char *)NULL, " \t\n"); ! 126: if (!val) ! 127: specerr(); ! 128: switch(type) { ! 129: case F_CKSUM: ! 130: ip->cksum = atol(val); ! 131: break; ! 132: case F_GROUP: ! 133: ip->st_gid = getgroup(val); ! 134: break; ! 135: case F_IGN: ! 136: /* just set flag bit */ ! 137: break; ! 138: case F_MODE: { ! 139: mode_t *m, *setmode(); ! 140: ! 141: if (!(m = setmode(val))) { ! 142: (void)fprintf(stderr, ! 143: "mtree: invalid file mode %s.\n", val); ! 144: specerr(); ! 145: } ! 146: ip->st_mode = getmode(m, 0); ! 147: break; ! 148: } ! 149: case F_NLINK: ! 150: ip->st_nlink = atoi(val); ! 151: break; ! 152: case F_OWNER: ! 153: ip->st_uid = getowner(val); ! 154: break; ! 155: case F_SIZE: ! 156: ip->st_size = atol(val); ! 157: break; ! 158: case F_SLINK: ! 159: if (!(ip->slink = strdup(val))) ! 160: nomem(); ! 161: break; ! 162: case F_TIME: ! 163: ip->st_mtime = atol(val); ! 164: break; ! 165: case F_TYPE: ! 166: switch(*val) { ! 167: case 'b': ! 168: if (!strcmp(val, "block")) ! 169: ip->type = F_BLOCK; ! 170: break; ! 171: case 'c': ! 172: if (!strcmp(val, "char")) ! 173: ip->type = F_CHAR; ! 174: break; ! 175: case 'd': ! 176: if (!strcmp(val, "dir")) ! 177: ip->type = F_DIR; ! 178: break; ! 179: case 'f': ! 180: if (!strcmp(val, "file")) ! 181: ip->type = F_FILE; ! 182: if (!strcmp(val, "fifo")) ! 183: ip->type = F_FIFO; ! 184: break; ! 185: case 'l': ! 186: if (!strcmp(val, "link")) ! 187: ip->type = F_LINK; ! 188: break; ! 189: case 's': ! 190: if (!strcmp(val, "socket")) ! 191: ip->type = F_SOCK; ! 192: break; ! 193: default: ! 194: (void)fprintf(stderr, ! 195: "mtree: unknown file type %s.\n", val); ! 196: specerr(); ! 197: } ! 198: break; ! 199: } ! 200: } ! 201: } ! 202: ! 203: unset(ip) ! 204: register NODE *ip; ! 205: { ! 206: register char *p; ! 207: ! 208: while (p = strtok((char *)NULL, "\n\t ")) ! 209: ip->flags &= ~key(p); ! 210: } ! 211: ! 212: key(p) ! 213: char *p; ! 214: { ! 215: switch(*p) { ! 216: case 'c': ! 217: if (!strcmp(p, "cksum")) ! 218: return(F_CKSUM); ! 219: break; ! 220: case 'g': ! 221: if (!strcmp(p, "group")) ! 222: return(F_GROUP); ! 223: break; ! 224: case 'i': ! 225: if (!strcmp(p, "ignore")) ! 226: return(F_IGN); ! 227: break; ! 228: case 'l': ! 229: if (!strcmp(p, "link")) ! 230: return(F_SLINK); ! 231: break; ! 232: case 'm': ! 233: if (!strcmp(p, "mode")) ! 234: return(F_MODE); ! 235: break; ! 236: case 'n': ! 237: if (!strcmp(p, "nlink")) ! 238: return(F_NLINK); ! 239: break; ! 240: case 'o': ! 241: if (!strcmp(p, "owner")) ! 242: return(F_OWNER); ! 243: break; ! 244: case 's': ! 245: if (!strcmp(p, "size")) ! 246: return(F_SIZE); ! 247: break; ! 248: case 't': ! 249: if (!strcmp(p, "type")) ! 250: return(F_TYPE); ! 251: if (!strcmp(p, "time")) ! 252: return(F_TIME); ! 253: break; ! 254: } ! 255: (void)fprintf(stderr, "mtree: unknown keyword %s.\n", p); ! 256: specerr(); ! 257: /* NOTREACHED */ ! 258: } ! 259: ! 260: ! 261: uid_t ! 262: getowner(p) ! 263: register char *p; ! 264: { ! 265: struct passwd *pw; ! 266: int val; ! 267: ! 268: if (isdigit(*p)) { ! 269: if ((val = atoi(p)) >= 0) ! 270: return((uid_t)val); ! 271: (void)fprintf(stderr, "mtree: illegal uid value %s.\n", p); ! 272: } else if (pw = getpwnam(p)) ! 273: return(pw->pw_uid); ! 274: else ! 275: (void)fprintf(stderr, "mtree: unknown user %s.\n", p); ! 276: specerr(); ! 277: /* NOTREACHED */ ! 278: } ! 279: ! 280: gid_t ! 281: getgroup(p) ! 282: register char *p; ! 283: { ! 284: struct group *gr; ! 285: int val; ! 286: ! 287: if (isdigit(*p)) { ! 288: if ((val = atoi(p)) >= 0) ! 289: return((gid_t)val); ! 290: (void)fprintf(stderr, "mtree: illegal gid value %s.\n", p); ! 291: } else if (gr = getgrnam(p)) ! 292: return(gr->gr_gid); ! 293: else ! 294: (void)fprintf(stderr, "mtree: unknown group %s.\n", p); ! 295: specerr(); ! 296: /* NOTREACHED */ ! 297: } ! 298: ! 299: noparent() ! 300: { ! 301: (void)fprintf(stderr, "mtree: no parent node.\n"); ! 302: specerr(); ! 303: } ! 304: ! 305: specerr() ! 306: { ! 307: (void)fprintf(stderr, ! 308: "mtree: line %d of the specification is incorrect.\n", lineno); ! 309: exit(1); ! 310: } ! 311: ! 312: NODE * ! 313: emalloc(size) ! 314: int size; ! 315: { ! 316: void *p; ! 317: ! 318: /* NOSTRICT */ ! 319: if (!(p = malloc((u_int)size))) ! 320: nomem(); ! 321: bzero(p, size); ! 322: return((NODE *)p); ! 323: } ! 324: ! 325: nomem() ! 326: { ! 327: (void)fprintf(stderr, "mtree: %s.\n", strerror(ENOMEM)); ! 328: exit(1); ! 329: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.