xref: /illumos-gate/usr/src/cmd/rmformat/rmf_main.c (revision 141040e8a310da49386b596573e5dde5580572ec)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License, Version 1.0 only
6  * (the "License").  You may not use this file except in compliance
7  * with the License.
8  *
9  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10  * or http://www.opensolaris.org/os/licensing.
11  * See the License for the specific language governing permissions
12  * and limitations under the License.
13  *
14  * When distributing Covered Code, include this CDDL HEADER in each
15  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16  * If applicable, add the following below this CDDL HEADER, with the
17  * fields enclosed by brackets "[]" replaced with your own identifying
18  * information: Portions Copyright [yyyy] [name of copyright owner]
19  *
20  * CDDL HEADER END
21  */
22 /*
23  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 #pragma ident	"%Z%%M%	%I%	%E% SMI"
28 
29 /*
30  * rmf_main.c :
31  *	The file containing main() for rmformat. The command line
32  *	options are parsed in this file.
33  */
34 
35 
36 #include <priv.h>
37 #include "rmformat.h"
38 
39 int32_t b_flag = 0;
40 int32_t c_flag = 0;
41 int32_t D_flag = 0;
42 int32_t e_flag = 0;
43 int32_t F_flag = 0;
44 int32_t H_flag = 0;
45 int32_t l_flag = 0;
46 int32_t p_flag = 0;
47 int32_t R_flag = 0;
48 int32_t s_flag = 0;
49 int32_t U_flag = 0;
50 int32_t V_flag = 0;
51 int32_t W_flag = 0;
52 int32_t w_flag = 0;
53 
54 static char *myname;
55 char *slice_file = NULL;
56 char *label;
57 uint32_t repair_blk_no;
58 int32_t quick_format = 0;
59 int32_t long_format = 0;
60 int32_t force_format = 0;
61 int32_t rw_protect_enable = 0;
62 int32_t rw_protect_disable = 0;
63 int32_t wp_enable_passwd = 0;
64 int32_t wp_disable_passwd = 0;
65 int32_t wp_enable = 0;
66 int32_t wp_disable = 0;
67 int32_t verify_write = 0;
68 char *dev_name = NULL;
69 
70 static void usage(char *);
71 void check_invalid_combinations();
72 void check_invalid_combinations_again(int32_t);
73 extern int64_t my_atoll(char *ptr);
74 extern void my_perror(char *err_string);
75 void process_options();
76 
77 int
78 main(int32_t argc, char **argv)
79 {
80 	char i;
81 	char *tmp_ptr;
82 
83 	/*
84 	 * This program requires file_dac_read, file_dac_write,
85 	 * proc_fork, and proc_exec privileges
86 	 *
87 	 * child processes require the sys_mount privilege
88 	 */
89 	(void) priv_set(PRIV_SET, PRIV_LIMIT, PRIV_FILE_DAC_READ,
90 	    PRIV_FILE_DAC_WRITE, PRIV_PROC_FORK, PRIV_PROC_EXEC,
91 	    PRIV_SYS_MOUNT, (char *)NULL);
92 
93 	/* Turn privileges off until needed */
94 	(void) priv_set(PRIV_OFF, PRIV_EFFECTIVE, PRIV_FILE_DAC_READ,
95 	    PRIV_FILE_DAC_WRITE, PRIV_PROC_FORK, PRIV_PROC_EXEC,
96 	    PRIV_SYS_MOUNT, (char *)NULL);
97 
98 	/* Become who we really are */
99 	if (seteuid(getuid()) < 0) {
100 		PERROR("Can't set effective user id");
101 		exit(1);
102 	}
103 	if (setegid(getgid()) < 0) {
104 		PERROR("Can't set effective group id");
105 		exit(1);
106 	}
107 
108 	(void) setlocale(LC_ALL, "");
109 
110 #if !defined(TEXT_DOMAIN)
111 #define	TEXT_DOMAIN	"SYS_TEST"
112 #endif
113 
114 	(void) textdomain(TEXT_DOMAIN);
115 
116 	myname = argv[0];
117 	DPRINTF1("myname %s\n", myname);
118 
119 	while ((i = getopt(argc, argv, "b:c:DeF:HlpR:s:tUV:W:w:"))
120 							!= -1) {
121 		DPRINTF1("arg %c\n", i);
122 		switch (i) {
123 		case 'b' :
124 			b_flag++;
125 			label = strdup(optarg);
126 			if (strlen(label) > 8) {
127 				(void) fprintf(stderr, gettext("Label is \
128 restricted to 8 characters.\n"));
129 				exit(1);
130 			}
131 
132 			break;
133 
134 		case 'c' :
135 			c_flag++;
136 			tmp_ptr = strdup(optarg);
137 			errno = 0;
138 			repair_blk_no = (uint32_t)my_atoll(tmp_ptr);
139 			if (repair_blk_no == (uint32_t)(-1)) {
140 				free(tmp_ptr);
141 				usage("invalid block number");
142 			}
143 
144 			DPRINTF1(" block no. %x\n", repair_blk_no);
145 			free(tmp_ptr);
146 			break;
147 
148 		case 'D' :
149 			D_flag++;
150 			break;
151 
152 		case 'e' :
153 			e_flag++;
154 			break;
155 
156 		case 'F' :
157 			F_flag++;
158 			tmp_ptr = strdup(optarg);
159 			if (strcmp(tmp_ptr, "quick") == 0) {
160 				DPRINTF("q");
161 				quick_format = 1;
162 			} else if (strcmp(tmp_ptr, "long") == 0) {
163 				DPRINTF("l");
164 				long_format = 1;
165 			} else if (strcmp(tmp_ptr, "force") == 0) {
166 				DPRINTF("f");
167 				force_format = 1;
168 			} else {
169 				free(tmp_ptr);
170 				usage("invalid argument for option -F");
171 			}
172 			free(tmp_ptr);
173 			break;
174 
175 		case 'H' :
176 			H_flag++;
177 			break;
178 
179 		case 'l' :
180 			l_flag++;
181 			break;
182 
183 		case 'p' :
184 			p_flag++;
185 			break;
186 
187 		case 'R' :
188 			R_flag++;
189 			tmp_ptr = strdup(optarg);
190 			if (strcmp(tmp_ptr, "enable") == 0) {
191 				rw_protect_enable++;
192 			} else if (strcmp(tmp_ptr, "disable") == 0) {
193 				rw_protect_disable++;
194 			} else {
195 				usage("Invalid argument for -R option");
196 			}
197 			free(tmp_ptr);
198 			break;
199 
200 		case 's' :
201 			s_flag++;
202 
203 			slice_file = strdup(optarg);
204 			break;
205 
206 		case 'U' :
207 			U_flag++;
208 			break;
209 
210 		case 'V' :
211 			V_flag++;
212 			tmp_ptr = strdup(optarg);
213 			if (strcmp(tmp_ptr, "read") == 0) {
214 				verify_write = 0;
215 			} else if (strcmp(tmp_ptr, "write") == 0) {
216 				verify_write = 1;
217 			} else {
218 				usage("Invalid argument for -V option");
219 			}
220 			free(tmp_ptr);
221 			break;
222 
223 		case 'W' :
224 			W_flag++;
225 			tmp_ptr = strdup(optarg);
226 			if (strcmp(tmp_ptr, "enable") == 0) {
227 				wp_enable_passwd++;
228 			} else if (strcmp(tmp_ptr, "disable") == 0) {
229 				wp_disable_passwd++;
230 			} else {
231 				usage("Invalid argument for -W option");
232 			}
233 			free(tmp_ptr);
234 			break;
235 
236 		case 'w' :
237 			w_flag++;
238 			tmp_ptr = strdup(optarg);
239 			if (strcmp(tmp_ptr, "enable") == 0) {
240 				wp_enable++;
241 			} else if (strcmp(tmp_ptr, "disable") == 0) {
242 				wp_disable++;
243 			} else {
244 				usage("Invalid arguments for -w option");
245 			}
246 			free(tmp_ptr);
247 			break;
248 
249 		default:
250 			usage("");
251 			break;
252 		}
253 	}
254 	if (optind < argc -1) {
255 		usage("more than one device name argument");
256 		/* NOTREACHED */
257 	}
258 
259 	if (optind == argc -1) {
260 		dev_name = argv[optind];
261 	} else if (optind == 1) {
262 		/* list devices by default */
263 		l_flag++;
264 	} else if ((optind == argc) && !l_flag) {
265 		(void) fprintf(stderr,
266 		    gettext("No device specified.\n"));
267 		exit(1);
268 #if 0
269 		(void) printf("Using floppy device\n");
270 		dev_name = "/dev/rdiskette";
271 #endif /* 0 */
272 	}
273 
274 	process_options();
275 	return (0);
276 }
277 
278 static void
279 usage(char *str)
280 {
281 
282 	if (strlen(str)) {
283 		(void) fprintf(stderr, "%s : ", myname);
284 		(void) fprintf(stderr, gettext(str));
285 		(void) fprintf(stderr, "\n");
286 	}
287 
288 	(void) fprintf(stderr, "Usage:\n");
289 	(void) fprintf(stderr, gettext("\t%s \
290 [ -DeHpU ] [ -b label ] [ -c blockno ] [ -F quick|long|force ] \
291 [ -R enable|disable ] [ -s filename ] [ -V read|write ] \
292 [ -w enable|disable ] [ -W enable|disable ] devname \n"), myname);
293 	(void) fprintf(stderr, gettext("\t%s -l [ devname ]\n"),
294 	    myname);
295 	exit(1);
296 }
297 
298 void
299 check_invalid_combinations()
300 {
301 
302 	/* Inherited from FLOPPY */
303 
304 	if (D_flag && H_flag) {
305 		usage("Options -D and -H incompatible");
306 	}
307 
308 	if (D_flag && F_flag) {
309 		usage("Options -D and -F incompatible");
310 	}
311 
312 	if (H_flag && F_flag) {
313 		usage("Options -H and -F incompatible");
314 	}
315 
316 	/* rmformat additions */
317 
318 	if ((w_flag && W_flag) || (w_flag && R_flag) || (W_flag && R_flag)) {
319 		usage("Options -w, -W and -R incompatible");
320 	}
321 
322 	if (c_flag && F_flag) {
323 		usage("Options -c, -F incompatible");
324 	}
325 
326 	/* l_flag is mutually exclusive of these flags */
327 	if (l_flag && (D_flag + e_flag + H_flag + p_flag + U_flag +
328 	    b_flag + c_flag + F_flag + R_flag + s_flag + V_flag +
329 	    w_flag + W_flag)) {
330 		usage("Options incompatible");
331 	}
332 }
333 
334 
335 void
336 check_invalid_combinations_again(int32_t medium_type)
337 {
338 	if ((medium_type != SM_FLOPPY) &&
339 			(medium_type != SM_PCMCIA_MEM)) {
340 		if (D_flag || H_flag) {
341 			usage("-D, -H  options are compatible with floppy and \
342 PCMCIA memory cards only.");
343 		}
344 	}
345 }
346