strtofflags.c revision 150065
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 * 3. All advertising materials mentioning features or use of this software 141556Srgrimes * must display the following acknowledgement: 151556Srgrimes * This product includes software developed by the University of 161556Srgrimes * California, Berkeley and its contributors. 171556Srgrimes * 4. Neither the name of the University nor the names of its contributors 181556Srgrimes * may be used to endorse or promote products derived from this software 191556Srgrimes * without specific prior written permission. 201556Srgrimes * 211556Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 221556Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 231556Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 241556Srgrimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 251556Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 261556Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 271556Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 281556Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 291556Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 301556Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 311556Srgrimes * SUCH DAMAGE. 321556Srgrimes */ 331556Srgrimes 3490039Sobrien#if defined(LIBC_SCCS) && !defined(lint) 3527967Sstevestatic char sccsid[] = "@(#)stat_flags.c 8.1 (Berkeley) 5/31/93"; 3690039Sobrien#endif /* LIBC_SCCS and not lint */ 3790039Sobrien#include <sys/cdefs.h> 3890039Sobrien__FBSDID("$FreeBSD: head/lib/libc/gen/strtofflags.c 150065 2005-09-12 19:52:42Z stefanf $"); 391556Srgrimes 401556Srgrimes#include <sys/types.h> 411556Srgrimes#include <sys/stat.h> 421556Srgrimes 431556Srgrimes#include <stddef.h> 4461746Sjoe#include <stdlib.h> 451556Srgrimes#include <string.h> 46150065Sstefanf#include <unistd.h> 471556Srgrimes 4854827Srobertostatic struct { 4954827Sroberto char *name; 5054827Sroberto u_long flag; 5154827Sroberto int invert; 5254827Sroberto} mapping[] = { 5354827Sroberto /* shorter names per flag first, all prefixed by "no" */ 5454827Sroberto { "nosappnd", SF_APPEND, 0 }, 5554827Sroberto { "nosappend", SF_APPEND, 0 }, 5654827Sroberto { "noarch", SF_ARCHIVED, 0 }, 5754827Sroberto { "noarchived", SF_ARCHIVED, 0 }, 5854827Sroberto { "noschg", SF_IMMUTABLE, 0 }, 5957389Sru { "noschange", SF_IMMUTABLE, 0 }, 6054827Sroberto { "nosimmutable", SF_IMMUTABLE, 0 }, 6157389Sru { "nosunlnk", SF_NOUNLINK, 0 }, 6257389Sru { "nosunlink", SF_NOUNLINK, 0 }, 6394831Sjoe#ifdef SF_SNAPSHOT 6494831Sjoe { "nosnapshot", SF_SNAPSHOT, 0 }, 6594831Sjoe#endif 6654827Sroberto { "nouappnd", UF_APPEND, 0 }, 6754827Sroberto { "nouappend", UF_APPEND, 0 }, 6854827Sroberto { "nouchg", UF_IMMUTABLE, 0 }, 6954827Sroberto { "nouchange", UF_IMMUTABLE, 0 }, 7054827Sroberto { "nouimmutable", UF_IMMUTABLE, 0 }, 7157389Sru { "nodump", UF_NODUMP, 1 }, 7257389Sru { "noopaque", UF_OPAQUE, 0 }, 7357389Sru { "nouunlnk", UF_NOUNLINK, 0 }, 7457389Sru { "nouunlink", UF_NOUNLINK, 0 } 7554827Sroberto}; 7661746Sjoe#define longestflaglen 12 7754827Sroberto#define nmappings (sizeof(mapping) / sizeof(mapping[0])) 781556Srgrimes 791556Srgrimes/* 8061737Sjoe * fflagstostr -- 8161737Sjoe * Convert file flags to a comma-separated string. If no flags 8261738Sjoe * are set, return the empty string. 831556Srgrimes */ 841556Srgrimeschar * 8561738Sjoefflagstostr(flags) 861556Srgrimes u_long flags; 871556Srgrimes{ 8861746Sjoe char *string; 8954827Sroberto char *sp, *dp; 9054827Sroberto u_long setflags; 9154827Sroberto int i; 921556Srgrimes 9361746Sjoe if ((string = (char *)malloc(nmappings * (longestflaglen + 1))) == NULL) 9461746Sjoe return (NULL); 9561746Sjoe 9654827Sroberto setflags = flags; 9754827Sroberto dp = string; 9854827Sroberto for (i = 0; i < nmappings; i++) { 9954827Sroberto if (setflags & mapping[i].flag) { 10054827Sroberto if (dp > string) 10154827Sroberto *dp++ = ','; 10254827Sroberto for (sp = mapping[i].invert ? mapping[i].name : 10354827Sroberto mapping[i].name + 2; *sp; *dp++ = *sp++) ; 10454827Sroberto setflags &= ~mapping[i].flag; 10554827Sroberto } 10654827Sroberto } 10754948Sroberto *dp = '\0'; 10861738Sjoe return (string); 1091556Srgrimes} 1101556Srgrimes 1111556Srgrimes/* 11261737Sjoe * strtofflags -- 11361737Sjoe * Take string of arguments and return file flags. Return 0 on 1141556Srgrimes * success, 1 on failure. On failure, stringp is set to point 1151556Srgrimes * to the offending token. 1161556Srgrimes */ 1171556Srgrimesint 11861737Sjoestrtofflags(stringp, setp, clrp) 1191556Srgrimes char **stringp; 1201556Srgrimes u_long *setp, *clrp; 1211556Srgrimes{ 1221556Srgrimes char *string, *p; 12354827Sroberto int i; 1241556Srgrimes 1251556Srgrimes if (setp) 1261556Srgrimes *setp = 0; 1271556Srgrimes if (clrp) 1281556Srgrimes *clrp = 0; 1291556Srgrimes string = *stringp; 1301556Srgrimes while ((p = strsep(&string, "\t ,")) != NULL) { 1311556Srgrimes *stringp = p; 1321556Srgrimes if (*p == '\0') 1331556Srgrimes continue; 13454827Sroberto for (i = 0; i < nmappings; i++) { 13554827Sroberto if (strcmp(p, mapping[i].name + 2) == 0) { 13654827Sroberto if (mapping[i].invert) { 13754827Sroberto if (clrp) 13854827Sroberto *clrp |= mapping[i].flag; 13954827Sroberto } else { 14054827Sroberto if (setp) 14154827Sroberto *setp |= mapping[i].flag; 14254827Sroberto } 14354827Sroberto break; 14454827Sroberto } else if (strcmp(p, mapping[i].name) == 0) { 14554827Sroberto if (mapping[i].invert) { 14654827Sroberto if (setp) 14754827Sroberto *setp |= mapping[i].flag; 14854827Sroberto } else { 14954827Sroberto if (clrp) 15054827Sroberto *clrp |= mapping[i].flag; 15154827Sroberto } 15254827Sroberto break; 15354827Sroberto } 1541556Srgrimes } 15554827Sroberto if (i == nmappings) 15654827Sroberto return 1; 1571556Srgrimes } 15854827Sroberto return 0; 1591556Srgrimes} 160