1/*  Copyright 1996-2004,2007-2009 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
24const char *progname;
25
26static 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	{"mtoolstest", mtoolstest, 0},
54	{"mtype",mcopy, 1},
55	{"mwrite",mcopy, 0},
56	{"mzip", mzip, 0}
57};
58#define NDISPATCH (sizeof dispatch / sizeof dispatch[0])
59
60int main(int argc,char **argv)
61{
62	unsigned int i;
63	const char *name;
64
65#ifdef HAVE_SETLOCALE
66	char *locale;
67	locale=setlocale(LC_ALL, "");
68	if(locale == NULL || !strcmp(locale, "C"))
69		setlocale(LC_ALL, "en_US");
70#endif
71
72	init_privs();
73#ifdef __EMX__
74	_wildcard(&argc,&argv);
75#endif
76
77/*#define PRIV_TEST*/
78
79#ifdef PRIV_TEST
80	{
81		int euid;
82		char command[100];
83
84		printf("INIT: %d %d\n", getuid(), geteuid());
85		drop_privs();
86		printf("DROP: %d %d\n", getuid(), geteuid());
87		reclaim_privs();
88		printf("RECLAIM: %d %d\n", getuid(), geteuid());
89		euid = geteuid();
90		if(argc & 1) {
91			drop_privs();
92			printf("DROP: %d %d\n", getuid(), geteuid());
93		}
94		if(!((argc-1) & 2)) {
95			destroy_privs();
96			printf("DESTROY: %d %d\n", getuid(), geteuid());
97		}
98		sprintf(command, "a.out %d", euid);
99		system(command);
100		return 1;
101	}
102#endif
103
104
105#ifdef __EMX__
106       _wildcard(&argc,&argv);
107#endif
108
109
110	/* check whether the compiler lays out structures in a sane way */
111	if(sizeof(struct partition) != 16 ||
112	   sizeof(struct directory) != 32 ||
113	   sizeof(struct vfat_subentry) !=32) {
114		fprintf(stderr,"Mtools has not been correctly compiled\n");
115		fprintf(stderr,"Recompile it using a more recent compiler\n");
116		return 137;
117	}
118
119#ifdef __EMX__
120       argv[0] = _getname(argv[0]); _remext(argv[0]); name = argv[0];
121#else
122#ifdef OS_mingw32msvc
123	_stripexe(argv[0]);
124#endif
125	name = _basename(argv[0]);
126#endif
127	progname = argv[0];
128
129	/* this allows the different tools to be called as "mtools -c <command>"
130	** where <command> is mdir, mdel, mcopy etcetera
131	** Mainly done for the BeOS, which doesn't support links yet.
132	*/
133
134	if(argc >= 3 &&
135	   !strcmp(argv[1], "-c") &&
136	   !strcmp(name, "mtools")) {
137		argc-=2;
138		argv+=2;
139		name = argv[0];
140	}
141
142
143
144	/* print the version */
145	if(argc >= 2 &&
146	   (strcmp(argv[1], "-V") == 0 || strcmp(argv[1], "--version") ==0)) {
147		printf("%s (GNU mtools) %s\n",
148		       name, mversion);
149		printf("configured with the following options: ");
150#ifdef USE_XDF
151		printf("enable-xdf ");
152#else
153		printf("disable-xdf ");
154#endif
155#ifdef USING_VOLD
156		printf("enable-vold ");
157#else
158		printf("disable-vold ");
159#endif
160#ifdef USING_NEW_VOLD
161		printf("enable-new-vold ");
162#else
163		printf("disable-new-vold ");
164#endif
165#ifdef DEBUG
166		printf("enable-debug ");
167#else
168		printf("disable-debug ");
169#endif
170#ifdef USE_RAWTERM
171		printf("enable-raw-term ");
172#else
173		printf("disable-raw-term ");
174#endif
175		printf("\n");
176		return 0;
177	}
178
179	read_config();
180	setup_signal();
181	for (i = 0; i < NDISPATCH; i++) {
182		if (!strcmp(name,dispatch[i].cmd))
183			dispatch[i].fn(argc, argv, dispatch[i].type);
184	}
185	if (strcmp(name,"mtools"))
186		fprintf(stderr,"Unknown mtools command '%s'\n",name);
187	fprintf(stderr,"Supported commands:");
188	for (i = 0; i < NDISPATCH; i++) {
189		if (i%8 == 0) putc('\n', stderr);
190		else fprintf(stderr, ", ");
191		fprintf(stderr, "%s", dispatch[i].cmd);
192	}
193	putc('\n', stderr);
194
195	return 1;
196}
197
198int helpFlag(int argc, char **argv) {
199	return (argc > 1 && !strcmp(argv[1], "--help"));
200}
201