mount: (try to) support cifs with IPv6

This commit is contained in:
Denis Vlasenko 2007-02-04 02:39:55 +00:00
parent 42823d597a
commit 5870ad9672
3 changed files with 33 additions and 15 deletions

View File

@ -316,7 +316,10 @@ int xconnect_stream(const len_and_sockaddr *lsa);
/* Return malloc'ed len_and_sockaddr with socket address of host:port /* Return malloc'ed len_and_sockaddr with socket address of host:port
* Currently will return IPv4 or IPv6 sockaddrs only * Currently will return IPv4 or IPv6 sockaddrs only
* (depending on host), but in theory nothing prevents e.g. * (depending on host), but in theory nothing prevents e.g.
* UNIX socket address being returned, IPX sockaddr etc... */ * UNIX socket address being returned, IPX sockaddr etc...
* On error does bb_error_msg and returns NULL */
len_and_sockaddr* host2sockaddr(const char *host, int port);
/* Versions which die on error */
len_and_sockaddr* xhost2sockaddr(const char *host, int port); len_and_sockaddr* xhost2sockaddr(const char *host, int port);
#if ENABLE_FEATURE_IPV6 #if ENABLE_FEATURE_IPV6
/* Same, useful if you want to force family (e.g. IPv6) */ /* Same, useful if you want to force family (e.g. IPv6) */

View File

@ -164,8 +164,9 @@ USE_FEATURE_IPV6(sa_family_t af,)
hint.ai_flags = ai_flags & ~DIE_ON_ERROR; hint.ai_flags = ai_flags & ~DIE_ON_ERROR;
rc = getaddrinfo(host, NULL, &hint, &result); rc = getaddrinfo(host, NULL, &hint, &result);
if (rc || !result) { if (rc || !result) {
bb_error_msg("bad address '%s'", org_host);
if (ai_flags & DIE_ON_ERROR) if (ai_flags & DIE_ON_ERROR)
bb_error_msg_and_die("bad address '%s'", org_host); sleep_and_die();
goto ret; goto ret;
} }
r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen);
@ -187,6 +188,11 @@ len_and_sockaddr* xhost_and_af2sockaddr(const char *host, int port, sa_family_t
} }
#endif #endif
len_and_sockaddr* host2sockaddr(const char *host, int port)
{
return str2sockaddr(host, port, AF_UNSPEC, 0);
}
len_and_sockaddr* xhost2sockaddr(const char *host, int port) len_and_sockaddr* xhost2sockaddr(const char *host, int port)
{ {
return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR); return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR);

View File

@ -687,6 +687,8 @@ get_mountport(struct sockaddr_in *server_addr,
static struct pmap p = {0, 0, 0, 0}; static struct pmap p = {0, 0, 0, 0};
server_addr->sin_port = PMAPPORT; server_addr->sin_port = PMAPPORT;
/* glibc 2.4 (still) has pmap_getmaps(struct sockaddr_in *).
* I understand it like "IPv6 for this is not 100% ready" */
pmap = pmap_getmaps(server_addr); pmap = pmap_getmaps(server_addr);
if (version > MAX_NFSPROT) if (version > MAX_NFSPROT)
@ -1396,8 +1398,9 @@ static int singlemount(struct mntent *mp, int ignore_busy)
&& (mp->mnt_fsname[0]=='/' || mp->mnt_fsname[0]=='\\') && (mp->mnt_fsname[0]=='/' || mp->mnt_fsname[0]=='\\')
&& mp->mnt_fsname[0]==mp->mnt_fsname[1] && mp->mnt_fsname[0]==mp->mnt_fsname[1]
) { ) {
struct hostent *he; len_and_sockaddr *lsa;
char ip[32], *s; char *ip, *dotted;
char *s;
rc = 1; rc = 1;
// Replace '/' with '\' and verify that unc points to "//server/share". // Replace '/' with '\' and verify that unc points to "//server/share".
@ -1408,29 +1411,34 @@ static int singlemount(struct mntent *mp, int ignore_busy)
// get server IP // get server IP
s = strrchr(mp->mnt_fsname, '\\'); s = strrchr(mp->mnt_fsname, '\\');
if (s == mp->mnt_fsname+1) goto report_error; if (s <= mp->mnt_fsname+1) goto report_error;
*s = '\0'; *s = '\0';
he = gethostbyname(mp->mnt_fsname+2); lsa = host2sockaddr(mp->mnt_fsname+2, 0);
*s = '\\'; *s = '\\';
if (!he) goto report_error; if (!lsa) goto report_error;
// Insert ip=... option into string flags. (NOTE: Add IPv6 support.) // insert ip=... option into string flags.
sprintf(ip, "ip=%d.%d.%d.%d", he->h_addr[0], he->h_addr[1], dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len);
he->h_addr[2], he->h_addr[3]); ip = xasprintf("ip=%s", dotted);
parse_mount_options(ip, &filteropts); parse_mount_options(ip, &filteropts);
// compose new unc '\\server-ip\share' // compose new unc '\\server-ip\share'
// (s => slash after hostname)
mp->mnt_fsname = xasprintf("\\\\%s%s", ip+3, mp->mnt_fsname = xasprintf("\\\\%s%s", dotted, s);
strchr(mp->mnt_fsname+2,'\\'));
// lock is required // lock is required
vfsflags |= MS_MANDLOCK; vfsflags |= MS_MANDLOCK;
mp->mnt_type = (char*)"cifs"; mp->mnt_type = (char*)"cifs";
rc = mount_it_now(mp, vfsflags, filteropts); rc = mount_it_now(mp, vfsflags, filteropts);
if (ENABLE_FEATURE_CLEAN_UP) free(mp->mnt_fsname); if (ENABLE_FEATURE_CLEAN_UP) {
free(mp->mnt_fsname);
free(ip);
free(dotted);
free(lsa);
}
goto report_error; goto report_error;
} }
@ -1508,8 +1516,9 @@ static int singlemount(struct mntent *mp, int ignore_busy)
} }
} }
report_error: report_error:
if (ENABLE_FEATURE_CLEAN_UP) free(filteropts); if (ENABLE_FEATURE_CLEAN_UP)
free(filteropts);
if (rc && errno == EBUSY && ignore_busy) rc = 0; if (rc && errno == EBUSY && ignore_busy) rc = 0;
if (rc < 0) if (rc < 0)