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