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