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