Bug 183153 - [patch] Fix iconv support of mount_smbfs(8)
Summary: [patch] Fix iconv support of mount_smbfs(8)
Status: Closed FIXED
Alias: None
Product: Base System
Classification: Unclassified
Component: bin (show other bugs)
Version: unspecified
Hardware: Any Any
: Normal Affects Only Me
Assignee: Gleb Smirnoff
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2013-10-21 12:30 UTC by kamikaze
Modified: 2016-01-29 14:55 UTC (History)
1 user (show)

See Also:


Attachments
file.diff (4.26 KB, patch)
2013-10-21 12:30 UTC, kamikaze
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description kamikaze 2013-10-21 12:30:00 UTC
mount_smb fails when trying to perform charset conversions with the -E argument:


mount_smbfs: Unable to load iconv library: Shared object "libiconv.so" not found, required by "mount_smbfs"
: No error: 0
mount_smbfs: can't initialize iconv support (UTF-8:850): syserr = No such file or directory

Fix: The attached patch gets rid of dlopen() and uses base system iconv support instead.

Patch attached with submission follows:
How-To-Repeat: mount_smbfs -E UTF-8:850 /from /to
Comment 1 dfilter service freebsd_committer 2013-11-09 14:48:58 UTC
Author: glebius
Date: Sat Nov  9 14:48:50 2013
New Revision: 257888
URL: http://svnweb.freebsd.org/changeset/base/257888

Log:
  Use system libiconv, instead of trying to dlopen() it.
  
  PR:		183153
  Submitted by:	Dominic Fandrey <kamikaze bsdforen.de>

Modified:
  head/contrib/smbfs/lib/smb/nls.c
  head/usr.sbin/mount_smbfs/Makefile

Modified: head/contrib/smbfs/lib/smb/nls.c
==============================================================================
--- head/contrib/smbfs/lib/smb/nls.c	Sat Nov  9 14:46:24 2013	(r257887)
+++ head/contrib/smbfs/lib/smb/nls.c	Sat Nov  9 14:48:50 2013	(r257888)
@@ -36,12 +36,9 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
-#include <sys/iconv.h>
+#include <iconv.h>
 #include <sys/sysctl.h>
 #include <ctype.h>
-#ifndef APPLE
-#include <dlfcn.h>
-#endif
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
@@ -50,21 +47,10 @@ __FBSDID("$FreeBSD$");
 #include <err.h>
 #include <netsmb/smb_lib.h>
 
-/*
- * prototype iconv* functions
- */
-typedef void *iconv_t;
-
-static iconv_t (*my_iconv_open)(const char *, const char *);
-static size_t(*my_iconv)(iconv_t, const char **, size_t *, char **, size_t *);
-static int(*my_iconv_close)(iconv_t);
-
 u_char nls_lower[256];
 u_char nls_upper[256];
 
 static iconv_t nls_toext, nls_toloc;
-static int iconv_loaded;
-static void *iconv_lib;
 
 int
 nls_setlocale(const char *name)
@@ -90,32 +76,18 @@ nls_setrecode(const char *local, const c
 #else
 	iconv_t icd;
 
-	if (iconv_loaded == 2)
-		return ENOENT;
-	else if (iconv_loaded == 0) {
-		iconv_loaded++;
-		iconv_lib = dlopen("libiconv.so", RTLD_LAZY | RTLD_GLOBAL);
-		if (iconv_lib == NULL) {
-			warn("Unable to load iconv library: %s\n", dlerror());
-			iconv_loaded++;
-			return ENOENT;
-		}
-		my_iconv_open = dlsym(iconv_lib, "iconv_open");
-		my_iconv = dlsym(iconv_lib, "iconv");
-		my_iconv_close = dlsym(iconv_lib, "iconv_close");
-	}
 	if (nls_toext)
-		my_iconv_close(nls_toext);
+		iconv_close(nls_toext);
 	if (nls_toloc)
-		my_iconv_close(nls_toloc);
+		iconv_close(nls_toloc);
 	nls_toext = nls_toloc = (iconv_t)0;
-	icd = my_iconv_open(external, local);
+	icd = iconv_open(external, local);
 	if (icd == (iconv_t)-1)
 		return errno;
 	nls_toext = icd;
-	icd = my_iconv_open(local, external);
+	icd = iconv_open(local, external);
 	if (icd == (iconv_t)-1) {
-		my_iconv_close(nls_toext);
+		iconv_close(nls_toext);
 		nls_toext = (iconv_t)0;
 		return errno;
 	}
@@ -130,14 +102,11 @@ nls_str_toloc(char *dst, const char *src
 	char *p = dst;
 	size_t inlen, outlen;
 
-	if (!iconv_loaded)
-		return strcpy(dst, src);
-
 	if (nls_toloc == (iconv_t)0)
 		return strcpy(dst, src);
 	inlen = outlen = strlen(src);
-	my_iconv(nls_toloc, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toloc, &src, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toloc, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toloc, &src, &inlen, &p, &outlen) == -1) {
 		*p++ = *src++;
 		inlen--;
 		outlen--;
@@ -152,14 +121,11 @@ nls_str_toext(char *dst, const char *src
 	char *p = dst;
 	size_t inlen, outlen;
 
-	if (!iconv_loaded)
-		return strcpy(dst, src);
-
 	if (nls_toext == (iconv_t)0)
 		return strcpy(dst, src);
 	inlen = outlen = strlen(src);
-	my_iconv(nls_toext, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toext, &src, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toext, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toext, &src, &inlen, &p, &outlen) == -1) {
 		*p++ = *src++;
 		inlen--;
 		outlen--;
@@ -175,17 +141,14 @@ nls_mem_toloc(void *dst, const void *src
 	const char *s = src;
 	size_t inlen, outlen;
 
-	if (!iconv_loaded)
-		return memcpy(dst, src, size);
-
 	if (size == 0)
 		return NULL;
 
 	if (nls_toloc == (iconv_t)0)
 		return memcpy(dst, src, size);
 	inlen = outlen = size;
-	my_iconv(nls_toloc, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toloc, &s, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toloc, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toloc, &s, &inlen, &p, &outlen) == -1) {
 		*p++ = *s++;
 		inlen--;
 		outlen--;
@@ -203,12 +166,12 @@ nls_mem_toext(void *dst, const void *src
 	if (size == 0)
 		return NULL;
 
-	if (!iconv_loaded || nls_toext == (iconv_t)0)
+	if (nls_toext == (iconv_t)0)
 		return memcpy(dst, src, size);
 
 	inlen = outlen = size;
-	my_iconv(nls_toext, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toext, &s, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toext, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toext, &s, &inlen, &p, &outlen) == -1) {
 		*p++ = *s++;
 		inlen--;
 		outlen--;

Modified: head/usr.sbin/mount_smbfs/Makefile
==============================================================================
--- head/usr.sbin/mount_smbfs/Makefile	Sat Nov  9 14:46:24 2013	(r257887)
+++ head/usr.sbin/mount_smbfs/Makefile	Sat Nov  9 14:48:50 2013	(r257888)
@@ -11,11 +11,6 @@ CFLAGS+=	-DSMBFS -I${MOUNTDIR} -I${CONTR
 LDADD=	-lsmb -lkiconv
 DPADD=	${LIBSMB} ${LIBKICONV}
 
-# Needs to be dynamically linked for optional dlopen() access to
-# userland libiconv (see the -E option).
-#
-NO_SHARED?=	NO
-
 .PATH:	${CONTRIBDIR}/mount_smbfs
 .PATH:  ${MOUNTDIR}
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 2 Gleb Smirnoff freebsd_committer 2013-11-09 14:49:13 UTC
State Changed
From-To: open->patched

Committed, thanks! 


Comment 3 Gleb Smirnoff freebsd_committer 2013-11-09 14:49:13 UTC
Responsible Changed
From-To: freebsd-bugs->glebius

Committed, thanks!
Comment 4 dfilter service freebsd_committer 2013-11-14 09:25:38 UTC
Author: glebius
Date: Thu Nov 14 09:25:29 2013
New Revision: 258125
URL: http://svnweb.freebsd.org/changeset/base/258125

Log:
  Merge r257888, r258049 from head:
  
    - Use system libiconv, instead of trying to dlopen() it.
    - Just disable recoding support in libsmb if built WITHOUT_ICONV.
  
  PR:		183153
  Approved by:	re (kib)

Modified:
  stable/10/contrib/smbfs/lib/smb/nls.c
  stable/10/lib/libsmb/Makefile
  stable/10/usr.sbin/mount_smbfs/Makefile
Directory Properties:
  stable/10/contrib/smbfs/   (props changed)
  stable/10/lib/libsmb/   (props changed)
  stable/10/usr.sbin/mount_smbfs/   (props changed)

Modified: stable/10/contrib/smbfs/lib/smb/nls.c
==============================================================================
--- stable/10/contrib/smbfs/lib/smb/nls.c	Thu Nov 14 09:22:32 2013	(r258124)
+++ stable/10/contrib/smbfs/lib/smb/nls.c	Thu Nov 14 09:25:29 2013	(r258125)
@@ -36,12 +36,8 @@
 __FBSDID("$FreeBSD$");
 
 #include <sys/types.h>
-#include <sys/iconv.h>
 #include <sys/sysctl.h>
 #include <ctype.h>
-#ifndef APPLE
-#include <dlfcn.h>
-#endif
 #include <errno.h>
 #include <stdio.h>
 #include <string.h>
@@ -50,21 +46,16 @@ __FBSDID("$FreeBSD$");
 #include <err.h>
 #include <netsmb/smb_lib.h>
 
-/*
- * prototype iconv* functions
- */
-typedef void *iconv_t;
-
-static iconv_t (*my_iconv_open)(const char *, const char *);
-static size_t(*my_iconv)(iconv_t, const char **, size_t *, char **, size_t *);
-static int(*my_iconv_close)(iconv_t);
+#ifdef HAVE_ICONV
+#include <iconv.h>
+#endif
 
 u_char nls_lower[256];
 u_char nls_upper[256];
 
+#ifdef HAVE_ICONV
 static iconv_t nls_toext, nls_toloc;
-static int iconv_loaded;
-static void *iconv_lib;
+#endif
 
 int
 nls_setlocale(const char *name)
@@ -85,117 +76,107 @@ nls_setlocale(const char *name)
 int
 nls_setrecode(const char *local, const char *external)
 {
-#ifdef APPLE
-	return ENOENT;
-#else
+#ifdef HAVE_ICONV
 	iconv_t icd;
 
-	if (iconv_loaded == 2)
-		return ENOENT;
-	else if (iconv_loaded == 0) {
-		iconv_loaded++;
-		iconv_lib = dlopen("libiconv.so", RTLD_LAZY | RTLD_GLOBAL);
-		if (iconv_lib == NULL) {
-			warn("Unable to load iconv library: %s\n", dlerror());
-			iconv_loaded++;
-			return ENOENT;
-		}
-		my_iconv_open = dlsym(iconv_lib, "iconv_open");
-		my_iconv = dlsym(iconv_lib, "iconv");
-		my_iconv_close = dlsym(iconv_lib, "iconv_close");
-	}
 	if (nls_toext)
-		my_iconv_close(nls_toext);
+		iconv_close(nls_toext);
 	if (nls_toloc)
-		my_iconv_close(nls_toloc);
+		iconv_close(nls_toloc);
 	nls_toext = nls_toloc = (iconv_t)0;
-	icd = my_iconv_open(external, local);
+	icd = iconv_open(external, local);
 	if (icd == (iconv_t)-1)
 		return errno;
 	nls_toext = icd;
-	icd = my_iconv_open(local, external);
+	icd = iconv_open(local, external);
 	if (icd == (iconv_t)-1) {
-		my_iconv_close(nls_toext);
+		iconv_close(nls_toext);
 		nls_toext = (iconv_t)0;
 		return errno;
 	}
 	nls_toloc = icd;
 	return 0;
+#else
+	return ENOENT;
 #endif
 }
 
 char *
 nls_str_toloc(char *dst, const char *src)
 {
+#ifdef HAVE_ICONV
 	char *p = dst;
 	size_t inlen, outlen;
 
-	if (!iconv_loaded)
-		return strcpy(dst, src);
-
 	if (nls_toloc == (iconv_t)0)
 		return strcpy(dst, src);
 	inlen = outlen = strlen(src);
-	my_iconv(nls_toloc, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toloc, &src, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toloc, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toloc, &src, &inlen, &p, &outlen) == -1) {
 		*p++ = *src++;
 		inlen--;
 		outlen--;
 	}
 	*p = 0;
 	return dst;
+#else
+	return strcpy(dst, src);
+#endif
 }
 
 char *
 nls_str_toext(char *dst, const char *src)
 {
+#ifdef HAVE_ICONV
 	char *p = dst;
 	size_t inlen, outlen;
 
-	if (!iconv_loaded)
-		return strcpy(dst, src);
-
 	if (nls_toext == (iconv_t)0)
 		return strcpy(dst, src);
 	inlen = outlen = strlen(src);
-	my_iconv(nls_toext, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toext, &src, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toext, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toext, &src, &inlen, &p, &outlen) == -1) {
 		*p++ = *src++;
 		inlen--;
 		outlen--;
 	}
 	*p = 0;
 	return dst;
+#else
+	return strcpy(dst, src);
+#endif
 }
 
 void *
 nls_mem_toloc(void *dst, const void *src, int size)
 {
+#ifdef HAVE_ICONV
 	char *p = dst;
 	const char *s = src;
 	size_t inlen, outlen;
 
-	if (!iconv_loaded)
-		return memcpy(dst, src, size);
-
 	if (size == 0)
 		return NULL;
 
 	if (nls_toloc == (iconv_t)0)
 		return memcpy(dst, src, size);
 	inlen = outlen = size;
-	my_iconv(nls_toloc, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toloc, &s, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toloc, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toloc, &s, &inlen, &p, &outlen) == -1) {
 		*p++ = *s++;
 		inlen--;
 		outlen--;
 	}
 	return dst;
+#else
+	return memcpy(dst, src, size);
+#endif
 }
 
 void *
 nls_mem_toext(void *dst, const void *src, int size)
 {
+#ifdef HAVE_ICONV
 	char *p = dst;
 	const char *s = src;
 	size_t inlen, outlen;
@@ -203,17 +184,20 @@ nls_mem_toext(void *dst, const void *src
 	if (size == 0)
 		return NULL;
 
-	if (!iconv_loaded || nls_toext == (iconv_t)0)
+	if (nls_toext == (iconv_t)0)
 		return memcpy(dst, src, size);
 
 	inlen = outlen = size;
-	my_iconv(nls_toext, NULL, NULL, &p, &outlen);
-	while (my_iconv(nls_toext, &s, &inlen, &p, &outlen) == -1) {
+	iconv(nls_toext, NULL, NULL, &p, &outlen);
+	while (iconv(nls_toext, &s, &inlen, &p, &outlen) == -1) {
 		*p++ = *s++;
 		inlen--;
 		outlen--;
 	}
 	return dst;
+#else
+	return memcpy(dst, src, size);
+#endif
 }
 
 char *

Modified: stable/10/lib/libsmb/Makefile
==============================================================================
--- stable/10/lib/libsmb/Makefile	Thu Nov 14 09:22:32 2013	(r258124)
+++ stable/10/lib/libsmb/Makefile	Thu Nov 14 09:25:29 2013	(r258125)
@@ -1,5 +1,7 @@
 # $FreeBSD$
 
+.include <bsd.own.mk>
+
 CONTRIBDIR=	${.CURDIR}/../../contrib/smbfs
 .PATH: ${CONTRIBDIR}/lib/smb
 
@@ -16,4 +18,8 @@ SRCS=	rcfile.c ctx.c cfopt.c subr.c nls.
 WARNS?=	1
 CFLAGS+= -DSMB_CFG_FILE=\"/etc/nsmb.conf\" -I${CONTRIBDIR}/include
 
+.if ${MK_ICONV} != "no"
+CFLAGS+= -DHAVE_ICONV=1
+.endif
+
 .include <bsd.lib.mk>

Modified: stable/10/usr.sbin/mount_smbfs/Makefile
==============================================================================
--- stable/10/usr.sbin/mount_smbfs/Makefile	Thu Nov 14 09:22:32 2013	(r258124)
+++ stable/10/usr.sbin/mount_smbfs/Makefile	Thu Nov 14 09:25:29 2013	(r258125)
@@ -11,11 +11,6 @@ CFLAGS+=	-DSMBFS -I${MOUNTDIR} -I${CONTR
 LDADD=	-lsmb -lkiconv
 DPADD=	${LIBSMB} ${LIBKICONV}
 
-# Needs to be dynamically linked for optional dlopen() access to
-# userland libiconv (see the -E option).
-#
-NO_SHARED?=	NO
-
 .PATH:	${CONTRIBDIR}/mount_smbfs
 .PATH:  ${MOUNTDIR}
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
Comment 5 Gleb Smirnoff freebsd_committer 2013-11-14 09:41:21 UTC
State Changed
From-To: patched->closed

Merged to stable/10.