From nobody@FreeBSD.org  Mon May 14 15:12:47 2007
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id ED23116A400
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 14 May 2007 15:12:47 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [69.147.83.33])
	by mx1.freebsd.org (Postfix) with ESMTP id DC78713C45B
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 14 May 2007 15:12:47 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.13.1/8.13.1) with ESMTP id l4EFClVf073382
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 14 May 2007 15:12:47 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.13.1/8.13.1/Submit) id l4EF7kUt072625;
	Mon, 14 May 2007 15:07:46 GMT
	(envelope-from nobody)
Message-Id: <200705141507.l4EF7kUt072625@www.freebsd.org>
Date: Mon, 14 May 2007 15:07:46 GMT
From: Ganael LAPLANCHE<ganael.laplanche@martymac.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [PATCH] Smbfs and caching problems (resolves bin/111004)
X-Send-Pr-Version: www-3.0

>Number:         112658
>Category:       kern
>Synopsis:       [smbfs] [patch] smbfs and caching problems (resolves bin/111004)
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    freebsd-fs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon May 14 15:20:02 GMT 2007
>Closed-Date:    
>Last-Modified:  Wed Feb 20 07:20:00 UTC 2013
>Originator:     Ganael LAPLANCHE
>Release:        6.2-STABLE
>Organization:
http://contribs.martymac.com
>Environment:
FreeBSD home.martymac.com 6.2-STABLE FreeBSD 6.2-STABLE #0: Mon Apr 30 08:41:10 UTC 2007     martymac@home.martymac.com:/usr/src/sys/i386/compile/MYKERNEL  i386
>Description:
This PR includes a patch for PR bin/111004.

I've encountered caching problems with smbfs mounts when the server is case-insensitive (e.g. with 'case sensitive = no' in smb.conf on the server - no problem with 'case sensitive = yes'). Sometimes, a wrong entry is created in the cache and does not match the real filename's case on the server. This happens because the server answers : 'yes, the file exists' while it has a different case. Sometimes then, this cache entry is found and used (because of cache's case-sensitiveness), while it should not. 

----
Here is a test you can perform (on a smbfs mount point) :

$ touch foo && rm -f foo && touch FOO && rm -f FOO
This is to purge cache entries explicitly.

$ touch foo && ls -i foo
2864008422 foo
$ ls -i FOO
2864008422 FOO
This is OK since we should see the inode of foo.

$ rm -f foo
$ touch FOO && ls -i FOO
2864008422 FOO
Nope, we should get another inode (2322004806) since inodes depend on the filename and the parent directory. Here, a wrong cache entry has been used.

$ rm -f FOO
$ touch FOO && ls -i FOO
2322004806 FOO

This is OK again (because the cache entry has been explicitely removed before).
----

The attached patch is inspired from Opendarwin's code and uses the filename provided by the server when the file is found (instead of using the requested filename that may differ). This allows a better cache synchronization and solves this inode/caching problem.

Moreover, I've added a fix for PR bin/111004 which now allows to modify the case of a file (to 'rename' it).

This patch applies cleanly (and works ;-)) on 6.2-STABLE. It also applies to -CURRENT, but I have not tested it on this version.

Best regards,

--
Ganael LAPLANCHE.
ganael.laplanche@martymac.com
http://contribs.martymac.com
>How-To-Repeat:
Try the test above.
>Fix:


Patch attached with submission follows:

diff -aur smbfs.orig/smbfs_node.c smbfs/smbfs_node.c
--- smbfs.orig/smbfs_node.c	Thu May  3 18:20:57 2007
+++ smbfs/smbfs_node.c	Mon May 14 14:00:59 2007
@@ -108,7 +108,7 @@
 	return 0;
 }
 
-static char *
+char *
 smbfs_name_alloc(const u_char *name, int nmlen)
 {
 	u_char *cp;
@@ -130,7 +130,7 @@
 	return cp;
 }
 
-static void
+void
 smbfs_name_free(u_char *name)
 {
 #ifdef SMBFS_NAME_DEBUG
diff -aur smbfs.orig/smbfs_node.h smbfs/smbfs_node.h
--- smbfs.orig/smbfs_node.h	Thu May  3 18:20:57 2007
+++ smbfs/smbfs_node.h	Mon May 14 14:00:59 2007
@@ -87,6 +87,9 @@
 	struct smbfattr *fap, struct vnode **vpp);
 u_int32_t smbfs_hash(const u_char *name, int nmlen);
 
+char  *smbfs_name_alloc(const u_char *name, int nmlen);
+void   smbfs_name_free(u_char *name);
+
 int  smbfs_getpages(struct vop_getpages_args *);
 int  smbfs_putpages(struct vop_putpages_args *);
 int  smbfs_readvnode(struct vnode *vp, struct uio *uiop, struct ucred *cred);
diff -aur smbfs.orig/smbfs_smb.c smbfs/smbfs_smb.c
--- smbfs.orig/smbfs_smb.c	Thu May  3 18:20:57 2007
+++ smbfs/smbfs_smb.c	Mon May 14 14:00:59 2007
@@ -1470,37 +1470,50 @@
 }
 
 int
-smbfs_smb_lookup(struct smbnode *dnp, const char *name, int nmlen,
+smbfs_smb_lookup(struct smbnode *dnp, char **namep, int *nmlenp,
 	struct smbfattr *fap, struct smb_cred *scred)
 {
 	struct smbfs_fctx *ctx;
 	int error;
 
-	if (dnp == NULL || (dnp->n_ino == 2 && name == NULL)) {
+	if (dnp == NULL ||
+		(dnp->n_ino == 2 && (namep == NULL || *namep == NULL))) {
 		bzero(fap, sizeof(*fap));
 		fap->fa_attr = SMB_FA_DIR;
 		fap->fa_ino = 2;
 		return 0;
 	}
-	if (nmlen == 1 && name[0] == '.') {
-		error = smbfs_smb_lookup(dnp, NULL, 0, fap, scred);
+	if (nmlenp && *nmlenp == 1 && namep && (*namep)[0] == '.') {
+		error = smbfs_smb_lookup(dnp, NULL, NULL, fap, scred);
 		return error;
-	} else if (nmlen == 2 && name[0] == '.' && name[1] == '.') {
-		error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
-		    scred);
+	} else if (nmlenp && *nmlenp == 2 && namep && (*namep)[0] == '.' &&
+		(*namep)[1] == '.') {
+		error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, NULL,
+			fap, scred);
 		printf("%s: knows NOTHING about '..'\n", __func__);
 		return error;
 	}
-	error = smbfs_findopen(dnp, name, nmlen,
-	    SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, scred, &ctx);
+	error = smbfs_findopen(dnp, namep ? *namep : NULL, nmlenp ? *nmlenp : 0,
+		SMB_FA_SYSTEM | SMB_FA_HIDDEN | SMB_FA_DIR, scred, &ctx);
 	if (error)
 		return error;
 	ctx->f_flags |= SMBFS_RDD_FINDSINGLE;
 	error = smbfs_findnext(ctx, 1, scred);
 	if (error == 0) {
 		*fap = ctx->f_attr;
-		if (name == NULL)
+		if (namep == NULL || *namep == NULL)
 			fap->fa_ino = dnp->n_ino;
+		if (namep && *namep && nmlenp && *nmlenp) {
+			/* Return the *real* name and length of the file 
+			 * found on the server if necessary. If a new allocation
+			 * is done here, memory will be freed later */
+			if((ctx->f_nmlen != *nmlenp) ||
+				(bcmp(ctx->f_name, *namep, *nmlenp) != 0)) {
+				SMBVDEBUG("lookuped filename and server's filename differ\n");
+				*namep = smbfs_name_alloc((u_char *)(ctx->f_name), ctx->f_nmlen);
+				*nmlenp = ctx->f_nmlen;
+			}
+		}
 	}
 	smbfs_findclose(ctx, scred);
 	return error;
diff -aur smbfs.orig/smbfs_subr.h smbfs/smbfs_subr.h
--- smbfs.orig/smbfs_subr.h	Thu May  3 18:20:57 2007
+++ smbfs/smbfs_subr.h	Mon May 14 14:00:59 2007
@@ -171,7 +171,7 @@
 int  smbfs_findclose(struct smbfs_fctx *ctx, struct smb_cred *scred);
 int  smbfs_fullpath(struct mbchain *mbp, struct smb_vc *vcp,
 	struct smbnode *dnp, const char *name, int nmlen);
-int  smbfs_smb_lookup(struct smbnode *dnp, const char *name, int nmlen,
+int  smbfs_smb_lookup(struct smbnode *dnp, char **namep, int *nmlenp,
 	struct smbfattr *fap, struct smb_cred *scred);
 
 int  smbfs_fname_tolocal(struct smb_vc *vcp, char *name, int *nmlen, int caseopt);
diff -aur smbfs.orig/smbfs_vfsops.c smbfs/smbfs_vfsops.c
--- smbfs.orig/smbfs_vfsops.c	Thu May  3 18:20:57 2007
+++ smbfs/smbfs_vfsops.c	Mon May 14 14:00:59 2007
@@ -333,7 +333,7 @@
 		return vget(*vpp, LK_EXCLUSIVE | LK_RETRY, td);
 	}
 	smb_makescred(&scred, td, cred);
-	error = smbfs_smb_lookup(NULL, NULL, 0, &fattr, &scred);
+	error = smbfs_smb_lookup(NULL, NULL, NULL, &fattr, &scred);
 	if (error)
 		return error;
 	error = smbfs_nget(mp, NULL, "TheRooT", 7, &fattr, &vp);
diff -aur smbfs.orig/smbfs_vnops.c smbfs/smbfs_vnops.c
--- smbfs.orig/smbfs_vnops.c	Thu May  3 18:20:57 2007
+++ smbfs/smbfs_vnops.c	Mon May 14 14:06:01 2007
@@ -264,14 +264,15 @@
 	u_quad_t oldsize;
 	int error;
 
-	SMBVDEBUG("%lx: '%s' %d\n", (long)vp, np->n_name, (vp->v_vflag & VV_ROOT) != 0);
+	SMBVDEBUG("%lx: '%s' %d\n", (long)vp, np->n_name,
+		(vp->v_vflag & VV_ROOT) != 0);
 	error = smbfs_attr_cachelookup(vp, va);
 	if (!error)
 		return 0;
 	SMBVDEBUG("not in the cache\n");
 	smb_makescred(&scred, ap->a_td, ap->a_cred);
 	oldsize = np->n_size;
-	error = smbfs_smb_lookup(np, NULL, 0, &fattr, &scred);
+	error = smbfs_smb_lookup(np, NULL, NULL, &fattr, &scred);
 	if (error) {
 		SMBVDEBUG("error %d\n", error);
 		return error;
@@ -488,15 +489,21 @@
 	error = smbfs_smb_create(dnp, name, nmlen, &scred);
 	if (error)
 		return error;
-	error = smbfs_smb_lookup(dnp, name, nmlen, &fattr, &scred);
+	/* smbfs_smb_lookup can allocate a new "name" so use "out" from
+	 * here on */
+	error = smbfs_smb_lookup(dnp, &name, &nmlen, &fattr, &scred);
 	if (error)
-		return error;
+		goto out;
 	error = smbfs_nget(VTOVFS(dvp), dvp, name, nmlen, &fattr, &vp);
 	if (error)
-		return error;
+		goto out;
 	*vpp = vp;
 	if (cnp->cn_flags & MAKEENTRY)
 		cache_enter(dvp, vp, cnp);
+
+out:
+	if (name != cnp->cn_nameptr)
+		smbfs_name_free((u_char *)name);
 	return error;
 }
 
@@ -689,14 +696,21 @@
 	error = smbfs_smb_mkdir(dnp, name, len, &scred);
 	if (error)
 		return error;
-	error = smbfs_smb_lookup(dnp, name, len, &fattr, &scred);
+	/* smbfs_smb_lookup can allocate a new "name" so use "out" from
+	 * here on */
+	error = smbfs_smb_lookup(dnp, &name, &len, &fattr, &scred);
 	if (error)
-		return error;
+		goto out;
 	error = smbfs_nget(VTOVFS(dvp), dvp, name, len, &fattr, &vp);
 	if (error)
-		return error;
+		goto out;
 	*ap->a_vpp = vp;
-	return 0;
+	error = 0;
+
+out:
+	if (name != cnp->cn_nameptr)
+		smbfs_name_free((u_char *)name);
+	return error;
 }
 
 /*
@@ -1100,7 +1114,7 @@
 		cp = name + nmlen;
 		c = *cp;
 		*cp = 0;
-		SMBVDEBUG("%d '%s' in '%s' id=d\n", nameiop, name, 
+		SMBVDEBUG("nameiop = %d for '%s' in '%s'\n", nameiop, name,
 			VTOSMB(dvp)->n_name);
 		*cp = c;
 	}
@@ -1120,7 +1134,8 @@
 		return ENOENT;
 
 	error = cache_lookup(dvp, vpp, cnp);
-	SMBVDEBUG("cache_lookup returned %d\n", error);
+	SMBVDEBUG("cache_lookup for '%s' returned %d\n", cnp->cn_nameptr,
+		error);
 	if (error > 0)
 		return error;
 	if (error) {		/* name was found */
@@ -1144,10 +1159,10 @@
 		   killit = 1;
 		else if (error == 0
 	     /*    && vattr.va_ctime.tv_sec == VTOSMB(vp)->n_ctime*/) {
-		     if (nameiop != LOOKUP && islastcn)
-			     cnp->cn_flags |= SAVENAME;
-		     SMBVDEBUG("use cached vnode\n");
-		     return (0);
+			if (nameiop != LOOKUP && islastcn)
+				cnp->cn_flags |= SAVENAME;
+			SMBVDEBUG("use cached vnode\n");
+			return (0);
 		}
 		cache_purge(vp);
 		/*
@@ -1165,77 +1180,99 @@
 		*vpp = NULLVP;
 	}
 	/* 
-	 * entry is not in the cache or has been expired
+	 * entry is not in the cache, has been expired
+	 * or entry in the cache did not match input
+	 * filename's case
 	 */
 	error = 0;
 	*vpp = NULLVP;
 	smb_makescred(&scred, td, cnp->cn_cred);
 	fap = &fattr;
 	if (flags & ISDOTDOT) {
-		error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, 0, fap,
-		    &scred);
-		SMBVDEBUG("result of dotdot lookup: %d\n", error);
+		error = smbfs_smb_lookup(VTOSMB(dnp->n_parent), NULL, NULL, fap,
+			&scred);
+		SMBVDEBUG("result of dotdot smbfs_smb_lookup: %d\n", error);
 	} else {
-		fap = &fattr;
-		error = smbfs_smb_lookup(dnp, name, nmlen, fap, &scred);
+		/* smbfs_smb_lookup can allocate a new "name" so use "out" from
+		 * here on */
 /*		if (cnp->cn_namelen == 1 && cnp->cn_nameptr[0] == '.')*/
+		error = smbfs_smb_lookup(dnp, &name, &nmlen, fap, &scred);
 		SMBVDEBUG("result of smbfs_smb_lookup: %d\n", error);
 	}
 	if (error && error != ENOENT)
-		return error;
-	if (error) {			/* entry not found */
+		goto out;
+	if (error) {
+		/* entry not found */
+		SMBVDEBUG("entry not found on server\n");
+
 		/*
 		 * Handle RENAME or CREATE case...
 		 */
 		if ((nameiop == CREATE || nameiop == RENAME) && islastcn) {
 			error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
 			if (error)
-				return error;
+				goto out;
 			cnp->cn_flags |= SAVENAME;
-			return (EJUSTRETURN);
+			error = EJUSTRETURN;
+			goto out;
 		}
-		return ENOENT;
-	}/* else {
-		SMBVDEBUG("Found entry %s with id=%d\n", fap->entryName, fap->dirEntNum);
-	}*/
+		error = ENOENT;
+		goto out;
+	}
+
+        /* entry found */
+	SMBVDEBUG("entry found on server: '%s'\n", name);
+
 	/*
 	 * handle DELETE case ...
 	 */
 	if (nameiop == DELETE && islastcn) { 	/* delete last component */
 		error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
 		if (error)
-			return error;
+			goto out;
 		if (isdot) {
 			VREF(dvp);
 			*vpp = dvp;
-			return 0;
+			error = 0;
+			goto out;
 		}
 		error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
 		if (error)
-			return error;
+			goto out;
 		*vpp = vp;
 		cnp->cn_flags |= SAVENAME;
-		return 0;
+		error = 0;
+		goto out;
 	}
 	if (nameiop == RENAME && islastcn) {
+		if (name != cnp->cn_nameptr) {
+			/* Target has been found on the server. Just return here
+			* to avoir falling to the source vnode, which would lead
+			* to NOT call the rename syscall */
+			error = EJUSTRETURN;
+			goto out;
+		}
 		error = VOP_ACCESS(dvp, VWRITE, cnp->cn_cred, td);
 		if (error)
-			return error;
-		if (isdot)
-			return EISDIR;
+			goto out;
+		if (isdot) {
+			error = EISDIR;
+			goto out;
+		}
 		error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
 		if (error)
-			return error;
+			goto out;
 		*vpp = vp;
 		cnp->cn_flags |= SAVENAME;
-		return 0;
+		error = 0;
+		goto out;
 	}
 	if (flags & ISDOTDOT) {
 		VOP_UNLOCK(dvp, 0, td);
 		error = smbfs_nget(mp, dvp, name, nmlen, NULL, &vp);
 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
 		if (error)
-			return error;
+			goto out;
 		*vpp = vp;
 	} else if (isdot) {
 		vref(dvp);
@@ -1243,7 +1280,7 @@
 	} else {
 		error = smbfs_nget(mp, dvp, name, nmlen, fap, &vp);
 		if (error)
-			return error;
+			goto out;
 		*vpp = vp;
 		SMBVDEBUG("lookup: getnewvp!\n");
 	}
@@ -1251,5 +1288,10 @@
 /*		VTOSMB(*vpp)->n_ctime = VTOSMB(*vpp)->n_vattr.va_ctime.tv_sec;*/
 		cache_enter(dvp, *vpp, cnp);
 	}
-	return 0;
+	error = 0;
+
+out:
+	if (name != cnp->cn_nameptr)
+		smbfs_name_free((u_char *)name);
+	return error;
 }

>Release-Note:
>Audit-Trail:

From: "Ganael LAPLANCHE" <ganael.laplanche@martymac.com>
To: bug-followup@FreeBSD.org, ganael.laplanche@martymac.com
Cc:  
Subject: Re: kern/112658: [smbfs] [patch] smbfs and caching problems (resolves bin/111004)
Date: Mon, 21 May 2007 15:40:45 +0200 (CEST)

 Hi,
 
 I've just tested the patch on -CURRENT. Everything went OK :)
 
 Ganal LAPLANCHE
 ganael.laplanche@martymac.com
 http://www.martymac.com
 
Responsible-Changed-From-To: freebsd-bugs->freebsd-fs 
Responsible-Changed-By: rodrigc 
Responsible-Changed-When: Thu Jul 26 02:24:18 UTC 2007 
Responsible-Changed-Why:  


http://www.freebsd.org/cgi/query-pr.cgi?pr=112658 

From: "Ganael LAPLANCHE" <ganael.laplanche@martymac.org>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/112658: [smbfs] [patch] smbfs and caching problems (resolves bin/111004)
Date: Wed, 20 Feb 2013 07:16:27 +0000 (UTC)

 This is a multi-part message in MIME format.
 
 ------=OPENWEBMAIL_ATT_0.350054851341159
 Content-Type: text/plain; charset=iso-8859-15
 
 Here is an updated version of the patch.
 It applies to svn revision 246938.
 
 --
 Ganael LAPLANCHE <ganael.laplanche@martymac.org>
 http://www.martymac.org | http://contribs.martymac.org
 FreeBSD: martymac <martymac@FreeBSD.org>, http://www.FreeBSD.org
 
 ------=OPENWEBMAIL_ATT_0.350054851341159
 Content-Type: text/plain;
 	name="patch-smbfs-svnrev-246938.txt"
 Content-Disposition: attachment; filename="patch-smbfs-svnrev-246938.txt"
 Content-Transfer-Encoding: base64
 
 ZGlmZiAtYXVyTiBzeXMvZnMvc21iZnMub3JpZy9zbWJmc19ub2RlLmMgc3lzL2ZzL3NtYmZzL3Nt
 YmZzX25vZGUuYwotLS0gc3lzL2ZzL3NtYmZzLm9yaWcvc21iZnNfbm9kZS5jCTIwMTItMTItMTQg
 MDk6NTk6MTEuNjgyNzQxMDAwICswMTAwCisrKyBzeXMvZnMvc21iZnMvc21iZnNfbm9kZS5jCTIw
 MTMtMDItMjAgMDY6MDA6MzcuNjUyNzk2MzA1ICswMTAwCkBAIC02NCw3ICs2NCw3IEBACiAJcmV0
 dXJuIChmbnZfMzJfYnVmKG5hbWUsIG5tbGVuLCBGTlYxXzMyX0lOSVQpKTsgCiB9CiAKLXN0YXRp
 YyBjaGFyICoKK2NoYXIgKgogc21iZnNfbmFtZV9hbGxvYyhjb25zdCB1X2NoYXIgKm5hbWUsIGlu
 dCBubWxlbikKIHsKIAl1X2NoYXIgKmNwOwpAQCAtNzYsNyArNzYsNyBAQAogCXJldHVybiBjcDsK
 IH0KIAotc3RhdGljIHZvaWQKK3ZvaWQKIHNtYmZzX25hbWVfZnJlZSh1X2NoYXIgKm5hbWUpCiB7
 CiAKZGlmZiAtYXVyTiBzeXMvZnMvc21iZnMub3JpZy9zbWJmc19ub2RlLmggc3lzL2ZzL3NtYmZz
 L3NtYmZzX25vZGUuaAotLS0gc3lzL2ZzL3NtYmZzLm9yaWcvc21iZnNfbm9kZS5oCTIwMTItMTIt
 MTQgMDk6NTk6MTEuNjc2NzQwMDAwICswMTAwCisrKyBzeXMvZnMvc21iZnMvc21iZnNfbm9kZS5o
 CTIwMTMtMDItMjAgMDY6MDA6MzcuNjU4ODE5MjA3ICswMTAwCkBAIC05MSw2ICs5MSw5IEBACiAJ
 c3RydWN0IHNtYmZhdHRyICpmYXAsIHN0cnVjdCB2bm9kZSAqKnZwcCk7CiB1X2ludDMyX3Qgc21i
 ZnNfaGFzaChjb25zdCB1X2NoYXIgKm5hbWUsIGludCBubWxlbik7CiAKK2NoYXIgICpzbWJmc19u
 YW1lX2FsbG9jKGNvbnN0IHVfY2hhciAqbmFtZSwgaW50IG5tbGVuKTsKK3ZvaWQgICBzbWJmc19u
 YW1lX2ZyZWUodV9jaGFyICpuYW1lKTsKKwogaW50ICBzbWJmc19nZXRwYWdlcyhzdHJ1Y3Qgdm9w
 X2dldHBhZ2VzX2FyZ3MgKik7CiBpbnQgIHNtYmZzX3B1dHBhZ2VzKHN0cnVjdCB2b3BfcHV0cGFn
 ZXNfYXJncyAqKTsKIGludCAgc21iZnNfcmVhZHZub2RlKHN0cnVjdCB2bm9kZSAqdnAsIHN0cnVj
 dCB1aW8gKnVpb3AsIHN0cnVjdCB1Y3JlZCAqY3JlZCk7CmRpZmYgLWF1ck4gc3lzL2ZzL3NtYmZz
 Lm9yaWcvc21iZnNfc21iLmMgc3lzL2ZzL3NtYmZzL3NtYmZzX3NtYi5jCi0tLSBzeXMvZnMvc21i
 ZnMub3JpZy9zbWJmc19zbWIuYwkyMDEyLTEyLTE0IDA5OjU5OjExLjY4MDc0MDAwMCArMDEwMAor
 Kysgc3lzL2ZzL3NtYmZzL3NtYmZzX3NtYi5jCTIwMTMtMDItMjAgMDY6MDA6MzcuNjY3ODE0ODMz
 ICswMTAwCkBAIC0xNDQzLDM3ICsxNDQzLDUwIEBACiB9CiAKIGludAotc21iZnNfc21iX2xvb2t1
 cChzdHJ1Y3Qgc21ibm9kZSAqZG5wLCBjb25zdCBjaGFyICpuYW1lLCBpbnQgbm1sZW4sCitzbWJm
 c19zbWJfbG9va3VwKHN0cnVjdCBzbWJub2RlICpkbnAsIGNoYXIgKipuYW1lcCwgaW50ICpubWxl
 bnAsCiAJc3RydWN0IHNtYmZhdHRyICpmYXAsIHN0cnVjdCBzbWJfY3JlZCAqc2NyZWQpCiB7CiAJ
 c3RydWN0IHNtYmZzX2ZjdHggKmN0eDsKIAlpbnQgZXJyb3I7CiAKLQlpZiAoZG5wID09IE5VTEwg
 fHwgKGRucC0+bl9pbm8gPT0gMiAmJiBuYW1lID09IE5VTEwpKSB7CisJaWYgKGRucCA9PSBOVUxM
 IHx8CisJCShkbnAtPm5faW5vID09IDIgJiYgKG5hbWVwID09IE5VTEwgfHwgKm5hbWVwID09IE5V
 TEwpKSkgewogCQliemVybyhmYXAsIHNpemVvZigqZmFwKSk7CiAJCWZhcC0+ZmFfYXR0ciA9IFNN
 Ql9GQV9ESVI7CiAJCWZhcC0+ZmFfaW5vID0gMjsKIAkJcmV0dXJuIDA7CiAJfQotCWlmIChubWxl
 biA9PSAxICYmIG5hbWVbMF0gPT0gJy4nKSB7Ci0JCWVycm9yID0gc21iZnNfc21iX2xvb2t1cChk
 bnAsIE5VTEwsIDAsIGZhcCwgc2NyZWQpOworCWlmIChubWxlbnAgJiYgKm5tbGVucCA9PSAxICYm
 IG5hbWVwICYmICgqbmFtZXApWzBdID09ICcuJykgeworCQllcnJvciA9IHNtYmZzX3NtYl9sb29r
 dXAoZG5wLCBOVUxMLCBOVUxMLCBmYXAsIHNjcmVkKTsKIAkJcmV0dXJuIGVycm9yOwotCX0gZWxz
 ZSBpZiAobm1sZW4gPT0gMiAmJiBuYW1lWzBdID09ICcuJyAmJiBuYW1lWzFdID09ICcuJykgewot
 CQllcnJvciA9IHNtYmZzX3NtYl9sb29rdXAoVlRPU01CKGRucC0+bl9wYXJlbnQpLCBOVUxMLCAw
 LCBmYXAsCi0JCSAgICBzY3JlZCk7CisJfSBlbHNlIGlmIChubWxlbnAgJiYgKm5tbGVucCA9PSAy
 ICYmIG5hbWVwICYmICgqbmFtZXApWzBdID09ICcuJyAmJgorCQkoKm5hbWVwKVsxXSA9PSAnLicp
 IHsKKwkJZXJyb3IgPSBzbWJmc19zbWJfbG9va3VwKFZUT1NNQihkbnAtPm5fcGFyZW50KSwgTlVM
 TCwgTlVMTCwKKwkJCWZhcCwgc2NyZWQpOwogCQlwcmludGYoIiVzOiBrbm93cyBOT1RISU5HIGFi
 b3V0ICcuLidcbiIsIF9fZnVuY19fKTsKIAkJcmV0dXJuIGVycm9yOwogCX0KLQllcnJvciA9IHNt
 YmZzX2ZpbmRvcGVuKGRucCwgbmFtZSwgbm1sZW4sCi0JICAgIFNNQl9GQV9TWVNURU0gfCBTTUJf
 RkFfSElEREVOIHwgU01CX0ZBX0RJUiwgc2NyZWQsICZjdHgpOworCWVycm9yID0gc21iZnNfZmlu
 ZG9wZW4oZG5wLCBuYW1lcCA/ICpuYW1lcCA6IE5VTEwsIG5tbGVucCA/ICpubWxlbnAgOiAwLAor
 CQlTTUJfRkFfU1lTVEVNIHwgU01CX0ZBX0hJRERFTiB8IFNNQl9GQV9ESVIsIHNjcmVkLCAmY3R4
 KTsKIAlpZiAoZXJyb3IpCiAJCXJldHVybiBlcnJvcjsKIAljdHgtPmZfZmxhZ3MgfD0gU01CRlNf
 UkREX0ZJTkRTSU5HTEU7CiAJZXJyb3IgPSBzbWJmc19maW5kbmV4dChjdHgsIDEsIHNjcmVkKTsK
 IAlpZiAoZXJyb3IgPT0gMCkgewogCQkqZmFwID0gY3R4LT5mX2F0dHI7Ci0JCWlmIChuYW1lID09
 IE5VTEwpCisJCWlmIChuYW1lcCA9PSBOVUxMIHx8ICpuYW1lcCA9PSBOVUxMKQogCQkJZmFwLT5m
 YV9pbm8gPSBkbnAtPm5faW5vOworCQlpZiAobmFtZXAgJiYgKm5hbWVwICYmIG5tbGVucCAmJiAq
 bm1sZW5wKSB7CisJCQkvKiBSZXR1cm4gdGhlICpyZWFsKiBuYW1lIGFuZCBsZW5ndGggb2YgdGhl
 IGZpbGUgCisJCQkgKiBmb3VuZCBvbiB0aGUgc2VydmVyIGlmIG5lY2Vzc2FyeS4gSWYgYSBuZXcg
 YWxsb2NhdGlvbgorCQkJICogaXMgZG9uZSBoZXJlLCBtZW1vcnkgd2lsbCBiZSBmcmVlZCBsYXRl
 ciAqLworCQkJaWYoKGN0eC0+Zl9ubWxlbiAhPSAqbm1sZW5wKSB8fAorCQkJCShiY21wKGN0eC0+
 Zl9uYW1lLCAqbmFtZXAsICpubWxlbnApICE9IDApKSB7CisJCQkJU01CVkRFQlVHKCJsb29rdXBl
 ZCBmaWxlbmFtZSBhbmQgc2VydmVyJ3MgZmlsZW5hbWUgZGlmZmVyXG4iKTsKKwkJCQkqbmFtZXAg
 PSBzbWJmc19uYW1lX2FsbG9jKCh1X2NoYXIgKikoY3R4LT5mX25hbWUpLCBjdHgtPmZfbm1sZW4p
 OworCQkJCSpubWxlbnAgPSBjdHgtPmZfbm1sZW47CisJCQl9CisJCX0KIAl9CiAJc21iZnNfZmlu
 ZGNsb3NlKGN0eCwgc2NyZWQpOwogCXJldHVybiBlcnJvcjsKZGlmZiAtYXVyTiBzeXMvZnMvc21i
 ZnMub3JpZy9zbWJmc19zdWJyLmggc3lzL2ZzL3NtYmZzL3NtYmZzX3N1YnIuaAotLS0gc3lzL2Zz
 L3NtYmZzLm9yaWcvc21iZnNfc3Vici5oCTIwMTItMTItMTQgMDk6NTk6MTEuNjc4NzQyMDAwICsw
 MTAwCisrKyBzeXMvZnMvc21iZnMvc21iZnNfc3Vici5oCTIwMTMtMDItMjAgMDY6MDA6MzcuNjcz
 Nzk5MDQ0ICswMTAwCkBAIC0xNjYsNyArMTY2LDcgQEAKIGludCAgc21iZnNfZmluZGNsb3NlKHN0
 cnVjdCBzbWJmc19mY3R4ICpjdHgsIHN0cnVjdCBzbWJfY3JlZCAqc2NyZWQpOwogaW50ICBzbWJm
 c19mdWxscGF0aChzdHJ1Y3QgbWJjaGFpbiAqbWJwLCBzdHJ1Y3Qgc21iX3ZjICp2Y3AsCiAJc3Ry
 dWN0IHNtYm5vZGUgKmRucCwgY29uc3QgY2hhciAqbmFtZSwgaW50IG5tbGVuKTsKLWludCAgc21i
 ZnNfc21iX2xvb2t1cChzdHJ1Y3Qgc21ibm9kZSAqZG5wLCBjb25zdCBjaGFyICpuYW1lLCBpbnQg
 bm1sZW4sCitpbnQgIHNtYmZzX3NtYl9sb29rdXAoc3RydWN0IHNtYm5vZGUgKmRucCwgY2hhciAq
 Km5hbWVwLCBpbnQgKm5tbGVucCwKIAlzdHJ1Y3Qgc21iZmF0dHIgKmZhcCwgc3RydWN0IHNtYl9j
 cmVkICpzY3JlZCk7CiAKIGludCAgc21iZnNfZm5hbWVfdG9sb2NhbChzdHJ1Y3Qgc21iX3ZjICp2
 Y3AsIGNoYXIgKm5hbWUsIGludCAqbm1sZW4sIGludCBjYXNlb3B0KTsKZGlmZiAtYXVyTiBzeXMv
 ZnMvc21iZnMub3JpZy9zbWJmc192ZnNvcHMuYyBzeXMvZnMvc21iZnMvc21iZnNfdmZzb3BzLmMK
 LS0tIHN5cy9mcy9zbWJmcy5vcmlnL3NtYmZzX3Zmc29wcy5jCTIwMTItMTItMTQgMDk6NTk6MTEu
 Njc5NzQxMDAwICswMTAwCisrKyBzeXMvZnMvc21iZnMvc21iZnNfdmZzb3BzLmMJMjAxMy0wMi0y
 MCAwNjowMDozNy42Nzk4MjE5NDYgKzAxMDAKQEAgLTMxNiw3ICszMTYsNyBAQAogCX0KIAlzY3Jl
 ZCA9IHNtYmZzX21hbGxvY19zY3JlZCgpOwogCXNtYl9tYWtlc2NyZWQoc2NyZWQsIHRkLCBjcmVk
 KTsKLQllcnJvciA9IHNtYmZzX3NtYl9sb29rdXAoTlVMTCwgTlVMTCwgMCwgJmZhdHRyLCBzY3Jl
 ZCk7CisJZXJyb3IgPSBzbWJmc19zbWJfbG9va3VwKE5VTEwsIE5VTEwsIE5VTEwsICZmYXR0ciwg
 c2NyZWQpOwogCWlmIChlcnJvcikKIAkJZ290byBvdXQ7CiAJZXJyb3IgPSBzbWJmc19uZ2V0KG1w
 LCBOVUxMLCBOVUxMLCAwLCAmZmF0dHIsICZ2cCk7CmRpZmYgLWF1ck4gc3lzL2ZzL3NtYmZzLm9y
 aWcvc21iZnNfdm5vcHMuYyBzeXMvZnMvc21iZnMvc21iZnNfdm5vcHMuYwotLS0gc3lzL2ZzL3Nt
 YmZzLm9yaWcvc21iZnNfdm5vcHMuYwkyMDEyLTEyLTE0IDA5OjU5OjExLjY4Mzc0MDAwMCArMDEw
 MAorKysgc3lzL2ZzL3NtYmZzL3NtYmZzX3Zub3BzLmMJMjAxMy0wMi0yMCAwNjowOTo1Mi44MTM4
 OTE3MDkgKzAxMDAKQEAgLTI3MCw3ICsyNzAsNyBAQAogCXNjcmVkID0gc21iZnNfbWFsbG9jX3Nj
 cmVkKCk7CiAJc21iX21ha2VzY3JlZChzY3JlZCwgY3VydGhyZWFkLCBhcC0+YV9jcmVkKTsKIAlv
 bGRzaXplID0gbnAtPm5fc2l6ZTsKLQllcnJvciA9IHNtYmZzX3NtYl9sb29rdXAobnAsIE5VTEws
 IDAsICZmYXR0ciwgc2NyZWQpOworCWVycm9yID0gc21iZnNfc21iX2xvb2t1cChucCwgTlVMTCwg
 TlVMTCwgJmZhdHRyLCBzY3JlZCk7CiAJaWYgKGVycm9yKSB7CiAJCVNNQlZERUJVRygiZXJyb3Ig
 JWRcbiIsIGVycm9yKTsKIAkJc21iZnNfZnJlZV9zY3JlZChzY3JlZCk7CkBAIC01MTQsNyArNTE0
 LDcgQEAKIAllcnJvciA9IHNtYmZzX3NtYl9jcmVhdGUoZG5wLCBuYW1lLCBubWxlbiwgc2NyZWQp
 OwogCWlmIChlcnJvcikKIAkJZ290byBvdXQ7Ci0JZXJyb3IgPSBzbWJmc19zbWJfbG9va3VwKGRu
 cCwgbmFtZSwgbm1sZW4sICZmYXR0ciwgc2NyZWQpOworCWVycm9yID0gc21iZnNfc21iX2xvb2t1
 cChkbnAsICZuYW1lLCAmbm1sZW4sICZmYXR0ciwgc2NyZWQpOwogCWlmIChlcnJvcikKIAkJZ290
 byBvdXQ7CiAJZXJyb3IgPSBzbWJmc19uZ2V0KFZUT1ZGUyhkdnApLCBkdnAsIG5hbWUsIG5tbGVu
 LCAmZmF0dHIsICZ2cCk7CkBAIC01MjQsNiArNTI0LDggQEAKIAlpZiAoY25wLT5jbl9mbGFncyAm
 IE1BS0VFTlRSWSkKIAkJY2FjaGVfZW50ZXIoZHZwLCB2cCwgY25wKTsKIG91dDoKKwlpZiAobmFt
 ZSAhPSBjbnAtPmNuX25hbWVwdHIpCisJCXNtYmZzX25hbWVfZnJlZSgodV9jaGFyICopbmFtZSk7
 CiAJc21iZnNfZnJlZV9zY3JlZChzY3JlZCk7CiAJcmV0dXJuIGVycm9yOwogfQpAQCAtNzIxLDE2
 ICs3MjMsMTkgQEAKIAllcnJvciA9IHNtYmZzX3NtYl9ta2RpcihkbnAsIG5hbWUsIGxlbiwgc2Ny
 ZWQpOwogCWlmIChlcnJvcikKIAkJZ290byBvdXQ7Ci0JZXJyb3IgPSBzbWJmc19zbWJfbG9va3Vw
 KGRucCwgbmFtZSwgbGVuLCAmZmF0dHIsIHNjcmVkKTsKKwllcnJvciA9IHNtYmZzX3NtYl9sb29r
 dXAoZG5wLCAmbmFtZSwgJmxlbiwgJmZhdHRyLCBzY3JlZCk7CiAJaWYgKGVycm9yKQogCQlnb3Rv
 IG91dDsKIAllcnJvciA9IHNtYmZzX25nZXQoVlRPVkZTKGR2cCksIGR2cCwgbmFtZSwgbGVuLCAm
 ZmF0dHIsICZ2cCk7CiAJaWYgKGVycm9yKQogCQlnb3RvIG91dDsKIAkqYXAtPmFfdnBwID0gdnA7
 CisJZXJyb3IgPSAwOwogb3V0OgorCWlmIChuYW1lICE9IGNucC0+Y25fbmFtZXB0cikKKwkJc21i
 ZnNfbmFtZV9mcmVlKCh1X2NoYXIgKiluYW1lKTsKIAlzbWJmc19mcmVlX3NjcmVkKHNjcmVkKTsK
 LQlyZXR1cm4gMDsKKwlyZXR1cm4gZXJyb3I7CiB9CiAKIC8qCkBAIC0xMTUwLDcgKzExNTUsNyBA
 QAogCQlyZXR1cm4gRU5PRU5UOwogCiAJZXJyb3IgPSBjYWNoZV9sb29rdXAoZHZwLCB2cHAsIGNu
 cCwgTlVMTCwgTlVMTCk7Ci0JU01CVkRFQlVHKCJjYWNoZV9sb29rdXAgcmV0dXJuZWQgJWRcbiIs
 IGVycm9yKTsKKwlTTUJWREVCVUcoImNhY2hlX2xvb2t1cCBmb3IgJyVzJyByZXR1cm5lZCAlZFxu
 IiwgY25wLT5jbl9uYW1lcHRyLCBlcnJvcik7CiAJaWYgKGVycm9yID4gMCkKIAkJcmV0dXJuIGVy
 cm9yOwogCWlmIChlcnJvcikgewkJLyogbmFtZSB3YXMgZm91bmQgKi8KQEAgLTExOTUsNyArMTIw
 MCw4IEBACiAJCSp2cHAgPSBOVUxMVlA7CiAJfQogCS8qIAotCSAqIGVudHJ5IGlzIG5vdCBpbiB0
 aGUgY2FjaGUgb3IgaGFzIGJlZW4gZXhwaXJlZAorCSAqIGVudHJ5IGlzIG5vdCBpbiB0aGUgY2Fj
 aGUsIGhhcyBiZWVuIGV4cGlyZWQKKwkgKiBvciBlbnRyeSBpbiB0aGUgY2FjaGUgZGlkIG5vdCBt
 YXRjaCBpbnB1dCBmaWxlbmFtZSdzIGNhc2UKIAkgKi8KIAllcnJvciA9IDA7CiAJKnZwcCA9IE5V
 TExWUDsKQEAgLTEyMDMsMTggKzEyMDksMTkgQEAKIAlzbWJfbWFrZXNjcmVkKHNjcmVkLCB0ZCwg
 Y25wLT5jbl9jcmVkKTsKIAlmYXAgPSAmZmF0dHI7CiAJaWYgKGZsYWdzICYgSVNET1RET1QpIHsK
 LQkJZXJyb3IgPSBzbWJmc19zbWJfbG9va3VwKFZUT1NNQihkbnAtPm5fcGFyZW50KSwgTlVMTCwg
 MCwgZmFwLAorCQllcnJvciA9IHNtYmZzX3NtYl9sb29rdXAoVlRPU01CKGRucC0+bl9wYXJlbnQp
 LCBOVUxMLCBOVUxMLCBmYXAsCiAJCSAgICBzY3JlZCk7Ci0JCVNNQlZERUJVRygicmVzdWx0IG9m
 IGRvdGRvdCBsb29rdXA6ICVkXG4iLCBlcnJvcik7CisJCVNNQlZERUJVRygicmVzdWx0IG9mIGRv
 dGRvdCBzbWJmc19zbWJfbG9va3VwOiAlZFxuIiwgZXJyb3IpOwogCX0gZWxzZSB7Ci0JCWZhcCA9
 ICZmYXR0cjsKLQkJZXJyb3IgPSBzbWJmc19zbWJfbG9va3VwKGRucCwgbmFtZSwgbm1sZW4sIGZh
 cCwgc2NyZWQpOworCQllcnJvciA9IHNtYmZzX3NtYl9sb29rdXAoZG5wLCAmbmFtZSwgJm5tbGVu
 LCBmYXAsIHNjcmVkKTsKIC8qCQlpZiAoY25wLT5jbl9uYW1lbGVuID09IDEgJiYgY25wLT5jbl9u
 YW1lcHRyWzBdID09ICcuJykqLwogCQlTTUJWREVCVUcoInJlc3VsdCBvZiBzbWJmc19zbWJfbG9v
 a3VwOiAlZFxuIiwgZXJyb3IpOwogCX0KIAlpZiAoZXJyb3IgJiYgZXJyb3IgIT0gRU5PRU5UKQog
 CQlnb3RvIG91dDsKIAlpZiAoZXJyb3IpIHsJCQkvKiBlbnRyeSBub3QgZm91bmQgKi8KKwkJU01C
 VkRFQlVHKCJlbnRyeSBub3QgZm91bmQgb24gc2VydmVyXG4iKTsKKwogCQkvKgogCQkgKiBIYW5k
 bGUgUkVOQU1FIG9yIENSRUFURSBjYXNlLi4uCiAJCSAqLwpAQCAtMTIyOCw5ICsxMjM1LDExIEBA
 CiAJCX0KIAkJZXJyb3IgPSBFTk9FTlQ7CiAJCWdvdG8gb3V0OwotCX0vKiBlbHNlIHsKLQkJU01C
 VkRFQlVHKCJGb3VuZCBlbnRyeSAlcyB3aXRoIGlkPSVkXG4iLCBmYXAtPmVudHJ5TmFtZSwgZmFw
 LT5kaXJFbnROdW0pOwotCX0qLworCX0KKworCS8qIGVudHJ5IGZvdW5kICovCisJU01CVkRFQlVH
 KCJlbnRyeSBmb3VuZCBvbiBzZXJ2ZXI6ICclcydcbiIsIG5hbWUpOworCiAJLyoKIAkgKiBoYW5k
 bGUgREVMRVRFIGNhc2UgLi4uCiAJICovCkBAIC0xMjUxLDYgKzEyNjAsMTMgQEAKIAkJZ290byBv
 dXQ7CiAJfQogCWlmIChuYW1laW9wID09IFJFTkFNRSAmJiBpc2xhc3RjbikgeworCQlpZiAobmFt
 ZSAhPSBjbnAtPmNuX25hbWVwdHIpIHsKKwkJCS8qIFRhcmdldCBoYXMgYmVlbiBmb3VuZCBvbiB0
 aGUgc2VydmVyLiBKdXN0IHJldHVybiBoZXJlCisJCQkqIHRvIGF2b2lyIGZhbGxpbmcgdG8gdGhl
 IHNvdXJjZSB2bm9kZSwgd2hpY2ggd291bGQgbGVhZAorCQkJKiB0byBOT1QgY2FsbCB0aGUgcmVu
 YW1lIHN5c2NhbGwgKi8KKwkJCWVycm9yID0gRUpVU1RSRVRVUk47CisJCQlnb3RvIG91dDsKKwkJ
 fQogCQllcnJvciA9IFZPUF9BQ0NFU1MoZHZwLCBWV1JJVEUsIGNucC0+Y25fY3JlZCwgdGQpOwog
 CQlpZiAoZXJyb3IpCiAJCQlnb3RvIG91dDsKQEAgLTEyNzQsMTEgKzEyOTAsMTQgQEAKIAkJCWVy
 cm9yID0gdmZzX2J1c3kobXAsIDApOwogCQkJdm5fbG9jayhkdnAsIExLX0VYQ0xVU0lWRSB8IExL
 X1JFVFJZKTsKIAkJCXZmc19yZWwobXApOwotCQkJaWYgKGVycm9yKQotCQkJCXJldHVybiAoRU5P
 RU5UKTsKKwkJCWlmIChlcnJvcikgeworCQkJCWVycm9yID0gRU5PRU5UOworCQkJCWdvdG8gb3V0
 OworCQkJfQogCQkJaWYgKChkdnAtPnZfaWZsYWcgJiBWSV9ET09NRUQpICE9IDApIHsKIAkJCQl2
 ZnNfdW5idXN5KG1wKTsKLQkJCQlyZXR1cm4gKEVOT0VOVCk7CQorCQkJCWVycm9yID0gRU5PRU5U
 OworCQkJCWdvdG8gb3V0OwogCQkJfQogCQl9CQogCQlWT1BfVU5MT0NLKGR2cCwgMCk7CkBAIC0x
 MzA4LDYgKzEzMjcsOCBAQAogCQljYWNoZV9lbnRlcihkdnAsICp2cHAsIGNucCk7CiAJfQogb3V0
 OgorCWlmIChuYW1lICE9IGNucC0+Y25fbmFtZXB0cikKKwkJc21iZnNfbmFtZV9mcmVlKCh1X2No
 YXIgKiluYW1lKTsKIAlzbWJmc19mcmVlX3NjcmVkKHNjcmVkKTsKIAlyZXR1cm4gKGVycm9yKTsK
 IH0K
 
 ------=OPENWEBMAIL_ATT_0.350054851341159--
>Unformatted:
