Do not install wrong cache routine if called before SysBase is complete.
[AROS.git] / workbench / c / Protect.c
blob0d60f0865d36a20997b51560b14937f6a4cfb9ea
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc: Protect CLI command
6 Lang: English
7 */
9 /*****************************************************************************
11 NAME
13 Protect
15 SYNOPSIS
17 FILE/A,FLAGS,ADD/S,SUB/S,ALL/S,QUIET/S
19 LOCATION
23 FUNCTION
25 Add or remove protection bits from a file or directory.
27 Protect allows the use of pattern matching and recursive directory
28 scans to protect many files/directories at any one time.
30 INPUTS
32 FILE -- Either a file, a directory or a pattern to match.
33 FLAGS -- One or more of the following flags:
35 S - Script
36 P - Pure
37 A - Archive
38 R - Read
39 W - Write
40 E - Execute
41 D - Delete
43 ADD -- Allows the bits to be set and hence allowable.
44 SUB -- Allows the bits to be cleared and hence not allowable.
45 ALL -- Allows a recursive scan of the volume/directory.
46 QUIET -- Suppresses any output to the shell.
48 RESULT
50 Standard DOS return codes.
52 NOTES
54 EXAMPLE
56 Protect ram: e add all
58 Recurses the ram: volume and attaches the executable bit.
60 BUGS
62 SEE ALSO
64 dos.library/SetProtection()
66 INTERNALS
68 ******************************************************************************/
71 #include <dos/dos.h>
72 #include <dos/dosasl.h>
73 #include <dos/dosextens.h>
74 #include <dos/exall.h>
75 #include <dos/rdargs.h>
76 #include <exec/memory.h>
77 #include <exec/types.h>
78 #include <utility/utility.h>
80 #include <proto/arossupport.h>
81 #include <proto/dos.h>
82 #include <proto/exec.h>
84 #include <ctype.h>
86 #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
88 #define Bit_Mask(bit) (1L << bit)
89 #define Bit_Clear(name, bit) name &= ~Bit_Mask(bit)
90 #define Bit_Set(name, bit) name |= Bit_Mask(bit)
92 #define ARG_TEMPLATE "FILE/A,FLAGS,ADD/S,SUB/S,ALL/S,QUIET/S"
94 #ifndef FIBB_HOLD
95 #define FIBB_HOLD 7
96 #endif
97 #ifndef FIBF_HOLD
98 #define FIBF_HOLD (1<<FIBB_HOLD)
99 #endif
101 enum
103 ARG_FILE = 0,
104 ARG_FLAGS,
105 ARG_ADD,
106 ARG_SUB,
107 ARG_ALL,
108 ARG_QUIET,
109 NOOFARGS
113 /* To define whether a command line switch was set or not.
115 #define NOT_SET(x) (x == 0)
116 #define IS_SET(x) (!NOT_SET(x))
118 #define MAX_PATH_LEN 512
120 const TEXT version[] = "$VER: Protect 41.1 (2.12.2000)\n";
122 struct UtilityBase *UtilityBase;
124 int Do_Protect(struct AnchorPath *, STRPTR, STRPTR, BOOL, BOOL, BOOL, BOOL);
126 int doProtect(struct AnchorPath *ap, STRPTR file, LONG flags, BOOL flagsSet,
127 BOOL add, BOOL sub, BOOL all, BOOL quiet);
128 BOOL setProtection(STRPTR file, LONG oldFlags, LONG flags, BOOL flagsSet,
129 BOOL add, BOOL sub);
131 int __nocommandline;
133 int main(void)
135 struct RDArgs *rda;
136 struct AnchorPath *apath;
138 IPTR args[NOOFARGS] = { NULL,
139 NULL,
140 (IPTR)FALSE,
141 (IPTR)FALSE,
142 (IPTR)FALSE,
143 (IPTR)FALSE };
145 int retval = RETURN_OK;
147 apath = AllocVec(sizeof(struct AnchorPath) + MAX_PATH_LEN,
148 MEMF_ANY | MEMF_CLEAR);
150 if (apath != NULL)
152 /* Make sure DOS knows the buffer size. */
153 apath->ap_Strlen = MAX_PATH_LEN;
155 rda = ReadArgs(ARG_TEMPLATE, args, NULL);
157 if (rda != NULL)
159 STRPTR file = (STRPTR)args[ARG_FILE];
160 STRPTR flags = (STRPTR)args[ARG_FLAGS];
161 BOOL add = (BOOL)args[ARG_ADD];
162 BOOL sub = (BOOL)args[ARG_SUB];
163 BOOL all = (BOOL)args[ARG_ALL];
164 BOOL quiet = (BOOL)args[ARG_QUIET];
166 LONG flagValues = FIBF_READ | FIBF_WRITE | FIBF_DELETE |
167 FIBF_EXECUTE;
169 if (flags != NULL)
171 if (*flags == '+')
173 add = TRUE;
174 flags++;
176 if (*flags == '-')
178 sub = TRUE;
179 flags++;
182 while (*flags != 0 && retval == RETURN_OK)
184 switch (toupper(*flags))
186 /* Active low */
187 case 'R':
188 flagValues &= ~FIBF_READ;
189 break;
191 case 'W':
192 flagValues &= ~FIBF_WRITE;
193 break;
195 case 'D':
196 flagValues &= ~FIBF_DELETE;
197 break;
199 case 'E':
200 flagValues &= ~FIBF_EXECUTE;
201 break;
203 /* Active high */
204 case 'A':
205 flagValues |= FIBF_ARCHIVE;
206 break;
208 case 'S':
209 flagValues |= FIBF_SCRIPT;
210 break;
212 case 'P':
213 flagValues |= FIBF_PURE;
214 break;
216 case 'H':
217 flagValues |= FIBF_HOLD;
218 break;
220 default:
221 Printf("Invalid flags - must be one of HSPARWED\n");
222 retval = RETURN_FAIL;
225 flags++;
226 } /* while (*flags != 0) */
229 if (add && sub)
231 Printf("ADD and SUB are mutually exclusive\n");
232 retval = RETURN_FAIL;
235 if (retval == RETURN_OK)
237 if (!all && IsDosEntryA(file, LDF_VOLUMES | LDF_DEVICES))
239 Printf("Can't set protection for %s - ", file);
240 SetIoErr(ERROR_OBJECT_WRONG_TYPE);
241 PrintFault(IoErr(), NULL);
243 retval = RETURN_FAIL;
245 else
247 retval = doProtect(apath, file, flagValues,
248 flags != NULL, add, sub, all,
249 quiet);
253 FreeArgs(rda);
255 else
257 PrintFault(IoErr(), "Protect");
258 retval = RETURN_FAIL;
261 else
263 retval = RETURN_FAIL;
266 FreeVec(apath);
268 return retval;
271 #define isDir(fib) ((fib)->fib_DirEntryType >= 0)
273 int doProtect(struct AnchorPath *ap, STRPTR file, LONG flags, BOOL flagsSet,
274 BOOL add, BOOL sub, BOOL all, BOOL quiet)
276 LONG match;
277 int retval = RETURN_OK;
278 LONG indent = 0;
279 int i; /* Loop variable */
280 BOOL success;
281 ULONG match_count = 0;
283 for (match = MatchFirst(file, ap);
284 match == 0 && retval == RETURN_OK && !CTRL_C;
285 match = MatchNext(ap))
287 match_count++;
288 if (isDir(&ap->ap_Info))
290 if (ap->ap_Flags & APF_DIDDIR)
292 indent--;
293 ap->ap_Flags &= ~APF_DIDDIR; /* Should not be necessary */
294 continue;
296 else if (all)
298 ap->ap_Flags |= APF_DODIR;
299 indent++;
305 success = setProtection(ap->ap_Buf, ap->ap_Info.fib_Protection, flags,
306 flagsSet, add, sub);
308 if (!quiet)
310 LONG ioerr = IoErr();
312 /* Fix indentation level */
313 for (i = 0; i < indent; i++)
315 PutStr(" ");
318 if (!isDir(&ap->ap_Info))
320 PutStr(" ");
323 PutStr(ap->ap_Info.fib_FileName);
325 if (isDir(&ap->ap_Info))
327 PutStr(" (dir)");
330 if (!success)
332 PrintFault(ioerr, "..error");
333 retval = RETURN_ERROR;
335 else
337 PutStr("..done\n");
342 if (match_count == 0 || IoErr() != ERROR_NO_MORE_ENTRIES)
344 PrintFault(IoErr(), NULL);
345 retval = RETURN_ERROR;
348 MatchEnd(ap);
350 return retval;
353 #define ALL_OFF (FIBF_READ | FIBF_WRITE | FIBF_DELETE | FIBF_EXECUTE)
354 #define addFlags(new, old) ((~(~old | ~new) & ALL_OFF) | \
355 ((old | new) & ~ALL_OFF))
357 #define subFlags(new, old) (((old | ~new) & ALL_OFF) | \
358 ((old & ~new) & ~ALL_OFF))
360 BOOL setProtection(STRPTR file, LONG oldFlags, LONG flags, BOOL flagsSet,
361 BOOL add, BOOL sub)
363 LONG newFlags;
365 if (flags != ALL_OFF)
367 if (add)
369 /* Enable permission */
370 newFlags = addFlags(flags, oldFlags);
372 else if (sub)
374 /* Disable permissions */
375 newFlags = subFlags(flags, oldFlags);
377 else
379 /* Clear all permissions then set the ones given. */
380 newFlags = flags;
383 else
385 /* No flags were given */
386 if (!add && !sub)
388 /* Disable all permissions */
389 newFlags = ALL_OFF;
391 else
393 /* Do nothing */
394 return FALSE;
398 if (!SetProtection(file, newFlags))
400 return FALSE;
403 return TRUE;