2 Copyright © 1995-2001, 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()
70 27-Jul-1997 laguest -- Initial inclusion into the AROS tree
71 3.12.2000 SDuvan -- Rewrote, simplified and implemented missing
74 ******************************************************************************/
78 #include <dos/dosasl.h>
79 #include <dos/dosextens.h>
80 #include <dos/exall.h>
81 #include <dos/rdargs.h>
82 #include <exec/memory.h>
83 #include <exec/types.h>
84 #include <utility/utility.h>
86 #include <proto/arossupport.h>
87 #include <proto/dos.h>
88 #include <proto/exec.h>
92 #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
94 #define Bit_Mask(bit) (1L << bit)
95 #define Bit_Clear(name, bit) name &= ~Bit_Mask(bit)
96 #define Bit_Set(name, bit) name |= Bit_Mask(bit)
98 #define ARG_TEMPLATE "FILE/A,FLAGS,ADD/S,SUB/S,ALL/S,QUIET/S"
104 #define FIBF_HOLD (1<<FIBB_HOLD)
119 /* To define whether a command line switch was set or not.
121 #define NOT_SET(x) (x == 0)
122 #define IS_SET(x) (!NOT_SET(x))
124 #define MAX_PATH_LEN 512
126 static const char version
[] = "$VER: Protect 41.1 (2.12.2000)\n";
128 struct UtilityBase
*UtilityBase
;
130 int Do_Protect(struct AnchorPath
*, STRPTR
, STRPTR
, BOOL
, BOOL
, BOOL
, BOOL
);
132 int doProtect(struct AnchorPath
*ap
, STRPTR file
, LONG flags
, BOOL flagsSet
,
133 BOOL add
, BOOL sub
, BOOL all
, BOOL quiet
);
134 BOOL
setProtection(STRPTR file
, LONG oldFlags
, LONG flags
, BOOL flagsSet
,
142 struct AnchorPath
*apath
;
144 IPTR args
[NOOFARGS
] = { NULL
,
151 int retval
= RETURN_OK
;
153 apath
= AllocVec(sizeof(struct AnchorPath
) + MAX_PATH_LEN
,
154 MEMF_ANY
| MEMF_CLEAR
);
158 /* Make sure DOS knows the buffer size. */
159 apath
->ap_Strlen
= MAX_PATH_LEN
;
161 rda
= ReadArgs(ARG_TEMPLATE
, args
, NULL
);
165 STRPTR file
= (STRPTR
)args
[ARG_FILE
];
166 STRPTR flags
= (STRPTR
)args
[ARG_FLAGS
];
167 BOOL add
= (BOOL
)args
[ARG_ADD
];
168 BOOL sub
= (BOOL
)args
[ARG_SUB
];
169 BOOL all
= (BOOL
)args
[ARG_ALL
];
170 BOOL quiet
= (BOOL
)args
[ARG_QUIET
];
172 LONG flagValues
= FIBF_READ
| FIBF_WRITE
| FIBF_DELETE
|
188 while (*flags
!= 0 && retval
== RETURN_OK
)
190 switch (toupper(*flags
))
194 flagValues
&= ~FIBF_READ
;
198 flagValues
&= ~FIBF_WRITE
;
202 flagValues
&= ~FIBF_DELETE
;
206 flagValues
&= ~FIBF_EXECUTE
;
211 flagValues
|= FIBF_ARCHIVE
;
215 flagValues
|= FIBF_SCRIPT
;
219 flagValues
|= FIBF_PURE
;
223 flagValues
|= FIBF_HOLD
;
227 Printf("Invalid flags - must be one of HSPARWED\n");
228 retval
= RETURN_FAIL
;
232 } /* while (*flags != 0) */
237 Printf("ADD and SUB are mutually exclusive\n");
238 retval
= RETURN_FAIL
;
241 if (retval
== RETURN_OK
)
243 if (!all
&&IsDosEntryA(file
, LDF_VOLUMES
| LDF_DEVICES
))
245 Printf("Can't set protection for %s - ", file
);
246 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
247 PrintFault(IoErr(), NULL
);
249 retval
= RETURN_FAIL
;
253 retval
= doProtect(apath
, file
, flagValues
,
254 flags
!= NULL
, add
, sub
, all
,
263 PrintFault(IoErr(), "Protect");
264 retval
= RETURN_FAIL
;
269 retval
= RETURN_FAIL
;
277 #define isDir(fib) ((fib)->fib_DirEntryType >= 0)
279 int doProtect(struct AnchorPath
*ap
, STRPTR file
, LONG flags
, BOOL flagsSet
,
280 BOOL add
, BOOL sub
, BOOL all
, BOOL quiet
)
283 int retval
= RETURN_OK
;
285 int i
; /* Loop variable */
288 for (match
= MatchFirst(file
, ap
);
289 match
== 0 && retval
== RETURN_OK
&& !CTRL_C
;
290 match
= MatchNext(ap
))
292 if (isDir(&ap
->ap_Info
))
294 if (ap
->ap_Flags
& APF_DIDDIR
)
297 ap
->ap_Flags
&= ~APF_DIDDIR
; /* Should not be necessary */
302 ap
->ap_Flags
|= APF_DODIR
;
309 error
= setProtection(ap
->ap_Buf
, ap
->ap_Info
.fib_Protection
, flags
,
314 LONG ioerr
= IoErr();
316 /* Fix indentation level */
317 for (i
= 0; i
< indent
; i
++)
322 if (!isDir(&ap
->ap_Info
))
327 PutStr(ap
->ap_Info
.fib_FileName
);
329 if (isDir(&ap
->ap_Info
))
336 PrintFault(ioerr
, "..error");
350 #define ALL_OFF (FIBF_READ | FIBF_WRITE | FIBF_DELETE | FIBF_EXECUTE)
351 #define addFlags(new, old) ((~(~old | ~new) & ALL_OFF) | \
352 ((old | new) & ~ALL_OFF))
354 #define subFlags(new, old) (((old | ~new) & ALL_OFF) | \
355 ((old & ~new) & ~ALL_OFF))
357 BOOL
setProtection(STRPTR file
, LONG oldFlags
, LONG flags
, BOOL flagsSet
,
362 if (flags
!= ALL_OFF
)
366 /* Enable permission */
367 newFlags
= addFlags(flags
, oldFlags
);
371 /* Disable permissions */
372 newFlags
= subFlags(flags
, oldFlags
);
376 /* Clear all permissions then set the ones given. */
382 /* No flags were given */
385 /* Disable all permissions */
395 if (!SetProtection(file
, newFlags
))