CD001UTF8 9CD `` LM"KKk !29VOLUMESET 9PUBLISHER DUMP9660 DUMP9660 2007091800335000200709180033500000000000000000000000000000000000ÿCD001import StringIO import Qid import Errors import Socketfile BIT8SZ = 1 BIT16SZ = 2 BIT32SZ = 4 BIT64SZ = 8 MAXMSG = 10000 QIDSZ = BIT8SZ + BIT32SZ + BIT64SZ # /* STATFIXLEN includes leading 16-bit count */ # /* The count, however, excludes itself; total size is BIT16SZ+count */ STATFIXLEN = BIT16SZ + QIDSZ + 5*BIT16SZ + 4*BIT32SZ + 1*BIT64SZ # /* amount of fixed lengt h data in a stat buffer */ def perm_mode(mode) : return mode & 0xffff class Dir : def __init__(self, filename="", type=0, dev=0, qid=None, mode=0, atime=0, mtime=0, length=0, uid='???', gid='???', muid='???') : self.name = filename self.type = type self.dev = dev if qid : self.qid = qid else : self.qid = Qid.Qid() self.mode = mode self.atime = atime self.mtime = mtime self.length = length if uid : self.uid = uid else : self.uid = '???' if gid : self.gid = gid else : self.gid = '???' if muid : self.muid = muid else : self.muid = '???' def load_from_stat_bytes(self, bytes) : sizes = bytes.GBIT16() # throw away self.type = bytes.GBIT16() self.dev = bytes.GBIT32() self.qid = bytes.gqid() self.mode = bytes.GBIT32() self.atime = bytes.GBIT32() self.mtime = bytes.GBIT32() self.length = bytes.GBIT64() self.name = bytes.gstring() self.uid = bytes.gstring() self.gid = bytes.gstring() self.muid = bytes.gstring() def D2M(self, include_d2msize=True) : ns = len(self.name) + len(self.uid) + len(self.gid) + len(self.muid) ss = STATFIXLEN + ns bio = Socketfile.ByteIO(StringIO.StringIO()) # dir entry size if include_d2msize : bio.PBIT16(ss - BIT16SZ + 2) # stat entry for dir bio.PBIT16(ss - BIT16SZ) bio.PBIT16(self.type) bio.PBIT32(self.dev) bio.pqid(self.qid) bio.PBIT32(self.mode) bio.PBIT32(self.atime) bio.PBIT32(self.mtime) bio.PBIT64(self.length) bio.pstring(self.name) bio.pstring(self.uid) bio.pstring(self.gid) bio.pstring(self.muid) return bio.getvalue() def __str__(self) : return "%s:%s %s \n\ttype: %s\n\tdev: %d\n\tqid: %s\n\tmode: %s\n\tatime: %d\n\tmtime: %d\n\tlength: %d" % (self.uid, self.gid, self.name, self.type, self.dev, str(self.qid), self.mode, self.atime, self.mtime, self.length) Eauth = 'authentication failed' Ebadfid = 'fid unknown or out of range' Ebadoffset = 'bad offset in directory read' Ebadusefid = 'bad use of fid' Ebadstat = 'bad stat' Edirchange = "wstat can't convert between files and directories" Eexist = 'file or directory already exists' Efidactive = 'fid already in use' Enotdir = 'not a directory' Enotfound = 'file not found' Enotingroup = 'not a member of proposed group' Enotowner = 'only owner can change group in wstat' Eperm = 'permission denied' Especial0 = 'already attached without access to special files' Especial1 = 'already attached with access to special files' Especial = 'no access to special file' Etoolarge = 'i/o count too large' Eunknowngroup = 'unknown group' Eunknownuser = 'unknown user' Ewstatbuffer = 'bogus wstat buffer' import sys import socket import os errconn = None def stderr(txt) : # if 'TCPREMOTEIP' in os.environ : return output_to_sys(txt) # else : # return output_to_socket(txt) pass def output_to_socket(txt) : global errconn if errconn == None : errconn = socket.socket(socket.AF_INET, socket.SOCK_STREAM) errconn.connect(('192.168.9.14', 6655)) errconn.send(txt + "\n") def output_to_sys(txt, fd=None) : pass # if fd == None : # fd = open('/home/maht/py9p/log', 'a') sys.stderr.write(txt + "\n") sys.stderr.flush() import os import os.path import Errors import sys import Dir import User import Qid import random import mutex OREAD = 0x00 OWRITE = 0x01 ORDWR = 0x02 OEXEC = 0x03 OTRUNC = 0x10 OCLOSE = 0x40 ODIR = 0x80000000 S_ISDIR = 0040000 fid_activity = {} fid_lock = mutex.mutex() def clone_to_random(fid=0, clone_fid=0, path='') : return Fid(fid).clone_to_random(clone_fid=clone_fid, path=path) def lookup_fid(fid) : global fid_activity if fid in fid_activity: try : return fid_activity[fid] except : # someone sniped it pass return None def new_fid(fid=1, path="") : global fid_lock # this is laid out a bit weird to keep the locked code as short as poss. # assigning a new fid so make sure we don't assign two with the same id f = Fid(fid) f.fd = -1 f.omode = -1 f.path = path while not fid_lock.testandset() : pass if lookup_fid(fid) : f = None else : fid_activity[fid] = f fid_lock.unlock() return (None, f) def clunk_fid(fid) : global fid_activity try : del fid_activity[fid] except : # don't worry if it disappeared pass return True class Fid : def __init__(self, fid=0) : self._reset(fid) def _reset(self, fid=0) : self.fid = fid self.path = "/" self.u = None # User* self.omode = 0 self.fd = -1 # int self.last_read_dir = None def clone(self, clone_fid=0, path="") : if path == "" : path = self.path elif self.path == '/' : path = self.path + path else : path = os.path.normpath(self.path + os.sep + path) if clone_fid != self.fid : (error, c)= new_fid(fid=clone_fid, path=path) else : c = lookup_fid(self.fid) if c : c.path = path c.last_read_dir = None return c def clone_to_random(self, clone_fid=0, path="") : c = None if clone_fid > 0 : c = self.clone(clone_fid=clone_fid, path=path) else : tries = 10 while tries and not c : clone_fid = random.randint(2, 6553) c = self.clone(clone_fid=clone_fid, path=path) tries -= 1 return c def __str__(self) : return ("Fid : %d path : \"%s\"" % (self.fid, self.path)) import os import os.path import Errors import sys import Dir import User import Qid import random import mutex OREAD = 0x00 OWRITE = 0x01 ORDWR = 0x02 OEXEC = 0x03 OTRUNC = 0x10 OCLOSE = 0x40 ODIR = 0x80000000 S_ISDIR = 0040000 virtual_drives = ['c', 'd', 'e', 'z'] root_qid = Qid.Qid(filename="", type=Qid.QTDIR, vers=0, path=1) root_dir = Dir.Dir(filename="", type=0, dev=0, qid=root_qid, mode=0755, length=512, uid='nokia', gid='nokia') fid_activity = {} qid2path = {str(root_qid):''} fid_lock = mutex.mutex() defaultuser = 'nobody' # this uglyness was to get the library through when being imported as a client on non-Unix systems try : import pwd import grp get_group_gid = grp.getgrgid get_pw_nam = pwd.getpwnam except : get_group_gid = lambda id : ('nokia', id, 'nokia') get_pw_nam = lambda s : ('nokia', 0, 0, 0) def omode_from_9pmode(mode) : omode = 0 if mode & OWRITE : omode |= os.O_WRONLY if mode & OWRITE : omode |= os.O_WRONLY if mode & ORDWR : omode |= os.O_RDWR if mode & OTRUNC : omode |= os.O_TRUNC return omode def plan9_mode(st_mode) : mode = 0L if st_mode & 0040000 : mode = mode | Qid.QTDIR mode = mode << 24 mode = mode | ( st_mode & 0777 ) return mode def uid_to_user(uid) : u = User.uid2user(uid) if u and u.name != '' : return u.name return '%d' % uid def gid_to_group(gid) : g = User.gid2group(gid) if g and g.name != '' : return g.name return '%d' % gid def muid_to_m(muid) : return '%d' % muid def qids_from_filesystem(fid, starting_qid, path_parts) : qids = [] if str(starting_qid) in qid2path : newpath = qid2path[str(starting_qid)] else : return qids if not len(path_parts) : return qids for part in path_parts : newpath = os.path.join(newpath, part) dir = path_to_dir(path=newpath) if not dir : break qids.append(dir.qid) return qids def qid_in_filesystem(qid) : if not qid : return False return qid2path[str(qid)][2:3] == ':' def qids_for_path(fid=0, starting_qid=None, path_parts=[]) : global root_qid if qid_in_filesystem(starting_qid) : return qids_from_filesystem(fid, starting_qid, path_parts) if starting_qid == root_qid : Errors.stderr("starting_qid == root_qid" ) if path_parts[0] == 'e:' : path_parts[0] = '/' return qids_from_filesystem(fid, starting_qid, path_parts) return [] def qid_from_st(filename="", mode=0, st=None) : q = Qid.Qid(filename=filename) if not st : return q if filename == "" : q.type |= Qid.QTDIR if mode & ODIR : q.type |= Qid.QTDIR q.vers =long(st.st_mtime) | (st.st_size << 16) q.path = st.st_ino ## ignore -> | (st.st_dev << 32) # no S_ISSPECIAL for python so this should ALWAYS except # so let's wreck the FS << cant remember why I wrote this, might be wise to look it up #if stat.S_ISSPECIAL(st.st_mode) : # q.type |= Qid.QTEXCL; return q def clone_to_random(fid=0, clone_fid=0, path='') : return Fid(fid).clone_to_random(clone_fid=clone_fid, path=path) def virtual_dir(fid=0, path=0) : filename=path mode = ODIR | 0755 qid = Qid.Qid(filename) qid.type |= Qid.QTDIR qid.vers = 1 qid.path = 1 dir = Dir.Dir(filename=filename, type=0, dev=0, qid=qid, mode=mode, length=512, uid=uid_to_user(0), gid=gid_to_group(0)) return dir def path_to_dir(fid=0, path="") : if path == "/" : return root_dir if len(path) > 3 and path[2:3]==':' : if path[1:] in virtual_drives : Errors.stderr("AHA") return virtual_dir(fid=fid, path=path) path = path[1] + ':' + path[2:] if path == "" : return None try : st = os.stat(path) except : Errors.stderr("except == os.stat(%s)" % path) return None filename=os.path.basename(path) mode = plan9_mode(st.st_mode) qid = qid_from_st(filename, mode, st) dir = Dir.Dir(filename=filename, type=0, dev=0, qid=qid, mode=mode, atime=int(st.st_atime), mtime=int(st.st_mtime), length=st.st_size, uid=uid_to_user(st.st_uid), gid=gid_to_group(st.st_gid)) qid2path[str(qid)] = path return dir def list_dir(fid=0) : f = lookup_fid(fid) if not f : return [] if str(f.qid) in qid2path : parent = qid2path[str(f.qid)] if parent[-1:] != '/' : parent += '/' paths = [] return [path_to_dir(fid, "%s%s" % (parent, entry)) for entry in os.listdir(parent)] return [] def attach_fid(fid, afid, uname, aname) : global root_qid if new_fid(fid=fid, qid=root_qid) > 0 : return root_qid def lookup_fid(fid) : global fid_activity if fid in fid_activity: try : return fid_activity[fid] except : # someone sniped it pass return None def lookup_qid(fid) : f = lookup_fid(fid) if f : return f.qid def disconnected() : pass def new_fid(fid=1, clone_from=0, qid=None) : global fid_lock # this is laid out a bit weird to keep the locked code as short as poss. # assigning a new fid so make sure we don't assign two with the same id f = Fid(fid) f.fd = None f.omode = -1 if qid == None and clone_from > 0 : c = lookup_fid(clone_from) if c : f.qid = c.qid else : return 0 else : f.qid = qid while not fid_lock.testandset() : pass if lookup_fid(fid) : fid = 0 else : fid_activity[fid] = f fid_lock.unlock() return fid def clunk_fid(fid) : global fid_activity f = lookup_fid(fid) if f : f.close() try : del fid_activity[fid] except : # don't worry if it disappeared pass return True class Fid : def __init__(self, fid=0) : self._reset(fid) def _reset(self, fid=0) : self.fid = fid self.path = "/" self.u = None # User* self.omode = 0 self.fd = None self.last_read_dir = None def dir(self) : return path_to_dir(fid=self.fid, path=self.path) def d2m(self) : dir = self.dir() if not dir : return None # convD2M d2m = dir.D2M() if len(d2m) <= Dir.BIT16SZ : return None return d2m def set_u(self, user) : self.u = get_pw_nam(user) def open(self, mode=OREAD) : self.fd = None omode = omode_from_9pmode(mode) try : self.fd = os.open(self.path, omode) self.omode = omode return self.qid # except OSError: # return Errors.Eperm except : # for virtual drives c:\\ d:\\ e:\\ z:\\ lazy implementation if self.is_dir() : return self.qid def read(self, offset, count) : if self.is_dir() : return self.read_dir(offset, count) if self.fd : os.lseek(self.fd, offset, 0) return (None, os.read(self.fd, count)) return (Errors.Eperm, None) def write(self, offset, count, data) : if self.fd : os.lseek(self.fd, offset, 0) return os.write(self.fd, data[:count]) return 0 def walk(self, qid) : self.qid = qid self.last_read_dir = None def create(self, name, perm, mode) : fullname = os.path.join(qid2path[self.qid], name) if perm & 0x80000000 : try : os.mkdir(fullname, Dir.perm_mode(perm)) except : return (str(sys.exc_info()[1]), None) else : try : f = file(fullname, 'w+') if not f : return ("Open failed", None) f.close() except : return (str(sys.exc_info()[1]), None) fid = self.fid self._reset() self.fid = fid self.open(mode) dir = self.dir() self.qid = dir.qid qid2path[str(self.qid)] = fullname return ("", self.qid) def close(self) : if self.fd : if not self.is_dir() : try : os.close(self.fd) except : pass try : if self.omode & Dir.OCLOSE : unlink(qid2path[str(self.qid)]) except : pass self._reset() def remove(self) : if self.is_dir() : try : os.rmdir(qid2path[str(self.qid)]) except : return str(sys.exc_info()[1]) else : try : os.unlink(qid2path[str(self.qid)]) except : return str(sys.exc_info()[1]) clunk_fid(self.fid) def userchange(self) : global defaultuser if defaultuser : return 1 if os.setreuid(0, 0) : Errors.stderr('Fid - userchange failed to setreuid(0,0)') raise "didn't get this far" def is_dir(self) : dir = self.dir() if dir : return dir.qid.type & Qid.QTDIR return False def wstat(self, st) : return None def read_dir(self, offset, count) : if offset == 0 or not self.last_read_dir : self.last_read_dir = reduce(lambda x, y : str(x) + str(y), [d.D2M(include_d2msize=False) for d in list_dir(self.fid)], "") return (None, self.last_read_dir[offset:offset+count]) def __str__(self) : d = self.dir() if not d : d = "None" return ("Fid : %d dir %s" % (self.fid, str(d))) import os import os.path import Errors import sys import Dir import User import Qid import random import mutex import fiddb OREAD = 0x00 OWRITE = 0x01 ORDWR = 0x02 OEXEC = 0x03 OTRUNC = 0x10 OCLOSE = 0x40 ODIR = 0x80000000 S_ISDIR = 0040000 dbase = fiddb.fiddb(user='maht', attach_qid=pg_Qid(type=128,path=1,vers=0)) attach_fid = dbase.attach_fid lookup_qid = dbase.lookup_qid lookup_fid = dbase.lookup_fid new_fid = dbase.new_fid clunk_fid = dbase.clunk_fid list_dir = dbase.list_dir # this uglyness was to get the library through when being imported as a client on non-Unix systems try : import pwd import grp get_group_gid = grp.getgrgid get_pw_nam = pwd.getpwnam except : get_group_gid = lambda id : ('wheel', id, 'root') get_pw_nam = lambda s : ('root', 0, 0, 0) def perm_for_flags(flags) : if flags == 0 : return 4 # b'100' perm = 0 if flags & OWRITE : perm |= 2 # b'010' if flags & ORDWR : perm |= 6 # b'110' if flags & OTRUNC : perm |= 2 # b'010' return perm def plan9_mode(st_mode) : mode = 0L if st_mode & 0040000 : mode = mode | Qid.QTDIR mode = mode << 24 mode = mode | ( st_mode & 0777 ) return mode def uid_to_user(uid) : u = User.uid2user(uid) if u and u.name != '' : return u.name return '%d' % uid def gid_to_group(gid) : g = User.gid2group(gid) if g and g.name != '' : return g.name return '%d' % gid def muid_to_m(muid) : return '%d' % muid def qids_for_path(fid=0, starting_qid=None, path_parts=[]) : global dbase qids = [] if not len(path_parts) : return qids qids.append(starting_qid) for part in path_parts : q = dbase.lookup_file(qids[-1:][0], part) if not q : break qids.append(q) return qids[1:] # drop starting point def clone_to_random(fid=0, clone_fid=0, path='') : return Fid(fid).clone_to_random(clone_fid=clone_fid, path=path) def disconnected() : global dbase dbase.disconnect() class Fid : db = None def __init__(self, fid=0) : self._reset(fid) if self.db == None : global dbase self.db = dbase def _reset(self, fid=0) : self.fid = fid self.last_read_dir = None def dir(self) : return self.db.dir(self.fid) def d2m(self) : dir = self.dir() if not dir : return None # convD2M d2m = dir.D2M() if len(d2m) <= Dir.BIT16SZ : return None return d2m def open(self, mode=OREAD) : return self.db.open(self.fid, mode) def read(self, offset, count) : if self.is_dir() : return self.read_dir(offset, count) return self.db.read(self.fid, offset, count) def write(self, offset, count, data) : return self.db.write(self.fid, offset, count, data) def walk(self, qid) : self.db.walk(fid=self.fid, qid=qid) self.last_read_dir = None def create(self, name, perm, mode) : qid= self.db.create(self.fid, name, perm, mode) if qid : return (None, qid) return (Errors.Eperm, None) def close(self, fid) : self.db.close(self.fid) self._reset() def remove(self) : self.db.remove(self.fid) clunk_fid(self.fid) self._reset() def userchange(self) : raise "didn't get this far" def is_dir(self) : return self.db.is_dir(fid=self.fid) def wstat(self, dir) : return self.db.wstat(self.fid, dir) def read_dir(self, offset, count) : if offset == 0 or not self.last_read_dir : self.last_read_dir = reduce(lambda x, y : str(x) + str(y), [d.D2M(include_d2msize=False) for d in list_dir(self.fid)], "") return (None, self.last_read_dir[offset:offset+count]) def __str__(self) : d = self.dir() if not d : d = "None" return ("Fid : %d dir %s" % (self.fid, str(d))) import os import os.path import Errors import sys import Dir import User import Qid import random import mutex OREAD = 0x00 OWRITE = 0x01 ORDWR = 0x02 OEXEC = 0x03 OTRUNC = 0x10 OCLOSE = 0x40 ODIR = 0x80000000 S_ISDIR = 0040000 fid_activity = {} root_qid = path_to_dir(path='/').qid qid2path = {str(root_qid):'/'} fid_lock = mutex.mutex() defaultuser = 'nobody' # this uglyness was to get the library through when being imported as a client on non-Unix systems try : import pwd import grp get_group_gid = grp.getgrgid get_pw_nam = pwd.getpwnam except : get_group_gid = lambda id : ('nokia', id, 'nokia') get_pw_nam = lambda s : ('nokia', 0, 0, 0) def omode_from_9pmode(mode) : omode = 0 if mode & OWRITE : omode |= os.O_WRONLY if mode & OWRITE : omode |= os.O_WRONLY if mode & ORDWR : omode |= os.O_RDWR if mode & OTRUNC : omode |= os.O_TRUNC return omode def plan9_mode(st_mode) : mode = 0L if st_mode & 0040000 : mode = mode | Qid.QTDIR mode = mode << 24 mode = mode | ( st_mode & 0777 ) return mode def uid_to_user(uid) : u = User.uid2user(uid) if u and u.name != '' : return u.name return '%d' % uid def gid_to_group(gid) : g = User.gid2group(gid) if g and g.name != '' : return g.name return '%d' % gid def muid_to_m(muid) : return '%d' % muid def qids_for_path(fid=0, starting_qid=None, path_parts=[]) : qids = [] if str(starting_qid) in qid2path : newpath = qid2path[str(starting_qid)] else : return qids if not len(path_parts) : return qids for part in path_parts : newpath = os.path.join(newpath, part) dir = path_to_dir(path=newpath) if not dir : break qids.append(dir.qid) return qids def qid_from_st(filename="", mode=0, st=None) : q = Qid.Qid(filename=filename) if not st : return q if filename == "" : q.type |= Qid.QTDIR if mode & ODIR : q.type |= Qid.QTDIR q.vers =long(st.st_mtime) | (st.st_size << 16) q.path = st.st_ino ## ignore -> | (st.st_dev << 32) # no S_ISSPECIAL for python so this should ALWAYS except # so let's wreck the FS << cant remember why I wrote this, might be wise to look it up #if stat.S_ISSPECIAL(st.st_mode) : # q.type |= Qid.QTEXCL; return q def clone_to_random(fid=0, clone_fid=0, path='') : return Fid(fid).clone_to_random(clone_fid=clone_fid, path=path) def path_to_dir(fid=0, path="") : if path == "" : return None try : st = os.stat(path) except : return None filename=os.path.basename(path) mode = plan9_mode(st.st_mode) qid = qid_from_st(filename, mode, st) dir = Dir.Dir(filename=filename, type=0, dev=0, qid=qid, mode=mode, atime=int(st.st_atime), mtime=int(st.st_mtime), length=st.st_size, uid=uid_to_user(st.st_uid), gid=gid_to_group(st.st_gid)) qid2path[str(qid)] = path return dir def list_dir(fid=0) : f = lookup_fid(fid) if not f : return [] if str(f.qid) in qid2path : parent = qid2path[str(f.qid)] if parent[-1:] != '/' : parent += '/' paths = [] return [path_to_dir(fid, "%s%s" % (parent, entry)) for entry in os.listdir(parent)] return [] def attach_fid(fid, afid, uname, aname) : global root_qid if new_fid(fid=fid, qid=root_qid) > 0 : return root_qid def lookup_fid(fid) : global fid_activity if fid in fid_activity: try : return fid_activity[fid] except : # someone sniped it pass return None def lookup_qid(fid) : f = lookup_fid(fid) if f : return f.qid def disconnected() : pass def new_fid(fid=1, clone_from=0, qid=None) : global fid_lock # this is laid out a bit weird to keep the locked code as short as poss. # assigning a new fid so make sure we don't assign two with the same id f = Fid(fid) f.fd = None f.omode = -1 if qid == None and clone_from > 0 : c = lookup_fid(clone_from) if c : f.qid = c.qid else : return 0 else : f.qid = qid while not fid_lock.testandset() : pass if lookup_fid(fid) : fid = 0 else : fid_activity[fid] = f fid_lock.unlock() return fid def clunk_fid(fid) : global fid_activity f = lookup_fid(fid) if f : f.close() try : del fid_activity[fid] except : # don't worry if it disappeared pass return True class Fid : def __init__(self, fid=0) : self._reset(fid) def _reset(self, fid=0) : self.fid = fid self.path = "/" self.u = None # User* self.omode = 0 self.fd = None self.last_read_dir = None def dir(self) : return path_to_dir(fid=self.fid, path=self.path) def d2m(self) : dir = self.dir() if not dir : return None # convD2M d2m = dir.D2M() if len(d2m) <= Dir.BIT16SZ : return None return d2m def set_u(self, user) : self.u = get_pw_nam(user) def open(self, mode=OREAD) : self.fd = None omode = omode_from_9pmode(mode) try : self.fd = os.open(self.path, omode) self.omode = omode return self.qid # except OSError: # return Errors.Eperm except : # for virtual drives c:\\ d:\\ e:\\ z:\\ lazy implementation if self.is_dir() : return self.qid def read(self, offset, count) : if self.is_dir() : return self.read_dir(offset, count) if self.fd : os.lseek(self.fd, offset, 0) return (None, os.read(self.fd, count)) return (Errors.Eperm, None) def write(self, offset, count, data) : if self.fd : os.lseek(self.fd, offset, 0) return os.write(self.fd, data[:count]) return 0 def walk(self, qid) : self.qid = qid self.last_read_dir = None def create(self, name, perm, mode) : fullname = os.path.join(qid2path[self.qid], name) if perm & 0x80000000 : try : os.mkdir(fullname, Dir.perm_mode(perm)) except : return (str(sys.exc_info()[1]), None) else : try : f = file(fullname, 'w+') if not f : return ("Open failed", None) f.close() except : return (str(sys.exc_info()[1]), None) fid = self.fid self._reset() self.fid = fid self.open(mode) dir = self.dir() self.qid = dir.qid qid2path[str(self.qid)] = fullname return ("", self.qid) def close(self) : if self.fd : if not self.is_dir() : try : os.close(self.fd) except : pass try : if self.omode & Dir.OCLOSE : unlink(qid2path[str(self.qid)]) del qid2path[str(self.qid)] except : pass self._reset() def remove(self) : if self.is_dir() : try : os.rmdir(qid2path[str(self.qid)]) del qid2path[str(self.qid)] except : return str(sys.exc_info()[1]) else : try : os.unlink(qid2path[str(self.qid)]) del qid2path[str(self.qid)] except : return str(sys.exc_info()[1]) clunk_fid(self.fid) def userchange(self) : global defaultuser if defaultuser : return 1 if os.setreuid(0, 0) : Errors.stderr('Fid - userchange failed to setreuid(0,0)') raise "didn't get this far" def is_dir(self) : dir = self.dir() if dir : return dir.qid.type & Qid.QTDIR return False def wstat(self, st) : return None def read_dir(self, offset, count) : if offset == 0 or not self.last_read_dir : self.last_read_dir = reduce(lambda x, y : str(x) + str(y), [d.D2M(include_d2msize=False) for d in list_dir(self.fid)], "") return (None, self.last_read_dir[offset:offset+count]) def __str__(self) : d = self.dir() if not d : d = "None" return ("Fid : %d dir %s" % (self.fid, str(d))) #!/usr/local/bin/python import plan9 from wxPython.wx import * class Form1(wxPanel): def __init__(self, parent, id): wxPanel.__init__(self, parent, id) wxFileDialog(self).ShowModal() app = wxPySimpleApp() frame = wxFrame(None, -1, " Our first Control") Form1(frame,-1) frame.Show(1) app.MainLoop() # python New.py QTDIR = 0x80 QTEXCL = 0x20 class Qid : def __init__ (self, filename='', type=0, vers=0, path=0) : self.type = type self.vers = vers self.path = path self.filename = filename def __str__(self) : # return "Qid type: %d vers: %d path: %d" % (self.type, self.vers, self.path) return "(x%02x, %d, %d)" % (self.type, self.path, self.vers) import Fid_client as Fid new_fid = Fid.new_fid clunk_fid = Fid.clunk_fid lookup_fid = Fid.lookup_fid clone_fid = Fid.clone_to_random qids_for_path = Noneimport Fid_n80 as Fid attach_fid = Fid.attach_fid new_fid = Fid.new_fid clunk_fid = Fid.clunk_fid lookup_qid = Fid.lookup_qid lookup_fid = Fid.lookup_fid clone_fid = Fid.clone_to_random qids_for_path = Fid.qids_for_path disconnected = Fid.disconnectedimport Fid_psql as Fid attach_fid = Fid.attach_fid new_fid = Fid.new_fid clunk_fid = Fid.clunk_fid lookup_qid = Fid.lookup_qid lookup_fid = Fid.lookup_fid clone_fid = Fid.clone_to_random qids_for_path = Fid.qids_for_path disconnected = Fid.disconnected import Fid_ufs as Fid attach_fid = Fid.attach_fid new_fid = Fid.new_fid clunk_fid = Fid.clunk_fid lookup_qid = Fid.lookup_qid lookup_fid = Fid.lookup_fid clone_fid = Fid.clone_to_random qids_for_path = Fid.qids_for_path disconnected = Fid.disconnected import Qid import Errors from pickle import decode_long class socketfile : def __init__(self, read, write, flush=None) : self.fread = read self.fwrite = write self.lush = flush self.data = "" def read(self, count) : return self.fread(count) def write(self, data) : if self.lush : self.fwrite(data) else : self.data += data def flush(self) : if self.lush : self.lush() else : self.fwrite(self.data) self.data = "" class ByteIO : def __init__(self, source) : self.debug = 0 self.read = source.read self.write = source.write try : self.getvalue = source.getvalue except : pass self.io_bytes_read = 0 self.io_bytes_written = 0 def GDATA(self, count) : data = self.read(count) self.io_bytes_read += len(data) return data def GBIT8(self) : self.io_bytes_read += 1 return decode_long(self.read(1)) def GBIT16(self) : self.io_bytes_read += 2 return decode_long(self.read(2)) def GBIT32(self) : # lower = self.read(2) # higher = self.read(2) # result = (higher << 2) | lower; # Errors.stderr("result %s" % str(result)) # self.io_bytes_read += 4 # gb = self.read(4) # up = struct.unpack('l', gb)[0] # import struct # Errors.stderr("GB %s" % str(up)) # dl = decode_long(gb) # Errors.stderr("DL %s" % str(dl)) return self.GBIT16() | self.GBIT16() << 2; # return def GBIT64(self) : self.io_bytes_read += 8 return decode_long(self.read(8)) def gstring(self) : return self.GDATA(self.GBIT16()) def gqid(self) : qid = Qid.Qid() qid.type = self.GBIT8() qid.vers = self.GBIT32() qid.path = self.GBIT64() return qid def PDATA(self, data) : self.write(data) self.io_bytes_written += len(data) def pstring(self, txt) : self.PBIT16(len(txt)) self.PDATA(txt) def PBIT8(self, v) : self.write(chr(int(v) & 255)) self.io_bytes_written += 1 def PBIT16(self, v) : self.PBIT8(v) self.PBIT8(v >> 8) def PBIT32(self, v) : self.PBIT16(v) self.PBIT16(v >> 16) def PBIT64(self, v) : self.PBIT32(v) self.PBIT32(v >> 32) def pqid(self, qid) : if qid : self.PBIT8(qid.type) self.PBIT32(qid.vers) self.PBIT64(qid.path) def PDATA(wryte, data) : wryte(data) def PSTRING(wryte, txt) : PBIT16(wryte, len(txt)) PDATA(wryte, txt) def PBIT8(wryte, v) : wryte(chr(int(v) & 255)) def PBIT16(wryte, v) : PBIT8(wryte, v) PBIT8(wryte, v >> 8) def PBIT32(wryte, v) : PBIT16(wryte, v) PBIT16(wryte, v >> 16) def PBIT64(wryte, v) : PBIT32(wryte, v) PBIT32(wryte, v >> 32) def pqid(wryte, qid) : if qid : PBIT8(wryte, qid.type) PBIT32(wryte, qid.vers) PBIT64(wryte, qid.path) from Socketfile import * import StringIO import sys import Qid import Dir import Errors BIT16SZ = 2 MAXWELEM = 16 # apparently IOUNIT = 8192 headersize = 4 + 1 + 2 authenticated = 0 debug = 1 settings = None def hex_format(data) : counter = '' dec = '' chrs = '' ex = '' for i in xrange(0, len(data)) : c = ord(data[i]) if c < 32 or c > 128 : ch = 32 else : ch = c counter += "%03d " % (i + headersize) dec += "%03d " % (c) chrs += "%3c " % (ch) h = hex(c)[1:] h = (3-len(h)) * ' ' + h ex += "%s " % (h) if counter != "" : return "%s\n%s\n%s\n%s" % (counter , dec, chrs, ex) return "" # ============================= T Message ============================================ class Message: def __init__(self, tag=0, size=0) : self.tag = tag self.size = size global debug self.debug = debug def __str__(self) : return "%05d-%s\n%s" % (self.tag, self.TR_name, hex_format(self.body_bytes().getvalue())) def load(self, size, bytes) : self.load_from_bytes(bytes) if bytes.io_bytes_read != size : raise 'wrong sized message', " exp: %d got: %d" % (size, bytes.io_bytes_read) def write_to(self, fd) : global headersize body = self.body_bytes().getvalue() PBIT32(fd.write, len(body) + headersize) PBIT8(fd.write, self.type) PBIT16(fd.write ,self.tag) fd.write(body) fd.flush() if self.debug : Errors.stderr("TX : %d bytes %s" % (len(body), str(self))) def __getattr__(self, attr) : if attr == 'TR_name' : try : str = Message_classes[self.type][1] except : str = 'Unknown type' return str else : raise AttributeError, "self.TR_name" + "." + attr def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) return bio class Tmessage(Message) : def load_from_bytes(self, bytes) : raise 'Tmessage.load_from_bytes - base class not overridden - bad news' def get_Rmessage(self) : raise ("Tmessage - get_Rmessage not overridden type %d" % (self.type,)) class Tversion(Tmessage) : type = 100 def load_from_bytes(self, bytes) : self.msize = bytes.GBIT32() self.version = bytes.gstring() if self.version[0:2] == '9P' : self.version = '9P2000' else : self.version = 'unknown' def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.msize) bio.pstring(self.version) return bio def get_Rmessage(self) : r = Rversion(self.tag) r.msize = self.msize r.version = self.version return r def __str__(self) : base = Message.__str__(self) return "%s\n\tVersion: %s" % (base, self.version) class Tflush(Tmessage) : type = 108 def load_from_bytes(self, bytes) : self.oldtag = bytes.GBIT16() def get_Rmessage(self) : r = Rflush(self.tag) return r class Tauth(Tmessage) : type = 102 def load_from_bytes(self, bytes) : self.afid = bytes.GBIT32() self.uname = bytes.gstring() self.aname = bytes.gstring() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.afid) bio.pstring(self.uname) bio.pstring(self.aname) return bio def get_Rmessage(self) : r = Rauth(self.tag) r.uname = self.uname r.aname = self.aname global authenticated authenticated = 1 return r def __str__(self) : base = Message.__str__(self) return "%s\n\tafid: %d\tuname: %s\taname: %s" % (base, self.afid, self.uname, self.aname) class Tattach(Tmessage) : type = 104 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() self.afid = bytes.GBIT32() self.uname = bytes.gstring() self.aname = bytes.gstring() if self.aname == 'device' : raise 'Tattach aname was set to "device" which was marked as a special case' def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) bio.PBIT32(self.afid) bio.pstring(self.uname) bio.pstring(self.aname) return bio def get_Rmessage(self) : q = settings.attach_fid(self.fid, self.afid, self.uname, self.aname) if not q : return Rerror(self.tag, error="Attach failed") Errors.stderr("AQ %s" % q) r = Rattach(self.tag) r.fid = self.fid r.afid = self.afid r.uname = self.uname r.aname = self.aname r.qid = q return r def __str__(self) : base = Message.__str__(self) return "%s\n\tfid : %d\tafid: %d\tuname: %s\taname: %s" % (base, self.fid, self.afid, self.uname, self.aname) class Twalk(Tmessage) : type = 110 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() self.newfid = bytes.GBIT32() self.nwname = bytes.GBIT16() self.wname = [] if self.nwname > MAXWELEM : raise "Twalk nwname > MAXWELEM %d" % (MAXWELEM) for i in xrange(0, self.nwname) : self.wname.append(bytes.gstring()) if self.nwname == 0 : self.wname = [] def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) bio.PBIT32(self.newfid) try : nwname = len(self.wname) if nwname > 0 : bio.PBIT16(nwname) for i in xrange(0, nwname) : bio.pstring(self.wname[i]) else : bio.PBIT16(0) except : bio.PBIT16(0) return bio def get_Rmessage(self) : r = Rwalk(self.tag) qid = settings.lookup_qid(self.fid) if not qid: return Rerror(self.tag, error=Errors.Ebadfid) if len(self.wname) == 0 : if self.fid == self.newfid : return r newfid = settings.new_fid(fid=self.newfid, clone_from=self.fid) if newfid : return r return Rerror(self.tag, error="new_fid failed") r.wqid = settings.qids_for_path(fid=self.fid, starting_qid=qid, path_parts=self.wname) if len(r.wqid) == 0 : return Rerror(self.tag, error=Errors.Enotfound) if len(r.wqid) == len(self.wname) : if self.newfid != self.fid : newfid = settings.new_fid(fid=self.newfid, qid=r.wqid[len(r.wqid)-1]) if not newfid : return Rerror(self.tag, error="New Fid failed") else : f.walk(r.wqid[len(r.wqid)-1]) return r def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d newfid: %d path: %s" % (base, self.fid, self.newfid, reduce(lambda x,y: str(x) + "/" + str(y), self.wname, "")[1:]) class Topen(Tmessage) : type = 112 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() self.mode = bytes.GBIT8() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) bio.PBIT8(self.mode) return bio def get_Rmessage(self) : f = settings.lookup_fid(self.fid) if not f : return Rerror(self.tag, error=Errors.Ebadfid) qid = f.open(mode=self.mode) if qid : return Ropen(self.tag, qid=qid) return Rerror(self.tag, error=Errors.Eperm) def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d\tmode: %d" % (base, self.fid, self.mode) class Tcreate(Tmessage) : type = 114 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() self.name = bytes.gstring() self.perm = bytes.GBIT32() self.mode = bytes.GBIT8() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) bio.pstring(self.name) bio.PBIT32(self.perm) bio.PBIT8(self.mode) return bio def get_Rmessage(self) : f = settings.lookup_fid(self.fid) if not f : return Rerror(self.tag, error=Errors.Ebadfid) (error, qid) = f.create(self.name, self.perm, self.mode) if qid : return Rcreate(self.tag, qid=qid) return Rerror(self.tag, error=error) def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d\tname: %s\tperm: %d\tmode: %d" % (base, self.fid, self.name, self.perm, self.mode) class Tread(Tmessage) : type = 116 def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) bio.PBIT64(self.offset) bio.PBIT32(self.count) return bio def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() self.offset = bytes.GBIT64() self.count = bytes.GBIT32() def get_Rmessage(self) : f = settings.lookup_fid(self.fid) if not f : return Rerror(self.tag, error=Errors.Ebadfid) (error, data) = f.read(self.offset, self.count) if error : return Rerror(self.tag, error=error) return Rread(self.tag, data=data) def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d\toffset: %d\tcount: %d" % (base, self.fid, self.offset, self.count) class Twrite(Tmessage) : type = 118 def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) bio.PBIT64(self.offset) bio.PBIT32(self.count) bio.PDATA(self.data) return bio def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() self.offset = bytes.GBIT64() self.count = bytes.GBIT32() self.data = bytes.GDATA(self.count) def get_Rmessage(self) : f = settings.lookup_fid(self.fid) if not f : return Rerror(self.tag, error=Errors.Ebadfid) r = Rwrite(self.tag) r.count = f.write(self.offset, self.count, self.data) return r def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d\toffset: %d\tcount: %d" % (base, self.fid, self.offset, self.count) class Tclunk(Tmessage) : type = 120 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) return bio def get_Rmessage(self) : settings.clunk_fid(self.fid) r = Rclunk(self.tag) return r def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d" % (base, self.fid) class Tremove(Tmessage) : type = 122 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) return bio def get_Rmessage(self) : q = settings.lookup_fid(self.fid) if not q : return Rerror(self.tag, error=Errors.Ebadfid) r = Rremove(self.tag) error = q.remove() if error : r = Rerror(self.tag, error=error) return r def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d" % (base, self.fid) class Tstat(Tmessage) : type = 124 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) return bio def get_Rmessage(self) : f = settings.lookup_fid(self.fid) if not f : return Rerror(self.tag, error=Errors.Ebadfid) r = Rstat(self.tag) r.fid = self.fid r.d2m = f.d2m() if not r.d2m : return Rerror(self.tag, error=Errors.Ebadstat) return r def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d" % (base, self.fid) class Twstat(Tmessage) : type = 126 def load_from_bytes(self, bytes) : self.fid = bytes.GBIT32() self.stat = bytes.gstring() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.fid) bio.pstring(self.stat) return bio def get_Rmessage(self) : f = settings.lookup_fid(self.fid) if not f : return Rerror(self.tag, error=Errors.Ebadfid) wdir = Dir.Dir() wdir.load_from_stat_bytes(ByteIO(StringIO.StringIO(self.stat))) if f.wstat(wdir) : return Rwstat(self.tag) return Rerror(self.tag, error=Errors.Eperm) def __str__(self) : base = Message.__str__(self) return "%s\n\tfid: %d\tstat: %s" % (base, self.fid, self.stat) class Terror : type = 106 def load_from_bytes(self, bytes) : raise "Terror" # ============================= R Message ============================================ class Rmessage(Message) : pass class Rversion(Rmessage) : type = 101 def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.msize) bio.pstring(self.version) return bio def load_from_bytes(self, bytes) : self.msize = bytes.GBIT32() self.version = bytes.gstring() if self.version[0:2] == '9P' : self.version = '9P2000' else : self.version = 'unknown' def __str__(self) : base = Message.__str__(self) return "%s\n\tversion: %s" % (base, self.version) class Rauth(Rmessage) : type = 103 def body_bytes(self) : self.type = Rerror.type bio = ByteIO(StringIO.StringIO()) bio.pstring('u9fs authnone: no authentication required') return bio class Rattach(Rmessage) : type = 105 def __init__(self, tag, size=0) : Rmessage.__init__(self, tag, size) self.qid = None def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.pqid(self.qid) return bio def load_from_bytes(self, bytes) : self.qid = Qid.Qid() self.qid.type = bytes.GBIT8() self.qid.vers = bytes.GBIT32() self.qid.path = bytes.GBIT64() def __str__(self) : base = Message.__str__(self) return "%s\n\tqid: %s" % (base, str(self.qid)) class Rwalk(Rmessage) : type = 111 def __init__(self, tag, size=0) : Rmessage.__init__(self, tag, size) self.wqid = [] def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) nwqid = len(self.wqid) bio.PBIT16(nwqid) for i in range(0, nwqid) : bio.pqid(self.wqid[i]) return bio def load_from_bytes(self, bytes) : nwqid = bytes.GBIT16() self.wqid = [] for i in xrange(0, nwqid) : self.wqid.append(bytes.gqid()) def __str__(self) : base = Message.__str__(self) return "%s\n\tqids: %s" % (base, reduce(lambda x, y : str(x) + '\n\t' + str(y), self.wqid, "")) class Rclunk(Rmessage) : type = 121 def load_from_bytes(self, bytes) : pass def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) return bio class Rstat(Rmessage) : type = 125 def __init__(self, tag, size=0) : Rmessage.__init__(self, tag, size) self.d2m = "" def body_bytes(self) : bio = ByteIO(StringIO.StringIO(self.d2m)) return bio def load_from_bytes(self, bytes) : self.stat_size = bytes.GBIT16() self.load_from_stat_bytes(bytes) def load_from_stat_bytes(self, bytes) : size = bytes.GBIT16() dir = Dir.Dir() dir.type = bytes.GBIT16() dir.dev = bytes.GBIT32() dir.qid = bytes.gqid() dir.mode = bytes.GBIT32() dir.atime = bytes.GBIT32() dir.mtime = bytes.GBIT32() dir.length = bytes.GBIT64() dir.name = bytes.gstring() if dir.name == '' : dir.name = '/' dir.uid = bytes.gstring() dir.gid = bytes.gstring() dir.muid = bytes.gstring() self.d2m = dir.D2M() class Rerror(Rmessage) : type = 107 def __init__(self, tag, size=0, error="ZError") : Rmessage.__init__(self, tag, size) self.error = error def load_from_bytes(self, bytes) : self.error = bytes.gstring() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) if self.error : bio.pstring(self.error) else : bio.pstring("EXrror") return bio def __str__(self) : base = Message.__str__(self) return "%s\n\tError: %s" % (base, self.error) class Rflush(Rmessage) : type = 109 class Ropen(Rmessage) : type = 113 def __init__(self, tag, size=0, qid=None) : Rmessage.__init__(self, tag, size) self.qid = qid self.iounit = IOUNIT def load_from_bytes(self, bytes) : self.qid = bytes.gqid() self.iounit = bytes.GBIT32() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.pqid(self.qid) bio.PBIT32(self.iounit) return bio def __str__(self) : base = Message.__str__(self) return "%s\n\tqid: %s\tiounit: %d" % (base, str(self.qid), self.iounit) class Rcreate(Rmessage) : type = 115 def __init__(self, tag=0, size=0, qid=None) : Rmessage.__init__(self, tag, size) self.qid = qid self.iounit = IOUNIT def load_from_bytes(self, bytes) : self.qid = bytes.gqid() self.iounit = bytes.GBIT32() def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.pqid(self.qid) bio.PBIT32(self.iounit) return bio def __str__(self) : base = Message.__str__(self) return "%s\n\tqid: %s\tiounit: %d" % (base, str(self.qid), self.iounit) class Rread(Rmessage) : type = 117 def __init__(self, tag, size=0, data=None) : Rmessage.__init__(self, tag, size) self.data = data def load_from_bytes(self, bytes) : self.count = bytes.GBIT32() # ignore count because if it is result of statting a directory it is not the same format self.data = bytes.GDATA(self.size - bytes.io_bytes_read) def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(len(self.data)) bio.PDATA(self.data) return bio def __str__(self) : base = Message.__str__(self) return "%s\n\tcount: %d\n\tdata: %s" % (base, len(self.data), self.data) class Rwrite(Rmessage) : type = 119 def body_bytes(self) : bio = ByteIO(StringIO.StringIO()) bio.PBIT32(self.count) return bio def load_from_bytes(self, bytes) : self.count = bytes.GBIT32() def __str__(self) : base = Message.__str__(self) return "%s\n\tcount: %d" % (base, self.count) class Rremove(Rmessage) : type = 123 class Rwstat(Rmessage) : type = 127 Message_classes = { 0 : (None, 'None'), 100 : (Tversion, 'Tversion'), 101 : (Rversion, "Rversion"), 102 : (Tauth, "Tauth"), 103: (Rauth, "Rauth"), 104 : (Tattach, "Tattach"), 105 : (Rattach, "Rattach"), 106 : (Terror, "Terror"), 107 : (Rerror, "Rerror"), 108 : (Tflush, "Tflush"), 109 : (Rflush, "Rflush"), 110 : (Twalk, "Twalk"), 111 : (Rwalk, "Rwalk"), 112 : (Topen, "Topen"), 113 : (Ropen, "Ropen"), 114 : (Tcreate, "Tcreate"), 115 : (Rcreate, "Rcreate"), 116 : (Tread, "Tread"), 117 : (Rread, "Rread"), 118 : (Twrite, "Twrite"), 119 : (Rwrite, "Rwrite"), 120 : (Tclunk, "Tclunk"), 121 : (Rclunk, "Rclunk"), 122 : (Tremove, "Tremove"), 123 : (Rremove, "Rremove"), 124 : (Tstat, "Tstat"), 125 : (Rstat, "Rstat"), 126 : (Twstat, "Twstat"), 127 : (Rwstat , "Rwstat"), 128 : (None , "Tmax") } # get a message from an instance # bytes must have read/write methods # and for Tmessages bytes needs getvalue def get_message(fin) : # fin needs a read(n) global debug bytes = ByteIO(fin) m = None if bytes : try: size = bytes.GBIT32() typ = bytes.GBIT8() tag = bytes.GBIT16() except : return None if typ == 0 : return None m = Message_classes[typ][0](tag, size) if m : if 1: m.load(size, bytes) if debug : Errors.stderr("RX : %s" % str(m)) # except : # if debug : # Errors.stderr("Load failed") # return None else : if debug : Errors.stderr("Unknown message type") return None return m import Fid users = {} groups = {} def gid2group(i) : global groups if groups.has_key(i) : return groups[i] g = Group() g.getgrgid(i) if g.gid > -1 : groups[i] = g return g def uid2user(i) : global users if users.has_key(i) : return users[i] u = User() u.getpwuid(i) if u.uid > -1 : users[i] = u return u class Group : def __init__(self) : self.gid = -1 self.name = '' self.members = None def getgrgid(self, gid) : try : g = Fid.get_group_gid(gid) except : return None if len(g) > 0 : self.name = g[0] if len(g) > 2 : self.gid = g[2] if len(g) > 3 : self.members = g[3] return True class User : def __init__(self) : self.name = '' self.uid = -1 self.gid = -1 def getpwnam(self, name) : self.name = '' self.uid = -1 self.gid = -1 try : pw = Fid.get_pw_nam(name) except : return None if len(pw) > 0 : self.name = pw[0] if len(pw) > 2 : self.uid = pw[2] if len(pw) > 3 : self.gid = pw[3] return 1 def getpwuid(self, uid) : self.name = '' self.uid = -1 self.gid = -1 try : pw = Fid.get_pw_nam(uid) except : return None if len(pw) > 0 : self.name = pw[0] if len(pw) > 2 : self.uid = pw[2] if len(pw) > 3 : self.gid = pw[3] return 1 def __str__(self) : return("User: name: %s uid: %d gid: %d" % (self.name, self.uid, self.gid)) #!/usr/local/bin/python import plan9_client p9 = plan9_client.client('192.168.9.14', 'maht') p9.connect() f = p9.attach() nf = p9.walk(path='/home/maht/success.txt') p9.open(nf) data = p9.read_file(nf) print "YESS : %s" % data p9.close(nf) p9.disconnect()#!/usr/local/bin/python import plan9_client import sys import Settings_client import Dir plan9_client.set_settings(Settings_client) p9 = plan9_client.client('192.168.9.14', 'maht', 2001) p9.connect() f = p9.attach() nf = p9.walk(path="9load") if not nf : print "create" nf = p9.walk(path="/") print p9.create(nf, '9load', 0777, plan9_client.OWRITE) else : print "open" print p9.open(nf, plan9_client.OWRITE) if nf > 0 : p9.write(nf, data=open('/home/maht/py9p/9load').read()[29:32]) p9.close(nf) #nf = p9.walk(path="NOsuccess.txt") #if nf > 0 : # print "reading" # print p9.open(nf) # print p9.read(nf) # p9.close(nf) #nf = p9.walk(path="NOsuccess.txt") #print p9.wstat(nf, Dir.Dir(mode=0777, mtime=1000, length=99, filename='sw', gid='sys')) #p9.close(nf) #nf = p9.walk(path="success.txt") #if nf > 0 : # print p9.stat(nf) p9.disconnect() #!/usr/local/bin/python import plan9_client import sys import Settings_client import Dir plan9_client.set_settings(Settings_client) p9 = plan9_client.client('192.168.9.14', 'maht', 2101) p9.connect() print "attach" f = p9.attach() print "walk" nf = p9.walk(path="/") if nf : print "stat" print p9.stat(nf) print "close" p9.close(nf) print "disconnect" p9.disconnect() print "byr"#!/usr/local/bin/python import plan9_client p9 = plan9_client.client('192.168.9.68', 'maht', 2001) p9.connect() f = p9.attach() nf = p9.walk(path='e:\\Python\\pyn80.py') print p9.stat(nf) data = p9.read_file(nf) print "%s" % data p9.close(nf) p9.disconnect()import psycopg import string import time # Put def escape(txt) : if txt == None : return 'NULL' t = str(txt) return "'%s'" % t.replace("'", "''").replace('\\', '\\\\') def escape_bytea(txt, not_so_uber=False) : # uber safe return "'%s'::bytea" % reduce(lambda x,y : x + y, ['\\\\%s' % string.zfill(oct(ord(t))[1:], 3) for t in txt], "") def epoch_to_timestamp(e) : return time.strftime('%Y-%m-%d %H:%M:%S', e) class db : def __init__(self, dbname='www', user='www', host='momo', stderr=None) : self.debug = False self.stderr = stderr self.conn = psycopg.connect('host=%s dbname=%s user=%s' % (host, dbname, user)) def cursor(self) : return self.conn.cursor() def do_sql(self, sql, cursor=None) : if self.debug : if self.stderr : self.stderr("%s;" % sql) else : print sql if cursor == None : cursor = self.cursor() cursor.execute(sql) self.conn.commit() return cursor def sql_to_int(self, sql) : c = self.do_sql(sql) try : return int(c.fetchone()[0]) except : return 0 def sql_test(self, sql) : c = self.do_sql(sql) try : return c.fetchone()[0] except : return None def currval(self, seq) : return self.sql_to_int('SELECT currval(%s)' % escape(seq)) def currid(self, seq) : return self.currval(seq + '_id_seq') import db def bits_to_int(bits) : value = 0 while len(bits) > 0 : value = value << 1 if bits[0] == "1" : value += 1 bits = bits[1:] return value def str_to_qid(str) : qbits = str[1:-1].split(',') return pg_Qid(type=bits_to_int(qbits[0]), path=int(qbits[1]), vers=int(qbits[2])) def row_to_dir(row) : return Dir.Dir(filename=row[0], type=bits_to_int(row[1]), dev=row[2], qid=str_to_qid(row[3]), mode=bits_to_int(row[4]), atime=row[5], mtime=row[6], length=row[7], uid=row[8], gid=row[9], muid=row[10]) class fiddb(db.db) : def __init__(self, dbname='pgfs', user='pgfs', host='momo', attach_qid=pg_Qid(type=128,path=1,vers=0)) : db.db.__init__(self, dbname=dbname, user=user, host=host, stderr=Errors.stderr) self.attach_id = 0 self.attached_fid = 0 self.root_qid = attach_qid self.debug = True self.stderr=Errors.stderr def sql_to_qids(self, sql) : c = self.do_sql("SELECT %s" % sql) qids = [] if c : r = c.fetchone() while r and r[0]: qids.append(str_to_qid(r[0])) r = c.fetchone() if len(qids) > 0 : return qids def sql_to_dirs(self, sql) : c = self.do_sql("SELECT name, type, dev, q, mode, extract(epoch from atime), extract(epoch from mtime), length, uid, gid, muid %s" % sql) if c : return [row_to_dir(x) for x in c.fetchall()] def attach_fid(self, fid, afid, uname, aname) : self.attach_id = self.sql_to_int("SELECT attach(%d, %d, %s, %s, %s)" % (fid, afid, db.escape(uname), db.escape(aname), db.escape(self.root_qid))) if self.attach_id > 0 : self.attached_fid = fid return self.root_qid def disconnect(self) : self.do_sql("SELECT disconnect(%d)" % self.attached_fid); def lookup_file(self, q, path) : qids = self.sql_to_qids("lookup_file(%s, %s)" % (db.escape(q), db.escape(path))) if qids : return qids[0] def lookup_qid(self, fid) : qids = self.sql_to_qids("lookup_qid(%d, %d)" % (self.attach_id, fid)) if qids : return qids[0] def lookup_fid(self, fid) : if self.lookup_qid(fid) : return Fid(fid=fid) def new_fid(self, fid=1, clone_from=0, qid=None) : if qid == None : if clone_from == 0 : clone_from = self.attached_fid qid = self.lookup_qid(clone_from) if qid : return self.sql_to_int("SELECT new_fid(%d, %d, %s)" % (self.attach_id, fid, db.escape(qid))) def clunk_fid(self, fid=0) : self.do_sql("SELECT clunk_fid(%d, %d)" % (self.attach_id, fid)) def walk(self, fid, qid) : self.do_sql("UPDATE fid SET q=%s WHERE attach_id=%d and id=%d" % (self.attach_id, fid, db.escape(qid))) def is_dir(self, fid=0) : return self.sql_to_int("SELECT ((q).type & x'80')::INTEGER FROM fid WHERE attach_id=%d and id=%d" % (self.attach_id, fid)) > 0 def create(self, fid, name, perm, mode) : perm_h = (perm >>4 ) & 0x8000 perm_l = perm & 0x0000ffff qids = self.sql_to_qids("createfilepy(%d, %d, %s, x'%x', x'%x', x'%x')" % (self.attach_id, fid, db.escape(name), perm_h, perm_l, mode)) if qids : return qids[0] def open(self, fid, mode) : qids = self.sql_to_qids("open(%d, %d, x'%x')" % (self.attach_id, fid, mode)) if qids : return qids[0] def dir(self, fid) : dirs = self.sql_to_dirs("FROM file WHERE q=(SELECT q FROM fid WHERE attach_id=%d AND id=%d)" % (self.attach_id, fid)) if dirs : return dirs[0] def read(self, fid, offset, count) : c = self.do_sql("SELECT read(%d, %d, %d, %d)" % (self.attach_id, fid, offset, count)) if c : one = c.fetchone(); if one and len(one) > 0 and one[0] > 0 : return (None, one[0]) return (Errors.Eperm, None) return (Errors.Enotfound, None) def write(self, fid, offset, count, data) : return self.sql_to_int("SELECT write(%d, %d, %d, %d, %s)" % (self.attach_id, fid, offset, count, db.escape_bytea(data))) def wstat(self, fid, dir) : return self.sql_to_int("SELECT wstat(%d, %d, (%s)::bit(32), %s, %d, %s, %s)" % (self.attach_id, fid, dir.mode, db.epoch_to_timestamp(dir.mtime), dir.length, db.escape(dir.name), db.escape(dir.gid))) def list_dir(self, fid) : return self.sql_to_dirs("FROM ls WHERE q=(SELECT q FROM fid WHERE attach_id=%d AND id=%d) AND ls.entry != ls.q" % (self.attach_id, fid)) ÿþ# # filebrowser.py # # A very simple file browser script to demonstrate the power of Python # on Series 60. # # 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 os import appuifw import e32 import dir_iter class Filebrowser: def __init__(self): self.script_lock = e32.Ao_lock() self.dir_stack = [] self.current_dir = dir_iter.Directory_iter(e32.drive_list()) def run(self): from key_codes import EKeyLeftArrow entries = self.current_dir.list_repr() if not self.current_dir.at_root: entries.insert(0, (u"..", u"")) self.lb = appuifw.Listbox(entries, self.lbox_observe) self.lb.bind(EKeyLeftArrow, lambda: self.lbox_observe(0)) old_title = appuifw.app.title self.refresh() self.script_lock.wait() appuifw.app.title = old_title appuifw.app.body = None self.lb = None def refresh(self): appuifw.app.title = u"File browser" appuifw.app.menu = [] appuifw.app.exit_key_handler = self.exit_key_handler appuifw.app.body = self.lb def do_exit(self): self.exit_key_handler() def exit_key_handler(self): appuifw.app.exit_key_handler = None self.script_lock.signal() def lbox_observe(self, ind = None): if not ind == None: index = ind else: index = self.lb.current() focused_item = 0 if self.current_dir.at_root: self.dir_stack.append(index) self.current_dir.add(index) elif index == 0: # ".." selected focused_item = self.dir_stack.pop() self.current_dir.pop() elif os.path.isdir(self.current_dir.entry(index-1)): self.dir_stack.append(index) self.current_dir.add(index-1) else: item = self.current_dir.entry(index-1) if os.path.splitext(item)[1] == '.py': i = appuifw.popup_menu([u"execfile()", u"Delete"]) else: i = appuifw.popup_menu([u"Open", u"Delete"]) if i == 0: if os.path.splitext(item)[1].lower() == u'.py': execfile(item, globals()) self.refresh() #appuifw.Content_handler().open_standalone(item) else: try: appuifw.Content_handler().open(item) except: import sys type, value = sys.exc_info() [:2] appuifw.note(unicode(str(type)+'\n'+str(value)), "info") return elif i == 1: os.remove(item) focused_item = index - 1 entries = self.current_dir.list_repr() if not self.current_dir.at_root: entries.insert(0, (u"..", u"")) self.lb.set_list(entries, focused_item) if __name__ == '__main__': Filebrowser().run() #!/usr/local/bin/python import socket def myip(name) : s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('192.168.9.14', 7777)) s.send(name) return s.recv(255) import os import Dir try : from e32socket import * root = 'e:\\' except : root = '/' s = os.stat(root) d = Dir.dir_from_stat(root, s) print d print os.access(root, os.F_OK) # Put # python n80testsrc.pyimport db d = db.db(dbname='pgfs', user='maht') c = d.cursor() name = 'one' blob = 'abcd' d.do_sql("insert into tt values('zx', 'asx')") # python pgtest.py from socket import * import TR_message import StringIO import re import Socketfile OREAD = 0x00 OWRITE = 0x01 def set_settings(settings) : TR_message.settings = settings class client : msg_size = 8216 def __init__(self, host, username, port=564) : self.base_fid = 1 self.tag = None self.host = host self.username = username self.port = int(port) def __getattr__(self, attr) : if attr == 'next_tag' : if self.tag == None : self.tag = 0 else : self.tag += 1 return self.tag if attr == 'connected' : return self.io != None raise AttributeError, attr def connect(self) : s = socket(AF_INET, SOCK_STREAM) s.connect((self.host, self.port)) self.io = Socketfile.socketfile(s.recv, s.sendall) t = TR_message.Tversion(self.next_tag) t.msize = self.msg_size t.version = '9P2000' t.write_to(self.io) r = TR_message.get_message(self.io) if not r : raise "No reply was all he said" if r.version != t.version : raise '9P Version mismatch', 'I can only do 9p2000' return r def attach(self, afid=0, aname='') : if not self.connected : return None t = TR_message.Tattach(self.next_tag) t.fid = self.base_fid t.afid = afid t.uname = self.username t.aname = aname t.write_to(self.io) r = TR_message.get_message(self.io) return r def walk(self, fid=0, path='/') : if fid == 0 : fid = self.base_fid t = TR_message.Twalk(self.next_tag) cloned = TR_message.settings.clone_fid(fid=fid, path=path) if not cloned : return 0 t.fid = fid t.newfid = cloned.fid cpath = filter(lambda x : x != '', cloned.path.split('/')) if len(cpath) == 0 : cpath.append('/') t.wname = cpath t.write_to(self.io) r = TR_message.get_message(self.io) if r and r.type != TR_message.Rerror.type : return cloned.fid def open(self, fid, mode=OREAD) : t = TR_message.Topen(self.next_tag) t.fid = fid t.mode = mode t.write_to(self.io) r = TR_message.get_message(self.io) return r def stat(self, fid) : t = TR_message.Tstat(self.next_tag) t.fid = fid t.write_to(self.io) r = TR_message.get_message(self.io) return r def wstat(self, fid, dir) : t = TR_message.Twstat(self.next_tag) import Errors Errors.stderr("DIRR %s" % (str(dir))) t.fid = fid t.stat = dir.D2M() t.write_to(self.io) r = TR_message.get_message(self.io) return r def close(self, fid) : t = TR_message.Tclunk(self.next_tag) t.fid = fid t.write_to(self.io) r = TR_message.get_message(self.io) TR_message.settings.clunk_fid(fid) def write(self, fid, blocksize=4096, offset=0, count=None, data=None) : if count == None : count = len(data) if count == 0 : return 0 t = TR_message.Twrite(self.next_tag) t.fid = fid t.offset = offset t.count = min(count, min(blocksize, len(data))) t.data = data[0:t.count] if t.count > 0 : t.write_to(self.io) r = TR_message.get_message(self.io) return t.count + self.write(fid, blocksize=blocksize, offset=offset+t.count, data = data[t.count:], count=count-t.count) return 0 def read(self, fid, blocksize=4096, offset=0, count=None) : if count == 0 : return "" t = TR_message.Tread(self.next_tag) t.fid = fid t.offset = offset if count == None : t.count = blocksize else : t.count = min(count, blocksize) t.write_to(self.io) r = TR_message.get_message(self.io) if not r or r.type == TR_message.Rerror.type : return "" if len(r.data) == 0 : return "" if count == None : return r.data + self.read(fid, blocksize=blocksize, offset=offset+len(r.data)) else : return r.data + self.read(fid, blocksize=blocksize, offset=offset+len(r.data), count=count-len(r.data)) def read_dir(self, blocksize=4096) : stat_data = self.read_file(blocksize) stat_bytes = ByteIO.ByteIO(StringIO.StringIO(stat_data)) stat_bytes.debug=0 stats = [] try : while 1 : st = TR_message.Rstat() st.load_from_stat_bytes(stat_bytes) stats.append(st) except : pass return stats def disconnect(self) : self.close(self.base_fid) def create(self, fid, name, mode, omode) : t = TR_message.Tcreate(self.next_tag) t.fid = fid t.name = name t.perm = mode t.mode = omode t.write_to(self.io) r = TR_message.get_message(self.io) if not r or r.type == TR_message.Rerror.type : return None return r.qid #!/usr/local/bin/rc tcpserver 192.168.9.14 2101 /home/maht/py9p/srv.py #tcpserver 192.168.9.14 2001 python /home/maht/py9p/9pm/pyn80.py #DIR read through Tread is always a directory #Rstat came back correct #!/usr/local/bin/python import sys import TR_message import myip import Errors import Socketfile import os import Settings_psql TR_message.settings = Settings_psql disconnected = Settings_psql.disconnected #import Settings_ufs #TR_message.settings = Settings_ufs port = 0 try : from e32socket import * port = 564 except : if not 'TCPREMOTEIP' in os.environ : from socket import * port = 2100 def ascertain_accept(port) : if 'TCPREMOTEIP' in os.environ : return None s = socket(AF_INET, SOCK_STREAM) ip = myip.myip('n80') s.bind((ip, port)) s.listen(1) Errors.stderr("Listening on tcp!%s!%d" % (ip, port)) return s.accept def msg_loop(src) : msg = TR_message.get_message(src); while msg : r = msg.get_Rmessage() r.write_to(src) msg = TR_message.get_message(src); disconnected() def accept_loop(accept) : while 1: conn, addr = accept() Errors.stderr("Accepted from %s" % str(addr)) src = Socketfile.socketfile(conn.recv, conn.sendall) msg_loop(src) def single_conversation(accept) : import sys msg_loop(Socketfile.socketfile(sys.stdin.read, sys.stdout.write, sys.stdout.flush)) accept = ascertain_accept(port) if accept : run = accept_loop else : run = single_conversation #try : if 1: run(accept) #except : # Errors.stderr(str(sys.exc_info()[0])) #!/usr/local/bin/python import sys import TR_message import myip import Errors import Socketfile import os import Settings_n80 TR_message.settings = Settings_n80 disconnected = Settings_n80.disconnected port = 0 try : from e32socket import * port = 564 except : if not 'TCPREMOTEIP' in os.environ : from socket import * port = 2100 def ascertain_accept(port) : if 'TCPREMOTEIP' in os.environ : return None s = socket(AF_INET, SOCK_STREAM) ip = myip.myip('n80') s.bind((ip, port)) s.listen(1) Errors.stderr("Listening on tcp!%s!%d" % (ip, port)) return s.accept def msg_loop(src) : msg = TR_message.get_message(src); while msg : r = msg.get_Rmessage() r.write_to(src) msg = TR_message.get_message(src); disconnected() def accept_loop(accept) : while 1: conn, addr = accept() Errors.stderr("Accepted from %s" % str(addr)) src = Socketfile.socketfile(conn.recv, conn.sendall) msg_loop(src) def single_conversation(accept) : import sys msg_loop(Socketfile.socketfile(sys.stdin.read, sys.stdout.write, sys.stdout.flush)) accept = ascertain_accept(port) if accept : run = accept_loop else : run = single_conversation #try : if 1: run(accept) #except : # Errors.stderr(str(sys.exc_info()[0])) #!/usr/local/bin/python import sys import TR_message import myip import Errors import Socketfile import os import Settings_ufs TR_message.settings = Settings_ufs disconnected = Settings_ufs.disconnected port = 0 try : from e32socket import * port = 1564 except : if not 'TCPREMOTEIP' in os.environ : from socket import * port = 564 def ascertain_accept(port) : if 'TCPREMOTEIP' in os.environ : return None s = socket(AF_INET, SOCK_STREAM) ip = '127.0.0.1' s.bind((ip, port)) s.listen(1) Errors.stderr("Listening on tcp!%s!%d" % (ip, port)) return s.accept def msg_loop(src) : msg = TR_message.get_message(src); while msg : r = msg.get_Rmessage() r.write_to(src) msg = TR_message.get_message(src); disconnected() def accept_loop(accept) : while 1: conn, addr = accept() Errors.stderr("Accepted from %s" % str(addr)) src = Socketfile.socketfile(conn.recv, conn.sendall) msg_loop(src) def single_conversation(accept) : import sys msg_loop(Socketfile.socketfile(sys.stdin.read, sys.stdout.write, sys.stdout.flush)) accept = ascertain_accept(port) if accept : run = accept_loop else : run = single_conversation #try : if 1: run(accept) #except : # Errors.stderr(str(sys.exc_info()[0])) import string def pgoct(x) : # if ord(x) == 0 : return '\\\\000' o = return def escape_bytea(txt, not_so_uber=False) : # uber safe return "'%s'::bytea" % reduce(lambda x,y : x + y, ['\\\\%s' % string.zfill(oct(ord(t))[1:], 3).replace('134', '\\\\\\') for t in txt], "") data = open("/home/maht/py9p/9load").read()[29:32] for c in data : print ord(c) print escape_bytea(data) # Put python test.py"KKk !2"KKk !2(²²k Dir.py*..k  Errors.py.k  Fid_client.py,« «k  Fid_n80.py,ð ðk  Fid_psql.py,eek  Fid_ufs.py(""HHk  New.py(##__k "Qid.py4$$ššk $Settings_client.py0%%ýýk %Settings_n80.py2&&ÿÿk &Settings_psql.py0''þþk 'Settings_ufs.py.((Y Yk ( Socketfile.py.**¦FF¦k * TR_message.py(33ppk -User.py*44k . client.py.55[[k / client2001.py.66††k 1 client2100.py077k 2client682001.py&88$$k 3db.py*99,,k 5fiddb.py0<<  k 6filebrowser.py(@@¶¶k 7myip.py.AAÕÕk 8 n80testsrc.py*BBžžk 9 pgtest.py0CCk :plan9_client.py$FFÔÔk ;srv(GGk srv.py*HHÔÔk  srvN80.py*IIÏÏk  srvUFS.py(JJ››k test.pyKK