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_menu.c : 30 * Command line options to rmformat are processed in this file. 31 */ 32 33 #include "rmformat.h" 34 #include <sys/smedia.h> 35 #include <priv_utils.h> 36 37 extern int32_t D_flag; 38 extern int32_t e_flag; 39 extern int32_t H_flag; 40 extern int32_t U_flag; 41 extern int32_t V_flag; 42 extern int32_t b_flag; 43 extern int32_t w_flag; 44 extern int32_t W_flag; 45 extern int32_t s_flag; 46 extern int32_t c_flag; 47 extern int32_t F_flag; 48 extern int32_t R_flag; 49 extern int32_t p_flag; 50 extern int32_t l_flag; 51 52 extern char *myname; 53 extern char *slice_file; 54 extern uint32_t repair_blk_no; 55 extern int32_t quick_format; 56 extern int32_t long_format; 57 extern int32_t force_format; 58 extern int32_t rw_protect_enable; 59 extern int32_t rw_protect_disable; 60 extern int32_t wp_enable_passwd; 61 extern int32_t wp_disable_passwd; 62 extern int32_t wp_enable; 63 extern int32_t wp_disable; 64 extern int32_t verify_write; 65 extern char *dev_name; 66 extern char *label; 67 extern int total_devices_found; 68 extern int removable_found; 69 char *global_intr_msg; 70 smmedium_prop_t med_info; 71 int vol_running; 72 73 extern void check_invalid_combinations(); 74 extern void check_invalid_combinations_again(int32_t); 75 extern void process_options(); 76 extern void get_passwd(struct smwp_state *wp, int32_t confirm); 77 extern int32_t valid_slice_file(smedia_handle_t, int32_t, char *, 78 struct vtoc *); 79 extern void trap_SIGINT(); 80 extern void release_SIGINT(); 81 extern int32_t verify(smedia_handle_t handle, int32_t fd, 82 uint32_t start_sector, uint32_t nblocks, 83 char *buf, int32_t flag, int32_t blocksize, int32_t no_raw_rw); 84 extern void my_perror(char *err_string); 85 extern void write_default_label(smedia_handle_t, int32_t fd); 86 extern int find_device(int defer, char *tmpstr); 87 88 void overwrite_metadata(int32_t fd, smedia_handle_t handle); 89 90 int32_t write_sunos_label(int32_t fd, int32_t media_type); 91 92 int32_t my_open(char *device_name, int32_t flags); 93 int32_t check_and_unmount_vold(char *device_name, int32_t flag); 94 int32_t check_and_unmount_scsi(char *device_name, int32_t flag); 95 96 int32_t check_and_unmount_floppy(int32_t fd, int32_t flag); 97 int32_t get_confirmation(void); 98 99 100 static void process_F_flag(smedia_handle_t handle, int32_t fd); 101 static void process_w_flag(smedia_handle_t handle); 102 static void process_W_flag(smedia_handle_t handle); 103 static void process_R_flag(smedia_handle_t handle); 104 void process_p_flag(smedia_handle_t handle, int32_t fd); 105 static void process_c_flag(smedia_handle_t handle); 106 static void process_V_flag(smedia_handle_t handle, int32_t fd); 107 static void process_s_flag(smedia_handle_t, int32_t fd); 108 static void process_e_flag(smedia_handle_t handle); 109 static void process_H_flag(smedia_handle_t handle, int32_t fd); 110 static void process_D_flag(smedia_handle_t handle, int32_t fd); 111 static void process_b_flag(int32_t fd); 112 static void process_l_flag(void); 113 114 void 115 process_options() 116 { 117 int32_t fd; 118 smedia_handle_t handle; 119 int32_t m_scsi_umount = 0; 120 int32_t m_flp_umount = 0; 121 int32_t v_device_umount = 0; 122 int32_t umount_required = 0; 123 int32_t removable; 124 int32_t umount_failed = 0; 125 struct dk_minfo media; 126 127 check_invalid_combinations(); 128 129 if (l_flag && !dev_name) { 130 process_l_flag(); 131 return; 132 } 133 134 if (U_flag) { 135 if (!(F_flag || H_flag || D_flag)) { 136 F_flag = 1; 137 long_format = 1; 138 } 139 } 140 141 if (F_flag || w_flag || W_flag || R_flag || D_flag || H_flag || 142 V_flag || c_flag || b_flag || s_flag || e_flag) { 143 umount_required = 1; 144 } 145 146 fd = my_open(dev_name, O_RDONLY|O_NDELAY); 147 if (fd < 0) { 148 PERROR("Could not open device"); 149 (void) close(fd); 150 exit(1); 151 } 152 153 if (ioctl(fd, DKIOCREMOVABLE, &removable) < 0) { 154 PERROR("DKIOCREMOVABLE ioctl failed"); 155 (void) close(fd); 156 exit(1); 157 } 158 if (!removable) { 159 (void) fprintf(stderr, 160 gettext("Not a removable media device\n")); 161 (void) close(fd); 162 exit(1); 163 } 164 165 if (ioctl(fd, DKIOCGMEDIAINFO, &media) < 0) { 166 (void) fprintf(stderr, 167 gettext("No media in specified device\n")); 168 (void) close(fd); 169 exit(1); 170 } 171 172 /* Check if volume manager has mounted this */ 173 if (umount_required) { 174 v_device_umount = check_and_unmount_vold(dev_name, U_flag); 175 if (v_device_umount != 1) { 176 m_scsi_umount = check_and_unmount_scsi(dev_name, 177 U_flag); 178 if (m_scsi_umount != 1) { 179 m_flp_umount = check_and_unmount_floppy(fd, 180 U_flag); 181 if (m_flp_umount != 1) { 182 umount_failed = 1; 183 } 184 } 185 } 186 } 187 188 if (umount_required && U_flag && umount_failed) { 189 if (v_device_umount || m_scsi_umount || m_flp_umount) { 190 (void) fprintf(stderr, 191 gettext("Could not unmount device.\n")); 192 (void) close(fd); 193 exit(1); 194 } 195 } 196 197 if (umount_required && !U_flag) { 198 if (v_device_umount || m_scsi_umount || m_flp_umount) { 199 (void) fprintf(stderr, gettext("Device mounted.\n")); 200 (void) fprintf(stderr, 201 gettext("Requested operation can not be \ 202 performed on a mounted device.\n")); 203 (void) close(fd); 204 exit(1); 205 } 206 } 207 /* register the fd with the libsmedia */ 208 handle = smedia_get_handle(fd); 209 if (handle == NULL) { 210 (void) fprintf(stderr, 211 gettext("Failed to get libsmedia handle.\n")); 212 (void) close(fd); 213 exit(1); 214 } 215 216 if (smedia_get_medium_property(handle, &med_info) < 0) { 217 (void) fprintf(stderr, 218 gettext("Get medium property failed \n")); 219 (void) smedia_release_handle(handle); 220 (void) close(fd); 221 exit(1); 222 } 223 224 DPRINTF1("media type %x\n", med_info.sm_media_type); 225 DPRINTF1("media block size %x\n", med_info.sm_blocksize); 226 DPRINTF1("media capacity %x\n", med_info.sm_capacity); 227 DPRINTF3("media cyl %d head %d sect %d\n", 228 med_info.sm_pcyl, med_info.sm_nhead, med_info.sm_nsect); 229 check_invalid_combinations_again(med_info.sm_media_type); 230 231 /* 232 * Special handling for pcmcia, sometimes open the file in 233 * read-write mode. 234 */ 235 236 if (med_info.sm_media_type == SM_PCMCIA_MEM) { 237 if (F_flag || H_flag || D_flag || (V_flag && verify_write)) { 238 (void) close(fd); 239 DPRINTF("Reopening device\n"); 240 fd = my_open(dev_name, O_RDWR|O_NDELAY); 241 if (fd < 0) { 242 PERROR("Could not open device"); 243 (void) smedia_release_handle(handle); 244 (void) close(fd); 245 exit(1); 246 } 247 } 248 } 249 250 if (med_info.sm_media_type == SM_PCMCIA_ATA) { 251 if (V_flag || c_flag) { 252 (void) fprintf(stderr, 253 gettext("Option not supported on PC ATA cards\n")); 254 (void) smedia_release_handle(handle); 255 (void) close(fd); 256 exit(1); 257 } 258 if (F_flag) { 259 /* same text as used by the format command */ 260 (void) fprintf(stderr, 261 gettext("Cannot format this drive. Please use your \ 262 Manufacturer supplied formatting utility.\n")); 263 (void) smedia_release_handle(handle); 264 (void) close(fd); 265 exit(1); 266 } 267 } 268 269 if (F_flag) 270 process_F_flag(handle, fd); 271 if (w_flag) 272 process_w_flag(handle); 273 if (W_flag) 274 process_W_flag(handle); 275 if (R_flag) 276 process_R_flag(handle); 277 if (p_flag) 278 process_p_flag(handle, fd); 279 if (D_flag) 280 process_D_flag(handle, fd); 281 if (H_flag) 282 process_H_flag(handle, fd); 283 if (V_flag) 284 process_V_flag(handle, fd); 285 if (c_flag) 286 process_c_flag(handle); 287 if (b_flag) 288 process_b_flag(fd); 289 if (s_flag) 290 process_s_flag(handle, fd); 291 if (e_flag) 292 process_e_flag(handle); 293 if (l_flag) { 294 process_l_flag(); 295 } 296 297 (void) smedia_release_handle(handle); 298 (void) close(fd); 299 } 300 301 /* 302 * This routine handles the F_flag. 303 * This options should not be used for floppy. However, 304 * if this option is used for floppy, the option will 305 * be forced to SM_FORMAT_HD and smedia_format is called. 306 * Note that smedia_format is a blocked mode format and it 307 * returns only after the complete formatting is over. 308 */ 309 310 static void 311 process_F_flag(smedia_handle_t handle, int32_t fd) 312 { 313 uint32_t format_flag; 314 int32_t old_per = 0; 315 int32_t new_per, ret_val; 316 317 if (force_format) { 318 (void) fprintf(stderr, 319 gettext("Formatting disk.\n")); 320 } else { 321 (void) fprintf(stderr, 322 gettext("Formatting will erase all the data on disk.\n")); 323 if (!get_confirmation()) 324 return; 325 } 326 327 if (quick_format) 328 format_flag = SM_FORMAT_QUICK; 329 else if (long_format) 330 format_flag = SM_FORMAT_LONG; 331 else if (force_format) 332 format_flag = SM_FORMAT_FORCE; 333 334 if (med_info.sm_media_type == SM_FLOPPY) 335 format_flag = SM_FORMAT_HD; 336 337 if ((med_info.sm_media_type != SM_FLOPPY) && 338 (med_info.sm_media_type != SM_PCMCIA_MEM) && 339 (med_info.sm_media_type != SM_SCSI_FLOPPY)) { 340 global_intr_msg = "Interrupting format may render the \ 341 medium useless"; 342 } else { 343 global_intr_msg = ""; 344 } 345 trap_SIGINT(); 346 347 if (smedia_format(handle, format_flag, SM_FORMAT_IMMEDIATE) != 0) { 348 if (errno == EINVAL) { 349 (void) fprintf(stderr, gettext("Format failed.\n")); 350 (void) fprintf(stderr, gettext("The medium may not \ 351 be compatible for format operation.\n")); 352 (void) fprintf(stderr, gettext("read/write surface \ 353 scan may be used to get the effect of formatting.\n")); 354 } else { 355 PERROR("Format failed"); 356 } 357 (void) smedia_release_handle(handle); 358 (void) close(fd); 359 exit(1); 360 } 361 362 /* CONSTCOND */ 363 while (1) { 364 ret_val = smedia_check_format_status(handle); 365 if (ret_val == -1) { 366 if (errno != ENOTSUP) { 367 PERROR("Format failed"); 368 (void) smedia_release_handle(handle); 369 (void) close(fd); 370 exit(1); 371 } else { 372 /* Background formatting is not supported */ 373 break; 374 } 375 } 376 if (ret_val == 100) { 377 (void) printf("\n"); 378 (void) fflush(stdout); 379 break; 380 } 381 new_per = (ret_val * 80)/100; 382 while (new_per >= old_per) { 383 (void) printf("."); 384 (void) fflush(stdout); 385 old_per++; 386 } 387 (void) sleep(6); 388 } 389 390 if ((med_info.sm_media_type == SM_FLOPPY) || 391 (med_info.sm_media_type == SM_PCMCIA_MEM) || 392 (med_info.sm_media_type == SM_SCSI_FLOPPY)) { 393 (void) write_sunos_label(fd, med_info.sm_media_type); 394 } else { 395 396 /* 397 * Iomega drives don't destroy the data in quick format. 398 * Do a best effort write to first 1024 sectors. 399 */ 400 401 if (quick_format) 402 overwrite_metadata(fd, handle); 403 404 (void) write_default_label(handle, fd); 405 } 406 407 release_SIGINT(); 408 } 409 410 /* 411 * List removable devices. 412 */ 413 static void 414 process_l_flag() 415 { 416 int retry; 417 int removable; 418 int total_devices_found_last_time; 419 int defer = 0; 420 char *tmpstr; 421 422 #define MAX_RETRIES_FOR_SCANNING 3 423 424 vol_running = volmgt_running(); 425 if (vol_running) 426 defer = 1; 427 (void) printf(gettext("Looking for devices...\n")); 428 total_devices_found_last_time = 0; 429 430 /* 431 * Strip out any leading path. For example, /dev/rdsk/c3t0d0s2 432 * will result in tmpstr = c3t0d0s2. dev_name is given as input 433 * argument. 434 */ 435 if (dev_name) { 436 if ((tmpstr = strrchr(dev_name, '/')) != NULL) { 437 tmpstr += sizeof (char); 438 } else { 439 tmpstr = dev_name; 440 } 441 } 442 443 for (retry = 0; retry < MAX_RETRIES_FOR_SCANNING; retry++) { 444 removable = find_device(defer, tmpstr); 445 if (removable == -1) 446 break; 447 448 /* 449 * We'll do a small sleep and retry the command if volume 450 * manager is running and no removable devices are found. 451 * This is because the device may be busy. 452 */ 453 if (defer || (vol_running && (removable == 0))) { 454 if ((total_devices_found == 0) || 455 (total_devices_found != 456 total_devices_found_last_time)) { 457 total_devices_found_last_time = 458 total_devices_found; 459 (void) sleep(2); 460 } else { 461 /* Do the printing this time */ 462 defer = 0; 463 removable_found = 0; 464 } 465 466 } else 467 break; 468 } 469 if (removable_found == 0) 470 (void) printf(gettext("No removables found.\n")); 471 } 472 473 /* 474 * The following three routines handle the write protect 475 * options. These options are mostly Iomega ZIP/Jaz centric. 476 * The following options are allowed : 477 * No write protect <=> write protect without passwd : use -w flag 478 * from any state to WP with passwd : use -W flag 479 * from WP with passwd to no write protect : use -W flag 480 * from any state to RWP with passwd : use -R flag 481 * from RWP with passwd to no write protect : use -R flag 482 * 483 * The following transitions is not allowed 484 * WP with passwd or RWP to WP without passwd. 485 */ 486 487 static void 488 process_w_flag(smedia_handle_t handle) 489 { 490 int32_t rval; 491 int32_t med_status; 492 struct smwp_state wps; 493 494 if ((rval = smedia_get_protection_status((handle), &wps)) < 0) { 495 (void) fprintf(stderr, 496 gettext("Could not get medium status \n")); 497 return; 498 } 499 med_status = wps.sm_new_state; 500 501 wps.sm_version = SMWP_STATE_V_1; 502 503 if (wp_enable) { /* Enable write protect no password */ 504 505 switch (med_status) { 506 case SM_WRITE_PROTECT_DISABLE : 507 wps.sm_new_state = 508 SM_WRITE_PROTECT_NOPASSWD; 509 wps.sm_passwd_len = 0; 510 rval = smedia_set_protection_status(handle, 511 &wps); 512 if (rval == -1) 513 PERROR(WP_ERROR); 514 break; 515 case SM_WRITE_PROTECT_NOPASSWD : 516 (void) fprintf(stderr, gettext(WP_MSG_0)); 517 break; 518 case SM_WRITE_PROTECT_PASSWD : 519 (void) fprintf(stderr, gettext(WP_MSG_1)); 520 break; 521 case SM_READ_WRITE_PROTECT : 522 (void) fprintf(stderr, gettext(WP_MSG_2)); 523 break; 524 case SM_STATUS_UNKNOWN : 525 default : 526 (void) fprintf(stderr, gettext(WP_UNKNOWN)); 527 break; 528 } 529 } else if (wp_disable) { 530 switch (med_status) { 531 case SM_WRITE_PROTECT_NOPASSWD : 532 wps.sm_new_state = 533 SM_WRITE_PROTECT_DISABLE; 534 wps.sm_passwd_len = 0; 535 rval = smedia_set_protection_status(handle, 536 &wps); 537 if (rval == -1) 538 PERROR(WP_ERROR); 539 break; 540 case SM_WRITE_PROTECT_DISABLE : 541 (void) fprintf(stderr, gettext(WP_MSG_3)); 542 break; 543 case SM_WRITE_PROTECT_PASSWD : 544 (void) fprintf(stderr, gettext(WP_MSG_1)); 545 break; 546 case SM_READ_WRITE_PROTECT : 547 (void) fprintf(stderr, gettext(WP_MSG_2)); 548 break; 549 case SM_STATUS_UNKNOWN : 550 default : 551 (void) fprintf(stderr, gettext(WP_UNKNOWN)); 552 break; 553 } 554 } 555 } 556 557 static void 558 process_W_flag(smedia_handle_t handle) 559 { 560 int32_t rval; 561 int32_t med_status; 562 struct smwp_state wps; 563 564 DPRINTF("Write protect with password\n"); 565 566 if ((rval = smedia_get_protection_status((handle), &wps)) < 0) { 567 (void) fprintf(stderr, 568 gettext("Could not get medium status \n")); 569 return; 570 } 571 med_status = wps.sm_new_state; 572 573 wps.sm_version = SMWP_STATE_V_1; 574 575 if (wp_enable_passwd) { /* Enable write protect */ 576 switch (med_status) { 577 case SM_WRITE_PROTECT_DISABLE : 578 case SM_WRITE_PROTECT_NOPASSWD : 579 DPRINTF("Getting passwd\n"); 580 get_passwd(&wps, 1); 581 wps.sm_new_state = 582 SM_WRITE_PROTECT_PASSWD; 583 rval = smedia_set_protection_status(handle, 584 &wps); 585 if (rval == -1) { 586 PERROR(WP_ERROR); 587 } 588 break; 589 case SM_READ_WRITE_PROTECT : 590 (void) fprintf(stderr, gettext(WP_MSG_4)); 591 (void) fprintf(stderr, gettext(WP_MSG_5)); 592 get_passwd(&wps, 0); 593 wps.sm_new_state = 594 SM_WRITE_PROTECT_PASSWD; 595 rval = smedia_set_protection_status(handle, 596 &wps); 597 if (rval == -1) { 598 if (errno == EACCES) { 599 (void) fprintf(stderr, 600 gettext(WP_MSG_10)); 601 } else { 602 PERROR(WP_ERROR); 603 } 604 } 605 break; 606 case SM_WRITE_PROTECT_PASSWD : 607 (void) fprintf(stderr, gettext(WP_MSG_6)); 608 break; 609 case SM_STATUS_UNKNOWN : 610 default : 611 (void) fprintf(stderr, 612 gettext(WP_UNKNOWN)); 613 break; 614 } 615 } else if (wp_disable_passwd) { 616 switch (med_status) { 617 case SM_WRITE_PROTECT_PASSWD : 618 get_passwd(&wps, 0); 619 wps.sm_new_state = 620 SM_WRITE_PROTECT_DISABLE; 621 rval = smedia_set_protection_status(handle, 622 &wps); 623 if (rval == -1) { 624 if (errno == EACCES) { 625 (void) fprintf(stderr, 626 gettext(WP_MSG_10)); 627 } else { 628 PERROR(WP_ERROR); 629 } 630 } 631 break; 632 case SM_READ_WRITE_PROTECT : 633 (void) fprintf(stderr, gettext(WP_MSG_2)); 634 break; 635 case SM_WRITE_PROTECT_NOPASSWD : 636 (void) fprintf(stderr, gettext(WP_MSG_7)); 637 break; 638 case SM_WRITE_PROTECT_DISABLE : 639 (void) fprintf(stderr, gettext(WP_MSG_3)); 640 break; 641 case SM_STATUS_UNKNOWN : 642 default : 643 (void) fprintf(stderr, gettext(WP_UNKNOWN)); 644 break; 645 } 646 } 647 } 648 649 static void 650 process_R_flag(smedia_handle_t handle) 651 { 652 int32_t rval; 653 int32_t med_status; 654 struct smwp_state wps; 655 656 DPRINTF("Read Write protect \n"); 657 658 if ((rval = smedia_get_protection_status((handle), &wps)) < 0) { 659 (void) fprintf(stderr, 660 gettext("Could not get medium status \n")); 661 return; 662 } 663 med_status = wps.sm_new_state; 664 665 wps.sm_version = SMWP_STATE_V_1; 666 667 if (rw_protect_enable) { /* Enable write protect */ 668 switch (med_status) { 669 case SM_WRITE_PROTECT_DISABLE : 670 case SM_WRITE_PROTECT_NOPASSWD : 671 DPRINTF("Getting passwd\n"); 672 get_passwd(&wps, 1); 673 wps.sm_new_state = 674 SM_READ_WRITE_PROTECT; 675 rval = smedia_set_protection_status(handle, 676 &wps); 677 if (rval == -1) 678 PERROR(WP_ERROR); 679 break; 680 case SM_WRITE_PROTECT_PASSWD : 681 (void) fprintf(stderr, gettext(WP_MSG_8)); 682 (void) fprintf(stderr, gettext(WP_MSG_9)); 683 get_passwd(&wps, 0); 684 wps.sm_new_state = 685 SM_READ_WRITE_PROTECT; 686 rval = smedia_set_protection_status(handle, 687 &wps); 688 if (rval == -1) { 689 if (errno == EACCES) { 690 (void) fprintf(stderr, 691 gettext(WP_MSG_10)); 692 } else { 693 PERROR(WP_ERROR); 694 } 695 } 696 break; 697 case SM_READ_WRITE_PROTECT : 698 (void) fprintf(stderr, gettext(WP_MSG_4)); 699 break; 700 case SM_STATUS_UNKNOWN : 701 default : 702 (void) fprintf(stderr, gettext(WP_UNKNOWN)); 703 break; 704 } 705 } else if (rw_protect_disable) { 706 switch (med_status) { 707 case SM_READ_WRITE_PROTECT : 708 case SM_STATUS_UNKNOWN : 709 get_passwd(&wps, 0); 710 wps.sm_new_state = 711 SM_WRITE_PROTECT_DISABLE; 712 rval = smedia_set_protection_status(handle, 713 &wps); 714 if (rval == -1) { 715 if (errno == EACCES) { 716 (void) fprintf(stderr, 717 gettext(WP_MSG_10)); 718 } else { 719 PERROR(WP_ERROR); 720 } 721 } 722 break; 723 case SM_WRITE_PROTECT_PASSWD : 724 (void) fprintf(stderr, gettext(WP_MSG_1)); 725 break; 726 case SM_WRITE_PROTECT_NOPASSWD : 727 (void) fprintf(stderr, gettext(WP_MSG_7)); 728 break; 729 case SM_WRITE_PROTECT_DISABLE : 730 (void) fprintf(stderr, gettext(WP_MSG_3)); 731 break; 732 default : 733 (void) fprintf(stderr, gettext(WP_UNKNOWN)); 734 break; 735 } 736 } 737 } 738 739 void 740 process_p_flag(smedia_handle_t handle, int32_t fd) 741 { 742 int32_t med_status; 743 smwp_state_t wps; 744 745 med_status = smedia_get_protection_status((handle), &wps); 746 DPRINTF("Could not get medium status \n"); 747 748 /* 749 * Workaround in case mode sense fails. 750 * 751 * Also, special handling for PCMCIA. PCMCIA does not have any 752 * ioctl to find out the write protect status. So, open the 753 * device with O_RDWR. If it passes, it is not write protected, 754 * otherwise it is write protected. 755 * If it fails, reopen with O_RDONLY, may be some other 756 * operation can go through. 757 */ 758 if ((med_status < 0) || (med_info.sm_media_type == SM_PCMCIA_MEM) || 759 (med_info.sm_media_type == SM_PCMCIA_ATA)) { 760 (void) close(fd); 761 DPRINTF("Reopening device for -p option\n"); 762 fd = my_open(dev_name, O_RDONLY|O_NDELAY); 763 if (fd < 0) { 764 if (p_flag) { 765 PERROR("Could not open device"); 766 (void) smedia_release_handle(handle); 767 (void) close(fd); 768 exit(1); 769 } else { 770 (void) fprintf(stderr, 771 gettext("<Unknown>\n")); 772 (void) smedia_release_handle(handle); 773 (void) close(fd); 774 return; 775 } 776 fd = my_open(dev_name, O_RDWR|O_NDELAY); 777 if (fd < 0) { 778 (void) fprintf(stderr, 779 gettext("Medium is write protected.\n")); 780 } 781 } else { /* Open succeeded */ 782 (void) fprintf(stderr, 783 gettext("Medium is not write protected.\n")); 784 } 785 return; 786 } 787 med_status = wps.sm_new_state; 788 switch (med_status) { 789 790 case SM_READ_WRITE_PROTECT : 791 (void) fprintf(stderr, 792 gettext("Medium is read-write protected.\n")); 793 break; 794 case SM_WRITE_PROTECT_PASSWD : 795 (void) fprintf(stderr, 796 gettext("Medium is write protected with password.\n")); 797 break; 798 case SM_WRITE_PROTECT_NOPASSWD : 799 (void) fprintf(stderr, 800 gettext("Medium is write protected.\n")); 801 break; 802 case SM_WRITE_PROTECT_DISABLE : 803 (void) fprintf(stderr, 804 gettext("Medium is not write protected.\n")); 805 break; 806 case SM_STATUS_UNKNOWN : 807 default: 808 (void) fprintf(stderr, 809 gettext("Unknown write protect status.\n")); 810 break; 811 } 812 } 813 814 static void 815 process_c_flag(smedia_handle_t handle) 816 { 817 char error_string[256]; 818 819 if (smedia_reassign_block(handle, repair_blk_no) != 0) { 820 (void) snprintf(error_string, 255, 821 gettext("Could not repair block no %d"), repair_blk_no); 822 PERROR(error_string); 823 return; 824 } 825 } 826 827 /* 828 * This routine handles the -V (verify) option. 829 * There can be devices without rw_read option. If the raw_read 830 * and raw_write are not supported by the interface, then read and 831 * write system calls are used. It is assumed that either both 832 * raw_read and raw_write are supported or both are unsupported. 833 */ 834 835 static void 836 process_V_flag(smedia_handle_t handle, int32_t fd) 837 { 838 int32_t ret; 839 uint32_t i, j; 840 char *read_buf, *write_buf; 841 int32_t old_per = 0; 842 int32_t new_per; 843 int32_t no_raw_rw = 0; 844 int32_t verify_size; 845 uint32_t capacity; 846 int32_t blocksize; 847 848 DPRINTF("ANALYSE MEDIA \n"); 849 850 ret = smedia_get_medium_property(handle, &med_info); 851 if (ret == -1) { 852 DPRINTF("get_media_info failed\n"); 853 return; 854 } 855 856 DPRINTF1("media_type %d\n", med_info.sm_media_type); 857 DPRINTF1("sector_size %d\n", med_info.sm_blocksize); 858 DPRINTF1("num_sectors %d\n", med_info.sm_capacity); 859 DPRINTF1("nsect %d\n", med_info.sm_nsect); 860 861 blocksize = med_info.sm_blocksize; 862 863 capacity = med_info.sm_capacity; 864 verify_size = (med_info.sm_nsect > 64) ? 64 : med_info.sm_nsect; 865 read_buf = (char *)malloc(blocksize * verify_size); 866 if (read_buf == NULL) { 867 DPRINTF("Could not allocate memory\n"); 868 return; 869 } 870 write_buf = (char *)malloc(blocksize * verify_size); 871 if (write_buf == NULL) { 872 DPRINTF("Could not allocate memory\n"); 873 free(read_buf); 874 return; 875 } 876 877 if (!verify_write) { 878 DPRINTF("Non-destructive verify \n"); 879 for (i = 0; i < med_info.sm_capacity; i += verify_size) { 880 new_per = (i * 80)/med_info.sm_capacity; 881 if (new_per >= old_per) { 882 (void) printf("."); 883 (void) fflush(stdout); 884 old_per++; 885 } 886 DPRINTF2("Reading %d blks starting at %d\n", 887 verify_size, i); 888 ret = verify(handle, fd, i, verify_size, read_buf, 889 VERIFY_READ, blocksize, no_raw_rw); 890 if ((ret == -1) && (errno == ENOTSUP)) { 891 no_raw_rw = 1; 892 ret = verify(handle, fd, i, verify_size, 893 read_buf, 894 VERIFY_READ, blocksize, no_raw_rw); 895 capacity = med_info.sm_pcyl * med_info.sm_nhead 896 * med_info.sm_nsect; 897 } 898 899 if (ret != 0) { 900 for (j = 0; j < verify_size; j++) { 901 if ((i + j) >= capacity) 902 return; 903 DPRINTF2( 904 "Reading %d blks starting at %d\n", 905 1, i+j); 906 ret = verify(handle, fd, i + j, 1, 907 read_buf, 908 VERIFY_READ, blocksize, 909 no_raw_rw); 910 if (ret == -1) { 911 (void) printf("Bad block %d\n", 912 i+j); 913 } 914 } 915 } 916 } 917 } else { 918 919 DPRINTF("Destrutive verify \n"); 920 for (i = 0; i < med_info.sm_capacity; i += verify_size) { 921 new_per = (i * 80)/med_info.sm_capacity; 922 if (new_per >= old_per) { 923 (void) printf("."); 924 925 (void) fflush(stdout); 926 old_per++; 927 } 928 929 for (j = 0; j < blocksize * verify_size; j++) { 930 write_buf[j] = (i|j) & 0xFF; 931 } 932 DPRINTF2("Writing %d blks starting at %d\n", 933 verify_size, i); 934 ret = verify(handle, fd, i, verify_size, write_buf, 935 VERIFY_WRITE, blocksize, no_raw_rw); 936 937 if (ret != 0) { 938 for (j = 0; j < verify_size; j++) { 939 if ((i + j) >= capacity) 940 break; 941 DPRINTF2( 942 "Writing %d blks starting at %d\n", 943 1, i+j); 944 ret = verify(handle, fd, i + j, 1, 945 write_buf, 946 VERIFY_WRITE, blocksize, 947 no_raw_rw); 948 if (ret == -1) { 949 (void) printf("Bad block %d\n", 950 i+j); 951 } 952 } 953 } 954 DPRINTF2("Read after write %d blks starting at %d\n", 955 verify_size, i); 956 ret = verify(handle, fd, i, verify_size, 957 read_buf, VERIFY_READ, blocksize, no_raw_rw); 958 959 if (ret != 0) { 960 for (j = 0; j < verify_size; j++) { 961 if ((i + j) >= capacity) 962 return; 963 DPRINTF2( 964 "Read after write %d blks starting at %d\n", 965 1, i+j); 966 ret = verify(handle, fd, i + j, 1, 967 read_buf, VERIFY_READ, 968 blocksize, no_raw_rw); 969 if (ret == -1) { 970 (void) printf("Bad block %d\n", 971 i+j); 972 } 973 } 974 } 975 976 977 } 978 } 979 } 980 981 static void 982 process_s_flag(smedia_handle_t handle, int32_t fd) 983 { 984 int32_t i, ret; 985 struct vtoc v_toc, t_vtoc; 986 if (valid_slice_file(handle, fd, slice_file, &v_toc)) { 987 (void) smedia_release_handle(handle); 988 (void) close(fd); 989 exit(1); 990 } 991 992 (void) memset(&t_vtoc, 0, sizeof (t_vtoc)); 993 994 995 t_vtoc.v_nparts = V_NUMPAR; 996 t_vtoc.v_sanity = VTOC_SANE; 997 t_vtoc.v_version = V_VERSION; 998 t_vtoc.v_sectorsz = DEV_BSIZE; 999 1000 /* Get existing Vtoc, don't bother if it fails. */ 1001 1002 /* Turn on privileges. */ 1003 (void) __priv_bracket(PRIV_ON); 1004 1005 (void) read_vtoc(fd, &t_vtoc); 1006 1007 /* Turn off privileges. */ 1008 (void) __priv_bracket(PRIV_OFF); 1009 1010 for (i = 0; i < V_NUMPAR; i++) { 1011 t_vtoc.v_part[i].p_start = v_toc.v_part[i].p_start; 1012 t_vtoc.v_part[i].p_size = v_toc.v_part[i].p_size; 1013 t_vtoc.v_part[i].p_tag = v_toc.v_part[i].p_tag; 1014 t_vtoc.v_part[i].p_flag = v_toc.v_part[i].p_flag; 1015 } 1016 1017 errno = 0; 1018 1019 1020 /* Turn on privileges. */ 1021 (void) __priv_bracket(PRIV_ON); 1022 1023 ret = write_vtoc(fd, &t_vtoc); 1024 1025 /* Turn off privileges. */ 1026 (void) __priv_bracket(PRIV_OFF); 1027 1028 if (ret < 0) { 1029 #ifdef sparc 1030 PERROR("write VTOC failed"); 1031 DPRINTF1("Errno = %d\n", errno); 1032 #else /* i386 */ 1033 if (errno == EIO) { 1034 PERROR("No Solaris partition, eject & retry"); 1035 DPRINTF1("Errno = %d\n", errno); 1036 } else { 1037 PERROR("write VTOC failed"); 1038 DPRINTF1("Errno = %d\n", errno); 1039 } 1040 #endif 1041 } 1042 } 1043 static void 1044 process_e_flag(smedia_handle_t handle) 1045 { 1046 if (smedia_eject(handle) < 0) { 1047 PERROR("Eject failed"); 1048 } 1049 } 1050 static void 1051 process_H_flag(smedia_handle_t handle, int32_t fd) 1052 { 1053 uint32_t cyl, head; 1054 int32_t old_per = 0; 1055 int32_t new_per; 1056 1057 (void) fprintf(stderr, 1058 gettext("Formatting will erase all the data on disk.\n")); 1059 if (!get_confirmation()) 1060 return; 1061 1062 for (cyl = 0; cyl < med_info.sm_pcyl; cyl++) { 1063 for (head = 0; head < med_info.sm_nhead; head++) { 1064 if (smedia_format_track(handle, cyl, head, SM_FORMAT_HD) 1065 < 0) { 1066 PERROR("Format failed"); 1067 return; 1068 } 1069 } 1070 new_per = (cyl * 80)/med_info.sm_pcyl; 1071 while (new_per >= old_per) { 1072 (void) printf("."); 1073 (void) fflush(stdout); 1074 old_per++; 1075 } 1076 } 1077 1078 (void) write_sunos_label(fd, med_info.sm_media_type); 1079 } 1080 1081 static void 1082 process_D_flag(smedia_handle_t handle, int32_t fd) 1083 { 1084 uint32_t cyl, head; 1085 int32_t old_per = 0; 1086 int32_t new_per; 1087 1088 (void) fprintf(stderr, 1089 gettext("Formatting will erase all the data on disk.\n")); 1090 if (!get_confirmation()) 1091 return; 1092 for (cyl = 0; cyl < med_info.sm_pcyl; cyl++) { 1093 for (head = 0; head < med_info.sm_nhead; head++) { 1094 if (smedia_format_track(handle, cyl, head, SM_FORMAT_DD) 1095 < 0) { 1096 PERROR("Format failed"); 1097 return; 1098 } 1099 } 1100 new_per = (cyl * 80)/med_info.sm_pcyl; 1101 while (new_per >= old_per) { 1102 (void) printf("."); 1103 (void) fflush(stdout); 1104 old_per++; 1105 } 1106 } 1107 (void) write_sunos_label(fd, med_info.sm_media_type); 1108 } 1109 1110 /* 1111 * This routine handles the -b (label) option. 1112 * Please note that, this will fail if there is no valid vtoc is 1113 * there on the medium and the vtoc is not faked. 1114 */ 1115 1116 static void 1117 process_b_flag(int32_t fd) 1118 { 1119 int32_t ret, nparts; 1120 struct vtoc v_toc; 1121 struct dk_gpt *vtoc64; 1122 1123 /* For EFI disks. */ 1124 if (efi_type(fd)) { 1125 if (efi_alloc_and_read(fd, &vtoc64) < 0) { 1126 /* 1127 * If reading the vtoc failed, try to 1128 * auto-sense the disk configuration. 1129 */ 1130 if (efi_auto_sense(fd, &vtoc64) < 0) { 1131 (void) fprintf(stderr, 1132 gettext("Could not write label.\n")); 1133 return; 1134 } 1135 } 1136 for (nparts = 0; nparts < vtoc64->efi_nparts; 1137 nparts++) { 1138 if (vtoc64->efi_parts[nparts].p_tag == 1139 V_RESERVED) { 1140 if (vtoc64->efi_parts[nparts].p_name) { 1141 (void) strncpy( 1142 vtoc64->efi_parts[nparts].p_name, label, 1143 EFI_PART_NAME_LEN); 1144 } 1145 break; 1146 } 1147 } 1148 if (efi_write(fd, vtoc64) != 0) { 1149 (void) efi_err_check(vtoc64); 1150 (void) fprintf(stderr, 1151 gettext("Could not write label.\n")); 1152 } 1153 return; 1154 } 1155 1156 /* Get existing Vtoc */ 1157 1158 /* Turn on privileges. */ 1159 (void) __priv_bracket(PRIV_ON); 1160 1161 ret = read_vtoc(fd, &v_toc); 1162 1163 /* Turn off privileges */ 1164 (void) __priv_bracket(PRIV_OFF); 1165 1166 if (ret < 0) { 1167 #ifdef sparc 1168 PERROR("read VTOC failed"); 1169 DPRINTF1("Errno = %d\n", errno); 1170 #else /* i386 */ 1171 if (errno == EIO) { 1172 PERROR("No Solaris partition, eject & retry"); 1173 DPRINTF1("Errno = %d\n", errno); 1174 } else { 1175 PERROR("read VTOC failed"); 1176 DPRINTF1("Errno = %d\n", errno); 1177 } 1178 #endif 1179 return; 1180 } 1181 1182 (void) strncpy(v_toc.v_volume, label, LEN_DKL_VVOL); 1183 1184 1185 /* Turn on the privileges. */ 1186 (void) __priv_bracket(PRIV_ON); 1187 1188 ret = write_vtoc(fd, &v_toc); 1189 1190 /* Turn off the privileges. */ 1191 (void) __priv_bracket(PRIV_OFF); 1192 1193 if (ret < 0) { 1194 #ifdef sparc 1195 PERROR("write VTOC failed"); 1196 DPRINTF1("Errno = %d\n", errno); 1197 #else /* i386 */ 1198 if (errno == EIO) { 1199 PERROR("No Solaris partition, eject & retry"); 1200 DPRINTF1("Errno = %d\n", errno); 1201 } else { 1202 PERROR("write VTOC failed"); 1203 DPRINTF1("Errno = %d\n", errno); 1204 } 1205 #endif 1206 } 1207 } 1208