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