205
207
:param relpath: Location to put the contents, relative to base.
206
208
:param f: File-like or string object.
208
# FIXME: should do something atomic or locking here, this is unsafe
210
path = self._abspath(relpath)
211
fout = self._sftp.file(path, 'wb')
211
finalpath = self._abspath(relpath)
212
tmp_path = '%s.tmp.%.9f.%d.%d' % (finalpath, time.time(),
213
os.getpid(), random.randint(0,0x7FFFFFFF))
214
# I would *really* like to pass in the SFTP_FLAG_EXCL,
215
# but there doesn't seem to be a way to do it in the
216
# self._sftp.file() interface.
217
fout = self._sftp.file(tmp_path, 'wb')
212
218
except IOError, e:
219
# Maybe this should actually be using the relative form of tmp_path
213
220
self._translate_io_exception(e, relpath)
214
221
except (IOError, paramiko.SSHException), x:
215
raise SFTPTransportError('Unable to write file %r' % (path,), x)
222
raise SFTPTransportError('Unable to open file %r' % (tmp_path,), x)
228
self._translate_io_exception(e, relpath)
229
except paramiko.SSHException, x:
230
raise SFTPTransportError('Unable to write file %r' % (path,), x)
232
# If we fail, try to clean up the temporary file
233
# before we throw the exception
234
# but don't let another exception mess things up
237
self._sftp.remove(tmp_path)
244
self._sftp.rename(tmp_path, finalpath)
246
self._translate_io_exception(e, relpath)
247
except paramiko.SSHException, x:
248
raise SFTPTransportError('Unable to rename into file %r'
221
251
def iter_files_recursive(self):
222
252
"""Walk the relative paths of all files in this transport."""