2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
5 Desc: Protect CLI command
9 /*****************************************************************************
17 FILE/A,FLAGS,ADD/S,SUB/S,ALL/S,QUIET/S
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.
32 FILE -- Either a file, a directory or a pattern to match.
33 FLAGS -- One or more of the following flags:
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.
50 Standard DOS return codes.
56 Protect ram: e add all
58 Recurses the ram: volume and attaches the executable bit.
64 dos.library/SetProtection()
68 ******************************************************************************/
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>
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"
98 #define FIBF_HOLD (1<<FIBB_HOLD)
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
,
136 struct AnchorPath
*apath
;
138 IPTR args
[NOOFARGS
] = { NULL
,
145 int retval
= RETURN_OK
;
147 apath
= AllocVec(sizeof(struct AnchorPath
) + MAX_PATH_LEN
,
148 MEMF_ANY
| MEMF_CLEAR
);
152 /* Make sure DOS knows the buffer size. */
153 apath
->ap_Strlen
= MAX_PATH_LEN
;
155 rda
= ReadArgs(ARG_TEMPLATE
, args
, 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
|
182 while (*flags
!= 0 && retval
== RETURN_OK
)
184 switch (toupper(*flags
))
188 flagValues
&= ~FIBF_READ
;
192 flagValues
&= ~FIBF_WRITE
;
196 flagValues
&= ~FIBF_DELETE
;
200 flagValues
&= ~FIBF_EXECUTE
;
205 flagValues
|= FIBF_ARCHIVE
;
209 flagValues
|= FIBF_SCRIPT
;
213 flagValues
|= FIBF_PURE
;
217 flagValues
|= FIBF_HOLD
;
221 Printf("Invalid flags - must be one of HSPARWED\n");
222 retval
= RETURN_FAIL
;
226 } /* while (*flags != 0) */
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
;
247 retval
= doProtect(apath
, file
, flagValues
,
248 flags
!= NULL
, add
, sub
, all
,
257 PrintFault(IoErr(), "Protect");
258 retval
= RETURN_FAIL
;
263 retval
= RETURN_FAIL
;
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
)
277 int retval
= RETURN_OK
;
279 int i
; /* Loop variable */
281 ULONG match_count
= 0;
283 for (match
= MatchFirst(file
, ap
);
284 match
== 0 && retval
== RETURN_OK
&& !CTRL_C
;
285 match
= MatchNext(ap
))
288 if (isDir(&ap
->ap_Info
))
290 if (ap
->ap_Flags
& APF_DIDDIR
)
293 ap
->ap_Flags
&= ~APF_DIDDIR
; /* Should not be necessary */
298 ap
->ap_Flags
|= APF_DODIR
;
305 success
= setProtection(ap
->ap_Buf
, ap
->ap_Info
.fib_Protection
, flags
,
310 LONG ioerr
= IoErr();
312 /* Fix indentation level */
313 for (i
= 0; i
< indent
; i
++)
318 if (!isDir(&ap
->ap_Info
))
323 PutStr(ap
->ap_Info
.fib_FileName
);
325 if (isDir(&ap
->ap_Info
))
332 PrintFault(ioerr
, "..error");
333 retval
= RETURN_ERROR
;
342 if (match_count
== 0 || IoErr() != ERROR_NO_MORE_ENTRIES
)
344 PrintFault(IoErr(), NULL
);
345 retval
= RETURN_ERROR
;
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
,
365 if (flags
!= ALL_OFF
)
369 /* Enable permission */
370 newFlags
= addFlags(flags
, oldFlags
);
374 /* Disable permissions */
375 newFlags
= subFlags(flags
, oldFlags
);
379 /* Clear all permissions then set the ones given. */
385 /* No flags were given */
388 /* Disable all permissions */
398 if (!SetProtection(file
, newFlags
))