[linux-cifs-client] [PATCH 1/5] cifs: Introduce helpers for unicode buffer handing

Suresh Jayaraman sjayaraman at suse.de
Fri Apr 17 15:09:28 GMT 2009


Introduce helpers to compute length of NLS string in bytes and to
convert ucs string to nls format.

Signed-off-by: Suresh Jayaraman <sjayaraman at suse.de>
---
 fs/cifs/cifs_unicode.h |   27 +++++++++++++++++++++++++++
 fs/cifs/cifsproto.h    |    2 ++
 fs/cifs/cifssmb.c      |   31 +++++++++++++++++++++++++++++++
 3 files changed, 60 insertions(+), 0 deletions(-)

Index: cifs-2.6.git/fs/cifs/cifs_unicode.h
===================================================================
--- cifs-2.6.git.orig/fs/cifs/cifs_unicode.h
+++ cifs-2.6.git/fs/cifs/cifs_unicode.h
@@ -159,6 +159,33 @@ UniStrnlen(const wchar_t *ucs1, int maxl
 }
 
 /*
+ * UniStrnlenBytes: Return the length of a NLS string in bytes. Also, populates
+ * 'nchars' with the length of string in 16 bit Unicode chars.
+ */
+static inline size_t
+UniStrnlenBytes(const wchar_t *str, int maxlen, int *nchars,
+		const struct nls_table *codepage)
+{
+	int nc;
+	size_t nbytes = 0;
+	char buf[NLS_MAX_CHARSET_SIZE]; /* enough for one char at a time */
+
+	*nchars = 0;
+	while (*str++ && maxlen) {
+		nc = codepage->uni2char(*str, buf, NLS_MAX_CHARSET_SIZE);
+		if (nc > 0)
+			nbytes += nc;
+		else
+			nbytes += 1; /* for '?' */
+		(*nchars)++;
+		if (*nchars >= maxlen)
+			break;
+	}
+
+	return nbytes;
+}
+
+/*
  * UniStrncat:  Concatenate length limited string
  */
 static inline wchar_t *
Index: cifs-2.6.git/fs/cifs/cifsproto.h
===================================================================
--- cifs-2.6.git.orig/fs/cifs/cifsproto.h
+++ cifs-2.6.git/fs/cifs/cifsproto.h
@@ -383,4 +383,6 @@ extern int CIFSSMBSetPosixACL(const int
 		const struct nls_table *nls_codepage, int remap_special_chars);
 extern int CIFSGetExtAttr(const int xid, struct cifsTconInfo *tcon,
 			const int netfid, __u64 *pExtAttrBits, __u64 *pMask);
+extern int cifs_ucs_to_nls(char **dst, const char *src, const int maxlen,
+			   int *plen, const struct nls_table *nls_codepage);
 #endif			/* _CIFSPROTO_H */
Index: cifs-2.6.git/fs/cifs/cifssmb.c
===================================================================
--- cifs-2.6.git.orig/fs/cifs/cifssmb.c
+++ cifs-2.6.git/fs/cifs/cifssmb.c
@@ -81,6 +81,37 @@ static struct {
 #endif /* CONFIG_CIFS_WEAK_PW_HASH */
 #endif /* CIFS_POSIX */
 
+
+/*
+ * Calculates, allocates memory and converts to a NLS string.
+ * Note: caller is responsible for freeing dst if function returned 0.
+ * returns:
+ * 	on success - 0
+ * 	on failure - errno
+ */
+int
+cifs_ucs_to_nls(char **dst, const char *src, const int maxlen, int *plen,
+		       const struct nls_table *nls_codepage)
+{
+	size_t nbytes;
+
+	nbytes = UniStrnlenBytes((wchar_t *)src, maxlen, plen, nls_codepage);
+	cFYI(1, ("UniStrnlenBytes returned %ld bytes", nbytes));
+	*dst = kzalloc(nbytes + 2, GFP_KERNEL);
+	if (!*dst)
+		goto err_exit;
+
+	cifs_strfromUCS_le(*dst, (__le16 *)src, *plen, nls_codepage);
+
+	/* kzalloc() ensures NULL termination */
+
+	return 0;
+
+err_exit:
+	cERROR(1, ("Failed to allocate buffer for string\n"));
+	return -ENOMEM;
+}
+
 /* Allocates buffer into dst and copies smb string from src to it.
  * caller is responsible for freeing dst if function returned 0.
  * returns:


More information about the linux-cifs-client mailing list