xref: /minix3/lib/libutil/getfsspecname.c (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /*	$NetBSD: getfsspecname.c,v 1.5 2014/05/25 13:46:07 christos Exp $	*/
2dba3562dSLionel Sambuc 
3dba3562dSLionel Sambuc /*-
4dba3562dSLionel Sambuc  * Copyright (c) 2012 The NetBSD Foundation, Inc.
5dba3562dSLionel Sambuc  * All rights reserved.
6dba3562dSLionel Sambuc  *
7dba3562dSLionel Sambuc  * This code is derived from software contributed to The NetBSD Foundation
8dba3562dSLionel Sambuc  * by Christos Zoulas.
9dba3562dSLionel Sambuc  *
10dba3562dSLionel Sambuc  * Redistribution and use in source and binary forms, with or without
11dba3562dSLionel Sambuc  * modification, are permitted provided that the following conditions
12dba3562dSLionel Sambuc  * are met:
13dba3562dSLionel Sambuc  * 1. Redistributions of source code must retain the above copyright
14dba3562dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer.
15dba3562dSLionel Sambuc  * 2. Redistributions in binary form must reproduce the above copyright
16dba3562dSLionel Sambuc  *    notice, this list of conditions and the following disclaimer in the
17dba3562dSLionel Sambuc  *    documentation and/or other materials provided with the distribution.
18dba3562dSLionel Sambuc  *
19dba3562dSLionel Sambuc  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20dba3562dSLionel Sambuc  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21dba3562dSLionel Sambuc  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22dba3562dSLionel Sambuc  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23dba3562dSLionel Sambuc  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24dba3562dSLionel Sambuc  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25dba3562dSLionel Sambuc  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26dba3562dSLionel Sambuc  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27dba3562dSLionel Sambuc  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28dba3562dSLionel Sambuc  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29dba3562dSLionel Sambuc  * POSSIBILITY OF SUCH DAMAGE.
30dba3562dSLionel Sambuc  */
31dba3562dSLionel Sambuc #include <sys/cdefs.h>
32*0a6a1f1dSLionel Sambuc __RCSID("$NetBSD: getfsspecname.c,v 1.5 2014/05/25 13:46:07 christos Exp $");
33dba3562dSLionel Sambuc 
34dba3562dSLionel Sambuc #include <sys/types.h>
3584d9c625SLionel Sambuc #include <sys/ioctl.h>
36dba3562dSLionel Sambuc #include <sys/sysctl.h>
37dba3562dSLionel Sambuc #include <sys/disk.h>
38dba3562dSLionel Sambuc 
39dba3562dSLionel Sambuc #include <stdio.h>
40dba3562dSLionel Sambuc #include <vis.h>
41dba3562dSLionel Sambuc #include <string.h>
42dba3562dSLionel Sambuc #include <fstab.h>
43dba3562dSLionel Sambuc #include <fcntl.h>
44dba3562dSLionel Sambuc #include <stdlib.h>
45dba3562dSLionel Sambuc #include <errno.h>
46dba3562dSLionel Sambuc #include <unistd.h>
47dba3562dSLionel Sambuc #include <util.h>
48dba3562dSLionel Sambuc 
4984d9c625SLionel Sambuc #if !defined(__minix)
50dba3562dSLionel Sambuc #define COMPAT_DKWEDGE	/* To be removed */
5184d9c625SLionel Sambuc #endif /* !defined(__minix) */
52dba3562dSLionel Sambuc 
53dba3562dSLionel Sambuc const char *
getfsspecname(char * buf,size_t bufsiz,const char * name)54dba3562dSLionel Sambuc getfsspecname(char *buf, size_t bufsiz, const char *name)
55dba3562dSLionel Sambuc {
56dba3562dSLionel Sambuc 	static const int mib[] = { CTL_HW, HW_DISKNAMES };
57dba3562dSLionel Sambuc 	static const unsigned int miblen = __arraycount(mib);
58*0a6a1f1dSLionel Sambuc 	char *drives, *dk, *p;
59dba3562dSLionel Sambuc 	size_t len;
60*0a6a1f1dSLionel Sambuc 	int fd, savee = errno;
61dba3562dSLionel Sambuc 	char *vname;
62dba3562dSLionel Sambuc 
63*0a6a1f1dSLionel Sambuc 	p = drives = vname = NULL;
64dba3562dSLionel Sambuc 	if (strncasecmp(name, "NAME=", 5) != 0) {
65dba3562dSLionel Sambuc #ifdef COMPAT_DKWEDGE
66dba3562dSLionel Sambuc 		/*
67dba3562dSLionel Sambuc 		 * We try to open the disk name, and if we fail with EBUSY
68dba3562dSLionel Sambuc 		 * we use the name as the label to find the wedge.
69dba3562dSLionel Sambuc 		 */
70dba3562dSLionel Sambuc 		char rbuf[MAXPATHLEN];
71dba3562dSLionel Sambuc 		if (name[0] == '/') {
72dba3562dSLionel Sambuc 			if (getdiskrawname(rbuf, sizeof(rbuf), name) != NULL) {
73dba3562dSLionel Sambuc 				if ((fd = open(rbuf, O_RDONLY)) == -1) {
74dba3562dSLionel Sambuc 					if (errno == EBUSY) {
75dba3562dSLionel Sambuc 						name = strrchr(name, '/') + 1;
76dba3562dSLionel Sambuc 						goto search;
77dba3562dSLionel Sambuc 					}
78dba3562dSLionel Sambuc 				} else
79dba3562dSLionel Sambuc 					close(fd);
80dba3562dSLionel Sambuc 			}
81dba3562dSLionel Sambuc 		}
82dba3562dSLionel Sambuc #endif
83dba3562dSLionel Sambuc 		strlcpy(buf, name, bufsiz);
84dba3562dSLionel Sambuc 		return buf;
85dba3562dSLionel Sambuc 	} else
86dba3562dSLionel Sambuc 		name += 5;
87dba3562dSLionel Sambuc 
88dba3562dSLionel Sambuc #ifdef COMPAT_DKWEDGE
89dba3562dSLionel Sambuc search:
90dba3562dSLionel Sambuc #endif
91dba3562dSLionel Sambuc 	vname = malloc(strlen(name) * 4 + 1);
92dba3562dSLionel Sambuc 	if (vname == NULL) {
93dba3562dSLionel Sambuc 		savee = errno;
94dba3562dSLionel Sambuc 		strlcpy(buf, "malloc failed", bufsiz);
95dba3562dSLionel Sambuc 		goto out;
96dba3562dSLionel Sambuc 	}
97dba3562dSLionel Sambuc 
98dba3562dSLionel Sambuc 	strunvis(vname, name);
99dba3562dSLionel Sambuc 
100dba3562dSLionel Sambuc 	if (sysctl(mib, miblen, NULL, &len, NULL, 0) == -1) {
101dba3562dSLionel Sambuc 		savee = errno;
102dba3562dSLionel Sambuc 		strlcpy(buf, "sysctl hw.disknames failed", bufsiz);
103dba3562dSLionel Sambuc 		goto out;
104dba3562dSLionel Sambuc 	}
105dba3562dSLionel Sambuc 
106dba3562dSLionel Sambuc 	drives = malloc(len);
107dba3562dSLionel Sambuc 	if (drives == NULL) {
108dba3562dSLionel Sambuc 		savee = errno;
109dba3562dSLionel Sambuc 		strlcpy(buf, "malloc failed", bufsiz);
110dba3562dSLionel Sambuc 		goto out;
111dba3562dSLionel Sambuc 	}
112dba3562dSLionel Sambuc 	if (sysctl(mib, miblen, drives, &len, NULL, 0) == -1) {
113dba3562dSLionel Sambuc 		savee = errno;
114dba3562dSLionel Sambuc 		strlcpy(buf, "sysctl hw.disknames failed", bufsiz);
115dba3562dSLionel Sambuc 		goto out;
116dba3562dSLionel Sambuc 	}
117dba3562dSLionel Sambuc 
118dba3562dSLionel Sambuc 	for (dk = strtok(drives, " "); dk != NULL; dk = strtok(NULL, " ")) {
119dba3562dSLionel Sambuc 		struct dkwedge_info dkw;
120dba3562dSLionel Sambuc 		if (strncmp(dk, "dk", 2) != 0)
121dba3562dSLionel Sambuc 			continue;
122dba3562dSLionel Sambuc 		fd = opendisk(dk, O_RDONLY, buf, bufsiz, 0);
123dba3562dSLionel Sambuc 		if (fd == -1)
124dba3562dSLionel Sambuc 			continue;
125dba3562dSLionel Sambuc 		if (ioctl(fd, DIOCGWEDGEINFO, &dkw) == -1) {
126dba3562dSLionel Sambuc 			savee = errno;
127dba3562dSLionel Sambuc 			snprintf(buf, bufsiz, "%s: getwedgeinfo", dk);
128dba3562dSLionel Sambuc 			(void)close(fd);
129dba3562dSLionel Sambuc 			goto out;
130dba3562dSLionel Sambuc 		}
131dba3562dSLionel Sambuc 		(void)close(fd);
132dba3562dSLionel Sambuc 		if (strcmp(vname, (char *)dkw.dkw_wname) == 0) {
133*0a6a1f1dSLionel Sambuc 			p = strstr(buf, "/rdk");
134*0a6a1f1dSLionel Sambuc 			goto good;
135dba3562dSLionel Sambuc 		}
136dba3562dSLionel Sambuc 	}
137*0a6a1f1dSLionel Sambuc #ifdef COMPAT_DKWEDGE
138*0a6a1f1dSLionel Sambuc 	/* Last ditch effort assuming NAME=label, and label is a disk name */
139*0a6a1f1dSLionel Sambuc 	fd = opendisk(name, O_RDONLY, buf, bufsiz, 0);
140*0a6a1f1dSLionel Sambuc 	if (fd != -1) {
141*0a6a1f1dSLionel Sambuc 		close(fd);
142*0a6a1f1dSLionel Sambuc 		p = strstr(buf, "/r");
143*0a6a1f1dSLionel Sambuc 		goto good;
144*0a6a1f1dSLionel Sambuc 	}
145*0a6a1f1dSLionel Sambuc #endif
146dba3562dSLionel Sambuc 	savee = ESRCH;
147dba3562dSLionel Sambuc 	snprintf(buf, bufsiz, "no match for `%s'", vname);
148dba3562dSLionel Sambuc out:
149*0a6a1f1dSLionel Sambuc 	buf = NULL;
150*0a6a1f1dSLionel Sambuc good:
151*0a6a1f1dSLionel Sambuc 	if (p++ != NULL)
152*0a6a1f1dSLionel Sambuc 		strcpy(p, p + 1);
153dba3562dSLionel Sambuc 	free(drives);
154dba3562dSLionel Sambuc 	free(vname);
155dba3562dSLionel Sambuc 	errno = savee;
156*0a6a1f1dSLionel Sambuc 	return buf;
157dba3562dSLionel Sambuc }
158