1 /* $NetBSD: spec.c,v 1.12 1998/09/23 19:46:00 itohy Exp $ */
4 * Copyright (c) 1989, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. All advertising materials mentioning features or use of this software
16 * must display the following acknowledgement:
17 * This product includes software developed by the University of
18 * California, Berkeley and its contributors.
19 * 4. Neither the name of the University nor the names of its contributors
20 * may be used to endorse or promote products derived from this software
21 * without specific prior written permission.
23 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 #include <sys/cdefs.h>
39 static char sccsid
[] = "@(#)spec.c 8.2 (Berkeley) 4/28/95";
41 __RCSID("$NetBSD: spec.c,v 1.12 1998/09/23 19:46:00 itohy Exp $");
45 #include <sys/types.h>
59 int lineno
; /* Current spec line number. */
61 static void set
__P((char *, NODE
*));
62 static void unset
__P((char *, NODE
*));
75 memset(&ginfo
, 0, sizeof(ginfo
));
77 for (lineno
= 1; fgets(buf
, sizeof(buf
), stdin
);
78 ++lineno
, c_cur
= c_next
, c_next
= 0) {
79 /* Skip empty lines. */
83 /* Find end of line. */
84 if ((p
= strchr(buf
, '\n')) == NULL
)
85 mtree_err("line %d too long", lineno
);
87 /* See if next line is continuation line. */
93 /* Null-terminate the line. */
96 /* Skip leading whitespace. */
97 for (p
= buf
; *p
&& isspace(*p
); ++p
);
99 /* If nothing but whitespace or comment char, continue. */
100 if (!*p
|| *p
== '#')
104 (void)fprintf(stderr
, "line %d: {%s}\n", lineno
, p
);
111 /* Grab file name, "$", "set", or "unset". */
112 if ((p
= strtok(p
, "\n\t ")) == NULL
)
113 mtree_err("missing field");
118 if (strcmp(p
+ 1, "set"))
123 if (strcmp(p
+ 1, "unset"))
130 mtree_err("slash character in file name");
132 if (!strcmp(p
, "..")) {
133 /* Don't go up, if haven't gone down. */
136 if (last
->type
!= F_DIR
|| last
->flags
& F_DONE
) {
141 last
->flags
|= F_DONE
;
144 noparent
: mtree_err("no parent node");
147 if ((centry
= calloc(1, sizeof(NODE
) + strlen(p
))) == NULL
)
148 mtree_err("%s", strerror(errno
));
150 (void)strcpy(centry
->name
, p
);
152 if (strpbrk(p
, MAGIC
))
153 centry
->flags
|= F_MAGIC
;
157 last
= root
= centry
;
159 } else if (last
->type
== F_DIR
&& !(last
->flags
& F_DONE
)) {
160 centry
->parent
= last
;
161 last
= last
->child
= centry
;
163 centry
->parent
= last
->parent
;
165 last
= last
->next
= centry
;
185 for (; (kw
= strtok(t
, "= \t\n")) != NULL
; t
= NULL
) {
186 ip
->flags
|= type
= parsekey(kw
, &value
);
187 if (value
&& (val
= strtok(NULL
, " \t\n")) == NULL
)
188 mtree_err("missing value");
191 ip
->cksum
= strtoul(val
, &ep
, 10);
193 mtree_err("invalid checksum %s", val
);
196 ip
->st_gid
= (gid_t
)strtoul(val
, &ep
, 10);
198 mtree_err("invalid gid %s", val
);
201 if ((gr
= getgrnam(val
)) == NULL
)
202 mtree_err("unknown group %s", val
);
203 ip
->st_gid
= gr
->gr_gid
;
206 /* just set flag bit */
209 if ((m
= setmode(val
)) == NULL
)
210 mtree_err("invalid file mode %s", val
);
211 ip
->st_mode
= getmode(m
, 0);
215 ip
->st_nlink
= (nlink_t
)strtoul(val
, &ep
, 10);
217 mtree_err("invalid link count %s", val
);
220 ip
->st_size
= (off_t
)strtoq(val
, &ep
, 10);
222 mtree_err("invalid size %s", val
);
225 if ((ip
->slink
= strdup(val
)) == NULL
)
226 mtree_err("%s", strerror(errno
));
229 ip
->st_mtimespec
.tv_sec
=
230 (time_t)strtoul(val
, &ep
, 10);
232 mtree_err("invalid time %s", val
);
234 ip
->st_mtimespec
.tv_nsec
= strtol(val
, &ep
, 10);
236 mtree_err("invalid time %s", val
);
241 if (!strcmp(val
, "block"))
245 if (!strcmp(val
, "char"))
249 if (!strcmp(val
, "dir"))
253 if (!strcmp(val
, "file"))
255 if (!strcmp(val
, "fifo"))
259 if (!strcmp(val
, "link"))
263 if (!strcmp(val
, "socket"))
267 mtree_err("unknown file type %s", val
);
271 ip
->st_uid
= (uid_t
)strtoul(val
, &ep
, 10);
273 mtree_err("invalid uid %s", val
);
276 if ((pw
= getpwnam(val
)) == NULL
)
277 mtree_err("unknown user %s", val
);
278 ip
->st_uid
= pw
->pw_uid
;
291 while ((p
= strtok(t
, "\n\t ")) != NULL
)
292 ip
->flags
&= ~parsekey(p
, NULL
);