2 * Copyright (c) 2009 The DragonFly Project. All rights reserved.
4 * This code is derived from software contributed to The DragonFly Project
5 * by Matthew Dillon <dillon@backplane.com>
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * 1. Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * 3. Neither the name of The DragonFly Project nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific, prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
31 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 #include <sys/types.h>
48 static void finddevlabel(char **pathp
, const char *devname
);
49 static int xlatedevpath(char **pathp
, struct stat
*st
);
50 static char *dodequote(char *base
);
53 * Acquire device path.
57 getdevpath(const char *devname
, int flags
)
64 if (devname
[0] == '/' || devname
[0] == '.') {
65 asprintf(&path
, "%s", devname
);
66 } else if ((ptr
= strchr(devname
, ':')) != NULL
) {
67 asprintf(&path
, "/dev/%*.*s/%s",
68 ptr
- devname
, ptr
- devname
, devname
,
71 asprintf(&path
, "/dev/%s", devname
);
72 if (lstat(path
, &st
) < 0) {
75 finddevlabel(&path
, devname
);
82 * Translate softlinks if requested. If the lstat() of the
83 * pre-translated path fails NULL is expected to be returned.
84 * lstat() is not called on the post-translated path.
86 if ((flags
& GETDEVPATH_RAWDEV
) && path
) {
87 if (stgood
== 0 && lstat(path
, &st
) == 0)
90 stgood
= xlatedevpath(&path
, &st
);
103 finddevlabel(char **pathp
, const char *devname
)
105 const char *prefix
= _PATH_DEVTAB_PATHS
;
115 while (*prefix
&& *pathp
== NULL
) {
116 ptr1
= strchr(prefix
, ':');
117 len
= (ptr1
) ? (size_t)(ptr1
- prefix
) : strlen(prefix
);
118 asprintf(&dtpath
, "%*.*s/devtab", len
, len
, prefix
);
119 if ((fp
= fopen(dtpath
, "r")) != NULL
) {
120 while (fgets(buf
, sizeof(buf
), fp
) != NULL
) {
121 ptr1
= strtok_r(buf
, " \t\r\n", &bufp
);
122 if (ptr1
== NULL
|| *ptr1
== 0 || *ptr1
== '#')
124 if (strcmp(devname
, ptr1
) != 0)
126 ptr2
= strtok_r(NULL
, " \t\r\n", &bufp
);
127 ptr3
= strtok_r(NULL
, " \t\r\n", &bufp
);
128 if (ptr2
== NULL
|| ptr3
== NULL
)
130 if (*ptr2
== 0 || *ptr3
== 0)
132 ptr3
= dodequote(ptr3
);
133 if (strcmp(ptr2
, "path") == 0) {
134 asprintf(pathp
, "%s", ptr3
);
136 asprintf(pathp
, "/dev/%s/%s",
151 xlatedevpath(char **pathp
, struct stat
*st
)
158 * If not a softlink return unchanged.
160 if (!S_ISLNK(st
->st_mode
))
164 * If the softlink isn't reasonable return bad (0)
166 len
= (int)st
->st_size
;
167 if (len
< 0 || len
> PATH_MAX
)
171 * Read the link, return if the result is not what we expected.
173 path
= malloc(len
+ 1);
174 n
= readlink(*pathp
, path
, len
);
175 if (n
< 0 || n
> len
) {
181 * Success, replace (*pathp).
190 dodequote(char *base
)
192 int len
= strlen(base
);
194 if (len
&& base
[0] == '\"' && base
[len
-1] == '\"') {