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 <aros/debug.h>
74 #include <dos/dosasl.h>
75 #include <dos/dosextens.h>
76 #include <dos/exall.h>
77 #include <dos/rdargs.h>
78 #include <exec/memory.h>
79 #include <exec/types.h>
80 #include <utility/utility.h>
82 #include <proto/arossupport.h>
83 #include <proto/dos.h>
84 #include <proto/exec.h>
85 #include <proto/utility.h>
87 #define CTRL_C (SetSignal(0L,0L) & SIGBREAKF_CTRL_C)
89 #define Bit_Mask(bit) (1L << bit)
90 #define Bit_Clear(name, bit) name &= ~Bit_Mask(bit)
91 #define Bit_Set(name, bit) name |= Bit_Mask(bit)
93 #define ARG_TEMPLATE "FILE/A,FLAGS,ADD/S,SUB/S,ALL/S,QUIET/S"
99 #define FIBF_HOLD (1<<FIBB_HOLD)
114 /* To define whether a command line switch was set or not.
116 #define NOT_SET(x) (x == 0)
117 #define IS_SET(x) (!NOT_SET(x))
119 #define MAX_PATH_LEN 512
121 const TEXT version
[] = "$VER: Protect 41.1 (2.12.2000)\n";
123 int Do_Protect(struct AnchorPath
*, STRPTR
, STRPTR
, BOOL
, BOOL
, BOOL
, BOOL
);
125 int doProtect(struct AnchorPath
*ap
, STRPTR file
, LONG flags
, BOOL flagsSet
,
126 BOOL add
, BOOL sub
, BOOL all
, BOOL quiet
);
127 BOOL
setProtection(STRPTR file
, LONG oldFlags
, LONG flags
, BOOL flagsSet
,
135 struct AnchorPath
*apath
;
137 IPTR args
[NOOFARGS
] = { 0,
144 int retval
= RETURN_OK
;
146 apath
= AllocVec(sizeof(struct AnchorPath
) + MAX_PATH_LEN
,
147 MEMF_ANY
| MEMF_CLEAR
);
151 /* Make sure DOS knows the buffer size. */
152 apath
->ap_Strlen
= MAX_PATH_LEN
;
154 rda
= ReadArgs(ARG_TEMPLATE
, args
, NULL
);
158 STRPTR file
= (STRPTR
)args
[ARG_FILE
];
159 STRPTR flags
= (STRPTR
)args
[ARG_FLAGS
];
160 BOOL add
= (BOOL
)args
[ARG_ADD
];
161 BOOL sub
= (BOOL
)args
[ARG_SUB
];
162 BOOL all
= (BOOL
)args
[ARG_ALL
];
163 BOOL quiet
= (BOOL
)args
[ARG_QUIET
];
165 LONG flagValues
= FIBF_READ
| FIBF_WRITE
| FIBF_DELETE
|
170 D(Printf("Flags: %s\n", flags
));
183 while (*flags
!= 0 && retval
== RETURN_OK
)
185 char f
= ToUpper(*flags
);
187 D(Printf("Checking flag: %lc\n", f
));
192 flagValues
&= ~FIBF_READ
;
196 flagValues
&= ~FIBF_WRITE
;
200 flagValues
&= ~FIBF_DELETE
;
204 flagValues
&= ~FIBF_EXECUTE
;
209 flagValues
|= FIBF_ARCHIVE
;
213 flagValues
|= FIBF_SCRIPT
;
217 flagValues
|= FIBF_PURE
;
221 flagValues
|= FIBF_HOLD
;
225 Printf("Invalid flags - must be one of HSPARWED\n");
226 retval
= RETURN_FAIL
;
230 } /* while (*flags != 0) */
235 Printf("ADD and SUB are mutually exclusive\n");
236 retval
= RETURN_FAIL
;
239 if (retval
== RETURN_OK
)
241 if (!all
&& IsDosEntryA(file
, LDF_VOLUMES
| LDF_DEVICES
))
243 Printf("Can't set protection for %s - ", file
);
244 SetIoErr(ERROR_OBJECT_WRONG_TYPE
);
245 PrintFault(IoErr(), NULL
);
247 retval
= RETURN_FAIL
;
251 retval
= doProtect(apath
, file
, flagValues
,
252 flags
!= NULL
, add
, sub
, all
,
261 PrintFault(IoErr(), "Protect");
262 retval
= RETURN_FAIL
;
267 retval
= RETURN_FAIL
;
275 #define isDir(fib) ((fib)->fib_DirEntryType >= 0)
277 int doProtect(struct AnchorPath
*ap
, STRPTR file
, LONG flags
, BOOL flagsSet
,
278 BOOL add
, BOOL sub
, BOOL all
, BOOL quiet
)
281 int retval
= RETURN_OK
;
283 int i
; /* Loop variable */
285 ULONG match_count
= 0;
287 for (match
= MatchFirst(file
, ap
);
288 match
== 0 && retval
== RETURN_OK
&& !CTRL_C
;
289 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 success
= 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");
337 retval
= RETURN_ERROR
;
346 if (match_count
== 0 || IoErr() != ERROR_NO_MORE_ENTRIES
)
348 PrintFault(IoErr(), NULL
);
349 retval
= RETURN_ERROR
;
357 #define ALL_OFF (FIBF_READ | FIBF_WRITE | FIBF_DELETE | FIBF_EXECUTE)
358 #define addFlags(new, old) ((~(~old | ~new) & ALL_OFF) | \
359 ((old | new) & ~ALL_OFF))
361 #define subFlags(new, old) (((old | ~new) & ALL_OFF) | \
362 ((old & ~new) & ~ALL_OFF))
364 BOOL
setProtection(STRPTR file
, LONG oldFlags
, LONG flags
, BOOL flagsSet
,
369 if (flags
!= ALL_OFF
)
373 /* Enable permission */
374 newFlags
= addFlags(flags
, oldFlags
);
378 /* Disable permissions */
379 newFlags
= subFlags(flags
, oldFlags
);
383 /* Clear all permissions then set the ones given. */
389 /* No flags were given */
392 /* Disable all permissions */
402 if (!SetProtection(file
, newFlags
))