1 /*
2   Copyright 2021 Northern.tech AS
3 
4   This file is part of CFEngine 3 - written and maintained by Northern.tech AS.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the
8   Free Software Foundation; version 3.
9 
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14 
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
18 
19   To the extent this program is licensed as part of the Enterprise
20   versions of CFEngine, the applicable Commercial Open Source License
21   (COSL) may apply to this file if you as a licensee so wish it. See
22   included file COSL.txt.
23 */
24 
25 /* BSD flags */
26 
27 #include <chflags.h>
28 
29 typedef struct
30 {
31     char *name;
32     u_long bits;
33 } BSDFlag;
34 
35 static const BSDFlag CF_BSDFLAGS[] =
36 {
37     {"arch", (u_long) SF_ARCHIVED},
38     {"archived", (u_long) SF_ARCHIVED},
39     {"nodump", (u_long) UF_NODUMP},
40     {"opaque", (u_long) UF_OPAQUE},
41     {"sappnd", (u_long) SF_APPEND},
42     {"sappend", (u_long) SF_APPEND},
43     {"schg", (u_long) SF_IMMUTABLE},
44     {"schange", (u_long) SF_IMMUTABLE},
45     {"simmutable", (u_long) SF_IMMUTABLE},
46     {"sunlnk", (u_long) SF_NOUNLINK},
47     {"sunlink", (u_long) SF_NOUNLINK},
48     {"uappnd", (u_long) UF_APPEND},
49     {"uappend", (u_long) UF_APPEND},
50     {"uchg", (u_long) UF_IMMUTABLE},
51     {"uchange", (u_long) UF_IMMUTABLE},
52     {"uimmutable", (u_long) UF_IMMUTABLE},
53     {"uunlnk", (u_long) UF_NOUNLINK},
54     {"uunlink", (u_long) UF_NOUNLINK},
55     {NULL, (u_long) 0}
56 };
57 
58 /***************************************************************/
59 
60 static u_long ConvertBSDBits(const char *s);
61 
62 /***************************************************************/
63 
ParseFlagString(Rlist * bitlist,u_long * plusmask,u_long * minusmask)64 bool ParseFlagString(Rlist *bitlist, u_long *plusmask, u_long *minusmask)
65 {
66     // FIXME: ALWAYS returns true
67     if (bitlist == NULL)
68     {
69         return true;
70     }
71 
72     *plusmask = 0;
73     *minusmask = 0;
74 
75     for (const Rlist *rp = bitlist; rp != NULL; rp = rp->next)
76     {
77         const char *flag = RlistScalarValue(rp);
78         char op = *RlistScalarValue(rp);
79 
80         switch (op)
81         {
82         case '-':
83             *minusmask |= ConvertBSDBits(flag + 1);
84             break;
85 
86         case '+':
87             *plusmask |= ConvertBSDBits(flag + 1);
88             break;
89 
90         default:
91             *plusmask |= ConvertBSDBits(flag);
92             break;
93 
94         }
95     }
96 
97     Log(LOG_LEVEL_DEBUG, "ParseFlagString: [PLUS = %lo] [MINUS = %lo]", *plusmask, *minusmask);
98     return true;
99 }
100 
101 /***************************************************************/
102 
ConvertBSDBits(const char * s)103 static u_long ConvertBSDBits(const char *s)
104 {
105     int i;
106 
107     for (i = 0; CF_BSDFLAGS[i].name != NULL; i++)
108     {
109         if (strcmp(s, CF_BSDFLAGS[i].name) == 0)
110         {
111             return CF_BSDFLAGS[i].bits;
112         }
113     }
114 
115     return 0;
116 }
117 
118 /*
119 CHFLAGS(1)              FreeBSD General Commands Manual             CHFLAGS(1)
120 
121 NAME
122      chflags - change file flags
123 
124 SYNOPSIS
125      chflags [-R [-H | -L | -P]] flags file ...
126 
127 DESCRIPTION
128      The chflags utility modifies the file flags of the listed files as speci-
129      fied by the flags operand.
130 
131      The options are as follows:
132 
133      -H      If the -R option is specified, symbolic links on the command line
134              are followed.  (Symbolic links encountered in the tree traversal
135              are not followed.)
136 
137      -L      If the -R option is specified, all symbolic links are followed.
138 
139      -P      If the -R option is specified, no symbolic links are followed.
140 
141      -R      Change the file flags for the file hierarchies rooted in the
142              files instead of just the files themselves.
143 
144      Flags are a comma separated list of keywords.  The following keywords are
145      currently defined:
146 
147            arch    set the archived flag (super-user only)
148            dump    set the dump flag
149            sappnd  set the system append-only flag (super-user only)
150            schg    set the system immutable flag (super-user only)
151            sunlnk  set the system undeletable flag (super-user only)
152            uappnd  set the user append-only flag (owner or super-user only)
153            uchg    set the user immutable flag (owner or super-user only)
154            uunlnk  set the user undeletable flag (owner or super-user only)
155            archived, sappend, schange, simmutable, uappend, uchange, uimmutable,
156            sunlink, uunlink
157                    aliases for the above
158 
159      Putting the letters ``no'' before an option causes the flag to be turned
160      off.  For example:
161 
162            nodump  the file should never be dumped
163 
164      Symbolic links do not have flags, so unless the -H or -L option is set,
165      chflags on a symbolic link always succeeds and has no effect.  The -H, -L
166      and -P options are ignored unless the -R option is specified.  In addi-
167      tion, these options override each other and the command's actions are de-
168      termined by the last one specified.
169 
170      You can use "ls -lo" to see the flags of existing files.
171 
172      The chflags utility exits 0 on success, and >0 if an error occurs.
173 
174 SEE ALSO
175      ls(1),  chflags(2),  stat(2),  fts(3),  symlink(7)
176 
177 HISTORY
178      The chflags command first appeared in 4.4BSD.
179 
180 BSD                             March 31, 1994                               1
181 */
182