1 /* Copyright 1986-1992 Emmet P. Gray.
2 * Copyright 1996-1998,2000-2002,2007,2009 Alain Knaff.
3 * This file is part of mtools.
5 * Mtools is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
10 * Mtools is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with Mtools. If not, see <http://www.gnu.org/licenses/>.
19 * Change MSDOS file attribute flags
22 #include "sysincludes.h"
27 typedef struct Arg_t {
30 struct MainParam_t mp;
35 static int attrib_file(direntry_t *entry, MainParam_t *mp)
37 Arg_t *arg=(Arg_t *) mp->arg;
39 if(entry->entry != -3) {
40 /* if not root directory, change it */
41 entry->dir.attr = (entry->dir.attr & arg->remove) | arg->add;
47 static int replay_attrib(direntry_t *entry, MainParam_t *mp UNUSEDP)
49 if ( (IS_ARCHIVE(entry) && IS_DIR(entry)) ||
50 (!IS_ARCHIVE(entry) && !IS_DIR(entry)) ||
51 IS_SYSTEM(entry) || IS_HIDDEN(entry)) {
55 if (IS_ARCHIVE(entry) && IS_DIR(entry)) {
59 if (!IS_ARCHIVE(entry) && !IS_DIR(entry)) {
63 if (IS_SYSTEM(entry)) {
67 if (IS_HIDDEN(entry)) {
71 fprintPwd(stdout, entry, 1);
79 static int view_attrib(direntry_t *entry, MainParam_t *mp UNUSEDP)
95 if(IS_READONLY(entry))
100 fprintPwd(stdout, entry, 0);
106 static int concise_view_attrib(direntry_t *entry, MainParam_t *mp)
108 Arg_t *arg=(Arg_t *) mp->arg;
110 if(IS_ARCHIVE(entry))
118 if(IS_READONLY(entry))
120 if(arg->doPrintName) {
122 fprintPwd(stdout, entry, 0);
128 static int recursive_attrib(direntry_t *entry, MainParam_t *mp)
130 mp->callback(entry, mp);
131 return mp->loop(mp->File, mp, "*");
135 static void usage(int ret) NORETURN;
136 static void usage(int ret)
138 fprintf(stderr, "Mtools version %s, dated %s\n",
141 "Usage: %s [-p] [-a|+a] [-h|+h] [-r|+r] [-s|+s] msdosfile [msdosfiles...]\n",
146 static int letterToCode(int letter)
148 switch (toupper(letter)) {
154 return ATTR_READONLY;
163 void mattrib(int argc, char **argv, int type UNUSEDP)
182 if(helpFlag(argc, argv))
184 while ((c = getopt(argc, argv, "i:/ahrsAHRSXp")) != EOF) {
190 arg.remove &= ~letterToCode(c);
193 set_cmd_line_image(optarg);
209 if(optind == argc && wantUsage) {
213 for(;optind < argc;optind++) {
214 switch(argv[optind][0]) {
216 for(ptr = argv[optind] + 1; *ptr; ptr++)
217 arg.add |= letterToCode(*ptr);
220 for(ptr = argv[optind] + 1; *ptr; ptr++)
221 arg.remove &= ~letterToCode(*ptr);
227 if(arg.remove == 0xff && !arg.add)
236 arg.mp.callback = concise_view_attrib;
237 arg.doPrintName = (argc - optind > 1 ||
239 strpbrk(argv[optind], "*[?") != 0);
241 arg.mp.callback = replay_attrib;
243 arg.mp.callback = view_attrib;
244 arg.mp.openflags = O_RDONLY;
246 arg.mp.callback = attrib_file;
247 arg.mp.openflags = O_RDWR;
251 arg.mp.dirCallback = recursive_attrib;
253 arg.mp.arg = (void *) &arg;
254 arg.mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR;
256 arg.mp.lookupflags |= DO_OPEN_DIRS | NO_DOTS;
257 exit(main_loop(&arg.mp, argv + optind, argc - optind));