summaryrefslogtreecommitdiffstats
path: root/tupkg/client
diff options
context:
space:
mode:
Diffstat (limited to 'tupkg/client')
-rwxr-xr-xtupkg/client/tupkg142
1 files changed, 138 insertions, 4 deletions
diff --git a/tupkg/client/tupkg b/tupkg/client/tupkg
index ab42b43..4c0da4e 100755
--- a/tupkg/client/tupkg
+++ b/tupkg/client/tupkg
@@ -8,12 +8,146 @@
#
# Python Indentation:
# -------------------
-# Use tabs not spaces. If you use vim, the following comment will
-# configure it to use tabs.
-# vim: ts=2 sw=2 noet ft=python
+# For a vim: line to be effective, it must be at the end of the
+# file. See the end of the file for more information.
#
+import sys
+import socket
+import os
+import struct
+import os.path
+import cgi
+import urllib
+import md5
+
+class ClientFile:
+ def __init__(self, pathname):
+ self.pathname = pathname
+ self.filename = os.path.basename(pathname)
+ self.fd = open(pathname, "rb")
+ self.fd.seek(0, 2)
+ self.size = self.fd.tell()
+ self.fd.seek(0)
+ self.makeMd5()
+
+ def makeMd5(self):
+ md5sum = md5.new()
+ while self.fd.tell() != self.size:
+ md5sum.update(self.fd.read(1024))
+ self.md5 = md5sum.hexdigest()
+
+class ClientSocket:
+ def __init__(self, files, host, port, username, password):
+ self.files = files
+ self.host = host
+ self.port = port
+ self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+ self.username = username
+ self.password = password
+
+ def connect(self):
+ self.socket.connect((self.host, self.port))
+
+ def reliableRead(self, size):
+ totalread = ""
+ while len(totalread) < size:
+ read = self.socket.recv(size-len(totalread))
+ if read == 0:
+ raise RuntimeError, "socket connection broken"
+ totalread += read
+ return totalread
+
+ def sendMsg(self, msg):
+ if type(msg) == dict:
+ msg = urllib.unquote(urllib.urlencode(msg,1))
+ length = struct.pack("H", socket.htons(len(msg)))
+ self.socket.sendall(length)
+ self.socket.sendall(msg)
+
+ def readMsg(self, format=0):
+ initsize = self.reliableRead(2)
+ (length,) = struct.unpack("H", initsize)
+ length = socket.ntohs(length)
+ data = self.reliableRead(length)
+ if format == 1:
+ qs = cgi.parse_qs(data)
+ return qs
+ else:
+ return data
+
+ def close(self):
+ self.socket.close()
+
+ def auth(self):
+ msg = {'username': self.username, 'password': self.password}
+ self.sendMsg(msg)
+ reply = self.readMsg(1)
+ if reply['result'] == ["PASS"]:
+ return 1
+ else:
+ return 0
+
+ def sendFileMeta(self):
+ msg = {'numpkgs': len(self.files)}
+ for i, v in enumerate(self.files):
+ msg['name'+str(i)] = v.filename
+ msg['size'+str(i)] = v.size
+ msg['md5sum'+str(i)] = v.md5
+ self.sendMsg(msg)
+ reply = self.readMsg(1)
+ print reply
+ for i in reply:
+ if i[:4] == 'size':
+ self.files[int(i[4:])].cur_done = int(reply[i][0])
+
+ def sendFiles(self):
+ for i in self.files:
+ i.fd.seek(i.cur_done)
+ while i.fd.tell() < i.size:
+ self.socket.sendall(i.fd.read(1024))
+ reply = self.readMsg(1)
+ print reply
+ self.sendMsg("ack")
+
+def usage():
+ print "usage: tupkg <package file>"
+def main(argv=None):
+ if argv is None:
+ argv = sys.argv
-# TODO write the code
+ if len(argv) == 1:
+ usage()
+ return 1
+
+ try:
+ fil = ClientFile(argv[1])
+ except IOError, err:
+ print "Error: " + err.strerror + ": '" + err.filename + "'"
+ usage()
+ return 1
+
+ cs = ClientSocket([fil], 'localhost', 1034, "bfinch@example.net", "B0b")
+ cs.connect()
+
+ if not cs.auth():
+ print "Error authenticating you, you bastard"
+
+ cs.sendFileMeta()
+
+ cs.sendFiles()
+
+ cs.close()
+
+ return 0
+
+if __name__ == "__main__":
+ sys.exit(main())
+
+# Python Indentation:
+# -------------------
+# Use tabs not spaces. If you use vim, the following comment will
+# configure it to use tabs.
#
+# vim:noet:ts=2 sw=2 ft=python