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