From 05e56b66a4600a5b9194f47b7f348e3278da69b6 Mon Sep 17 00:00:00 2001 From: "Michael P. Soulier" Date: Sat, 10 Mar 2012 21:20:01 -0500 Subject: [PATCH] Fixing issue #26, with the server not creating the full path to the filename being uploaded. --- t/test.py | 9 ++++++--- tftpy/TftpClient.py | 12 ++++++------ tftpy/TftpStates.py | 26 ++++++++++++++++++-------- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/t/test.py b/t/test.py index d078f90..066d90a 100644 --- a/t/test.py +++ b/t/test.py @@ -141,12 +141,14 @@ class TestTftpyState(unittest.TestCase): def setUp(self): tftpy.setLogLevel(logging.DEBUG) - def clientServerUploadOptions(self, options): + def clientServerUploadOptions(self, options, transmitname=None): """Fire up a client and a server and do an upload.""" root = '/tmp' home = os.path.dirname(os.path.abspath(__file__)) filename = '100KBFILE' input_path = os.path.join(home, filename) + if transmitname: + filename = transmitname server = tftpy.TftpServer(root) client = tftpy.TftpClient('localhost', 20001, @@ -198,6 +200,9 @@ def testClientServerBlksize(self): def testClientServerUploadNoOptions(self): self.clientServerUploadOptions({}) + def testClientServerUploadWithSubdirs(self): + self.clientServerUploadOptions({}, transmitname='foo/bar/100KBFILE') + def testClientServerUploadOptions(self): for blksize in [512, 1024, 2048, 4096]: self.clientServerUploadOptions({'blksize': blksize}) @@ -208,7 +213,6 @@ def testClientServerNoOptionsDelay(self): tftpy.TftpStates.DELAY_BLOCK = 0 def testServerNoOptions(self): - """Test the server states.""" raddress = '127.0.0.2' rport = 10000 timeout = 5 @@ -246,7 +250,6 @@ def testServerNoOptions(self): self.assertTrue( finalstate is None ) def testServerNoOptionsSubdir(self): - """Test the server states.""" raddress = '127.0.0.2' rport = 10000 timeout = 5 diff --git a/tftpy/TftpClient.py b/tftpy/TftpClient.py index e9e46e7..9ea905f 100644 --- a/tftpy/TftpClient.py +++ b/tftpy/TftpClient.py @@ -79,12 +79,12 @@ def upload(self, filename, input, packethook=None, timeout=SOCK_TIMEOUT): Note: If output is a hyphen then stdout is used.""" self.context = TftpContextClientUpload(self.host, - self.iport, - filename, - input, - self.options, - packethook, - timeout) + self.iport, + filename, + input, + self.options, + packethook, + timeout) self.context.start() # Upload happens here self.context.end() diff --git a/tftpy/TftpStates.py b/tftpy/TftpStates.py index 6f829d9..c9f20b5 100644 --- a/tftpy/TftpStates.py +++ b/tftpy/TftpStates.py @@ -209,8 +209,14 @@ def resendLast(self): % (self.context.last_pkt, self)) self.context.metrics.resent_bytes += len(self.context.last_pkt.buffer) self.context.metrics.add_dup(self.context.last_pkt) + sendto_port = self.context.tidport + if not sendto_port: + # If the tidport wasn't set, then the remote end hasn't even + # started talking to us yet. That's not good. Maybe it's not + # there. + sendto_port = self.context.port self.context.sock.sendto(self.context.last_pkt.encode().buffer, - (self.context.host, self.context.tidport)) + (self.context.host, sendto_port)) if self.context.packethook: self.context.packethook(self.context.last_pkt) @@ -307,16 +313,20 @@ def make_subdirs(self): """The purpose of this method is to, if necessary, create all of the subdirectories leading up to the file to the written.""" # Pull off everything below the root. - subpath = self.full_path[:len(self.context.root)] + subpath = self.full_path[len(self.context.root):] log.debug("make_subdirs: subpath is %s" % subpath) - dirs = subpath.split(os.sep) + # Split on directory separators, but drop the last one, as it should + # be the filename. + dirs = subpath.split(os.sep)[:-1] + log.debug("dirs is %s" % dirs) current = self.context.root for dir in dirs: - current = os.path.join(current, dir) - if os.path.isdir(current): - log.debug("%s is already an existing directory" % current) - else: - os.mkdir(current, 0700) + if dir: + current = os.path.join(current, dir) + if os.path.isdir(current): + log.debug("%s is already an existing directory" % current) + else: + os.mkdir(current, 0700) def handle(self, pkt, raddress, rport): "Handle an initial WRQ packet as a server."