# fileserver.py
#
# A simple file transfer server for Series 60 Python environment.
#
# Copyright (c) 2005 Nokia Corporation
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import binascii
#DEBUGLOG=lambda x: sys.stdout.write(x+"\n")
DEBUGLOG=lambda x: 0
def file_checksums(filelist):
retval={}
for fname in filelist:
try:
f=open(fname,'rb')
checksum=binascii.crc32(f.read())
f.close()
except:
checksum=None
retval[fname]=checksum
return retval
class fileserver:
def __init__(self,sock):
self.sock=sock
self.commands={'quit': self.cmd_quit,
'get': self.cmd_get,
'put': self.cmd_put,
'exec': self.cmd_exec,
'eval': self.cmd_eval}
def cmd_quit(self,line):
self.finished=True
def cmd_invalid(self,line):
print >>sys.stderr,'Invalid command '+line,
self.finished=True
def cmd_get(self,cmdline):
filename=eval(cmdline[4:])
DEBUGLOG("get "+filename)
f=open(filename,'rb')
content=f.read()
f.close()
self.senddata(content)
def cmd_put(self,cmdline):
words=cmdline.split()
filename=eval(words[1])
DEBUGLOG("put "+filename)
content=self.recvdata()
f=open(filename,'wb')
f.write(content)
f.close()
print "Wrote %d bytes to %s."%(len(content),filename)
def senddata(self,data):
DEBUGLOG("Content-Length: %d"%len(data))
self.write('Content-Length: '+str(len(data))+'\n'+
'CRC32: '+str(binascii.crc32(data))+'\n')
sentbytes=0
# Send the data in little bits because the Bluetooth serial
# connection may lose data on large sends.
MAX_SEND=2048
while sentbytes<len(data):
n=min(len(data),MAX_SEND)
self.write(data[sentbytes:sentbytes+n])
sentbytes+=n
print "Sent %d bytes."%sentbytes
def recvdata(self):
DEBUGLOG("Waiting for data...")
header_lines=[self.readline() for x in range(2)]
header=dict([x.rstrip().split(': ') for x in header_lines])
content_length=int(header['Content-Length'])
crc32=int(header['CRC32'])
DEBUGLOG("Content-Length: %d"%content_length)
recvbytes=0
content=[]
DEBUGLOG("Receiving data...")
while recvbytes<content_length:
recvstring=self.sock.recv(min(content_length-recvbytes,2048))
recvbytes+=len(recvstring)
#print "Received: %d bytes (%3.1f%%)\r"%(recvbytes,(100.*recvbytes/content_length)),
content.append(recvstring)
print "Received %d bytes."%recvbytes
content=''.join(content)
if crc32 != binascii.crc32(content):
print "*** CRC error!"
return content
def cmd_exec(self,cmdline):
# command=eval(cmdline[5:])
command=eval(self.recvdata())
DEBUGLOG("exec "+command)
try:
exec command in globals()
result=(0,'')
except:
import traceback
result=(1,apply(traceback.format_exception,sys.exc_info()))
self.senddata(repr(result))
def cmd_eval(self,cmdline):
expr=eval(self.recvdata())
#expr=eval(cmdline[5:])
DEBUGLOG("eval "+expr)
# two eval's because we need to first get rid of one level of
# quoting.
result=''
try:
value=eval(expr,globals())
result=(0,value)
except:
import traceback
result=(1,apply(traceback.format_exception,sys.exc_info()))
self.senddata(repr(result))
def readline(self):
s=[]
while 1:
c=self.sock.recv(1)
#self.sock.send(c)
s.append(c)
# We support just sane line-endings here.
if c=='\n':
break
return ''.join(s)
def write(self,msg):
self.sock.send(msg)
def run(self):
self.finished=False
while not self.finished:
cmdline=self.readline().rstrip()
print "Received: "+cmdline
words=cmdline.split()
if len(words)>0:
cmd=words[0]
DEBUGLOG("Running command: "+cmdline)
self.commands.get(cmd,self.cmd_invalid)(cmdline)
if __name__ == '__main__':
import sys
from e32socket import *
import e32
if not e32.is_ui_thread():
f=open('c:/pythonout.txt','at')
sys.stdout=f
sys.stderr=f
print "Starting server"
use_tcp=0
if use_tcp:
s=socket(AF_INET,SOCK_STREAM)
addr=('127.0.0.1',1025)
s.bind(addr)
s.listen(1)
while 1:
print "Waiting"
(sock,remoteaddr)=s.accept()
print "Connected"
server=fileserver(sock)
try:
server.run()
except:
import traceback
traceback.print_exc()
sock.close()
else:
s=socket(AF_BT,SOCK_STREAM)
try:
f=open('c:/system/apps/python/fileserver_conf.txt')
conf=eval(f.read())
f.close()
addr=conf['target']
except:
addr=('00:20:e0:76:c3:52',10)
conf={}
#addr=('00:20:e0:76:c3:52',9)
print "Connecting to "+`addr`
s.connect(addr)
server=fileserver(s)
try:
server.run()
except:
import traceback
traceback.print_exc()
s.close()
print "Server finished."