10Sstevel@tonic-gate /* 20Sstevel@tonic-gate * CDDL HEADER START 30Sstevel@tonic-gate * 40Sstevel@tonic-gate * The contents of this file are subject to the terms of the 52160Szk194757 * Common Development and Distribution License (the "License"). 62160Szk194757 * You may not use this file except in compliance with the License. 70Sstevel@tonic-gate * 80Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 90Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 100Sstevel@tonic-gate * See the License for the specific language governing permissions 110Sstevel@tonic-gate * and limitations under the License. 120Sstevel@tonic-gate * 130Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 140Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 150Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 160Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 170Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 180Sstevel@tonic-gate * 190Sstevel@tonic-gate * CDDL HEADER END 200Sstevel@tonic-gate */ 210Sstevel@tonic-gate /* 221375Sphitran * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 230Sstevel@tonic-gate * Use is subject to license terms. 240Sstevel@tonic-gate */ 250Sstevel@tonic-gate 260Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 270Sstevel@tonic-gate 280Sstevel@tonic-gate 290Sstevel@tonic-gate /* 300Sstevel@tonic-gate * rmf_misc.c : 310Sstevel@tonic-gate * Miscelleneous routines for rmformat. 320Sstevel@tonic-gate */ 330Sstevel@tonic-gate 340Sstevel@tonic-gate #include <sys/types.h> 350Sstevel@tonic-gate #include <stdio.h> 360Sstevel@tonic-gate #include <sys/mnttab.h> 370Sstevel@tonic-gate #include <volmgt.h> 380Sstevel@tonic-gate #include <sys/dkio.h> 390Sstevel@tonic-gate #include <sys/fdio.h> 400Sstevel@tonic-gate #include <sys/vtoc.h> 410Sstevel@tonic-gate #include <sys/termios.h> 420Sstevel@tonic-gate #include <sys/mount.h> 430Sstevel@tonic-gate #include <ctype.h> 440Sstevel@tonic-gate #include <signal.h> 450Sstevel@tonic-gate #include <sys/wait.h> 460Sstevel@tonic-gate #include <dirent.h> 47*2172Szk194757 #include <priv_utils.h> 480Sstevel@tonic-gate #include <stdarg.h> 490Sstevel@tonic-gate #include "rmformat.h" 500Sstevel@tonic-gate /* 510Sstevel@tonic-gate * These defines are from the PCMCIA memory driver driver 520Sstevel@tonic-gate * header files (pcramio.h/pcramvar.h) and they are in 530Sstevel@tonic-gate * the Platform Specific (PS) train. 540Sstevel@tonic-gate */ 550Sstevel@tonic-gate #ifndef PCRAM_PROBESIZE 560Sstevel@tonic-gate #define PCRAMIOC ('P' << 8) 570Sstevel@tonic-gate #define PCRAM_PROBESIZE (PCRAMIOC|22) /* Probe memory card size */ 580Sstevel@tonic-gate #endif 590Sstevel@tonic-gate 600Sstevel@tonic-gate /* 610Sstevel@tonic-gate * Definitions. 620Sstevel@tonic-gate */ 630Sstevel@tonic-gate #define SENSE_KEY(rqbuf) (rqbuf[2] & 0xf) /* scsi error category */ 640Sstevel@tonic-gate #define ASC(rqbuf) (rqbuf[12]) /* additional sense code */ 650Sstevel@tonic-gate #define ASCQ(rqbuf) (rqbuf[13]) /* ASC qualifier */ 660Sstevel@tonic-gate 670Sstevel@tonic-gate #define DEFAULT_SCSI_TIMEOUT 60 680Sstevel@tonic-gate #define INQUIRY_CMD 0x12 690Sstevel@tonic-gate #define RQBUFLEN 32 700Sstevel@tonic-gate #define CD_RW 1 /* CD_RW/CD-R */ 710Sstevel@tonic-gate #define WRITE_10_CMD 0x2A 720Sstevel@tonic-gate #define READ_INFO_CMD 0x51 730Sstevel@tonic-gate #define SYNC_CACHE_CMD 0x35 740Sstevel@tonic-gate #define CLOSE_TRACK_CMD 0x5B 750Sstevel@tonic-gate #define MODE_SENSE_10_CMD 0x5A 760Sstevel@tonic-gate #define DEVFS_PREFIX "/devices" 770Sstevel@tonic-gate 780Sstevel@tonic-gate int uscsi_error; /* used for debugging failed uscsi */ 790Sstevel@tonic-gate char rqbuf[RQBUFLEN]; 800Sstevel@tonic-gate static uint_t total_retries; 810Sstevel@tonic-gate static struct uscsi_cmd uscmd; 820Sstevel@tonic-gate static char ucdb[16]; 830Sstevel@tonic-gate uchar_t uscsi_status, rqstatus, rqresid; 840Sstevel@tonic-gate int total_devices_found = 0; 850Sstevel@tonic-gate int removable_found = 0; 860Sstevel@tonic-gate 870Sstevel@tonic-gate extern char *global_intr_msg; 880Sstevel@tonic-gate extern int vol_running; 890Sstevel@tonic-gate extern char *dev_name; 900Sstevel@tonic-gate extern int32_t m_flag; 910Sstevel@tonic-gate 920Sstevel@tonic-gate /* 930Sstevel@tonic-gate * ON-private functions from libvolmgt 940Sstevel@tonic-gate */ 950Sstevel@tonic-gate int _dev_mounted(char *path); 960Sstevel@tonic-gate 970Sstevel@tonic-gate /* 980Sstevel@tonic-gate * Function prototypes. 990Sstevel@tonic-gate */ 1000Sstevel@tonic-gate static int my_umount(char *mountp); 1010Sstevel@tonic-gate static int my_volrmmount(char *real_name); 1020Sstevel@tonic-gate static int vol_name_to_dev_node(char *vname, char *found); 1030Sstevel@tonic-gate static int vol_lookup(char *supplied, char *found); 1040Sstevel@tonic-gate static device_t *get_device(char *user_supplied, char *node); 1050Sstevel@tonic-gate static char *get_physical_name(char *path); 1060Sstevel@tonic-gate static int lookup_device(char *supplied, char *found); 1070Sstevel@tonic-gate static void fini_device(device_t *dev); 1080Sstevel@tonic-gate static int is_cd(char *node); 1090Sstevel@tonic-gate void *my_zalloc(size_t size); 1100Sstevel@tonic-gate void err_msg(char *fmt, ...); 1110Sstevel@tonic-gate int inquiry(int fd, uchar_t *inq); 1120Sstevel@tonic-gate struct uscsi_cmd *get_uscsi_cmd(void); 1130Sstevel@tonic-gate int uscsi(int fd, struct uscsi_cmd *scmd); 1140Sstevel@tonic-gate int get_mode_page(int fd, int page_no, int pc, int buf_len, 1150Sstevel@tonic-gate uchar_t *buffer); 1160Sstevel@tonic-gate int mode_sense(int fd, uchar_t pc, int dbd, int page_len, 1170Sstevel@tonic-gate uchar_t *buffer); 1180Sstevel@tonic-gate uint16_t read_scsi16(void *addr); 1190Sstevel@tonic-gate int check_device(device_t *dev, int cond); 1200Sstevel@tonic-gate static void get_media_info(device_t *t_dev, char *sdev, 1210Sstevel@tonic-gate char *pname, char *sn); 1220Sstevel@tonic-gate 1230Sstevel@tonic-gate extern void process_p_flag(smedia_handle_t handle, int32_t fd); 1240Sstevel@tonic-gate 1250Sstevel@tonic-gate void 1260Sstevel@tonic-gate my_perror(char *err_string) 1270Sstevel@tonic-gate { 1280Sstevel@tonic-gate 1290Sstevel@tonic-gate int error_no; 1300Sstevel@tonic-gate if (errno == 0) 1310Sstevel@tonic-gate return; 1320Sstevel@tonic-gate 1330Sstevel@tonic-gate error_no = errno; 1340Sstevel@tonic-gate (void) fprintf(stderr, "%s", err_string); 1350Sstevel@tonic-gate (void) fprintf(stderr, gettext(" : ")); 1360Sstevel@tonic-gate errno = error_no; 1370Sstevel@tonic-gate perror(""); 1380Sstevel@tonic-gate } 1390Sstevel@tonic-gate 1400Sstevel@tonic-gate int32_t 1410Sstevel@tonic-gate get_confirmation() 1420Sstevel@tonic-gate { 1430Sstevel@tonic-gate char c; 1440Sstevel@tonic-gate 1450Sstevel@tonic-gate (void) fprintf(stderr, gettext("Do you want to continue? (y/n)")); 1460Sstevel@tonic-gate c = getchar(); 1470Sstevel@tonic-gate if (c == 'y' || c == 'Y') 1480Sstevel@tonic-gate return (1); 1490Sstevel@tonic-gate else if (c == 'n' || c == 'N') 1500Sstevel@tonic-gate return (0); 1510Sstevel@tonic-gate else { 1520Sstevel@tonic-gate (void) fprintf(stderr, gettext("Invalid choice\n")); 1530Sstevel@tonic-gate return (0); 1540Sstevel@tonic-gate } 1550Sstevel@tonic-gate } 1560Sstevel@tonic-gate 1570Sstevel@tonic-gate 1580Sstevel@tonic-gate void 1590Sstevel@tonic-gate get_passwd(struct smwp_state *wp, int32_t confirm) 1600Sstevel@tonic-gate { 1610Sstevel@tonic-gate char passwd[256], re_passwd[256]; 1620Sstevel@tonic-gate int32_t len; 1630Sstevel@tonic-gate struct termios tio; 1640Sstevel@tonic-gate int32_t echo_off = 0; 1650Sstevel@tonic-gate FILE *in, *out; 1660Sstevel@tonic-gate char *buf; 1670Sstevel@tonic-gate 1680Sstevel@tonic-gate 1690Sstevel@tonic-gate in = fopen("/dev/tty", "r+"); 1700Sstevel@tonic-gate if (in == NULL) { 1710Sstevel@tonic-gate in = stdin; 1720Sstevel@tonic-gate out = stderr; 1730Sstevel@tonic-gate } else { 1740Sstevel@tonic-gate out = in; 1750Sstevel@tonic-gate } 1760Sstevel@tonic-gate 1770Sstevel@tonic-gate /* Turn echoing off if it is on now. */ 1780Sstevel@tonic-gate 1790Sstevel@tonic-gate if (tcgetattr(fileno(in), &tio) < 0) { 1800Sstevel@tonic-gate PERROR("Echo off ioctl failed"); 1810Sstevel@tonic-gate exit(1); 1820Sstevel@tonic-gate } 1830Sstevel@tonic-gate if (tio.c_lflag & ECHO) { 1840Sstevel@tonic-gate tio.c_lflag &= ~ECHO; 1850Sstevel@tonic-gate /* echo_off = tcsetattr(fileno(in), TCSAFLUSH, &tio) == 0; */ 1860Sstevel@tonic-gate echo_off = tcsetattr(fileno(in), TCSAFLUSH, &tio) == 0; 1870Sstevel@tonic-gate tio.c_lflag |= ECHO; 1880Sstevel@tonic-gate } 1890Sstevel@tonic-gate 1900Sstevel@tonic-gate /* CONSTCOND */ 1910Sstevel@tonic-gate while (1) { 1920Sstevel@tonic-gate (void) fputs( 1930Sstevel@tonic-gate gettext("Please enter password (32 chars maximum):"), 1940Sstevel@tonic-gate out); 1950Sstevel@tonic-gate (void) fflush(out); 1960Sstevel@tonic-gate buf = fgets(passwd, (size_t)256, in); 1970Sstevel@tonic-gate rewind(in); 1980Sstevel@tonic-gate if (buf == NULL) { 1990Sstevel@tonic-gate PERROR("Error reading password"); 2000Sstevel@tonic-gate continue; 2010Sstevel@tonic-gate } 2020Sstevel@tonic-gate len = strlen(passwd); 2030Sstevel@tonic-gate (void) fputc('\n', out); 2040Sstevel@tonic-gate len--; /* To offset the \n */ 2050Sstevel@tonic-gate if ((len <= 0) || (len > 32)) { 2060Sstevel@tonic-gate (void) fprintf(stderr, 2070Sstevel@tonic-gate gettext("Invalid length of password \n")); 2080Sstevel@tonic-gate (void) fputs("Try again\n", out); 2090Sstevel@tonic-gate continue; 2100Sstevel@tonic-gate } 2110Sstevel@tonic-gate 2120Sstevel@tonic-gate if (!confirm) 2130Sstevel@tonic-gate break; 2140Sstevel@tonic-gate 2150Sstevel@tonic-gate (void) fputs("Please reenter password:", out); 2160Sstevel@tonic-gate (void) fflush(out); 2170Sstevel@tonic-gate buf = fgets(re_passwd, (size_t)256, in); 2180Sstevel@tonic-gate rewind(in); 2190Sstevel@tonic-gate (void) fputc('\n', out); 2200Sstevel@tonic-gate if ((buf == NULL) || strcmp(passwd, re_passwd)) { 2210Sstevel@tonic-gate (void) fputs("passwords did not match\n", out); 2220Sstevel@tonic-gate (void) fputs("Try again\n", out); 2230Sstevel@tonic-gate } else { 2240Sstevel@tonic-gate break; 2250Sstevel@tonic-gate } 2260Sstevel@tonic-gate } 2270Sstevel@tonic-gate wp->sm_passwd_len = len; 2280Sstevel@tonic-gate (void) strncpy(wp->sm_passwd, passwd, wp->sm_passwd_len); 2290Sstevel@tonic-gate wp->sm_version = SMWP_STATE_V_1; 2300Sstevel@tonic-gate 2310Sstevel@tonic-gate /* Restore echoing. */ 2320Sstevel@tonic-gate if (echo_off) 2330Sstevel@tonic-gate (void) tcsetattr(fileno(in), TCSAFLUSH, &tio); 2340Sstevel@tonic-gate 2350Sstevel@tonic-gate } 2360Sstevel@tonic-gate 2370Sstevel@tonic-gate int32_t 2380Sstevel@tonic-gate check_and_unmount_vold(char *device_name, int32_t flag) 2390Sstevel@tonic-gate { 2400Sstevel@tonic-gate char *real_name; 2410Sstevel@tonic-gate char *nm; 2420Sstevel@tonic-gate char tmp_path_name[PATH_MAX]; 2430Sstevel@tonic-gate struct stat stat_buf; 2440Sstevel@tonic-gate int32_t ret_val = 0; 2450Sstevel@tonic-gate struct mnttab *mntp; 2460Sstevel@tonic-gate FILE *fp; 2470Sstevel@tonic-gate int nl; 2480Sstevel@tonic-gate 2490Sstevel@tonic-gate DPRINTF1("Device name %s\n", device_name); 2500Sstevel@tonic-gate 2510Sstevel@tonic-gate if (volmgt_running() == 0) { 2520Sstevel@tonic-gate DPRINTF("Vold not running\n"); 2530Sstevel@tonic-gate return (0); 2540Sstevel@tonic-gate } 2550Sstevel@tonic-gate if ((nm = volmgt_symname(device_name)) == NULL) { 2560Sstevel@tonic-gate DPRINTF("path not managed\n"); 2570Sstevel@tonic-gate real_name = media_findname(device_name); 2580Sstevel@tonic-gate } else { 2590Sstevel@tonic-gate DPRINTF1("path managed as %s\n", nm); 2600Sstevel@tonic-gate real_name = media_findname(nm); 2610Sstevel@tonic-gate DPRINTF1("real name %s\n", real_name); 2620Sstevel@tonic-gate } 2630Sstevel@tonic-gate 2640Sstevel@tonic-gate if (real_name == NULL) 2650Sstevel@tonic-gate return (-1); 2660Sstevel@tonic-gate 2670Sstevel@tonic-gate /* 2680Sstevel@tonic-gate * To find out whether the device has been mounted by 2690Sstevel@tonic-gate * volume manager... 2700Sstevel@tonic-gate * 2710Sstevel@tonic-gate * Convert the real name to a block device address. 2720Sstevel@tonic-gate * Do a partial match with the mnttab entries. 2730Sstevel@tonic-gate * Make sure the match is in the beginning to avoid if 2740Sstevel@tonic-gate * anybody puts a label similiar to volume manager path names. 2750Sstevel@tonic-gate * Then use "volrmmount -e <dev_name>" if -U flag is set. 2760Sstevel@tonic-gate */ 2770Sstevel@tonic-gate 2780Sstevel@tonic-gate nl = strlen("/vol/dev/"); 2790Sstevel@tonic-gate 2800Sstevel@tonic-gate if (strncmp(real_name, "/vol/dev/", nl) != 0) 2810Sstevel@tonic-gate return (0); 2820Sstevel@tonic-gate if (real_name[nl] == 'r') { 2830Sstevel@tonic-gate (void) snprintf(tmp_path_name, PATH_MAX, "%s%s", "/vol/dev/", 2840Sstevel@tonic-gate &real_name[nl + 1]); 2850Sstevel@tonic-gate } else { 2860Sstevel@tonic-gate (void) snprintf(tmp_path_name, PATH_MAX, "%s", real_name); 2870Sstevel@tonic-gate } 2880Sstevel@tonic-gate DPRINTF1("%s \n", tmp_path_name); 2890Sstevel@tonic-gate ret_val = stat(tmp_path_name, &stat_buf); 2900Sstevel@tonic-gate if (ret_val < 0) { 2910Sstevel@tonic-gate PERROR("Could not stat"); 2920Sstevel@tonic-gate return (-1); 2930Sstevel@tonic-gate } 2940Sstevel@tonic-gate 2950Sstevel@tonic-gate fp = fopen("/etc/mnttab", "r"); 2960Sstevel@tonic-gate 2970Sstevel@tonic-gate if (fp == NULL) { 2980Sstevel@tonic-gate PERROR("Could not open /etc/mnttab"); 2990Sstevel@tonic-gate return (-1); 3000Sstevel@tonic-gate } 3010Sstevel@tonic-gate 3020Sstevel@tonic-gate mntp = (struct mnttab *)malloc(sizeof (struct mnttab)); 3030Sstevel@tonic-gate if (mntp == NULL) { 3040Sstevel@tonic-gate PERROR("malloc failed"); 3050Sstevel@tonic-gate (void) fclose(fp); 3060Sstevel@tonic-gate return (-1); 3070Sstevel@tonic-gate } 3080Sstevel@tonic-gate errno = 0; 3090Sstevel@tonic-gate while (getmntent(fp, mntp) == 0) { 3100Sstevel@tonic-gate if (errno != 0) { 3110Sstevel@tonic-gate PERROR("Error with mnttab"); 3120Sstevel@tonic-gate (void) fclose(fp); 3130Sstevel@tonic-gate return (-1); 3140Sstevel@tonic-gate } 3150Sstevel@tonic-gate /* Is it a probable entry? */ 3160Sstevel@tonic-gate DPRINTF1(" %s \n", mntp->mnt_special); 3170Sstevel@tonic-gate if (strstr(mntp->mnt_special, tmp_path_name) != 3180Sstevel@tonic-gate mntp->mnt_special) { 3190Sstevel@tonic-gate /* Skip to next entry */ 3200Sstevel@tonic-gate continue; 3210Sstevel@tonic-gate } else { 3220Sstevel@tonic-gate DPRINTF1("Found!! %s\n", mntp->mnt_special); 3230Sstevel@tonic-gate ret_val = 1; 3240Sstevel@tonic-gate break; 3250Sstevel@tonic-gate } 3260Sstevel@tonic-gate } 3270Sstevel@tonic-gate 3280Sstevel@tonic-gate if (ret_val == 1) { 3290Sstevel@tonic-gate if (flag) { 3300Sstevel@tonic-gate if (my_volrmmount(real_name) < 0) { 3310Sstevel@tonic-gate ret_val = -1; 3320Sstevel@tonic-gate } 3330Sstevel@tonic-gate } else { 3340Sstevel@tonic-gate ret_val = -1; 3350Sstevel@tonic-gate } 3360Sstevel@tonic-gate } 3370Sstevel@tonic-gate (void) fclose(fp); 3380Sstevel@tonic-gate free(mntp); 3390Sstevel@tonic-gate return (ret_val); 3400Sstevel@tonic-gate } 3410Sstevel@tonic-gate 3420Sstevel@tonic-gate /* 3430Sstevel@tonic-gate * This routine checks if a device has mounted partitions. The 3440Sstevel@tonic-gate * device name is assumed to be /dev/rdsk/cNtNdNsN. So, this can 3450Sstevel@tonic-gate * be used for SCSI and PCMCIA cards. 3460Sstevel@tonic-gate * Returns 3470Sstevel@tonic-gate * 0 : if not mounted 3480Sstevel@tonic-gate * 1 : if successfully unmounted 3490Sstevel@tonic-gate * -1 : Any error or umount failed 3500Sstevel@tonic-gate */ 3510Sstevel@tonic-gate 3520Sstevel@tonic-gate int32_t 3530Sstevel@tonic-gate check_and_unmount_scsi(char *device_name, int32_t flag) 3540Sstevel@tonic-gate { 3550Sstevel@tonic-gate 3560Sstevel@tonic-gate struct mnttab *mntrefp; 3570Sstevel@tonic-gate struct mnttab *mntp; 3580Sstevel@tonic-gate FILE *fp; 3590Sstevel@tonic-gate char block_dev_name[PATH_MAX]; 3600Sstevel@tonic-gate char tmp_name[PATH_MAX]; 3610Sstevel@tonic-gate int32_t i, j; 3620Sstevel@tonic-gate int32_t unmounted = 0; 3630Sstevel@tonic-gate 3640Sstevel@tonic-gate /* 3650Sstevel@tonic-gate * If the device name is not a character special, anyway we 3660Sstevel@tonic-gate * can not progress further 3670Sstevel@tonic-gate */ 3680Sstevel@tonic-gate 3690Sstevel@tonic-gate if (strncmp(device_name, "/dev/rdsk/c", strlen("/dev/rdsk/c")) != 0) 3700Sstevel@tonic-gate return (0); 3710Sstevel@tonic-gate 3720Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, "/dev/%s", 3730Sstevel@tonic-gate &device_name[strlen("/dev/r")]); 3740Sstevel@tonic-gate fp = fopen("/etc/mnttab", "r"); 3750Sstevel@tonic-gate 3760Sstevel@tonic-gate if (fp == NULL) { 3770Sstevel@tonic-gate PERROR("Could not open /etc/mnttab"); 3780Sstevel@tonic-gate return (-1); 3790Sstevel@tonic-gate } 3800Sstevel@tonic-gate 3810Sstevel@tonic-gate mntrefp = (struct mnttab *)malloc(sizeof (struct mnttab)); 3820Sstevel@tonic-gate if (mntrefp == NULL) { 3830Sstevel@tonic-gate PERROR("malloc failed"); 3840Sstevel@tonic-gate (void) fclose(fp); 3850Sstevel@tonic-gate return (-1); 3860Sstevel@tonic-gate } 3870Sstevel@tonic-gate 3880Sstevel@tonic-gate mntp = (struct mnttab *)malloc(sizeof (struct mnttab)); 3890Sstevel@tonic-gate if (mntp == NULL) { 3900Sstevel@tonic-gate PERROR("malloc failed"); 3910Sstevel@tonic-gate (void) fclose(fp); 3920Sstevel@tonic-gate free(mntrefp); 3930Sstevel@tonic-gate return (-1); 3940Sstevel@tonic-gate } 3950Sstevel@tonic-gate 3960Sstevel@tonic-gate /* Try all the partitions */ 3970Sstevel@tonic-gate 3980Sstevel@tonic-gate (void) snprintf(tmp_name, PATH_MAX, "/dev/%s", 3990Sstevel@tonic-gate &device_name[strlen("/dev/r")]); 4000Sstevel@tonic-gate 4010Sstevel@tonic-gate tmp_name[strlen("/dev/dsk/c0t0d0s")] = '\0'; 4020Sstevel@tonic-gate 4030Sstevel@tonic-gate errno = 0; 4040Sstevel@tonic-gate while (getmntent(fp, mntp) == 0) { 4050Sstevel@tonic-gate if (errno != 0) { 4060Sstevel@tonic-gate PERROR("Error with mnttab"); 4070Sstevel@tonic-gate (void) fclose(fp); 4080Sstevel@tonic-gate return (-1); 4090Sstevel@tonic-gate } 4100Sstevel@tonic-gate /* Is it a probable entry? */ 4110Sstevel@tonic-gate if (strncmp(mntp->mnt_special, tmp_name, strlen(tmp_name))) { 4120Sstevel@tonic-gate /* Skip to next entry */ 4130Sstevel@tonic-gate continue; 4140Sstevel@tonic-gate } 4150Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 4160Sstevel@tonic-gate /* Check for ufs style mount devices */ 4170Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, 4180Sstevel@tonic-gate "%s%d", tmp_name, i); 4190Sstevel@tonic-gate 4200Sstevel@tonic-gate if (strcmp(mntp->mnt_special, block_dev_name) == 0) { 4210Sstevel@tonic-gate if (flag) { 4220Sstevel@tonic-gate if (my_umount(mntp->mnt_mountp) < 0) { 4230Sstevel@tonic-gate (void) fclose(fp); 4240Sstevel@tonic-gate return (-1); 4250Sstevel@tonic-gate } 4260Sstevel@tonic-gate unmounted = 1; 4270Sstevel@tonic-gate } else { 4280Sstevel@tonic-gate (void) fclose(fp); 4290Sstevel@tonic-gate return (-1); 4300Sstevel@tonic-gate } 4310Sstevel@tonic-gate /* Skip to next entry */ 4320Sstevel@tonic-gate continue; 4330Sstevel@tonic-gate } 4340Sstevel@tonic-gate 4350Sstevel@tonic-gate /* Try for :1 -> :24 for pcfs */ 4360Sstevel@tonic-gate 4370Sstevel@tonic-gate for (j = 1; j < 24; j++) { 4380Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, 4390Sstevel@tonic-gate "%s%d:%d", tmp_name, i, j); 4400Sstevel@tonic-gate 4410Sstevel@tonic-gate if (strcmp(mntp->mnt_special, 4420Sstevel@tonic-gate block_dev_name) == 0) { 4430Sstevel@tonic-gate if (flag) { 4440Sstevel@tonic-gate if (my_umount(mntp->mnt_mountp) 4450Sstevel@tonic-gate < 0) { 4460Sstevel@tonic-gate (void) fclose(fp); 4470Sstevel@tonic-gate return (-1); 4480Sstevel@tonic-gate } 4490Sstevel@tonic-gate unmounted = 1; 4500Sstevel@tonic-gate } else { 4510Sstevel@tonic-gate (void) fclose(fp); 4520Sstevel@tonic-gate return (-1); 4530Sstevel@tonic-gate } 4540Sstevel@tonic-gate /* Skip to next entry */ 4550Sstevel@tonic-gate continue; 4560Sstevel@tonic-gate } 4570Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, 4580Sstevel@tonic-gate "%s%d:%c", tmp_name, i, 'b' + j); 4590Sstevel@tonic-gate 4600Sstevel@tonic-gate if (strcmp(mntp->mnt_special, 4610Sstevel@tonic-gate block_dev_name) == 0) { 4620Sstevel@tonic-gate if (flag) { 4630Sstevel@tonic-gate if (my_umount(mntp->mnt_mountp) 4640Sstevel@tonic-gate < 0) { 4650Sstevel@tonic-gate (void) fclose(fp); 4660Sstevel@tonic-gate return (-1); 4670Sstevel@tonic-gate } 4680Sstevel@tonic-gate unmounted = 1; 4690Sstevel@tonic-gate } else { 4700Sstevel@tonic-gate (void) fclose(fp); 4710Sstevel@tonic-gate return (-1); 4720Sstevel@tonic-gate } 4730Sstevel@tonic-gate /* Skip to next entry */ 4740Sstevel@tonic-gate continue; 4750Sstevel@tonic-gate } 4760Sstevel@tonic-gate } 4770Sstevel@tonic-gate } 4780Sstevel@tonic-gate 4790Sstevel@tonic-gate } 4800Sstevel@tonic-gate 4810Sstevel@tonic-gate if (unmounted) 4820Sstevel@tonic-gate return (1); 4830Sstevel@tonic-gate return (0); 4840Sstevel@tonic-gate } 4850Sstevel@tonic-gate 4860Sstevel@tonic-gate /* 4870Sstevel@tonic-gate * This routine checks if a device has mounted partitions. The 4880Sstevel@tonic-gate * device name is assumed to be /dev/rdiskette. So, this can 4890Sstevel@tonic-gate * be used for Floppy controllers 4900Sstevel@tonic-gate * Returns 4910Sstevel@tonic-gate * 0 : if not mounted 4920Sstevel@tonic-gate * 1 : if successfully unmounted 4930Sstevel@tonic-gate * -1 : Any error or unmount failed 4940Sstevel@tonic-gate */ 4950Sstevel@tonic-gate 4960Sstevel@tonic-gate int32_t 4970Sstevel@tonic-gate check_and_unmount_floppy(int32_t fd, int32_t flag) 4980Sstevel@tonic-gate { 4990Sstevel@tonic-gate FILE *fp = NULL; 5000Sstevel@tonic-gate int32_t mfd; 5010Sstevel@tonic-gate struct dk_cinfo dkinfo, dkinfo_tmp; 5020Sstevel@tonic-gate struct mnttab mnt_record; 5030Sstevel@tonic-gate struct mnttab *mp = &mnt_record; 5040Sstevel@tonic-gate struct stat stbuf; 5050Sstevel@tonic-gate char raw_device[PATH_MAX]; 5060Sstevel@tonic-gate int32_t found = 0; 5070Sstevel@tonic-gate 5080Sstevel@tonic-gate 5090Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) { 5100Sstevel@tonic-gate return (-1); 5110Sstevel@tonic-gate } 5120Sstevel@tonic-gate 5130Sstevel@tonic-gate if ((fp = fopen(MNTTAB, "r")) == NULL) { 5140Sstevel@tonic-gate PERROR("Could not open /etc/mnttab"); 5150Sstevel@tonic-gate (void) close(fd); 5160Sstevel@tonic-gate exit(3); 5170Sstevel@tonic-gate } 5180Sstevel@tonic-gate 5190Sstevel@tonic-gate while (getmntent(fp, mp) == 0) { 5200Sstevel@tonic-gate if (strstr(mp->mnt_special, "/dev/fd") == NULL && 5210Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/disket") == NULL && 5220Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/c") == NULL) { 5230Sstevel@tonic-gate continue; 5240Sstevel@tonic-gate } 5250Sstevel@tonic-gate 5260Sstevel@tonic-gate (void) strcpy(raw_device, "/dev/r"); 5270Sstevel@tonic-gate (void) strcat(raw_device, mp->mnt_special + strlen("/dev/")); 5280Sstevel@tonic-gate 5290Sstevel@tonic-gate 5300Sstevel@tonic-gate /* 5310Sstevel@tonic-gate * Attempt to open the device. If it fails, skip it. 5320Sstevel@tonic-gate */ 5330Sstevel@tonic-gate 5342160Szk194757 /* Turn on the privileges. */ 5352160Szk194757 (void) __priv_bracket(PRIV_ON); 5360Sstevel@tonic-gate 5370Sstevel@tonic-gate mfd = open(raw_device, O_RDWR | O_NDELAY); 5380Sstevel@tonic-gate 5392160Szk194757 /* Turn off the privileges. */ 5402160Szk194757 (void) __priv_bracket(PRIV_OFF); 5410Sstevel@tonic-gate 5420Sstevel@tonic-gate if (mfd < 0) { 5430Sstevel@tonic-gate continue; 5440Sstevel@tonic-gate } 5450Sstevel@tonic-gate 5460Sstevel@tonic-gate /* 5470Sstevel@tonic-gate * Must be a character device 5480Sstevel@tonic-gate */ 5490Sstevel@tonic-gate if (fstat(mfd, &stbuf) < 0 || !S_ISCHR(stbuf.st_mode)) { 5500Sstevel@tonic-gate (void) close(mfd); 5510Sstevel@tonic-gate continue; 5520Sstevel@tonic-gate } 5530Sstevel@tonic-gate /* 5540Sstevel@tonic-gate * Attempt to read the configuration info on the disk. 5550Sstevel@tonic-gate */ 5560Sstevel@tonic-gate if (ioctl(mfd, DKIOCINFO, &dkinfo_tmp) < 0) { 5570Sstevel@tonic-gate (void) close(mfd); 5580Sstevel@tonic-gate continue; 5590Sstevel@tonic-gate } 5600Sstevel@tonic-gate /* 5610Sstevel@tonic-gate * Finished with the opened device 5620Sstevel@tonic-gate */ 5630Sstevel@tonic-gate (void) close(mfd); 5640Sstevel@tonic-gate 5650Sstevel@tonic-gate /* 5660Sstevel@tonic-gate * If it's not the disk we're interested in, it doesn't apply. 5670Sstevel@tonic-gate */ 5680Sstevel@tonic-gate if (dkinfo.dki_ctype != dkinfo_tmp.dki_ctype || 5690Sstevel@tonic-gate dkinfo.dki_cnum != dkinfo_tmp.dki_cnum || 5700Sstevel@tonic-gate dkinfo.dki_unit != dkinfo_tmp.dki_unit) { 5710Sstevel@tonic-gate continue; 5720Sstevel@tonic-gate } 5730Sstevel@tonic-gate /* 5740Sstevel@tonic-gate * It's a mount on the disk we're checking. If we are 5750Sstevel@tonic-gate * checking whole disk, then we found trouble. We can 5760Sstevel@tonic-gate * quit searching. 5770Sstevel@tonic-gate */ 5780Sstevel@tonic-gate 5790Sstevel@tonic-gate if (flag) { 5800Sstevel@tonic-gate if (my_umount(mp->mnt_mountp) < 0) { 5810Sstevel@tonic-gate return (-1); 5820Sstevel@tonic-gate } 5830Sstevel@tonic-gate found = 1; 5840Sstevel@tonic-gate } else { 5850Sstevel@tonic-gate return (-1); 5860Sstevel@tonic-gate } 5870Sstevel@tonic-gate } 5880Sstevel@tonic-gate return (found); 5890Sstevel@tonic-gate } 5900Sstevel@tonic-gate 5910Sstevel@tonic-gate 5920Sstevel@tonic-gate int32_t 5930Sstevel@tonic-gate my_open(char *device_name, int32_t flags) 5940Sstevel@tonic-gate { 5950Sstevel@tonic-gate char *real_name; 5960Sstevel@tonic-gate char *nm; 5970Sstevel@tonic-gate char tmp_path_name[PATH_MAX]; 5980Sstevel@tonic-gate struct stat stat_buf; 5990Sstevel@tonic-gate int32_t ret_val; 6000Sstevel@tonic-gate int32_t fd; 6010Sstevel@tonic-gate int32_t have_read_priv = 0; 6020Sstevel@tonic-gate DIR *dirp; 6030Sstevel@tonic-gate struct dirent *dp; 6040Sstevel@tonic-gate 6050Sstevel@tonic-gate DPRINTF1("Device name %s\n", device_name); 6060Sstevel@tonic-gate 6070Sstevel@tonic-gate if ((nm = volmgt_symname(device_name)) == NULL) { 6080Sstevel@tonic-gate DPRINTF("path not managed\n"); 6090Sstevel@tonic-gate real_name = media_findname(device_name); 6100Sstevel@tonic-gate } else { 6110Sstevel@tonic-gate DPRINTF1("path managed as %s\n", nm); 6120Sstevel@tonic-gate real_name = media_findname(nm); 6130Sstevel@tonic-gate DPRINTF1("real name %s\n", real_name); 6140Sstevel@tonic-gate } 6150Sstevel@tonic-gate 6160Sstevel@tonic-gate if (real_name == NULL) 6170Sstevel@tonic-gate return (-1); 6180Sstevel@tonic-gate 6190Sstevel@tonic-gate (void) strcpy(tmp_path_name, real_name); 6200Sstevel@tonic-gate ret_val = stat(tmp_path_name, &stat_buf); 6210Sstevel@tonic-gate if (ret_val < 0) { 6220Sstevel@tonic-gate PERROR("Could not stat"); 6230Sstevel@tonic-gate return (-1); 6240Sstevel@tonic-gate } 625871Scasper if (S_ISDIR(stat_buf.st_mode)) { 6260Sstevel@tonic-gate 6270Sstevel@tonic-gate /* 6280Sstevel@tonic-gate * Open the directory and look for the 6290Sstevel@tonic-gate * first non '.' entry. 6300Sstevel@tonic-gate * Since raw_read and raw_writes are used, we don't 6310Sstevel@tonic-gate * need to access the backup slice. 6320Sstevel@tonic-gate * For PCMCIA Memory cards, raw_read and raw_writes are 6330Sstevel@tonic-gate * not supported, but that is not a problem as, only slice2 6340Sstevel@tonic-gate * is allowed on PCMCIA memory cards. 6350Sstevel@tonic-gate */ 6360Sstevel@tonic-gate 6370Sstevel@tonic-gate /* 6380Sstevel@tonic-gate * First make sure we are operating with a /vol/.... 6390Sstevel@tonic-gate * Otherwise it can dangerous, 6400Sstevel@tonic-gate * e.g. rmformat -s /dev/rdsk 6410Sstevel@tonic-gate * We should not look into the directory contents here. 6420Sstevel@tonic-gate */ 6430Sstevel@tonic-gate if (strncmp(tmp_path_name, "/vol/dev/", strlen("/vol/dev/")) 6440Sstevel@tonic-gate != 0) { 6450Sstevel@tonic-gate (void) fprintf(stderr, gettext("The specified device \ 6460Sstevel@tonic-gate is not a raw device.\n")); 6470Sstevel@tonic-gate exit(1); 6480Sstevel@tonic-gate } 6490Sstevel@tonic-gate 6502160Szk194757 /* Turn on the privileges. */ 6512160Szk194757 (void) __priv_bracket(PRIV_ON); 6520Sstevel@tonic-gate 6530Sstevel@tonic-gate dirp = opendir(tmp_path_name); 6540Sstevel@tonic-gate 6552160Szk194757 /* Turn off the privileges. */ 6562160Szk194757 (void) __priv_bracket(PRIV_OFF); 6570Sstevel@tonic-gate 6580Sstevel@tonic-gate if (dirp == NULL) { 6590Sstevel@tonic-gate return (-1); 6600Sstevel@tonic-gate } 6610Sstevel@tonic-gate 6622160Szk194757 /* Turn on the privileges. */ 6632160Szk194757 (void) __priv_bracket(PRIV_ON); 6640Sstevel@tonic-gate have_read_priv = 1; 6650Sstevel@tonic-gate 6660Sstevel@tonic-gate while ((dp = readdir(dirp)) != NULL) { 6670Sstevel@tonic-gate 6682160Szk194757 /* Turn off the privileges. */ 6692160Szk194757 (void) __priv_bracket(PRIV_OFF); 6700Sstevel@tonic-gate have_read_priv = 0; 6710Sstevel@tonic-gate 6720Sstevel@tonic-gate DPRINTF1("Found %s\n", dp->d_name); 6730Sstevel@tonic-gate if ((strcmp(dp->d_name, ".") != 0) && 6740Sstevel@tonic-gate (strcmp(dp->d_name, "..") != 0)) { 6750Sstevel@tonic-gate (void) snprintf(tmp_path_name, PATH_MAX, 6760Sstevel@tonic-gate "%s/%s", tmp_path_name, dp->d_name); 6770Sstevel@tonic-gate 6780Sstevel@tonic-gate DPRINTF1("tmp_pathname is %s\n", tmp_path_name); 6790Sstevel@tonic-gate break; 6800Sstevel@tonic-gate } 6810Sstevel@tonic-gate 6822160Szk194757 /* Turn on the privileges. */ 6832160Szk194757 (void) __priv_bracket(PRIV_ON); 6840Sstevel@tonic-gate have_read_priv = 1; 6850Sstevel@tonic-gate } 6860Sstevel@tonic-gate 6870Sstevel@tonic-gate if (have_read_priv) { 6880Sstevel@tonic-gate /* drop the file_dac_read privilege */ 6892160Szk194757 (void) __priv_bracket(PRIV_OFF); 6900Sstevel@tonic-gate have_read_priv = 0; 6910Sstevel@tonic-gate } 6920Sstevel@tonic-gate 6930Sstevel@tonic-gate (void) closedir(dirp); 6940Sstevel@tonic-gate } 6950Sstevel@tonic-gate 6960Sstevel@tonic-gate 6970Sstevel@tonic-gate if (volmgt_running() == 0) { 6982160Szk194757 /* Turn on privileges. */ 6992160Szk194757 (void) __priv_bracket(PRIV_ON); 7000Sstevel@tonic-gate have_read_priv = 1; 7010Sstevel@tonic-gate } 7020Sstevel@tonic-gate 7030Sstevel@tonic-gate fd = open(tmp_path_name, flags); 7040Sstevel@tonic-gate 7050Sstevel@tonic-gate if (have_read_priv) { 7062160Szk194757 /* Turn off privileges. */ 7072160Szk194757 (void) __priv_bracket(PRIV_OFF); 7080Sstevel@tonic-gate have_read_priv = 0; 7090Sstevel@tonic-gate } 7100Sstevel@tonic-gate 7110Sstevel@tonic-gate DPRINTF1("path opened %s\n", tmp_path_name); 7120Sstevel@tonic-gate 7130Sstevel@tonic-gate return (fd); 7140Sstevel@tonic-gate } 7150Sstevel@tonic-gate 7160Sstevel@tonic-gate int64_t 7170Sstevel@tonic-gate my_atoll(char *ptr) 7180Sstevel@tonic-gate { 7190Sstevel@tonic-gate char *tmp_ptr = ptr; 7200Sstevel@tonic-gate int32_t base = 10; 7210Sstevel@tonic-gate int64_t ret_val; 7220Sstevel@tonic-gate 7230Sstevel@tonic-gate while (*tmp_ptr) { 7240Sstevel@tonic-gate if (isdigit(*tmp_ptr)) 7250Sstevel@tonic-gate tmp_ptr++; 7260Sstevel@tonic-gate else { 7270Sstevel@tonic-gate base = 16; 7280Sstevel@tonic-gate break; 7290Sstevel@tonic-gate } 7300Sstevel@tonic-gate } 7310Sstevel@tonic-gate tmp_ptr = ptr; 7320Sstevel@tonic-gate if (base == 16) { 7330Sstevel@tonic-gate if (strlen(tmp_ptr) < 3) { 7340Sstevel@tonic-gate return (-1); 7350Sstevel@tonic-gate } 7360Sstevel@tonic-gate if (*tmp_ptr++ != '0' || (*tmp_ptr != 'x' && *tmp_ptr != 'X')) { 7370Sstevel@tonic-gate return (-1); 7380Sstevel@tonic-gate } 7390Sstevel@tonic-gate tmp_ptr++; 7400Sstevel@tonic-gate while (*tmp_ptr) { 7410Sstevel@tonic-gate if (isxdigit(*tmp_ptr)) 7420Sstevel@tonic-gate tmp_ptr++; 7430Sstevel@tonic-gate else { 7440Sstevel@tonic-gate return (-1); 7450Sstevel@tonic-gate } 7460Sstevel@tonic-gate } 7470Sstevel@tonic-gate } 7480Sstevel@tonic-gate ret_val = strtoll(ptr, (char **)NULL, 0); 7490Sstevel@tonic-gate return (ret_val); 7500Sstevel@tonic-gate } 7510Sstevel@tonic-gate 7520Sstevel@tonic-gate int32_t 7530Sstevel@tonic-gate write_sunos_label(int32_t fd, int32_t media_type) 7540Sstevel@tonic-gate { 7550Sstevel@tonic-gate 7560Sstevel@tonic-gate struct vtoc v_toc; 7570Sstevel@tonic-gate int32_t ret; 7580Sstevel@tonic-gate 7590Sstevel@tonic-gate (void) memset(&v_toc, 0, sizeof (struct vtoc)); 7600Sstevel@tonic-gate 7610Sstevel@tonic-gate /* Initialize the vtoc information */ 7620Sstevel@tonic-gate 7630Sstevel@tonic-gate if (media_type == SM_FLOPPY) { 7640Sstevel@tonic-gate struct fd_char fdchar; 7650Sstevel@tonic-gate int32_t mult_factor; 7660Sstevel@tonic-gate 7670Sstevel@tonic-gate if (ioctl(fd, FDIOGCHAR, &fdchar) < 0) { 7680Sstevel@tonic-gate PERROR("FDIOGCHAR failed"); 7690Sstevel@tonic-gate return (-1); 7700Sstevel@tonic-gate } 7710Sstevel@tonic-gate 7720Sstevel@tonic-gate /* SPARC and x86 fd drivers use fdc_medium differently */ 7730Sstevel@tonic-gate #if defined(__sparc) 7740Sstevel@tonic-gate mult_factor = (fdchar.fdc_medium) ? 2 : 1; 7750Sstevel@tonic-gate #elif defined(__x86) 7760Sstevel@tonic-gate mult_factor = (fdchar.fdc_medium == 5) ? 2 : 1; 7770Sstevel@tonic-gate #else 7780Sstevel@tonic-gate #error No Platform defined 7790Sstevel@tonic-gate #endif /* defined(__sparc) */ 7800Sstevel@tonic-gate 7810Sstevel@tonic-gate /* initialize the vtoc structure */ 7820Sstevel@tonic-gate v_toc.v_nparts = 3; 7830Sstevel@tonic-gate 7840Sstevel@tonic-gate v_toc.v_part[0].p_start = 0; 7850Sstevel@tonic-gate v_toc.v_part[0].p_size = (fdchar.fdc_ncyl - 1) * 2 * 7860Sstevel@tonic-gate fdchar.fdc_secptrack * mult_factor; 7870Sstevel@tonic-gate v_toc.v_part[1].p_start = (fdchar.fdc_ncyl - 1) * 2 * 7880Sstevel@tonic-gate fdchar.fdc_secptrack * mult_factor; 7890Sstevel@tonic-gate v_toc.v_part[1].p_size = 2 * fdchar.fdc_secptrack * mult_factor; 7900Sstevel@tonic-gate 7910Sstevel@tonic-gate v_toc.v_part[2].p_start = 0; 7920Sstevel@tonic-gate v_toc.v_part[2].p_size = fdchar.fdc_ncyl * 2 * 7930Sstevel@tonic-gate fdchar.fdc_secptrack * mult_factor; 7940Sstevel@tonic-gate 7950Sstevel@tonic-gate } else if (media_type == SM_PCMCIA_MEM) { 7960Sstevel@tonic-gate 7970Sstevel@tonic-gate static struct dk_geom dkg; 7980Sstevel@tonic-gate 7990Sstevel@tonic-gate /* Get card cyl/head/secptrack info */ 8000Sstevel@tonic-gate if (ioctl(fd, DKIOCGGEOM, &dkg) < 0) { 8010Sstevel@tonic-gate /* 8020Sstevel@tonic-gate * Card doesn't have a CIS. So, ask driver 8030Sstevel@tonic-gate * to probe card size info 8040Sstevel@tonic-gate */ 8050Sstevel@tonic-gate if (ioctl(fd, PCRAM_PROBESIZE, &dkg) < 0) { 8060Sstevel@tonic-gate (void) fprintf(stderr, 8070Sstevel@tonic-gate gettext( 8080Sstevel@tonic-gate "Could not get card size information\n")); 8090Sstevel@tonic-gate (void) close(fd); 8100Sstevel@tonic-gate exit(3); 8110Sstevel@tonic-gate } 8120Sstevel@tonic-gate } 8130Sstevel@tonic-gate 8140Sstevel@tonic-gate 8150Sstevel@tonic-gate v_toc.v_part[2].p_start = 0; 8160Sstevel@tonic-gate v_toc.v_part[2].p_size = dkg.dkg_ncyl * dkg.dkg_nhead * 8170Sstevel@tonic-gate dkg.dkg_nsect; 8180Sstevel@tonic-gate 8190Sstevel@tonic-gate /* v_nparts was 1 in fdformat. But write vtoc failes */ 8200Sstevel@tonic-gate v_toc.v_nparts = 3; 8210Sstevel@tonic-gate 8220Sstevel@tonic-gate } else if (media_type == SM_SCSI_FLOPPY) { 8230Sstevel@tonic-gate 8240Sstevel@tonic-gate smedia_handle_t handle; 8250Sstevel@tonic-gate smmedium_prop_t med_info; 8260Sstevel@tonic-gate struct dk_geom dkgeom; 8270Sstevel@tonic-gate 8280Sstevel@tonic-gate 8290Sstevel@tonic-gate /* 8300Sstevel@tonic-gate * call smedia_get_medium_property to get the 8310Sstevel@tonic-gate * correct media information, since DKIOCGMEDIAINFO 8320Sstevel@tonic-gate * may fail for unformatted media. 8330Sstevel@tonic-gate */ 8340Sstevel@tonic-gate 8350Sstevel@tonic-gate handle = smedia_get_handle(fd); 8360Sstevel@tonic-gate if (handle == NULL) { 8370Sstevel@tonic-gate (void) fprintf(stderr, 8380Sstevel@tonic-gate gettext("Failed to get libsmedia handle.\n")); 8390Sstevel@tonic-gate 8400Sstevel@tonic-gate (void) close(fd); 8410Sstevel@tonic-gate return (-1); 8420Sstevel@tonic-gate } 8430Sstevel@tonic-gate 8440Sstevel@tonic-gate 8450Sstevel@tonic-gate if (smedia_get_medium_property(handle, &med_info) < 0) { 8460Sstevel@tonic-gate (void) fprintf(stderr, 8470Sstevel@tonic-gate gettext("Get medium property failed \n")); 8480Sstevel@tonic-gate 8490Sstevel@tonic-gate (void) smedia_release_handle(handle); 8500Sstevel@tonic-gate (void) close(fd); 8510Sstevel@tonic-gate return (-1); 8520Sstevel@tonic-gate } 8530Sstevel@tonic-gate 8540Sstevel@tonic-gate /* Fill in our own geometry information */ 8550Sstevel@tonic-gate 8560Sstevel@tonic-gate dkgeom.dkg_pcyl = med_info.sm_pcyl; 8570Sstevel@tonic-gate dkgeom.dkg_ncyl = med_info.sm_pcyl; 8580Sstevel@tonic-gate dkgeom.dkg_nhead = med_info.sm_nhead; 8590Sstevel@tonic-gate dkgeom.dkg_nsect = med_info.sm_nsect; 8600Sstevel@tonic-gate dkgeom.dkg_acyl = 0; 8610Sstevel@tonic-gate dkgeom.dkg_bcyl = 0; 8620Sstevel@tonic-gate dkgeom.dkg_intrlv = 0; 8630Sstevel@tonic-gate dkgeom.dkg_apc = 0; 8640Sstevel@tonic-gate 8650Sstevel@tonic-gate /* 8660Sstevel@tonic-gate * Try to set vtoc, if not successful we will 8670Sstevel@tonic-gate * continue to use the faked geometry information. 8680Sstevel@tonic-gate */ 8690Sstevel@tonic-gate 8700Sstevel@tonic-gate (void) ioctl(fd, DKIOCSGEOM, &dkgeom); 8710Sstevel@tonic-gate 8720Sstevel@tonic-gate (void) smedia_release_handle(handle); 8730Sstevel@tonic-gate 8740Sstevel@tonic-gate /* we want the same partitioning as used for normal floppies */ 8750Sstevel@tonic-gate 8760Sstevel@tonic-gate v_toc.v_part[0].p_start = 0; 8770Sstevel@tonic-gate v_toc.v_part[0].p_size = (dkgeom.dkg_ncyl - 1) * 8780Sstevel@tonic-gate dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8790Sstevel@tonic-gate 8800Sstevel@tonic-gate v_toc.v_part[1].p_start = (dkgeom.dkg_ncyl - 1) * 8810Sstevel@tonic-gate dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8820Sstevel@tonic-gate v_toc.v_part[1].p_size = dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8830Sstevel@tonic-gate 8840Sstevel@tonic-gate v_toc.v_part[2].p_start = 0; 8850Sstevel@tonic-gate v_toc.v_part[2].p_size = dkgeom.dkg_ncyl * 8860Sstevel@tonic-gate dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8870Sstevel@tonic-gate 8880Sstevel@tonic-gate /* both write_vtoc and DKIOCSVTOC require V_NUMPAR partitions */ 8890Sstevel@tonic-gate v_toc.v_nparts = V_NUMPAR; 8900Sstevel@tonic-gate 8910Sstevel@tonic-gate } else { 8920Sstevel@tonic-gate 8930Sstevel@tonic-gate return (0); 8940Sstevel@tonic-gate } 8950Sstevel@tonic-gate 8960Sstevel@tonic-gate v_toc.v_sanity = VTOC_SANE; 8970Sstevel@tonic-gate v_toc.v_version = V_VERSION; 8980Sstevel@tonic-gate 8990Sstevel@tonic-gate /* 9000Sstevel@tonic-gate * The label structure is set up for DEV_BSIZE(512 byte) blocks, 9010Sstevel@tonic-gate * even though a medium density diskette has 1024 byte blocks 9020Sstevel@tonic-gate * See dklabel.h for more details. 9030Sstevel@tonic-gate */ 9040Sstevel@tonic-gate v_toc.v_sectorsz = DEV_BSIZE; 9050Sstevel@tonic-gate 9060Sstevel@tonic-gate /* let the fd driver finish constructing the label and writing it. */ 9070Sstevel@tonic-gate 9080Sstevel@tonic-gate 9092160Szk194757 /* Turn on the privileges. */ 9102160Szk194757 (void) __priv_bracket(PRIV_ON); 9110Sstevel@tonic-gate 9120Sstevel@tonic-gate ret = write_vtoc(fd, &v_toc); 9130Sstevel@tonic-gate 9142160Szk194757 /* Turn off the privileges. */ 9152160Szk194757 (void) __priv_bracket(PRIV_OFF); 9160Sstevel@tonic-gate 9170Sstevel@tonic-gate if (ret < 0) { 9180Sstevel@tonic-gate PERROR("Write vtoc"); 9190Sstevel@tonic-gate DPRINTF1("Write vtoc failed errno:%d\n", errno); 9200Sstevel@tonic-gate return (-1); 9210Sstevel@tonic-gate } 9220Sstevel@tonic-gate 9230Sstevel@tonic-gate return (0); 9240Sstevel@tonic-gate } 9250Sstevel@tonic-gate 9260Sstevel@tonic-gate static void 9270Sstevel@tonic-gate intr_sig_handler() 9280Sstevel@tonic-gate { 9290Sstevel@tonic-gate char c; 9300Sstevel@tonic-gate 9310Sstevel@tonic-gate (void) fprintf(stderr, gettext(global_intr_msg)); 9320Sstevel@tonic-gate (void) fprintf(stderr, 9330Sstevel@tonic-gate gettext("\nDo you want to stop formatting?(y/n)")); 9340Sstevel@tonic-gate (void) fflush(stdout); 9350Sstevel@tonic-gate rewind(stdin); 9360Sstevel@tonic-gate while ((c = getchar()) == -1); 9370Sstevel@tonic-gate if (c == 'y' || c == 'Y') { 9380Sstevel@tonic-gate (void) fprintf(stderr, gettext("Format interrupted\n")); 9390Sstevel@tonic-gate exit(1); 9400Sstevel@tonic-gate } else if (c == 'n' || c == 'N') 9410Sstevel@tonic-gate return; 9420Sstevel@tonic-gate else { 9430Sstevel@tonic-gate (void) fprintf(stderr, gettext("Did not interrupt\n")); 9440Sstevel@tonic-gate return; 9450Sstevel@tonic-gate } 9460Sstevel@tonic-gate } 9470Sstevel@tonic-gate 9480Sstevel@tonic-gate static struct sigaction act, oact; 9490Sstevel@tonic-gate void 9500Sstevel@tonic-gate trap_SIGINT() 9510Sstevel@tonic-gate { 9520Sstevel@tonic-gate 9530Sstevel@tonic-gate act.sa_handler = intr_sig_handler; 9540Sstevel@tonic-gate (void) memset(&act.sa_mask, 0, sizeof (sigset_t)); 9550Sstevel@tonic-gate act.sa_flags = SA_RESTART; /* | SA_NODEFER; */ 9560Sstevel@tonic-gate if (sigaction(SIGINT, &act, &oact) < 0) { 9570Sstevel@tonic-gate DPRINTF("sigset failed\n"); 9580Sstevel@tonic-gate return; 9590Sstevel@tonic-gate } 9600Sstevel@tonic-gate } 9610Sstevel@tonic-gate 9620Sstevel@tonic-gate void 9630Sstevel@tonic-gate release_SIGINT() 9640Sstevel@tonic-gate { 9650Sstevel@tonic-gate if (sigaction(SIGINT, &oact, (struct sigaction *)NULL) < 0) { 9660Sstevel@tonic-gate DPRINTF("sigunset failed\n"); 9670Sstevel@tonic-gate return; 9680Sstevel@tonic-gate } 9690Sstevel@tonic-gate } 9700Sstevel@tonic-gate 9710Sstevel@tonic-gate int32_t 9720Sstevel@tonic-gate verify(smedia_handle_t handle, int32_t fd, uint32_t start_sector, 9730Sstevel@tonic-gate uint32_t nblocks, char *buf, 9740Sstevel@tonic-gate int32_t flag, int32_t blocksize, int32_t no_raw_rw) 9750Sstevel@tonic-gate { 9760Sstevel@tonic-gate int32_t ret; 9770Sstevel@tonic-gate 9780Sstevel@tonic-gate DPRINTF("ANALYSE MEDIA \n"); 9790Sstevel@tonic-gate 9800Sstevel@tonic-gate 9810Sstevel@tonic-gate if ((flag == VERIFY_READ) && (!no_raw_rw)) { 9820Sstevel@tonic-gate 9832160Szk194757 /* Turn on the privileges. */ 9842160Szk194757 (void) __priv_bracket(PRIV_ON); 9850Sstevel@tonic-gate 9860Sstevel@tonic-gate ret = smedia_raw_read(handle, start_sector, buf, nblocks * 9870Sstevel@tonic-gate blocksize); 9880Sstevel@tonic-gate 9892160Szk194757 /* Turn off the privileges. */ 9902160Szk194757 (void) __priv_bracket(PRIV_OFF); 9910Sstevel@tonic-gate 9920Sstevel@tonic-gate if ((ret < 0) || (ret != (nblocks * blocksize))) 9932160Szk194757 return (-1); 9940Sstevel@tonic-gate return (0); 9950Sstevel@tonic-gate 9962160Szk194757 } else if ((flag == VERIFY_WRITE) && (!no_raw_rw)) { 9970Sstevel@tonic-gate 9982160Szk194757 /* Turn on privileges. */ 9992160Szk194757 (void) __priv_bracket(PRIV_ON); 10000Sstevel@tonic-gate 10010Sstevel@tonic-gate ret = smedia_raw_write(handle, start_sector, buf, nblocks * 10020Sstevel@tonic-gate blocksize); 10030Sstevel@tonic-gate 10042160Szk194757 /* Turn off the privileges. */ 10052160Szk194757 (void) __priv_bracket(PRIV_OFF); 10060Sstevel@tonic-gate 10070Sstevel@tonic-gate if ((ret < 0) || (ret != (blocksize * nblocks))) 10080Sstevel@tonic-gate return (-1); 10090Sstevel@tonic-gate return (0); 10100Sstevel@tonic-gate 10110Sstevel@tonic-gate } else if ((flag == VERIFY_READ) && (no_raw_rw)) { 10120Sstevel@tonic-gate ret = llseek(fd, start_sector * blocksize, SEEK_SET); 10130Sstevel@tonic-gate if (ret != start_sector * blocksize) { 10140Sstevel@tonic-gate (void) fprintf(stderr, gettext("Seek failed\n")); 10150Sstevel@tonic-gate return (-2); 10160Sstevel@tonic-gate } 10170Sstevel@tonic-gate 10182160Szk194757 /* Turn on the privileges. */ 10192160Szk194757 (void) __priv_bracket(PRIV_ON); 10200Sstevel@tonic-gate 10210Sstevel@tonic-gate ret = read(fd, buf, nblocks * blocksize); 10220Sstevel@tonic-gate 10232160Szk194757 /* Turn off the privileges. */ 10242160Szk194757 (void) __priv_bracket(PRIV_OFF); 10250Sstevel@tonic-gate 10260Sstevel@tonic-gate if (ret != nblocks * blocksize) { 10270Sstevel@tonic-gate return (-1); 10280Sstevel@tonic-gate } 10290Sstevel@tonic-gate return (0); 10300Sstevel@tonic-gate } else if ((flag == VERIFY_WRITE) && (no_raw_rw)) { 10310Sstevel@tonic-gate ret = llseek(fd, start_sector * blocksize, SEEK_SET); 10320Sstevel@tonic-gate if (ret != start_sector * blocksize) { 10330Sstevel@tonic-gate (void) fprintf(stderr, gettext("Seek failed\n")); 10340Sstevel@tonic-gate return (-2); 10350Sstevel@tonic-gate } 10360Sstevel@tonic-gate 10372160Szk194757 /* Turn on the privileges. */ 10382160Szk194757 (void) __priv_bracket(PRIV_ON); 10390Sstevel@tonic-gate 10400Sstevel@tonic-gate ret = write(fd, buf, nblocks * blocksize); 10410Sstevel@tonic-gate 10422160Szk194757 /* Turn off the privileges. */ 10432160Szk194757 (void) __priv_bracket(PRIV_OFF); 10440Sstevel@tonic-gate 10450Sstevel@tonic-gate if (ret != nblocks * blocksize) { 10460Sstevel@tonic-gate return (-1); 10470Sstevel@tonic-gate } 10480Sstevel@tonic-gate return (0); 10490Sstevel@tonic-gate } else { 10500Sstevel@tonic-gate DPRINTF("Illegal parameter to verify_analysis!\n"); 10510Sstevel@tonic-gate return (-1); 10520Sstevel@tonic-gate } 10530Sstevel@tonic-gate } 10540Sstevel@tonic-gate 10550Sstevel@tonic-gate static int 10560Sstevel@tonic-gate my_umount(char *mountp) 10570Sstevel@tonic-gate { 10580Sstevel@tonic-gate pid_t pid; /* forked proc's pid */ 10590Sstevel@tonic-gate int rval; /* proc's return value */ 10600Sstevel@tonic-gate 10610Sstevel@tonic-gate 10620Sstevel@tonic-gate /* create a child to unmount the path */ 10630Sstevel@tonic-gate 10642160Szk194757 /* Turn on the privileges */ 10652160Szk194757 (void) __priv_bracket(PRIV_ON); 10660Sstevel@tonic-gate 10670Sstevel@tonic-gate pid = fork(); 10680Sstevel@tonic-gate 10692160Szk194757 /* Turn off the privileges. */ 10702160Szk194757 (void) __priv_bracket(PRIV_OFF); 10710Sstevel@tonic-gate 10720Sstevel@tonic-gate if (pid < 0) { 10730Sstevel@tonic-gate PERROR("fork failed"); 10740Sstevel@tonic-gate exit(0); 10750Sstevel@tonic-gate } 10760Sstevel@tonic-gate 10770Sstevel@tonic-gate if (pid == 0) { 10780Sstevel@tonic-gate /* the child */ 10790Sstevel@tonic-gate /* get rid of those nasty err messages */ 10800Sstevel@tonic-gate DPRINTF1("call_unmount_prog: calling %s \n", mountp); 10810Sstevel@tonic-gate 10822160Szk194757 /* Turn on the priviliges. */ 10832160Szk194757 (void) __priv_bracket(PRIV_ON); 10840Sstevel@tonic-gate 10850Sstevel@tonic-gate if (execl("/usr/sbin/umount", "/usr/sbin/umount", mountp, 10860Sstevel@tonic-gate NULL) < 0) { 10870Sstevel@tonic-gate perror("exec failed"); 10882160Szk194757 /* Turn off the privileges */ 10892160Szk194757 (void) __priv_bracket(PRIV_OFF); 10900Sstevel@tonic-gate exit(-1); 10910Sstevel@tonic-gate } 10920Sstevel@tonic-gate } 10930Sstevel@tonic-gate 10940Sstevel@tonic-gate /* wait for the umount command to exit */ 10950Sstevel@tonic-gate rval = 0; 10960Sstevel@tonic-gate if (waitpid(pid, &rval, 0) == pid) { 10970Sstevel@tonic-gate if (WIFEXITED(rval)) { 10980Sstevel@tonic-gate if (WEXITSTATUS(rval) == 0) { 10990Sstevel@tonic-gate DPRINTF("umount : Success\n"); 11000Sstevel@tonic-gate return (1); 11010Sstevel@tonic-gate } 11020Sstevel@tonic-gate } 11030Sstevel@tonic-gate } 11040Sstevel@tonic-gate return (-1); 11050Sstevel@tonic-gate } 11060Sstevel@tonic-gate 11070Sstevel@tonic-gate static int 11080Sstevel@tonic-gate my_volrmmount(char *real_name) 11090Sstevel@tonic-gate { 11100Sstevel@tonic-gate int pid, rval; 11110Sstevel@tonic-gate 11122160Szk194757 /* Turn on the privileges. */ 11132160Szk194757 (void) __priv_bracket(PRIV_ON); 11140Sstevel@tonic-gate 11150Sstevel@tonic-gate pid = fork(); 11160Sstevel@tonic-gate 11172160Szk194757 /* Turn off the privileges. */ 11182160Szk194757 (void) __priv_bracket(PRIV_OFF); 11190Sstevel@tonic-gate 11200Sstevel@tonic-gate /* create a child to unmount the path */ 11210Sstevel@tonic-gate if (pid < 0) { 11220Sstevel@tonic-gate PERROR("fork failed"); 11230Sstevel@tonic-gate exit(0); 11240Sstevel@tonic-gate } 11250Sstevel@tonic-gate 11260Sstevel@tonic-gate if (pid == 0) { 11270Sstevel@tonic-gate /* the child */ 11280Sstevel@tonic-gate /* get rid of those nasty err messages */ 11290Sstevel@tonic-gate DPRINTF1("call_unmount_prog: calling %s \n", 11300Sstevel@tonic-gate "/usr/bin/volrmmount"); 11310Sstevel@tonic-gate 11322160Szk194757 /* Turn on the privileges. */ 11332160Szk194757 (void) __priv_bracket(PRIV_ON); 11340Sstevel@tonic-gate if (execl("/usr/bin/volrmmount", "/usr/bin/volrmmount", "-e", 11350Sstevel@tonic-gate real_name, NULL) < 0) { 11360Sstevel@tonic-gate PERROR("volrmmount exec failed"); 11372160Szk194757 /* Turn off the privileges */ 11382160Szk194757 (void) __priv_bracket(PRIV_OFF); 11390Sstevel@tonic-gate exit(-1); 11400Sstevel@tonic-gate } 11410Sstevel@tonic-gate } else if (waitpid(pid, &rval, 0) == pid) { 11420Sstevel@tonic-gate if (WIFEXITED(rval)) { 11430Sstevel@tonic-gate if (WEXITSTATUS(rval) == 0) { 11440Sstevel@tonic-gate DPRINTF("volrmmount: Success\n"); 11450Sstevel@tonic-gate return (1); 11460Sstevel@tonic-gate } 11470Sstevel@tonic-gate } 11480Sstevel@tonic-gate } 11490Sstevel@tonic-gate return (-1); 11500Sstevel@tonic-gate } 11510Sstevel@tonic-gate 11520Sstevel@tonic-gate int 11530Sstevel@tonic-gate find_device(int defer, char *tmpstr) 11540Sstevel@tonic-gate { 11550Sstevel@tonic-gate DIR *dir; 11560Sstevel@tonic-gate struct dirent *dirent; 11570Sstevel@tonic-gate char sdev[PATH_MAX], dev[PATH_MAX], *pname; 11580Sstevel@tonic-gate device_t *t_dev; 11590Sstevel@tonic-gate int removable, device_type; 11600Sstevel@tonic-gate struct dk_minfo mediainfo; 11610Sstevel@tonic-gate static int found = 0; 11620Sstevel@tonic-gate 11630Sstevel@tonic-gate dir = opendir("/dev/rdsk"); 11640Sstevel@tonic-gate if (dir == NULL) 11650Sstevel@tonic-gate return (-1); 11660Sstevel@tonic-gate 11670Sstevel@tonic-gate total_devices_found = 0; 11680Sstevel@tonic-gate while ((dirent = readdir(dir)) != NULL) { 11690Sstevel@tonic-gate if (dirent->d_name[0] == '.') { 11700Sstevel@tonic-gate continue; 11710Sstevel@tonic-gate } 11720Sstevel@tonic-gate (void) snprintf(sdev, PATH_MAX, "/dev/rdsk/%s", 11730Sstevel@tonic-gate dirent->d_name); 11740Sstevel@tonic-gate #ifdef sparc 11750Sstevel@tonic-gate if (!strstr(sdev, "s2")) { 11760Sstevel@tonic-gate continue; 11770Sstevel@tonic-gate } 11780Sstevel@tonic-gate #else /* x86 */ 11790Sstevel@tonic-gate if (vol_running) { 11800Sstevel@tonic-gate if (!(strstr(sdev, "s2") || strstr(sdev, "p0"))) { 11810Sstevel@tonic-gate continue; 11820Sstevel@tonic-gate } 11830Sstevel@tonic-gate } else { 11840Sstevel@tonic-gate if (!strstr(sdev, "p0")) { 11850Sstevel@tonic-gate continue; 11860Sstevel@tonic-gate } 11870Sstevel@tonic-gate } 11880Sstevel@tonic-gate #endif 11890Sstevel@tonic-gate if (!lookup_device(sdev, dev)) { 11900Sstevel@tonic-gate continue; 11910Sstevel@tonic-gate } 11920Sstevel@tonic-gate if ((t_dev = get_device(NULL, dev)) == NULL) { 11930Sstevel@tonic-gate continue; 11940Sstevel@tonic-gate } 11950Sstevel@tonic-gate total_devices_found++; 11960Sstevel@tonic-gate 11970Sstevel@tonic-gate if ((!defer) && !found) { 11980Sstevel@tonic-gate char *sn, *tmpbuf; 11990Sstevel@tonic-gate /* 12000Sstevel@tonic-gate * dev_name is an optional command line input. 12010Sstevel@tonic-gate */ 12020Sstevel@tonic-gate if (dev_name) { 12030Sstevel@tonic-gate if (strstr(dirent->d_name, tmpstr)) { 12040Sstevel@tonic-gate found = 1; 12050Sstevel@tonic-gate } else if (!vol_running) { 12060Sstevel@tonic-gate continue; 12070Sstevel@tonic-gate } 12080Sstevel@tonic-gate } 12090Sstevel@tonic-gate /* 12100Sstevel@tonic-gate * volmgt_symname() returns NULL if the device 12110Sstevel@tonic-gate * is not managed by volmgt. 12120Sstevel@tonic-gate */ 12130Sstevel@tonic-gate sn = volmgt_symname(sdev); 12140Sstevel@tonic-gate 12150Sstevel@tonic-gate if (vol_running && (sn != NULL)) { 12160Sstevel@tonic-gate if (strstr(sn, "dev") == NULL) { 12170Sstevel@tonic-gate tmpbuf = (char *)my_zalloc(PATH_MAX); 12180Sstevel@tonic-gate (void) strcpy(tmpbuf, 12190Sstevel@tonic-gate "/vol/dev/aliases/"); 12200Sstevel@tonic-gate (void) strcat(tmpbuf, sn); 12210Sstevel@tonic-gate free(sn); 12220Sstevel@tonic-gate sn = tmpbuf; 12230Sstevel@tonic-gate } 12240Sstevel@tonic-gate if (dev_name && !found) { 12250Sstevel@tonic-gate if (!strstr(tmpbuf, tmpstr)) { 12260Sstevel@tonic-gate continue; 12270Sstevel@tonic-gate } else { 12280Sstevel@tonic-gate found = 1; 12290Sstevel@tonic-gate } 12300Sstevel@tonic-gate } 12310Sstevel@tonic-gate } 12320Sstevel@tonic-gate 12330Sstevel@tonic-gate /* 12340Sstevel@tonic-gate * Get device type information for CD/DVD devices. 12350Sstevel@tonic-gate */ 12360Sstevel@tonic-gate if (is_cd(dev)) { 12370Sstevel@tonic-gate if (check_device(t_dev, 12380Sstevel@tonic-gate CHECK_DEVICE_IS_DVD_WRITABLE)) { 12390Sstevel@tonic-gate device_type = DK_DVDR; 12400Sstevel@tonic-gate } else if (check_device(t_dev, 12410Sstevel@tonic-gate CHECK_DEVICE_IS_DVD_READABLE)) { 12420Sstevel@tonic-gate device_type = DK_DVDROM; 12430Sstevel@tonic-gate } else if (check_device(t_dev, 12440Sstevel@tonic-gate CHECK_DEVICE_IS_CD_WRITABLE)) { 12450Sstevel@tonic-gate device_type = DK_CDR; 12460Sstevel@tonic-gate } else { 12470Sstevel@tonic-gate device_type = DK_CDROM; 12480Sstevel@tonic-gate } 12490Sstevel@tonic-gate } else { 12500Sstevel@tonic-gate device_type = ioctl(t_dev->d_fd, 12510Sstevel@tonic-gate DKIOCGMEDIAINFO, &mediainfo); 12520Sstevel@tonic-gate if (device_type < 0) 12530Sstevel@tonic-gate device_type = 0; 12540Sstevel@tonic-gate else 12550Sstevel@tonic-gate device_type = mediainfo.dki_media_type; 12560Sstevel@tonic-gate } 12570Sstevel@tonic-gate 12580Sstevel@tonic-gate if (!ioctl(t_dev->d_fd, DKIOCREMOVABLE, &removable)) { 12590Sstevel@tonic-gate if (removable) { 12600Sstevel@tonic-gate removable_found++; 12610Sstevel@tonic-gate pname = get_physical_name(sdev); 12620Sstevel@tonic-gate if (sn) { 12630Sstevel@tonic-gate (void) printf(" %4d. " 12640Sstevel@tonic-gate "Volmgt Node: %s\n", 12650Sstevel@tonic-gate removable_found, sn); 12660Sstevel@tonic-gate (void) printf(" " 12670Sstevel@tonic-gate "Logical Node: %s\n", sdev); 12680Sstevel@tonic-gate (void) printf(" " 12690Sstevel@tonic-gate "Physical Node: %s\n", 12700Sstevel@tonic-gate pname); 12710Sstevel@tonic-gate } else { 12720Sstevel@tonic-gate (void) printf(" %4d. " 12730Sstevel@tonic-gate "Logical Node: %s\n", 12740Sstevel@tonic-gate removable_found, sdev); 12750Sstevel@tonic-gate (void) printf(" " 12760Sstevel@tonic-gate "Physical Node: %s\n", 12770Sstevel@tonic-gate pname); 12780Sstevel@tonic-gate } 12790Sstevel@tonic-gate (void) printf(" Connected " 12800Sstevel@tonic-gate "Device: %-8.8s %-16.16s " 12810Sstevel@tonic-gate "%-4.4s\n", 12820Sstevel@tonic-gate &t_dev->d_inq[8], 12830Sstevel@tonic-gate &t_dev->d_inq[16], 12840Sstevel@tonic-gate &t_dev->d_inq[32]); 12850Sstevel@tonic-gate (void) printf(" Device " 12860Sstevel@tonic-gate "Type: "); 12870Sstevel@tonic-gate } else 12880Sstevel@tonic-gate continue; 12890Sstevel@tonic-gate } else 12900Sstevel@tonic-gate continue; 12910Sstevel@tonic-gate 12920Sstevel@tonic-gate switch (device_type) { 12930Sstevel@tonic-gate case DK_CDROM: 12940Sstevel@tonic-gate (void) printf("CD Reader\n"); 12950Sstevel@tonic-gate break; 12960Sstevel@tonic-gate case DK_CDR: 12970Sstevel@tonic-gate case DK_CDRW: 12980Sstevel@tonic-gate (void) printf("CD Reader/Writer\n"); 12990Sstevel@tonic-gate break; 13000Sstevel@tonic-gate case DK_DVDROM: 13010Sstevel@tonic-gate (void) printf("DVD Reader\n"); 13020Sstevel@tonic-gate break; 13030Sstevel@tonic-gate case DK_DVDR: 13040Sstevel@tonic-gate case DK_DVDRAM: 13050Sstevel@tonic-gate (void) printf("DVD Reader/Writer\n"); 13060Sstevel@tonic-gate break; 13070Sstevel@tonic-gate case DK_FIXED_DISK: 13080Sstevel@tonic-gate if (strstr((const char *) 13090Sstevel@tonic-gate &t_dev->d_inq[16], "FD") || 13100Sstevel@tonic-gate strstr((const char *) 13110Sstevel@tonic-gate &t_dev->d_inq[16], "LS-120")) 13120Sstevel@tonic-gate (void) printf("Floppy " 13130Sstevel@tonic-gate "drive\n"); 13140Sstevel@tonic-gate else 13150Sstevel@tonic-gate (void) printf("Removable\n"); 13160Sstevel@tonic-gate break; 13170Sstevel@tonic-gate case DK_FLOPPY: 13180Sstevel@tonic-gate (void) printf("Floppy drive\n"); 13190Sstevel@tonic-gate break; 13200Sstevel@tonic-gate case DK_ZIP: 13210Sstevel@tonic-gate (void) printf("Zip drive\n"); 13220Sstevel@tonic-gate break; 13230Sstevel@tonic-gate case DK_JAZ: 13240Sstevel@tonic-gate (void) printf("Jaz drive\n"); 13250Sstevel@tonic-gate break; 13260Sstevel@tonic-gate default: 13270Sstevel@tonic-gate (void) printf("<Unknown>\n"); 13280Sstevel@tonic-gate DPRINTF1("\t %d\n", device_type); 13290Sstevel@tonic-gate break; 13300Sstevel@tonic-gate } 13310Sstevel@tonic-gate get_media_info(t_dev, sdev, pname, sn); 13320Sstevel@tonic-gate } 13330Sstevel@tonic-gate fini_device(t_dev); 13340Sstevel@tonic-gate } 13350Sstevel@tonic-gate 13360Sstevel@tonic-gate (void) closedir(dir); 13370Sstevel@tonic-gate return (removable_found); 13380Sstevel@tonic-gate } 13390Sstevel@tonic-gate 13400Sstevel@tonic-gate /* 13410Sstevel@tonic-gate * Returns a device_t handle for a node returned by lookup_device() 13420Sstevel@tonic-gate * and takes the user supplied name and stores it inside the node. 13430Sstevel@tonic-gate */ 13440Sstevel@tonic-gate static device_t * 13450Sstevel@tonic-gate get_device(char *user_supplied, char *node) 13460Sstevel@tonic-gate { 13470Sstevel@tonic-gate device_t *dev; 13480Sstevel@tonic-gate int fd; 13490Sstevel@tonic-gate char devnode[PATH_MAX]; 13500Sstevel@tonic-gate int size; 13510Sstevel@tonic-gate 13520Sstevel@tonic-gate /* 13530Sstevel@tonic-gate * we need to resolve any link paths to avoid fake files 13540Sstevel@tonic-gate * such as /dev/rdsk/../../export/file. 13550Sstevel@tonic-gate */ 13560Sstevel@tonic-gate size = resolvepath(node, devnode, PATH_MAX); 13570Sstevel@tonic-gate if ((size <= 0) || (size >= (PATH_MAX - 1))) 13580Sstevel@tonic-gate return (NULL); 13590Sstevel@tonic-gate 13600Sstevel@tonic-gate /* resolvepath may not return a null terminated string */ 13610Sstevel@tonic-gate devnode[size] = '\0'; 13620Sstevel@tonic-gate 13630Sstevel@tonic-gate 13640Sstevel@tonic-gate /* the device node must be in /devices/ or /vol/dev/rdsk */ 13650Sstevel@tonic-gate 13660Sstevel@tonic-gate if ((strncmp(devnode, "/devices/", 9) != 0) && 13670Sstevel@tonic-gate (strncmp(devnode, "/vol/dev/rdsk", 13) != 0)) 13680Sstevel@tonic-gate return (NULL); 13690Sstevel@tonic-gate 13702160Szk194757 /* Turn on the privileges. */ 13712160Szk194757 (void) __priv_bracket(PRIV_ON); 13720Sstevel@tonic-gate 13730Sstevel@tonic-gate /* 13740Sstevel@tonic-gate * Since we are currently running with the user euid it is 13750Sstevel@tonic-gate * safe to try to open the file without checking access. 13760Sstevel@tonic-gate */ 13770Sstevel@tonic-gate 13780Sstevel@tonic-gate fd = open(devnode, O_RDONLY|O_NDELAY); 13790Sstevel@tonic-gate 13802160Szk194757 /* Turn off the privileges. */ 13812160Szk194757 (void) __priv_bracket(PRIV_OFF); 13820Sstevel@tonic-gate 13830Sstevel@tonic-gate if (fd < 0) { 13840Sstevel@tonic-gate return (NULL); 13850Sstevel@tonic-gate } 13860Sstevel@tonic-gate 13870Sstevel@tonic-gate dev = (device_t *)my_zalloc(sizeof (device_t)); 13880Sstevel@tonic-gate 13890Sstevel@tonic-gate dev->d_node = (char *)my_zalloc(strlen(devnode) + 1); 13900Sstevel@tonic-gate (void) strcpy(dev->d_node, devnode); 13910Sstevel@tonic-gate 13920Sstevel@tonic-gate dev->d_fd = fd; 13930Sstevel@tonic-gate 13940Sstevel@tonic-gate dev->d_inq = (uchar_t *)my_zalloc(INQUIRY_DATA_LENGTH); 13950Sstevel@tonic-gate 13962160Szk194757 /* Turn on privileges. */ 13972160Szk194757 (void) __priv_bracket(PRIV_ON); 13980Sstevel@tonic-gate if (!inquiry(fd, dev->d_inq)) { 13990Sstevel@tonic-gate DPRINTF1("USCSI ioctl failed %d\n", 14000Sstevel@tonic-gate uscsi_error); 14010Sstevel@tonic-gate free(dev->d_inq); 14020Sstevel@tonic-gate free(dev->d_node); 14030Sstevel@tonic-gate (void) close(dev->d_fd); 14040Sstevel@tonic-gate free(dev); 14052160Szk194757 /* Turn off privileges. */ 14062160Szk194757 (void) __priv_bracket(PRIV_OFF); 14070Sstevel@tonic-gate return (NULL); 14080Sstevel@tonic-gate } 14092160Szk194757 /* Turn off privileges. */ 14102160Szk194757 (void) __priv_bracket(PRIV_OFF); 14110Sstevel@tonic-gate 14120Sstevel@tonic-gate if (user_supplied) { 14130Sstevel@tonic-gate dev->d_name = (char *)my_zalloc(strlen(user_supplied) + 1); 14140Sstevel@tonic-gate (void) strcpy(dev->d_name, user_supplied); 14150Sstevel@tonic-gate } 14160Sstevel@tonic-gate return (dev); 14170Sstevel@tonic-gate } 14180Sstevel@tonic-gate 14190Sstevel@tonic-gate /* 14200Sstevel@tonic-gate * Check for device specific characteristics. 14210Sstevel@tonic-gate */ 14220Sstevel@tonic-gate int 14230Sstevel@tonic-gate check_device(device_t *dev, int cond) 14240Sstevel@tonic-gate { 14250Sstevel@tonic-gate uchar_t page_code[4]; 14260Sstevel@tonic-gate 14270Sstevel@tonic-gate /* Look at the capabilities page for this information */ 14280Sstevel@tonic-gate if (cond & CHECK_DEVICE_IS_CD_WRITABLE) { 14290Sstevel@tonic-gate if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) && 14300Sstevel@tonic-gate (page_code[3] & 1)) { 14310Sstevel@tonic-gate return (1); 14320Sstevel@tonic-gate } 14330Sstevel@tonic-gate } 14340Sstevel@tonic-gate 14350Sstevel@tonic-gate if (cond & CHECK_DEVICE_IS_DVD_WRITABLE) { 14360Sstevel@tonic-gate if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) && 14370Sstevel@tonic-gate (page_code[3] & 0x10)) { 14380Sstevel@tonic-gate return (1); 14390Sstevel@tonic-gate } 14400Sstevel@tonic-gate } 14410Sstevel@tonic-gate 14420Sstevel@tonic-gate if (cond & CHECK_DEVICE_IS_DVD_READABLE) { 14430Sstevel@tonic-gate if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) && 14440Sstevel@tonic-gate (page_code[2] & 0x8)) { 14450Sstevel@tonic-gate return (1); 14460Sstevel@tonic-gate } 14470Sstevel@tonic-gate } 14480Sstevel@tonic-gate 14490Sstevel@tonic-gate return (0); 14500Sstevel@tonic-gate } 14510Sstevel@tonic-gate 14520Sstevel@tonic-gate /* 14530Sstevel@tonic-gate * Builds an open()able device path from a user supplied node which can be 14540Sstevel@tonic-gate * of the * form of /dev/[r]dsk/cxtxdx[sx] or cxtxdx[sx] or volmgt-name like 14550Sstevel@tonic-gate * cdrom[n]. 14560Sstevel@tonic-gate * Returns the path found in 'found' and returns 1. Otherwise returns 0. 14570Sstevel@tonic-gate */ 14580Sstevel@tonic-gate int 14590Sstevel@tonic-gate lookup_device(char *supplied, char *found) 14600Sstevel@tonic-gate { 14610Sstevel@tonic-gate struct stat statbuf; 14620Sstevel@tonic-gate int fd; 14630Sstevel@tonic-gate char tmpstr[PATH_MAX]; 14640Sstevel@tonic-gate 14652160Szk194757 /* Turn on privileges */ 14662160Szk194757 (void) __priv_bracket(PRIV_ON); 14670Sstevel@tonic-gate 14680Sstevel@tonic-gate /* If everything is fine and proper, no need to analyze */ 1469871Scasper if ((stat(supplied, &statbuf) == 0) && S_ISCHR(statbuf.st_mode) && 14700Sstevel@tonic-gate ((fd = open(supplied, O_RDONLY|O_NDELAY)) >= 0)) { 14710Sstevel@tonic-gate (void) close(fd); 14720Sstevel@tonic-gate (void) strlcpy(found, supplied, PATH_MAX); 14732160Szk194757 /* Turn off privilege */ 14742160Szk194757 (void) __priv_bracket(PRIV_OFF); 14750Sstevel@tonic-gate return (1); 14760Sstevel@tonic-gate } 14770Sstevel@tonic-gate 14782160Szk194757 /* Turn off privileges. */ 14792160Szk194757 (void) __priv_bracket(PRIV_OFF); 14800Sstevel@tonic-gate 14810Sstevel@tonic-gate if (strncmp(supplied, "/dev/rdsk/", 10) == 0) 14820Sstevel@tonic-gate return (vol_lookup(supplied, found)); 14830Sstevel@tonic-gate if (strncmp(supplied, "/dev/dsk/", 9) == 0) { 14840Sstevel@tonic-gate (void) snprintf(tmpstr, PATH_MAX, "/dev/rdsk/%s", 14850Sstevel@tonic-gate (char *)strrchr(supplied, '/')); 14860Sstevel@tonic-gate 14870Sstevel@tonic-gate if ((fd = open(tmpstr, O_RDONLY|O_NDELAY)) >= 0) { 14880Sstevel@tonic-gate (void) close(fd); 14890Sstevel@tonic-gate (void) strlcpy(found, supplied, PATH_MAX); 14900Sstevel@tonic-gate return (1); 14910Sstevel@tonic-gate } 14920Sstevel@tonic-gate if ((access(tmpstr, F_OK) == 0) && vol_running) 14930Sstevel@tonic-gate return (vol_lookup(tmpstr, found)); 14940Sstevel@tonic-gate else 14950Sstevel@tonic-gate return (0); 14960Sstevel@tonic-gate } 14970Sstevel@tonic-gate if ((strncmp(supplied, "cdrom", 5) != 0) && 14980Sstevel@tonic-gate (strlen(supplied) < 32)) { 14990Sstevel@tonic-gate (void) snprintf(tmpstr, sizeof (tmpstr), "/dev/rdsk/%s", 15000Sstevel@tonic-gate supplied); 15010Sstevel@tonic-gate if (access(tmpstr, F_OK) < 0) { 15020Sstevel@tonic-gate (void) strcat(tmpstr, "s2"); 15030Sstevel@tonic-gate } 15040Sstevel@tonic-gate if ((fd = open(tmpstr, O_RDONLY|O_NDELAY)) >= 0) { 15050Sstevel@tonic-gate (void) close(fd); 15060Sstevel@tonic-gate (void) strlcpy(found, tmpstr, PATH_MAX); 15070Sstevel@tonic-gate return (1); 15080Sstevel@tonic-gate } 15090Sstevel@tonic-gate if ((access(tmpstr, F_OK) == 0) && vol_running) 15100Sstevel@tonic-gate return (vol_lookup(tmpstr, found)); 15110Sstevel@tonic-gate } 15120Sstevel@tonic-gate return (vol_name_to_dev_node(supplied, found)); 15130Sstevel@tonic-gate } 15140Sstevel@tonic-gate 15150Sstevel@tonic-gate int 15160Sstevel@tonic-gate is_cd(char *node) 15170Sstevel@tonic-gate { 15180Sstevel@tonic-gate int fd; 15190Sstevel@tonic-gate struct dk_cinfo cinfo; 15200Sstevel@tonic-gate 15210Sstevel@tonic-gate fd = open(node, O_RDONLY|O_NDELAY); 15220Sstevel@tonic-gate if (fd < 0) 15230Sstevel@tonic-gate return (0); 15240Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &cinfo) < 0) { 15250Sstevel@tonic-gate (void) close(fd); 15260Sstevel@tonic-gate return (0); 15270Sstevel@tonic-gate } 15280Sstevel@tonic-gate if (cinfo.dki_ctype != DKC_CDROM) 15290Sstevel@tonic-gate return (0); 15300Sstevel@tonic-gate return (1); 15310Sstevel@tonic-gate } 15320Sstevel@tonic-gate 15330Sstevel@tonic-gate void 15340Sstevel@tonic-gate print_header(void) 15350Sstevel@tonic-gate { 15360Sstevel@tonic-gate /* l10n_NOTE : Column spacing should be kept same */ 15370Sstevel@tonic-gate (void) printf(gettext(" Node " 15380Sstevel@tonic-gate "Connected Device")); 15390Sstevel@tonic-gate /* l10n_NOTE : Column spacing should be kept same */ 15400Sstevel@tonic-gate (void) printf(gettext(" Device type\n")); 15410Sstevel@tonic-gate (void) printf( 15420Sstevel@tonic-gate "---------------------------+---------------------------"); 15430Sstevel@tonic-gate (void) printf("-----+----------------\n"); 15440Sstevel@tonic-gate } 15450Sstevel@tonic-gate 15460Sstevel@tonic-gate void 15470Sstevel@tonic-gate print_divider(void) 15480Sstevel@tonic-gate { 15490Sstevel@tonic-gate (void) printf( 15500Sstevel@tonic-gate "---------------------------+---------------------------"); 15510Sstevel@tonic-gate (void) printf("-----+----------------\n"); 15520Sstevel@tonic-gate } 15530Sstevel@tonic-gate 15540Sstevel@tonic-gate static void 15550Sstevel@tonic-gate fini_device(device_t *dev) 15560Sstevel@tonic-gate { 15570Sstevel@tonic-gate free(dev->d_inq); 15580Sstevel@tonic-gate free(dev->d_node); 15590Sstevel@tonic-gate (void) close(dev->d_fd); 15600Sstevel@tonic-gate if (dev->d_name) 15610Sstevel@tonic-gate free(dev->d_name); 15620Sstevel@tonic-gate free(dev); 15630Sstevel@tonic-gate } 15640Sstevel@tonic-gate 15650Sstevel@tonic-gate void * 15660Sstevel@tonic-gate my_zalloc(size_t size) 15670Sstevel@tonic-gate { 15680Sstevel@tonic-gate void *ret; 15690Sstevel@tonic-gate 15700Sstevel@tonic-gate ret = malloc(size); 15710Sstevel@tonic-gate if (ret == NULL) { 15720Sstevel@tonic-gate 15730Sstevel@tonic-gate /* Lets wait a sec. and try again */ 15740Sstevel@tonic-gate if (errno == EAGAIN) { 15750Sstevel@tonic-gate (void) sleep(1); 15760Sstevel@tonic-gate ret = malloc(size); 15770Sstevel@tonic-gate } 15780Sstevel@tonic-gate 15790Sstevel@tonic-gate if (ret == NULL) { 15800Sstevel@tonic-gate (void) err_msg("%s\n", gettext(strerror(errno))); 15810Sstevel@tonic-gate (void) err_msg(gettext( 15820Sstevel@tonic-gate "Memory allocation failure, Exiting...\n")); 15830Sstevel@tonic-gate exit(1); 15840Sstevel@tonic-gate } 15850Sstevel@tonic-gate } 15860Sstevel@tonic-gate (void) memset(ret, 0, size); 15870Sstevel@tonic-gate return (ret); 15880Sstevel@tonic-gate } 15890Sstevel@tonic-gate 15900Sstevel@tonic-gate static int 15910Sstevel@tonic-gate vol_name_to_dev_node(char *vname, char *found) 15920Sstevel@tonic-gate { 15930Sstevel@tonic-gate struct stat statbuf; 15940Sstevel@tonic-gate char *p1; 15950Sstevel@tonic-gate int i; 15960Sstevel@tonic-gate 15970Sstevel@tonic-gate if (vname == NULL) 15980Sstevel@tonic-gate return (0); 15990Sstevel@tonic-gate if (vol_running) 16000Sstevel@tonic-gate (void) volmgt_check(vname); 16010Sstevel@tonic-gate p1 = media_findname(vname); 16020Sstevel@tonic-gate if (p1 == NULL) 16030Sstevel@tonic-gate return (0); 16040Sstevel@tonic-gate if (stat(p1, &statbuf) < 0) { 16050Sstevel@tonic-gate free(p1); 16060Sstevel@tonic-gate return (0); 16070Sstevel@tonic-gate } 1608871Scasper if (S_ISDIR(statbuf.st_mode)) { 16090Sstevel@tonic-gate for (i = 0; i < 16; i++) { 16100Sstevel@tonic-gate (void) snprintf(found, PATH_MAX, "%s/s%d", p1, i); 16110Sstevel@tonic-gate if (access(found, F_OK) >= 0) 16120Sstevel@tonic-gate break; 16130Sstevel@tonic-gate } 16140Sstevel@tonic-gate if (i == 16) { 16150Sstevel@tonic-gate free(p1); 16160Sstevel@tonic-gate return (0); 16170Sstevel@tonic-gate } 16180Sstevel@tonic-gate } else { 16190Sstevel@tonic-gate (void) strlcpy(found, p1, PATH_MAX); 16200Sstevel@tonic-gate } 16210Sstevel@tonic-gate free(p1); 16220Sstevel@tonic-gate return (1); 16230Sstevel@tonic-gate } 16240Sstevel@tonic-gate 16250Sstevel@tonic-gate /* 16260Sstevel@tonic-gate * Searches for volume manager's equivalent char device for the 16270Sstevel@tonic-gate * supplied pathname which is of the form of /dev/rdsk/cxtxdxsx 16280Sstevel@tonic-gate */ 16290Sstevel@tonic-gate static int 16300Sstevel@tonic-gate vol_lookup(char *supplied, char *found) 16310Sstevel@tonic-gate { 16320Sstevel@tonic-gate char tmpstr[PATH_MAX], tmpstr1[PATH_MAX], *p; 16330Sstevel@tonic-gate int i, ret; 16340Sstevel@tonic-gate 16350Sstevel@tonic-gate (void) strlcpy(tmpstr, supplied, PATH_MAX); 16360Sstevel@tonic-gate if ((p = volmgt_symname(tmpstr)) == NULL) { 16370Sstevel@tonic-gate if (strstr(tmpstr, "s2") != NULL) { 16380Sstevel@tonic-gate *((char *)(strrchr(tmpstr, 's') + 1)) = 0; 16390Sstevel@tonic-gate for (i = 0; i < 16; i++) { 16400Sstevel@tonic-gate (void) snprintf(tmpstr1, PATH_MAX, "%s%d", 16410Sstevel@tonic-gate tmpstr, i); 16420Sstevel@tonic-gate if ((p = volmgt_symname(tmpstr1)) != NULL) 16430Sstevel@tonic-gate break; 16440Sstevel@tonic-gate } 16450Sstevel@tonic-gate } else if (strstr(tmpstr, "p0") != NULL) { 16460Sstevel@tonic-gate *((char *)(strrchr(tmpstr, 'p') + 1)) = 0; 16470Sstevel@tonic-gate for (i = 0; i < 5; i++) { 16480Sstevel@tonic-gate (void) snprintf(tmpstr1, PATH_MAX, "%s%d", 16490Sstevel@tonic-gate tmpstr, i); 16500Sstevel@tonic-gate if ((p = volmgt_symname(tmpstr1)) != NULL) 16510Sstevel@tonic-gate break; 16520Sstevel@tonic-gate } 16530Sstevel@tonic-gate } else 16540Sstevel@tonic-gate return (0); 16550Sstevel@tonic-gate if (p == NULL) 16560Sstevel@tonic-gate return (0); 16570Sstevel@tonic-gate } 16580Sstevel@tonic-gate 16590Sstevel@tonic-gate ret = vol_name_to_dev_node(p, found); 16600Sstevel@tonic-gate free(p); 16610Sstevel@tonic-gate return (ret); 16620Sstevel@tonic-gate } 16630Sstevel@tonic-gate 16640Sstevel@tonic-gate /*PRINTFLIKE1*/ 16650Sstevel@tonic-gate void 16660Sstevel@tonic-gate err_msg(char *fmt, ...) 16670Sstevel@tonic-gate { 16680Sstevel@tonic-gate va_list ap; 16690Sstevel@tonic-gate 16700Sstevel@tonic-gate va_start(ap, fmt); 16710Sstevel@tonic-gate (void) vfprintf(stderr, fmt, ap); 16720Sstevel@tonic-gate va_end(ap); 16730Sstevel@tonic-gate } 16740Sstevel@tonic-gate 16750Sstevel@tonic-gate int 16760Sstevel@tonic-gate inquiry(int fd, uchar_t *inq) 16770Sstevel@tonic-gate { 16780Sstevel@tonic-gate struct uscsi_cmd *scmd; 16790Sstevel@tonic-gate 16800Sstevel@tonic-gate scmd = get_uscsi_cmd(); 16810Sstevel@tonic-gate scmd->uscsi_flags = USCSI_READ|USCSI_SILENT; 16820Sstevel@tonic-gate scmd->uscsi_timeout = DEFAULT_SCSI_TIMEOUT; 16830Sstevel@tonic-gate scmd->uscsi_cdb[0] = INQUIRY_CMD; 16840Sstevel@tonic-gate scmd->uscsi_cdb[4] = INQUIRY_DATA_LENGTH; 16850Sstevel@tonic-gate scmd->uscsi_cdblen = 6; 16860Sstevel@tonic-gate scmd->uscsi_bufaddr = (char *)inq; 16870Sstevel@tonic-gate scmd->uscsi_buflen = INQUIRY_DATA_LENGTH; 16880Sstevel@tonic-gate if ((uscsi_error = uscsi(fd, scmd)) < 0) 16890Sstevel@tonic-gate return (0); 16900Sstevel@tonic-gate return (1); 16910Sstevel@tonic-gate } 16920Sstevel@tonic-gate 16930Sstevel@tonic-gate struct uscsi_cmd * 16940Sstevel@tonic-gate get_uscsi_cmd(void) 16950Sstevel@tonic-gate { 16960Sstevel@tonic-gate (void) memset(&uscmd, 0, sizeof (uscmd)); 16970Sstevel@tonic-gate (void) memset(ucdb, 0, 16); 16980Sstevel@tonic-gate uscmd.uscsi_cdb = ucdb; 16990Sstevel@tonic-gate return (&uscmd); 17000Sstevel@tonic-gate } 17010Sstevel@tonic-gate 17020Sstevel@tonic-gate int 17030Sstevel@tonic-gate uscsi(int fd, struct uscsi_cmd *scmd) 17040Sstevel@tonic-gate { 17050Sstevel@tonic-gate int ret, global_rqsense; 17060Sstevel@tonic-gate int retries, max_retries = 5; 17070Sstevel@tonic-gate int i; 17080Sstevel@tonic-gate 17090Sstevel@tonic-gate /* set up for request sense extensions */ 17100Sstevel@tonic-gate if (!(scmd->uscsi_flags & USCSI_RQENABLE)) { 17110Sstevel@tonic-gate scmd->uscsi_flags |= USCSI_RQENABLE; 17120Sstevel@tonic-gate scmd->uscsi_rqlen = RQBUFLEN; 17130Sstevel@tonic-gate scmd->uscsi_rqbuf = rqbuf; 17140Sstevel@tonic-gate global_rqsense = 1; 17150Sstevel@tonic-gate } else { 17160Sstevel@tonic-gate global_rqsense = 0; 17170Sstevel@tonic-gate } 17180Sstevel@tonic-gate 17190Sstevel@tonic-gate /* 17200Sstevel@tonic-gate * The device may be busy or slow and fail with a not ready status. 17210Sstevel@tonic-gate * we'll allow a limited number of retries to give the drive time 17220Sstevel@tonic-gate * to recover. 17230Sstevel@tonic-gate */ 17240Sstevel@tonic-gate for (retries = 0; retries < max_retries; retries++) { 17250Sstevel@tonic-gate 17260Sstevel@tonic-gate scmd->uscsi_status = 0; 17270Sstevel@tonic-gate 17280Sstevel@tonic-gate if (global_rqsense) 17290Sstevel@tonic-gate (void) memset(rqbuf, 0, RQBUFLEN); 17300Sstevel@tonic-gate 17310Sstevel@tonic-gate DPRINTF("cmd:["); 17320Sstevel@tonic-gate for (i = 0; i < scmd->uscsi_cdblen; i++) 17330Sstevel@tonic-gate DPRINTF1("0x%02x ", 17340Sstevel@tonic-gate (uchar_t)scmd->uscsi_cdb[i]); 17350Sstevel@tonic-gate DPRINTF("]\n"); 17360Sstevel@tonic-gate 17370Sstevel@tonic-gate /* 17380Sstevel@tonic-gate * We need to have root privledges in order to use 17390Sstevel@tonic-gate * uscsi commands on the device. 17400Sstevel@tonic-gate */ 17410Sstevel@tonic-gate 17420Sstevel@tonic-gate ret = ioctl(fd, USCSICMD, scmd); 17430Sstevel@tonic-gate 17440Sstevel@tonic-gate /* maintain consistency in case of sgen */ 17450Sstevel@tonic-gate if ((ret == 0) && (scmd->uscsi_status == 2)) { 17460Sstevel@tonic-gate ret = -1; 17470Sstevel@tonic-gate errno = EIO; 17480Sstevel@tonic-gate } 17490Sstevel@tonic-gate 17500Sstevel@tonic-gate /* if error and extended request sense, retrieve errors */ 17510Sstevel@tonic-gate if (global_rqsense && (ret < 0) && (scmd->uscsi_status == 2)) { 17520Sstevel@tonic-gate /* 17530Sstevel@tonic-gate * The drive is not ready to recieve commands but 17540Sstevel@tonic-gate * may be in the process of becoming ready. 17550Sstevel@tonic-gate * sleep for a short time then retry command. 17560Sstevel@tonic-gate * SENSE/ASC = 2/4 : not ready 17570Sstevel@tonic-gate * ASCQ = 0 Not Reportable. 17580Sstevel@tonic-gate * ASCQ = 1 Becoming ready. 17590Sstevel@tonic-gate */ 17600Sstevel@tonic-gate if ((SENSE_KEY(rqbuf) == 2) && (ASC(rqbuf) == 4) && 17610Sstevel@tonic-gate ((ASCQ(rqbuf) == 0) || (ASCQ(rqbuf) == 1))) { 17620Sstevel@tonic-gate total_retries++; 17630Sstevel@tonic-gate (void) sleep(3); 17640Sstevel@tonic-gate continue; 17650Sstevel@tonic-gate } 17660Sstevel@tonic-gate 17670Sstevel@tonic-gate /* 17680Sstevel@tonic-gate * Device is not ready to transmit or a device reset 17690Sstevel@tonic-gate * has occurred. wait for a short period of time then 17700Sstevel@tonic-gate * retry the command. 17710Sstevel@tonic-gate */ 17720Sstevel@tonic-gate if ((SENSE_KEY(rqbuf) == 6) && ((ASC(rqbuf) == 0x28) || 17730Sstevel@tonic-gate (ASC(rqbuf) == 0x29))) { 17740Sstevel@tonic-gate (void) sleep(3); 17750Sstevel@tonic-gate total_retries++; 17760Sstevel@tonic-gate continue; 17770Sstevel@tonic-gate } 17780Sstevel@tonic-gate 17790Sstevel@tonic-gate DPRINTF3("cmd: 0x%02x ret:%i status:%02x ", 17800Sstevel@tonic-gate (uchar_t)scmd->uscsi_cdb[0], ret, 17810Sstevel@tonic-gate scmd->uscsi_status); 17820Sstevel@tonic-gate DPRINTF3(" sense: %02x ASC: %02x ASCQ:%02x\n", 17830Sstevel@tonic-gate (uchar_t)SENSE_KEY(rqbuf), 17840Sstevel@tonic-gate (uchar_t)ASC(rqbuf), (uchar_t)ASCQ(rqbuf)); 17850Sstevel@tonic-gate } 17860Sstevel@tonic-gate 17870Sstevel@tonic-gate /* no errors we'll return */ 17880Sstevel@tonic-gate break; 17890Sstevel@tonic-gate } 17900Sstevel@tonic-gate 17910Sstevel@tonic-gate /* store the error status for later debug printing */ 17920Sstevel@tonic-gate if ((ret < 0) && (global_rqsense)) { 17930Sstevel@tonic-gate uscsi_status = scmd->uscsi_status; 17940Sstevel@tonic-gate rqstatus = scmd->uscsi_rqstatus; 17950Sstevel@tonic-gate rqresid = scmd->uscsi_rqresid; 17960Sstevel@tonic-gate 17970Sstevel@tonic-gate } 17980Sstevel@tonic-gate 17990Sstevel@tonic-gate DPRINTF1("total retries: %d\n", total_retries); 18000Sstevel@tonic-gate 18010Sstevel@tonic-gate return (ret); 18020Sstevel@tonic-gate } 18030Sstevel@tonic-gate 18040Sstevel@tonic-gate /* 18050Sstevel@tonic-gate * will get the mode page only i.e. will strip off the header. 18060Sstevel@tonic-gate */ 18070Sstevel@tonic-gate int 18080Sstevel@tonic-gate get_mode_page(int fd, int page_no, int pc, int buf_len, uchar_t *buffer) 18090Sstevel@tonic-gate { 18100Sstevel@tonic-gate int ret; 18110Sstevel@tonic-gate uchar_t byte2, *buf; 18120Sstevel@tonic-gate uint_t header_len, page_len, copy_cnt; 18130Sstevel@tonic-gate 18140Sstevel@tonic-gate byte2 = (uchar_t)(((pc << 6) & 0xC0) | (page_no & 0x3f)); 18150Sstevel@tonic-gate buf = (uchar_t *)my_zalloc(256); 18160Sstevel@tonic-gate 18170Sstevel@tonic-gate /* Ask 254 bytes only to make our IDE driver happy */ 18180Sstevel@tonic-gate ret = mode_sense(fd, byte2, 1, 254, buf); 18190Sstevel@tonic-gate if (ret == 0) { 18200Sstevel@tonic-gate free(buf); 18210Sstevel@tonic-gate return (0); 18220Sstevel@tonic-gate } 18230Sstevel@tonic-gate 18240Sstevel@tonic-gate header_len = 8 + read_scsi16(&buf[6]); 18250Sstevel@tonic-gate page_len = buf[header_len + 1] + 2; 18260Sstevel@tonic-gate 18270Sstevel@tonic-gate copy_cnt = (page_len > buf_len) ? buf_len : page_len; 18280Sstevel@tonic-gate (void) memcpy(buffer, &buf[header_len], copy_cnt); 18290Sstevel@tonic-gate free(buf); 18300Sstevel@tonic-gate 18310Sstevel@tonic-gate return (1); 18320Sstevel@tonic-gate } 18330Sstevel@tonic-gate 18340Sstevel@tonic-gate int 18350Sstevel@tonic-gate mode_sense(int fd, uchar_t pc, int dbd, int page_len, uchar_t *buffer) 18360Sstevel@tonic-gate { 18370Sstevel@tonic-gate struct uscsi_cmd *scmd; 18380Sstevel@tonic-gate 18390Sstevel@tonic-gate scmd = get_uscsi_cmd(); 18400Sstevel@tonic-gate scmd->uscsi_flags = USCSI_READ|USCSI_SILENT; 18410Sstevel@tonic-gate scmd->uscsi_buflen = page_len; 18420Sstevel@tonic-gate scmd->uscsi_bufaddr = (char *)buffer; 18430Sstevel@tonic-gate scmd->uscsi_timeout = DEFAULT_SCSI_TIMEOUT; 18440Sstevel@tonic-gate scmd->uscsi_cdblen = 0xa; 18450Sstevel@tonic-gate scmd->uscsi_cdb[0] = MODE_SENSE_10_CMD; 18460Sstevel@tonic-gate if (dbd) { 18470Sstevel@tonic-gate /* don't return any block descriptors */ 18480Sstevel@tonic-gate scmd->uscsi_cdb[1] = 0x8; 18490Sstevel@tonic-gate } 18500Sstevel@tonic-gate /* the page code we want */ 18510Sstevel@tonic-gate scmd->uscsi_cdb[2] = pc; 18520Sstevel@tonic-gate /* allocation length */ 18530Sstevel@tonic-gate scmd->uscsi_cdb[7] = (page_len >> 8) & 0xff; 18540Sstevel@tonic-gate scmd->uscsi_cdb[8] = page_len & 0xff; 18550Sstevel@tonic-gate 18560Sstevel@tonic-gate if ((uscsi_error = uscsi(fd, scmd)) < 0) 18570Sstevel@tonic-gate return (0); 18580Sstevel@tonic-gate return (1); 18590Sstevel@tonic-gate } 18600Sstevel@tonic-gate 18610Sstevel@tonic-gate uint16_t 18620Sstevel@tonic-gate read_scsi16(void *addr) 18630Sstevel@tonic-gate { 18640Sstevel@tonic-gate uchar_t *ad = (uchar_t *)addr; 18650Sstevel@tonic-gate uint16_t ret; 18660Sstevel@tonic-gate 18670Sstevel@tonic-gate ret = ((((uint16_t)ad[0]) << 8) | ad[1]); 18680Sstevel@tonic-gate return (ret); 18690Sstevel@tonic-gate } 18700Sstevel@tonic-gate 18710Sstevel@tonic-gate /* 18720Sstevel@tonic-gate * Allocate space for and return a pointer to a string 18730Sstevel@tonic-gate * on the stack. If the string is null, create 18740Sstevel@tonic-gate * an empty string. 18750Sstevel@tonic-gate * Use destroy_data() to free when no longer used. 18760Sstevel@tonic-gate */ 18770Sstevel@tonic-gate char * 18780Sstevel@tonic-gate alloc_string(s) 18790Sstevel@tonic-gate char *s; 18800Sstevel@tonic-gate { 18810Sstevel@tonic-gate char *ns; 18820Sstevel@tonic-gate 18830Sstevel@tonic-gate if (s == (char *)NULL) { 18840Sstevel@tonic-gate ns = (char *)my_zalloc(1); 18850Sstevel@tonic-gate } else { 18860Sstevel@tonic-gate ns = (char *)my_zalloc(strlen(s) + 1); 18870Sstevel@tonic-gate (void) strcpy(ns, s); 18880Sstevel@tonic-gate } 18890Sstevel@tonic-gate return (ns); 18900Sstevel@tonic-gate } 18910Sstevel@tonic-gate 18920Sstevel@tonic-gate /* 18930Sstevel@tonic-gate * Follow symbolic links from the logical device name to 18940Sstevel@tonic-gate * the /devfs physical device name. To be complete, we 18950Sstevel@tonic-gate * handle the case of multiple links. This function 18960Sstevel@tonic-gate * either returns NULL (no links, or some other error), 18970Sstevel@tonic-gate * or the physical device name, alloc'ed on the heap. 18980Sstevel@tonic-gate * 18990Sstevel@tonic-gate * Note that the standard /devices prefix is stripped from 19000Sstevel@tonic-gate * the final pathname, if present. The trailing options 19010Sstevel@tonic-gate * are also removed (":c, raw"). 19020Sstevel@tonic-gate */ 19030Sstevel@tonic-gate static char * 19040Sstevel@tonic-gate get_physical_name(char *path) 19050Sstevel@tonic-gate { 19060Sstevel@tonic-gate struct stat stbuf; 19070Sstevel@tonic-gate int i; 19080Sstevel@tonic-gate int level; 19090Sstevel@tonic-gate char *p; 19100Sstevel@tonic-gate char s[MAXPATHLEN]; 19110Sstevel@tonic-gate char buf[MAXPATHLEN]; 19120Sstevel@tonic-gate char dir[MAXPATHLEN]; 19130Sstevel@tonic-gate char savedir[MAXPATHLEN]; 19140Sstevel@tonic-gate char *result = NULL; 19150Sstevel@tonic-gate 19160Sstevel@tonic-gate if (getcwd(savedir, sizeof (savedir)) == NULL) { 19170Sstevel@tonic-gate DPRINTF1("getcwd() failed - %s\n", strerror(errno)); 19180Sstevel@tonic-gate return (NULL); 19190Sstevel@tonic-gate } 19200Sstevel@tonic-gate 19210Sstevel@tonic-gate (void) strcpy(s, path); 19220Sstevel@tonic-gate if ((p = strrchr(s, '/')) != NULL) { 19230Sstevel@tonic-gate *p = 0; 19240Sstevel@tonic-gate } 19250Sstevel@tonic-gate if (s[0] == 0) { 19260Sstevel@tonic-gate (void) strcpy(s, "/"); 19270Sstevel@tonic-gate } 19280Sstevel@tonic-gate if (chdir(s) == -1) { 19290Sstevel@tonic-gate DPRINTF2("cannot chdir() to %s - %s\n", 19300Sstevel@tonic-gate s, strerror(errno)); 19310Sstevel@tonic-gate goto exit; 19320Sstevel@tonic-gate } 19330Sstevel@tonic-gate 19340Sstevel@tonic-gate level = 0; 19350Sstevel@tonic-gate (void) strcpy(s, path); 19360Sstevel@tonic-gate for (;;) { 19370Sstevel@tonic-gate /* 19380Sstevel@tonic-gate * See if there's a real file out there. If not, 19390Sstevel@tonic-gate * we have a dangling link and we ignore it. 19400Sstevel@tonic-gate */ 19410Sstevel@tonic-gate if (stat(s, &stbuf) == -1) { 19420Sstevel@tonic-gate goto exit; 19430Sstevel@tonic-gate } 19440Sstevel@tonic-gate if (lstat(s, &stbuf) == -1) { 19450Sstevel@tonic-gate DPRINTF2("%s: lstat() failed - %s\n", 19460Sstevel@tonic-gate s, strerror(errno)); 19470Sstevel@tonic-gate goto exit; 19480Sstevel@tonic-gate } 19490Sstevel@tonic-gate /* 19500Sstevel@tonic-gate * If the file is not a link, we're done one 19510Sstevel@tonic-gate * way or the other. If there were links, 19520Sstevel@tonic-gate * return the full pathname of the resulting 19530Sstevel@tonic-gate * file. 19540Sstevel@tonic-gate */ 19550Sstevel@tonic-gate if (!S_ISLNK(stbuf.st_mode)) { 19560Sstevel@tonic-gate if (level > 0) { 19570Sstevel@tonic-gate /* 19580Sstevel@tonic-gate * Strip trailing options from the 19590Sstevel@tonic-gate * physical device name 19600Sstevel@tonic-gate */ 19610Sstevel@tonic-gate if ((p = strrchr(s, ':')) != NULL) { 19620Sstevel@tonic-gate *p = 0; 19630Sstevel@tonic-gate } 19640Sstevel@tonic-gate /* 19650Sstevel@tonic-gate * Get the current directory, and 19660Sstevel@tonic-gate * glue the pieces together. 19670Sstevel@tonic-gate */ 19680Sstevel@tonic-gate if (getcwd(dir, sizeof (dir)) == NULL) { 19690Sstevel@tonic-gate DPRINTF1("getcwd() failed - %s\n", 19700Sstevel@tonic-gate strerror(errno)); 19710Sstevel@tonic-gate goto exit; 19720Sstevel@tonic-gate } 19730Sstevel@tonic-gate (void) strcat(dir, "/"); 19740Sstevel@tonic-gate (void) strcat(dir, s); 19750Sstevel@tonic-gate /* 19760Sstevel@tonic-gate * If we have the standard fixed 19770Sstevel@tonic-gate * /devices prefix, remove it. 19780Sstevel@tonic-gate */ 19790Sstevel@tonic-gate p = (strstr(dir, DEVFS_PREFIX) == dir) ? 19800Sstevel@tonic-gate dir+strlen(DEVFS_PREFIX) : dir; 19810Sstevel@tonic-gate result = alloc_string(p); 19820Sstevel@tonic-gate } 19830Sstevel@tonic-gate goto exit; 19840Sstevel@tonic-gate } 19850Sstevel@tonic-gate i = readlink(s, buf, sizeof (buf)); 19860Sstevel@tonic-gate if (i == -1) { 19870Sstevel@tonic-gate DPRINTF2("%s: readlink() failed - %s\n", 19880Sstevel@tonic-gate s, strerror(errno)); 19890Sstevel@tonic-gate goto exit; 19900Sstevel@tonic-gate } 19910Sstevel@tonic-gate level++; 19920Sstevel@tonic-gate buf[i] = 0; 19930Sstevel@tonic-gate 19940Sstevel@tonic-gate /* 19950Sstevel@tonic-gate * Break up the pathname into the directory 19960Sstevel@tonic-gate * reference, if applicable and simple filename. 19970Sstevel@tonic-gate * chdir()'ing to the directory allows us to 19980Sstevel@tonic-gate * handle links with relative pathnames correctly. 19990Sstevel@tonic-gate */ 20000Sstevel@tonic-gate (void) strcpy(dir, buf); 20010Sstevel@tonic-gate if ((p = strrchr(dir, '/')) != NULL) { 20020Sstevel@tonic-gate *p = 0; 20030Sstevel@tonic-gate if (chdir(dir) == -1) { 20040Sstevel@tonic-gate DPRINTF2("cannot chdir() to %s - %s\n", 20050Sstevel@tonic-gate dir, strerror(errno)); 20060Sstevel@tonic-gate goto exit; 20070Sstevel@tonic-gate } 20080Sstevel@tonic-gate (void) strcpy(s, p+1); 20090Sstevel@tonic-gate } else { 20100Sstevel@tonic-gate (void) strcpy(s, buf); 20110Sstevel@tonic-gate } 20120Sstevel@tonic-gate } 20130Sstevel@tonic-gate 20140Sstevel@tonic-gate exit: 20150Sstevel@tonic-gate if (chdir(savedir) == -1) { 20160Sstevel@tonic-gate (void) printf("cannot chdir() to %s - %s\n", 20170Sstevel@tonic-gate savedir, strerror(errno)); 20180Sstevel@tonic-gate } 20190Sstevel@tonic-gate 20200Sstevel@tonic-gate return (result); 20210Sstevel@tonic-gate } 20220Sstevel@tonic-gate 20230Sstevel@tonic-gate static void 20240Sstevel@tonic-gate get_media_info(device_t *t_dev, char *sdev, char *pname, char *sn) 20250Sstevel@tonic-gate { 20260Sstevel@tonic-gate struct dk_cinfo cinfo; 20270Sstevel@tonic-gate struct vtoc vtocinfo; 20280Sstevel@tonic-gate float size; 20290Sstevel@tonic-gate int32_t fd; 20300Sstevel@tonic-gate smedia_handle_t handle; 20310Sstevel@tonic-gate struct dk_minfo mediainfo; 20320Sstevel@tonic-gate int device_type; 20330Sstevel@tonic-gate 20340Sstevel@tonic-gate device_type = ioctl(t_dev->d_fd, DKIOCGMEDIAINFO, &mediainfo); 20350Sstevel@tonic-gate 20360Sstevel@tonic-gate /* 20370Sstevel@tonic-gate * Determine bus type. 20380Sstevel@tonic-gate */ 20390Sstevel@tonic-gate if (!ioctl(t_dev->d_fd, DKIOCINFO, &cinfo)) { 20400Sstevel@tonic-gate if (strstr(cinfo.dki_cname, "usb") || strstr(pname, "usb")) { 20410Sstevel@tonic-gate (void) printf("\tBus: USB\n"); 20420Sstevel@tonic-gate } else if (strstr(cinfo.dki_cname, "firewire") || 20430Sstevel@tonic-gate strstr(pname, "firewire")) { 20440Sstevel@tonic-gate (void) printf("\tBus: Firewire\n"); 20450Sstevel@tonic-gate } else if (strstr(cinfo.dki_cname, "ide") || 20460Sstevel@tonic-gate strstr(pname, "ide")) { 20470Sstevel@tonic-gate (void) printf("\tBus: IDE\n"); 20480Sstevel@tonic-gate } else if (strstr(cinfo.dki_cname, "scsi") || 20490Sstevel@tonic-gate strstr(pname, "scsi")) { 20500Sstevel@tonic-gate (void) printf("\tBus: SCSI\n"); 20510Sstevel@tonic-gate } else { 20520Sstevel@tonic-gate (void) printf("\tBus: <Unknown>\n"); 20530Sstevel@tonic-gate } 20540Sstevel@tonic-gate } else { 20550Sstevel@tonic-gate (void) printf("\tBus: <Unknown>\n"); 20560Sstevel@tonic-gate } 20570Sstevel@tonic-gate 20580Sstevel@tonic-gate /* 20590Sstevel@tonic-gate * Calculate size of media. 20600Sstevel@tonic-gate */ 20610Sstevel@tonic-gate if (!device_type && 20620Sstevel@tonic-gate (!ioctl(t_dev->d_fd, DKIOCGMEDIAINFO, &mediainfo))) { 20630Sstevel@tonic-gate size = (mediainfo.dki_lbsize* 20640Sstevel@tonic-gate mediainfo.dki_capacity)/(1024.0*1024.0); 20650Sstevel@tonic-gate if (size < 1000) { 20660Sstevel@tonic-gate (void) printf("\tSize: %.1f MB\n", size); 20670Sstevel@tonic-gate } else { 20680Sstevel@tonic-gate size = size/1000; 20690Sstevel@tonic-gate (void) printf("\tSize: %.1f GB\n", size); 20700Sstevel@tonic-gate } 20710Sstevel@tonic-gate } else { 20720Sstevel@tonic-gate (void) printf("\tSize: <Unknown>\n"); 20730Sstevel@tonic-gate } 20740Sstevel@tonic-gate 20750Sstevel@tonic-gate /* 20760Sstevel@tonic-gate * Print label. 20770Sstevel@tonic-gate */ 20780Sstevel@tonic-gate if (!device_type && (!ioctl(t_dev->d_fd, DKIOCGVTOC, &vtocinfo))) { 20790Sstevel@tonic-gate if (*vtocinfo.v_volume) { 20800Sstevel@tonic-gate (void) printf("\tLabel: %s\n", vtocinfo.v_volume); 20810Sstevel@tonic-gate } else { 20820Sstevel@tonic-gate (void) printf("\tLabel: <None>\n"); 20830Sstevel@tonic-gate } 20840Sstevel@tonic-gate } else { 20850Sstevel@tonic-gate (void) printf("\tLabel: <Unknown>\n"); 20860Sstevel@tonic-gate } 20870Sstevel@tonic-gate 20880Sstevel@tonic-gate /* 20890Sstevel@tonic-gate * Acess permissions. 20900Sstevel@tonic-gate */ 20910Sstevel@tonic-gate if (device_type) { 20920Sstevel@tonic-gate (void) printf("\tAccess permissions: <Unknown>\n"); 20930Sstevel@tonic-gate return; 20940Sstevel@tonic-gate } 20950Sstevel@tonic-gate 20960Sstevel@tonic-gate (void) fprintf(stderr, gettext("\tAccess permissions: ")); 20970Sstevel@tonic-gate if (sn) { 20980Sstevel@tonic-gate /* 20990Sstevel@tonic-gate * Set dev_name for process_p_flag(). 21000Sstevel@tonic-gate */ 21010Sstevel@tonic-gate dev_name = sn; 21020Sstevel@tonic-gate fd = my_open(sn, O_RDONLY|O_NDELAY); 21030Sstevel@tonic-gate } else { 21040Sstevel@tonic-gate dev_name = sdev; 21050Sstevel@tonic-gate fd = my_open(sdev, O_RDONLY|O_NDELAY); 21060Sstevel@tonic-gate } 21070Sstevel@tonic-gate if (fd < 0) { 21080Sstevel@tonic-gate (void) printf("<Unknown>\n"); 21090Sstevel@tonic-gate DPRINTF("Could not open device.\n"); 21100Sstevel@tonic-gate (void) close(fd); 21110Sstevel@tonic-gate } else { 21120Sstevel@tonic-gate /* register the fd with the libsmedia */ 21130Sstevel@tonic-gate handle = smedia_get_handle(fd); 21140Sstevel@tonic-gate if (handle == NULL) { 21150Sstevel@tonic-gate (void) printf("<Unknown>\n"); 21160Sstevel@tonic-gate DPRINTF("Failed to get libsmedia handle.\n"); 21170Sstevel@tonic-gate (void) close(fd); 21180Sstevel@tonic-gate } else { 21190Sstevel@tonic-gate process_p_flag(handle, fd); 21200Sstevel@tonic-gate } 21210Sstevel@tonic-gate } 21221375Sphitran /* Clear dev_name */ 21231375Sphitran dev_name = NULL; 21240Sstevel@tonic-gate } 2125