From 032cac36ede68e0c5676abb885f77a51ca2880dc Mon Sep 17 00:00:00 2001
From: robk-tahoe <robk-tahoe@allmydata.com>
Date: Thu, 16 Oct 2008 17:44:21 -0700
Subject: [PATCH] fuse/blackmatch: add readability to some logging, fix a
 permissions problem

adds a couple of functions to unpack 'mode' and 'flags' for open() calls, to
facilitate debugging.

adds a fix to ensure that all tmp files created for writing are opened with
permissions 0600 - one problem I had with testing with the Finder was that
files were being opened write only (0200) and were then failing to upload
to tahoe due to internal permission denied errors.

there remain a variety of problems with finder access which I'm unable to
comprehend at this time.  sometimes copies to tahoe will work fine, sometimes
they yield "the finder cannot complete the operation because some data ...
could not be read or written. (Error code -36)" sometimes "You may need to
enter the name and password for an administrator on this computer to change
the item" sometimes "The operation cannot be completed because an item with
the name ... already exists." and sometimes "The operation cannot be completed
because the item ... is locked."  What seems to be absent is rhyme or reason.

unix operations (cp, mv) work fine, rsync works fine.
---
 contrib/fuse/impl_c/blackmatch.py | 31 ++++++++++++++++++++++++++++++-
 1 file changed, 30 insertions(+), 1 deletion(-)

diff --git a/contrib/fuse/impl_c/blackmatch.py b/contrib/fuse/impl_c/blackmatch.py
index cce9a779..3d10d921 100644
--- a/contrib/fuse/impl_c/blackmatch.py
+++ b/contrib/fuse/impl_c/blackmatch.py
@@ -177,11 +177,35 @@ def logexc(meth):
 def log_exc():
     log('exception:\n%s' % (traceback.format_exc(),))
 
+def repr_mode(mode=None):
+    if mode is None:
+        return 'none'
+    fields = ['S_ENFMT', 'S_IFBLK', 'S_IFCHR', 'S_IFDIR', 'S_IFIFO', 'S_IFLNK', 'S_IFREG', 'S_IFSOCK', 'S_IRGRP', 'S_IROTH', 'S_IRUSR', 'S_IRWXG', 'S_IRWXO', 'S_IRWXU', 'S_ISGID', 'S_ISUID', 'S_ISVTX', 'S_IWGRP', 'S_IWOTH', 'S_IWUSR', 'S_IXGRP', 'S_IXOTH', 'S_IXUSR']
+    ret = []
+    for field in fields:
+        fval = getattr(stat, field)
+        if (mode & fval) == fval:
+            ret.append(field)
+    return '|'.join(ret)
+
+def repr_flags(flags=None):
+    if flags is None:
+        return 'none'
+    fields = ['O_WRONLY', 'O_RDWR', 'O_NONBLOCK', 'O_APPEND', 'O_CREAT', 'O_TRUNC', 'O_EXCL', 'O_SHLOCK', 'O_EXLOCK', 'O_NOFOLLOW']
+    ret = []
+    for field in fields:
+        fval = getattr(os, field)
+        if (flags & fval) == fval:
+            ret.append(field)
+    if not ret:
+        ret = ['O_RDONLY']
+    return '|'.join(ret)
+
 class TahoeFuseFile(object):
 
     #def __init__(self, path, flags, *mode):
     def __init__(self, tfs, path, flags, *mode):
-        log("TFF: __init__(%r, %r, %r)" % (path, flags, mode))
+        log("TFF: __init__(%r, %r:%s, %r:%s)" % (path, flags, repr_flags(flags), mode, repr_mode(*mode)))
         self.tfs = tfs
 
         self._path = path # for tahoe put
@@ -202,6 +226,11 @@ class TahoeFuseFile(object):
                     log('TFF: [%s] open() for write: existing file node lists %s' % (self.name, self.fname, ))
                 else:
                     log('TFF: [%s] open() for write: existing file node lists no tmp_file, using new %s' % (self.name, self.fname, ))
+                if mode != (0600,):
+                    log('TFF: [%s] changing mode %s(%s) to 0600' % (self.name, repr_mode(*mode), mode))
+                    mode = (0600,)
+                log('TFF: [%s] opening(%s) with flags %s(%s), mode %s(%s)' % (self.name, self.fname, repr_flags(flags|os.O_CREAT), flags|os.O_CREAT, repr_mode(*mode), mode))
+                #self.file = os.fdopen(os.open(self.fname, flags|os.O_CREAT, *mode), m)
                 self.file = os.fdopen(os.open(self.fname, flags|os.O_CREAT, *mode), m)
                 self.fd = self.file.fileno()
                 log('TFF: opened(%s) for write' % self.fname)
-- 
2.45.2