1*388550b0Srillig /* $NetBSD: stat_flags.c,v 1.3 2022/04/19 20:32:17 rillig Exp $ */
233d6b113Schristos
333d6b113Schristos /*-
433d6b113Schristos * Copyright (c) 1993
533d6b113Schristos * The Regents of the University of California. All rights reserved.
633d6b113Schristos *
733d6b113Schristos * Redistribution and use in source and binary forms, with or without
833d6b113Schristos * modification, are permitted provided that the following conditions
933d6b113Schristos * are met:
1033d6b113Schristos * 1. Redistributions of source code must retain the above copyright
1133d6b113Schristos * notice, this list of conditions and the following disclaimer.
1233d6b113Schristos * 2. Redistributions in binary form must reproduce the above copyright
1333d6b113Schristos * notice, this list of conditions and the following disclaimer in the
1433d6b113Schristos * documentation and/or other materials provided with the distribution.
1533d6b113Schristos * 3. Neither the name of the University nor the names of its contributors
1633d6b113Schristos * may be used to endorse or promote products derived from this software
1733d6b113Schristos * without specific prior written permission.
1833d6b113Schristos *
1933d6b113Schristos * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
2033d6b113Schristos * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2133d6b113Schristos * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2233d6b113Schristos * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
2333d6b113Schristos * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2433d6b113Schristos * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2533d6b113Schristos * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2633d6b113Schristos * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2733d6b113Schristos * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2833d6b113Schristos * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2933d6b113Schristos * SUCH DAMAGE.
3033d6b113Schristos */
3133d6b113Schristos
3233d6b113Schristos #if HAVE_NBTOOL_CONFIG_H
3333d6b113Schristos #include "nbtool_config.h"
3433d6b113Schristos #else
3533d6b113Schristos #define HAVE_STRUCT_STAT_ST_FLAGS 1
3633d6b113Schristos #endif
3733d6b113Schristos
3833d6b113Schristos #include <sys/cdefs.h>
3933d6b113Schristos #if !defined(lint)
4033d6b113Schristos #if 0
4133d6b113Schristos static char sccsid[] = "@(#)stat_flags.c 8.2 (Berkeley) 7/28/94";
4233d6b113Schristos #else
43*388550b0Srillig __RCSID("$NetBSD: stat_flags.c,v 1.3 2022/04/19 20:32:17 rillig Exp $");
4433d6b113Schristos #endif
4533d6b113Schristos #endif /* not lint */
4633d6b113Schristos
4733d6b113Schristos #include <sys/types.h>
4833d6b113Schristos #include <sys/stat.h>
4933d6b113Schristos #include <fts.h>
5033d6b113Schristos #include <stddef.h>
5133d6b113Schristos #include <string.h>
5233d6b113Schristos #include <stdlib.h>
5333d6b113Schristos
5433d6b113Schristos #include "util.h"
5533d6b113Schristos
5633d6b113Schristos #define SAPPEND(s) do { \
5733d6b113Schristos if (prefix != NULL) \
5833d6b113Schristos (void)strlcat(string, prefix, sizeof(string)); \
5933d6b113Schristos (void)strlcat(string, s, sizeof(string)); \
6033d6b113Schristos prefix = ","; \
61*388550b0Srillig } while (0)
6233d6b113Schristos
6333d6b113Schristos /*
6433d6b113Schristos * flags_to_string --
6533d6b113Schristos * Convert stat flags to a comma-separated string. If no flags
6633d6b113Schristos * are set, return the default string.
6733d6b113Schristos */
6833d6b113Schristos char *
flags_to_string(u_long flags,const char * def)6933d6b113Schristos flags_to_string(u_long flags, const char *def)
7033d6b113Schristos {
7113b35046Scbiere char string[128];
7233d6b113Schristos const char *prefix;
7333d6b113Schristos
7433d6b113Schristos string[0] = '\0';
7533d6b113Schristos prefix = NULL;
7633d6b113Schristos #if HAVE_STRUCT_STAT_ST_FLAGS
7733d6b113Schristos if (flags & UF_APPEND)
7833d6b113Schristos SAPPEND("uappnd");
7933d6b113Schristos if (flags & UF_IMMUTABLE)
8033d6b113Schristos SAPPEND("uchg");
8133d6b113Schristos if (flags & UF_NODUMP)
8233d6b113Schristos SAPPEND("nodump");
8333d6b113Schristos if (flags & UF_OPAQUE)
8433d6b113Schristos SAPPEND("opaque");
8533d6b113Schristos if (flags & SF_APPEND)
8633d6b113Schristos SAPPEND("sappnd");
8733d6b113Schristos if (flags & SF_ARCHIVED)
8833d6b113Schristos SAPPEND("arch");
8933d6b113Schristos if (flags & SF_IMMUTABLE)
9033d6b113Schristos SAPPEND("schg");
9133d6b113Schristos #ifdef SF_SNAPSHOT
9233d6b113Schristos if (flags & SF_SNAPSHOT)
9333d6b113Schristos SAPPEND("snap");
9433d6b113Schristos #endif
9533d6b113Schristos #endif
9633d6b113Schristos if (prefix != NULL)
9713b35046Scbiere return strdup(string);
9833d6b113Schristos return strdup(def);
9933d6b113Schristos }
10033d6b113Schristos
10133d6b113Schristos #define TEST(a, b, f) { \
10233d6b113Schristos if (!strcmp(a, b)) { \
10333d6b113Schristos if (clear) { \
10433d6b113Schristos if (clrp) \
10533d6b113Schristos *clrp |= (f); \
10633d6b113Schristos if (setp) \
10733d6b113Schristos *setp &= ~(f); \
10833d6b113Schristos } else { \
10933d6b113Schristos if (setp) \
11033d6b113Schristos *setp |= (f); \
11133d6b113Schristos if (clrp) \
11233d6b113Schristos *clrp &= ~(f); \
11333d6b113Schristos } \
11433d6b113Schristos break; \
11533d6b113Schristos } \
11633d6b113Schristos }
11733d6b113Schristos
11833d6b113Schristos /*
11933d6b113Schristos * string_to_flags --
12033d6b113Schristos * Take string of arguments and return stat flags. Return 0 on
12133d6b113Schristos * success, 1 on failure. On failure, stringp is set to point
12233d6b113Schristos * to the offending token.
12333d6b113Schristos */
12433d6b113Schristos int
string_to_flags(char ** stringp,u_long * setp,u_long * clrp)12533d6b113Schristos string_to_flags(char **stringp, u_long *setp, u_long *clrp)
12633d6b113Schristos {
12733d6b113Schristos int clear;
12833d6b113Schristos char *string, *p;
12933d6b113Schristos
13033d6b113Schristos if (setp)
13133d6b113Schristos *setp = 0;
13233d6b113Schristos if (clrp)
13333d6b113Schristos *clrp = 0;
13433d6b113Schristos
13533d6b113Schristos #if HAVE_STRUCT_STAT_ST_FLAGS
13633d6b113Schristos string = *stringp;
13733d6b113Schristos while ((p = strsep(&string, "\t ,")) != NULL) {
13833d6b113Schristos clear = 0;
13933d6b113Schristos *stringp = p;
14033d6b113Schristos if (*p == '\0')
14133d6b113Schristos continue;
14233d6b113Schristos if (p[0] == 'n' && p[1] == 'o') {
14333d6b113Schristos clear = 1;
14433d6b113Schristos p += 2;
14533d6b113Schristos }
14633d6b113Schristos switch (p[0]) {
14733d6b113Schristos case 'a':
14833d6b113Schristos TEST(p, "arch", SF_ARCHIVED);
14933d6b113Schristos TEST(p, "archived", SF_ARCHIVED);
15033d6b113Schristos return (1);
15133d6b113Schristos case 'd':
15233d6b113Schristos clear = !clear;
15333d6b113Schristos TEST(p, "dump", UF_NODUMP);
15433d6b113Schristos return (1);
15533d6b113Schristos case 'n':
15633d6b113Schristos /*
15733d6b113Schristos * Support `nonodump'. Note that
15833d6b113Schristos * the state of clear is not changed.
15933d6b113Schristos */
16033d6b113Schristos TEST(p, "nodump", UF_NODUMP);
16133d6b113Schristos return (1);
16233d6b113Schristos case 'o':
16333d6b113Schristos TEST(p, "opaque", UF_OPAQUE);
16433d6b113Schristos return (1);
16533d6b113Schristos case 's':
16633d6b113Schristos TEST(p, "sappnd", SF_APPEND);
16733d6b113Schristos TEST(p, "sappend", SF_APPEND);
16833d6b113Schristos TEST(p, "schg", SF_IMMUTABLE);
16933d6b113Schristos TEST(p, "schange", SF_IMMUTABLE);
17033d6b113Schristos TEST(p, "simmutable", SF_IMMUTABLE);
17133d6b113Schristos return (1);
17233d6b113Schristos case 'u':
17333d6b113Schristos TEST(p, "uappnd", UF_APPEND);
17433d6b113Schristos TEST(p, "uappend", UF_APPEND);
17533d6b113Schristos TEST(p, "uchg", UF_IMMUTABLE);
17633d6b113Schristos TEST(p, "uchange", UF_IMMUTABLE);
17733d6b113Schristos TEST(p, "uimmutable", UF_IMMUTABLE);
17833d6b113Schristos return (1);
17933d6b113Schristos default:
18033d6b113Schristos return (1);
18133d6b113Schristos }
18233d6b113Schristos }
18333d6b113Schristos #endif
18433d6b113Schristos
18533d6b113Schristos return (0);
18633d6b113Schristos }
187