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 6 * provided that the above copyright notice and this paragraph are 7 * duplicated in all such forms and that any documentation, 8 * advertising materials, and other materials related to such 9 * distribution and use acknowledge that the software was developed 10 * by the University of California, Berkeley. The name of the 11 * University may not be used to endorse or promote products derived 12 * from this software without specific prior written permission. 13 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 14 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 15 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 16 */ 17 18 #ifndef lint 19 static char sccsid[] = "@(#)spec.c 5.3 (Berkeley) 05/15/90"; 20 #endif /* not lint */ 21 22 #include <sys/types.h> 23 #include <ctype.h> 24 #include <stdio.h> 25 #include <string.h> 26 #include "mtree.h" 27 28 extern ENTRY *root; /* root of the tree */ 29 int lineno; /* current spec line number */ 30 mode_t dmode; 31 mode_t fmode; 32 33 spec() 34 { 35 register char *p; 36 ENTRY *centry, *last; 37 INFO info; 38 int ch, ignore; 39 char buf[2048], *emalloc(); 40 41 info.flags = 0; 42 last = NULL; 43 for (lineno = 1; fgets(buf, sizeof(buf), stdin); ++lineno) { 44 if (!(p = index(buf, '\n'))) { 45 (void)fprintf(stderr, 46 "mtree: line %d too long.\n", lineno); 47 while ((ch = getchar()) != '\n' && ch != EOF); 48 continue; 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(buf, "\n\t "))) 57 specerr(); 58 59 ignore = 0; 60 if (p[0] == '/') 61 switch(p[1]) { 62 case 'i': 63 ignore = 1; 64 if (!(p = strtok((char *)NULL, "\t "))) 65 specerr(); 66 break; 67 case 's': 68 if (strcmp(p + 1, "set")) 69 break; 70 if (!(p = strtok((char *)NULL, "\t "))) 71 specerr(); 72 set(p, &info, 1); 73 continue; 74 case 'u': 75 if (strcmp(p + 1, "unset")) 76 break; 77 if (!(p = strtok((char *)NULL, "\t "))) 78 specerr(); 79 unset(p, &info); 80 continue; 81 } 82 83 if (index(p, '/')) { 84 (void)fprintf(stderr, 85 "mtree: file names may not contain slashes.\n"); 86 specerr(); 87 } 88 89 if (!(info.flags&F_TYPE)) { 90 (void)fprintf(stderr, "mtree: no type set.\n"); 91 specerr(); 92 } 93 94 if (!strcmp(p, "..")) { 95 /* don't go up, if haven't gone down */ 96 if (!root) 97 noparent(); 98 if (last->info.type != F_DIR || last->flags&F_DONE) { 99 if (last == root) 100 noparent(); 101 last = last->parent; 102 } 103 last->flags |= F_DONE; 104 continue; 105 } 106 107 centry = (ENTRY *)emalloc(sizeof(ENTRY)); 108 if (!(centry->name = strdup(p))) 109 nomem(); 110 centry->info = info; 111 centry->info.st_mode = info.type == F_DIR ? dmode : fmode; 112 centry->flags = ignore; 113 while (p = strtok((char *)NULL, "\t ")) 114 set(p, ¢ry->info, 0); 115 116 if (!root) { 117 last = root = centry; 118 root->parent = root; 119 } else if (last->info.type == F_DIR && !(last->flags&F_DONE)) { 120 centry->parent = last; 121 last = last->child = centry; 122 } else { 123 centry->parent = last->parent; 124 last = last->next = centry; 125 } 126 } 127 } 128 129 noparent() 130 { 131 (void)fprintf(stderr, "mtree: no parent node.\n"); 132 specerr(); 133 } 134