1 /*  Copyright 1996-2004,2007-2010 Alain Knaff.
2  *  This file is part of mtools.
3  *
4  *  Mtools is free software: you can redistribute it and/or modify
5  *  it under the terms of the GNU General Public License as published by
6  *  the Free Software Foundation, either version 3 of the License, or
7  *  (at your option) any later version.
8  *
9  *  Mtools is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *  GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with Mtools.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "sysincludes.h"
19 #include "msdos.h"
20 #include "mtools.h"
21 #include "partition.h"
22 #include "vfat.h"
23 
24 const char *progname;
25 
26 static const struct dispatch {
27 	const char *cmd;
28 	void (*fn)(int, char **, int);
29 	int type;
30 } dispatch[] = {
31 	{"mattrib",mattrib, 0},
32 	{"mbadblocks",mbadblocks, 0},
33 	{"mcat",mcat, 0},
34 	{"mcd",mcd, 0},
35 	{"mclasserase",mclasserase, 0},
36 	{"mcopy",mcopy, 0},
37 	{"mdel",mdel, 0},
38 	{"mdeltree",mdel, 2},
39 	{"mdir",mdir, 0},
40 	{"mdoctorfat",mdoctorfat, 0},
41 	{"mdu",mdu, 0},
42 	{"mformat",mformat, 0},
43 	{"minfo", minfo, 0},
44 	{"mlabel",mlabel, 0},
45 	{"mmd",mmd, 0},
46 	{"mmount",mmount, 0},
47 	{"mpartition",mpartition, 0},
48 	{"mrd",mdel, 1},
49 	{"mread",mcopy, 0},
50 	{"mmove",mmove, 0},
51 	{"mren",mmove, 1},
52 	{"mshowfat", mshowfat, 0},
53 	{"mshortname", mshortname, 0},
54 	{"mtoolstest", mtoolstest, 0},
55 	{"mtype",mcopy, 1},
56 	{"mwrite",mcopy, 0},
57 	{"mzip", mzip, 0}
58 };
59 #define NDISPATCH (sizeof dispatch / sizeof dispatch[0])
60 
main(int argc,char ** argv)61 int main(int argc,char **argv)
62 {
63 	unsigned int i;
64 	const char *name;
65 
66 #ifdef HAVE_SETLOCALE
67 	char *locale;
68 	locale=setlocale(LC_ALL, "");
69 	if(locale == NULL || !strcmp(locale, "C"))
70 		setlocale(LC_ALL, "en_US");
71 #endif
72 
73 	init_privs();
74 #ifdef __EMX__
75 	_wildcard(&argc,&argv);
76 #endif
77 
78 /*#define PRIV_TEST*/
79 
80 #ifdef PRIV_TEST
81 	{
82 		int euid;
83 		char command[100];
84 
85 		printf("INIT: %d %d\n", getuid(), geteuid());
86 		drop_privs();
87 		printf("DROP: %d %d\n", getuid(), geteuid());
88 		reclaim_privs();
89 		printf("RECLAIM: %d %d\n", getuid(), geteuid());
90 		euid = geteuid();
91 		if(argc & 1) {
92 			drop_privs();
93 			printf("DROP: %d %d\n", getuid(), geteuid());
94 		}
95 		if(!((argc-1) & 2)) {
96 			destroy_privs();
97 			printf("DESTROY: %d %d\n", getuid(), geteuid());
98 		}
99 		sprintf(command, "a.out %d", euid);
100 		system(command);
101 		return 1;
102 	}
103 #endif
104 
105 
106 #ifdef __EMX__
107        _wildcard(&argc,&argv);
108 #endif
109 
110 
111 	/* check whether the compiler lays out structures in a sane way */
112 	if(sizeof(struct partition) != 16 ||
113 	   sizeof(struct directory) != 32 ||
114 	   sizeof(struct vfat_subentry) !=32) {
115 		fprintf(stderr,"Mtools has not been correctly compiled\n");
116 		fprintf(stderr,"Recompile it using a more recent compiler\n");
117 		return 137;
118 	}
119 
120 #ifdef __EMX__
121        argv[0] = _getname(argv[0]); _remext(argv[0]); name = argv[0];
122 #else
123 #ifdef OS_mingw32msvc
124 	_stripexe(argv[0]);
125 #endif
126 	name = _basename(argv[0]);
127 #endif
128 	progname = argv[0];
129 
130 	/* this allows the different tools to be called as "mtools -c <command>"
131 	** where <command> is mdir, mdel, mcopy etcetera
132 	** Mainly done for the BeOS, which doesn't support links yet.
133 	*/
134 
135 	if(argc >= 3 &&
136 	   !strcmp(argv[1], "-c") &&
137 	   !strcmp(name, "mtools")) {
138 		argc-=2;
139 		argv+=2;
140 		name = argv[0];
141 	}
142 
143 
144 
145 	/* print the version */
146 	if(argc >= 2 &&
147 	   (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") ==0)) {
148 		printf("%s (GNU mtools) %s\n",
149 		       name, mversion);
150 		printf("configured with the following options: ");
151 #ifdef USE_XDF
152 		printf("enable-xdf ");
153 #else
154 		printf("disable-xdf ");
155 #endif
156 #ifdef USING_VOLD
157 		printf("enable-vold ");
158 #else
159 		printf("disable-vold ");
160 #endif
161 #ifdef USING_NEW_VOLD
162 		printf("enable-new-vold ");
163 #else
164 		printf("disable-new-vold ");
165 #endif
166 #ifdef DEBUG
167 		printf("enable-debug ");
168 #else
169 		printf("disable-debug ");
170 #endif
171 #ifdef USE_RAWTERM
172 		printf("enable-raw-term ");
173 #else
174 		printf("disable-raw-term ");
175 #endif
176 		printf("\n");
177 		return 0;
178 	}
179 
180 	read_config();
181 	setup_signal();
182 	for (i = 0; i < NDISPATCH; i++) {
183 		if (!strcmp(name,dispatch[i].cmd))
184 			dispatch[i].fn(argc, argv, dispatch[i].type);
185 	}
186 	if (strcmp(name,"mtools"))
187 		fprintf(stderr,"Unknown mtools command '%s'\n",name);
188 	fprintf(stderr,"Supported commands:");
189 	for (i = 0; i < NDISPATCH; i++) {
190 		if (i%8 == 0) putc('\n', stderr);
191 		else fprintf(stderr, ", ");
192 		fprintf(stderr, "%s", dispatch[i].cmd);
193 	}
194 	putc('\n', stderr);
195 
196 	return 1;
197 }
198 
helpFlag(int argc,char ** argv)199 int helpFlag(int argc, char **argv) {
200 	return (argc > 1 && !strcmp(argv[1], "--help"));
201 }
202