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: #if !defined(lint) && defined(DOSCCS) 35: static char sccsid[] = "@(#)stat_flags.c 8.1.1 (2.11BSD GTE) 12/3/94"; 36: #endif 37: 38: /* 39: * Modified from the 4.4-Lite version for 2.11BSD. Main change was to 40: * use 'u_short' instead of 'u_long' for the flags word. 41: */ 42: 43: #include <stdio.h> 44: #include <sys/types.h> 45: #include <sys/stat.h> 46: #include <string.h> 47: 48: #define SAPPEND(s) { \ 49: if (prefix != NULL) \ 50: (void)strcat(string, prefix); \ 51: (void)strcat(string, s); \ 52: prefix = ","; \ 53: } 54: 55: /* 56: * flags_to_string -- 57: * Convert stat flags to a comma-separated string. If no flags 58: * are set, return the default string. 59: */ 60: char * 61: flags_to_string(flags, def) 62: register u_short flags; 63: char *def; 64: { 65: static char string[64]; 66: register char *prefix; 67: 68: string[0] = '\0'; 69: prefix = NULL; 70: if (flags & UF_APPEND) 71: SAPPEND("uappnd"); 72: if (flags & UF_IMMUTABLE) 73: SAPPEND("uchg"); 74: if (flags & UF_NODUMP) 75: SAPPEND("nodump"); 76: if (flags & SF_APPEND) 77: SAPPEND("sappnd"); 78: if (flags & SF_ARCHIVED) 79: SAPPEND("arch"); 80: if (flags & SF_IMMUTABLE) 81: SAPPEND("schg"); 82: return (prefix == NULL && def != NULL ? def : string); 83: } 84: 85: #define TEST(a, b, f) { \ 86: if (!memcmp(a, b, sizeof(b))) { \ 87: if (clear) { \ 88: if (clrp) \ 89: *clrp |= (f); \ 90: } else if (setp) \ 91: *setp |= (f); \ 92: break; \ 93: } \ 94: } 95: 96: /* 97: * string_to_flags -- 98: * Take string of arguments and return stat flags. Return 0 on 99: * success, 1 on failure. On failure, stringp is set to point 100: * to the offending token. 101: */ 102: u_short 103: string_to_flags(stringp, setp, clrp) 104: char **stringp; 105: register u_short *setp, *clrp; 106: { 107: int clear; 108: char *string; 109: register char *p; 110: 111: if (setp) 112: *setp = 0; 113: if (clrp) 114: *clrp = 0; 115: string = *stringp; 116: while ((p = strsep(&string, "\t ,")) != NULL) { 117: *stringp = p; 118: if (*p == '\0') 119: continue; 120: if (p[0] == 'n' && p[1] == 'o') { 121: clear = 1; 122: p += 2; 123: } 124: else 125: clear = 0; /* This was done only once on entry! */ 126: switch (p[0]) { 127: case 'a': 128: TEST(p, "arch", SF_ARCHIVED); 129: TEST(p, "archived", SF_ARCHIVED); 130: return (1); 131: case 'd': 132: clear = !clear; 133: TEST(p, "dump", UF_NODUMP); 134: return (1); 135: case 's': 136: TEST(p, "sappnd", SF_APPEND); 137: TEST(p, "sappend", SF_APPEND); 138: TEST(p, "schg", SF_IMMUTABLE); 139: TEST(p, "schange", SF_IMMUTABLE); 140: TEST(p, "simmutable", SF_IMMUTABLE); 141: return (1); 142: case 'u': 143: TEST(p, "uappnd", UF_APPEND); 144: TEST(p, "uappend", UF_APPEND); 145: TEST(p, "uchg", UF_IMMUTABLE); 146: TEST(p, "uchange", UF_IMMUTABLE); 147: TEST(p, "uimmutable", UF_IMMUTABLE); 148: /* FALLTHROUGH */ 149: default: 150: return (1); 151: } 152: } 153: return (0); 154: }