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 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 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 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 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