xref: /original-bsd/bin/ls/stat_flags.c (revision deff14a8)
1 /*-
2  * Copyright (c) 1993
3  *	The Regents of the University of California.  All rights reserved.
4  *
5  * %sccs.include.redist.c%
6  */
7 
8 #ifndef lint
9 static char sccsid[] = "@(#)stat_flags.c	8.2 (Berkeley) 07/28/94";
10 #endif /* not lint */
11 
12 #include <sys/types.h>
13 #include <sys/stat.h>
14 
15 #include <stddef.h>
16 #include <string.h>
17 
18 #define	SAPPEND(s) {							\
19 	if (prefix != NULL)						\
20 		(void)strcat(string, prefix);				\
21 	(void)strcat(string, s);					\
22 	prefix = ",";							\
23 }
24 
25 /*
26  * flags_to_string --
27  *	Convert stat flags to a comma-separated string.  If no flags
28  *	are set, return the default string.
29  */
30 char *
31 flags_to_string(flags, def)
32 	u_long flags;
33 	char *def;
34 {
35 	static char string[128];
36 	char *prefix;
37 
38 	string[0] = '\0';
39 	prefix = NULL;
40 	if (flags & UF_APPEND)
41 		SAPPEND("uappnd");
42 	if (flags & UF_IMMUTABLE)
43 		SAPPEND("uchg");
44 	if (flags & UF_NODUMP)
45 		SAPPEND("nodump");
46 	if (flags & UF_OPAQUE)
47 		SAPPEND("opaque");
48 	if (flags & SF_APPEND)
49 		SAPPEND("sappnd");
50 	if (flags & SF_ARCHIVED)
51 		SAPPEND("arch");
52 	if (flags & SF_IMMUTABLE)
53 		SAPPEND("schg");
54 	return (prefix == NULL && def != NULL ? def : string);
55 }
56 
57 #define	TEST(a, b, f) {							\
58 	if (!memcmp(a, b, sizeof(b))) {					\
59 		if (clear) {						\
60 			if (clrp)					\
61 				*clrp |= (f);				\
62 		} else if (setp)					\
63 			*setp |= (f);					\
64 		break;							\
65 	}								\
66 }
67 
68 /*
69  * string_to_flags --
70  *	Take string of arguments and return stat flags.  Return 0 on
71  *	success, 1 on failure.  On failure, stringp is set to point
72  *	to the offending token.
73  */
74 int
75 string_to_flags(stringp, setp, clrp)
76 	char **stringp;
77 	u_long *setp, *clrp;
78 {
79 	int clear;
80 	char *string, *p;
81 
82 	clear = 0;
83 	if (setp)
84 		*setp = 0;
85 	if (clrp)
86 		*clrp = 0;
87 	string = *stringp;
88 	while ((p = strsep(&string, "\t ,")) != NULL) {
89 		*stringp = p;
90 		if (*p == '\0')
91 			continue;
92 		if (p[0] == 'n' && p[1] == 'o') {
93 			clear = 1;
94 			p += 2;
95 		}
96 		switch (p[0]) {
97 		case 'a':
98 			TEST(p, "arch", SF_ARCHIVED);
99 			TEST(p, "archived", SF_ARCHIVED);
100 			return (1);
101 		case 'd':
102 			clear = !clear;
103 			TEST(p, "dump", UF_NODUMP);
104 			return (1);
105 		case 'o':
106 			TEST(p, "opaque", UF_OPAQUE);
107 			return (1);
108 		case 's':
109 			TEST(p, "sappnd", SF_APPEND);
110 			TEST(p, "sappend", SF_APPEND);
111 			TEST(p, "schg", SF_IMMUTABLE);
112 			TEST(p, "schange", SF_IMMUTABLE);
113 			TEST(p, "simmutable", SF_IMMUTABLE);
114 			return (1);
115 		case 'u':
116 			TEST(p, "uappnd", UF_APPEND);
117 			TEST(p, "uappend", UF_APPEND);
118 			TEST(p, "uchg", UF_IMMUTABLE);
119 			TEST(p, "uchange", UF_IMMUTABLE);
120 			TEST(p, "uimmutable", UF_IMMUTABLE);
121 			/* FALLTHROUGH */
122 		default:
123 			return (1);
124 		}
125 	}
126 	return (0);
127 }
128