diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-04 02:39:55 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-02-04 02:39:55 +0000 |
| commit | 5870ad9672ac09e366f1bfd4086e98cd019ed8f2 (patch) | |
| tree | d7657a18e022900fdc6e0df24b59af9042e84109 | |
| parent | 42823d597a9029ac497edda9102f61283630635b (diff) | |
| download | busybox-w32-5870ad9672ac09e366f1bfd4086e98cd019ed8f2.tar.gz busybox-w32-5870ad9672ac09e366f1bfd4086e98cd019ed8f2.tar.bz2 busybox-w32-5870ad9672ac09e366f1bfd4086e98cd019ed8f2.zip | |
mount: (try to) support cifs with IPv6
| -rw-r--r-- | include/libbb.h | 5 | ||||
| -rw-r--r-- | libbb/xconnect.c | 8 | ||||
| -rw-r--r-- | util-linux/mount.c | 35 |
3 files changed, 33 insertions, 15 deletions
diff --git a/include/libbb.h b/include/libbb.h index dd23c704d..742d04031 100644 --- a/include/libbb.h +++ b/include/libbb.h | |||
| @@ -316,7 +316,10 @@ int xconnect_stream(const len_and_sockaddr *lsa); | |||
| 316 | /* Return malloc'ed len_and_sockaddr with socket address of host:port | 316 | /* Return malloc'ed len_and_sockaddr with socket address of host:port |
| 317 | * Currently will return IPv4 or IPv6 sockaddrs only | 317 | * Currently will return IPv4 or IPv6 sockaddrs only |
| 318 | * (depending on host), but in theory nothing prevents e.g. | 318 | * (depending on host), but in theory nothing prevents e.g. |
| 319 | * UNIX socket address being returned, IPX sockaddr etc... */ | 319 | * UNIX socket address being returned, IPX sockaddr etc... |
| 320 | * On error does bb_error_msg and returns NULL */ | ||
| 321 | len_and_sockaddr* host2sockaddr(const char *host, int port); | ||
| 322 | /* Versions which die on error */ | ||
| 320 | len_and_sockaddr* xhost2sockaddr(const char *host, int port); | 323 | len_and_sockaddr* xhost2sockaddr(const char *host, int port); |
| 321 | #if ENABLE_FEATURE_IPV6 | 324 | #if ENABLE_FEATURE_IPV6 |
| 322 | /* Same, useful if you want to force family (e.g. IPv6) */ | 325 | /* Same, useful if you want to force family (e.g. IPv6) */ |
diff --git a/libbb/xconnect.c b/libbb/xconnect.c index e5bdaac38..c3ccc470b 100644 --- a/libbb/xconnect.c +++ b/libbb/xconnect.c | |||
| @@ -164,8 +164,9 @@ USE_FEATURE_IPV6(sa_family_t af,) | |||
| 164 | hint.ai_flags = ai_flags & ~DIE_ON_ERROR; | 164 | hint.ai_flags = ai_flags & ~DIE_ON_ERROR; |
| 165 | rc = getaddrinfo(host, NULL, &hint, &result); | 165 | rc = getaddrinfo(host, NULL, &hint, &result); |
| 166 | if (rc || !result) { | 166 | if (rc || !result) { |
| 167 | bb_error_msg("bad address '%s'", org_host); | ||
| 167 | if (ai_flags & DIE_ON_ERROR) | 168 | if (ai_flags & DIE_ON_ERROR) |
| 168 | bb_error_msg_and_die("bad address '%s'", org_host); | 169 | sleep_and_die(); |
| 169 | goto ret; | 170 | goto ret; |
| 170 | } | 171 | } |
| 171 | r = xmalloc(offsetof(len_and_sockaddr, sa) + result->ai_addrlen); | 172 | 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 | |||
| 187 | } | 188 | } |
| 188 | #endif | 189 | #endif |
| 189 | 190 | ||
| 191 | len_and_sockaddr* host2sockaddr(const char *host, int port) | ||
| 192 | { | ||
| 193 | return str2sockaddr(host, port, AF_UNSPEC, 0); | ||
| 194 | } | ||
| 195 | |||
| 190 | len_and_sockaddr* xhost2sockaddr(const char *host, int port) | 196 | len_and_sockaddr* xhost2sockaddr(const char *host, int port) |
| 191 | { | 197 | { |
| 192 | return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR); | 198 | return str2sockaddr(host, port, AF_UNSPEC, DIE_ON_ERROR); |
diff --git a/util-linux/mount.c b/util-linux/mount.c index 702c0338a..567514ccb 100644 --- a/util-linux/mount.c +++ b/util-linux/mount.c | |||
| @@ -687,6 +687,8 @@ get_mountport(struct sockaddr_in *server_addr, | |||
| 687 | static struct pmap p = {0, 0, 0, 0}; | 687 | static struct pmap p = {0, 0, 0, 0}; |
| 688 | 688 | ||
| 689 | server_addr->sin_port = PMAPPORT; | 689 | server_addr->sin_port = PMAPPORT; |
| 690 | /* glibc 2.4 (still) has pmap_getmaps(struct sockaddr_in *). | ||
| 691 | * I understand it like "IPv6 for this is not 100% ready" */ | ||
| 690 | pmap = pmap_getmaps(server_addr); | 692 | pmap = pmap_getmaps(server_addr); |
| 691 | 693 | ||
| 692 | if (version > MAX_NFSPROT) | 694 | if (version > MAX_NFSPROT) |
| @@ -1396,8 +1398,9 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
| 1396 | && (mp->mnt_fsname[0]=='/' || mp->mnt_fsname[0]=='\\') | 1398 | && (mp->mnt_fsname[0]=='/' || mp->mnt_fsname[0]=='\\') |
| 1397 | && mp->mnt_fsname[0]==mp->mnt_fsname[1] | 1399 | && mp->mnt_fsname[0]==mp->mnt_fsname[1] |
| 1398 | ) { | 1400 | ) { |
| 1399 | struct hostent *he; | 1401 | len_and_sockaddr *lsa; |
| 1400 | char ip[32], *s; | 1402 | char *ip, *dotted; |
| 1403 | char *s; | ||
| 1401 | 1404 | ||
| 1402 | rc = 1; | 1405 | rc = 1; |
| 1403 | // Replace '/' with '\' and verify that unc points to "//server/share". | 1406 | // Replace '/' with '\' and verify that unc points to "//server/share". |
| @@ -1408,29 +1411,34 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
| 1408 | // get server IP | 1411 | // get server IP |
| 1409 | 1412 | ||
| 1410 | s = strrchr(mp->mnt_fsname, '\\'); | 1413 | s = strrchr(mp->mnt_fsname, '\\'); |
| 1411 | if (s == mp->mnt_fsname+1) goto report_error; | 1414 | if (s <= mp->mnt_fsname+1) goto report_error; |
| 1412 | *s = '\0'; | 1415 | *s = '\0'; |
| 1413 | he = gethostbyname(mp->mnt_fsname+2); | 1416 | lsa = host2sockaddr(mp->mnt_fsname+2, 0); |
| 1414 | *s = '\\'; | 1417 | *s = '\\'; |
| 1415 | if (!he) goto report_error; | 1418 | if (!lsa) goto report_error; |
| 1416 | 1419 | ||
| 1417 | // Insert ip=... option into string flags. (NOTE: Add IPv6 support.) | 1420 | // insert ip=... option into string flags. |
| 1418 | 1421 | ||
| 1419 | sprintf(ip, "ip=%d.%d.%d.%d", he->h_addr[0], he->h_addr[1], | 1422 | dotted = xmalloc_sockaddr2dotted_noport(&lsa->sa, lsa->len); |
| 1420 | he->h_addr[2], he->h_addr[3]); | 1423 | ip = xasprintf("ip=%s", dotted); |
| 1421 | parse_mount_options(ip, &filteropts); | 1424 | parse_mount_options(ip, &filteropts); |
| 1422 | 1425 | ||
| 1423 | // compose new unc '\\server-ip\share' | 1426 | // compose new unc '\\server-ip\share' |
| 1427 | // (s => slash after hostname) | ||
| 1424 | 1428 | ||
| 1425 | mp->mnt_fsname = xasprintf("\\\\%s%s", ip+3, | 1429 | mp->mnt_fsname = xasprintf("\\\\%s%s", dotted, s); |
| 1426 | strchr(mp->mnt_fsname+2,'\\')); | ||
| 1427 | 1430 | ||
| 1428 | // lock is required | 1431 | // lock is required |
| 1429 | vfsflags |= MS_MANDLOCK; | 1432 | vfsflags |= MS_MANDLOCK; |
| 1430 | 1433 | ||
| 1431 | mp->mnt_type = (char*)"cifs"; | 1434 | mp->mnt_type = (char*)"cifs"; |
| 1432 | rc = mount_it_now(mp, vfsflags, filteropts); | 1435 | rc = mount_it_now(mp, vfsflags, filteropts); |
| 1433 | if (ENABLE_FEATURE_CLEAN_UP) free(mp->mnt_fsname); | 1436 | if (ENABLE_FEATURE_CLEAN_UP) { |
| 1437 | free(mp->mnt_fsname); | ||
| 1438 | free(ip); | ||
| 1439 | free(dotted); | ||
| 1440 | free(lsa); | ||
| 1441 | } | ||
| 1434 | goto report_error; | 1442 | goto report_error; |
| 1435 | } | 1443 | } |
| 1436 | 1444 | ||
| @@ -1508,8 +1516,9 @@ static int singlemount(struct mntent *mp, int ignore_busy) | |||
| 1508 | } | 1516 | } |
| 1509 | } | 1517 | } |
| 1510 | 1518 | ||
| 1511 | report_error: | 1519 | report_error: |
| 1512 | if (ENABLE_FEATURE_CLEAN_UP) free(filteropts); | 1520 | if (ENABLE_FEATURE_CLEAN_UP) |
| 1521 | free(filteropts); | ||
| 1513 | 1522 | ||
| 1514 | if (rc && errno == EBUSY && ignore_busy) rc = 0; | 1523 | if (rc && errno == EBUSY && ignore_busy) rc = 0; |
| 1515 | if (rc < 0) | 1524 | if (rc < 0) |
