184d9c625SLionel Sambuc /* $NetBSD: misc.c,v 1.34 2012/12/20 19:09:25 christos Exp $ */
2d433a562SThomas Veerman
3d433a562SThomas Veerman /*-
4d433a562SThomas Veerman * Copyright (c) 1991, 1993
5d433a562SThomas Veerman * The Regents of the University of California. All rights reserved.
6d433a562SThomas Veerman *
7d433a562SThomas Veerman * Redistribution and use in source and binary forms, with or without
8d433a562SThomas Veerman * modification, are permitted provided that the following conditions
9d433a562SThomas Veerman * are met:
10d433a562SThomas Veerman * 1. Redistributions of source code must retain the above copyright
11d433a562SThomas Veerman * notice, this list of conditions and the following disclaimer.
12d433a562SThomas Veerman * 2. Redistributions in binary form must reproduce the above copyright
13d433a562SThomas Veerman * notice, this list of conditions and the following disclaimer in the
14d433a562SThomas Veerman * documentation and/or other materials provided with the distribution.
15d433a562SThomas Veerman * 3. Neither the name of the University nor the names of its contributors
16d433a562SThomas Veerman * may be used to endorse or promote products derived from this software
17d433a562SThomas Veerman * without specific prior written permission.
18d433a562SThomas Veerman *
19d433a562SThomas Veerman * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20d433a562SThomas Veerman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21d433a562SThomas Veerman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22d433a562SThomas Veerman * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23d433a562SThomas Veerman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24d433a562SThomas Veerman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25d433a562SThomas Veerman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26d433a562SThomas Veerman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27d433a562SThomas Veerman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28d433a562SThomas Veerman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29d433a562SThomas Veerman * SUCH DAMAGE.
30d433a562SThomas Veerman *
31d433a562SThomas Veerman * @(#)misc.c 8.1 (Berkeley) 6/6/93
32d433a562SThomas Veerman */
33d433a562SThomas Veerman
34d433a562SThomas Veerman #if HAVE_NBTOOL_CONFIG_H
35d433a562SThomas Veerman #include "nbtool_config.h"
36d433a562SThomas Veerman #endif
37d433a562SThomas Veerman
38d433a562SThomas Veerman #include <sys/cdefs.h>
39d433a562SThomas Veerman #if defined(__RCSID) && !defined(lint)
4084d9c625SLionel Sambuc __RCSID("$NetBSD: misc.c,v 1.34 2012/12/20 19:09:25 christos Exp $");
41d433a562SThomas Veerman #endif /* not lint */
42d433a562SThomas Veerman
43d433a562SThomas Veerman #include <sys/types.h>
44d433a562SThomas Veerman #include <sys/stat.h>
45d433a562SThomas Veerman
46d433a562SThomas Veerman #include <stdarg.h>
47d433a562SThomas Veerman #include <stdio.h>
48d433a562SThomas Veerman #include <stdlib.h>
49d433a562SThomas Veerman #include <string.h>
50d433a562SThomas Veerman
51d433a562SThomas Veerman #include "extern.h"
52d433a562SThomas Veerman
5384d9c625SLionel Sambuc #if 1 /* defined(__minix): LSC: our mkfs doesn't understand escaped names,
5484d9c625SLionel Sambuc so always default to netbsd6 escaping mode. */
5584d9c625SLionel Sambuc enum flavor flavor = F_NETBSD6;
5684d9c625SLionel Sambuc #else
5784d9c625SLionel Sambuc enum flavor flavor = F_MTREE;
5884d9c625SLionel Sambuc #endif /* defined(__minix) */
59*0a6a1f1dSLionel Sambuc
60d433a562SThomas Veerman typedef struct _key {
61d433a562SThomas Veerman const char *name; /* key name */
62d433a562SThomas Veerman u_int val; /* value */
63d433a562SThomas Veerman
64d433a562SThomas Veerman #define NEEDVALUE 0x01
65d433a562SThomas Veerman u_int flags;
66d433a562SThomas Veerman } KEY;
67d433a562SThomas Veerman
68d433a562SThomas Veerman /* NB: the following tables must be sorted lexically. */
69d433a562SThomas Veerman static KEY keylist[] = {
70d433a562SThomas Veerman {"cksum", F_CKSUM, NEEDVALUE},
71d433a562SThomas Veerman {"device", F_DEV, NEEDVALUE},
72d433a562SThomas Veerman {"flags", F_FLAGS, NEEDVALUE},
73d433a562SThomas Veerman {"gid", F_GID, NEEDVALUE},
74d433a562SThomas Veerman {"gname", F_GNAME, NEEDVALUE},
75d433a562SThomas Veerman {"ignore", F_IGN, 0},
76d433a562SThomas Veerman {"link", F_SLINK, NEEDVALUE},
77d433a562SThomas Veerman {"md5", F_MD5, NEEDVALUE},
78d433a562SThomas Veerman {"md5digest", F_MD5, NEEDVALUE},
79d433a562SThomas Veerman {"mode", F_MODE, NEEDVALUE},
80d433a562SThomas Veerman {"nlink", F_NLINK, NEEDVALUE},
81a8ef0910SBen Gras {"nochange", F_NOCHANGE, 0},
82d433a562SThomas Veerman {"optional", F_OPT, 0},
83a8ef0910SBen Gras {"ripemd160digest", F_RMD160, NEEDVALUE},
84d433a562SThomas Veerman {"rmd160", F_RMD160, NEEDVALUE},
85d433a562SThomas Veerman {"rmd160digest",F_RMD160, NEEDVALUE},
86d433a562SThomas Veerman {"sha1", F_SHA1, NEEDVALUE},
87d433a562SThomas Veerman {"sha1digest", F_SHA1, NEEDVALUE},
88d433a562SThomas Veerman {"sha256", F_SHA256, NEEDVALUE},
89d433a562SThomas Veerman {"sha256digest",F_SHA256, NEEDVALUE},
90d433a562SThomas Veerman {"sha384", F_SHA384, NEEDVALUE},
91d433a562SThomas Veerman {"sha384digest",F_SHA384, NEEDVALUE},
92d433a562SThomas Veerman {"sha512", F_SHA512, NEEDVALUE},
93d433a562SThomas Veerman {"sha512digest",F_SHA512, NEEDVALUE},
94d433a562SThomas Veerman {"size", F_SIZE, NEEDVALUE},
95d433a562SThomas Veerman {"tags", F_TAGS, NEEDVALUE},
96d433a562SThomas Veerman {"time", F_TIME, NEEDVALUE},
97d433a562SThomas Veerman {"type", F_TYPE, NEEDVALUE},
98d433a562SThomas Veerman {"uid", F_UID, NEEDVALUE},
99d433a562SThomas Veerman {"uname", F_UNAME, NEEDVALUE}
100d433a562SThomas Veerman };
101d433a562SThomas Veerman
102d433a562SThomas Veerman static KEY typelist[] = {
103d433a562SThomas Veerman {"block", F_BLOCK, 0},
104d433a562SThomas Veerman {"char", F_CHAR, 0},
105d433a562SThomas Veerman {"dir", F_DIR, 0},
106d433a562SThomas Veerman #ifdef S_IFDOOR
107d433a562SThomas Veerman {"door", F_DOOR, 0},
108d433a562SThomas Veerman #endif
109d433a562SThomas Veerman {"fifo", F_FIFO, 0},
110d433a562SThomas Veerman {"file", F_FILE, 0},
111d433a562SThomas Veerman {"link", F_LINK, 0},
112d433a562SThomas Veerman {"socket", F_SOCK, 0},
113d433a562SThomas Veerman };
114d433a562SThomas Veerman
115d433a562SThomas Veerman slist_t excludetags, includetags;
116d433a562SThomas Veerman int keys = KEYDEFAULT;
117d433a562SThomas Veerman
118d433a562SThomas Veerman
119d433a562SThomas Veerman int keycompare(const void *, const void *);
120d433a562SThomas Veerman
121d433a562SThomas Veerman u_int
parsekey(const char * name,int * needvaluep)122d433a562SThomas Veerman parsekey(const char *name, int *needvaluep)
123d433a562SThomas Veerman {
124d433a562SThomas Veerman static int allbits;
125d433a562SThomas Veerman KEY *k, tmp;
126d433a562SThomas Veerman
127d433a562SThomas Veerman if (allbits == 0) {
128d433a562SThomas Veerman size_t i;
129d433a562SThomas Veerman
130d433a562SThomas Veerman for (i = 0; i < sizeof(keylist) / sizeof(KEY); i++)
131d433a562SThomas Veerman allbits |= keylist[i].val;
132d433a562SThomas Veerman }
133d433a562SThomas Veerman tmp.name = name;
134d433a562SThomas Veerman if (strcmp(name, "all") == 0)
135d433a562SThomas Veerman return (allbits);
136d433a562SThomas Veerman k = (KEY *)bsearch(&tmp, keylist, sizeof(keylist) / sizeof(KEY),
137d433a562SThomas Veerman sizeof(KEY), keycompare);
138d433a562SThomas Veerman if (k == NULL)
139d433a562SThomas Veerman mtree_err("unknown keyword `%s'", name);
140d433a562SThomas Veerman
141d433a562SThomas Veerman if (needvaluep)
142d433a562SThomas Veerman *needvaluep = k->flags & NEEDVALUE ? 1 : 0;
143d433a562SThomas Veerman
144d433a562SThomas Veerman return (k->val);
145d433a562SThomas Veerman }
146d433a562SThomas Veerman
147d433a562SThomas Veerman u_int
parsetype(const char * name)148d433a562SThomas Veerman parsetype(const char *name)
149d433a562SThomas Veerman {
150d433a562SThomas Veerman KEY *k, tmp;
151d433a562SThomas Veerman
152d433a562SThomas Veerman tmp.name = name;
153d433a562SThomas Veerman k = (KEY *)bsearch(&tmp, typelist, sizeof(typelist) / sizeof(KEY),
154d433a562SThomas Veerman sizeof(KEY), keycompare);
155d433a562SThomas Veerman if (k == NULL)
156d433a562SThomas Veerman mtree_err("unknown file type `%s'", name);
157d433a562SThomas Veerman
158d433a562SThomas Veerman return (k->val);
159d433a562SThomas Veerman }
160d433a562SThomas Veerman
161d433a562SThomas Veerman int
keycompare(const void * a,const void * b)162d433a562SThomas Veerman keycompare(const void *a, const void *b)
163d433a562SThomas Veerman {
164d433a562SThomas Veerman
165d433a562SThomas Veerman return (strcmp(((const KEY *)a)->name, ((const KEY *)b)->name));
166d433a562SThomas Veerman }
167d433a562SThomas Veerman
168d433a562SThomas Veerman void
mtree_err(const char * fmt,...)169d433a562SThomas Veerman mtree_err(const char *fmt, ...)
170d433a562SThomas Veerman {
171d433a562SThomas Veerman va_list ap;
172d433a562SThomas Veerman
173d433a562SThomas Veerman va_start(ap, fmt);
174d433a562SThomas Veerman vwarnx(fmt, ap);
175d433a562SThomas Veerman va_end(ap);
176d433a562SThomas Veerman if (mtree_lineno)
177d433a562SThomas Veerman warnx("failed at line %lu of the specification",
178d433a562SThomas Veerman (u_long) mtree_lineno);
179d433a562SThomas Veerman exit(1);
180d433a562SThomas Veerman /* NOTREACHED */
181d433a562SThomas Veerman }
182d433a562SThomas Veerman
183d433a562SThomas Veerman void
addtag(slist_t * list,char * elem)184d433a562SThomas Veerman addtag(slist_t *list, char *elem)
185d433a562SThomas Veerman {
186d433a562SThomas Veerman
187d433a562SThomas Veerman #define TAG_CHUNK 20
188d433a562SThomas Veerman
189d433a562SThomas Veerman if ((list->count % TAG_CHUNK) == 0) {
190d433a562SThomas Veerman char **new;
191d433a562SThomas Veerman
192d433a562SThomas Veerman new = (char **)realloc(list->list, (list->count + TAG_CHUNK)
193d433a562SThomas Veerman * sizeof(char *));
194d433a562SThomas Veerman if (new == NULL)
195d433a562SThomas Veerman mtree_err("memory allocation error");
196d433a562SThomas Veerman list->list = new;
197d433a562SThomas Veerman }
198d433a562SThomas Veerman list->list[list->count] = elem;
199d433a562SThomas Veerman list->count++;
200d433a562SThomas Veerman }
201d433a562SThomas Veerman
202d433a562SThomas Veerman void
parsetags(slist_t * list,char * args)203d433a562SThomas Veerman parsetags(slist_t *list, char *args)
204d433a562SThomas Veerman {
205d433a562SThomas Veerman char *p, *e;
206d433a562SThomas Veerman int len;
207d433a562SThomas Veerman
208d433a562SThomas Veerman if (args == NULL) {
209d433a562SThomas Veerman addtag(list, NULL);
210d433a562SThomas Veerman return;
211d433a562SThomas Veerman }
212d433a562SThomas Veerman while ((p = strsep(&args, ",")) != NULL) {
213d433a562SThomas Veerman if (*p == '\0')
214d433a562SThomas Veerman continue;
215d433a562SThomas Veerman len = strlen(p) + 3; /* "," + p + ",\0" */
216d433a562SThomas Veerman if ((e = malloc(len)) == NULL)
217d433a562SThomas Veerman mtree_err("memory allocation error");
218d433a562SThomas Veerman snprintf(e, len, ",%s,", p);
219d433a562SThomas Veerman addtag(list, e);
220d433a562SThomas Veerman }
221d433a562SThomas Veerman }
222d433a562SThomas Veerman
223d433a562SThomas Veerman /*
224d433a562SThomas Veerman * matchtags
225d433a562SThomas Veerman * returns 0 if there's a match from the exclude list in the node's tags,
226d433a562SThomas Veerman * or there's an include list and no match.
227d433a562SThomas Veerman * return 1 otherwise.
228d433a562SThomas Veerman */
229d433a562SThomas Veerman int
matchtags(NODE * node)230d433a562SThomas Veerman matchtags(NODE *node)
231d433a562SThomas Veerman {
232d433a562SThomas Veerman int i;
233d433a562SThomas Veerman
234d433a562SThomas Veerman if (node->tags) {
235d433a562SThomas Veerman for (i = 0; i < excludetags.count; i++)
236d433a562SThomas Veerman if (strstr(node->tags, excludetags.list[i]))
237d433a562SThomas Veerman break;
238d433a562SThomas Veerman if (i < excludetags.count)
239d433a562SThomas Veerman return (0);
240d433a562SThomas Veerman
241d433a562SThomas Veerman for (i = 0; i < includetags.count; i++)
242d433a562SThomas Veerman if (strstr(node->tags, includetags.list[i]))
243d433a562SThomas Veerman break;
244d433a562SThomas Veerman if (i > 0 && i == includetags.count)
245d433a562SThomas Veerman return (0);
246d433a562SThomas Veerman } else if (includetags.count > 0) {
247d433a562SThomas Veerman return (0);
248d433a562SThomas Veerman }
249d433a562SThomas Veerman return (1);
250d433a562SThomas Veerman }
251d433a562SThomas Veerman
252d433a562SThomas Veerman u_int
nodetoino(u_int type)253d433a562SThomas Veerman nodetoino(u_int type)
254d433a562SThomas Veerman {
255d433a562SThomas Veerman
256d433a562SThomas Veerman switch (type) {
257d433a562SThomas Veerman case F_BLOCK:
258d433a562SThomas Veerman return S_IFBLK;
259d433a562SThomas Veerman case F_CHAR:
260d433a562SThomas Veerman return S_IFCHR;
261d433a562SThomas Veerman case F_DIR:
262d433a562SThomas Veerman return S_IFDIR;
263d433a562SThomas Veerman case F_FIFO:
264d433a562SThomas Veerman return S_IFIFO;
265d433a562SThomas Veerman case F_FILE:
266d433a562SThomas Veerman return S_IFREG;
267d433a562SThomas Veerman case F_LINK:
268d433a562SThomas Veerman return S_IFLNK;
269d433a562SThomas Veerman #ifdef S_IFSOCK
270d433a562SThomas Veerman case F_SOCK:
271d433a562SThomas Veerman return S_IFSOCK;
272d433a562SThomas Veerman #endif
273d433a562SThomas Veerman default:
274d433a562SThomas Veerman printf("unknown type %d", type);
275d433a562SThomas Veerman abort();
276d433a562SThomas Veerman }
277d433a562SThomas Veerman /* NOTREACHED */
278d433a562SThomas Veerman }
279d433a562SThomas Veerman
280d433a562SThomas Veerman const char *
nodetype(u_int type)281d433a562SThomas Veerman nodetype(u_int type)
282d433a562SThomas Veerman {
283d433a562SThomas Veerman
284d433a562SThomas Veerman return (inotype(nodetoino(type)));
285d433a562SThomas Veerman }
286d433a562SThomas Veerman
287d433a562SThomas Veerman
288d433a562SThomas Veerman const char *
inotype(u_int type)289d433a562SThomas Veerman inotype(u_int type)
290d433a562SThomas Veerman {
291d433a562SThomas Veerman
292d433a562SThomas Veerman switch (type & S_IFMT) {
293d433a562SThomas Veerman case S_IFBLK:
294d433a562SThomas Veerman return ("block");
295d433a562SThomas Veerman case S_IFCHR:
296d433a562SThomas Veerman return ("char");
297d433a562SThomas Veerman case S_IFDIR:
298d433a562SThomas Veerman return ("dir");
299d433a562SThomas Veerman case S_IFIFO:
300d433a562SThomas Veerman return ("fifo");
301d433a562SThomas Veerman case S_IFREG:
302d433a562SThomas Veerman return ("file");
303d433a562SThomas Veerman case S_IFLNK:
304d433a562SThomas Veerman return ("link");
305d433a562SThomas Veerman #ifdef S_IFSOCK
306d433a562SThomas Veerman case S_IFSOCK:
307d433a562SThomas Veerman return ("socket");
308d433a562SThomas Veerman #endif
309d433a562SThomas Veerman #ifdef S_IFDOOR
310d433a562SThomas Veerman case S_IFDOOR:
311d433a562SThomas Veerman return ("door");
312d433a562SThomas Veerman #endif
313d433a562SThomas Veerman default:
314d433a562SThomas Veerman return ("unknown");
315d433a562SThomas Veerman }
316d433a562SThomas Veerman /* NOTREACHED */
317d433a562SThomas Veerman }
318