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