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