patch-2.4.19 linux-2.4.19/fs/smbfs/proc.c

Next file: linux-2.4.19/fs/super.c
Previous file: linux-2.4.19/fs/smbfs/cache.c
Back to the patch index
Back to the overall index

diff -urN linux-2.4.18/fs/smbfs/proc.c linux-2.4.19/fs/smbfs/proc.c
@@ -109,6 +109,22 @@
 	return ilen;
 }
 
+static inline int write_char(unsigned char ch, char *output, int olen)
+{
+	if (olen < 4)
+		return -ENAMETOOLONG;
+	sprintf(output, ":x%02x", ch);
+	return 4;
+}
+
+static inline int write_unichar(wchar_t ch, char *output, int olen)
+{
+	if (olen < 5)
+		return -ENAMETOOLONG;
+	sprintf(output, ":%04x", ch);
+	return 5;
+}
+
 /* convert from one "codepage" to another (possibly being utf8). */
 static int convert_cp(char *output, int olen,
 		      const char *input, int ilen,
@@ -119,20 +135,26 @@
 	int n;
 	wchar_t ch;
 
-	if (!nls_from || !nls_to) {
-		PARANOIA("nls_from=%p, nls_to=%p\n", nls_from, nls_to);
-		return convert_memcpy(output, olen, input, ilen, NULL, NULL);
-	}
-
 	while (ilen > 0) {
 		/* convert by changing to unicode and back to the new cp */
 		n = nls_from->char2uni((unsigned char *)input, ilen, &ch);
-		if (n < 0)
+		if (n == -EINVAL) {
+			ilen--;
+			n = write_char(*input++, output, olen);
+			if (n < 0)
+				goto fail;
+			output += n;
+			olen -= n;
+			len += n;
+			continue;
+		} else if (n < 0)
 			goto fail;
 		input += n;
 		ilen -= n;
 
 		n = nls_to->uni2char(ch, output, olen);
+		if (n == -EINVAL)
+			n = write_unichar(ch, output, olen);
 		if (n < 0)
 			goto fail;
 		output += n;
@@ -226,8 +248,8 @@
 	if (maxlen < 2)
 		return -ENAMETOOLONG;
 
-	if (maxlen > SMB_MAXNAMELEN + 1)
-		maxlen = SMB_MAXNAMELEN + 1;
+	if (maxlen > SMB_MAXPATHLEN + 1)
+		maxlen = SMB_MAXPATHLEN + 1;
 
 	if (entry == NULL)
 		goto test_name_and_out;
@@ -1579,12 +1601,16 @@
 	}
 #endif
 
-	qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN,
-				     qname->name, len,
-				     server->remote_nls, server->local_nls);
-	qname->name = server->name_buf;
+	qname->len = 0;
+	len = server->convert(server->name_buf, SMB_MAXNAMELEN,
+			    qname->name, len,
+			    server->remote_nls, server->local_nls);
+	if (len > 0) {
+		qname->len = len;
+		qname->name = server->name_buf;
+		DEBUG1("len=%d, name=%.*s\n",qname->len,qname->len,qname->name);
+	}
 
-	DEBUG1("len=%d, name=%.*s\n", qname->len, qname->len, qname->name);
 	return p + 22;
 }
 
@@ -1700,7 +1726,8 @@
 		for (i = 0; i < count; i++) {
 			p = smb_decode_short_dirent(server, p, 
 						    &qname, &fattr);
-
+			if (qname.len == 0)
+				continue;
 			if (entries_seen == 2 && qname.name[0] == '.') {
 				if (qname.len == 1)
 					continue;
@@ -1737,6 +1764,7 @@
 {
 	char *result;
 	unsigned int len = 0;
+	int n;
 	__u16 date, time;
 
 	/*
@@ -1812,10 +1840,14 @@
 	}
 #endif
 
-	qname->len = server->convert(server->name_buf, SMB_MAXNAMELEN,
-				     qname->name, len,
-				     server->remote_nls, server->local_nls);
-	qname->name = server->name_buf;
+	qname->len = 0;
+	n = server->convert(server->name_buf, SMB_MAXNAMELEN,
+			    qname->name, len,
+			    server->remote_nls, server->local_nls);
+	if (n > 0) {
+		qname->len = n;
+		qname->name = server->name_buf;
+	}
 
 out:
 	return result;
@@ -1881,7 +1913,7 @@
 	 */
 	mask = param + 12;
 
-	mask_len = smb_encode_path(server, mask, SMB_MAXNAMELEN+1, dir, &star);
+	mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dir, &star);
 	if (mask_len < 0) {
 		result = mask_len;
 		goto unlock_return;
@@ -2030,6 +2062,8 @@
 
 			p = smb_decode_long_dirent(server, p, info_level,
 						   &qname, &fattr);
+			if (qname.len == 0)
+				continue;
 
 			/* ignore . and .. from the server */
 			if (entries_seen == 2 && qname.name[0] == '.') {
@@ -2088,7 +2122,7 @@
 	int mask_len, result;
 
 retry:
-	mask_len = smb_encode_path(server, mask, SMB_MAXNAMELEN+1, dentry, NULL);
+	mask_len = smb_encode_path(server, mask, SMB_MAXPATHLEN+1, dentry, NULL);
 	if (mask_len < 0) {
 		result = mask_len;
 		goto out;
@@ -2214,7 +2248,7 @@
       retry:
 	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */
 	DSET(param, 2, 0);
-	result = smb_encode_path(server, param+6, SMB_MAXNAMELEN+1, dir, NULL);
+	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
 	if (result < 0)
 		goto out;
 	p = param + 6 + result;
@@ -2464,7 +2498,7 @@
       retry:
 	WSET(param, 0, 1);	/* Info level SMB_INFO_STANDARD */
 	DSET(param, 2, 0);
-	result = smb_encode_path(server, param+6, SMB_MAXNAMELEN+1, dir, NULL);
+	result = smb_encode_path(server, param+6, SMB_MAXPATHLEN+1, dir, NULL);
 	if (result < 0)
 		goto out;
 	p = param + 6 + result;

FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)