xref: /original-bsd/usr.sbin/mtree/util.c (revision 10020db5)
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