2 * parse_dev.c -- parse device name into hostname and export path
4 * Copyright (C) 2008 Oracle. All rights reserved.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * General Public License for more details.
16 * You should have received a copy of the GNU General Public
17 * License along with this program; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 * Boston, MA 021110-1307, USA.
29 #include "parse_dev.h"
31 #ifndef NFS_MAXHOSTNAME
32 #define NFS_MAXHOSTNAME (255)
35 #ifndef NFS_MAXPATHNAME
36 #define NFS_MAXPATHNAME (1024)
39 extern char *progname;
42 static int nfs_pdn_no_devname_err(void)
44 nfs_error(_("%s: no device name was provided"), progname);
48 static int nfs_pdn_hostname_too_long_err(void)
50 nfs_error(_("%s: server hostname is too long"), progname);
54 static int nfs_pdn_pathname_too_long_err(void)
56 nfs_error(_("%s: export pathname is too long"), progname);
60 static int nfs_pdn_bad_format_err(void)
62 nfs_error(_("%s: remote share not in 'host:dir' format"), progname);
66 static int nfs_pdn_nomem_err(void)
68 nfs_error(_("%s: no memory available to parse devname"), progname);
72 static int nfs_pdn_missing_brace_err(void)
74 nfs_error(_("%s: closing bracket missing from server address"),
80 * Standard hostname:path format
82 static int nfs_parse_simple_hostname(const char *dev,
83 char **hostname, char **pathname)
85 size_t host_len, path_len;
88 /* Must have a colon */
89 colon = strchr(dev, ':');
91 return nfs_pdn_bad_format_err();
93 host_len = colon - dev;
95 if (host_len > NFS_MAXHOSTNAME)
96 return nfs_pdn_hostname_too_long_err();
98 /* If there's a comma before the colon, take only the
99 * first name in list */
100 comma = strchr(dev, ',');
103 host_len = comma - dev;
104 nfs_error(_("%s: warning: multiple hostnames not supported"),
109 path_len = strlen(colon);
110 if (path_len > NFS_MAXPATHNAME)
111 return nfs_pdn_pathname_too_long_err();
114 *hostname = strndup(dev, host_len);
115 if (*hostname == NULL)
116 return nfs_pdn_nomem_err();
119 *pathname = strndup(colon, path_len);
120 if (*pathname == NULL) {
122 return nfs_pdn_nomem_err();
129 * To handle raw IPv6 addresses (which contain colons), the
130 * server's address is enclosed in square brackets. Return
131 * what's between the brackets.
133 * There could be anything in between the brackets, but we'll
134 * let DNS resolution sort it out later.
136 static int nfs_parse_square_bracket(const char *dev,
137 char **hostname, char **pathname)
139 size_t host_len, path_len;
144 /* Must have a closing square bracket */
145 cbrace = strchr(dev, ']');
147 return nfs_pdn_missing_brace_err();
149 host_len = cbrace - dev;
151 /* Must have a colon just after the closing bracket */
154 return nfs_pdn_bad_format_err();
156 if (host_len > NFS_MAXHOSTNAME)
157 return nfs_pdn_hostname_too_long_err();
160 path_len = strlen(cbrace);
161 if (path_len > NFS_MAXPATHNAME)
162 return nfs_pdn_pathname_too_long_err();
165 *hostname = strndup(dev, host_len);
166 if (*hostname == NULL)
167 return nfs_pdn_nomem_err();
170 *pathname = strndup(cbrace, path_len);
171 if (*pathname == NULL) {
173 return nfs_pdn_nomem_err();
180 * RFC 2224 says an NFS client must grok "public file handles" to
181 * support NFS URLs. Linux doesn't do that yet. Print a somewhat
182 * helpful error message in this case instead of pressing forward
183 * with the mount request and failing with a cryptic error message
186 static int nfs_parse_nfs_url(__attribute__((unused)) const char *dev,
187 __attribute__((unused)) char **hostname,
188 __attribute__((unused)) char **pathname)
190 nfs_error(_("%s: NFS URLs are not supported"), progname);
195 * nfs_parse_devname - Determine the server's hostname by looking at "devname".
196 * @devname: pointer to mounted device name (first argument of mount command)
197 * @hostname: OUT: pointer to server's hostname
198 * @pathname: OUT: pointer to export path on server
200 * Returns 1 if succesful, or zero if some error occurred. On success,
201 * @hostname and @pathname point to dynamically allocated buffers containing
202 * the hostname of the server and the export pathname (both '\0'-terminated).
204 * @hostname or @pathname may be NULL if caller doesn't want a copy of those
207 * Note that this will not work if @devname is a wide-character string.
209 int nfs_parse_devname(const char *devname,
210 char **hostname, char **pathname)
216 return nfs_pdn_no_devname_err();
218 /* Parser is destructive, so operate on a copy of the device name. */
219 dev = strdup(devname);
221 return nfs_pdn_nomem_err();
223 result = nfs_parse_square_bracket(dev, hostname, pathname);
224 else if (strncmp(dev, "nfs://", 6) == 0)
225 result = nfs_parse_nfs_url(dev, hostname, pathname);
227 result = nfs_parse_simple_hostname(dev, hostname, pathname);