stat_flags.c revision 1.1 1 /* $NetBSD: stat_flags.c,v 1.1 2006/12/14 19:18:01 christos Exp $ */
2
3 /*-
4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
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. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32 #if HAVE_NBTOOL_CONFIG_H
33 #include "nbtool_config.h"
34 #else
35 #define HAVE_STRUCT_STAT_ST_FLAGS 1
36 #endif
37
38 #include <sys/cdefs.h>
39 #if !defined(lint)
40 #if 0
41 static char sccsid[] = "@(#)stat_flags.c 8.2 (Berkeley) 7/28/94";
42 #else
43 __RCSID("$NetBSD: stat_flags.c,v 1.1 2006/12/14 19:18:01 christos Exp $");
44 #endif
45 #endif /* not lint */
46
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include <fts.h>
50 #include <stddef.h>
51 #include <string.h>
52 #include <stdlib.h>
53
54 #include "util.h"
55
56 #define SAPPEND(s) do { \
57 if (prefix != NULL) \
58 (void)strlcat(string, prefix, sizeof(string)); \
59 (void)strlcat(string, s, sizeof(string)); \
60 prefix = ","; \
61 } while (/* CONSTCOND */ 0)
62
63 /*
64 * flags_to_string --
65 * Convert stat flags to a comma-separated string. If no flags
66 * are set, return the default string.
67 */
68 char *
69 flags_to_string(u_long flags, const char *def)
70 {
71 char *string;
72 const char *prefix;
73 if ((string = malloc(128)) == NULL)
74 return NULL;
75
76 string[0] = '\0';
77 prefix = NULL;
78 #if HAVE_STRUCT_STAT_ST_FLAGS
79 if (flags & UF_APPEND)
80 SAPPEND("uappnd");
81 if (flags & UF_IMMUTABLE)
82 SAPPEND("uchg");
83 if (flags & UF_NODUMP)
84 SAPPEND("nodump");
85 if (flags & UF_OPAQUE)
86 SAPPEND("opaque");
87 if (flags & SF_APPEND)
88 SAPPEND("sappnd");
89 if (flags & SF_ARCHIVED)
90 SAPPEND("arch");
91 if (flags & SF_IMMUTABLE)
92 SAPPEND("schg");
93 #ifdef SF_SNAPSHOT
94 if (flags & SF_SNAPSHOT)
95 SAPPEND("snap");
96 #endif
97 #endif
98 if (prefix != NULL)
99 return string;
100 /*###99 [cc] warning: implicit declaration of function 'free'%%%*/
101 free(string);
102 return strdup(def);
103 }
104
105 #define TEST(a, b, f) { \
106 if (!strcmp(a, b)) { \
107 if (clear) { \
108 if (clrp) \
109 *clrp |= (f); \
110 if (setp) \
111 *setp &= ~(f); \
112 } else { \
113 if (setp) \
114 *setp |= (f); \
115 if (clrp) \
116 *clrp &= ~(f); \
117 } \
118 break; \
119 } \
120 }
121
122 /*
123 * string_to_flags --
124 * Take string of arguments and return stat flags. Return 0 on
125 * success, 1 on failure. On failure, stringp is set to point
126 * to the offending token.
127 */
128 int
129 string_to_flags(char **stringp, u_long *setp, u_long *clrp)
130 {
131 int clear;
132 char *string, *p;
133
134 if (setp)
135 *setp = 0;
136 if (clrp)
137 *clrp = 0;
138
139 #if HAVE_STRUCT_STAT_ST_FLAGS
140 string = *stringp;
141 while ((p = strsep(&string, "\t ,")) != NULL) {
142 clear = 0;
143 *stringp = p;
144 if (*p == '\0')
145 continue;
146 if (p[0] == 'n' && p[1] == 'o') {
147 clear = 1;
148 p += 2;
149 }
150 switch (p[0]) {
151 case 'a':
152 TEST(p, "arch", SF_ARCHIVED);
153 TEST(p, "archived", SF_ARCHIVED);
154 return (1);
155 case 'd':
156 clear = !clear;
157 TEST(p, "dump", UF_NODUMP);
158 return (1);
159 case 'n':
160 /*
161 * Support `nonodump'. Note that
162 * the state of clear is not changed.
163 */
164 TEST(p, "nodump", UF_NODUMP);
165 return (1);
166 case 'o':
167 TEST(p, "opaque", UF_OPAQUE);
168 return (1);
169 case 's':
170 TEST(p, "sappnd", SF_APPEND);
171 TEST(p, "sappend", SF_APPEND);
172 TEST(p, "schg", SF_IMMUTABLE);
173 TEST(p, "schange", SF_IMMUTABLE);
174 TEST(p, "simmutable", SF_IMMUTABLE);
175 return (1);
176 case 'u':
177 TEST(p, "uappnd", UF_APPEND);
178 TEST(p, "uappend", UF_APPEND);
179 TEST(p, "uchg", UF_IMMUTABLE);
180 TEST(p, "uchange", UF_IMMUTABLE);
181 TEST(p, "uimmutable", UF_IMMUTABLE);
182 return (1);
183 default:
184 return (1);
185 }
186 }
187 #endif
188
189 return (0);
190 }
191