1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate */ 26*7c478bd9Sstevel@tonic-gate 27*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*7c478bd9Sstevel@tonic-gate /*LINTLIBRARY*/ 29*7c478bd9Sstevel@tonic-gate 30*7c478bd9Sstevel@tonic-gate #include <sys/types.h> 31*7c478bd9Sstevel@tonic-gate #include <stdio.h> 32*7c478bd9Sstevel@tonic-gate #include <errno.h> 33*7c478bd9Sstevel@tonic-gate #include <string.h> 34*7c478bd9Sstevel@tonic-gate #include <unistd.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include <sys/param.h> 37*7c478bd9Sstevel@tonic-gate #include <sys/stat.h> 38*7c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 39*7c478bd9Sstevel@tonic-gate #include <sys/vfstab.h> 40*7c478bd9Sstevel@tonic-gate #include <sys/lofi.h> 41*7c478bd9Sstevel@tonic-gate #include <sys/ramdisk.h> 42*7c478bd9Sstevel@tonic-gate #include <sys/fssnap_if.h> 43*7c478bd9Sstevel@tonic-gate #include "libadm.h" 44*7c478bd9Sstevel@tonic-gate 45*7c478bd9Sstevel@tonic-gate /* 46*7c478bd9Sstevel@tonic-gate * Globals: 47*7c478bd9Sstevel@tonic-gate * getfullrawname - returns a fully-qualified raw device name 48*7c478bd9Sstevel@tonic-gate * getfullblkname - returns a fully-qualified block device name 49*7c478bd9Sstevel@tonic-gate * 50*7c478bd9Sstevel@tonic-gate * These two routines take a device pathname and return corresponding 51*7c478bd9Sstevel@tonic-gate * the raw or block device name. 52*7c478bd9Sstevel@tonic-gate * 53*7c478bd9Sstevel@tonic-gate * First the device name is fully qualified: 54*7c478bd9Sstevel@tonic-gate * If the device name does not start with a '/' or starts with 55*7c478bd9Sstevel@tonic-gate * './' then the current working directory is added to the beginning 56*7c478bd9Sstevel@tonic-gate * of the pathname. 57*7c478bd9Sstevel@tonic-gate * 58*7c478bd9Sstevel@tonic-gate * If the device name starts with a '../' then all but the last 59*7c478bd9Sstevel@tonic-gate * sub-directory of the current working directory is added to the 60*7c478bd9Sstevel@tonic-gate * the beginning of the pathname. 61*7c478bd9Sstevel@tonic-gate * 62*7c478bd9Sstevel@tonic-gate * Second if the fully-qualified device name given is the raw/block 63*7c478bd9Sstevel@tonic-gate * device that is being asked for then the fully-qualified device name is 64*7c478bd9Sstevel@tonic-gate * returned. 65*7c478bd9Sstevel@tonic-gate * 66*7c478bd9Sstevel@tonic-gate * Third if an entry is found in /etc/vfstab which matches the given name 67*7c478bd9Sstevel@tonic-gate * then the corresponding raw/block device is returned. This allows 68*7c478bd9Sstevel@tonic-gate * non-standard names to be converted (.i.e., block device "/dev/joe" can 69*7c478bd9Sstevel@tonic-gate * be converted to raw device "/dev/fred", via this mechanism). 70*7c478bd9Sstevel@tonic-gate * 71*7c478bd9Sstevel@tonic-gate * Last standard names are converted. Standard names are those 72*7c478bd9Sstevel@tonic-gate * with a '/dsk/' for block or '/rdsk/' for raw sub-directory components 73*7c478bd9Sstevel@tonic-gate * in the device name. Or, the filename component has an 'r' for raw or 74*7c478bd9Sstevel@tonic-gate * no 'r' for block (e.g., rsd0a <=> sd0a). 75*7c478bd9Sstevel@tonic-gate * 76*7c478bd9Sstevel@tonic-gate * Caveat: 77*7c478bd9Sstevel@tonic-gate * It is assumed that the block and raw devices have the 78*7c478bd9Sstevel@tonic-gate * same device number, and this is used to verify the conversion 79*7c478bd9Sstevel@tonic-gate * happened corretly. If this happens not to be true, due to mapping 80*7c478bd9Sstevel@tonic-gate * of minor numbers or sometheing, then entries can be put in the 81*7c478bd9Sstevel@tonic-gate * the '/etc/vfstab' file to over-ride this checking. 82*7c478bd9Sstevel@tonic-gate * 83*7c478bd9Sstevel@tonic-gate * 84*7c478bd9Sstevel@tonic-gate * Return Values: 85*7c478bd9Sstevel@tonic-gate * raw/block device name - (depending on which routine is used) 86*7c478bd9Sstevel@tonic-gate * null string - When the conversion failed 87*7c478bd9Sstevel@tonic-gate * null pointer - malloc problems 88*7c478bd9Sstevel@tonic-gate * 89*7c478bd9Sstevel@tonic-gate * It is up to the user of these routines to free the memory, of 90*7c478bd9Sstevel@tonic-gate * the device name or null string returned by these library routines, 91*7c478bd9Sstevel@tonic-gate * when appropriate by the application. 92*7c478bd9Sstevel@tonic-gate */ 93*7c478bd9Sstevel@tonic-gate #define GET_BLK 0 94*7c478bd9Sstevel@tonic-gate #define GET_RAW 1 95*7c478bd9Sstevel@tonic-gate 96*7c478bd9Sstevel@tonic-gate static int test_if_blk(char *, dev_t); 97*7c478bd9Sstevel@tonic-gate static int test_if_raw(char *, dev_t); 98*7c478bd9Sstevel@tonic-gate static char *getblkcomplete(char *, struct stat64 *); 99*7c478bd9Sstevel@tonic-gate static char *getrawcomplete(char *, struct stat64 *); 100*7c478bd9Sstevel@tonic-gate 101*7c478bd9Sstevel@tonic-gate /* 102*7c478bd9Sstevel@tonic-gate * getfullname() - Builds a fully qualified pathname. 103*7c478bd9Sstevel@tonic-gate * This handles . and .. as well. 104*7c478bd9Sstevel@tonic-gate * NOTE: This is different from realpath(3C) because 105*7c478bd9Sstevel@tonic-gate * it does not follow links. 106*7c478bd9Sstevel@tonic-gate */ 107*7c478bd9Sstevel@tonic-gate static char * 108*7c478bd9Sstevel@tonic-gate getfullname(char *path) 109*7c478bd9Sstevel@tonic-gate { 110*7c478bd9Sstevel@tonic-gate char cwd[MAXPATHLEN]; 111*7c478bd9Sstevel@tonic-gate char *c; 112*7c478bd9Sstevel@tonic-gate char *wa; 113*7c478bd9Sstevel@tonic-gate size_t len; 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate if (*path == '/') 116*7c478bd9Sstevel@tonic-gate return (strdup(path)); 117*7c478bd9Sstevel@tonic-gate 118*7c478bd9Sstevel@tonic-gate if (getcwd(cwd, sizeof (cwd)) == NULL) 119*7c478bd9Sstevel@tonic-gate return (strdup("")); 120*7c478bd9Sstevel@tonic-gate 121*7c478bd9Sstevel@tonic-gate /* handle . and .. */ 122*7c478bd9Sstevel@tonic-gate if (strncmp(path, "./", 2) == 0) { 123*7c478bd9Sstevel@tonic-gate /* strip the ./ from the given path */ 124*7c478bd9Sstevel@tonic-gate path += 2; 125*7c478bd9Sstevel@tonic-gate } else if (strncmp(path, "../", 3) == 0) { 126*7c478bd9Sstevel@tonic-gate /* strip the last directory component from cwd */ 127*7c478bd9Sstevel@tonic-gate c = strrchr(cwd, '/'); 128*7c478bd9Sstevel@tonic-gate *c = '\0'; 129*7c478bd9Sstevel@tonic-gate 130*7c478bd9Sstevel@tonic-gate /* strip the ../ from the given path */ 131*7c478bd9Sstevel@tonic-gate path += 3; 132*7c478bd9Sstevel@tonic-gate } 133*7c478bd9Sstevel@tonic-gate 134*7c478bd9Sstevel@tonic-gate /* 135*7c478bd9Sstevel@tonic-gate * Adding 2 takes care of slash and null terminator. 136*7c478bd9Sstevel@tonic-gate */ 137*7c478bd9Sstevel@tonic-gate len = strlen(cwd) + strlen(path) + 2; 138*7c478bd9Sstevel@tonic-gate if ((wa = malloc(len)) == NULL) 139*7c478bd9Sstevel@tonic-gate return (NULL); 140*7c478bd9Sstevel@tonic-gate 141*7c478bd9Sstevel@tonic-gate (void) strcpy(wa, cwd); 142*7c478bd9Sstevel@tonic-gate (void) strcat(wa, "/"); 143*7c478bd9Sstevel@tonic-gate (void) strcat(wa, path); 144*7c478bd9Sstevel@tonic-gate 145*7c478bd9Sstevel@tonic-gate return (wa); 146*7c478bd9Sstevel@tonic-gate } 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate /* 149*7c478bd9Sstevel@tonic-gate * test the path/fname to see if is blk special 150*7c478bd9Sstevel@tonic-gate */ 151*7c478bd9Sstevel@tonic-gate static int 152*7c478bd9Sstevel@tonic-gate test_if_blk(char *new_path, dev_t raw_dev) 153*7c478bd9Sstevel@tonic-gate { 154*7c478bd9Sstevel@tonic-gate struct stat64 buf; 155*7c478bd9Sstevel@tonic-gate 156*7c478bd9Sstevel@tonic-gate /* check if we got a char special file */ 157*7c478bd9Sstevel@tonic-gate if (stat64(new_path, &buf) != 0) 158*7c478bd9Sstevel@tonic-gate return (0); 159*7c478bd9Sstevel@tonic-gate 160*7c478bd9Sstevel@tonic-gate if (!S_ISBLK(buf.st_mode)) 161*7c478bd9Sstevel@tonic-gate return (0); 162*7c478bd9Sstevel@tonic-gate 163*7c478bd9Sstevel@tonic-gate if (raw_dev != buf.st_rdev) 164*7c478bd9Sstevel@tonic-gate return (0); 165*7c478bd9Sstevel@tonic-gate 166*7c478bd9Sstevel@tonic-gate return (1); 167*7c478bd9Sstevel@tonic-gate } 168*7c478bd9Sstevel@tonic-gate 169*7c478bd9Sstevel@tonic-gate /* 170*7c478bd9Sstevel@tonic-gate * test the path/fname to see if is char special 171*7c478bd9Sstevel@tonic-gate */ 172*7c478bd9Sstevel@tonic-gate static int 173*7c478bd9Sstevel@tonic-gate test_if_raw(char *new_path, dev_t blk_dev) 174*7c478bd9Sstevel@tonic-gate { 175*7c478bd9Sstevel@tonic-gate struct stat64 buf; 176*7c478bd9Sstevel@tonic-gate 177*7c478bd9Sstevel@tonic-gate /* check if we got a char special file */ 178*7c478bd9Sstevel@tonic-gate if (stat64(new_path, &buf) != 0) 179*7c478bd9Sstevel@tonic-gate return (0); 180*7c478bd9Sstevel@tonic-gate 181*7c478bd9Sstevel@tonic-gate if (!S_ISCHR(buf.st_mode)) 182*7c478bd9Sstevel@tonic-gate return (0); 183*7c478bd9Sstevel@tonic-gate 184*7c478bd9Sstevel@tonic-gate if (blk_dev != buf.st_rdev) 185*7c478bd9Sstevel@tonic-gate return (0); 186*7c478bd9Sstevel@tonic-gate 187*7c478bd9Sstevel@tonic-gate return (1); 188*7c478bd9Sstevel@tonic-gate } 189*7c478bd9Sstevel@tonic-gate 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * complete getblkrawname() for blk->raw to handle volmgt devices 192*7c478bd9Sstevel@tonic-gate */ 193*7c478bd9Sstevel@tonic-gate 194*7c478bd9Sstevel@tonic-gate static char * 195*7c478bd9Sstevel@tonic-gate getblkcomplete(char *cp, struct stat64 *dat) 196*7c478bd9Sstevel@tonic-gate { 197*7c478bd9Sstevel@tonic-gate char *dp; 198*7c478bd9Sstevel@tonic-gate char *new_path; 199*7c478bd9Sstevel@tonic-gate char c; 200*7c478bd9Sstevel@tonic-gate 201*7c478bd9Sstevel@tonic-gate /* ok, so we either have a bad device or a floppy */ 202*7c478bd9Sstevel@tonic-gate 203*7c478bd9Sstevel@tonic-gate /* try the rfd# form */ 204*7c478bd9Sstevel@tonic-gate if ((dp = strstr(cp, "/rfd")) != NULL) { 205*7c478bd9Sstevel@tonic-gate if ((new_path = malloc(strlen(cp))) == NULL) 206*7c478bd9Sstevel@tonic-gate return (NULL); 207*7c478bd9Sstevel@tonic-gate 208*7c478bd9Sstevel@tonic-gate c = *++dp; /* save the 'r' */ 209*7c478bd9Sstevel@tonic-gate *dp = '\0'; /* replace it with a null */ 210*7c478bd9Sstevel@tonic-gate (void) strcpy(new_path, cp); /* save first part of it */ 211*7c478bd9Sstevel@tonic-gate *dp++ = c; /* give the 'r' back */ 212*7c478bd9Sstevel@tonic-gate (void) strcat(new_path, dp); /* copy, skipping the 'r' */ 213*7c478bd9Sstevel@tonic-gate 214*7c478bd9Sstevel@tonic-gate if (test_if_blk(new_path, dat->st_rdev)) 215*7c478bd9Sstevel@tonic-gate return (new_path); 216*7c478bd9Sstevel@tonic-gate 217*7c478bd9Sstevel@tonic-gate free(new_path); 218*7c478bd9Sstevel@tonic-gate return (strdup("")); 219*7c478bd9Sstevel@tonic-gate } 220*7c478bd9Sstevel@tonic-gate 221*7c478bd9Sstevel@tonic-gate /* try the rdiskette form */ 222*7c478bd9Sstevel@tonic-gate if ((dp = strstr(cp, "/rdiskette")) != NULL) { 223*7c478bd9Sstevel@tonic-gate if ((new_path = malloc(strlen(cp))) == NULL) 224*7c478bd9Sstevel@tonic-gate return (NULL); 225*7c478bd9Sstevel@tonic-gate 226*7c478bd9Sstevel@tonic-gate c = *++dp; /* save the 'r' */ 227*7c478bd9Sstevel@tonic-gate *dp = '\0'; /* replace it with a null */ 228*7c478bd9Sstevel@tonic-gate (void) strcpy(new_path, cp); /* save first part of it */ 229*7c478bd9Sstevel@tonic-gate *dp++ = c; /* give the 'r' back */ 230*7c478bd9Sstevel@tonic-gate (void) strcat(new_path, dp); /* copy, skipping the 'r' */ 231*7c478bd9Sstevel@tonic-gate 232*7c478bd9Sstevel@tonic-gate if (test_if_blk(new_path, dat->st_rdev)) 233*7c478bd9Sstevel@tonic-gate return (new_path); 234*7c478bd9Sstevel@tonic-gate 235*7c478bd9Sstevel@tonic-gate free(new_path); 236*7c478bd9Sstevel@tonic-gate return (strdup("")); 237*7c478bd9Sstevel@tonic-gate } 238*7c478bd9Sstevel@tonic-gate 239*7c478bd9Sstevel@tonic-gate /* no match found */ 240*7c478bd9Sstevel@tonic-gate return (strdup("")); 241*7c478bd9Sstevel@tonic-gate } 242*7c478bd9Sstevel@tonic-gate 243*7c478bd9Sstevel@tonic-gate /* 244*7c478bd9Sstevel@tonic-gate * complete getfullrawname() for raw->blk to handle volmgt devices 245*7c478bd9Sstevel@tonic-gate */ 246*7c478bd9Sstevel@tonic-gate 247*7c478bd9Sstevel@tonic-gate static char * 248*7c478bd9Sstevel@tonic-gate getrawcomplete(char *cp, struct stat64 *dat) 249*7c478bd9Sstevel@tonic-gate { 250*7c478bd9Sstevel@tonic-gate char *dp; 251*7c478bd9Sstevel@tonic-gate char *new_path; 252*7c478bd9Sstevel@tonic-gate char c; 253*7c478bd9Sstevel@tonic-gate 254*7c478bd9Sstevel@tonic-gate /* ok, so we either have a bad device or a floppy */ 255*7c478bd9Sstevel@tonic-gate 256*7c478bd9Sstevel@tonic-gate /* try the fd# form */ 257*7c478bd9Sstevel@tonic-gate if ((dp = strstr(cp, "/fd")) != NULL) { 258*7c478bd9Sstevel@tonic-gate /* malloc path for new_path to hold raw */ 259*7c478bd9Sstevel@tonic-gate if ((new_path = malloc(strlen(cp)+2)) == NULL) 260*7c478bd9Sstevel@tonic-gate return (NULL); 261*7c478bd9Sstevel@tonic-gate 262*7c478bd9Sstevel@tonic-gate c = *++dp; /* save the 'f' */ 263*7c478bd9Sstevel@tonic-gate *dp = '\0'; /* replace it with a null */ 264*7c478bd9Sstevel@tonic-gate (void) strcpy(new_path, cp); /* save first part of it */ 265*7c478bd9Sstevel@tonic-gate *dp = c; /* put the 'f' back */ 266*7c478bd9Sstevel@tonic-gate (void) strcat(new_path, "r"); /* insert an 'r' */ 267*7c478bd9Sstevel@tonic-gate (void) strcat(new_path, dp); /* copy the rest */ 268*7c478bd9Sstevel@tonic-gate 269*7c478bd9Sstevel@tonic-gate if (test_if_raw(new_path, dat->st_rdev)) 270*7c478bd9Sstevel@tonic-gate return (new_path); 271*7c478bd9Sstevel@tonic-gate 272*7c478bd9Sstevel@tonic-gate free(new_path); 273*7c478bd9Sstevel@tonic-gate } 274*7c478bd9Sstevel@tonic-gate 275*7c478bd9Sstevel@tonic-gate /* try the diskette form */ 276*7c478bd9Sstevel@tonic-gate if ((dp = strstr(cp, "/diskette")) != NULL) { 277*7c478bd9Sstevel@tonic-gate /* malloc path for new_path to hold raw */ 278*7c478bd9Sstevel@tonic-gate if ((new_path = malloc(strlen(cp)+2)) == NULL) 279*7c478bd9Sstevel@tonic-gate return (NULL); 280*7c478bd9Sstevel@tonic-gate 281*7c478bd9Sstevel@tonic-gate c = *++dp; /* save at 'd' */ 282*7c478bd9Sstevel@tonic-gate *dp = '\0'; /* replace it with a null */ 283*7c478bd9Sstevel@tonic-gate (void) strcpy(new_path, cp); /* save first part */ 284*7c478bd9Sstevel@tonic-gate *dp = c; /* put the 'd' back */ 285*7c478bd9Sstevel@tonic-gate (void) strcat(new_path, "r"); /* insert an 'r' */ 286*7c478bd9Sstevel@tonic-gate (void) strcat(new_path, dp); /* copy the rest */ 287*7c478bd9Sstevel@tonic-gate 288*7c478bd9Sstevel@tonic-gate if (test_if_raw(new_path, dat->st_rdev)) 289*7c478bd9Sstevel@tonic-gate return (new_path); 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate free(new_path); 292*7c478bd9Sstevel@tonic-gate return (strdup("")); 293*7c478bd9Sstevel@tonic-gate } 294*7c478bd9Sstevel@tonic-gate 295*7c478bd9Sstevel@tonic-gate /* failed to build raw name, return null string */ 296*7c478bd9Sstevel@tonic-gate return (strdup("")); 297*7c478bd9Sstevel@tonic-gate 298*7c478bd9Sstevel@tonic-gate 299*7c478bd9Sstevel@tonic-gate 300*7c478bd9Sstevel@tonic-gate } 301*7c478bd9Sstevel@tonic-gate 302*7c478bd9Sstevel@tonic-gate static char * 303*7c478bd9Sstevel@tonic-gate getvfsspecial(char *path, int raw_special) 304*7c478bd9Sstevel@tonic-gate { 305*7c478bd9Sstevel@tonic-gate FILE *fp; 306*7c478bd9Sstevel@tonic-gate struct vfstab vp; 307*7c478bd9Sstevel@tonic-gate struct vfstab ref_vp; 308*7c478bd9Sstevel@tonic-gate 309*7c478bd9Sstevel@tonic-gate if ((fp = fopen("/etc/vfstab", "r")) == NULL) 310*7c478bd9Sstevel@tonic-gate return (NULL); 311*7c478bd9Sstevel@tonic-gate 312*7c478bd9Sstevel@tonic-gate (void) memset(&ref_vp, 0, sizeof (struct vfstab)); 313*7c478bd9Sstevel@tonic-gate 314*7c478bd9Sstevel@tonic-gate if (raw_special) 315*7c478bd9Sstevel@tonic-gate ref_vp.vfs_special = path; 316*7c478bd9Sstevel@tonic-gate else 317*7c478bd9Sstevel@tonic-gate ref_vp.vfs_fsckdev = path; 318*7c478bd9Sstevel@tonic-gate 319*7c478bd9Sstevel@tonic-gate if (getvfsany(fp, &vp, &ref_vp)) { 320*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 321*7c478bd9Sstevel@tonic-gate return (NULL); 322*7c478bd9Sstevel@tonic-gate } 323*7c478bd9Sstevel@tonic-gate 324*7c478bd9Sstevel@tonic-gate (void) fclose(fp); 325*7c478bd9Sstevel@tonic-gate 326*7c478bd9Sstevel@tonic-gate if (raw_special) 327*7c478bd9Sstevel@tonic-gate return (vp.vfs_fsckdev); 328*7c478bd9Sstevel@tonic-gate 329*7c478bd9Sstevel@tonic-gate return (vp.vfs_special); 330*7c478bd9Sstevel@tonic-gate } 331*7c478bd9Sstevel@tonic-gate 332*7c478bd9Sstevel@tonic-gate /* 333*7c478bd9Sstevel@tonic-gate * change the device name to a block device name 334*7c478bd9Sstevel@tonic-gate */ 335*7c478bd9Sstevel@tonic-gate char * 336*7c478bd9Sstevel@tonic-gate getfullblkname(char *cp) 337*7c478bd9Sstevel@tonic-gate { 338*7c478bd9Sstevel@tonic-gate struct stat64 buf; 339*7c478bd9Sstevel@tonic-gate char *dp; 340*7c478bd9Sstevel@tonic-gate char *new_path; 341*7c478bd9Sstevel@tonic-gate dev_t raw_dev; 342*7c478bd9Sstevel@tonic-gate 343*7c478bd9Sstevel@tonic-gate if (cp == NULL) 344*7c478bd9Sstevel@tonic-gate return (strdup("")); 345*7c478bd9Sstevel@tonic-gate 346*7c478bd9Sstevel@tonic-gate /* 347*7c478bd9Sstevel@tonic-gate * Create a fully qualified name. 348*7c478bd9Sstevel@tonic-gate */ 349*7c478bd9Sstevel@tonic-gate if ((cp = getfullname(cp)) == NULL) 350*7c478bd9Sstevel@tonic-gate return (NULL); 351*7c478bd9Sstevel@tonic-gate 352*7c478bd9Sstevel@tonic-gate if (*cp == '\0') 353*7c478bd9Sstevel@tonic-gate return (cp); 354*7c478bd9Sstevel@tonic-gate 355*7c478bd9Sstevel@tonic-gate if (stat64(cp, &buf) != 0) { 356*7c478bd9Sstevel@tonic-gate free(cp); 357*7c478bd9Sstevel@tonic-gate return (strdup("")); 358*7c478bd9Sstevel@tonic-gate } 359*7c478bd9Sstevel@tonic-gate 360*7c478bd9Sstevel@tonic-gate if (S_ISBLK(buf.st_mode)) 361*7c478bd9Sstevel@tonic-gate return (cp); 362*7c478bd9Sstevel@tonic-gate 363*7c478bd9Sstevel@tonic-gate if (!S_ISCHR(buf.st_mode)) { 364*7c478bd9Sstevel@tonic-gate free(cp); 365*7c478bd9Sstevel@tonic-gate return (strdup("")); 366*7c478bd9Sstevel@tonic-gate } 367*7c478bd9Sstevel@tonic-gate 368*7c478bd9Sstevel@tonic-gate if ((dp = getvfsspecial(cp, GET_BLK)) != NULL) { 369*7c478bd9Sstevel@tonic-gate free(cp); 370*7c478bd9Sstevel@tonic-gate return (strdup(dp)); 371*7c478bd9Sstevel@tonic-gate } 372*7c478bd9Sstevel@tonic-gate 373*7c478bd9Sstevel@tonic-gate raw_dev = buf.st_rdev; 374*7c478bd9Sstevel@tonic-gate 375*7c478bd9Sstevel@tonic-gate /* 376*7c478bd9Sstevel@tonic-gate * We have a raw device name, go find the block name. 377*7c478bd9Sstevel@tonic-gate */ 378*7c478bd9Sstevel@tonic-gate if ((dp = strstr(cp, "/rdsk/")) == NULL && 379*7c478bd9Sstevel@tonic-gate (dp = strstr(cp, "/" LOFI_CHAR_NAME "/")) == NULL && 380*7c478bd9Sstevel@tonic-gate (dp = strstr(cp, "/" RD_CHAR_NAME "/")) == NULL && 381*7c478bd9Sstevel@tonic-gate (dp = strstr(cp, "/" SNAP_CHAR_NAME "/")) == NULL && 382*7c478bd9Sstevel@tonic-gate (dp = strrchr(cp, '/')) == NULL) { 383*7c478bd9Sstevel@tonic-gate /* this is not really possible */ 384*7c478bd9Sstevel@tonic-gate free(cp); 385*7c478bd9Sstevel@tonic-gate return (strdup("")); 386*7c478bd9Sstevel@tonic-gate } 387*7c478bd9Sstevel@tonic-gate dp++; 388*7c478bd9Sstevel@tonic-gate if (*dp != 'r') { 389*7c478bd9Sstevel@tonic-gate dp = getblkcomplete(cp, &buf); 390*7c478bd9Sstevel@tonic-gate free(cp); 391*7c478bd9Sstevel@tonic-gate return (dp); 392*7c478bd9Sstevel@tonic-gate } 393*7c478bd9Sstevel@tonic-gate if ((new_path = malloc(strlen(cp))) == NULL) { 394*7c478bd9Sstevel@tonic-gate free(cp); 395*7c478bd9Sstevel@tonic-gate return (NULL); 396*7c478bd9Sstevel@tonic-gate } 397*7c478bd9Sstevel@tonic-gate (void) strncpy(new_path, cp, dp - cp); 398*7c478bd9Sstevel@tonic-gate 399*7c478bd9Sstevel@tonic-gate /* fill in the rest of the unraw name */ 400*7c478bd9Sstevel@tonic-gate (void) strcpy(new_path + (dp - cp), dp + 1); 401*7c478bd9Sstevel@tonic-gate 402*7c478bd9Sstevel@tonic-gate if (test_if_blk(new_path, raw_dev)) { 403*7c478bd9Sstevel@tonic-gate free(cp); 404*7c478bd9Sstevel@tonic-gate /* block name was found, return it here */ 405*7c478bd9Sstevel@tonic-gate return (new_path); 406*7c478bd9Sstevel@tonic-gate } 407*7c478bd9Sstevel@tonic-gate free(new_path); 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate dp = getblkcomplete(cp, &buf); 410*7c478bd9Sstevel@tonic-gate free(cp); 411*7c478bd9Sstevel@tonic-gate return (dp); 412*7c478bd9Sstevel@tonic-gate } 413*7c478bd9Sstevel@tonic-gate 414*7c478bd9Sstevel@tonic-gate /* 415*7c478bd9Sstevel@tonic-gate * change the device name to a raw devname 416*7c478bd9Sstevel@tonic-gate */ 417*7c478bd9Sstevel@tonic-gate char * 418*7c478bd9Sstevel@tonic-gate getfullrawname(char *cp) 419*7c478bd9Sstevel@tonic-gate { 420*7c478bd9Sstevel@tonic-gate struct stat64 buf; 421*7c478bd9Sstevel@tonic-gate char *dp; 422*7c478bd9Sstevel@tonic-gate char *new_path; 423*7c478bd9Sstevel@tonic-gate dev_t blk_dev; 424*7c478bd9Sstevel@tonic-gate 425*7c478bd9Sstevel@tonic-gate if (cp == NULL) 426*7c478bd9Sstevel@tonic-gate return (strdup("")); 427*7c478bd9Sstevel@tonic-gate 428*7c478bd9Sstevel@tonic-gate /* 429*7c478bd9Sstevel@tonic-gate * Create a fully qualified name. 430*7c478bd9Sstevel@tonic-gate */ 431*7c478bd9Sstevel@tonic-gate if ((cp = getfullname(cp)) == NULL) 432*7c478bd9Sstevel@tonic-gate return (NULL); 433*7c478bd9Sstevel@tonic-gate 434*7c478bd9Sstevel@tonic-gate if (*cp == '\0') 435*7c478bd9Sstevel@tonic-gate return (cp); 436*7c478bd9Sstevel@tonic-gate 437*7c478bd9Sstevel@tonic-gate if (stat64(cp, &buf) != 0) { 438*7c478bd9Sstevel@tonic-gate free(cp); 439*7c478bd9Sstevel@tonic-gate return (strdup("")); 440*7c478bd9Sstevel@tonic-gate } 441*7c478bd9Sstevel@tonic-gate 442*7c478bd9Sstevel@tonic-gate if (S_ISCHR(buf.st_mode)) 443*7c478bd9Sstevel@tonic-gate return (cp); 444*7c478bd9Sstevel@tonic-gate 445*7c478bd9Sstevel@tonic-gate if (!S_ISBLK(buf.st_mode)) { 446*7c478bd9Sstevel@tonic-gate free(cp); 447*7c478bd9Sstevel@tonic-gate return (strdup("")); 448*7c478bd9Sstevel@tonic-gate } 449*7c478bd9Sstevel@tonic-gate 450*7c478bd9Sstevel@tonic-gate blk_dev = buf.st_rdev; 451*7c478bd9Sstevel@tonic-gate 452*7c478bd9Sstevel@tonic-gate if ((dp = getvfsspecial(cp, GET_RAW)) != NULL) { 453*7c478bd9Sstevel@tonic-gate free(cp); 454*7c478bd9Sstevel@tonic-gate return (strdup(dp)); 455*7c478bd9Sstevel@tonic-gate } 456*7c478bd9Sstevel@tonic-gate 457*7c478bd9Sstevel@tonic-gate /* 458*7c478bd9Sstevel@tonic-gate * We have a block device name, go find the raw name. 459*7c478bd9Sstevel@tonic-gate */ 460*7c478bd9Sstevel@tonic-gate if ((dp = strstr(cp, "/dsk/")) == NULL && 461*7c478bd9Sstevel@tonic-gate (dp = strstr(cp, "/" LOFI_BLOCK_NAME "/")) == NULL && 462*7c478bd9Sstevel@tonic-gate (dp = strstr(cp, "/" RD_BLOCK_NAME "/")) == NULL && 463*7c478bd9Sstevel@tonic-gate (dp = strstr(cp, "/" SNAP_BLOCK_NAME "/")) == NULL && 464*7c478bd9Sstevel@tonic-gate (dp = strrchr(cp, '/')) == NULL) { 465*7c478bd9Sstevel@tonic-gate /* this is not really possible */ 466*7c478bd9Sstevel@tonic-gate free(cp); 467*7c478bd9Sstevel@tonic-gate return (strdup("")); 468*7c478bd9Sstevel@tonic-gate } 469*7c478bd9Sstevel@tonic-gate dp++; 470*7c478bd9Sstevel@tonic-gate 471*7c478bd9Sstevel@tonic-gate if ((new_path = malloc(strlen(cp)+2)) == NULL) { 472*7c478bd9Sstevel@tonic-gate free(cp); 473*7c478bd9Sstevel@tonic-gate return (NULL); 474*7c478bd9Sstevel@tonic-gate } 475*7c478bd9Sstevel@tonic-gate (void) strncpy(new_path, cp, dp - cp); 476*7c478bd9Sstevel@tonic-gate /* fill in the rest of the raw name */ 477*7c478bd9Sstevel@tonic-gate new_path[dp - cp] = 'r'; 478*7c478bd9Sstevel@tonic-gate (void) strcpy(new_path + (dp - cp) + 1, dp); 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate if (test_if_raw(new_path, blk_dev)) { 481*7c478bd9Sstevel@tonic-gate free(cp); 482*7c478bd9Sstevel@tonic-gate return (new_path); 483*7c478bd9Sstevel@tonic-gate } 484*7c478bd9Sstevel@tonic-gate free(new_path); 485*7c478bd9Sstevel@tonic-gate 486*7c478bd9Sstevel@tonic-gate dp = getrawcomplete(cp, &buf); 487*7c478bd9Sstevel@tonic-gate free(cp); 488*7c478bd9Sstevel@tonic-gate return (dp); 489*7c478bd9Sstevel@tonic-gate } 490