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"); } } }