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[] = "@(#)util.c 5.1 (Berkeley) 09/04/89"; 20 #endif /* not lint */ 21 22 #include <sys/param.h> 23 #include <sys/time.h> 24 #include <pwd.h> 25 #include <grp.h> 26 #include <stdio.h> 27 #include <ctype.h> 28 #include <strings.h> 29 #include "mtree.h" 30 31 set(p, ip, override) 32 register char *p; 33 INFO *ip; 34 int override; 35 { 36 extern mode_t dmode, fmode; 37 int val; 38 char *kw; 39 gid_t getgroup(); 40 uid_t getowner(); 41 long atol(), strtol(); 42 43 for (kw = p; *p && *p != '='; ++p); 44 if (!*p) 45 specerr(); 46 *p++ = '\0'; 47 ip->flags |= val = key(kw); 48 49 switch(val) { 50 case F_CKSUM: 51 ip->cksum = atol(p); 52 break; 53 case F_DMODE: 54 if (!override) { 55 (void)fprintf(stderr, 56 "mtree: keyword dmode is global only.\n"); 57 specerr(); 58 } 59 dmode = (mode_t)strtol(p, (char **)NULL, 8); 60 break; 61 case F_FMODE: 62 if (!override) { 63 (void)fprintf(stderr, 64 "mtree: keyword fmode is global only.\n"); 65 specerr(); 66 } 67 fmode = (mode_t)strtol(p, (char **)NULL, 8); 68 break; 69 case F_GROUP: 70 ip->st_gid = getgroup(p); 71 break; 72 case F_MODE: 73 if (override) { 74 (void)fprintf(stderr, 75 "mtree: keyword mode is local only.\n"); 76 specerr(); 77 } 78 ip->st_mode = (mode_t)strtol(p, (char **)NULL, 8); 79 break; 80 case F_NLINK: 81 if ((ip->st_nlink = atoi(p)) <= 0) 82 specerr(); 83 break; 84 case F_OWNER: 85 ip->st_uid = getowner(p); 86 break; 87 case F_SIZE: 88 if ((ip->st_size = atol(p)) < 0) 89 specerr(); 90 break; 91 case F_SLINK: 92 if (!(ip->slink = strdup(p))) 93 nomem(); 94 break; 95 case F_TYPE: 96 ip->type = fkey(p); 97 break; 98 } 99 } 100 101 unset(p, ip) 102 char *p; 103 INFO *ip; 104 { 105 ip->flags &= !key(p); 106 } 107 108 key(p) 109 char *p; 110 { 111 switch(*p) { 112 case 'c': 113 if (!strcmp(p, "cksum")) 114 return(F_CKSUM); 115 break; 116 case 'd': 117 if (!strcmp(p, "dmode")) 118 return(F_DMODE); 119 break; 120 case 'f': 121 if (!strcmp(p, "fmode")) 122 return(F_FMODE); 123 break; 124 case 'g': 125 if (!strcmp(p, "group")) 126 return(F_GROUP); 127 break; 128 case 'm': 129 if (!strcmp(p, "mode")) 130 return(F_MODE); 131 break; 132 case 'n': 133 if (!strcmp(p, "nlink")) 134 return(F_NLINK); 135 break; 136 case 'o': 137 if (!strcmp(p, "owner")) 138 return(F_OWNER); 139 break; 140 case 's': 141 if (!strcmp(p, "size")) 142 return(F_SIZE); 143 if (!strcmp(p, "slink")) 144 return(F_SLINK); 145 break; 146 case 't': 147 if (!strcmp(p, "type")) 148 return(F_TYPE); 149 break; 150 } 151 (void)fprintf(stderr, "mtree: unknown keyword.\n"); 152 specerr(); 153 /* NOTREACHED */ 154 } 155 156 fkey(p) 157 char *p; 158 { 159 switch(*p) { 160 case 'b': 161 if (!strcmp(p, "block")) 162 return(F_BLOCK); 163 break; 164 case 'c': 165 if (!strcmp(p, "char")) 166 return(F_CHAR); 167 break; 168 case 'd': 169 if (!strcmp(p, "dir")) 170 return(F_DIR); 171 break; 172 case 'f': 173 if (!strcmp(p, "file")) 174 return(F_FILE); 175 break; 176 case 'l': 177 if (!strcmp(p, "link")) 178 return(F_LINK); 179 break; 180 case 's': 181 if (!strcmp(p, "socket")) 182 return(F_SOCK); 183 break; 184 } 185 (void)fprintf(stderr, "mtree: unknown file type.\n"); 186 specerr(); 187 /* NOTREACHED */ 188 } 189 190 uid_t 191 getowner(p) 192 register char *p; 193 { 194 struct passwd *pw; 195 int val; 196 197 if (isdigit(*p)) { 198 if ((val = atoi(p)) >= 0) 199 return((uid_t)val); 200 (void)fprintf(stderr, "mtree: illegal uid value %s.\n", p); 201 } else if (pw = getpwnam(p)) 202 return(pw->pw_uid); 203 else 204 (void)fprintf(stderr, "mtree: unknown user %s.\n", p); 205 specerr(); 206 /* NOTREACHED */ 207 } 208 209 gid_t 210 getgroup(p) 211 register char *p; 212 { 213 struct group *gr; 214 int val; 215 216 if (isdigit(*p)) { 217 if ((val = atoi(p)) >= 0) 218 return((gid_t)val); 219 (void)fprintf(stderr, "mtree: illegal gid value %s.\n", p); 220 } else if (gr = getgrnam(p)) 221 return(gr->gr_gid); 222 else 223 (void)fprintf(stderr, "mtree: unknown group %s.\n", p); 224 specerr(); 225 /* NOTREACHED */ 226 } 227 228 char * 229 rlink(name) 230 char *name; 231 { 232 extern int errno; 233 extern char path[]; 234 int len; 235 static char lbuf[MAXPATHLEN]; 236 237 len = readlink(name, lbuf, sizeof(lbuf)); 238 if (len == -1) { 239 (void)fprintf(stderr, "mtree: %s: %s.\n", 240 path + 2, strerror(errno)); 241 exit(1); 242 } 243 lbuf[len] = '\0'; 244 return(lbuf); 245 } 246 247 headers() 248 { 249 time_t clock, time(); 250 char curp[MAXPATHLEN], *ctime(), *getlogin(); 251 252 if (!getwd(curp)) { 253 (void)fprintf(stderr, "mtree: %s\n", curp); 254 exit(1); 255 } 256 (void)time(&clock); 257 (void)printf("#\n#\t%s\n#\tby: %s\n#\t%s#\n", 258 curp, getlogin(), ctime(&clock)); 259 } 260 261 specerr() 262 { 263 extern int lineno; 264 265 (void)fprintf(stderr, 266 "mtree: line %d of the specification is incorrect.\n", lineno); 267 exit(1); 268 } 269 270 char * 271 emalloc(size) 272 int size; 273 { 274 char *p, *malloc(); 275 276 /* NOSTRICT */ 277 if (!(p = malloc((u_int)size))) 278 nomem(); 279 bzero(p, size); 280 return(p); 281 } 282 283 nomem() 284 { 285 (void)fprintf(stderr, "mtree: no more memory.\n"); 286 exit(1); 287 } 288