17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5e3397557Szk194757 * Common Development and Distribution License (the "License"). 6e3397557Szk194757 * You may not use this file except in compliance with the License. 77c478bd9Sstevel@tonic-gate * 87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 117c478bd9Sstevel@tonic-gate * and limitations under the License. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 187c478bd9Sstevel@tonic-gate * 197c478bd9Sstevel@tonic-gate * CDDL HEADER END 207c478bd9Sstevel@tonic-gate */ 21342440ecSPrasad Singamsetty 227c478bd9Sstevel@tonic-gate /* 23*afb89a98SPavel Potoplyak * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate */ 267c478bd9Sstevel@tonic-gate 277c478bd9Sstevel@tonic-gate /* 287c478bd9Sstevel@tonic-gate * rmf_misc.c : 297c478bd9Sstevel@tonic-gate * Miscelleneous routines for rmformat. 307c478bd9Sstevel@tonic-gate */ 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate #include <sys/types.h> 337c478bd9Sstevel@tonic-gate #include <stdio.h> 347c478bd9Sstevel@tonic-gate #include <sys/mnttab.h> 357c478bd9Sstevel@tonic-gate #include <volmgt.h> 367c478bd9Sstevel@tonic-gate #include <sys/dkio.h> 377c478bd9Sstevel@tonic-gate #include <sys/fdio.h> 387c478bd9Sstevel@tonic-gate #include <sys/vtoc.h> 397c478bd9Sstevel@tonic-gate #include <sys/termios.h> 407c478bd9Sstevel@tonic-gate #include <sys/mount.h> 417c478bd9Sstevel@tonic-gate #include <ctype.h> 427c478bd9Sstevel@tonic-gate #include <signal.h> 437c478bd9Sstevel@tonic-gate #include <sys/wait.h> 447c478bd9Sstevel@tonic-gate #include <dirent.h> 45bbed02dfSzk194757 #include <priv_utils.h> 467c478bd9Sstevel@tonic-gate #include <stdarg.h> 477c478bd9Sstevel@tonic-gate #include "rmformat.h" 487c478bd9Sstevel@tonic-gate 497c478bd9Sstevel@tonic-gate /* 507c478bd9Sstevel@tonic-gate * Definitions. 517c478bd9Sstevel@tonic-gate */ 527c478bd9Sstevel@tonic-gate #define SENSE_KEY(rqbuf) (rqbuf[2] & 0xf) /* scsi error category */ 537c478bd9Sstevel@tonic-gate #define ASC(rqbuf) (rqbuf[12]) /* additional sense code */ 547c478bd9Sstevel@tonic-gate #define ASCQ(rqbuf) (rqbuf[13]) /* ASC qualifier */ 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #define DEFAULT_SCSI_TIMEOUT 60 577c478bd9Sstevel@tonic-gate #define INQUIRY_CMD 0x12 587c478bd9Sstevel@tonic-gate #define RQBUFLEN 32 597c478bd9Sstevel@tonic-gate #define CD_RW 1 /* CD_RW/CD-R */ 607c478bd9Sstevel@tonic-gate #define WRITE_10_CMD 0x2A 617c478bd9Sstevel@tonic-gate #define READ_INFO_CMD 0x51 627c478bd9Sstevel@tonic-gate #define SYNC_CACHE_CMD 0x35 637c478bd9Sstevel@tonic-gate #define CLOSE_TRACK_CMD 0x5B 647c478bd9Sstevel@tonic-gate #define MODE_SENSE_10_CMD 0x5A 657c478bd9Sstevel@tonic-gate #define DEVFS_PREFIX "/devices" 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate int uscsi_error; /* used for debugging failed uscsi */ 687c478bd9Sstevel@tonic-gate char rqbuf[RQBUFLEN]; 697c478bd9Sstevel@tonic-gate static uint_t total_retries; 707c478bd9Sstevel@tonic-gate static struct uscsi_cmd uscmd; 717c478bd9Sstevel@tonic-gate static char ucdb[16]; 727c478bd9Sstevel@tonic-gate uchar_t uscsi_status, rqstatus, rqresid; 737c478bd9Sstevel@tonic-gate int total_devices_found = 0; 747c478bd9Sstevel@tonic-gate int removable_found = 0; 757c478bd9Sstevel@tonic-gate 767c478bd9Sstevel@tonic-gate extern char *global_intr_msg; 777c478bd9Sstevel@tonic-gate extern int vol_running; 787c478bd9Sstevel@tonic-gate extern char *dev_name; 797c478bd9Sstevel@tonic-gate extern int32_t m_flag; 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate /* 827c478bd9Sstevel@tonic-gate * ON-private functions from libvolmgt 837c478bd9Sstevel@tonic-gate */ 847c478bd9Sstevel@tonic-gate int _dev_mounted(char *path); 857c478bd9Sstevel@tonic-gate 867c478bd9Sstevel@tonic-gate /* 877c478bd9Sstevel@tonic-gate * Function prototypes. 887c478bd9Sstevel@tonic-gate */ 897c478bd9Sstevel@tonic-gate static int my_umount(char *mountp); 907c478bd9Sstevel@tonic-gate static int my_volrmmount(char *real_name); 917c478bd9Sstevel@tonic-gate static int vol_name_to_dev_node(char *vname, char *found); 927c478bd9Sstevel@tonic-gate static int vol_lookup(char *supplied, char *found); 937c478bd9Sstevel@tonic-gate static device_t *get_device(char *user_supplied, char *node); 947c478bd9Sstevel@tonic-gate static char *get_physical_name(char *path); 957c478bd9Sstevel@tonic-gate static int lookup_device(char *supplied, char *found); 967c478bd9Sstevel@tonic-gate static void fini_device(device_t *dev); 977c478bd9Sstevel@tonic-gate static int is_cd(char *node); 987c478bd9Sstevel@tonic-gate void *my_zalloc(size_t size); 997c478bd9Sstevel@tonic-gate void err_msg(char *fmt, ...); 1007c478bd9Sstevel@tonic-gate int inquiry(int fd, uchar_t *inq); 1017c478bd9Sstevel@tonic-gate struct uscsi_cmd *get_uscsi_cmd(void); 1027c478bd9Sstevel@tonic-gate int uscsi(int fd, struct uscsi_cmd *scmd); 1037c478bd9Sstevel@tonic-gate int get_mode_page(int fd, int page_no, int pc, int buf_len, 1047c478bd9Sstevel@tonic-gate uchar_t *buffer); 1057c478bd9Sstevel@tonic-gate int mode_sense(int fd, uchar_t pc, int dbd, int page_len, 1067c478bd9Sstevel@tonic-gate uchar_t *buffer); 1077c478bd9Sstevel@tonic-gate uint16_t read_scsi16(void *addr); 1087c478bd9Sstevel@tonic-gate int check_device(device_t *dev, int cond); 1097c478bd9Sstevel@tonic-gate static void get_media_info(device_t *t_dev, char *sdev, 1107c478bd9Sstevel@tonic-gate char *pname, char *sn); 1117c478bd9Sstevel@tonic-gate 1127c478bd9Sstevel@tonic-gate extern void process_p_flag(smedia_handle_t handle, int32_t fd); 1137c478bd9Sstevel@tonic-gate 1147c478bd9Sstevel@tonic-gate void 1157c478bd9Sstevel@tonic-gate my_perror(char *err_string) 1167c478bd9Sstevel@tonic-gate { 1177c478bd9Sstevel@tonic-gate 1187c478bd9Sstevel@tonic-gate int error_no; 1197c478bd9Sstevel@tonic-gate if (errno == 0) 1207c478bd9Sstevel@tonic-gate return; 1217c478bd9Sstevel@tonic-gate 1227c478bd9Sstevel@tonic-gate error_no = errno; 1237c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s", err_string); 1247c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(" : ")); 1257c478bd9Sstevel@tonic-gate errno = error_no; 1267c478bd9Sstevel@tonic-gate perror(""); 1277c478bd9Sstevel@tonic-gate } 1287c478bd9Sstevel@tonic-gate 1297c478bd9Sstevel@tonic-gate int32_t 1307c478bd9Sstevel@tonic-gate get_confirmation() 1317c478bd9Sstevel@tonic-gate { 1327c478bd9Sstevel@tonic-gate char c; 1337c478bd9Sstevel@tonic-gate 1347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Do you want to continue? (y/n)")); 1357c478bd9Sstevel@tonic-gate c = getchar(); 1367c478bd9Sstevel@tonic-gate if (c == 'y' || c == 'Y') 1377c478bd9Sstevel@tonic-gate return (1); 1387c478bd9Sstevel@tonic-gate else if (c == 'n' || c == 'N') 1397c478bd9Sstevel@tonic-gate return (0); 1407c478bd9Sstevel@tonic-gate else { 1417c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Invalid choice\n")); 1427c478bd9Sstevel@tonic-gate return (0); 1437c478bd9Sstevel@tonic-gate } 1447c478bd9Sstevel@tonic-gate } 1457c478bd9Sstevel@tonic-gate 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate void 1487c478bd9Sstevel@tonic-gate get_passwd(struct smwp_state *wp, int32_t confirm) 1497c478bd9Sstevel@tonic-gate { 1507c478bd9Sstevel@tonic-gate char passwd[256], re_passwd[256]; 1517c478bd9Sstevel@tonic-gate int32_t len; 1527c478bd9Sstevel@tonic-gate struct termios tio; 1537c478bd9Sstevel@tonic-gate int32_t echo_off = 0; 1547c478bd9Sstevel@tonic-gate FILE *in, *out; 1557c478bd9Sstevel@tonic-gate char *buf; 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate 1587c478bd9Sstevel@tonic-gate in = fopen("/dev/tty", "r+"); 1597c478bd9Sstevel@tonic-gate if (in == NULL) { 1607c478bd9Sstevel@tonic-gate in = stdin; 1617c478bd9Sstevel@tonic-gate out = stderr; 1627c478bd9Sstevel@tonic-gate } else { 1637c478bd9Sstevel@tonic-gate out = in; 1647c478bd9Sstevel@tonic-gate } 1657c478bd9Sstevel@tonic-gate 1667c478bd9Sstevel@tonic-gate /* Turn echoing off if it is on now. */ 1677c478bd9Sstevel@tonic-gate 1687c478bd9Sstevel@tonic-gate if (tcgetattr(fileno(in), &tio) < 0) { 1697c478bd9Sstevel@tonic-gate PERROR("Echo off ioctl failed"); 1707c478bd9Sstevel@tonic-gate exit(1); 1717c478bd9Sstevel@tonic-gate } 1727c478bd9Sstevel@tonic-gate if (tio.c_lflag & ECHO) { 1737c478bd9Sstevel@tonic-gate tio.c_lflag &= ~ECHO; 1747c478bd9Sstevel@tonic-gate /* echo_off = tcsetattr(fileno(in), TCSAFLUSH, &tio) == 0; */ 1757c478bd9Sstevel@tonic-gate echo_off = tcsetattr(fileno(in), TCSAFLUSH, &tio) == 0; 1767c478bd9Sstevel@tonic-gate tio.c_lflag |= ECHO; 1777c478bd9Sstevel@tonic-gate } 1787c478bd9Sstevel@tonic-gate 1797c478bd9Sstevel@tonic-gate /* CONSTCOND */ 1807c478bd9Sstevel@tonic-gate while (1) { 1817c478bd9Sstevel@tonic-gate (void) fputs( 1827c478bd9Sstevel@tonic-gate gettext("Please enter password (32 chars maximum):"), 1837c478bd9Sstevel@tonic-gate out); 1847c478bd9Sstevel@tonic-gate (void) fflush(out); 1857c478bd9Sstevel@tonic-gate buf = fgets(passwd, (size_t)256, in); 1867c478bd9Sstevel@tonic-gate rewind(in); 1877c478bd9Sstevel@tonic-gate if (buf == NULL) { 1887c478bd9Sstevel@tonic-gate PERROR("Error reading password"); 1897c478bd9Sstevel@tonic-gate continue; 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate len = strlen(passwd); 1927c478bd9Sstevel@tonic-gate (void) fputc('\n', out); 1937c478bd9Sstevel@tonic-gate len--; /* To offset the \n */ 1947c478bd9Sstevel@tonic-gate if ((len <= 0) || (len > 32)) { 1957c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 1967c478bd9Sstevel@tonic-gate gettext("Invalid length of password \n")); 1977c478bd9Sstevel@tonic-gate (void) fputs("Try again\n", out); 1987c478bd9Sstevel@tonic-gate continue; 1997c478bd9Sstevel@tonic-gate } 2007c478bd9Sstevel@tonic-gate 2017c478bd9Sstevel@tonic-gate if (!confirm) 2027c478bd9Sstevel@tonic-gate break; 2037c478bd9Sstevel@tonic-gate 2047c478bd9Sstevel@tonic-gate (void) fputs("Please reenter password:", out); 2057c478bd9Sstevel@tonic-gate (void) fflush(out); 2067c478bd9Sstevel@tonic-gate buf = fgets(re_passwd, (size_t)256, in); 2077c478bd9Sstevel@tonic-gate rewind(in); 2087c478bd9Sstevel@tonic-gate (void) fputc('\n', out); 2097c478bd9Sstevel@tonic-gate if ((buf == NULL) || strcmp(passwd, re_passwd)) { 2107c478bd9Sstevel@tonic-gate (void) fputs("passwords did not match\n", out); 2117c478bd9Sstevel@tonic-gate (void) fputs("Try again\n", out); 2127c478bd9Sstevel@tonic-gate } else { 2137c478bd9Sstevel@tonic-gate break; 2147c478bd9Sstevel@tonic-gate } 2157c478bd9Sstevel@tonic-gate } 2167c478bd9Sstevel@tonic-gate wp->sm_passwd_len = len; 2177c478bd9Sstevel@tonic-gate (void) strncpy(wp->sm_passwd, passwd, wp->sm_passwd_len); 2187c478bd9Sstevel@tonic-gate wp->sm_version = SMWP_STATE_V_1; 2197c478bd9Sstevel@tonic-gate 2207c478bd9Sstevel@tonic-gate /* Restore echoing. */ 2217c478bd9Sstevel@tonic-gate if (echo_off) 2227c478bd9Sstevel@tonic-gate (void) tcsetattr(fileno(in), TCSAFLUSH, &tio); 2237c478bd9Sstevel@tonic-gate 2247c478bd9Sstevel@tonic-gate } 2257c478bd9Sstevel@tonic-gate 2267c478bd9Sstevel@tonic-gate int32_t 2277c478bd9Sstevel@tonic-gate check_and_unmount_vold(char *device_name, int32_t flag) 2287c478bd9Sstevel@tonic-gate { 2297c478bd9Sstevel@tonic-gate char *real_name; 2307c478bd9Sstevel@tonic-gate char *nm; 2317c478bd9Sstevel@tonic-gate char tmp_path_name[PATH_MAX]; 2327c478bd9Sstevel@tonic-gate struct stat stat_buf; 2337c478bd9Sstevel@tonic-gate int32_t ret_val = 0; 2347c478bd9Sstevel@tonic-gate struct mnttab *mntp; 2357c478bd9Sstevel@tonic-gate FILE *fp; 2367c478bd9Sstevel@tonic-gate int nl; 2377c478bd9Sstevel@tonic-gate 2387c478bd9Sstevel@tonic-gate DPRINTF1("Device name %s\n", device_name); 2397c478bd9Sstevel@tonic-gate 2407c478bd9Sstevel@tonic-gate if (volmgt_running() == 0) { 2417c478bd9Sstevel@tonic-gate DPRINTF("Vold not running\n"); 2427c478bd9Sstevel@tonic-gate return (0); 2437c478bd9Sstevel@tonic-gate } 2447c478bd9Sstevel@tonic-gate if ((nm = volmgt_symname(device_name)) == NULL) { 2457c478bd9Sstevel@tonic-gate DPRINTF("path not managed\n"); 2467c478bd9Sstevel@tonic-gate real_name = media_findname(device_name); 2477c478bd9Sstevel@tonic-gate } else { 2487c478bd9Sstevel@tonic-gate DPRINTF1("path managed as %s\n", nm); 2497c478bd9Sstevel@tonic-gate real_name = media_findname(nm); 2507c478bd9Sstevel@tonic-gate DPRINTF1("real name %s\n", real_name); 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate 2537c478bd9Sstevel@tonic-gate if (real_name == NULL) 2547c478bd9Sstevel@tonic-gate return (-1); 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate /* 2577c478bd9Sstevel@tonic-gate * To find out whether the device has been mounted by 2587c478bd9Sstevel@tonic-gate * volume manager... 2597c478bd9Sstevel@tonic-gate * 2607c478bd9Sstevel@tonic-gate * Convert the real name to a block device address. 2617c478bd9Sstevel@tonic-gate * Do a partial match with the mnttab entries. 2627c478bd9Sstevel@tonic-gate * Make sure the match is in the beginning to avoid if 2637c478bd9Sstevel@tonic-gate * anybody puts a label similiar to volume manager path names. 2647c478bd9Sstevel@tonic-gate * Then use "volrmmount -e <dev_name>" if -U flag is set. 2657c478bd9Sstevel@tonic-gate */ 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate nl = strlen("/vol/dev/"); 2687c478bd9Sstevel@tonic-gate 2697c478bd9Sstevel@tonic-gate if (strncmp(real_name, "/vol/dev/", nl) != 0) 2707c478bd9Sstevel@tonic-gate return (0); 2717c478bd9Sstevel@tonic-gate if (real_name[nl] == 'r') { 2727c478bd9Sstevel@tonic-gate (void) snprintf(tmp_path_name, PATH_MAX, "%s%s", "/vol/dev/", 2737c478bd9Sstevel@tonic-gate &real_name[nl + 1]); 2747c478bd9Sstevel@tonic-gate } else { 2757c478bd9Sstevel@tonic-gate (void) snprintf(tmp_path_name, PATH_MAX, "%s", real_name); 2767c478bd9Sstevel@tonic-gate } 2777c478bd9Sstevel@tonic-gate DPRINTF1("%s \n", tmp_path_name); 2787c478bd9Sstevel@tonic-gate ret_val = stat(tmp_path_name, &stat_buf); 2797c478bd9Sstevel@tonic-gate if (ret_val < 0) { 2807c478bd9Sstevel@tonic-gate PERROR("Could not stat"); 2817c478bd9Sstevel@tonic-gate return (-1); 2827c478bd9Sstevel@tonic-gate } 2837c478bd9Sstevel@tonic-gate 2847c478bd9Sstevel@tonic-gate fp = fopen("/etc/mnttab", "r"); 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate if (fp == NULL) { 2877c478bd9Sstevel@tonic-gate PERROR("Could not open /etc/mnttab"); 2887c478bd9Sstevel@tonic-gate return (-1); 2897c478bd9Sstevel@tonic-gate } 2907c478bd9Sstevel@tonic-gate 2917c478bd9Sstevel@tonic-gate mntp = (struct mnttab *)malloc(sizeof (struct mnttab)); 2927c478bd9Sstevel@tonic-gate if (mntp == NULL) { 2937c478bd9Sstevel@tonic-gate PERROR("malloc failed"); 2947c478bd9Sstevel@tonic-gate (void) fclose(fp); 2957c478bd9Sstevel@tonic-gate return (-1); 2967c478bd9Sstevel@tonic-gate } 2977c478bd9Sstevel@tonic-gate errno = 0; 2987c478bd9Sstevel@tonic-gate while (getmntent(fp, mntp) == 0) { 2997c478bd9Sstevel@tonic-gate if (errno != 0) { 3007c478bd9Sstevel@tonic-gate PERROR("Error with mnttab"); 3017c478bd9Sstevel@tonic-gate (void) fclose(fp); 3027c478bd9Sstevel@tonic-gate return (-1); 3037c478bd9Sstevel@tonic-gate } 3047c478bd9Sstevel@tonic-gate /* Is it a probable entry? */ 3057c478bd9Sstevel@tonic-gate DPRINTF1(" %s \n", mntp->mnt_special); 3067c478bd9Sstevel@tonic-gate if (strstr(mntp->mnt_special, tmp_path_name) != 3077c478bd9Sstevel@tonic-gate mntp->mnt_special) { 3087c478bd9Sstevel@tonic-gate /* Skip to next entry */ 3097c478bd9Sstevel@tonic-gate continue; 3107c478bd9Sstevel@tonic-gate } else { 3117c478bd9Sstevel@tonic-gate DPRINTF1("Found!! %s\n", mntp->mnt_special); 3127c478bd9Sstevel@tonic-gate ret_val = 1; 3137c478bd9Sstevel@tonic-gate break; 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate if (ret_val == 1) { 3187c478bd9Sstevel@tonic-gate if (flag) { 3197c478bd9Sstevel@tonic-gate if (my_volrmmount(real_name) < 0) { 3207c478bd9Sstevel@tonic-gate ret_val = -1; 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate } else { 3237c478bd9Sstevel@tonic-gate ret_val = -1; 3247c478bd9Sstevel@tonic-gate } 3257c478bd9Sstevel@tonic-gate } 3267c478bd9Sstevel@tonic-gate (void) fclose(fp); 3277c478bd9Sstevel@tonic-gate free(mntp); 3287c478bd9Sstevel@tonic-gate return (ret_val); 3297c478bd9Sstevel@tonic-gate } 3307c478bd9Sstevel@tonic-gate 3317c478bd9Sstevel@tonic-gate /* 3327c478bd9Sstevel@tonic-gate * This routine checks if a device has mounted partitions. The 3337c478bd9Sstevel@tonic-gate * device name is assumed to be /dev/rdsk/cNtNdNsN. So, this can 3347c478bd9Sstevel@tonic-gate * be used for SCSI and PCMCIA cards. 3357c478bd9Sstevel@tonic-gate * Returns 3367c478bd9Sstevel@tonic-gate * 0 : if not mounted 3377c478bd9Sstevel@tonic-gate * 1 : if successfully unmounted 3387c478bd9Sstevel@tonic-gate * -1 : Any error or umount failed 3397c478bd9Sstevel@tonic-gate */ 3407c478bd9Sstevel@tonic-gate 3417c478bd9Sstevel@tonic-gate int32_t 3427c478bd9Sstevel@tonic-gate check_and_unmount_scsi(char *device_name, int32_t flag) 3437c478bd9Sstevel@tonic-gate { 3447c478bd9Sstevel@tonic-gate 3457c478bd9Sstevel@tonic-gate struct mnttab *mntrefp; 3467c478bd9Sstevel@tonic-gate struct mnttab *mntp; 3477c478bd9Sstevel@tonic-gate FILE *fp; 3487c478bd9Sstevel@tonic-gate char block_dev_name[PATH_MAX]; 3497c478bd9Sstevel@tonic-gate char tmp_name[PATH_MAX]; 3507c478bd9Sstevel@tonic-gate int32_t i, j; 3517c478bd9Sstevel@tonic-gate int32_t unmounted = 0; 3527c478bd9Sstevel@tonic-gate 3537c478bd9Sstevel@tonic-gate /* 3547c478bd9Sstevel@tonic-gate * If the device name is not a character special, anyway we 3557c478bd9Sstevel@tonic-gate * can not progress further 3567c478bd9Sstevel@tonic-gate */ 3577c478bd9Sstevel@tonic-gate 3587c478bd9Sstevel@tonic-gate if (strncmp(device_name, "/dev/rdsk/c", strlen("/dev/rdsk/c")) != 0) 3597c478bd9Sstevel@tonic-gate return (0); 3607c478bd9Sstevel@tonic-gate 3617c478bd9Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, "/dev/%s", 3627c478bd9Sstevel@tonic-gate &device_name[strlen("/dev/r")]); 3637c478bd9Sstevel@tonic-gate fp = fopen("/etc/mnttab", "r"); 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate if (fp == NULL) { 3667c478bd9Sstevel@tonic-gate PERROR("Could not open /etc/mnttab"); 3677c478bd9Sstevel@tonic-gate return (-1); 3687c478bd9Sstevel@tonic-gate } 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate mntrefp = (struct mnttab *)malloc(sizeof (struct mnttab)); 3717c478bd9Sstevel@tonic-gate if (mntrefp == NULL) { 3727c478bd9Sstevel@tonic-gate PERROR("malloc failed"); 3737c478bd9Sstevel@tonic-gate (void) fclose(fp); 3747c478bd9Sstevel@tonic-gate return (-1); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate 3777c478bd9Sstevel@tonic-gate mntp = (struct mnttab *)malloc(sizeof (struct mnttab)); 3787c478bd9Sstevel@tonic-gate if (mntp == NULL) { 3797c478bd9Sstevel@tonic-gate PERROR("malloc failed"); 3807c478bd9Sstevel@tonic-gate (void) fclose(fp); 3817c478bd9Sstevel@tonic-gate free(mntrefp); 3827c478bd9Sstevel@tonic-gate return (-1); 3837c478bd9Sstevel@tonic-gate } 3847c478bd9Sstevel@tonic-gate 3857c478bd9Sstevel@tonic-gate /* Try all the partitions */ 3867c478bd9Sstevel@tonic-gate 3877c478bd9Sstevel@tonic-gate (void) snprintf(tmp_name, PATH_MAX, "/dev/%s", 3887c478bd9Sstevel@tonic-gate &device_name[strlen("/dev/r")]); 3897c478bd9Sstevel@tonic-gate 3907c478bd9Sstevel@tonic-gate tmp_name[strlen("/dev/dsk/c0t0d0s")] = '\0'; 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate errno = 0; 3937c478bd9Sstevel@tonic-gate while (getmntent(fp, mntp) == 0) { 3947c478bd9Sstevel@tonic-gate if (errno != 0) { 3957c478bd9Sstevel@tonic-gate PERROR("Error with mnttab"); 3967c478bd9Sstevel@tonic-gate (void) fclose(fp); 3977c478bd9Sstevel@tonic-gate return (-1); 3987c478bd9Sstevel@tonic-gate } 3997c478bd9Sstevel@tonic-gate /* Is it a probable entry? */ 4007c478bd9Sstevel@tonic-gate if (strncmp(mntp->mnt_special, tmp_name, strlen(tmp_name))) { 4017c478bd9Sstevel@tonic-gate /* Skip to next entry */ 4027c478bd9Sstevel@tonic-gate continue; 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate for (i = 0; i < NDKMAP; i++) { 4057c478bd9Sstevel@tonic-gate /* Check for ufs style mount devices */ 4067c478bd9Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, 4077c478bd9Sstevel@tonic-gate "%s%d", tmp_name, i); 4087c478bd9Sstevel@tonic-gate 4097c478bd9Sstevel@tonic-gate if (strcmp(mntp->mnt_special, block_dev_name) == 0) { 4107c478bd9Sstevel@tonic-gate if (flag) { 4117c478bd9Sstevel@tonic-gate if (my_umount(mntp->mnt_mountp) < 0) { 4127c478bd9Sstevel@tonic-gate (void) fclose(fp); 4137c478bd9Sstevel@tonic-gate return (-1); 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate unmounted = 1; 4167c478bd9Sstevel@tonic-gate } else { 4177c478bd9Sstevel@tonic-gate (void) fclose(fp); 4187c478bd9Sstevel@tonic-gate return (-1); 4197c478bd9Sstevel@tonic-gate } 4207c478bd9Sstevel@tonic-gate /* Skip to next entry */ 4217c478bd9Sstevel@tonic-gate continue; 4227c478bd9Sstevel@tonic-gate } 4237c478bd9Sstevel@tonic-gate 4247c478bd9Sstevel@tonic-gate /* Try for :1 -> :24 for pcfs */ 4257c478bd9Sstevel@tonic-gate 4267c478bd9Sstevel@tonic-gate for (j = 1; j < 24; j++) { 4277c478bd9Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, 4287c478bd9Sstevel@tonic-gate "%s%d:%d", tmp_name, i, j); 4297c478bd9Sstevel@tonic-gate 4307c478bd9Sstevel@tonic-gate if (strcmp(mntp->mnt_special, 4317c478bd9Sstevel@tonic-gate block_dev_name) == 0) { 4327c478bd9Sstevel@tonic-gate if (flag) { 4337c478bd9Sstevel@tonic-gate if (my_umount(mntp->mnt_mountp) 4347c478bd9Sstevel@tonic-gate < 0) { 4357c478bd9Sstevel@tonic-gate (void) fclose(fp); 4367c478bd9Sstevel@tonic-gate return (-1); 4377c478bd9Sstevel@tonic-gate } 4387c478bd9Sstevel@tonic-gate unmounted = 1; 4397c478bd9Sstevel@tonic-gate } else { 4407c478bd9Sstevel@tonic-gate (void) fclose(fp); 4417c478bd9Sstevel@tonic-gate return (-1); 4427c478bd9Sstevel@tonic-gate } 4437c478bd9Sstevel@tonic-gate /* Skip to next entry */ 4447c478bd9Sstevel@tonic-gate continue; 4457c478bd9Sstevel@tonic-gate } 4467c478bd9Sstevel@tonic-gate (void) snprintf(block_dev_name, PATH_MAX, 4477c478bd9Sstevel@tonic-gate "%s%d:%c", tmp_name, i, 'b' + j); 4487c478bd9Sstevel@tonic-gate 4497c478bd9Sstevel@tonic-gate if (strcmp(mntp->mnt_special, 4507c478bd9Sstevel@tonic-gate block_dev_name) == 0) { 4517c478bd9Sstevel@tonic-gate if (flag) { 4527c478bd9Sstevel@tonic-gate if (my_umount(mntp->mnt_mountp) 4537c478bd9Sstevel@tonic-gate < 0) { 4547c478bd9Sstevel@tonic-gate (void) fclose(fp); 4557c478bd9Sstevel@tonic-gate return (-1); 4567c478bd9Sstevel@tonic-gate } 4577c478bd9Sstevel@tonic-gate unmounted = 1; 4587c478bd9Sstevel@tonic-gate } else { 4597c478bd9Sstevel@tonic-gate (void) fclose(fp); 4607c478bd9Sstevel@tonic-gate return (-1); 4617c478bd9Sstevel@tonic-gate } 4627c478bd9Sstevel@tonic-gate /* Skip to next entry */ 4637c478bd9Sstevel@tonic-gate continue; 4647c478bd9Sstevel@tonic-gate } 4657c478bd9Sstevel@tonic-gate } 4667c478bd9Sstevel@tonic-gate } 4677c478bd9Sstevel@tonic-gate 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate 4707c478bd9Sstevel@tonic-gate if (unmounted) 4717c478bd9Sstevel@tonic-gate return (1); 4727c478bd9Sstevel@tonic-gate return (0); 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate 4757c478bd9Sstevel@tonic-gate /* 4767c478bd9Sstevel@tonic-gate * This routine checks if a device has mounted partitions. The 4777c478bd9Sstevel@tonic-gate * device name is assumed to be /dev/rdiskette. So, this can 4787c478bd9Sstevel@tonic-gate * be used for Floppy controllers 4797c478bd9Sstevel@tonic-gate * Returns 4807c478bd9Sstevel@tonic-gate * 0 : if not mounted 4817c478bd9Sstevel@tonic-gate * 1 : if successfully unmounted 4827c478bd9Sstevel@tonic-gate * -1 : Any error or unmount failed 4837c478bd9Sstevel@tonic-gate */ 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate int32_t 4867c478bd9Sstevel@tonic-gate check_and_unmount_floppy(int32_t fd, int32_t flag) 4877c478bd9Sstevel@tonic-gate { 4887c478bd9Sstevel@tonic-gate FILE *fp = NULL; 4897c478bd9Sstevel@tonic-gate int32_t mfd; 4907c478bd9Sstevel@tonic-gate struct dk_cinfo dkinfo, dkinfo_tmp; 4917c478bd9Sstevel@tonic-gate struct mnttab mnt_record; 4927c478bd9Sstevel@tonic-gate struct mnttab *mp = &mnt_record; 4937c478bd9Sstevel@tonic-gate struct stat stbuf; 4947c478bd9Sstevel@tonic-gate char raw_device[PATH_MAX]; 4957c478bd9Sstevel@tonic-gate int32_t found = 0; 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &dkinfo) < 0) { 4997c478bd9Sstevel@tonic-gate return (-1); 5007c478bd9Sstevel@tonic-gate } 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate if ((fp = fopen(MNTTAB, "r")) == NULL) { 5037c478bd9Sstevel@tonic-gate PERROR("Could not open /etc/mnttab"); 5047c478bd9Sstevel@tonic-gate (void) close(fd); 5057c478bd9Sstevel@tonic-gate exit(3); 5067c478bd9Sstevel@tonic-gate } 5077c478bd9Sstevel@tonic-gate 5087c478bd9Sstevel@tonic-gate while (getmntent(fp, mp) == 0) { 5097c478bd9Sstevel@tonic-gate if (strstr(mp->mnt_special, "/dev/fd") == NULL && 5107c478bd9Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/disket") == NULL && 5117c478bd9Sstevel@tonic-gate strstr(mp->mnt_special, "/dev/c") == NULL) { 5127c478bd9Sstevel@tonic-gate continue; 5137c478bd9Sstevel@tonic-gate } 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate (void) strcpy(raw_device, "/dev/r"); 5167c478bd9Sstevel@tonic-gate (void) strcat(raw_device, mp->mnt_special + strlen("/dev/")); 5177c478bd9Sstevel@tonic-gate 5187c478bd9Sstevel@tonic-gate 5197c478bd9Sstevel@tonic-gate /* 5207c478bd9Sstevel@tonic-gate * Attempt to open the device. If it fails, skip it. 5217c478bd9Sstevel@tonic-gate */ 5227c478bd9Sstevel@tonic-gate 523e3397557Szk194757 /* Turn on the privileges. */ 524e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 5257c478bd9Sstevel@tonic-gate 5267c478bd9Sstevel@tonic-gate mfd = open(raw_device, O_RDWR | O_NDELAY); 5277c478bd9Sstevel@tonic-gate 528e3397557Szk194757 /* Turn off the privileges. */ 529e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 5307c478bd9Sstevel@tonic-gate 5317c478bd9Sstevel@tonic-gate if (mfd < 0) { 5327c478bd9Sstevel@tonic-gate continue; 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate 5357c478bd9Sstevel@tonic-gate /* 5367c478bd9Sstevel@tonic-gate * Must be a character device 5377c478bd9Sstevel@tonic-gate */ 5387c478bd9Sstevel@tonic-gate if (fstat(mfd, &stbuf) < 0 || !S_ISCHR(stbuf.st_mode)) { 5397c478bd9Sstevel@tonic-gate (void) close(mfd); 5407c478bd9Sstevel@tonic-gate continue; 5417c478bd9Sstevel@tonic-gate } 5427c478bd9Sstevel@tonic-gate /* 5437c478bd9Sstevel@tonic-gate * Attempt to read the configuration info on the disk. 5447c478bd9Sstevel@tonic-gate */ 5457c478bd9Sstevel@tonic-gate if (ioctl(mfd, DKIOCINFO, &dkinfo_tmp) < 0) { 5467c478bd9Sstevel@tonic-gate (void) close(mfd); 5477c478bd9Sstevel@tonic-gate continue; 5487c478bd9Sstevel@tonic-gate } 5497c478bd9Sstevel@tonic-gate /* 5507c478bd9Sstevel@tonic-gate * Finished with the opened device 5517c478bd9Sstevel@tonic-gate */ 5527c478bd9Sstevel@tonic-gate (void) close(mfd); 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate /* 5557c478bd9Sstevel@tonic-gate * If it's not the disk we're interested in, it doesn't apply. 5567c478bd9Sstevel@tonic-gate */ 5577c478bd9Sstevel@tonic-gate if (dkinfo.dki_ctype != dkinfo_tmp.dki_ctype || 5587c478bd9Sstevel@tonic-gate dkinfo.dki_cnum != dkinfo_tmp.dki_cnum || 5597c478bd9Sstevel@tonic-gate dkinfo.dki_unit != dkinfo_tmp.dki_unit) { 5607c478bd9Sstevel@tonic-gate continue; 5617c478bd9Sstevel@tonic-gate } 5627c478bd9Sstevel@tonic-gate /* 5637c478bd9Sstevel@tonic-gate * It's a mount on the disk we're checking. If we are 5647c478bd9Sstevel@tonic-gate * checking whole disk, then we found trouble. We can 5657c478bd9Sstevel@tonic-gate * quit searching. 5667c478bd9Sstevel@tonic-gate */ 5677c478bd9Sstevel@tonic-gate 5687c478bd9Sstevel@tonic-gate if (flag) { 5697c478bd9Sstevel@tonic-gate if (my_umount(mp->mnt_mountp) < 0) { 5707c478bd9Sstevel@tonic-gate return (-1); 5717c478bd9Sstevel@tonic-gate } 5727c478bd9Sstevel@tonic-gate found = 1; 5737c478bd9Sstevel@tonic-gate } else { 5747c478bd9Sstevel@tonic-gate return (-1); 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate } 5777c478bd9Sstevel@tonic-gate return (found); 5787c478bd9Sstevel@tonic-gate } 5797c478bd9Sstevel@tonic-gate 5807c478bd9Sstevel@tonic-gate 5817c478bd9Sstevel@tonic-gate int32_t 5827c478bd9Sstevel@tonic-gate my_open(char *device_name, int32_t flags) 5837c478bd9Sstevel@tonic-gate { 5847c478bd9Sstevel@tonic-gate char *real_name; 5857c478bd9Sstevel@tonic-gate char *nm; 5867c478bd9Sstevel@tonic-gate char tmp_path_name[PATH_MAX]; 5877c478bd9Sstevel@tonic-gate struct stat stat_buf; 5887c478bd9Sstevel@tonic-gate int32_t ret_val; 5897c478bd9Sstevel@tonic-gate int32_t fd; 5907c478bd9Sstevel@tonic-gate int32_t have_read_priv = 0; 5917c478bd9Sstevel@tonic-gate DIR *dirp; 5927c478bd9Sstevel@tonic-gate struct dirent *dp; 5937c478bd9Sstevel@tonic-gate 5947c478bd9Sstevel@tonic-gate DPRINTF1("Device name %s\n", device_name); 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate if ((nm = volmgt_symname(device_name)) == NULL) { 5977c478bd9Sstevel@tonic-gate DPRINTF("path not managed\n"); 5987c478bd9Sstevel@tonic-gate real_name = media_findname(device_name); 5997c478bd9Sstevel@tonic-gate } else { 6007c478bd9Sstevel@tonic-gate DPRINTF1("path managed as %s\n", nm); 6017c478bd9Sstevel@tonic-gate real_name = media_findname(nm); 6027c478bd9Sstevel@tonic-gate DPRINTF1("real name %s\n", real_name); 6037c478bd9Sstevel@tonic-gate } 6047c478bd9Sstevel@tonic-gate 6057c478bd9Sstevel@tonic-gate if (real_name == NULL) 6067c478bd9Sstevel@tonic-gate return (-1); 6077c478bd9Sstevel@tonic-gate 6087c478bd9Sstevel@tonic-gate (void) strcpy(tmp_path_name, real_name); 6097c478bd9Sstevel@tonic-gate ret_val = stat(tmp_path_name, &stat_buf); 6107c478bd9Sstevel@tonic-gate if (ret_val < 0) { 6117c478bd9Sstevel@tonic-gate PERROR("Could not stat"); 6127c478bd9Sstevel@tonic-gate return (-1); 6137c478bd9Sstevel@tonic-gate } 6144bc0a2efScasper if (S_ISDIR(stat_buf.st_mode)) { 6157c478bd9Sstevel@tonic-gate 6167c478bd9Sstevel@tonic-gate /* 6177c478bd9Sstevel@tonic-gate * Open the directory and look for the 6187c478bd9Sstevel@tonic-gate * first non '.' entry. 6197c478bd9Sstevel@tonic-gate * Since raw_read and raw_writes are used, we don't 6207c478bd9Sstevel@tonic-gate * need to access the backup slice. 6217c478bd9Sstevel@tonic-gate * For PCMCIA Memory cards, raw_read and raw_writes are 6227c478bd9Sstevel@tonic-gate * not supported, but that is not a problem as, only slice2 6237c478bd9Sstevel@tonic-gate * is allowed on PCMCIA memory cards. 6247c478bd9Sstevel@tonic-gate */ 6257c478bd9Sstevel@tonic-gate 6267c478bd9Sstevel@tonic-gate /* 6277c478bd9Sstevel@tonic-gate * First make sure we are operating with a /vol/.... 6287c478bd9Sstevel@tonic-gate * Otherwise it can dangerous, 6297c478bd9Sstevel@tonic-gate * e.g. rmformat -s /dev/rdsk 6307c478bd9Sstevel@tonic-gate * We should not look into the directory contents here. 6317c478bd9Sstevel@tonic-gate */ 6327c478bd9Sstevel@tonic-gate if (strncmp(tmp_path_name, "/vol/dev/", strlen("/vol/dev/")) 6337c478bd9Sstevel@tonic-gate != 0) { 6347c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("The specified device \ 6357c478bd9Sstevel@tonic-gate is not a raw device.\n")); 6367c478bd9Sstevel@tonic-gate exit(1); 6377c478bd9Sstevel@tonic-gate } 6387c478bd9Sstevel@tonic-gate 639e3397557Szk194757 /* Turn on the privileges. */ 640e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate dirp = opendir(tmp_path_name); 6437c478bd9Sstevel@tonic-gate 644e3397557Szk194757 /* Turn off the privileges. */ 645e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 6467c478bd9Sstevel@tonic-gate 6477c478bd9Sstevel@tonic-gate if (dirp == NULL) { 6487c478bd9Sstevel@tonic-gate return (-1); 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate 651e3397557Szk194757 /* Turn on the privileges. */ 652e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 6537c478bd9Sstevel@tonic-gate have_read_priv = 1; 6547c478bd9Sstevel@tonic-gate 6557c478bd9Sstevel@tonic-gate while ((dp = readdir(dirp)) != NULL) { 6567c478bd9Sstevel@tonic-gate 657e3397557Szk194757 /* Turn off the privileges. */ 658e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 6597c478bd9Sstevel@tonic-gate have_read_priv = 0; 6607c478bd9Sstevel@tonic-gate 6617c478bd9Sstevel@tonic-gate DPRINTF1("Found %s\n", dp->d_name); 6627c478bd9Sstevel@tonic-gate if ((strcmp(dp->d_name, ".") != 0) && 6637c478bd9Sstevel@tonic-gate (strcmp(dp->d_name, "..") != 0)) { 6647c478bd9Sstevel@tonic-gate (void) snprintf(tmp_path_name, PATH_MAX, 6657c478bd9Sstevel@tonic-gate "%s/%s", tmp_path_name, dp->d_name); 6667c478bd9Sstevel@tonic-gate 6677c478bd9Sstevel@tonic-gate DPRINTF1("tmp_pathname is %s\n", tmp_path_name); 6687c478bd9Sstevel@tonic-gate break; 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate 671e3397557Szk194757 /* Turn on the privileges. */ 672e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 6737c478bd9Sstevel@tonic-gate have_read_priv = 1; 6747c478bd9Sstevel@tonic-gate } 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate if (have_read_priv) { 6777c478bd9Sstevel@tonic-gate /* drop the file_dac_read privilege */ 678e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 6797c478bd9Sstevel@tonic-gate have_read_priv = 0; 6807c478bd9Sstevel@tonic-gate } 6817c478bd9Sstevel@tonic-gate 6827c478bd9Sstevel@tonic-gate (void) closedir(dirp); 6837c478bd9Sstevel@tonic-gate } 6847c478bd9Sstevel@tonic-gate 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate if (volmgt_running() == 0) { 687e3397557Szk194757 /* Turn on privileges. */ 688e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 6897c478bd9Sstevel@tonic-gate have_read_priv = 1; 6907c478bd9Sstevel@tonic-gate } 6917c478bd9Sstevel@tonic-gate 6927c478bd9Sstevel@tonic-gate fd = open(tmp_path_name, flags); 6937c478bd9Sstevel@tonic-gate 6947c478bd9Sstevel@tonic-gate if (have_read_priv) { 695e3397557Szk194757 /* Turn off privileges. */ 696e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 6977c478bd9Sstevel@tonic-gate have_read_priv = 0; 6987c478bd9Sstevel@tonic-gate } 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate DPRINTF1("path opened %s\n", tmp_path_name); 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate return (fd); 7037c478bd9Sstevel@tonic-gate } 7047c478bd9Sstevel@tonic-gate 705342440ecSPrasad Singamsetty uint64_t 7067c478bd9Sstevel@tonic-gate my_atoll(char *ptr) 7077c478bd9Sstevel@tonic-gate { 7087c478bd9Sstevel@tonic-gate char *tmp_ptr = ptr; 7097c478bd9Sstevel@tonic-gate int32_t base = 10; 710342440ecSPrasad Singamsetty uint64_t ret_val; 7117c478bd9Sstevel@tonic-gate 7127c478bd9Sstevel@tonic-gate while (*tmp_ptr) { 7137c478bd9Sstevel@tonic-gate if (isdigit(*tmp_ptr)) 7147c478bd9Sstevel@tonic-gate tmp_ptr++; 7157c478bd9Sstevel@tonic-gate else { 7167c478bd9Sstevel@tonic-gate base = 16; 7177c478bd9Sstevel@tonic-gate break; 7187c478bd9Sstevel@tonic-gate } 7197c478bd9Sstevel@tonic-gate } 7207c478bd9Sstevel@tonic-gate tmp_ptr = ptr; 7217c478bd9Sstevel@tonic-gate if (base == 16) { 7227c478bd9Sstevel@tonic-gate if (strlen(tmp_ptr) < 3) { 7237c478bd9Sstevel@tonic-gate return (-1); 7247c478bd9Sstevel@tonic-gate } 7257c478bd9Sstevel@tonic-gate if (*tmp_ptr++ != '0' || (*tmp_ptr != 'x' && *tmp_ptr != 'X')) { 7267c478bd9Sstevel@tonic-gate return (-1); 7277c478bd9Sstevel@tonic-gate } 7287c478bd9Sstevel@tonic-gate tmp_ptr++; 7297c478bd9Sstevel@tonic-gate while (*tmp_ptr) { 7307c478bd9Sstevel@tonic-gate if (isxdigit(*tmp_ptr)) 7317c478bd9Sstevel@tonic-gate tmp_ptr++; 7327c478bd9Sstevel@tonic-gate else { 7337c478bd9Sstevel@tonic-gate return (-1); 7347c478bd9Sstevel@tonic-gate } 7357c478bd9Sstevel@tonic-gate } 7367c478bd9Sstevel@tonic-gate } 737342440ecSPrasad Singamsetty ret_val = (uint64_t)strtoull(ptr, (char **)NULL, 0); 7387c478bd9Sstevel@tonic-gate return (ret_val); 7397c478bd9Sstevel@tonic-gate } 7407c478bd9Sstevel@tonic-gate 7417c478bd9Sstevel@tonic-gate int32_t 7427c478bd9Sstevel@tonic-gate write_sunos_label(int32_t fd, int32_t media_type) 7437c478bd9Sstevel@tonic-gate { 7447c478bd9Sstevel@tonic-gate 745342440ecSPrasad Singamsetty struct extvtoc v_toc; 7467c478bd9Sstevel@tonic-gate int32_t ret; 7477c478bd9Sstevel@tonic-gate 748342440ecSPrasad Singamsetty (void) memset(&v_toc, 0, sizeof (struct extvtoc)); 7497c478bd9Sstevel@tonic-gate 7507c478bd9Sstevel@tonic-gate /* Initialize the vtoc information */ 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate if (media_type == SM_FLOPPY) { 7537c478bd9Sstevel@tonic-gate struct fd_char fdchar; 7547c478bd9Sstevel@tonic-gate int32_t mult_factor; 7557c478bd9Sstevel@tonic-gate 7567c478bd9Sstevel@tonic-gate if (ioctl(fd, FDIOGCHAR, &fdchar) < 0) { 7577c478bd9Sstevel@tonic-gate PERROR("FDIOGCHAR failed"); 7587c478bd9Sstevel@tonic-gate return (-1); 7597c478bd9Sstevel@tonic-gate } 7607c478bd9Sstevel@tonic-gate 7617c478bd9Sstevel@tonic-gate /* SPARC and x86 fd drivers use fdc_medium differently */ 7627c478bd9Sstevel@tonic-gate #if defined(__sparc) 7637c478bd9Sstevel@tonic-gate mult_factor = (fdchar.fdc_medium) ? 2 : 1; 7647c478bd9Sstevel@tonic-gate #elif defined(__x86) 7657c478bd9Sstevel@tonic-gate mult_factor = (fdchar.fdc_medium == 5) ? 2 : 1; 7667c478bd9Sstevel@tonic-gate #else 7677c478bd9Sstevel@tonic-gate #error No Platform defined 7687c478bd9Sstevel@tonic-gate #endif /* defined(__sparc) */ 7697c478bd9Sstevel@tonic-gate 7707c478bd9Sstevel@tonic-gate /* initialize the vtoc structure */ 7717c478bd9Sstevel@tonic-gate v_toc.v_nparts = 3; 7727c478bd9Sstevel@tonic-gate 7737c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_start = 0; 7747c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_size = (fdchar.fdc_ncyl - 1) * 2 * 7757c478bd9Sstevel@tonic-gate fdchar.fdc_secptrack * mult_factor; 7767c478bd9Sstevel@tonic-gate v_toc.v_part[1].p_start = (fdchar.fdc_ncyl - 1) * 2 * 7777c478bd9Sstevel@tonic-gate fdchar.fdc_secptrack * mult_factor; 7787c478bd9Sstevel@tonic-gate v_toc.v_part[1].p_size = 2 * fdchar.fdc_secptrack * mult_factor; 7797c478bd9Sstevel@tonic-gate 7807c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_start = 0; 7817c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_size = fdchar.fdc_ncyl * 2 * 7827c478bd9Sstevel@tonic-gate fdchar.fdc_secptrack * mult_factor; 7837c478bd9Sstevel@tonic-gate 7847c478bd9Sstevel@tonic-gate } else if (media_type == SM_SCSI_FLOPPY) { 7857c478bd9Sstevel@tonic-gate 7867c478bd9Sstevel@tonic-gate smedia_handle_t handle; 7877c478bd9Sstevel@tonic-gate smmedium_prop_t med_info; 7887c478bd9Sstevel@tonic-gate struct dk_geom dkgeom; 7897c478bd9Sstevel@tonic-gate 7907c478bd9Sstevel@tonic-gate 7917c478bd9Sstevel@tonic-gate /* 7927c478bd9Sstevel@tonic-gate * call smedia_get_medium_property to get the 7937c478bd9Sstevel@tonic-gate * correct media information, since DKIOCGMEDIAINFO 7947c478bd9Sstevel@tonic-gate * may fail for unformatted media. 7957c478bd9Sstevel@tonic-gate */ 7967c478bd9Sstevel@tonic-gate 7977c478bd9Sstevel@tonic-gate handle = smedia_get_handle(fd); 7987c478bd9Sstevel@tonic-gate if (handle == NULL) { 7997c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8007c478bd9Sstevel@tonic-gate gettext("Failed to get libsmedia handle.\n")); 8017c478bd9Sstevel@tonic-gate 8027c478bd9Sstevel@tonic-gate (void) close(fd); 8037c478bd9Sstevel@tonic-gate return (-1); 8047c478bd9Sstevel@tonic-gate } 8057c478bd9Sstevel@tonic-gate 8067c478bd9Sstevel@tonic-gate 8077c478bd9Sstevel@tonic-gate if (smedia_get_medium_property(handle, &med_info) < 0) { 8087c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8097c478bd9Sstevel@tonic-gate gettext("Get medium property failed \n")); 8107c478bd9Sstevel@tonic-gate 8117c478bd9Sstevel@tonic-gate (void) smedia_release_handle(handle); 8127c478bd9Sstevel@tonic-gate (void) close(fd); 8137c478bd9Sstevel@tonic-gate return (-1); 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate 8167c478bd9Sstevel@tonic-gate /* Fill in our own geometry information */ 8177c478bd9Sstevel@tonic-gate 8187c478bd9Sstevel@tonic-gate dkgeom.dkg_pcyl = med_info.sm_pcyl; 8197c478bd9Sstevel@tonic-gate dkgeom.dkg_ncyl = med_info.sm_pcyl; 8207c478bd9Sstevel@tonic-gate dkgeom.dkg_nhead = med_info.sm_nhead; 8217c478bd9Sstevel@tonic-gate dkgeom.dkg_nsect = med_info.sm_nsect; 8227c478bd9Sstevel@tonic-gate dkgeom.dkg_acyl = 0; 8237c478bd9Sstevel@tonic-gate dkgeom.dkg_bcyl = 0; 8247c478bd9Sstevel@tonic-gate dkgeom.dkg_intrlv = 0; 8257c478bd9Sstevel@tonic-gate dkgeom.dkg_apc = 0; 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate /* 8287c478bd9Sstevel@tonic-gate * Try to set vtoc, if not successful we will 8297c478bd9Sstevel@tonic-gate * continue to use the faked geometry information. 8307c478bd9Sstevel@tonic-gate */ 8317c478bd9Sstevel@tonic-gate 8327c478bd9Sstevel@tonic-gate (void) ioctl(fd, DKIOCSGEOM, &dkgeom); 8337c478bd9Sstevel@tonic-gate 8347c478bd9Sstevel@tonic-gate (void) smedia_release_handle(handle); 8357c478bd9Sstevel@tonic-gate 8367c478bd9Sstevel@tonic-gate /* we want the same partitioning as used for normal floppies */ 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate v_toc.v_part[0].p_start = 0; 839342440ecSPrasad Singamsetty v_toc.v_part[0].p_size = (diskaddr_t)(dkgeom.dkg_ncyl - 1) * 8407c478bd9Sstevel@tonic-gate dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8417c478bd9Sstevel@tonic-gate 842342440ecSPrasad Singamsetty v_toc.v_part[1].p_start = (diskaddr_t)(dkgeom.dkg_ncyl - 1) * 8437c478bd9Sstevel@tonic-gate dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8447c478bd9Sstevel@tonic-gate v_toc.v_part[1].p_size = dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8457c478bd9Sstevel@tonic-gate 8467c478bd9Sstevel@tonic-gate v_toc.v_part[2].p_start = 0; 847342440ecSPrasad Singamsetty v_toc.v_part[2].p_size = (diskaddr_t)dkgeom.dkg_ncyl * 8487c478bd9Sstevel@tonic-gate dkgeom.dkg_nhead * dkgeom.dkg_nsect; 8497c478bd9Sstevel@tonic-gate 8507c478bd9Sstevel@tonic-gate /* both write_vtoc and DKIOCSVTOC require V_NUMPAR partitions */ 8517c478bd9Sstevel@tonic-gate v_toc.v_nparts = V_NUMPAR; 8527c478bd9Sstevel@tonic-gate 8537c478bd9Sstevel@tonic-gate } else { 8547c478bd9Sstevel@tonic-gate 8557c478bd9Sstevel@tonic-gate return (0); 8567c478bd9Sstevel@tonic-gate } 8577c478bd9Sstevel@tonic-gate 8587c478bd9Sstevel@tonic-gate v_toc.v_sanity = VTOC_SANE; 8597c478bd9Sstevel@tonic-gate v_toc.v_version = V_VERSION; 8607c478bd9Sstevel@tonic-gate 8617c478bd9Sstevel@tonic-gate /* 8627c478bd9Sstevel@tonic-gate * The label structure is set up for DEV_BSIZE(512 byte) blocks, 8637c478bd9Sstevel@tonic-gate * even though a medium density diskette has 1024 byte blocks 8647c478bd9Sstevel@tonic-gate * See dklabel.h for more details. 8657c478bd9Sstevel@tonic-gate */ 8667c478bd9Sstevel@tonic-gate v_toc.v_sectorsz = DEV_BSIZE; 8677c478bd9Sstevel@tonic-gate 8687c478bd9Sstevel@tonic-gate /* let the fd driver finish constructing the label and writing it. */ 8697c478bd9Sstevel@tonic-gate 8707c478bd9Sstevel@tonic-gate 871e3397557Szk194757 /* Turn on the privileges. */ 872e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 8737c478bd9Sstevel@tonic-gate 874342440ecSPrasad Singamsetty ret = write_extvtoc(fd, &v_toc); 8757c478bd9Sstevel@tonic-gate 876e3397557Szk194757 /* Turn off the privileges. */ 877e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate if (ret < 0) { 8807c478bd9Sstevel@tonic-gate PERROR("Write vtoc"); 8817c478bd9Sstevel@tonic-gate DPRINTF1("Write vtoc failed errno:%d\n", errno); 8827c478bd9Sstevel@tonic-gate return (-1); 8837c478bd9Sstevel@tonic-gate } 8847c478bd9Sstevel@tonic-gate 8857c478bd9Sstevel@tonic-gate return (0); 8867c478bd9Sstevel@tonic-gate } 8877c478bd9Sstevel@tonic-gate 8887c478bd9Sstevel@tonic-gate static void 8897c478bd9Sstevel@tonic-gate intr_sig_handler() 8907c478bd9Sstevel@tonic-gate { 8917c478bd9Sstevel@tonic-gate char c; 8927c478bd9Sstevel@tonic-gate 8937c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext(global_intr_msg)); 8947c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 8957c478bd9Sstevel@tonic-gate gettext("\nDo you want to stop formatting?(y/n)")); 8967c478bd9Sstevel@tonic-gate (void) fflush(stdout); 8977c478bd9Sstevel@tonic-gate rewind(stdin); 898*afb89a98SPavel Potoplyak while ((c = getchar()) == -1) 899*afb89a98SPavel Potoplyak ; 9007c478bd9Sstevel@tonic-gate if (c == 'y' || c == 'Y') { 9017c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Format interrupted\n")); 9027c478bd9Sstevel@tonic-gate exit(1); 9037c478bd9Sstevel@tonic-gate } else if (c == 'n' || c == 'N') 9047c478bd9Sstevel@tonic-gate return; 9057c478bd9Sstevel@tonic-gate else { 9067c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Did not interrupt\n")); 9077c478bd9Sstevel@tonic-gate return; 9087c478bd9Sstevel@tonic-gate } 9097c478bd9Sstevel@tonic-gate } 9107c478bd9Sstevel@tonic-gate 9117c478bd9Sstevel@tonic-gate static struct sigaction act, oact; 9127c478bd9Sstevel@tonic-gate void 9137c478bd9Sstevel@tonic-gate trap_SIGINT() 9147c478bd9Sstevel@tonic-gate { 9157c478bd9Sstevel@tonic-gate 9167c478bd9Sstevel@tonic-gate act.sa_handler = intr_sig_handler; 9177c478bd9Sstevel@tonic-gate (void) memset(&act.sa_mask, 0, sizeof (sigset_t)); 9187c478bd9Sstevel@tonic-gate act.sa_flags = SA_RESTART; /* | SA_NODEFER; */ 9197c478bd9Sstevel@tonic-gate if (sigaction(SIGINT, &act, &oact) < 0) { 9207c478bd9Sstevel@tonic-gate DPRINTF("sigset failed\n"); 9217c478bd9Sstevel@tonic-gate return; 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate } 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate void 9267c478bd9Sstevel@tonic-gate release_SIGINT() 9277c478bd9Sstevel@tonic-gate { 9287c478bd9Sstevel@tonic-gate if (sigaction(SIGINT, &oact, (struct sigaction *)NULL) < 0) { 9297c478bd9Sstevel@tonic-gate DPRINTF("sigunset failed\n"); 9307c478bd9Sstevel@tonic-gate return; 9317c478bd9Sstevel@tonic-gate } 9327c478bd9Sstevel@tonic-gate } 9337c478bd9Sstevel@tonic-gate 9347c478bd9Sstevel@tonic-gate int32_t 935342440ecSPrasad Singamsetty verify(smedia_handle_t handle, int32_t fd, diskaddr_t start_sector, 9367c478bd9Sstevel@tonic-gate uint32_t nblocks, char *buf, 9377c478bd9Sstevel@tonic-gate int32_t flag, int32_t blocksize, int32_t no_raw_rw) 9387c478bd9Sstevel@tonic-gate { 939342440ecSPrasad Singamsetty uint64_t ret; 9407c478bd9Sstevel@tonic-gate 9417c478bd9Sstevel@tonic-gate DPRINTF("ANALYSE MEDIA \n"); 9427c478bd9Sstevel@tonic-gate 9437c478bd9Sstevel@tonic-gate 9447c478bd9Sstevel@tonic-gate if ((flag == VERIFY_READ) && (!no_raw_rw)) { 9457c478bd9Sstevel@tonic-gate 946e3397557Szk194757 /* Turn on the privileges. */ 947e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 9487c478bd9Sstevel@tonic-gate 9497c478bd9Sstevel@tonic-gate ret = smedia_raw_read(handle, start_sector, buf, nblocks * 9507c478bd9Sstevel@tonic-gate blocksize); 9517c478bd9Sstevel@tonic-gate 952e3397557Szk194757 /* Turn off the privileges. */ 953e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 9547c478bd9Sstevel@tonic-gate 955342440ecSPrasad Singamsetty if (ret != (nblocks * blocksize)) 9567c478bd9Sstevel@tonic-gate return (-1); 9577c478bd9Sstevel@tonic-gate return (0); 9587c478bd9Sstevel@tonic-gate 9597c478bd9Sstevel@tonic-gate } else if ((flag == VERIFY_WRITE) && (!no_raw_rw)) { 9607c478bd9Sstevel@tonic-gate 961e3397557Szk194757 /* Turn on privileges. */ 962e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 9637c478bd9Sstevel@tonic-gate 9647c478bd9Sstevel@tonic-gate ret = smedia_raw_write(handle, start_sector, buf, nblocks * 9657c478bd9Sstevel@tonic-gate blocksize); 9667c478bd9Sstevel@tonic-gate 967e3397557Szk194757 /* Turn off the privileges. */ 968e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 9697c478bd9Sstevel@tonic-gate 970342440ecSPrasad Singamsetty if (ret != (blocksize * nblocks)) 9717c478bd9Sstevel@tonic-gate return (-1); 9727c478bd9Sstevel@tonic-gate return (0); 9737c478bd9Sstevel@tonic-gate 9747c478bd9Sstevel@tonic-gate } else if ((flag == VERIFY_READ) && (no_raw_rw)) { 9757c478bd9Sstevel@tonic-gate ret = llseek(fd, start_sector * blocksize, SEEK_SET); 9767c478bd9Sstevel@tonic-gate if (ret != start_sector * blocksize) { 9777c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Seek failed\n")); 9787c478bd9Sstevel@tonic-gate return (-2); 9797c478bd9Sstevel@tonic-gate } 9807c478bd9Sstevel@tonic-gate 981e3397557Szk194757 /* Turn on the privileges. */ 982e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 9837c478bd9Sstevel@tonic-gate 9847c478bd9Sstevel@tonic-gate ret = read(fd, buf, nblocks * blocksize); 9857c478bd9Sstevel@tonic-gate 986e3397557Szk194757 /* Turn off the privileges. */ 987e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 9887c478bd9Sstevel@tonic-gate 9897c478bd9Sstevel@tonic-gate if (ret != nblocks * blocksize) { 9907c478bd9Sstevel@tonic-gate return (-1); 9917c478bd9Sstevel@tonic-gate } 9927c478bd9Sstevel@tonic-gate return (0); 9937c478bd9Sstevel@tonic-gate } else if ((flag == VERIFY_WRITE) && (no_raw_rw)) { 9947c478bd9Sstevel@tonic-gate ret = llseek(fd, start_sector * blocksize, SEEK_SET); 9957c478bd9Sstevel@tonic-gate if (ret != start_sector * blocksize) { 9967c478bd9Sstevel@tonic-gate (void) fprintf(stderr, gettext("Seek failed\n")); 9977c478bd9Sstevel@tonic-gate return (-2); 9987c478bd9Sstevel@tonic-gate } 9997c478bd9Sstevel@tonic-gate 1000e3397557Szk194757 /* Turn on the privileges. */ 1001e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 10027c478bd9Sstevel@tonic-gate 10037c478bd9Sstevel@tonic-gate ret = write(fd, buf, nblocks * blocksize); 10047c478bd9Sstevel@tonic-gate 1005e3397557Szk194757 /* Turn off the privileges. */ 1006e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 10077c478bd9Sstevel@tonic-gate 10087c478bd9Sstevel@tonic-gate if (ret != nblocks * blocksize) { 10097c478bd9Sstevel@tonic-gate return (-1); 10107c478bd9Sstevel@tonic-gate } 10117c478bd9Sstevel@tonic-gate return (0); 10127c478bd9Sstevel@tonic-gate } else { 10137c478bd9Sstevel@tonic-gate DPRINTF("Illegal parameter to verify_analysis!\n"); 10147c478bd9Sstevel@tonic-gate return (-1); 10157c478bd9Sstevel@tonic-gate } 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate 10187c478bd9Sstevel@tonic-gate static int 10197c478bd9Sstevel@tonic-gate my_umount(char *mountp) 10207c478bd9Sstevel@tonic-gate { 10217c478bd9Sstevel@tonic-gate pid_t pid; /* forked proc's pid */ 10227c478bd9Sstevel@tonic-gate int rval; /* proc's return value */ 10237c478bd9Sstevel@tonic-gate 10247c478bd9Sstevel@tonic-gate 10257c478bd9Sstevel@tonic-gate /* create a child to unmount the path */ 10267c478bd9Sstevel@tonic-gate 1027e3397557Szk194757 /* Turn on the privileges */ 1028e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 10297c478bd9Sstevel@tonic-gate 10307c478bd9Sstevel@tonic-gate pid = fork(); 10317c478bd9Sstevel@tonic-gate 1032e3397557Szk194757 /* Turn off the privileges. */ 1033e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 10347c478bd9Sstevel@tonic-gate 10357c478bd9Sstevel@tonic-gate if (pid < 0) { 10367c478bd9Sstevel@tonic-gate PERROR("fork failed"); 10377c478bd9Sstevel@tonic-gate exit(0); 10387c478bd9Sstevel@tonic-gate } 10397c478bd9Sstevel@tonic-gate 10407c478bd9Sstevel@tonic-gate if (pid == 0) { 10417c478bd9Sstevel@tonic-gate /* the child */ 10427c478bd9Sstevel@tonic-gate /* get rid of those nasty err messages */ 10437c478bd9Sstevel@tonic-gate DPRINTF1("call_unmount_prog: calling %s \n", mountp); 10447c478bd9Sstevel@tonic-gate 1045e3397557Szk194757 /* Turn on the priviliges. */ 1046e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 10477c478bd9Sstevel@tonic-gate 10487c478bd9Sstevel@tonic-gate if (execl("/usr/sbin/umount", "/usr/sbin/umount", mountp, 10497c478bd9Sstevel@tonic-gate NULL) < 0) { 10507c478bd9Sstevel@tonic-gate perror("exec failed"); 1051e3397557Szk194757 /* Turn off the privileges */ 1052e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 10537c478bd9Sstevel@tonic-gate exit(-1); 10547c478bd9Sstevel@tonic-gate } 10557c478bd9Sstevel@tonic-gate } 10567c478bd9Sstevel@tonic-gate 10577c478bd9Sstevel@tonic-gate /* wait for the umount command to exit */ 10587c478bd9Sstevel@tonic-gate rval = 0; 10597c478bd9Sstevel@tonic-gate if (waitpid(pid, &rval, 0) == pid) { 10607c478bd9Sstevel@tonic-gate if (WIFEXITED(rval)) { 10617c478bd9Sstevel@tonic-gate if (WEXITSTATUS(rval) == 0) { 10627c478bd9Sstevel@tonic-gate DPRINTF("umount : Success\n"); 10637c478bd9Sstevel@tonic-gate return (1); 10647c478bd9Sstevel@tonic-gate } 10657c478bd9Sstevel@tonic-gate } 10667c478bd9Sstevel@tonic-gate } 10677c478bd9Sstevel@tonic-gate return (-1); 10687c478bd9Sstevel@tonic-gate } 10697c478bd9Sstevel@tonic-gate 10707c478bd9Sstevel@tonic-gate static int 10717c478bd9Sstevel@tonic-gate my_volrmmount(char *real_name) 10727c478bd9Sstevel@tonic-gate { 10737c478bd9Sstevel@tonic-gate int pid, rval; 10747c478bd9Sstevel@tonic-gate 1075e3397557Szk194757 /* Turn on the privileges. */ 1076e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 10777c478bd9Sstevel@tonic-gate 10787c478bd9Sstevel@tonic-gate pid = fork(); 10797c478bd9Sstevel@tonic-gate 1080e3397557Szk194757 /* Turn off the privileges. */ 1081e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 10827c478bd9Sstevel@tonic-gate 10837c478bd9Sstevel@tonic-gate /* create a child to unmount the path */ 10847c478bd9Sstevel@tonic-gate if (pid < 0) { 10857c478bd9Sstevel@tonic-gate PERROR("fork failed"); 10867c478bd9Sstevel@tonic-gate exit(0); 10877c478bd9Sstevel@tonic-gate } 10887c478bd9Sstevel@tonic-gate 10897c478bd9Sstevel@tonic-gate if (pid == 0) { 10907c478bd9Sstevel@tonic-gate /* the child */ 10917c478bd9Sstevel@tonic-gate /* get rid of those nasty err messages */ 10927c478bd9Sstevel@tonic-gate DPRINTF1("call_unmount_prog: calling %s \n", 10937c478bd9Sstevel@tonic-gate "/usr/bin/volrmmount"); 10947c478bd9Sstevel@tonic-gate 1095e3397557Szk194757 /* Turn on the privileges. */ 1096e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 10977c478bd9Sstevel@tonic-gate if (execl("/usr/bin/volrmmount", "/usr/bin/volrmmount", "-e", 10987c478bd9Sstevel@tonic-gate real_name, NULL) < 0) { 10997c478bd9Sstevel@tonic-gate PERROR("volrmmount exec failed"); 1100e3397557Szk194757 /* Turn off the privileges */ 1101e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 11027c478bd9Sstevel@tonic-gate exit(-1); 11037c478bd9Sstevel@tonic-gate } 11047c478bd9Sstevel@tonic-gate } else if (waitpid(pid, &rval, 0) == pid) { 11057c478bd9Sstevel@tonic-gate if (WIFEXITED(rval)) { 11067c478bd9Sstevel@tonic-gate if (WEXITSTATUS(rval) == 0) { 11077c478bd9Sstevel@tonic-gate DPRINTF("volrmmount: Success\n"); 11087c478bd9Sstevel@tonic-gate return (1); 11097c478bd9Sstevel@tonic-gate } 11107c478bd9Sstevel@tonic-gate } 11117c478bd9Sstevel@tonic-gate } 11127c478bd9Sstevel@tonic-gate return (-1); 11137c478bd9Sstevel@tonic-gate } 11147c478bd9Sstevel@tonic-gate 11157c478bd9Sstevel@tonic-gate int 11167c478bd9Sstevel@tonic-gate find_device(int defer, char *tmpstr) 11177c478bd9Sstevel@tonic-gate { 11187c478bd9Sstevel@tonic-gate DIR *dir; 11197c478bd9Sstevel@tonic-gate struct dirent *dirent; 11207c478bd9Sstevel@tonic-gate char sdev[PATH_MAX], dev[PATH_MAX], *pname; 11217c478bd9Sstevel@tonic-gate device_t *t_dev; 1122dd97b1d6Sphitran int removable = 0; 1123dd97b1d6Sphitran int device_type = 0; 1124dd97b1d6Sphitran int hotpluggable = 0; 11257c478bd9Sstevel@tonic-gate struct dk_minfo mediainfo; 11267c478bd9Sstevel@tonic-gate static int found = 0; 11277c478bd9Sstevel@tonic-gate 11287c478bd9Sstevel@tonic-gate dir = opendir("/dev/rdsk"); 11297c478bd9Sstevel@tonic-gate if (dir == NULL) 11307c478bd9Sstevel@tonic-gate return (-1); 11317c478bd9Sstevel@tonic-gate 11327c478bd9Sstevel@tonic-gate total_devices_found = 0; 11337c478bd9Sstevel@tonic-gate while ((dirent = readdir(dir)) != NULL) { 11347c478bd9Sstevel@tonic-gate if (dirent->d_name[0] == '.') { 11357c478bd9Sstevel@tonic-gate continue; 11367c478bd9Sstevel@tonic-gate } 11377c478bd9Sstevel@tonic-gate (void) snprintf(sdev, PATH_MAX, "/dev/rdsk/%s", 11387c478bd9Sstevel@tonic-gate dirent->d_name); 11397c478bd9Sstevel@tonic-gate #ifdef sparc 11407c478bd9Sstevel@tonic-gate if (!strstr(sdev, "s2")) { 11417c478bd9Sstevel@tonic-gate continue; 11427c478bd9Sstevel@tonic-gate } 11437c478bd9Sstevel@tonic-gate #else /* x86 */ 11447c478bd9Sstevel@tonic-gate if (vol_running) { 11457c478bd9Sstevel@tonic-gate if (!(strstr(sdev, "s2") || strstr(sdev, "p0"))) { 11467c478bd9Sstevel@tonic-gate continue; 11477c478bd9Sstevel@tonic-gate } 11487c478bd9Sstevel@tonic-gate } else { 11497c478bd9Sstevel@tonic-gate if (!strstr(sdev, "p0")) { 11507c478bd9Sstevel@tonic-gate continue; 11517c478bd9Sstevel@tonic-gate } 11527c478bd9Sstevel@tonic-gate } 11537c478bd9Sstevel@tonic-gate #endif 11547c478bd9Sstevel@tonic-gate if (!lookup_device(sdev, dev)) { 11557c478bd9Sstevel@tonic-gate continue; 11567c478bd9Sstevel@tonic-gate } 11577c478bd9Sstevel@tonic-gate if ((t_dev = get_device(NULL, dev)) == NULL) { 11587c478bd9Sstevel@tonic-gate continue; 11597c478bd9Sstevel@tonic-gate } 11607c478bd9Sstevel@tonic-gate total_devices_found++; 11617c478bd9Sstevel@tonic-gate 11627c478bd9Sstevel@tonic-gate if ((!defer) && !found) { 11637c478bd9Sstevel@tonic-gate char *sn, *tmpbuf; 11647c478bd9Sstevel@tonic-gate /* 11657c478bd9Sstevel@tonic-gate * dev_name is an optional command line input. 11667c478bd9Sstevel@tonic-gate */ 11677c478bd9Sstevel@tonic-gate if (dev_name) { 11687c478bd9Sstevel@tonic-gate if (strstr(dirent->d_name, tmpstr)) { 11697c478bd9Sstevel@tonic-gate found = 1; 11707c478bd9Sstevel@tonic-gate } else if (!vol_running) { 11717c478bd9Sstevel@tonic-gate continue; 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate } 11747c478bd9Sstevel@tonic-gate /* 11757c478bd9Sstevel@tonic-gate * volmgt_symname() returns NULL if the device 11767c478bd9Sstevel@tonic-gate * is not managed by volmgt. 11777c478bd9Sstevel@tonic-gate */ 11787c478bd9Sstevel@tonic-gate sn = volmgt_symname(sdev); 11797c478bd9Sstevel@tonic-gate 11807c478bd9Sstevel@tonic-gate if (vol_running && (sn != NULL)) { 11817c478bd9Sstevel@tonic-gate if (strstr(sn, "dev") == NULL) { 11827c478bd9Sstevel@tonic-gate tmpbuf = (char *)my_zalloc(PATH_MAX); 11837c478bd9Sstevel@tonic-gate (void) strcpy(tmpbuf, 11847c478bd9Sstevel@tonic-gate "/vol/dev/aliases/"); 11857c478bd9Sstevel@tonic-gate (void) strcat(tmpbuf, sn); 11867c478bd9Sstevel@tonic-gate free(sn); 11877c478bd9Sstevel@tonic-gate sn = tmpbuf; 11887c478bd9Sstevel@tonic-gate } 11897c478bd9Sstevel@tonic-gate if (dev_name && !found) { 11907c478bd9Sstevel@tonic-gate if (!strstr(tmpbuf, tmpstr)) { 11917c478bd9Sstevel@tonic-gate continue; 11927c478bd9Sstevel@tonic-gate } else { 11937c478bd9Sstevel@tonic-gate found = 1; 11947c478bd9Sstevel@tonic-gate } 11957c478bd9Sstevel@tonic-gate } 11967c478bd9Sstevel@tonic-gate } 11977c478bd9Sstevel@tonic-gate 11987c478bd9Sstevel@tonic-gate /* 11997c478bd9Sstevel@tonic-gate * Get device type information for CD/DVD devices. 12007c478bd9Sstevel@tonic-gate */ 12017c478bd9Sstevel@tonic-gate if (is_cd(dev)) { 12027c478bd9Sstevel@tonic-gate if (check_device(t_dev, 12037c478bd9Sstevel@tonic-gate CHECK_DEVICE_IS_DVD_WRITABLE)) { 12047c478bd9Sstevel@tonic-gate device_type = DK_DVDR; 12057c478bd9Sstevel@tonic-gate } else if (check_device(t_dev, 12067c478bd9Sstevel@tonic-gate CHECK_DEVICE_IS_DVD_READABLE)) { 12077c478bd9Sstevel@tonic-gate device_type = DK_DVDROM; 12087c478bd9Sstevel@tonic-gate } else if (check_device(t_dev, 12097c478bd9Sstevel@tonic-gate CHECK_DEVICE_IS_CD_WRITABLE)) { 12107c478bd9Sstevel@tonic-gate device_type = DK_CDR; 12117c478bd9Sstevel@tonic-gate } else { 12127c478bd9Sstevel@tonic-gate device_type = DK_CDROM; 12137c478bd9Sstevel@tonic-gate } 12147c478bd9Sstevel@tonic-gate } else { 12157c478bd9Sstevel@tonic-gate device_type = ioctl(t_dev->d_fd, 12167c478bd9Sstevel@tonic-gate DKIOCGMEDIAINFO, &mediainfo); 12177c478bd9Sstevel@tonic-gate if (device_type < 0) 12187c478bd9Sstevel@tonic-gate device_type = 0; 12197c478bd9Sstevel@tonic-gate else 12207c478bd9Sstevel@tonic-gate device_type = mediainfo.dki_media_type; 12217c478bd9Sstevel@tonic-gate } 12227c478bd9Sstevel@tonic-gate 1223dd97b1d6Sphitran if (!ioctl(t_dev->d_fd, DKIOCREMOVABLE, &removable) && 1224dd97b1d6Sphitran !ioctl(t_dev->d_fd, DKIOCHOTPLUGGABLE, 1225dd97b1d6Sphitran &hotpluggable)) { 1226dd97b1d6Sphitran if (removable || hotpluggable) { 12277c478bd9Sstevel@tonic-gate removable_found++; 12287c478bd9Sstevel@tonic-gate pname = get_physical_name(sdev); 12297c478bd9Sstevel@tonic-gate if (sn) { 12307c478bd9Sstevel@tonic-gate (void) printf(" %4d. " 12317c478bd9Sstevel@tonic-gate "Volmgt Node: %s\n", 12327c478bd9Sstevel@tonic-gate removable_found, sn); 12337c478bd9Sstevel@tonic-gate (void) printf(" " 12347c478bd9Sstevel@tonic-gate "Logical Node: %s\n", sdev); 12357c478bd9Sstevel@tonic-gate (void) printf(" " 12367c478bd9Sstevel@tonic-gate "Physical Node: %s\n", 12377c478bd9Sstevel@tonic-gate pname); 12387c478bd9Sstevel@tonic-gate } else { 12397c478bd9Sstevel@tonic-gate (void) printf(" %4d. " 12407c478bd9Sstevel@tonic-gate "Logical Node: %s\n", 12417c478bd9Sstevel@tonic-gate removable_found, sdev); 12427c478bd9Sstevel@tonic-gate (void) printf(" " 12437c478bd9Sstevel@tonic-gate "Physical Node: %s\n", 12447c478bd9Sstevel@tonic-gate pname); 12457c478bd9Sstevel@tonic-gate } 12467c478bd9Sstevel@tonic-gate (void) printf(" Connected " 12477c478bd9Sstevel@tonic-gate "Device: %-8.8s %-16.16s " 12487c478bd9Sstevel@tonic-gate "%-4.4s\n", 12497c478bd9Sstevel@tonic-gate &t_dev->d_inq[8], 12507c478bd9Sstevel@tonic-gate &t_dev->d_inq[16], 12517c478bd9Sstevel@tonic-gate &t_dev->d_inq[32]); 12527c478bd9Sstevel@tonic-gate (void) printf(" Device " 12537c478bd9Sstevel@tonic-gate "Type: "); 12547c478bd9Sstevel@tonic-gate } else 12557c478bd9Sstevel@tonic-gate continue; 12567c478bd9Sstevel@tonic-gate } else 12577c478bd9Sstevel@tonic-gate continue; 12587c478bd9Sstevel@tonic-gate 12597c478bd9Sstevel@tonic-gate switch (device_type) { 12607c478bd9Sstevel@tonic-gate case DK_CDROM: 12617c478bd9Sstevel@tonic-gate (void) printf("CD Reader\n"); 12627c478bd9Sstevel@tonic-gate break; 12637c478bd9Sstevel@tonic-gate case DK_CDR: 12647c478bd9Sstevel@tonic-gate case DK_CDRW: 12657c478bd9Sstevel@tonic-gate (void) printf("CD Reader/Writer\n"); 12667c478bd9Sstevel@tonic-gate break; 12677c478bd9Sstevel@tonic-gate case DK_DVDROM: 12687c478bd9Sstevel@tonic-gate (void) printf("DVD Reader\n"); 12697c478bd9Sstevel@tonic-gate break; 12707c478bd9Sstevel@tonic-gate case DK_DVDR: 12717c478bd9Sstevel@tonic-gate case DK_DVDRAM: 12727c478bd9Sstevel@tonic-gate (void) printf("DVD Reader/Writer\n"); 12737c478bd9Sstevel@tonic-gate break; 12747c478bd9Sstevel@tonic-gate case DK_FIXED_DISK: 12757c478bd9Sstevel@tonic-gate if (strstr((const char *) 12767c478bd9Sstevel@tonic-gate &t_dev->d_inq[16], "FD") || 12777c478bd9Sstevel@tonic-gate strstr((const char *) 12787c478bd9Sstevel@tonic-gate &t_dev->d_inq[16], "LS-120")) 12797c478bd9Sstevel@tonic-gate (void) printf("Floppy " 12807c478bd9Sstevel@tonic-gate "drive\n"); 12817c478bd9Sstevel@tonic-gate else 12827c478bd9Sstevel@tonic-gate (void) printf("Removable\n"); 12837c478bd9Sstevel@tonic-gate break; 12847c478bd9Sstevel@tonic-gate case DK_FLOPPY: 12857c478bd9Sstevel@tonic-gate (void) printf("Floppy drive\n"); 12867c478bd9Sstevel@tonic-gate break; 12877c478bd9Sstevel@tonic-gate case DK_ZIP: 12887c478bd9Sstevel@tonic-gate (void) printf("Zip drive\n"); 12897c478bd9Sstevel@tonic-gate break; 12907c478bd9Sstevel@tonic-gate case DK_JAZ: 12917c478bd9Sstevel@tonic-gate (void) printf("Jaz drive\n"); 12927c478bd9Sstevel@tonic-gate break; 12937c478bd9Sstevel@tonic-gate default: 12947c478bd9Sstevel@tonic-gate (void) printf("<Unknown>\n"); 12957c478bd9Sstevel@tonic-gate DPRINTF1("\t %d\n", device_type); 12967c478bd9Sstevel@tonic-gate break; 12977c478bd9Sstevel@tonic-gate } 12987c478bd9Sstevel@tonic-gate get_media_info(t_dev, sdev, pname, sn); 12997c478bd9Sstevel@tonic-gate } 13007c478bd9Sstevel@tonic-gate fini_device(t_dev); 13017c478bd9Sstevel@tonic-gate } 13027c478bd9Sstevel@tonic-gate 13037c478bd9Sstevel@tonic-gate (void) closedir(dir); 13047c478bd9Sstevel@tonic-gate return (removable_found); 13057c478bd9Sstevel@tonic-gate } 13067c478bd9Sstevel@tonic-gate 13077c478bd9Sstevel@tonic-gate /* 13087c478bd9Sstevel@tonic-gate * Returns a device_t handle for a node returned by lookup_device() 13097c478bd9Sstevel@tonic-gate * and takes the user supplied name and stores it inside the node. 13107c478bd9Sstevel@tonic-gate */ 13117c478bd9Sstevel@tonic-gate static device_t * 13127c478bd9Sstevel@tonic-gate get_device(char *user_supplied, char *node) 13137c478bd9Sstevel@tonic-gate { 13147c478bd9Sstevel@tonic-gate device_t *dev; 13157c478bd9Sstevel@tonic-gate int fd; 13167c478bd9Sstevel@tonic-gate char devnode[PATH_MAX]; 13177c478bd9Sstevel@tonic-gate int size; 13187c478bd9Sstevel@tonic-gate 13197c478bd9Sstevel@tonic-gate /* 13207c478bd9Sstevel@tonic-gate * we need to resolve any link paths to avoid fake files 13217c478bd9Sstevel@tonic-gate * such as /dev/rdsk/../../export/file. 13227c478bd9Sstevel@tonic-gate */ 13237c478bd9Sstevel@tonic-gate size = resolvepath(node, devnode, PATH_MAX); 13247c478bd9Sstevel@tonic-gate if ((size <= 0) || (size >= (PATH_MAX - 1))) 13257c478bd9Sstevel@tonic-gate return (NULL); 13267c478bd9Sstevel@tonic-gate 13277c478bd9Sstevel@tonic-gate /* resolvepath may not return a null terminated string */ 13287c478bd9Sstevel@tonic-gate devnode[size] = '\0'; 13297c478bd9Sstevel@tonic-gate 13307c478bd9Sstevel@tonic-gate 13317c478bd9Sstevel@tonic-gate /* the device node must be in /devices/ or /vol/dev/rdsk */ 13327c478bd9Sstevel@tonic-gate 13337c478bd9Sstevel@tonic-gate if ((strncmp(devnode, "/devices/", 9) != 0) && 13347c478bd9Sstevel@tonic-gate (strncmp(devnode, "/vol/dev/rdsk", 13) != 0)) 13357c478bd9Sstevel@tonic-gate return (NULL); 13367c478bd9Sstevel@tonic-gate 1337e3397557Szk194757 /* Turn on the privileges. */ 1338e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 13397c478bd9Sstevel@tonic-gate 13407c478bd9Sstevel@tonic-gate /* 13417c478bd9Sstevel@tonic-gate * Since we are currently running with the user euid it is 13427c478bd9Sstevel@tonic-gate * safe to try to open the file without checking access. 13437c478bd9Sstevel@tonic-gate */ 13447c478bd9Sstevel@tonic-gate 13457c478bd9Sstevel@tonic-gate fd = open(devnode, O_RDONLY|O_NDELAY); 13467c478bd9Sstevel@tonic-gate 1347e3397557Szk194757 /* Turn off the privileges. */ 1348e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 13497c478bd9Sstevel@tonic-gate 13507c478bd9Sstevel@tonic-gate if (fd < 0) { 13517c478bd9Sstevel@tonic-gate return (NULL); 13527c478bd9Sstevel@tonic-gate } 13537c478bd9Sstevel@tonic-gate 13547c478bd9Sstevel@tonic-gate dev = (device_t *)my_zalloc(sizeof (device_t)); 13557c478bd9Sstevel@tonic-gate 13567c478bd9Sstevel@tonic-gate dev->d_node = (char *)my_zalloc(strlen(devnode) + 1); 13577c478bd9Sstevel@tonic-gate (void) strcpy(dev->d_node, devnode); 13587c478bd9Sstevel@tonic-gate 13597c478bd9Sstevel@tonic-gate dev->d_fd = fd; 13607c478bd9Sstevel@tonic-gate 13617c478bd9Sstevel@tonic-gate dev->d_inq = (uchar_t *)my_zalloc(INQUIRY_DATA_LENGTH); 13627c478bd9Sstevel@tonic-gate 1363e3397557Szk194757 /* Turn on privileges. */ 1364e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 13657c478bd9Sstevel@tonic-gate if (!inquiry(fd, dev->d_inq)) { 13667c478bd9Sstevel@tonic-gate DPRINTF1("USCSI ioctl failed %d\n", 13677c478bd9Sstevel@tonic-gate uscsi_error); 13687c478bd9Sstevel@tonic-gate free(dev->d_inq); 13697c478bd9Sstevel@tonic-gate free(dev->d_node); 13707c478bd9Sstevel@tonic-gate (void) close(dev->d_fd); 13717c478bd9Sstevel@tonic-gate free(dev); 1372e3397557Szk194757 /* Turn off privileges. */ 1373e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 13747c478bd9Sstevel@tonic-gate return (NULL); 13757c478bd9Sstevel@tonic-gate } 1376e3397557Szk194757 /* Turn off privileges. */ 1377e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 13787c478bd9Sstevel@tonic-gate 13797c478bd9Sstevel@tonic-gate if (user_supplied) { 13807c478bd9Sstevel@tonic-gate dev->d_name = (char *)my_zalloc(strlen(user_supplied) + 1); 13817c478bd9Sstevel@tonic-gate (void) strcpy(dev->d_name, user_supplied); 13827c478bd9Sstevel@tonic-gate } 13837c478bd9Sstevel@tonic-gate return (dev); 13847c478bd9Sstevel@tonic-gate } 13857c478bd9Sstevel@tonic-gate 13867c478bd9Sstevel@tonic-gate /* 13877c478bd9Sstevel@tonic-gate * Check for device specific characteristics. 13887c478bd9Sstevel@tonic-gate */ 13897c478bd9Sstevel@tonic-gate int 13907c478bd9Sstevel@tonic-gate check_device(device_t *dev, int cond) 13917c478bd9Sstevel@tonic-gate { 13927c478bd9Sstevel@tonic-gate uchar_t page_code[4]; 13937c478bd9Sstevel@tonic-gate 13947c478bd9Sstevel@tonic-gate /* Look at the capabilities page for this information */ 13957c478bd9Sstevel@tonic-gate if (cond & CHECK_DEVICE_IS_CD_WRITABLE) { 13967c478bd9Sstevel@tonic-gate if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) && 13977c478bd9Sstevel@tonic-gate (page_code[3] & 1)) { 13987c478bd9Sstevel@tonic-gate return (1); 13997c478bd9Sstevel@tonic-gate } 14007c478bd9Sstevel@tonic-gate } 14017c478bd9Sstevel@tonic-gate 14027c478bd9Sstevel@tonic-gate if (cond & CHECK_DEVICE_IS_DVD_WRITABLE) { 14037c478bd9Sstevel@tonic-gate if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) && 14047c478bd9Sstevel@tonic-gate (page_code[3] & 0x10)) { 14057c478bd9Sstevel@tonic-gate return (1); 14067c478bd9Sstevel@tonic-gate } 14077c478bd9Sstevel@tonic-gate } 14087c478bd9Sstevel@tonic-gate 14097c478bd9Sstevel@tonic-gate if (cond & CHECK_DEVICE_IS_DVD_READABLE) { 14107c478bd9Sstevel@tonic-gate if (get_mode_page(dev->d_fd, 0x2a, 0, 4, page_code) && 14117c478bd9Sstevel@tonic-gate (page_code[2] & 0x8)) { 14127c478bd9Sstevel@tonic-gate return (1); 14137c478bd9Sstevel@tonic-gate } 14147c478bd9Sstevel@tonic-gate } 14157c478bd9Sstevel@tonic-gate 14167c478bd9Sstevel@tonic-gate return (0); 14177c478bd9Sstevel@tonic-gate } 14187c478bd9Sstevel@tonic-gate 14197c478bd9Sstevel@tonic-gate /* 14207c478bd9Sstevel@tonic-gate * Builds an open()able device path from a user supplied node which can be 14217c478bd9Sstevel@tonic-gate * of the * form of /dev/[r]dsk/cxtxdx[sx] or cxtxdx[sx] or volmgt-name like 14227c478bd9Sstevel@tonic-gate * cdrom[n]. 14237c478bd9Sstevel@tonic-gate * Returns the path found in 'found' and returns 1. Otherwise returns 0. 14247c478bd9Sstevel@tonic-gate */ 14257c478bd9Sstevel@tonic-gate int 14267c478bd9Sstevel@tonic-gate lookup_device(char *supplied, char *found) 14277c478bd9Sstevel@tonic-gate { 14287c478bd9Sstevel@tonic-gate struct stat statbuf; 14297c478bd9Sstevel@tonic-gate int fd; 14307c478bd9Sstevel@tonic-gate char tmpstr[PATH_MAX]; 14317c478bd9Sstevel@tonic-gate 1432e3397557Szk194757 /* Turn on privileges */ 1433e3397557Szk194757 (void) __priv_bracket(PRIV_ON); 14347c478bd9Sstevel@tonic-gate 14357c478bd9Sstevel@tonic-gate /* If everything is fine and proper, no need to analyze */ 14364bc0a2efScasper if ((stat(supplied, &statbuf) == 0) && S_ISCHR(statbuf.st_mode) && 14377c478bd9Sstevel@tonic-gate ((fd = open(supplied, O_RDONLY|O_NDELAY)) >= 0)) { 14387c478bd9Sstevel@tonic-gate (void) close(fd); 14397c478bd9Sstevel@tonic-gate (void) strlcpy(found, supplied, PATH_MAX); 1440e3397557Szk194757 /* Turn off privilege */ 1441e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 14427c478bd9Sstevel@tonic-gate return (1); 14437c478bd9Sstevel@tonic-gate } 14447c478bd9Sstevel@tonic-gate 1445e3397557Szk194757 /* Turn off privileges. */ 1446e3397557Szk194757 (void) __priv_bracket(PRIV_OFF); 14477c478bd9Sstevel@tonic-gate 14487c478bd9Sstevel@tonic-gate if (strncmp(supplied, "/dev/rdsk/", 10) == 0) 14497c478bd9Sstevel@tonic-gate return (vol_lookup(supplied, found)); 14507c478bd9Sstevel@tonic-gate if (strncmp(supplied, "/dev/dsk/", 9) == 0) { 14517c478bd9Sstevel@tonic-gate (void) snprintf(tmpstr, PATH_MAX, "/dev/rdsk/%s", 14527c478bd9Sstevel@tonic-gate (char *)strrchr(supplied, '/')); 14537c478bd9Sstevel@tonic-gate 14547c478bd9Sstevel@tonic-gate if ((fd = open(tmpstr, O_RDONLY|O_NDELAY)) >= 0) { 14557c478bd9Sstevel@tonic-gate (void) close(fd); 14567c478bd9Sstevel@tonic-gate (void) strlcpy(found, supplied, PATH_MAX); 14577c478bd9Sstevel@tonic-gate return (1); 14587c478bd9Sstevel@tonic-gate } 14597c478bd9Sstevel@tonic-gate if ((access(tmpstr, F_OK) == 0) && vol_running) 14607c478bd9Sstevel@tonic-gate return (vol_lookup(tmpstr, found)); 14617c478bd9Sstevel@tonic-gate else 14627c478bd9Sstevel@tonic-gate return (0); 14637c478bd9Sstevel@tonic-gate } 14647c478bd9Sstevel@tonic-gate if ((strncmp(supplied, "cdrom", 5) != 0) && 14657c478bd9Sstevel@tonic-gate (strlen(supplied) < 32)) { 14667c478bd9Sstevel@tonic-gate (void) snprintf(tmpstr, sizeof (tmpstr), "/dev/rdsk/%s", 14677c478bd9Sstevel@tonic-gate supplied); 14687c478bd9Sstevel@tonic-gate if (access(tmpstr, F_OK) < 0) { 14697c478bd9Sstevel@tonic-gate (void) strcat(tmpstr, "s2"); 14707c478bd9Sstevel@tonic-gate } 14717c478bd9Sstevel@tonic-gate if ((fd = open(tmpstr, O_RDONLY|O_NDELAY)) >= 0) { 14727c478bd9Sstevel@tonic-gate (void) close(fd); 14737c478bd9Sstevel@tonic-gate (void) strlcpy(found, tmpstr, PATH_MAX); 14747c478bd9Sstevel@tonic-gate return (1); 14757c478bd9Sstevel@tonic-gate } 14767c478bd9Sstevel@tonic-gate if ((access(tmpstr, F_OK) == 0) && vol_running) 14777c478bd9Sstevel@tonic-gate return (vol_lookup(tmpstr, found)); 14787c478bd9Sstevel@tonic-gate } 14797c478bd9Sstevel@tonic-gate return (vol_name_to_dev_node(supplied, found)); 14807c478bd9Sstevel@tonic-gate } 14817c478bd9Sstevel@tonic-gate 14827c478bd9Sstevel@tonic-gate int 14837c478bd9Sstevel@tonic-gate is_cd(char *node) 14847c478bd9Sstevel@tonic-gate { 14857c478bd9Sstevel@tonic-gate int fd; 14867c478bd9Sstevel@tonic-gate struct dk_cinfo cinfo; 14877c478bd9Sstevel@tonic-gate 14887c478bd9Sstevel@tonic-gate fd = open(node, O_RDONLY|O_NDELAY); 14897c478bd9Sstevel@tonic-gate if (fd < 0) 14907c478bd9Sstevel@tonic-gate return (0); 14917c478bd9Sstevel@tonic-gate if (ioctl(fd, DKIOCINFO, &cinfo) < 0) { 14927c478bd9Sstevel@tonic-gate (void) close(fd); 14937c478bd9Sstevel@tonic-gate return (0); 14947c478bd9Sstevel@tonic-gate } 14957c478bd9Sstevel@tonic-gate if (cinfo.dki_ctype != DKC_CDROM) 14967c478bd9Sstevel@tonic-gate return (0); 14977c478bd9Sstevel@tonic-gate return (1); 14987c478bd9Sstevel@tonic-gate } 14997c478bd9Sstevel@tonic-gate 15007c478bd9Sstevel@tonic-gate void 15017c478bd9Sstevel@tonic-gate print_header(void) 15027c478bd9Sstevel@tonic-gate { 15037c478bd9Sstevel@tonic-gate /* l10n_NOTE : Column spacing should be kept same */ 15047c478bd9Sstevel@tonic-gate (void) printf(gettext(" Node " 15057c478bd9Sstevel@tonic-gate "Connected Device")); 15067c478bd9Sstevel@tonic-gate /* l10n_NOTE : Column spacing should be kept same */ 15077c478bd9Sstevel@tonic-gate (void) printf(gettext(" Device type\n")); 15087c478bd9Sstevel@tonic-gate (void) printf( 15097c478bd9Sstevel@tonic-gate "---------------------------+---------------------------"); 15107c478bd9Sstevel@tonic-gate (void) printf("-----+----------------\n"); 15117c478bd9Sstevel@tonic-gate } 15127c478bd9Sstevel@tonic-gate 15137c478bd9Sstevel@tonic-gate void 15147c478bd9Sstevel@tonic-gate print_divider(void) 15157c478bd9Sstevel@tonic-gate { 15167c478bd9Sstevel@tonic-gate (void) printf( 15177c478bd9Sstevel@tonic-gate "---------------------------+---------------------------"); 15187c478bd9Sstevel@tonic-gate (void) printf("-----+----------------\n"); 15197c478bd9Sstevel@tonic-gate } 15207c478bd9Sstevel@tonic-gate 15217c478bd9Sstevel@tonic-gate static void 15227c478bd9Sstevel@tonic-gate fini_device(device_t *dev) 15237c478bd9Sstevel@tonic-gate { 15247c478bd9Sstevel@tonic-gate free(dev->d_inq); 15257c478bd9Sstevel@tonic-gate free(dev->d_node); 15267c478bd9Sstevel@tonic-gate (void) close(dev->d_fd); 15277c478bd9Sstevel@tonic-gate if (dev->d_name) 15287c478bd9Sstevel@tonic-gate free(dev->d_name); 15297c478bd9Sstevel@tonic-gate free(dev); 15307c478bd9Sstevel@tonic-gate } 15317c478bd9Sstevel@tonic-gate 15327c478bd9Sstevel@tonic-gate void * 15337c478bd9Sstevel@tonic-gate my_zalloc(size_t size) 15347c478bd9Sstevel@tonic-gate { 15357c478bd9Sstevel@tonic-gate void *ret; 15367c478bd9Sstevel@tonic-gate 15377c478bd9Sstevel@tonic-gate ret = malloc(size); 15387c478bd9Sstevel@tonic-gate if (ret == NULL) { 15397c478bd9Sstevel@tonic-gate 15407c478bd9Sstevel@tonic-gate /* Lets wait a sec. and try again */ 15417c478bd9Sstevel@tonic-gate if (errno == EAGAIN) { 15427c478bd9Sstevel@tonic-gate (void) sleep(1); 15437c478bd9Sstevel@tonic-gate ret = malloc(size); 15447c478bd9Sstevel@tonic-gate } 15457c478bd9Sstevel@tonic-gate 15467c478bd9Sstevel@tonic-gate if (ret == NULL) { 15477c478bd9Sstevel@tonic-gate (void) err_msg("%s\n", gettext(strerror(errno))); 15487c478bd9Sstevel@tonic-gate (void) err_msg(gettext( 15497c478bd9Sstevel@tonic-gate "Memory allocation failure, Exiting...\n")); 15507c478bd9Sstevel@tonic-gate exit(1); 15517c478bd9Sstevel@tonic-gate } 15527c478bd9Sstevel@tonic-gate } 15537c478bd9Sstevel@tonic-gate (void) memset(ret, 0, size); 15547c478bd9Sstevel@tonic-gate return (ret); 15557c478bd9Sstevel@tonic-gate } 15567c478bd9Sstevel@tonic-gate 15577c478bd9Sstevel@tonic-gate static int 15587c478bd9Sstevel@tonic-gate vol_name_to_dev_node(char *vname, char *found) 15597c478bd9Sstevel@tonic-gate { 15607c478bd9Sstevel@tonic-gate struct stat statbuf; 15617c478bd9Sstevel@tonic-gate char *p1; 15627c478bd9Sstevel@tonic-gate int i; 15637c478bd9Sstevel@tonic-gate 15647c478bd9Sstevel@tonic-gate if (vname == NULL) 15657c478bd9Sstevel@tonic-gate return (0); 15667c478bd9Sstevel@tonic-gate if (vol_running) 15677c478bd9Sstevel@tonic-gate (void) volmgt_check(vname); 15687c478bd9Sstevel@tonic-gate p1 = media_findname(vname); 15697c478bd9Sstevel@tonic-gate if (p1 == NULL) 15707c478bd9Sstevel@tonic-gate return (0); 15717c478bd9Sstevel@tonic-gate if (stat(p1, &statbuf) < 0) { 15727c478bd9Sstevel@tonic-gate free(p1); 15737c478bd9Sstevel@tonic-gate return (0); 15747c478bd9Sstevel@tonic-gate } 15754bc0a2efScasper if (S_ISDIR(statbuf.st_mode)) { 15767c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) { 15777c478bd9Sstevel@tonic-gate (void) snprintf(found, PATH_MAX, "%s/s%d", p1, i); 15787c478bd9Sstevel@tonic-gate if (access(found, F_OK) >= 0) 15797c478bd9Sstevel@tonic-gate break; 15807c478bd9Sstevel@tonic-gate } 15817c478bd9Sstevel@tonic-gate if (i == 16) { 15827c478bd9Sstevel@tonic-gate free(p1); 15837c478bd9Sstevel@tonic-gate return (0); 15847c478bd9Sstevel@tonic-gate } 15857c478bd9Sstevel@tonic-gate } else { 15867c478bd9Sstevel@tonic-gate (void) strlcpy(found, p1, PATH_MAX); 15877c478bd9Sstevel@tonic-gate } 15887c478bd9Sstevel@tonic-gate free(p1); 15897c478bd9Sstevel@tonic-gate return (1); 15907c478bd9Sstevel@tonic-gate } 15917c478bd9Sstevel@tonic-gate 15927c478bd9Sstevel@tonic-gate /* 15937c478bd9Sstevel@tonic-gate * Searches for volume manager's equivalent char device for the 15947c478bd9Sstevel@tonic-gate * supplied pathname which is of the form of /dev/rdsk/cxtxdxsx 15957c478bd9Sstevel@tonic-gate */ 15967c478bd9Sstevel@tonic-gate static int 15977c478bd9Sstevel@tonic-gate vol_lookup(char *supplied, char *found) 15987c478bd9Sstevel@tonic-gate { 15997c478bd9Sstevel@tonic-gate char tmpstr[PATH_MAX], tmpstr1[PATH_MAX], *p; 16007c478bd9Sstevel@tonic-gate int i, ret; 16017c478bd9Sstevel@tonic-gate 16027c478bd9Sstevel@tonic-gate (void) strlcpy(tmpstr, supplied, PATH_MAX); 16037c478bd9Sstevel@tonic-gate if ((p = volmgt_symname(tmpstr)) == NULL) { 16047c478bd9Sstevel@tonic-gate if (strstr(tmpstr, "s2") != NULL) { 16057c478bd9Sstevel@tonic-gate *((char *)(strrchr(tmpstr, 's') + 1)) = 0; 16067c478bd9Sstevel@tonic-gate for (i = 0; i < 16; i++) { 16077c478bd9Sstevel@tonic-gate (void) snprintf(tmpstr1, PATH_MAX, "%s%d", 16087c478bd9Sstevel@tonic-gate tmpstr, i); 16097c478bd9Sstevel@tonic-gate if ((p = volmgt_symname(tmpstr1)) != NULL) 16107c478bd9Sstevel@tonic-gate break; 16117c478bd9Sstevel@tonic-gate } 16127c478bd9Sstevel@tonic-gate } else if (strstr(tmpstr, "p0") != NULL) { 16137c478bd9Sstevel@tonic-gate *((char *)(strrchr(tmpstr, 'p') + 1)) = 0; 16147c478bd9Sstevel@tonic-gate for (i = 0; i < 5; i++) { 16157c478bd9Sstevel@tonic-gate (void) snprintf(tmpstr1, PATH_MAX, "%s%d", 16167c478bd9Sstevel@tonic-gate tmpstr, i); 16177c478bd9Sstevel@tonic-gate if ((p = volmgt_symname(tmpstr1)) != NULL) 16187c478bd9Sstevel@tonic-gate break; 16197c478bd9Sstevel@tonic-gate } 16207c478bd9Sstevel@tonic-gate } else 16217c478bd9Sstevel@tonic-gate return (0); 16227c478bd9Sstevel@tonic-gate if (p == NULL) 16237c478bd9Sstevel@tonic-gate return (0); 16247c478bd9Sstevel@tonic-gate } 16257c478bd9Sstevel@tonic-gate 16267c478bd9Sstevel@tonic-gate ret = vol_name_to_dev_node(p, found); 16277c478bd9Sstevel@tonic-gate free(p); 16287c478bd9Sstevel@tonic-gate return (ret); 16297c478bd9Sstevel@tonic-gate } 16307c478bd9Sstevel@tonic-gate 16317c478bd9Sstevel@tonic-gate /*PRINTFLIKE1*/ 16327c478bd9Sstevel@tonic-gate void 16337c478bd9Sstevel@tonic-gate err_msg(char *fmt, ...) 16347c478bd9Sstevel@tonic-gate { 16357c478bd9Sstevel@tonic-gate va_list ap; 16367c478bd9Sstevel@tonic-gate 16377c478bd9Sstevel@tonic-gate va_start(ap, fmt); 16387c478bd9Sstevel@tonic-gate (void) vfprintf(stderr, fmt, ap); 16397c478bd9Sstevel@tonic-gate va_end(ap); 16407c478bd9Sstevel@tonic-gate } 16417c478bd9Sstevel@tonic-gate 16427c478bd9Sstevel@tonic-gate int 16437c478bd9Sstevel@tonic-gate inquiry(int fd, uchar_t *inq) 16447c478bd9Sstevel@tonic-gate { 16457c478bd9Sstevel@tonic-gate struct uscsi_cmd *scmd; 16467c478bd9Sstevel@tonic-gate 16477c478bd9Sstevel@tonic-gate scmd = get_uscsi_cmd(); 16487c478bd9Sstevel@tonic-gate scmd->uscsi_flags = USCSI_READ|USCSI_SILENT; 16497c478bd9Sstevel@tonic-gate scmd->uscsi_timeout = DEFAULT_SCSI_TIMEOUT; 16507c478bd9Sstevel@tonic-gate scmd->uscsi_cdb[0] = INQUIRY_CMD; 16517c478bd9Sstevel@tonic-gate scmd->uscsi_cdb[4] = INQUIRY_DATA_LENGTH; 16527c478bd9Sstevel@tonic-gate scmd->uscsi_cdblen = 6; 16537c478bd9Sstevel@tonic-gate scmd->uscsi_bufaddr = (char *)inq; 16547c478bd9Sstevel@tonic-gate scmd->uscsi_buflen = INQUIRY_DATA_LENGTH; 16557c478bd9Sstevel@tonic-gate if ((uscsi_error = uscsi(fd, scmd)) < 0) 16567c478bd9Sstevel@tonic-gate return (0); 16577c478bd9Sstevel@tonic-gate return (1); 16587c478bd9Sstevel@tonic-gate } 16597c478bd9Sstevel@tonic-gate 16607c478bd9Sstevel@tonic-gate struct uscsi_cmd * 16617c478bd9Sstevel@tonic-gate get_uscsi_cmd(void) 16627c478bd9Sstevel@tonic-gate { 16637c478bd9Sstevel@tonic-gate (void) memset(&uscmd, 0, sizeof (uscmd)); 16647c478bd9Sstevel@tonic-gate (void) memset(ucdb, 0, 16); 16657c478bd9Sstevel@tonic-gate uscmd.uscsi_cdb = ucdb; 16667c478bd9Sstevel@tonic-gate return (&uscmd); 16677c478bd9Sstevel@tonic-gate } 16687c478bd9Sstevel@tonic-gate 16697c478bd9Sstevel@tonic-gate int 16707c478bd9Sstevel@tonic-gate uscsi(int fd, struct uscsi_cmd *scmd) 16717c478bd9Sstevel@tonic-gate { 16727c478bd9Sstevel@tonic-gate int ret, global_rqsense; 16737c478bd9Sstevel@tonic-gate int retries, max_retries = 5; 16747c478bd9Sstevel@tonic-gate int i; 16757c478bd9Sstevel@tonic-gate 16767c478bd9Sstevel@tonic-gate /* set up for request sense extensions */ 16777c478bd9Sstevel@tonic-gate if (!(scmd->uscsi_flags & USCSI_RQENABLE)) { 16787c478bd9Sstevel@tonic-gate scmd->uscsi_flags |= USCSI_RQENABLE; 16797c478bd9Sstevel@tonic-gate scmd->uscsi_rqlen = RQBUFLEN; 16807c478bd9Sstevel@tonic-gate scmd->uscsi_rqbuf = rqbuf; 16817c478bd9Sstevel@tonic-gate global_rqsense = 1; 16827c478bd9Sstevel@tonic-gate } else { 16837c478bd9Sstevel@tonic-gate global_rqsense = 0; 16847c478bd9Sstevel@tonic-gate } 16857c478bd9Sstevel@tonic-gate 16867c478bd9Sstevel@tonic-gate /* 16877c478bd9Sstevel@tonic-gate * The device may be busy or slow and fail with a not ready status. 16887c478bd9Sstevel@tonic-gate * we'll allow a limited number of retries to give the drive time 16897c478bd9Sstevel@tonic-gate * to recover. 16907c478bd9Sstevel@tonic-gate */ 16917c478bd9Sstevel@tonic-gate for (retries = 0; retries < max_retries; retries++) { 16927c478bd9Sstevel@tonic-gate 16937c478bd9Sstevel@tonic-gate scmd->uscsi_status = 0; 16947c478bd9Sstevel@tonic-gate 16957c478bd9Sstevel@tonic-gate if (global_rqsense) 16967c478bd9Sstevel@tonic-gate (void) memset(rqbuf, 0, RQBUFLEN); 16977c478bd9Sstevel@tonic-gate 16987c478bd9Sstevel@tonic-gate DPRINTF("cmd:["); 16997c478bd9Sstevel@tonic-gate for (i = 0; i < scmd->uscsi_cdblen; i++) 17007c478bd9Sstevel@tonic-gate DPRINTF1("0x%02x ", 17017c478bd9Sstevel@tonic-gate (uchar_t)scmd->uscsi_cdb[i]); 17027c478bd9Sstevel@tonic-gate DPRINTF("]\n"); 17037c478bd9Sstevel@tonic-gate 17047c478bd9Sstevel@tonic-gate /* 17057c478bd9Sstevel@tonic-gate * We need to have root privledges in order to use 17067c478bd9Sstevel@tonic-gate * uscsi commands on the device. 17077c478bd9Sstevel@tonic-gate */ 17087c478bd9Sstevel@tonic-gate 17097c478bd9Sstevel@tonic-gate ret = ioctl(fd, USCSICMD, scmd); 17107c478bd9Sstevel@tonic-gate 17117c478bd9Sstevel@tonic-gate /* maintain consistency in case of sgen */ 17127c478bd9Sstevel@tonic-gate if ((ret == 0) && (scmd->uscsi_status == 2)) { 17137c478bd9Sstevel@tonic-gate ret = -1; 17147c478bd9Sstevel@tonic-gate errno = EIO; 17157c478bd9Sstevel@tonic-gate } 17167c478bd9Sstevel@tonic-gate 17177c478bd9Sstevel@tonic-gate /* if error and extended request sense, retrieve errors */ 17187c478bd9Sstevel@tonic-gate if (global_rqsense && (ret < 0) && (scmd->uscsi_status == 2)) { 17197c478bd9Sstevel@tonic-gate /* 17207c478bd9Sstevel@tonic-gate * The drive is not ready to recieve commands but 17217c478bd9Sstevel@tonic-gate * may be in the process of becoming ready. 17227c478bd9Sstevel@tonic-gate * sleep for a short time then retry command. 17237c478bd9Sstevel@tonic-gate * SENSE/ASC = 2/4 : not ready 17247c478bd9Sstevel@tonic-gate * ASCQ = 0 Not Reportable. 17257c478bd9Sstevel@tonic-gate * ASCQ = 1 Becoming ready. 17267c478bd9Sstevel@tonic-gate */ 17277c478bd9Sstevel@tonic-gate if ((SENSE_KEY(rqbuf) == 2) && (ASC(rqbuf) == 4) && 17287c478bd9Sstevel@tonic-gate ((ASCQ(rqbuf) == 0) || (ASCQ(rqbuf) == 1))) { 17297c478bd9Sstevel@tonic-gate total_retries++; 17307c478bd9Sstevel@tonic-gate (void) sleep(3); 17317c478bd9Sstevel@tonic-gate continue; 17327c478bd9Sstevel@tonic-gate } 17337c478bd9Sstevel@tonic-gate 17347c478bd9Sstevel@tonic-gate /* 17357c478bd9Sstevel@tonic-gate * Device is not ready to transmit or a device reset 17367c478bd9Sstevel@tonic-gate * has occurred. wait for a short period of time then 17377c478bd9Sstevel@tonic-gate * retry the command. 17387c478bd9Sstevel@tonic-gate */ 17397c478bd9Sstevel@tonic-gate if ((SENSE_KEY(rqbuf) == 6) && ((ASC(rqbuf) == 0x28) || 17407c478bd9Sstevel@tonic-gate (ASC(rqbuf) == 0x29))) { 17417c478bd9Sstevel@tonic-gate (void) sleep(3); 17427c478bd9Sstevel@tonic-gate total_retries++; 17437c478bd9Sstevel@tonic-gate continue; 17447c478bd9Sstevel@tonic-gate } 17457c478bd9Sstevel@tonic-gate 17467c478bd9Sstevel@tonic-gate DPRINTF3("cmd: 0x%02x ret:%i status:%02x ", 17477c478bd9Sstevel@tonic-gate (uchar_t)scmd->uscsi_cdb[0], ret, 17487c478bd9Sstevel@tonic-gate scmd->uscsi_status); 17497c478bd9Sstevel@tonic-gate DPRINTF3(" sense: %02x ASC: %02x ASCQ:%02x\n", 17507c478bd9Sstevel@tonic-gate (uchar_t)SENSE_KEY(rqbuf), 17517c478bd9Sstevel@tonic-gate (uchar_t)ASC(rqbuf), (uchar_t)ASCQ(rqbuf)); 17527c478bd9Sstevel@tonic-gate } 17537c478bd9Sstevel@tonic-gate 17547c478bd9Sstevel@tonic-gate /* no errors we'll return */ 17557c478bd9Sstevel@tonic-gate break; 17567c478bd9Sstevel@tonic-gate } 17577c478bd9Sstevel@tonic-gate 17587c478bd9Sstevel@tonic-gate /* store the error status for later debug printing */ 17597c478bd9Sstevel@tonic-gate if ((ret < 0) && (global_rqsense)) { 17607c478bd9Sstevel@tonic-gate uscsi_status = scmd->uscsi_status; 17617c478bd9Sstevel@tonic-gate rqstatus = scmd->uscsi_rqstatus; 17627c478bd9Sstevel@tonic-gate rqresid = scmd->uscsi_rqresid; 17637c478bd9Sstevel@tonic-gate 17647c478bd9Sstevel@tonic-gate } 17657c478bd9Sstevel@tonic-gate 17667c478bd9Sstevel@tonic-gate DPRINTF1("total retries: %d\n", total_retries); 17677c478bd9Sstevel@tonic-gate 17687c478bd9Sstevel@tonic-gate return (ret); 17697c478bd9Sstevel@tonic-gate } 17707c478bd9Sstevel@tonic-gate 17717c478bd9Sstevel@tonic-gate /* 17727c478bd9Sstevel@tonic-gate * will get the mode page only i.e. will strip off the header. 17737c478bd9Sstevel@tonic-gate */ 17747c478bd9Sstevel@tonic-gate int 17757c478bd9Sstevel@tonic-gate get_mode_page(int fd, int page_no, int pc, int buf_len, uchar_t *buffer) 17767c478bd9Sstevel@tonic-gate { 17777c478bd9Sstevel@tonic-gate int ret; 17787c478bd9Sstevel@tonic-gate uchar_t byte2, *buf; 17797c478bd9Sstevel@tonic-gate uint_t header_len, page_len, copy_cnt; 17807c478bd9Sstevel@tonic-gate 17817c478bd9Sstevel@tonic-gate byte2 = (uchar_t)(((pc << 6) & 0xC0) | (page_no & 0x3f)); 17827c478bd9Sstevel@tonic-gate buf = (uchar_t *)my_zalloc(256); 17837c478bd9Sstevel@tonic-gate 17847c478bd9Sstevel@tonic-gate /* Ask 254 bytes only to make our IDE driver happy */ 17857c478bd9Sstevel@tonic-gate ret = mode_sense(fd, byte2, 1, 254, buf); 17867c478bd9Sstevel@tonic-gate if (ret == 0) { 17877c478bd9Sstevel@tonic-gate free(buf); 17887c478bd9Sstevel@tonic-gate return (0); 17897c478bd9Sstevel@tonic-gate } 17907c478bd9Sstevel@tonic-gate 17917c478bd9Sstevel@tonic-gate header_len = 8 + read_scsi16(&buf[6]); 17927c478bd9Sstevel@tonic-gate page_len = buf[header_len + 1] + 2; 17937c478bd9Sstevel@tonic-gate 17947c478bd9Sstevel@tonic-gate copy_cnt = (page_len > buf_len) ? buf_len : page_len; 17957c478bd9Sstevel@tonic-gate (void) memcpy(buffer, &buf[header_len], copy_cnt); 17967c478bd9Sstevel@tonic-gate free(buf); 17977c478bd9Sstevel@tonic-gate 17987c478bd9Sstevel@tonic-gate return (1); 17997c478bd9Sstevel@tonic-gate } 18007c478bd9Sstevel@tonic-gate 18017c478bd9Sstevel@tonic-gate int 18027c478bd9Sstevel@tonic-gate mode_sense(int fd, uchar_t pc, int dbd, int page_len, uchar_t *buffer) 18037c478bd9Sstevel@tonic-gate { 18047c478bd9Sstevel@tonic-gate struct uscsi_cmd *scmd; 18057c478bd9Sstevel@tonic-gate 18067c478bd9Sstevel@tonic-gate scmd = get_uscsi_cmd(); 18077c478bd9Sstevel@tonic-gate scmd->uscsi_flags = USCSI_READ|USCSI_SILENT; 18087c478bd9Sstevel@tonic-gate scmd->uscsi_buflen = page_len; 18097c478bd9Sstevel@tonic-gate scmd->uscsi_bufaddr = (char *)buffer; 18107c478bd9Sstevel@tonic-gate scmd->uscsi_timeout = DEFAULT_SCSI_TIMEOUT; 18117c478bd9Sstevel@tonic-gate scmd->uscsi_cdblen = 0xa; 18127c478bd9Sstevel@tonic-gate scmd->uscsi_cdb[0] = MODE_SENSE_10_CMD; 18137c478bd9Sstevel@tonic-gate if (dbd) { 18147c478bd9Sstevel@tonic-gate /* don't return any block descriptors */ 18157c478bd9Sstevel@tonic-gate scmd->uscsi_cdb[1] = 0x8; 18167c478bd9Sstevel@tonic-gate } 18177c478bd9Sstevel@tonic-gate /* the page code we want */ 18187c478bd9Sstevel@tonic-gate scmd->uscsi_cdb[2] = pc; 18197c478bd9Sstevel@tonic-gate /* allocation length */ 18207c478bd9Sstevel@tonic-gate scmd->uscsi_cdb[7] = (page_len >> 8) & 0xff; 18217c478bd9Sstevel@tonic-gate scmd->uscsi_cdb[8] = page_len & 0xff; 18227c478bd9Sstevel@tonic-gate 18237c478bd9Sstevel@tonic-gate if ((uscsi_error = uscsi(fd, scmd)) < 0) 18247c478bd9Sstevel@tonic-gate return (0); 18257c478bd9Sstevel@tonic-gate return (1); 18267c478bd9Sstevel@tonic-gate } 18277c478bd9Sstevel@tonic-gate 18287c478bd9Sstevel@tonic-gate uint16_t 18297c478bd9Sstevel@tonic-gate read_scsi16(void *addr) 18307c478bd9Sstevel@tonic-gate { 18317c478bd9Sstevel@tonic-gate uchar_t *ad = (uchar_t *)addr; 18327c478bd9Sstevel@tonic-gate uint16_t ret; 18337c478bd9Sstevel@tonic-gate 18347c478bd9Sstevel@tonic-gate ret = ((((uint16_t)ad[0]) << 8) | ad[1]); 18357c478bd9Sstevel@tonic-gate return (ret); 18367c478bd9Sstevel@tonic-gate } 18377c478bd9Sstevel@tonic-gate 18387c478bd9Sstevel@tonic-gate /* 18397c478bd9Sstevel@tonic-gate * Allocate space for and return a pointer to a string 18407c478bd9Sstevel@tonic-gate * on the stack. If the string is null, create 18417c478bd9Sstevel@tonic-gate * an empty string. 18427c478bd9Sstevel@tonic-gate * Use destroy_data() to free when no longer used. 18437c478bd9Sstevel@tonic-gate */ 18447c478bd9Sstevel@tonic-gate char * 18457c478bd9Sstevel@tonic-gate alloc_string(s) 18467c478bd9Sstevel@tonic-gate char *s; 18477c478bd9Sstevel@tonic-gate { 18487c478bd9Sstevel@tonic-gate char *ns; 18497c478bd9Sstevel@tonic-gate 18507c478bd9Sstevel@tonic-gate if (s == (char *)NULL) { 18517c478bd9Sstevel@tonic-gate ns = (char *)my_zalloc(1); 18527c478bd9Sstevel@tonic-gate } else { 18537c478bd9Sstevel@tonic-gate ns = (char *)my_zalloc(strlen(s) + 1); 18547c478bd9Sstevel@tonic-gate (void) strcpy(ns, s); 18557c478bd9Sstevel@tonic-gate } 18567c478bd9Sstevel@tonic-gate return (ns); 18577c478bd9Sstevel@tonic-gate } 18587c478bd9Sstevel@tonic-gate 18597c478bd9Sstevel@tonic-gate /* 18607c478bd9Sstevel@tonic-gate * Follow symbolic links from the logical device name to 18617c478bd9Sstevel@tonic-gate * the /devfs physical device name. To be complete, we 18627c478bd9Sstevel@tonic-gate * handle the case of multiple links. This function 18637c478bd9Sstevel@tonic-gate * either returns NULL (no links, or some other error), 18647c478bd9Sstevel@tonic-gate * or the physical device name, alloc'ed on the heap. 18657c478bd9Sstevel@tonic-gate * 18667c478bd9Sstevel@tonic-gate * Note that the standard /devices prefix is stripped from 18677c478bd9Sstevel@tonic-gate * the final pathname, if present. The trailing options 18687c478bd9Sstevel@tonic-gate * are also removed (":c, raw"). 18697c478bd9Sstevel@tonic-gate */ 18707c478bd9Sstevel@tonic-gate static char * 18717c478bd9Sstevel@tonic-gate get_physical_name(char *path) 18727c478bd9Sstevel@tonic-gate { 18737c478bd9Sstevel@tonic-gate struct stat stbuf; 18747c478bd9Sstevel@tonic-gate int i; 18757c478bd9Sstevel@tonic-gate int level; 18767c478bd9Sstevel@tonic-gate char *p; 18777c478bd9Sstevel@tonic-gate char s[MAXPATHLEN]; 18787c478bd9Sstevel@tonic-gate char buf[MAXPATHLEN]; 18797c478bd9Sstevel@tonic-gate char dir[MAXPATHLEN]; 18807c478bd9Sstevel@tonic-gate char savedir[MAXPATHLEN]; 18817c478bd9Sstevel@tonic-gate char *result = NULL; 18827c478bd9Sstevel@tonic-gate 18837c478bd9Sstevel@tonic-gate if (getcwd(savedir, sizeof (savedir)) == NULL) { 18847c478bd9Sstevel@tonic-gate DPRINTF1("getcwd() failed - %s\n", strerror(errno)); 18857c478bd9Sstevel@tonic-gate return (NULL); 18867c478bd9Sstevel@tonic-gate } 18877c478bd9Sstevel@tonic-gate 18887c478bd9Sstevel@tonic-gate (void) strcpy(s, path); 18897c478bd9Sstevel@tonic-gate if ((p = strrchr(s, '/')) != NULL) { 18907c478bd9Sstevel@tonic-gate *p = 0; 18917c478bd9Sstevel@tonic-gate } 18927c478bd9Sstevel@tonic-gate if (s[0] == 0) { 18937c478bd9Sstevel@tonic-gate (void) strcpy(s, "/"); 18947c478bd9Sstevel@tonic-gate } 18957c478bd9Sstevel@tonic-gate if (chdir(s) == -1) { 18967c478bd9Sstevel@tonic-gate DPRINTF2("cannot chdir() to %s - %s\n", 18977c478bd9Sstevel@tonic-gate s, strerror(errno)); 18987c478bd9Sstevel@tonic-gate goto exit; 18997c478bd9Sstevel@tonic-gate } 19007c478bd9Sstevel@tonic-gate 19017c478bd9Sstevel@tonic-gate level = 0; 19027c478bd9Sstevel@tonic-gate (void) strcpy(s, path); 19037c478bd9Sstevel@tonic-gate for (;;) { 19047c478bd9Sstevel@tonic-gate /* 19057c478bd9Sstevel@tonic-gate * See if there's a real file out there. If not, 19067c478bd9Sstevel@tonic-gate * we have a dangling link and we ignore it. 19077c478bd9Sstevel@tonic-gate */ 19087c478bd9Sstevel@tonic-gate if (stat(s, &stbuf) == -1) { 19097c478bd9Sstevel@tonic-gate goto exit; 19107c478bd9Sstevel@tonic-gate } 19117c478bd9Sstevel@tonic-gate if (lstat(s, &stbuf) == -1) { 19127c478bd9Sstevel@tonic-gate DPRINTF2("%s: lstat() failed - %s\n", 19137c478bd9Sstevel@tonic-gate s, strerror(errno)); 19147c478bd9Sstevel@tonic-gate goto exit; 19157c478bd9Sstevel@tonic-gate } 19167c478bd9Sstevel@tonic-gate /* 19177c478bd9Sstevel@tonic-gate * If the file is not a link, we're done one 19187c478bd9Sstevel@tonic-gate * way or the other. If there were links, 19197c478bd9Sstevel@tonic-gate * return the full pathname of the resulting 19207c478bd9Sstevel@tonic-gate * file. 19217c478bd9Sstevel@tonic-gate */ 19227c478bd9Sstevel@tonic-gate if (!S_ISLNK(stbuf.st_mode)) { 19237c478bd9Sstevel@tonic-gate if (level > 0) { 19247c478bd9Sstevel@tonic-gate /* 19257c478bd9Sstevel@tonic-gate * Strip trailing options from the 19267c478bd9Sstevel@tonic-gate * physical device name 19277c478bd9Sstevel@tonic-gate */ 19287c478bd9Sstevel@tonic-gate if ((p = strrchr(s, ':')) != NULL) { 19297c478bd9Sstevel@tonic-gate *p = 0; 19307c478bd9Sstevel@tonic-gate } 19317c478bd9Sstevel@tonic-gate /* 19327c478bd9Sstevel@tonic-gate * Get the current directory, and 19337c478bd9Sstevel@tonic-gate * glue the pieces together. 19347c478bd9Sstevel@tonic-gate */ 19357c478bd9Sstevel@tonic-gate if (getcwd(dir, sizeof (dir)) == NULL) { 19367c478bd9Sstevel@tonic-gate DPRINTF1("getcwd() failed - %s\n", 19377c478bd9Sstevel@tonic-gate strerror(errno)); 19387c478bd9Sstevel@tonic-gate goto exit; 19397c478bd9Sstevel@tonic-gate } 19407c478bd9Sstevel@tonic-gate (void) strcat(dir, "/"); 19417c478bd9Sstevel@tonic-gate (void) strcat(dir, s); 19427c478bd9Sstevel@tonic-gate /* 19437c478bd9Sstevel@tonic-gate * If we have the standard fixed 19447c478bd9Sstevel@tonic-gate * /devices prefix, remove it. 19457c478bd9Sstevel@tonic-gate */ 19467c478bd9Sstevel@tonic-gate p = (strstr(dir, DEVFS_PREFIX) == dir) ? 19477c478bd9Sstevel@tonic-gate dir+strlen(DEVFS_PREFIX) : dir; 19487c478bd9Sstevel@tonic-gate result = alloc_string(p); 19497c478bd9Sstevel@tonic-gate } 19507c478bd9Sstevel@tonic-gate goto exit; 19517c478bd9Sstevel@tonic-gate } 19527c478bd9Sstevel@tonic-gate i = readlink(s, buf, sizeof (buf)); 19537c478bd9Sstevel@tonic-gate if (i == -1) { 19547c478bd9Sstevel@tonic-gate DPRINTF2("%s: readlink() failed - %s\n", 19557c478bd9Sstevel@tonic-gate s, strerror(errno)); 19567c478bd9Sstevel@tonic-gate goto exit; 19577c478bd9Sstevel@tonic-gate } 19587c478bd9Sstevel@tonic-gate level++; 19597c478bd9Sstevel@tonic-gate buf[i] = 0; 19607c478bd9Sstevel@tonic-gate 19617c478bd9Sstevel@tonic-gate /* 19627c478bd9Sstevel@tonic-gate * Break up the pathname into the directory 19637c478bd9Sstevel@tonic-gate * reference, if applicable and simple filename. 19647c478bd9Sstevel@tonic-gate * chdir()'ing to the directory allows us to 19657c478bd9Sstevel@tonic-gate * handle links with relative pathnames correctly. 19667c478bd9Sstevel@tonic-gate */ 19677c478bd9Sstevel@tonic-gate (void) strcpy(dir, buf); 19687c478bd9Sstevel@tonic-gate if ((p = strrchr(dir, '/')) != NULL) { 19697c478bd9Sstevel@tonic-gate *p = 0; 19707c478bd9Sstevel@tonic-gate if (chdir(dir) == -1) { 19717c478bd9Sstevel@tonic-gate DPRINTF2("cannot chdir() to %s - %s\n", 19727c478bd9Sstevel@tonic-gate dir, strerror(errno)); 19737c478bd9Sstevel@tonic-gate goto exit; 19747c478bd9Sstevel@tonic-gate } 19757c478bd9Sstevel@tonic-gate (void) strcpy(s, p+1); 19767c478bd9Sstevel@tonic-gate } else { 19777c478bd9Sstevel@tonic-gate (void) strcpy(s, buf); 19787c478bd9Sstevel@tonic-gate } 19797c478bd9Sstevel@tonic-gate } 19807c478bd9Sstevel@tonic-gate 19817c478bd9Sstevel@tonic-gate exit: 19827c478bd9Sstevel@tonic-gate if (chdir(savedir) == -1) { 19837c478bd9Sstevel@tonic-gate (void) printf("cannot chdir() to %s - %s\n", 19847c478bd9Sstevel@tonic-gate savedir, strerror(errno)); 19857c478bd9Sstevel@tonic-gate } 19867c478bd9Sstevel@tonic-gate 19877c478bd9Sstevel@tonic-gate return (result); 19887c478bd9Sstevel@tonic-gate } 19897c478bd9Sstevel@tonic-gate 19907c478bd9Sstevel@tonic-gate static void 19917c478bd9Sstevel@tonic-gate get_media_info(device_t *t_dev, char *sdev, char *pname, char *sn) 19927c478bd9Sstevel@tonic-gate { 19937c478bd9Sstevel@tonic-gate struct dk_cinfo cinfo; 1994342440ecSPrasad Singamsetty struct extvtoc vtocinfo; 19957c478bd9Sstevel@tonic-gate float size; 19967c478bd9Sstevel@tonic-gate int32_t fd; 19977c478bd9Sstevel@tonic-gate smedia_handle_t handle; 19987c478bd9Sstevel@tonic-gate struct dk_minfo mediainfo; 19997c478bd9Sstevel@tonic-gate int device_type; 20007c478bd9Sstevel@tonic-gate 20017c478bd9Sstevel@tonic-gate device_type = ioctl(t_dev->d_fd, DKIOCGMEDIAINFO, &mediainfo); 20027c478bd9Sstevel@tonic-gate 20037c478bd9Sstevel@tonic-gate /* 20047c478bd9Sstevel@tonic-gate * Determine bus type. 20057c478bd9Sstevel@tonic-gate */ 20067c478bd9Sstevel@tonic-gate if (!ioctl(t_dev->d_fd, DKIOCINFO, &cinfo)) { 20077c478bd9Sstevel@tonic-gate if (strstr(cinfo.dki_cname, "usb") || strstr(pname, "usb")) { 20087c478bd9Sstevel@tonic-gate (void) printf("\tBus: USB\n"); 20097c478bd9Sstevel@tonic-gate } else if (strstr(cinfo.dki_cname, "firewire") || 20107c478bd9Sstevel@tonic-gate strstr(pname, "firewire")) { 20117c478bd9Sstevel@tonic-gate (void) printf("\tBus: Firewire\n"); 20127c478bd9Sstevel@tonic-gate } else if (strstr(cinfo.dki_cname, "ide") || 20137c478bd9Sstevel@tonic-gate strstr(pname, "ide")) { 20147c478bd9Sstevel@tonic-gate (void) printf("\tBus: IDE\n"); 20157c478bd9Sstevel@tonic-gate } else if (strstr(cinfo.dki_cname, "scsi") || 20167c478bd9Sstevel@tonic-gate strstr(pname, "scsi")) { 20177c478bd9Sstevel@tonic-gate (void) printf("\tBus: SCSI\n"); 20187c478bd9Sstevel@tonic-gate } else { 20197c478bd9Sstevel@tonic-gate (void) printf("\tBus: <Unknown>\n"); 20207c478bd9Sstevel@tonic-gate } 20217c478bd9Sstevel@tonic-gate } else { 20227c478bd9Sstevel@tonic-gate (void) printf("\tBus: <Unknown>\n"); 20237c478bd9Sstevel@tonic-gate } 20247c478bd9Sstevel@tonic-gate 20257c478bd9Sstevel@tonic-gate /* 20267c478bd9Sstevel@tonic-gate * Calculate size of media. 20277c478bd9Sstevel@tonic-gate */ 20287c478bd9Sstevel@tonic-gate if (!device_type && 20297c478bd9Sstevel@tonic-gate (!ioctl(t_dev->d_fd, DKIOCGMEDIAINFO, &mediainfo))) { 20307c478bd9Sstevel@tonic-gate size = (mediainfo.dki_lbsize* 20317c478bd9Sstevel@tonic-gate mediainfo.dki_capacity)/(1024.0*1024.0); 20327c478bd9Sstevel@tonic-gate if (size < 1000) { 20337c478bd9Sstevel@tonic-gate (void) printf("\tSize: %.1f MB\n", size); 20347c478bd9Sstevel@tonic-gate } else { 20357c478bd9Sstevel@tonic-gate size = size/1000; 20367c478bd9Sstevel@tonic-gate (void) printf("\tSize: %.1f GB\n", size); 20377c478bd9Sstevel@tonic-gate } 20387c478bd9Sstevel@tonic-gate } else { 20397c478bd9Sstevel@tonic-gate (void) printf("\tSize: <Unknown>\n"); 20407c478bd9Sstevel@tonic-gate } 20417c478bd9Sstevel@tonic-gate 20427c478bd9Sstevel@tonic-gate /* 20437c478bd9Sstevel@tonic-gate * Print label. 20447c478bd9Sstevel@tonic-gate */ 2045342440ecSPrasad Singamsetty if (!device_type && (read_extvtoc(t_dev->d_fd, &vtocinfo) >= 0)) { 20467c478bd9Sstevel@tonic-gate if (*vtocinfo.v_volume) { 20477c478bd9Sstevel@tonic-gate (void) printf("\tLabel: %s\n", vtocinfo.v_volume); 20487c478bd9Sstevel@tonic-gate } else { 20497c478bd9Sstevel@tonic-gate (void) printf("\tLabel: <None>\n"); 20507c478bd9Sstevel@tonic-gate } 20517c478bd9Sstevel@tonic-gate } else { 20527c478bd9Sstevel@tonic-gate (void) printf("\tLabel: <Unknown>\n"); 20537c478bd9Sstevel@tonic-gate } 20547c478bd9Sstevel@tonic-gate 20557c478bd9Sstevel@tonic-gate /* 20567c478bd9Sstevel@tonic-gate * Acess permissions. 20577c478bd9Sstevel@tonic-gate */ 20587c478bd9Sstevel@tonic-gate if (device_type) { 20597c478bd9Sstevel@tonic-gate (void) printf("\tAccess permissions: <Unknown>\n"); 20607c478bd9Sstevel@tonic-gate return; 20617c478bd9Sstevel@tonic-gate } 20627c478bd9Sstevel@tonic-gate 2063*afb89a98SPavel Potoplyak (void) fprintf(stdout, gettext("\tAccess permissions: ")); 20647c478bd9Sstevel@tonic-gate if (sn) { 20657c478bd9Sstevel@tonic-gate /* 20667c478bd9Sstevel@tonic-gate * Set dev_name for process_p_flag(). 20677c478bd9Sstevel@tonic-gate */ 20687c478bd9Sstevel@tonic-gate dev_name = sn; 20697c478bd9Sstevel@tonic-gate fd = my_open(sn, O_RDONLY|O_NDELAY); 20707c478bd9Sstevel@tonic-gate } else { 20717c478bd9Sstevel@tonic-gate dev_name = sdev; 20727c478bd9Sstevel@tonic-gate fd = my_open(sdev, O_RDONLY|O_NDELAY); 20737c478bd9Sstevel@tonic-gate } 20747c478bd9Sstevel@tonic-gate if (fd < 0) { 20757c478bd9Sstevel@tonic-gate (void) printf("<Unknown>\n"); 20767c478bd9Sstevel@tonic-gate DPRINTF("Could not open device.\n"); 20777c478bd9Sstevel@tonic-gate (void) close(fd); 20787c478bd9Sstevel@tonic-gate } else { 20797c478bd9Sstevel@tonic-gate /* register the fd with the libsmedia */ 20807c478bd9Sstevel@tonic-gate handle = smedia_get_handle(fd); 20817c478bd9Sstevel@tonic-gate if (handle == NULL) { 20827c478bd9Sstevel@tonic-gate (void) printf("<Unknown>\n"); 20837c478bd9Sstevel@tonic-gate DPRINTF("Failed to get libsmedia handle.\n"); 20847c478bd9Sstevel@tonic-gate (void) close(fd); 20857c478bd9Sstevel@tonic-gate } else { 20867c478bd9Sstevel@tonic-gate process_p_flag(handle, fd); 208726e3e7deSphitran } 208826e3e7deSphitran } 20897c478bd9Sstevel@tonic-gate /* Clear dev_name */ 20907c478bd9Sstevel@tonic-gate dev_name = NULL; 20917c478bd9Sstevel@tonic-gate } 2092