def serve(self, host, port): s = socket.socket() s.bind((host, port)) s.listen(1) while True: conn, client = s.accept() self.clients[client] = self.store while client in self.clients: message = styx.decode(sock=conn) try: handler = self.handlers[message.code] reply = handler(self, client, message) except KeyError: reply = styx.Rerror(message.tag, "Unsupported message.") except StyxServerError as e: reply = styx.Rerror(message.tag, e.message) except socket.error: # The connection was probably closed by the client. break reply.encode(conn)
def Twrite(self, client, msg): store = self.clients[client] # The fid must have an existing qid. count = store.write(msg.fid, msg.offset, msg.data) if count == -1: return styx.Rerror(msg.tag, "Not a file.") elif count != len(msg.data): return styx.Rerror(msg.tag, "Failed to write data.") return styx.Rwrite(msg.tag, count)
def Tcreate(self, client, msg): store = self.clients[client] # The fid must have an existing qid that corresponds to a directory # and cannot be itself in use. qid, path = store.get_qid_path(msg.fid) new_qid = store.create(msg.fid, msg.name, msg.perm) if new_qid == False: return styx.Rerror(msg.tag, "Cannot create file.") # The fid now refers to the newly open file or directory. if not store.open(msg.fid, msg.mode): return styx.Rerror(msg.tag, "Cannot open file.") return styx.Rcreate(msg.tag, new_qid, self.MAX_MSG_SIZE)
def Tstat(self, client, msg): store = self.clients[client] s = store.stat(msg.fid) if s == None: return styx.Rerror(msg.tag, "Not found.") return styx.Rstat(msg.tag, s)
def Tattach(self, client, msg): store = self.clients[client] qid = store.get_root_qid(msg.fid, msg.afid, msg.uname, msg.aname) if qid == None: return styx.Rerror(msg.tag, "Root not found.") return styx.Rattach(msg.tag, qid)
def Topen(self, client, msg): store = self.clients[client] # The fid must have an existing qid. qid, path = store.get_qid_path(msg.fid) if not store.open(msg.fid, msg.mode): return styx.Rerror(msg.tag, "Cannot open file.") return styx.Ropen(msg.tag, qid, self.MAX_MSG_SIZE)
def Tremove(self, client, msg): store = self.clients[client] # Remove the file and clunk it whether the remove was successful or not. result = store.remove(msg.fid) if result == True: store.free_qid_path(msg.fid) return styx.Rremove(msg.tag) else: store.free_qid_path(msg.fid) return styx.Rerror(msg.tag, result)
def Twalk(self, client, msg): store = self.clients[client] # The fid must have an existing qid but not be in use for open or create. qid, path = store.get_qid_path(msg.fid) # Generate qids for each of the elements in the path, starting from the # path corresponding to the current fid. qids = [] new_path = path.split("/") for element in msg.wname: if element == "..": # Handle parent directories as path elements. if new_path: new_path.pop() else: new_path.append(element) # Update the qid variable, create qids for each intermediate # path, and record the qids created. qid = store.make_qid("/".join(new_path)) if qid == None: if len(qids) > 0: return styx.Rwalk(msg.tag, qids) else: return styx.Rerror(msg.tag, "Not found.") qids.append(qid) # Set the qid and path for the newfid passed by the caller. store.set_qid_path(msg.newfid, qid, "/".join(new_path)) return styx.Rwalk(msg.tag, qids)