/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* rmf_menu.c :
* Command line options to rmformat are processed in this file.
*/
#include "rmformat.h"
#include <priv_utils.h>
extern char *myname;
extern char *slice_file;
extern diskaddr_t repair_blk_no;
extern int32_t quick_format;
extern int32_t long_format;
extern int32_t force_format;
extern int32_t rw_protect_enable;
extern int32_t rw_protect_disable;
extern int32_t wp_enable_passwd;
extern int32_t wp_disable_passwd;
extern int32_t wp_disable;
extern int32_t verify_write;
extern char *dev_name;
extern char *label;
extern int total_devices_found;
extern int removable_found;
char *global_intr_msg;
int vol_running;
extern void check_invalid_combinations();
extern void check_invalid_combinations_again(int32_t);
extern void process_options();
struct extvtoc *);
extern void trap_SIGINT();
extern void release_SIGINT();
extern void my_perror(char *err_string);
int32_t get_confirmation(void);
static void process_l_flag(void);
void
{
return;
}
if (U_flag) {
F_flag = 1;
long_format = 1;
}
}
umount_required = 1;
}
if (fd < 0) {
PERROR("Could not open device");
exit(1);
}
PERROR("DKIOCREMOVABLE ioctl failed");
exit(1);
}
if (!removable) {
gettext("Not a removable media device\n"));
exit(1);
}
gettext("No media in specified device\n"));
exit(1);
}
/* Check if volume manager has mounted this */
if (umount_required) {
if (v_device_umount != 1) {
U_flag);
if (m_scsi_umount != 1) {
U_flag);
if (m_flp_umount != 1) {
umount_failed = 1;
}
}
}
}
gettext("Could not unmount device.\n"));
exit(1);
}
}
if (umount_required && !U_flag) {
gettext("Requested operation can not be \
performed on a mounted device.\n"));
exit(1);
}
}
/* register the fd with the libsmedia */
gettext("Failed to get libsmedia handle.\n"));
exit(1);
}
gettext("Get medium property failed \n"));
(void) smedia_release_handle(handle);
exit(1);
}
DPRINTF3("media cyl %d head %d sect %d\n",
/*
* Special handling for pcmcia, sometimes open the file in
* read-write mode.
*/
DPRINTF("Reopening device\n");
if (fd < 0) {
PERROR("Could not open device");
(void) smedia_release_handle(handle);
exit(1);
}
}
}
gettext("Option not supported on PC ATA cards\n"));
(void) smedia_release_handle(handle);
exit(1);
}
if (F_flag) {
/* same text as used by the format command */
gettext("Cannot format this drive. Please use your \
Manufacturer supplied formatting utility.\n"));
(void) smedia_release_handle(handle);
exit(1);
}
}
if (F_flag)
if (w_flag)
if (W_flag)
if (R_flag)
if (p_flag)
if (D_flag)
if (H_flag)
if (V_flag)
if (c_flag)
if (b_flag)
if (s_flag)
if (e_flag)
if (l_flag) {
}
(void) smedia_release_handle(handle);
}
/*
* This routine handles the F_flag.
* This options should not be used for floppy. However,
* if this option is used for floppy, the option will
* be forced to SM_FORMAT_HD and smedia_format is called.
* Note that smedia_format is a blocked mode format and it
* returns only after the complete formatting is over.
*/
static void
{
if (force_format) {
gettext("Formatting disk.\n"));
} else {
gettext("Formatting will erase all the data on disk.\n"));
if (!get_confirmation())
return;
}
if (quick_format)
else if (long_format)
else if (force_format)
global_intr_msg = "Interrupting format may render the \
medium useless";
} else {
global_intr_msg = "";
}
trap_SIGINT();
be compatible for format operation.\n"));
scan may be used to get the effect of formatting.\n"));
} else {
PERROR("Format failed");
}
(void) smedia_release_handle(handle);
exit(1);
}
/* CONSTCOND */
while (1) {
if (ret_val == -1) {
PERROR("Format failed");
(void) smedia_release_handle(handle);
exit(1);
} else {
/* Background formatting is not supported */
break;
}
}
if (ret_val == 100) {
(void) printf("\n");
break;
}
(void) printf(".");
old_per++;
}
(void) sleep(6);
}
} else {
/*
* Iomega drives don't destroy the data in quick format.
* Do a best effort write to first 1024 sectors.
*/
if (quick_format)
}
}
/*
* List removable devices.
*/
static void
{
int retry;
int removable;
int defer = 0;
char *tmpstr;
if (vol_running)
defer = 1;
/*
* will result in tmpstr = c3t0d0s2. dev_name is given as input
* argument.
*/
if (dev_name) {
tmpstr += sizeof (char);
} else {
}
}
if (removable == -1)
break;
/*
* We'll do a small sleep and retry the command if volume
* manager is running and no removable devices are found.
* This is because the device may be busy.
*/
if ((total_devices_found == 0) ||
(void) sleep(2);
} else {
/* Do the printing this time */
defer = 0;
removable_found = 0;
}
} else
break;
}
if (removable_found == 0)
}
/*
* The following three routines handle the write protect
* The following options are allowed :
* No write protect <=> write protect without passwd : use -w flag
* from any state to WP with passwd : use -W flag
* from WP with passwd to no write protect : use -W flag
* from any state to RWP with passwd : use -R flag
* from RWP with passwd to no write protect : use -R flag
*
* The following transitions is not allowed
* WP with passwd or RWP to WP without passwd.
*/
static void
{
gettext("Could not get medium status \n"));
return;
}
if (wp_enable) { /* Enable write protect no password */
switch (med_status) {
case SM_WRITE_PROTECT_DISABLE :
wps.sm_passwd_len = 0;
&wps);
if (rval == -1)
break;
case SM_WRITE_PROTECT_NOPASSWD :
break;
case SM_WRITE_PROTECT_PASSWD :
break;
case SM_READ_WRITE_PROTECT :
break;
case SM_STATUS_UNKNOWN :
default :
break;
}
} else if (wp_disable) {
switch (med_status) {
case SM_WRITE_PROTECT_NOPASSWD :
wps.sm_passwd_len = 0;
&wps);
if (rval == -1)
break;
case SM_WRITE_PROTECT_DISABLE :
break;
case SM_WRITE_PROTECT_PASSWD :
break;
case SM_READ_WRITE_PROTECT :
break;
case SM_STATUS_UNKNOWN :
default :
break;
}
}
}
static void
{
DPRINTF("Write protect with password\n");
gettext("Could not get medium status \n"));
return;
}
if (wp_enable_passwd) { /* Enable write protect */
switch (med_status) {
case SM_WRITE_PROTECT_DISABLE :
case SM_WRITE_PROTECT_NOPASSWD :
DPRINTF("Getting passwd\n");
&wps);
if (rval == -1) {
}
break;
case SM_READ_WRITE_PROTECT :
get_passwd(&wps, 0);
&wps);
if (rval == -1) {
} else {
}
}
break;
case SM_WRITE_PROTECT_PASSWD :
break;
case SM_STATUS_UNKNOWN :
default :
break;
}
} else if (wp_disable_passwd) {
switch (med_status) {
case SM_WRITE_PROTECT_PASSWD :
get_passwd(&wps, 0);
&wps);
if (rval == -1) {
} else {
}
}
break;
case SM_READ_WRITE_PROTECT :
break;
case SM_WRITE_PROTECT_NOPASSWD :
break;
case SM_WRITE_PROTECT_DISABLE :
break;
case SM_STATUS_UNKNOWN :
default :
break;
}
}
}
static void
{
DPRINTF("Read Write protect \n");
gettext("Could not get medium status \n"));
return;
}
if (rw_protect_enable) { /* Enable write protect */
switch (med_status) {
case SM_WRITE_PROTECT_DISABLE :
case SM_WRITE_PROTECT_NOPASSWD :
DPRINTF("Getting passwd\n");
&wps);
if (rval == -1)
break;
case SM_WRITE_PROTECT_PASSWD :
get_passwd(&wps, 0);
&wps);
if (rval == -1) {
} else {
}
}
break;
case SM_READ_WRITE_PROTECT :
break;
case SM_STATUS_UNKNOWN :
default :
break;
}
} else if (rw_protect_disable) {
switch (med_status) {
case SM_READ_WRITE_PROTECT :
case SM_STATUS_UNKNOWN :
get_passwd(&wps, 0);
&wps);
if (rval == -1) {
} else {
}
}
break;
case SM_WRITE_PROTECT_PASSWD :
break;
case SM_WRITE_PROTECT_NOPASSWD :
break;
case SM_WRITE_PROTECT_DISABLE :
break;
default :
break;
}
}
}
void
{
DPRINTF("Could not get medium status \n");
/*
* Workaround in case mode sense fails.
*
* Also, special handling for PCMCIA. PCMCIA does not have any
* ioctl to find out the write protect status. So, open the
* device with O_RDWR. If it passes, it is not write protected,
* otherwise it is write protected.
* If it fails, reopen with O_RDONLY, may be some other
* operation can go through.
*/
DPRINTF("Reopening device for -p option\n");
if (fd < 0) {
if (p_flag) {
PERROR("Could not open device");
(void) smedia_release_handle(handle);
exit(1);
} else {
gettext("<Unknown>\n"));
(void) smedia_release_handle(handle);
return;
}
if (fd < 0) {
gettext("Medium is write protected.\n"));
}
} else { /* Open succeeded */
gettext("Medium is not write protected.\n"));
}
return;
}
switch (med_status) {
case SM_READ_WRITE_PROTECT :
gettext("Medium is read-write protected.\n"));
break;
case SM_WRITE_PROTECT_PASSWD :
gettext("Medium is write protected with password.\n"));
break;
case SM_WRITE_PROTECT_NOPASSWD :
gettext("Medium is write protected.\n"));
break;
case SM_WRITE_PROTECT_DISABLE :
gettext("Medium is not write protected.\n"));
break;
case SM_STATUS_UNKNOWN :
default:
gettext("Unknown write protect status.\n"));
break;
}
}
static void
{
return;
}
}
/*
* This routine handles the -V (verify) option.
* There can be devices without rw_read option. If the raw_read
* and raw_write are not supported by the interface, then read and
* write system calls are used. It is assumed that either both
* raw_read and raw_write are supported or both are unsupported.
*/
static void
{
uint32_t j;
DPRINTF("ANALYSE MEDIA \n");
if (ret == -1) {
DPRINTF("get_media_info failed\n");
return;
}
DPRINTF("Could not allocate memory\n");
return;
}
DPRINTF("Could not allocate memory\n");
return;
}
if (!verify_write) {
DPRINTF("Non-destructive verify \n");
bn += verify_size) {
(void) printf(".");
old_per++;
}
DPRINTF2("Reading %d blks starting at %llu\n",
verify_size, bn);
no_raw_rw = 1;
}
if (ret != 0) {
for (j = 0; j < verify_size; j++) {
return;
"Reading %d blks starting "
if (ret == -1) {
(void) printf(
"Bad block %llu\n",
bn + j);
}
}
}
}
} else {
DPRINTF("Destrutive verify \n");
bn += verify_size) {
(void) printf(".");
old_per++;
}
for (j = 0; j < blocksize * verify_size; j++) {
}
DPRINTF2("Writing %d blks starting at %llu\n",
verify_size, bn);
if (ret != 0) {
for (j = 0; j < verify_size; j++) {
break;
"Writing %d blks starting "
if (ret == -1) {
(void) printf(
"Bad block %llu\n", bn + j);
}
}
}
DPRINTF2("Read after write %d blks starting at %llu\n",
verify_size, bn);
if (ret != 0) {
for (j = 0; j < verify_size; j++) {
return;
"Read after write %d blks "
if (ret == -1) {
(void) printf(
"Bad block %llu\n", bn + j);
}
}
}
}
}
}
static void
{
(void) smedia_release_handle(handle);
exit(1);
}
/* Get existing Vtoc, don't bother if it fails. */
/* Turn on privileges. */
(void) __priv_bracket(PRIV_ON);
/* Turn off privileges. */
(void) __priv_bracket(PRIV_OFF);
for (i = 0; i < V_NUMPAR; i++) {
}
errno = 0;
/* Turn on privileges. */
(void) __priv_bracket(PRIV_ON);
/* Turn off privileges. */
(void) __priv_bracket(PRIV_OFF);
if (ret < 0) {
#ifdef sparc
PERROR("write VTOC failed");
#else /* i386 */
PERROR("No Solaris partition, eject & retry");
} else {
PERROR("write VTOC failed");
}
#endif
}
}
static void
{
if (smedia_eject(handle) < 0) {
PERROR("Eject failed");
}
}
static void
{
gettext("Formatting will erase all the data on disk.\n"));
if (!get_confirmation())
return;
< 0) {
PERROR("Format failed");
return;
}
}
(void) printf(".");
old_per++;
}
}
}
static void
{
gettext("Formatting will erase all the data on disk.\n"));
if (!get_confirmation())
return;
< 0) {
PERROR("Format failed");
return;
}
}
(void) printf(".");
old_per++;
}
}
}
/*
* This routine handles the -b (label) option.
* Please note that, this will fail if there is no valid vtoc is
* there on the medium and the vtoc is not faked.
*/
static void
{
/* For EFI disks. */
/*
* If reading the vtoc failed, try to
* auto-sense the disk configuration.
*/
gettext("Could not write label.\n"));
return;
}
}
nparts++) {
V_RESERVED) {
(void) strncpy(
}
break;
}
}
(void) efi_err_check(vtoc64);
gettext("Could not write label.\n"));
}
return;
}
/* Get existing Vtoc */
/* Turn on privileges. */
(void) __priv_bracket(PRIV_ON);
/* Turn off privileges */
(void) __priv_bracket(PRIV_OFF);
if (ret < 0) {
#ifdef sparc
PERROR("read VTOC failed");
#else /* i386 */
PERROR("No Solaris partition, eject & retry");
} else {
PERROR("read VTOC failed");
}
#endif
return;
}
/* Turn on the privileges. */
(void) __priv_bracket(PRIV_ON);
/* Turn off the privileges. */
(void) __priv_bracket(PRIV_OFF);
if (ret < 0) {
#ifdef sparc
PERROR("write VTOC failed");
#else /* i386 */
PERROR("No Solaris partition, eject & retry");
} else {
PERROR("write VTOC failed");
}
#endif
}
}