xref: /aosp_15_r20/external/mtools/mattrib.c (revision d5c9a868b113e0ec0db2f27bc2ce8a253e77c4b0)
1*d5c9a868SElliott Hughes /*  Copyright 1986-1992 Emmet P. Gray.
2*d5c9a868SElliott Hughes  *  Copyright 1996-1998,2000-2002,2007,2009 Alain Knaff.
3*d5c9a868SElliott Hughes  *  This file is part of mtools.
4*d5c9a868SElliott Hughes  *
5*d5c9a868SElliott Hughes  *  Mtools is free software: you can redistribute it and/or modify
6*d5c9a868SElliott Hughes  *  it under the terms of the GNU General Public License as published by
7*d5c9a868SElliott Hughes  *  the Free Software Foundation, either version 3 of the License, or
8*d5c9a868SElliott Hughes  *  (at your option) any later version.
9*d5c9a868SElliott Hughes  *
10*d5c9a868SElliott Hughes  *  Mtools is distributed in the hope that it will be useful,
11*d5c9a868SElliott Hughes  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12*d5c9a868SElliott Hughes  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13*d5c9a868SElliott Hughes  *  GNU General Public License for more details.
14*d5c9a868SElliott Hughes  *
15*d5c9a868SElliott Hughes  *  You should have received a copy of the GNU General Public License
16*d5c9a868SElliott Hughes  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
17*d5c9a868SElliott Hughes  *
18*d5c9a868SElliott Hughes  * mattrib.c
19*d5c9a868SElliott Hughes  * Change MSDOS file attribute flags
20*d5c9a868SElliott Hughes  */
21*d5c9a868SElliott Hughes 
22*d5c9a868SElliott Hughes #include "sysincludes.h"
23*d5c9a868SElliott Hughes #include "msdos.h"
24*d5c9a868SElliott Hughes #include "mtools.h"
25*d5c9a868SElliott Hughes #include "mainloop.h"
26*d5c9a868SElliott Hughes 
27*d5c9a868SElliott Hughes typedef struct Arg_t {
28*d5c9a868SElliott Hughes 	int recursive;
29*d5c9a868SElliott Hughes 	int doPrintName;
30*d5c9a868SElliott Hughes 	unsigned char add;
31*d5c9a868SElliott Hughes 	unsigned char remove;
32*d5c9a868SElliott Hughes } Arg_t;
33*d5c9a868SElliott Hughes 
attrib_file(direntry_t * entry,MainParam_t * mp)34*d5c9a868SElliott Hughes static int attrib_file(direntry_t *entry, MainParam_t *mp)
35*d5c9a868SElliott Hughes {
36*d5c9a868SElliott Hughes 	Arg_t *arg=(Arg_t *) mp->arg;
37*d5c9a868SElliott Hughes 
38*d5c9a868SElliott Hughes 	if(entry->entry != -3) {
39*d5c9a868SElliott Hughes 		/* if not root directory, change it */
40*d5c9a868SElliott Hughes 		entry->dir.attr = (entry->dir.attr & arg->remove) | arg->add;
41*d5c9a868SElliott Hughes 		dir_write(entry);
42*d5c9a868SElliott Hughes 	}
43*d5c9a868SElliott Hughes 	return GOT_ONE;
44*d5c9a868SElliott Hughes }
45*d5c9a868SElliott Hughes 
replay_attrib(direntry_t * entry,MainParam_t * mp UNUSEDP)46*d5c9a868SElliott Hughes static int replay_attrib(direntry_t *entry, MainParam_t *mp UNUSEDP)
47*d5c9a868SElliott Hughes {
48*d5c9a868SElliott Hughes 	if ( (IS_ARCHIVE(entry) && IS_DIR(entry)) ||
49*d5c9a868SElliott Hughes 		 (!IS_ARCHIVE(entry) && !IS_DIR(entry)) ||
50*d5c9a868SElliott Hughes 		 IS_SYSTEM(entry) || IS_HIDDEN(entry)) {
51*d5c9a868SElliott Hughes 
52*d5c9a868SElliott Hughes 		printf("mattrib ");
53*d5c9a868SElliott Hughes 
54*d5c9a868SElliott Hughes 		if (IS_ARCHIVE(entry) && IS_DIR(entry)) {
55*d5c9a868SElliott Hughes 			printf("+a ");
56*d5c9a868SElliott Hughes 		}
57*d5c9a868SElliott Hughes 
58*d5c9a868SElliott Hughes 		if (!IS_ARCHIVE(entry) && !IS_DIR(entry)) {
59*d5c9a868SElliott Hughes 			printf("-a ");
60*d5c9a868SElliott Hughes 		}
61*d5c9a868SElliott Hughes 
62*d5c9a868SElliott Hughes 		if (IS_SYSTEM(entry)) {
63*d5c9a868SElliott Hughes 			printf("+s ");
64*d5c9a868SElliott Hughes 		}
65*d5c9a868SElliott Hughes 
66*d5c9a868SElliott Hughes 		if (IS_HIDDEN(entry)) {
67*d5c9a868SElliott Hughes 			printf("+h ");
68*d5c9a868SElliott Hughes 		}
69*d5c9a868SElliott Hughes 
70*d5c9a868SElliott Hughes 		fprintPwd(stdout, entry, 1);
71*d5c9a868SElliott Hughes 		printf("\n");
72*d5c9a868SElliott Hughes 	}
73*d5c9a868SElliott Hughes 	return GOT_ONE;
74*d5c9a868SElliott Hughes }
75*d5c9a868SElliott Hughes 
76*d5c9a868SElliott Hughes 
77*d5c9a868SElliott Hughes 
view_attrib(direntry_t * entry,MainParam_t * mp UNUSEDP)78*d5c9a868SElliott Hughes static int view_attrib(direntry_t *entry, MainParam_t *mp UNUSEDP)
79*d5c9a868SElliott Hughes {
80*d5c9a868SElliott Hughes 	printf("  ");
81*d5c9a868SElliott Hughes 	if(IS_ARCHIVE(entry))
82*d5c9a868SElliott Hughes 		putchar('A');
83*d5c9a868SElliott Hughes 	else
84*d5c9a868SElliott Hughes 		putchar(' ');
85*d5c9a868SElliott Hughes 	fputs("  ",stdout);
86*d5c9a868SElliott Hughes 	if(IS_SYSTEM(entry))
87*d5c9a868SElliott Hughes 		putchar('S');
88*d5c9a868SElliott Hughes 	else
89*d5c9a868SElliott Hughes 		putchar(' ');
90*d5c9a868SElliott Hughes 	if(IS_HIDDEN(entry))
91*d5c9a868SElliott Hughes 		putchar('H');
92*d5c9a868SElliott Hughes 	else
93*d5c9a868SElliott Hughes 		putchar(' ');
94*d5c9a868SElliott Hughes 	if(IS_READONLY(entry))
95*d5c9a868SElliott Hughes 		putchar('R');
96*d5c9a868SElliott Hughes 	else
97*d5c9a868SElliott Hughes 		putchar(' ');
98*d5c9a868SElliott Hughes 	printf("     ");
99*d5c9a868SElliott Hughes 	fprintPwd(stdout, entry, 0);
100*d5c9a868SElliott Hughes 	printf("\n");
101*d5c9a868SElliott Hughes 	return GOT_ONE;
102*d5c9a868SElliott Hughes }
103*d5c9a868SElliott Hughes 
104*d5c9a868SElliott Hughes 
concise_view_attrib(direntry_t * entry,MainParam_t * mp)105*d5c9a868SElliott Hughes static int concise_view_attrib(direntry_t *entry, MainParam_t *mp)
106*d5c9a868SElliott Hughes {
107*d5c9a868SElliott Hughes 	Arg_t *arg=(Arg_t *) mp->arg;
108*d5c9a868SElliott Hughes 
109*d5c9a868SElliott Hughes 	if(IS_ARCHIVE(entry))
110*d5c9a868SElliott Hughes 		putchar('A');
111*d5c9a868SElliott Hughes 	if(IS_DIR(entry))
112*d5c9a868SElliott Hughes 		putchar('D');
113*d5c9a868SElliott Hughes 	if(IS_SYSTEM(entry))
114*d5c9a868SElliott Hughes 		putchar('S');
115*d5c9a868SElliott Hughes 	if(IS_HIDDEN(entry))
116*d5c9a868SElliott Hughes 		putchar('H');
117*d5c9a868SElliott Hughes 	if(IS_READONLY(entry))
118*d5c9a868SElliott Hughes 		putchar('R');
119*d5c9a868SElliott Hughes 	if(arg->doPrintName) {
120*d5c9a868SElliott Hughes 		putchar(' ');
121*d5c9a868SElliott Hughes 		fprintPwd(stdout, entry, 0);
122*d5c9a868SElliott Hughes 	}
123*d5c9a868SElliott Hughes 	putchar('\n');
124*d5c9a868SElliott Hughes 	return GOT_ONE;
125*d5c9a868SElliott Hughes }
126*d5c9a868SElliott Hughes 
recursive_attrib(direntry_t * entry,MainParam_t * mp)127*d5c9a868SElliott Hughes static int recursive_attrib(direntry_t *entry, MainParam_t *mp)
128*d5c9a868SElliott Hughes {
129*d5c9a868SElliott Hughes 	mp->callback(entry, mp);
130*d5c9a868SElliott Hughes 	return mp->loop(mp->File, mp, "*");
131*d5c9a868SElliott Hughes }
132*d5c9a868SElliott Hughes 
133*d5c9a868SElliott Hughes 
134*d5c9a868SElliott Hughes static void usage(int ret) NORETURN;
usage(int ret)135*d5c9a868SElliott Hughes static void usage(int ret)
136*d5c9a868SElliott Hughes {
137*d5c9a868SElliott Hughes 	fprintf(stderr, "Mtools version %s, dated %s\n",
138*d5c9a868SElliott Hughes 		mversion, mdate);
139*d5c9a868SElliott Hughes 	fprintf(stderr,
140*d5c9a868SElliott Hughes 		"Usage: %s [-p] [-a|+a] [-h|+h] [-r|+r] [-s|+s] msdosfile [msdosfiles...]\n",
141*d5c9a868SElliott Hughes 		progname);
142*d5c9a868SElliott Hughes 	exit(ret);
143*d5c9a868SElliott Hughes }
144*d5c9a868SElliott Hughes 
letterToCode(int letter)145*d5c9a868SElliott Hughes static int letterToCode(int letter)
146*d5c9a868SElliott Hughes {
147*d5c9a868SElliott Hughes 	switch (toupper(letter)) {
148*d5c9a868SElliott Hughes 		case 'A':
149*d5c9a868SElliott Hughes 			return ATTR_ARCHIVE;
150*d5c9a868SElliott Hughes 		case 'H':
151*d5c9a868SElliott Hughes 			return ATTR_HIDDEN;
152*d5c9a868SElliott Hughes 		case 'R':
153*d5c9a868SElliott Hughes 			return ATTR_READONLY;
154*d5c9a868SElliott Hughes 		case 'S':
155*d5c9a868SElliott Hughes 			return ATTR_SYSTEM;
156*d5c9a868SElliott Hughes 		default:
157*d5c9a868SElliott Hughes 			usage(1);
158*d5c9a868SElliott Hughes 	}
159*d5c9a868SElliott Hughes }
160*d5c9a868SElliott Hughes 
161*d5c9a868SElliott Hughes void mattrib(int argc, char **argv, int type UNUSEDP) NORETURN;
mattrib(int argc,char ** argv,int type UNUSEDP)162*d5c9a868SElliott Hughes void mattrib(int argc, char **argv, int type UNUSEDP)
163*d5c9a868SElliott Hughes {
164*d5c9a868SElliott Hughes 	Arg_t arg;
165*d5c9a868SElliott Hughes 	struct MainParam_t mp;
166*d5c9a868SElliott Hughes 	int view;
167*d5c9a868SElliott Hughes 	int c;
168*d5c9a868SElliott Hughes 	int concise;
169*d5c9a868SElliott Hughes 	int replay;
170*d5c9a868SElliott Hughes 	char *ptr;
171*d5c9a868SElliott Hughes 	int wantUsage;
172*d5c9a868SElliott Hughes 
173*d5c9a868SElliott Hughes 	arg.add = 0;
174*d5c9a868SElliott Hughes 	arg.remove = 0xff;
175*d5c9a868SElliott Hughes 	arg.recursive = 0;
176*d5c9a868SElliott Hughes 	arg.doPrintName = 1;
177*d5c9a868SElliott Hughes 	view = 0;
178*d5c9a868SElliott Hughes 	concise = 0;
179*d5c9a868SElliott Hughes 	replay = 0;
180*d5c9a868SElliott Hughes 	wantUsage = 0;
181*d5c9a868SElliott Hughes 
182*d5c9a868SElliott Hughes 	if(helpFlag(argc, argv))
183*d5c9a868SElliott Hughes 		usage(0);
184*d5c9a868SElliott Hughes 	while ((c = getopt(argc, argv, "i:/ahrsAHRSXp")) != EOF) {
185*d5c9a868SElliott Hughes 		switch (c) {
186*d5c9a868SElliott Hughes 			case 'h':
187*d5c9a868SElliott Hughes 				wantUsage = 1;
188*d5c9a868SElliott Hughes 				/* FALL THROUGH */
189*d5c9a868SElliott Hughes 			default:
190*d5c9a868SElliott Hughes 				arg.remove &= ~letterToCode(c);
191*d5c9a868SElliott Hughes 				break;
192*d5c9a868SElliott Hughes 			case 'i':
193*d5c9a868SElliott Hughes 				set_cmd_line_image(optarg);
194*d5c9a868SElliott Hughes 				break;
195*d5c9a868SElliott Hughes 			case 'p':
196*d5c9a868SElliott Hughes 				replay = 1;
197*d5c9a868SElliott Hughes 				break;
198*d5c9a868SElliott Hughes 			case '/':
199*d5c9a868SElliott Hughes 				arg.recursive = 1;
200*d5c9a868SElliott Hughes 				break;
201*d5c9a868SElliott Hughes 			case 'X':
202*d5c9a868SElliott Hughes 				concise = 1;
203*d5c9a868SElliott Hughes 				break;
204*d5c9a868SElliott Hughes 			case '?':
205*d5c9a868SElliott Hughes 				usage(1);
206*d5c9a868SElliott Hughes 		}
207*d5c9a868SElliott Hughes 	}
208*d5c9a868SElliott Hughes 
209*d5c9a868SElliott Hughes 	if(optind == argc && wantUsage) {
210*d5c9a868SElliott Hughes 		usage(0);
211*d5c9a868SElliott Hughes 	}
212*d5c9a868SElliott Hughes 
213*d5c9a868SElliott Hughes 	for(;optind < argc;optind++) {
214*d5c9a868SElliott Hughes 		switch(argv[optind][0]) {
215*d5c9a868SElliott Hughes 			case '+':
216*d5c9a868SElliott Hughes 				for(ptr = argv[optind] + 1; *ptr; ptr++)
217*d5c9a868SElliott Hughes 					arg.add |= letterToCode(*ptr);
218*d5c9a868SElliott Hughes 				continue;
219*d5c9a868SElliott Hughes 			case '-':
220*d5c9a868SElliott Hughes 				for(ptr = argv[optind] + 1; *ptr; ptr++)
221*d5c9a868SElliott Hughes 					arg.remove &= ~letterToCode(*ptr);
222*d5c9a868SElliott Hughes 				continue;
223*d5c9a868SElliott Hughes 		}
224*d5c9a868SElliott Hughes 		break;
225*d5c9a868SElliott Hughes 	}
226*d5c9a868SElliott Hughes 
227*d5c9a868SElliott Hughes 	if(arg.remove == 0xff && !arg.add)
228*d5c9a868SElliott Hughes 		view = 1;
229*d5c9a868SElliott Hughes 
230*d5c9a868SElliott Hughes 	if (optind >= argc)
231*d5c9a868SElliott Hughes 		usage(1);
232*d5c9a868SElliott Hughes 
233*d5c9a868SElliott Hughes 	init_mp(&mp);
234*d5c9a868SElliott Hughes 	if(view){
235*d5c9a868SElliott Hughes 		if(concise) {
236*d5c9a868SElliott Hughes 			mp.callback = concise_view_attrib;
237*d5c9a868SElliott Hughes 			arg.doPrintName = (argc - optind > 1 ||
238*d5c9a868SElliott Hughes 					   arg.recursive ||
239*d5c9a868SElliott Hughes 					   strpbrk(argv[optind], "*[?") != 0);
240*d5c9a868SElliott Hughes 		} else if (replay) {
241*d5c9a868SElliott Hughes 			mp.callback = replay_attrib;
242*d5c9a868SElliott Hughes 		} else
243*d5c9a868SElliott Hughes 			mp.callback = view_attrib;
244*d5c9a868SElliott Hughes 		mp.openflags = O_RDONLY;
245*d5c9a868SElliott Hughes 	} else {
246*d5c9a868SElliott Hughes 		mp.callback = attrib_file;
247*d5c9a868SElliott Hughes 		mp.openflags = O_RDWR;
248*d5c9a868SElliott Hughes 	}
249*d5c9a868SElliott Hughes 
250*d5c9a868SElliott Hughes 	if(arg.recursive)
251*d5c9a868SElliott Hughes 		mp.dirCallback = recursive_attrib;
252*d5c9a868SElliott Hughes 
253*d5c9a868SElliott Hughes 	mp.arg = (void *) &arg;
254*d5c9a868SElliott Hughes 	mp.lookupflags = ACCEPT_PLAIN | ACCEPT_DIR;
255*d5c9a868SElliott Hughes 	if(arg.recursive)
256*d5c9a868SElliott Hughes 		mp.lookupflags |= DO_OPEN_DIRS | NO_DOTS;
257*d5c9a868SElliott Hughes 	exit(main_loop(&mp, argv + optind, argc - optind));
258*d5c9a868SElliott Hughes }
259