| @@ -17,7 +17,7 @@ · 16 unmodified lines |
| 17 | # You should have received a copy of the GNU General Public License | 17 | # You should have received a copy of the GNU General Public License |
| 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | 18 | # along with this program. If not, see <http://www.gnu.org/licenses/>. |
| 19 | | 19 | |
| 20 | import os, stat, sys | 20 | import locale, os, stat, sys |
| 21 | import styx, styxserver | 21 | import styx, styxserver |
| 22 | | 22 | |
| 23 | class FileStore: | 23 | class FileStore: |
| @@ -34,11 +34,12 @@ class FileStore: · 10 unmodified lines |
| 34 | self.paths = {} | 34 | self.paths = {} |
| 35 | self.opened = {} | 35 | self.opened = {} |
| 36 | self.root_fid = None | 36 | self.root_fid = None |
| | 37 | self.encoding = sys.getfilesystemencoding() |
| 37 | | 38 | |
| 38 | def get_root_qid(self, fid, afid, uname, aname): | 39 | def get_root_qid(self, fid, afid, uname, aname): |
| 39 | | 40 | |
| 40 | qid = self.make_qid("") | 41 | qid = self.make_qid(u"/") |
| 41 | self.set_qid_path(fid, qid, "") | 42 | self.set_qid_path(fid, qid, u"/") |
| 42 | self.root_fid = fid | 43 | self.root_fid = fid |
| 43 | return qid | 44 | return qid |
| 44 | | 45 | |
| @@ -48,16 +49,16 @@ class FileStore: · 3 unmodified lines |
| 48 | | 49 | |
| 49 | def set_qid_path(self, fid, qid, path): | 50 | def set_qid_path(self, fid, qid, path): |
| 50 | | 51 | |
| 51 | path = path.lstrip("/") | 52 | path = path.lstrip(u"/") |
| 52 | | 53 | |
| 53 | self.qids[fid] = qid | 54 | self.qids[fid] = qid |
| 54 | self.paths[fid] = path | 55 | self.paths[fid] = path |
| 55 | | 56 | |
| 56 | def make_qid(self, path): | 57 | def make_qid(self, path): |
| 57 | | 58 | |
| 58 | path = path.lstrip("/") | 59 | path = path.lstrip(u"/") |
| 59 | | 60 | |
| 60 | real_path = os.path.join(self.dir, path) | 61 | real_path = os.path.join(self.dir, path).encode(self.encoding) |
| 61 | | 62 | |
| 62 | try: | 63 | try: |
| 63 | s = os.stat(real_path) | 64 | s = os.stat(real_path) |
| @@ -93,10 +94,10 @@ class FileStore: · 29 unmodified lines |
| 93 | | 94 | |
| 94 | def _stat(self, qid, path): | 95 | def _stat(self, qid, path): |
| 95 | | 96 | |
| 96 | path = path.lstrip("/") | 97 | path = path.lstrip(u"/") |
| 97 | | 98 | |
| 98 | name = os.path.split(path)[1] | 99 | name = os.path.split(path)[1] |
| 99 | real_path = os.path.join(self.dir, path) | 100 | real_path = os.path.join(self.dir, path).encode(self.encoding) |
| 100 | | 101 | |
| 101 | try: | 102 | try: |
| 102 | s = os.stat(real_path) | 103 | s = os.stat(real_path) |
| @@ -110,14 +111,14 @@ class FileStore: · 7 unmodified lines |
| 110 | mode = 0 | 111 | mode = 0 |
| 111 | size = s.st_size | 112 | size = s.st_size |
| 112 | | 113 | |
| 113 | mode |= (s.st_mode & 0777) | 114 | mode |= (s.st_mode & 0o777) |
| 114 | | 115 | |
| 115 | return styx.Stat(0, 0, qid, mode, s.st_atime, s.st_mtime, size, | 116 | return styx.Stat(0, 0, qid, mode, s.st_atime, s.st_mtime, size, |
| 116 | name, "styxfs", "styxfs", "") | 117 | name, u"styxfs", u"styxfs", u"") |
| 117 | | 118 | |
| 118 | def create(self, fid, name, perm): | 119 | def create(self, fid, name, perm): |
| 119 | | 120 | |
| 120 | if name in (".", ".."): | 121 | if name in (u".", u".."): |
| 121 | return False | 122 | return False |
| 122 | | 123 | |
| 123 | elif fid in self.opened: | 124 | elif fid in self.opened: |
| @@ -125,7 +126,7 @@ class FileStore: · 1 unmodified line |
| 125 | else: | 126 | else: |
| 126 | # Obtain the real path of the directory. | 127 | # Obtain the real path of the directory. |
| 127 | path = self.paths[fid] | 128 | path = self.paths[fid] |
| 128 | real_path = os.path.join(self.dir, path) | 129 | real_path = os.path.join(self.dir, path).encode(self.encoding) |
| 129 | | 130 | |
| 130 | if not os.path.isdir(real_path): | 131 | if not os.path.isdir(real_path): |
| 131 | return False | 132 | return False |
| @@ -133,7 +134,7 @@ class FileStore: · 1 unmodified line |
| 133 | # Read the directory permissions. | 134 | # Read the directory permissions. |
| 134 | dir_perm = os.stat(real_path).st_mode | 135 | dir_perm = os.stat(real_path).st_mode |
| 135 | | 136 | |
| 136 | new_real_path = os.path.join(real_path, name) | 137 | new_real_path = os.path.join(self.dir, path, name).encode(self.encoding) |
| 137 | | 138 | |
| 138 | if os.path.exists(new_real_path): | 139 | if os.path.exists(new_real_path): |
| 139 | return False | 140 | return False |
| @@ -143,18 +144,18 @@ class FileStore: · 3 unmodified lines |
| 143 | if perm & styx.Stat.DMDIR: | 144 | if perm & styx.Stat.DMDIR: |
| 144 | # Only pass the lowest permission bits through to the | 145 | # Only pass the lowest permission bits through to the |
| 145 | # underlying filing system. | 146 | # underlying filing system. |
| 146 | mode = dir_perm & 0777 | 147 | mode = dir_perm & 0o777 |
| 147 | os.mkdir(new_real_path, mode) | 148 | os.mkdir(new_real_path, mode) |
| 148 | else: | 149 | else: |
| 149 | mode = dir_perm & 0666 | 150 | mode = dir_perm & 0o666 |
| 150 | os.mknod(new_real_path, mode, stat.S_IFREG) | 151 | os.mknod(new_real_path, mode, stat.S_IFREG) |
| 151 | | 152 | |
| 152 | except OSError: | 153 | except OSError: |
| 153 | return False | 154 | return False |
| 154 | | 155 | |
| 155 | # Update the fid to refer to the new object. | 156 | # Update the fid to refer to the new object. |
| 156 | qid = self.make_qid(path + "/" + name) | 157 | qid = self.make_qid(path + u"/" + name) |
| 157 | self.set_qid_path(fid, qid, path + "/" + name) | 158 | self.set_qid_path(fid, qid, path + u"/" + name) |
| 158 | | 159 | |
| 159 | return qid | 160 | return qid |
| 160 | | 161 | |
| @@ -177,7 +178,7 @@ class FileStore: · 16 unmodified lines |
| 177 | | 178 | |
| 178 | path = self.paths[fid] | 179 | path = self.paths[fid] |
| 179 | real_path = os.path.join(self.dir, path) | 180 | real_path = os.path.join(self.dir, path) |
| 180 | data = "" | 181 | data = b"" |
| 181 | | 182 | |
| 182 | if os.path.isdir(real_path): | 183 | if os.path.isdir(real_path): |
| 183 | | 184 | |
| @@ -187,8 +188,8 @@ class FileStore: · 3 unmodified lines |
| 187 | files.sort() | 188 | files.sort() |
| 188 | | 189 | |
| 189 | for file_name in files: | 190 | for file_name in files: |
| 190 | qid = self.make_qid(path + "/" + file_name) | 191 | qid = self.make_qid(path + u"/" + file_name) |
| 191 | data += self._stat(qid, path + "/" + file_name).encode() | 192 | data += self._stat(qid, path + u"/" + file_name).encode() |
| 192 | | 193 | |
| 193 | return data[offset:offset + count] | 194 | return data[offset:offset + count] |
| 194 | else: | 195 | else: |
| @@ -207,7 +208,7 @@ class FileStore: · 12 unmodified lines |
| 207 | if os.path.isdir(real_path): | 208 | if os.path.isdir(real_path): |
| 208 | return -1 | 209 | return -1 |
| 209 | | 210 | |
| 210 | f = open(real_path, "r+wb") | 211 | f = open(real_path, "r+b") |
| 211 | f.seek(offset) | 212 | f.seek(offset) |
| 212 | f.write(data) | 213 | f.write(data) |
| 213 | f.close() | 214 | f.close() |
| @@ -225,7 +226,7 @@ class FileStore: · 11 unmodified lines |
| 225 | else: | 226 | else: |
| 226 | os.remove(real_path) | 227 | os.remove(real_path) |
| 227 | | 228 | |
| 228 | except OSError, e: | 229 | except OSError as e: |
| 229 | return str(e) | 230 | return str(e) |
| 230 | | 231 | |
| 231 | return True | 232 | return True |
| @@ -233,18 +234,25 @@ class FileStore: · 1 unmodified line |
| 233 | def wstat(self, fid, st): | 234 | def wstat(self, fid, st): |
| 234 | | 235 | |
| 235 | path = self.paths[fid] | 236 | path = self.paths[fid] |
| 236 | real_path = os.path.join(self.dir, path) | 237 | real_path = os.path.join(self.dir, path).encode(self.encoding) |
| | 238 | |
| | 239 | pieces = path.split(u"/") |
| | 240 | old_name = pieces[-1] |
| 237 | | 241 | |
| 238 | old_name = path.split("/")[-1] | 242 | # Only update the name if the specified name is not empty and differs |
| 239 | if st.name != "" and st.name != old_name: | 243 | # from the existing path. |
| 240 | new_path = os.path.join(os.path.split(real_path)[0], st.name) | 244 | if st.name != u"" and st.name != old_name: |
| | 245 | # Rename the file and use the new path for any further operations. |
| | 246 | new_path = os.path.join(os.path.split(real_path)[0], st.name).encode(self.encoding) |
| 241 | os.rename(real_path, new_path) | 247 | os.rename(real_path, new_path) |
| 242 | real_path = new_path | 248 | real_path = new_path |
| | 249 | # Update the path dictionary to contain the new path. |
| | 250 | self.paths[fid] = pieces + [u"/" + st.name] |
| 243 | | 251 | |
| 244 | s = os.stat(real_path) | 252 | s = os.stat(real_path) |
| 245 | | 253 | |
| 246 | if st.mode != 0xffffffff: | 254 | if st.mode != 0xffffffff: |
| 247 | os.chmod(real_path, st.mode & 0777) | 255 | os.chmod(real_path, st.mode & 0o777) |
| 248 | | 256 | |
| 249 | if st.mtime != 0xffffffff or st.atime != 0xffffffff: | 257 | if st.mtime != 0xffffffff or st.atime != 0xffffffff: |
| 250 | if st.mtime == 0xffffffff: | 258 | if st.mtime == 0xffffffff: |
| @@ -271,4 +279,4 @@ if __name__ == "__main__": · 20 unmodified lines |
| 271 | | 279 | |
| 272 | store = FileStore(directory) | 280 | store = FileStore(directory) |
| 273 | server = styxserver.StyxServer(store) | 281 | server = styxserver.StyxServer(store) |
| 274 | server.serve("", port) | 282 | server.serve(b"", port) |