예제 #1
0
    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)
예제 #2
0
    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)
예제 #3
0
    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)
예제 #4
0
    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)
예제 #5
0
    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)
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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)