xref: /original-bsd/bin/ls/stat_flags.c (revision dc11c638)
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.1 (Berkeley) 05/31/93";
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 & SF_APPEND)
47 		SAPPEND("sappnd");
48 	if (flags & SF_ARCHIVED)
49 		SAPPEND("arch");
50 	if (flags & SF_IMMUTABLE)
51 		SAPPEND("schg");
52 	return (prefix == NULL && def != NULL ? def : string);
53 }
54 
55 #define	TEST(a, b, f) {							\
56 	if (!memcmp(a, b, sizeof(b))) {					\
57 		if (clear) {						\
58 			if (clrp)					\
59 				*clrp |= (f);				\
60 		} else if (setp)					\
61 			*setp |= (f);					\
62 		break;							\
63 	}								\
64 }
65 
66 /*
67  * string_to_flags --
68  *	Take string of arguments and return stat flags.  Return 0 on
69  *	success, 1 on failure.  On failure, stringp is set to point
70  *	to the offending token.
71  */
72 int
73 string_to_flags(stringp, setp, clrp)
74 	char **stringp;
75 	u_long *setp, *clrp;
76 {
77 	int clear;
78 	char *string, *p;
79 
80 	clear = 0;
81 	if (setp)
82 		*setp = 0;
83 	if (clrp)
84 		*clrp = 0;
85 	string = *stringp;
86 	while ((p = strsep(&string, "\t ,")) != NULL) {
87 		*stringp = p;
88 		if (*p == '\0')
89 			continue;
90 		if (p[0] == 'n' && p[1] == 'o') {
91 			clear = 1;
92 			p += 2;
93 		}
94 		switch (p[0]) {
95 		case 'a':
96 			TEST(p, "arch", SF_ARCHIVED);
97 			TEST(p, "archived", SF_ARCHIVED);
98 			return (1);
99 		case 'd':
100 			clear = !clear;
101 			TEST(p, "dump", UF_NODUMP);
102 			return (1);
103 		case 's':
104 			TEST(p, "sappnd", SF_APPEND);
105 			TEST(p, "sappend", SF_APPEND);
106 			TEST(p, "schg", SF_IMMUTABLE);
107 			TEST(p, "schange", SF_IMMUTABLE);
108 			TEST(p, "simmutable", SF_IMMUTABLE);
109 			return (1);
110 		case 'u':
111 			TEST(p, "uappnd", UF_APPEND);
112 			TEST(p, "uappend", UF_APPEND);
113 			TEST(p, "uchg", UF_IMMUTABLE);
114 			TEST(p, "uchange", UF_IMMUTABLE);
115 			TEST(p, "uimmutable", UF_IMMUTABLE);
116 			/* FALLTHROUGH */
117 		default:
118 			return (1);
119 		}
120 	}
121 	return (0);
122 }
123