示例#1
0
        public static void Main(string[] args)
        {
            //SERVER CODE: if you want the client, comment until CLIENT CODE
            ninepc.ninep protocol;
            protocol = new ninepc.ninep();
            string clientname = "unset";
            //string cmd, server;
            TcpListener server = protocol.serve(9999);



            Inode root = createnode("/", 0x00000755, "jeb", "kerman", (byte)proto.QTDIR);

            root.data = new Byte[0];


            Inode testdir = createnode("testdir", 0x00000755, "jeb", "kerman", (byte)proto.QTDIR);

            testdir.data   = new Byte[0];
            testdir.parent = root;
            root.children.Add(testdir);


            Qid[] wqid = new Qid[10];              //max number of walks... increase if needed.


            UTF8Encoding utf8 = new UTF8Encoding();

            Byte[] strdata = utf8.GetBytes("This is the file contents");
            Inode  child   = createnode("test", 0x00000755, "valerie", "kerman", (byte)proto.QTFILE);

            child.data       = strdata;
            child.dir.length = (ulong)strdata.Length;
            child.dir.qid.vers++;
            testdir.children.Add(child);
            child.parent = testdir;


            server.Start();
            //ep = new IPEndPoint(addr[0], port);
            while (true)
            {
                TcpClient client = protocol.AcceptTcpClient(server);
                while (client.Connected)
                {
                    protocol.recieve(client);
                    printPacket(protocol.pktT, "T");
                    ushort tag = protocol.fT.tag;
                    int    fid = protocol.fT.fid;
                    switch (protocol.fT.type)
                    {
                    case (byte)proto.Tstat:
                        Inode statnode;
                        if (!fidlist.TryGetValue(fid, out statnode))
                        {
                            protocol.doRerror(tag, "unrecognized fid");
                        }
                        protocol.doRstat(tag, statnode.dir);
                        break;

                    case (byte)proto.Topen:
                        Inode opnode;
                        if (!fidlist.TryGetValue(fid, out opnode))
                        {
                            protocol.doRerror(tag, "unrecognized fid");
                        }
                        //permissions stuff goes here
                        opnode.mode = protocol.fT.mode;
                        protocol.doRopen(tag, opnode.dir.qid, protocol.mmsgsz);
                        break;

                    case (byte)proto.Tread:
                        Inode  rnode;
                        uint   count;
                        Byte[] data;
                        if (!fidlist.TryGetValue(fid, out rnode))
                        {
                            protocol.doRerror(tag, "unrecognized fid");
                        }
                        count = protocol.fT.count;
                        if (count + protocol.fT.offset > rnode.dir.length)
                        {
                            count = (uint)rnode.dir.length - (uint)protocol.fT.offset;
                        }
                        if (rnode.dir.qid.type == (byte)proto.QTDIR)
                        {
                            List <Byte[]> dirdata = new List <Byte[]> ();
                            int           len     = 0;
                            foreach (Inode i in rnode.children)
                            {
                                Byte[] temp = new Byte[protocol.sizeD2M(i.dir)];
                                protocol.convD2M(i.dir, temp);
                                //printPacket (temp, "D");
                                len += temp.Length;
                                dirdata.Add(temp);
                            }
                            data = new Byte[len];
                            int pp = 0;
                            foreach (Byte[] b in dirdata)
                            {
                                System.Buffer.BlockCopy(b, 0, data, pp, b.Length);
                                pp += b.Length;
                            }
                            protocol.doRread(tag, (uint)data.Length, data);
                        }
                        else
                        {
                            if (count > 0)
                            {
                                data = new Byte[count];
                                Array.Copy(rnode.data, (int)protocol.fT.offset, data, 0, count);
                                protocol.doRread(tag, count, data);
                            }
                            else
                            {
                                protocol.doRread(tag, 0, new Byte[0]);
                            }
                        }
                        break;

                    case (byte)proto.Tauth:
                        clientname = protocol.fT.uname;
                        protocol.doRerror(tag, "u9fs authnone: no authentication required");
                        break;

                    case (byte)proto.Tattach:

                        if (protocol.fT.aname.Equals(""))
                        {
                            if (fidlist.ContainsKey(fid) == false)
                            {
                                fidlist.Add(fid, root);
                                protocol.doRattach(tag, root.dir.qid);
                            }
                            else
                            {
                                protocol.doRerror(tag, "Fid currently in use");
                            }
                        }
                        printfidlist();
                        break;

                    case (byte)proto.Tclunk:
                        if (listclunk(fid))
                        {
                            Console.WriteLine("clunked fid:{0}", fid);
                            protocol.doRclunk(tag, fid);
                        }
                        else
                        {
                            protocol.doRerror(tag, "Unrecognized fid");
                        }
                        printfidlist();
                        break;

                    case (byte)proto.Twalk:
                        Inode  cfidnode;
                        Inode  wfidnode;
                        ushort nwqid = 0;
                        if (fidlist.TryGetValue(fid, out cfidnode) == false)
                        {
                            protocol.doRerror(tag, "Unrecognized fid");
                            break;
                        }
                        else if (fidlist.ContainsKey(protocol.fT.newfid))
                        {
                            //protocol.doRerror (tag, protocol.fT.tag, "New fid already in use");
                            listclunk(fid);
                            break;
                        }
                        if (protocol.fT.nwname > 0)
                        {
                            //walk throught the file tree, creating qid's
                            wfidnode = cfidnode;

                            for (nwqid = 0; nwqid < protocol.fT.nwname; nwqid++, cfidnode = wfidnode)
                            {
                                Console.WriteLine("nwname={0}, wname={1}", protocol.fT.nwname, protocol.fT.wname [nwqid]);
                                if (walkChild(cfidnode, protocol.fT.wname [nwqid], out wfidnode))
                                {
                                    //Console.WriteLine ("Walkchild succeeded");
                                    wqid [nwqid] = wfidnode.dir.qid;
                                }
                                else if (nwqid == 0)
                                {
                                    protocol.doRerror(tag, "first nwname walk failed");
                                    //Console.WriteLine ("first nwname walk failed");
                                    break;
                                }
                            }
                            // take the last successful walk and make that the new fid.
                            fidlist.Add(protocol.fT.newfid, wfidnode);
                        }
                        else                             // simply create a new fid for the current file
                        {
                            fidlist.Add(protocol.fT.newfid, cfidnode);
                            nwqid    = 1;
                            wqid [0] = cfidnode.dir.qid;
                        }
                        printfidlist();
                        protocol.doRwalk(tag, nwqid, wqid);

                        break;

                    case (byte)proto.Tremove:
                        Inode rfidnode;
                        if (fidlist.TryGetValue(fid, out rfidnode) == false)
                        {
                            protocol.doRerror(tag, "Unrecognized fid");
                            break;
                        }
                        if (delnode(rfidnode.parent, rfidnode.dir.name))
                        {
                            listclunk(fid);
                            protocol.doRremove(tag);
                        }
                        break;

                    case (byte)proto.Tversion:
                        if (protocol.fT.version.Equals("9P2000"))
                        {
                            protocol.doRversion(tag);
                        }
                        else
                        {
                            protocol.doRerror(tag, "Version :" + protocol.fT.version + " not supported.");
                        }

                        break;

                    case (byte)proto.Tflush:
                        //do nothing
                        protocol.doRflush(tag);
                        break;

                    case (byte)proto.Tcreate:
                        Inode dirnode;
                        if (fidlist.TryGetValue(fid, out dirnode) == false)
                        {
                            protocol.doRerror(tag, "Unrecognized fid");
                            break;
                        }
                        byte type = (byte)proto.QTFILE;
                        Console.WriteLine("perm = {0}", BitConverter.ToString((BitConverter.GetBytes(protocol.fT.perm))));
                        if ((protocol.fT.perm & (uint)proto.DMDIR) != 0)
                        {
                            type = (byte)proto.QTDIR;
                            Console.WriteLine("Created Directory");
                        }
                        Inode newfile = createnode(protocol.fT.name, protocol.fT.perm, clientname, "client", type);
                        dirnode.children.Add(newfile);
                        newfile.parent = dirnode;
                        newfile.mode   = protocol.fT.mode;
                        newfile.data   = new Byte[0];
                        protocol.doRcreate(tag, new Qid(), protocol.mmsgsz);
                        break;

                    case (byte)proto.Twstat:
                        Inode wnode;
                        Dir   tdir;
                        if (fidlist.TryGetValue(fid, out wnode) == false)
                        {
                            protocol.doRerror(tag, "Unrecognized fid");
                            break;
                        }
                        tdir      = protocol.convM2D(protocol.fT.stat, 0);
                        wnode.dir = tdir;                         // some permissions stuff should precede this.
                        protocol.doRwstat(tag);
                        break;

                    case (byte)proto.Twrite:
                        Inode wrnode;
                        if (fidlist.TryGetValue(fid, out wrnode) == false)
                        {
                            protocol.doRerror(tag, "Unrecognized fid");
                            break;
                        }
                        if (wrnode.mode.Equals((uint)proto.OREAD))
                        {
                            protocol.doRerror(tag, "File not opened for writing");
                            break;
                        }
                        int woffset = (int)protocol.fT.offset;
                        if ((wrnode.mode & (uint)proto.OAPPEND) > 0)
                        {
                            woffset = (int)wrnode.data.Length;
                        }
                        if (woffset > (int)wrnode.data.Length)
                        {
                            protocol.doRerror(tag, "offset out of bounds");
                            break;
                        }
                        Byte[] newdata = new Byte[woffset + (int)protocol.fT.count];
                        Array.Copy(wrnode.data, 0, newdata, 0, woffset);                          //copy existing data before offset
                        Array.Copy(protocol.fT.data, 0, newdata, woffset, protocol.fT.count);
                        wrnode.data          = newdata;
                        wrnode.dir.muid      = clientname;
                        wrnode.dir.mtime     = (uint)DateTime.Now.ToFileTime();
                        wrnode.dir.qid.vers += 1;
                        wrnode.dir.length    = (ulong)wrnode.data.Length;
                        protocol.doRwrite(tag, protocol.fT.count);
                        Console.WriteLine("new contents:{0}", BitConverter.ToString(wrnode.data, 0, wrnode.data.Length));
                        break;

                    default:
                        throw new ninepexception("unrecognized message type");
                    }
                    printPacket(protocol.pktR, "R");
                }
            }
        }