strtofflags.c revision 90039
1177526Sjeff/*- 2177526Sjeff * Copyright (c) 1993 3177526Sjeff * The Regents of the University of California. All rights reserved. 4177526Sjeff * 5177526Sjeff * Redistribution and use in source and binary forms, with or without 6177526Sjeff * modification, are permitted provided that the following conditions 7177526Sjeff * are met: 8177526Sjeff * 1. Redistributions of source code must retain the above copyright 9177526Sjeff * notice, this list of conditions and the following disclaimer. 10177526Sjeff * 2. Redistributions in binary form must reproduce the above copyright 11177526Sjeff * notice, this list of conditions and the following disclaimer in the 12177526Sjeff * documentation and/or other materials provided with the distribution. 13177526Sjeff * 3. All advertising materials mentioning features or use of this software 14177526Sjeff * must display the following acknowledgement: 15177526Sjeff * This product includes software developed by the University of 16177526Sjeff * California, Berkeley and its contributors. 17177526Sjeff * 4. Neither the name of the University nor the names of its contributors 18177526Sjeff * may be used to endorse or promote products derived from this software 19177526Sjeff * without specific prior written permission. 20177526Sjeff * 21177526Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22177526Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23177526Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24177526Sjeff * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25177526Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26177526Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27177526Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28177526Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29177526Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30177526Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31177526Sjeff * SUCH DAMAGE. 32177526Sjeff */ 33177526Sjeff 34177526Sjeff#if defined(LIBC_SCCS) && !defined(lint) 35177526Sjeffstatic char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93"; 36177526Sjeff#endif /* LIBC_SCCS and not lint */ 37177526Sjeff#include <sys/cdefs.h> 38177526Sjeff__FBSDID("$FreeBSD: head/lib/libc/gen/strtofflags.c 90039 2002-02-01 00:57:29Z obrien $"); 39177526Sjeff 40177526Sjeff#include <sys/types.h> 41177526Sjeff#include <sys/stat.h> 42177526Sjeff 43177526Sjeff#include <stddef.h> 44177526Sjeff#include <stdlib.h> 45177526Sjeff#include <string.h> 46177526Sjeff 47177526Sjeffstatic struct { 48177526Sjeff char *name; 49177526Sjeff u_long flag; 50177526Sjeff int invert; 51177526Sjeff} mapping[] = { 52177526Sjeff /* shorter names per flag first, all prefixed by "no" */ 53177526Sjeff { "nosappnd", SF_APPEND, 0 }, 54177526Sjeff { "nosappend", SF_APPEND, 0 }, 55177526Sjeff { "noarch", SF_ARCHIVED, 0 }, 56177526Sjeff { "noarchived", SF_ARCHIVED, 0 }, 57177526Sjeff { "noschg", SF_IMMUTABLE, 0 }, 58177526Sjeff { "noschange", SF_IMMUTABLE, 0 }, 59177526Sjeff { "nosimmutable", SF_IMMUTABLE, 0 }, 60177526Sjeff { "nosunlnk", SF_NOUNLINK, 0 }, 61177526Sjeff { "nosunlink", SF_NOUNLINK, 0 }, 62177526Sjeff { "nouappnd", UF_APPEND, 0 }, 63177526Sjeff { "nouappend", UF_APPEND, 0 }, 64177526Sjeff { "nouchg", UF_IMMUTABLE, 0 }, 65177526Sjeff { "nouchange", UF_IMMUTABLE, 0 }, 66177526Sjeff { "nouimmutable", UF_IMMUTABLE, 0 }, 67177526Sjeff { "nodump", UF_NODUMP, 1 }, 68177526Sjeff { "noopaque", UF_OPAQUE, 0 }, 69177526Sjeff { "nouunlnk", UF_NOUNLINK, 0 }, 70177526Sjeff { "nouunlink", UF_NOUNLINK, 0 } 71177526Sjeff}; 72177526Sjeff#define longestflaglen 12 73177526Sjeff#define nmappings (sizeof(mapping) / sizeof(mapping[0])) 74177526Sjeff 75177526Sjeff/* 76177526Sjeff * fflagstostr -- 77177526Sjeff * Convert file flags to a comma-separated string. If no flags 78177526Sjeff * are set, return the empty string. 79177526Sjeff */ 80177526Sjeffchar * 81177526Sjefffflagstostr(flags) 82177526Sjeff u_long flags; 83177526Sjeff{ 84177526Sjeff char *string; 85177526Sjeff char *sp, *dp; 86177526Sjeff u_long setflags; 87177526Sjeff int i; 88177526Sjeff 89177526Sjeff if ((string = (char *)malloc(nmappings * (longestflaglen + 1))) == NULL) 90177526Sjeff return (NULL); 91177526Sjeff 92177526Sjeff setflags = flags; 93177526Sjeff dp = string; 94177526Sjeff for (i = 0; i < nmappings; i++) { 95177526Sjeff if (setflags & mapping[i].flag) { 96177526Sjeff if (dp > string) 97177526Sjeff *dp++ = ','; 98177526Sjeff for (sp = mapping[i].invert ? mapping[i].name : 99177526Sjeff mapping[i].name + 2; *sp; *dp++ = *sp++) ; 100177526Sjeff setflags &= ~mapping[i].flag; 101177526Sjeff } 102177526Sjeff } 103177526Sjeff *dp = '\0'; 104177526Sjeff return (string); 105177526Sjeff} 106177526Sjeff 107177526Sjeff/* 108177526Sjeff * strtofflags -- 109177526Sjeff * Take string of arguments and return file flags. Return 0 on 110177526Sjeff * success, 1 on failure. On failure, stringp is set to point 111177526Sjeff * to the offending token. 112177526Sjeff */ 113177526Sjeffint 114177526Sjeffstrtofflags(stringp, setp, clrp) 115177526Sjeff char **stringp; 116177526Sjeff u_long *setp, *clrp; 117177526Sjeff{ 118177526Sjeff char *string, *p; 119177526Sjeff int i; 120177526Sjeff 121177526Sjeff if (setp) 122177526Sjeff *setp = 0; 123177526Sjeff if (clrp) 124177526Sjeff *clrp = 0; 125177526Sjeff string = *stringp; 126177526Sjeff while ((p = strsep(&string, "\t ,")) != NULL) { 127177526Sjeff *stringp = p; 128177526Sjeff if (*p == '\0') 129177526Sjeff continue; 130177526Sjeff for (i = 0; i < nmappings; i++) { 131177526Sjeff if (strcmp(p, mapping[i].name + 2) == 0) { 132177526Sjeff if (mapping[i].invert) { 133177526Sjeff if (clrp) 134177526Sjeff *clrp |= mapping[i].flag; 135177526Sjeff } else { 136 if (setp) 137 *setp |= mapping[i].flag; 138 } 139 break; 140 } else if (strcmp(p, mapping[i].name) == 0) { 141 if (mapping[i].invert) { 142 if (setp) 143 *setp |= mapping[i].flag; 144 } else { 145 if (clrp) 146 *clrp |= mapping[i].flag; 147 } 148 break; 149 } 150 } 151 if (i == nmappings) 152 return 1; 153 } 154 return 0; 155} 156