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