]> err.no Git - sash/blob - cmd_chattr.c
Stop stripping during build. Also thanks to Helmut Grohne. Closes: #852771
[sash] / cmd_chattr.c
1 /*
2  * Copyright (c) 2014 by David I. Bell
3  * Permission is granted to use, distribute, or modify this source,
4  * provided that this copyright notice remains intact.
5  *
6  * The "chattr" and "lsattr" built-in commands.
7  * These commands are optionally built into sash.
8  * They manipulate the important ext2 file system file attribute flags.
9  */
10
11 #if     HAVE_LINUX_ATTR
12
13 #include <sys/ioctl.h>
14 #include <sys/types.h>
15
16 /*
17  * These were used for old linux versions.
18  * #include <linux/fs.h>
19  * #include <linux/ext2_fs.h>
20  */
21
22 #include <ext2fs/ext2_fs.h>
23
24
25 #include "sash.h"
26
27
28 /*
29  * The chattr command.
30  * This can turn on or off the immutable and append-only ext2 flags.
31  */
32 int
33 do_chattr(int argc, const char ** argv)
34 {
35         const char *    fileName;
36         const char *    options;
37         int *           flagPointer;
38         int             offFlags;
39         int             onFlags;
40         int             oldFlags;
41         int             newFlags;
42         int             fd;
43         int             r;
44
45         r = 0;
46         argc--;
47         argv++;
48
49         /*
50          * Parse the options.
51          */
52         onFlags = 0;
53         offFlags = 0;
54
55         while ((**argv == '-') || (**argv == '+'))
56         {
57                 options = *argv++;
58                 argc--;
59
60                 /*
61                  * Point at the proper flags to be modified.
62                  */
63                 if (*options++ == '+')
64                         flagPointer = &onFlags;
65                 else
66                         flagPointer = &offFlags;
67
68                 /*
69                  * Parse the flag characters.
70                  */
71                 while (*options)
72                 {
73                         switch (*options++)
74                         {
75                                 case 'i':
76                                         *flagPointer |= EXT2_IMMUTABLE_FL;
77                                         break;
78
79                                 case 'a':
80                                         *flagPointer |= EXT2_APPEND_FL;
81                                         break;
82
83                                 default:
84                                         fprintf(stderr, "Unknown flag '%c'\n",
85                                                 options[-1]);
86
87                                         return 1;
88                         }
89                 }
90         }
91
92         /*
93          * Make sure that the attributes are reasonable.
94          */
95         if ((onFlags == 0) && (offFlags == 0))
96         {
97                 fprintf(stderr, "No attributes specified\n");
98
99                 return 1;
100         }
101
102         if ((onFlags & offFlags) != 0)
103         {
104                 fprintf(stderr, "Inconsistent attributes specified\n");
105
106                 return 1;
107         }
108
109         /*
110          * Make sure there are some files to affect.
111          */
112         if (argc <= 0)
113         {
114                 fprintf(stderr, "No files specified for setting attributes\n");
115
116                 return 1;
117         }
118
119         /*
120          * Iterate over all of the file names.
121          */
122         while (argc-- > 0)
123         {
124                 fileName = *argv++;
125
126                 /*
127                  * Open the file name.
128                  */
129                 fd = open(fileName, O_RDONLY | O_NONBLOCK);
130
131                 if (fd < 0)
132                 {
133                         perror(fileName);
134                         r = 1;
135                         continue;
136                 }
137
138                 /*
139                  * Read the current ext2 flag bits.
140                  */
141                 if (ioctl(fd, EXT2_IOC_GETFLAGS, &oldFlags) < 0)
142                 {
143                         perror(fileName);
144                         r = 1;
145                         (void) close(fd);
146
147                         continue;
148                 }
149
150                 /*
151                  * Modify the flag bits as specified.
152                  */
153                 newFlags = oldFlags;
154                 newFlags |= onFlags;
155                 newFlags &= ~offFlags;
156
157                 /*
158                  * If the flags aren't being changed, then close this
159                  * file and continue.
160                  */
161                 if (newFlags == oldFlags)
162                 {
163                         (void) close(fd);
164
165                         continue;
166                 }
167
168                 /*
169                  * Set the new ext2 flag bits.
170                  */
171                 if (ioctl(fd, EXT2_IOC_SETFLAGS, &newFlags) < 0)
172                 {
173                         perror(fileName);
174                         r = 1;
175                         (void) close(fd);
176
177                         continue;
178                 }
179
180                 /*
181                  * Close the file.
182                  */
183                 (void) close(fd);
184         }
185
186         return r;
187 }
188
189
190 /*
191  * The lsattr command.
192  * This lists the immutable and append-only ext2 flags.
193  */
194 int
195 do_lsattr(int argc, const char ** argv)
196 {
197         const char *    fileName;
198         int             r;
199         int             fd;
200         int             status;
201         int             flags;
202         char            string[4];
203
204         r = 0;
205         argc--;
206         argv++;
207
208         /*
209          * Iterate over all of the file names.
210          */
211         while (argc-- > 0)
212         {
213                 fileName = *argv++;
214
215                 /*
216                  * Open the file name.
217                  */
218                 fd = open(fileName, O_RDONLY | O_NONBLOCK);
219
220                 if (fd < 0)
221                 {
222                         perror(fileName);
223                         r = 1;
224                         continue;
225                 }
226
227                 /*
228                  * Read the ext2 flag bits.
229                  */
230                 status = ioctl(fd, EXT2_IOC_GETFLAGS, &flags);
231
232                 /*
233                  * Close the file and check the status.
234                  */
235                 (void) close(fd);
236
237                 if (status < 0)
238                 {
239                         perror(fileName);
240                         r = 1;
241
242                         continue;
243                 }
244
245                 /*
246                  * Build up the string according to the flags.
247                  * This is 'i' for immutable, and 'a' for append only.
248                  */
249                 string[0] = ((flags & EXT2_IMMUTABLE_FL) ? 'i' : '-');
250                 string[1] = ((flags & EXT2_APPEND_FL) ? 'a' : '-');
251                 string[2] = '\0';
252
253                 /*
254                  * Print the flags and the file name.
255                  */
256                 printf("%s  %s\n", string, fileName);
257         }
258
259         return r;
260 }
261
262 #endif
263
264
265 /* END CODE */