11556Srgrimes/*- 21556Srgrimes * Copyright (c) 1993 31556Srgrimes * The Regents of the University of California. All rights reserved. 41556Srgrimes * 51556Srgrimes * Redistribution and use in source and binary forms, with or without 61556Srgrimes * modification, are permitted provided that the following conditions 71556Srgrimes * are met: 81556Srgrimes * 1. Redistributions of source code must retain the above copyright 91556Srgrimes * notice, this list of conditions and the following disclaimer. 101556Srgrimes * 2. Redistributions in binary form must reproduce the above copyright 111556Srgrimes * notice, this list of conditions and the following disclaimer in the 121556Srgrimes * documentation and/or other materials provided with the distribution. 131556Srgrimes * 4. Neither the name of the University nor the names of its contributors 141556Srgrimes * may be used to endorse or promote products derived from this software 151556Srgrimes * without specific prior written permission. 161556Srgrimes * 171556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 181556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 191556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 201556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 211556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 221556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 231556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 241556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 251556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 261556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 271556Srgrimes * SUCH DAMAGE. 281556Srgrimes */ 291556Srgrimes 3090039Sobrien#if defined(LIBC_SCCS) && !defined(lint) 3127967Sstevestatic char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93"; 3290039Sobrien#endif /* LIBC_SCCS and not lint */ 3390039Sobrien#include <sys/cdefs.h> 3490039Sobrien__FBSDID("$FreeBSD$"); 351556Srgrimes 361556Srgrimes#include <sys/types.h> 371556Srgrimes#include <sys/stat.h> 381556Srgrimes 391556Srgrimes#include <stddef.h> 4061746Sjoe#include <stdlib.h> 411556Srgrimes#include <string.h> 42150065Sstefanf#include <unistd.h> 431556Srgrimes 44228972Sjilles#define longestflaglen 12 4554827Srobertostatic struct { 46228972Sjilles char name[longestflaglen + 1]; 47228972Sjilles char invert; 4854827Sroberto u_long flag; 49228972Sjilles} const mapping[] = { 5054827Sroberto /* shorter names per flag first, all prefixed by "no" */ 51228972Sjilles { "nosappnd", 0, SF_APPEND }, 52228972Sjilles { "nosappend", 0, SF_APPEND }, 53228972Sjilles { "noarch", 0, SF_ARCHIVED }, 54228972Sjilles { "noarchived", 0, SF_ARCHIVED }, 55228972Sjilles { "noschg", 0, SF_IMMUTABLE }, 56228972Sjilles { "noschange", 0, SF_IMMUTABLE }, 57228972Sjilles { "nosimmutable", 0, SF_IMMUTABLE }, 58228972Sjilles { "nosunlnk", 0, SF_NOUNLINK }, 59228972Sjilles { "nosunlink", 0, SF_NOUNLINK }, 6094831Sjoe#ifdef SF_SNAPSHOT 61228972Sjilles { "nosnapshot", 0, SF_SNAPSHOT }, 6294831Sjoe#endif 63228972Sjilles { "nouappnd", 0, UF_APPEND }, 64228972Sjilles { "nouappend", 0, UF_APPEND }, 65254627Sken { "nouarch", 0, UF_ARCHIVE }, 66254627Sken { "nouarchive", 0, UF_ARCHIVE }, 67254627Sken { "nohidden", 0, UF_HIDDEN }, 68254627Sken { "nouhidden", 0, UF_HIDDEN }, 69228972Sjilles { "nouchg", 0, UF_IMMUTABLE }, 70228972Sjilles { "nouchange", 0, UF_IMMUTABLE }, 71228972Sjilles { "nouimmutable", 0, UF_IMMUTABLE }, 72228972Sjilles { "nodump", 1, UF_NODUMP }, 73254627Sken { "nouunlnk", 0, UF_NOUNLINK }, 74254627Sken { "nouunlink", 0, UF_NOUNLINK }, 75254627Sken { "nooffline", 0, UF_OFFLINE }, 76254627Sken { "nouoffline", 0, UF_OFFLINE }, 77228972Sjilles { "noopaque", 0, UF_OPAQUE }, 78254627Sken { "nordonly", 0, UF_READONLY }, 79254627Sken { "nourdonly", 0, UF_READONLY }, 80254627Sken { "noreadonly", 0, UF_READONLY }, 81254627Sken { "noureadonly", 0, UF_READONLY }, 82254627Sken { "noreparse", 0, UF_REPARSE }, 83254627Sken { "noureparse", 0, UF_REPARSE }, 84254627Sken { "nosparse", 0, UF_SPARSE }, 85254627Sken { "nousparse", 0, UF_SPARSE }, 86254627Sken { "nosystem", 0, UF_SYSTEM }, 87254627Sken { "nousystem", 0, UF_SYSTEM } 8854827Sroberto}; 8954827Sroberto#define nmappings (sizeof(mapping) / sizeof(mapping[0])) 901556Srgrimes 911556Srgrimes/* 9261737Sjoe * fflagstostr -- 9361737Sjoe * Convert file flags to a comma-separated string. If no flags 9461738Sjoe * are set, return the empty string. 951556Srgrimes */ 961556Srgrimeschar * 9761738Sjoefflagstostr(flags) 981556Srgrimes u_long flags; 991556Srgrimes{ 10061746Sjoe char *string; 101229024Sdim const char *sp; 102229024Sdim char *dp; 10354827Sroberto u_long setflags; 10454827Sroberto int i; 1051556Srgrimes 10661746Sjoe if ((string = (char *)malloc(nmappings * (longestflaglen + 1))) == NULL) 10761746Sjoe return (NULL); 10861746Sjoe 10954827Sroberto setflags = flags; 11054827Sroberto dp = string; 11154827Sroberto for (i = 0; i < nmappings; i++) { 11254827Sroberto if (setflags & mapping[i].flag) { 11354827Sroberto if (dp > string) 11454827Sroberto *dp++ = ','; 11554827Sroberto for (sp = mapping[i].invert ? mapping[i].name : 11654827Sroberto mapping[i].name + 2; *sp; *dp++ = *sp++) ; 11754827Sroberto setflags &= ~mapping[i].flag; 11854827Sroberto } 11954827Sroberto } 12054948Sroberto *dp = '\0'; 12161738Sjoe return (string); 1221556Srgrimes} 1231556Srgrimes 1241556Srgrimes/* 12561737Sjoe * strtofflags -- 12661737Sjoe * Take string of arguments and return file flags. Return 0 on 1271556Srgrimes * success, 1 on failure. On failure, stringp is set to point 1281556Srgrimes * to the offending token. 1291556Srgrimes */ 1301556Srgrimesint 13161737Sjoestrtofflags(stringp, setp, clrp) 1321556Srgrimes char **stringp; 1331556Srgrimes u_long *setp, *clrp; 1341556Srgrimes{ 1351556Srgrimes char *string, *p; 13654827Sroberto int i; 1371556Srgrimes 1381556Srgrimes if (setp) 1391556Srgrimes *setp = 0; 1401556Srgrimes if (clrp) 1411556Srgrimes *clrp = 0; 1421556Srgrimes string = *stringp; 1431556Srgrimes while ((p = strsep(&string, "\t ,")) != NULL) { 1441556Srgrimes *stringp = p; 1451556Srgrimes if (*p == '\0') 1461556Srgrimes continue; 14754827Sroberto for (i = 0; i < nmappings; i++) { 14854827Sroberto if (strcmp(p, mapping[i].name + 2) == 0) { 14954827Sroberto if (mapping[i].invert) { 15054827Sroberto if (clrp) 15154827Sroberto *clrp |= mapping[i].flag; 15254827Sroberto } else { 15354827Sroberto if (setp) 15454827Sroberto *setp |= mapping[i].flag; 15554827Sroberto } 15654827Sroberto break; 15754827Sroberto } else if (strcmp(p, mapping[i].name) == 0) { 15854827Sroberto if (mapping[i].invert) { 15954827Sroberto if (setp) 16054827Sroberto *setp |= mapping[i].flag; 16154827Sroberto } else { 16254827Sroberto if (clrp) 16354827Sroberto *clrp |= mapping[i].flag; 16454827Sroberto } 16554827Sroberto break; 16654827Sroberto } 1671556Srgrimes } 16854827Sroberto if (i == nmappings) 16954827Sroberto return 1; 1701556Srgrimes } 17154827Sroberto return 0; 1721556Srgrimes} 173