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