Don't call InvertPixelArray with negative width and/or height.
[tangerine.git] / workbench / c / Protect.c
blobe0e1c2002eced3c94cc206080b53a728ad5f2d50
1 /*
2 Copyright © 1995-2001, 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
21 Workbench:c
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 HISTORY
70 27-Jul-1997 laguest -- Initial inclusion into the AROS tree
71 3.12.2000 SDuvan -- Rewrote, simplified and implemented missing
72 functionality
74 ******************************************************************************/
77 #include <dos/dos.h>
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>
90 #include <ctype.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"
100 #ifndef FIBB_HOLD
101 #define FIBB_HOLD 7
102 #endif
103 #ifndef FIBF_HOLD
104 #define FIBF_HOLD (1<<FIBB_HOLD)
105 #endif
107 enum
109 ARG_FILE = 0,
110 ARG_FLAGS,
111 ARG_ADD,
112 ARG_SUB,
113 ARG_ALL,
114 ARG_QUIET,
115 NOOFARGS
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,
135 BOOL add, BOOL sub);
137 int __nocommandline;
139 int main(void)
141 struct RDArgs *rda;
142 struct AnchorPath *apath;
144 IPTR args[NOOFARGS] = { NULL,
145 NULL,
146 (IPTR)FALSE,
147 (IPTR)FALSE,
148 (IPTR)FALSE,
149 (IPTR)FALSE };
151 int retval = RETURN_OK;
153 apath = AllocVec(sizeof(struct AnchorPath) + MAX_PATH_LEN,
154 MEMF_ANY | MEMF_CLEAR);
156 if (apath != NULL)
158 /* Make sure DOS knows the buffer size. */
159 apath->ap_Strlen = MAX_PATH_LEN;
161 rda = ReadArgs(ARG_TEMPLATE, args, NULL);
163 if (rda != 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 |
173 FIBF_EXECUTE;
175 if (flags != NULL)
177 if (*flags == '+')
179 add = TRUE;
180 flags++;
182 if (*flags == '-')
184 sub = TRUE;
185 flags++;
188 while (*flags != 0 && retval == RETURN_OK)
190 switch (toupper(*flags))
192 /* Active low */
193 case 'R':
194 flagValues &= ~FIBF_READ;
195 break;
197 case 'W':
198 flagValues &= ~FIBF_WRITE;
199 break;
201 case 'D':
202 flagValues &= ~FIBF_DELETE;
203 break;
205 case 'E':
206 flagValues &= ~FIBF_EXECUTE;
207 break;
209 /* Active high */
210 case 'A':
211 flagValues |= FIBF_ARCHIVE;
212 break;
214 case 'S':
215 flagValues |= FIBF_SCRIPT;
216 break;
218 case 'P':
219 flagValues |= FIBF_PURE;
220 break;
222 case 'H':
223 flagValues |= FIBF_HOLD;
224 break;
226 default:
227 Printf("Invalid flags - must be one of HSPARWED\n");
228 retval = RETURN_FAIL;
231 flags++;
232 } /* while (*flags != 0) */
235 if (add && sub)
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;
251 else
253 retval = doProtect(apath, file, flagValues,
254 flags != NULL, add, sub, all,
255 quiet);
259 FreeArgs(rda);
261 else
263 PrintFault(IoErr(), "Protect");
264 retval = RETURN_FAIL;
267 else
269 retval = RETURN_FAIL;
272 FreeVec(apath);
274 return retval;
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)
282 LONG match;
283 int retval = RETURN_OK;
284 LONG indent = 0;
285 int i; /* Loop variable */
286 BOOL error;
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)
296 indent--;
297 ap->ap_Flags &= ~APF_DIDDIR; /* Should not be necessary */
298 continue;
300 else if (all)
302 ap->ap_Flags |= APF_DODIR;
303 indent++;
309 error = setProtection(ap->ap_Buf, ap->ap_Info.fib_Protection, flags,
310 flagsSet, add, sub);
312 if (!quiet)
314 LONG ioerr = IoErr();
316 /* Fix indentation level */
317 for (i = 0; i < indent; i++)
319 PutStr(" ");
322 if (!isDir(&ap->ap_Info))
324 PutStr(" ");
327 PutStr(ap->ap_Info.fib_FileName);
329 if (isDir(&ap->ap_Info))
331 PutStr(" (dir)");
334 if (!error)
336 PrintFault(ioerr, "..error");
338 else
340 PutStr("..done\n");
345 MatchEnd(ap);
347 return retval;
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,
358 BOOL add, BOOL sub)
360 LONG newFlags;
362 if (flags != ALL_OFF)
364 if (add)
366 /* Enable permission */
367 newFlags = addFlags(flags, oldFlags);
369 else if (sub)
371 /* Disable permissions */
372 newFlags = subFlags(flags, oldFlags);
374 else
376 /* Clear all permissions then set the ones given. */
377 newFlags = flags;
380 else
382 /* No flags were given */
383 if (!add && !sub)
385 /* Disable all permissions */
386 newFlags = ALL_OFF;
388 else
390 /* Do nothing */
391 return FALSE;
395 if (!SetProtection(file, newFlags))
397 return FALSE;
400 return TRUE;