C# files (9pc 2.0)

The file Main.cs has been updated for naming rule violations, to add [Serializable] to Ninepexception, and for the obsoleted 'Dns.Resolve(string)'.

C:\Users\Eric\Documents\Visual Studio 2017\Projects\9pc>TYPE AssemblyInfo.cs
using System.Reflection;
using System.Runtime.CompilerServices;

// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.

[assembly: AssemblyTitle("")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]

// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):

[assembly: AssemblyVersion("1.0.*")]

// The following attributes specify the key for the sign of your assembly. See the
// .NET Framework documentation for more information about signing.
// This is not required, if you don't want signing let these attributes like they're.
[assembly: AssemblyDelaySign(false)]
[assembly: AssemblyKeyFile("")]

C:\Users\Eric\Documents\Visual Studio 2017\Projects\9pc>

C:\Users\Eric\Documents\Visual Studio 2017\Projects\9pc>TYPE Main.cs
/*
 * Copy me if you can.
 * by 20h
 */

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;

namespace ninepc
{
        public enum Proto : uint {
                Blocksize =             65536,

                Tversion =              100,
                Rversion,
                Tauth,
                Rauth,
                Tattach,
                Rattach,
                Terror,
                Rerror,
                Tflush,
                Rflush,
                Twalk,
                Rwalk,
                Topen,
                Ropen,
                Tcreate,
                Rcreate,
                Tread,
                Rread,
                Twrite,
                Rwrite,
                Tclunk,
                Rclunk,
                Tremove,
                Rremove,
                Tstat,
                Rstat,
                Twstat,
                Rwstat,

                BIT64SZ =               8,
                BIT32SZ =               4,
                BIT16SZ =               2,
                BIT8SZ =                        1,
                QIDSZ =                 (BIT8SZ + BIT32SZ + BIT64SZ),

                MAXWELEM =              16,
                STATFIXLEN =            (BIT16SZ + QIDSZ + 5 * BIT16SZ + 4 * BIT32SZ + BIT64SZ),
                MAXPKTSIZE =            8192,
                IOHDRSIZE =                     (BIT8SZ + BIT16SZ + 3 * BIT32SZ + BIT64SZ),

                DMDIR =                         0x80000000,
                DMAPPEND =      0x40000000,
                DMEXCL =                        0x20000000,
                DMMOUNT =               0x10000000,
                DMAUTH =                        0x08000000,
                DMTMP =                 0x04000000,
                DMNONE =                        0xFC000000,
        }

        struct Qid {
                public ulong path;
                public uint vers;
                public byte type;
        }

        struct Dir {
                public int status;

                public ushort type;
                public uint dev;

                public Qid qid;
                public uint mode;
                public uint atime;
                public uint mtime;
                public ulong length;
                public string name;
                public string uid;
                public string gid;
                public string muid;
        }

        struct Fcall {
                public int status;

                public byte type;
                public int fid;
                public ushort tag;

                public uint msize;
                public string version;

                public ushort oldtag;

                public string ename;

                public Qid qid;
                public uint iounit;

                public Qid aqid;

                public int afid;
                public string uname;
                public string aname;

                public uint perm;
                public string name;
                public byte mode;

                public int newfid;
                public ushort nwname;
                public string[] wname;

                public ushort nwqid;
                public Qid[] wqid;

                public ulong offset;
                public uint count;
                public Byte[] data;

                public ushort nstat;
                public Byte[] stat;
        }

        [Serializable]
    class Ninepexception : Exception
        {
                public Ninepexception(string str)
                {
                        Console.WriteLine("9P error: {0}", str);
                }
        }

        class Ninep
        {
                Socket sock;
                public Fcall fin;
                public Fcall fout;

                public Dir dir;

                public Byte[] pktin;
                public Byte[] pktout;

                public Byte[] readbuf;

                public ushort tag;
                public int root;
                public int afid;
                public int cwd;
                public int fid;
                public int ffid;

                public string uname;
                public string aname;

                public uint mmsgsz;
                public uint mdatasz;

                public string Modestr(uint mode)
                {
                        string[] bits;
                        string d;

                        bits = new string[8] {"---", "--x", "-w-", "-wx", "r--", "r-x", "rw-", "rwx"};
                        d = "";
                        if((mode & (uint)Proto.DMDIR) > 0)
                                d += "d";
                        if((mode & (uint)Proto.DMAPPEND) > 0)
                                d += "a";
                        if((mode & (uint)Proto.DMEXCL) > 0)
                                d += "e";
                        if((mode & (uint)Proto.DMMOUNT) > 0)
                                d += "m";
                        if((mode & (uint)Proto.DMAUTH) > 0)
                                d += "u";
                        if((mode & (uint)Proto.DMTMP) > 0)
                                d += "t";
                        if((mode & (uint)Proto.DMNONE) == 0)
                                d = "-";

                        return string.Format(null, "{0}{1}{2}{3}", new Object[] {d, bits[(mode >> 6) & 0x07],
                                                                bits[(mode >> 3) & 0x07], bits[mode & 0x07]});
                }

                public void Connect(string host, int port)
                {
                        IPHostEntry iphost;
                        IPAddress[] addr;
                        EndPoint ep;

                        tag = 10;
                        root = 9;
                        afid = -1;
                        cwd = 7;
                        fid = 6;
                        ffid = 5;
                        mmsgsz = (uint)Proto.MAXPKTSIZE;
                        mdatasz = mmsgsz - (uint)Proto.IOHDRSIZE;

                        uname = "andrey";
                        aname = "";

                        fin = new Fcall();
                        pktin = new Byte[mmsgsz];

                        iphost = Dns.GetHostEntry(host);
                        addr = iphost.AddressList;
                        ep = new IPEndPoint(addr[0], port);

                        sock = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp);
                        try {
                                sock.Connect(ep);
                                Console.WriteLine("Connected");
                        } catch(Exception ex) {
                                throw new Ninepexception(ex.ToString());
                        }
                }

                public void Shutdown()
                {
                        sock.Shutdown(SocketShutdown.Both);
                        sock.Close();
                        Console.WriteLine("Disconnected");
                }

                public ulong Getulong(Byte[] data, uint dp)
                {
                        return BitConverter.ToUInt64(data, (int)dp);
                }

                public uint Getuint(Byte[] data, uint dp)
                {
                        return BitConverter.ToUInt32(data, (int)dp);
                }

                public ushort Getushort(Byte[] data, uint dp)
                {
                        return BitConverter.ToUInt16(data, (int)dp);
                }

                public string Getstring(Byte[] data, uint dp)
                {
                        ushort len;
                        char[] strdata;
                        string ret;
                UTF8Encoding utf8;

                utf8 = new UTF8Encoding();

                        len = Getushort(data, dp);
                        dp += (uint)Proto.BIT16SZ;

                        strdata = new char[utf8.GetCharCount(data, (int)dp, (int)len)];
                        utf8.GetChars(data, (int)dp, (int)len, strdata, 0);
                        ret = new string(strdata);

                        return ret;
                }

                public string Convstring(Byte[] data)
                {
                        char[] strdata;
                        string ret;
                UTF8Encoding utf8;

                utf8 = new UTF8Encoding();

                        strdata = new char[utf8.GetCharCount(data, 0, data.Length)];
                        utf8.GetChars(data, 0, data.Length, strdata, 0);
                        ret = new string(strdata);

                        return ret;
                }

                public Qid Getqid(Byte[] data, uint dp)
                {
                        Qid q;

                        q.type = data[dp];
                        dp += (uint)Proto.BIT8SZ;
                        q.vers = Getuint(data, dp);
                        dp += (uint)Proto.BIT32SZ;
                        q.path = Getulong(data, dp);
                        dp += (uint)Proto.BIT64SZ;

                        return q;
                }

                public void Putulong(Byte[] data, uint dp, ulong var)
                {
                        Byte[] datavar;

                        datavar = BitConverter.GetBytes(var);
                        Array.Copy(datavar, 0, data, dp, (uint)datavar.Length);
                }

                public void Putuint(Byte[] data, uint dp, uint var)
                {
                        Byte[] datavar;

                        datavar = BitConverter.GetBytes(var);
                        Array.Copy(datavar, 0, data, dp, (uint)datavar.Length);
                }

                public void Putushort(Byte[] data, uint dp, ushort var)
                {
                        Byte[] datavar;

                        datavar = BitConverter.GetBytes(var);
                        Array.Copy(datavar, 0, data, dp, (uint)datavar.Length);
                }

                public void Putstring(Byte[] data, uint dp, string var)
                {
                        Byte[] strdata;
                UTF8Encoding utf8;

                utf8 = new UTF8Encoding();

                        Putushort(data, dp, (ushort)var.Length);
                        dp += (uint)Proto.BIT16SZ;

                        strdata = utf8.GetBytes(var);
                        Array.Copy(strdata, 0, data, dp, (uint)strdata.Length);
                }

                public void Putqid(Byte[] data, uint dp, Qid q)
                {
                        data[dp] = q.type;
                        dp += (uint)Proto.BIT8SZ;
                        Putuint(data, dp, q.vers);
                        dp += (uint)Proto.BIT32SZ;
                        Putulong(data, dp, q.path);
                        dp += (uint)Proto.BIT64SZ;
                }

                public Byte[] Recvn(int n)
                {
                        Byte[] data;
                        int r, i;

                        r = 0;
                        data = new Byte[n];

                        while(r < n) {
                                i = sock.Receive(data, r, data.Length - r, SocketFlags.None);
                                r += i;
                                if(i == 0)
                                        break;
                        }

                        return data;
                }

                public Byte[] Read9pmsg()
                {
                        Byte[] data, len, pkt;
                        uint pktlen;

                        len = Recvn((int)Proto.BIT32SZ);
                        pktlen = Getuint(len, 0);
                        if(pktlen - (int)Proto.BIT32SZ > mmsgsz)
                                throw new Ninepexception("pkt too small");

                        data = Recvn((int)pktlen - (int)Proto.BIT32SZ);

                        pkt = new Byte[pktlen];
                        len.CopyTo(pkt, 0);
                        data.CopyTo(pkt, (int)Proto.BIT32SZ);

                        return pkt;
                }

                public void Send9pmsg(Byte[] pkt)
                {
                        int len;

                        len = (int)Getuint(pkt, 0);

                        try {
                                sock.Send(pkt, len, SocketFlags.None);
                        } catch(Exception ex) {
                                Console.WriteLine("Error send9pmsg: {0}", ex.ToString());
                                throw new Ninepexception("send9pmsg failed");
                        }
                }

                public Fcall ConvM2S(Byte[] pkt)
                {
                        Byte[] buf;
                        uint len, pp, i;
                        Fcall f;

                        f = new Fcall();
                        buf = new Byte[(int)Proto.BIT32SZ];
                        pp = 0;

                        if(pkt.Length < (int)Proto.BIT32SZ + (int)Proto.BIT8SZ + (int)Proto.BIT16SZ)
                                return f;
                        len = Getuint(pkt, 0);
                        if(len < (int)Proto.BIT32SZ + (int)Proto.BIT8SZ + (int)Proto.BIT16SZ)
                                return f;
                        pp += (uint)Proto.BIT32SZ;

                        f.type = pkt[pp];
                        pp += (uint)Proto.BIT8SZ;
                        Array.Copy(pkt, pp, buf, (uint)Proto.BIT32SZ - (uint)Proto.BIT16SZ, (uint)Proto.BIT16SZ);
                        f.tag = Getushort(pkt, pp);
                        pp += (uint)Proto.BIT16SZ;

                        switch(f.type) {
                        default:
                                return f;
                        case (byte)Proto.Tversion:
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                Array.Copy(pkt, pp, buf, (uint)Proto.BIT32SZ - (uint)Proto.BIT16SZ, (uint)Proto.BIT16SZ);
                                f.msize = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.version = Getstring(pkt, pp);
                                pp += (uint)f.version.Length;
                                break;
                        case (byte)Proto.Tflush:
                                if(pp + (uint)Proto.BIT16SZ > len)
                                        return f;
                                f.oldtag = Getushort(pkt, pp);
                                pp += (uint)Proto.BIT16SZ;
                                break;
                        case (byte)Proto.Tauth:
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.afid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.uname = Getstring(pkt, pp);
                                pp += (uint)f.uname.Length;
                                f.aname = Getstring(pkt, pp);
                                pp += (uint)f.aname.Length;
                                break;
                        case (byte)Proto.Tattach:
                                if(pp + (uint)Proto.BIT32SZ + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.afid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.uname = Getstring(pkt, pp);
                                pp += (uint)f.uname.Length;
                                f.aname = Getstring(pkt, pp);
                                pp += (uint)f.aname.Length;
                                break;
                        case (byte)Proto.Twalk:
                                if(pp + (uint)Proto.BIT32SZ + (uint)Proto.BIT32SZ + (uint)Proto.BIT16SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.newfid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.nwname = Getushort(pkt, pp);
                                if(f.nwname > (int)Proto.MAXWELEM)
                                        return f;
                                f.wname = new string[f.nwname];
                                for(i = 0; i < f.nwname; i++) {
                                        f.wname[i] = Getstring(pkt, pp);
                                        pp += (uint)f.wname[i].Length;
                                }
                                break;
                        case (byte)Proto.Topen:
                                if(pp + (uint)Proto.BIT32SZ + (uint)Proto.BIT8SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.mode = pkt[pp];
                                pp += (uint)Proto.BIT8SZ;
                                break;
                        case (byte)Proto.Tcreate:
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.name = Getstring(pkt, pp);
                                pp += (uint)f.name.Length;
                                if(pp + (uint)Proto.BIT32SZ + (uint)Proto.BIT8SZ > len)
                                        return f;
                                f.perm = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.mode = pkt[pp];
                                pp += (uint)Proto.BIT8SZ;
                                break;
                        case (byte)Proto.Tread:
                                if(pp + (uint)Proto.BIT32SZ + (uint)Proto.BIT64SZ + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.offset = Getulong(pkt, pp);
                                pp += (uint)Proto.BIT64SZ;
                                f.count = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Twrite:
                                if(pp + (uint)Proto.BIT32SZ + (uint)Proto.BIT64SZ + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.offset = Getulong(pkt, pp);
                                pp += (uint)Proto.BIT64SZ;
                                f.count = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                if(pp + f.count > len)
                                        return f;
                                f.data = new Byte[f.count];
                                Array.Copy(pkt, pp, f.data, 0, f.count);
                                pp += f.count;
                                break;
                        case (byte)Proto.Tclunk:
                        case (byte)Proto.Tremove:
                        case (byte)Proto.Tstat:
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Twstat:
                                if(pp + (uint)Proto.BIT32SZ + (uint)Proto.BIT16SZ > len)
                                        return f;
                                f.fid = (int)Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.nstat = Getushort(pkt, pp);
                                pp += (uint)Proto.BIT16SZ;
                                if(pp + f.nstat > len)
                                        return f;
                                f.stat = new Byte[f.nstat];
                                Array.Copy(pkt, pp, f.stat, 0, f.nstat);
                                pp += f.nstat;
                                break;

                        case (byte)Proto.Rversion:
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.msize = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                f.version = Getstring(pkt, pp);
                                pp += (uint)f.version.Length;
                                break;
                        case (byte)Proto.Rerror:
                                f.ename = Getstring(pkt, pp);
                                pp += (uint)f.ename.Length;
                                break;
                        case (byte)Proto.Rauth:
                                f.aqid = Getqid(pkt, pp);
                                pp += (uint)Proto.QIDSZ;
                                break;
                        case (byte)Proto.Rattach:
                                f.qid = Getqid(pkt, pp);
                                pp += (uint)Proto.QIDSZ;
                                break;
                        case (byte)Proto.Rwalk:
                                if(pp + (uint)Proto.BIT16SZ > len)
                                        return f;
                                f.nwqid = Getushort(pkt, pp);
                                pp += (uint)Proto.BIT16SZ;
                                if(f.nwqid > (int)Proto.MAXWELEM)
                                        return f;
                                f.wqid = new Qid[f.nwqid];
                                for(i = 0; i < f.nwqid; i++) {
                                        f.wqid[i] = Getqid(pkt, pp);
                                        pp += (uint)Proto.QIDSZ;
                                }
                                break;
                        case (byte)Proto.Ropen:
                        case (byte)Proto.Rcreate:
                                f.qid = Getqid(pkt, pp);
                                pp += (uint)Proto.QIDSZ;
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.iounit = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Rread:
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.count = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                if(pp + f.count > len)
                                        return f;
                                f.data = new Byte[f.count];
                                Array.Copy(pkt, pp, f.data, 0, f.count);
                                pp += f.count;
                                break;
                        case (byte)Proto.Rwrite:
                                if(pp + (uint)Proto.BIT32SZ > len)
                                        return f;
                                f.count = Getuint(pkt, pp);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Rclunk:
                        case (byte)Proto.Rremove:
                        case (byte)Proto.Rwstat:
                        case (byte)Proto.Rflush:
                                break;
                        case (byte)Proto.Rstat:
                                if(pp + (uint)Proto.BIT16SZ > len)
                                        return f;
                                f.nstat = Getushort(pkt, pp);
                                pp += (uint)Proto.BIT16SZ;
                                if(pp + f.nstat > len)
                                        return f;
                                f.stat = new Byte[f.nstat];
                                Array.Copy(pkt, pp, f.stat, 0, f.nstat);
                                pp += (uint)f.nstat;
                                break;
                        }

                        if(pp <= len)
                                f.status = 1;

                        return f;
                }

                public uint SizeS2M(Fcall f)
                {
                        uint n, i;

                        n = (uint)Proto.BIT32SZ + (uint)Proto.BIT8SZ + (uint)Proto.BIT16SZ;
                        switch(f.type) {
                        default:
                                return 0;
                        case (byte)Proto.Tversion:
                        case (byte)Proto.Rversion:
                                n += (uint)Proto.BIT32SZ + (uint)Proto.BIT16SZ + (uint)f.version.Length;
                                break;
                        case (byte)Proto.Tflush:
                                n += (uint)Proto.BIT16SZ;
                                break;
                        case (byte)Proto.Tauth:
                                n += (uint)Proto.BIT32SZ + 2 * (uint)Proto.BIT16SZ + (uint)f.uname.Length + (uint)f.aname.Length;
                                break;
                        case (byte)Proto.Tattach:
                                n += 2 * (uint)Proto.BIT32SZ + 2 * (uint)Proto.BIT16SZ + (uint)f.uname.Length + (uint)f.aname.Length;
                                break;
                        case (byte)Proto.Twalk:
                                n += 2 * (uint)Proto.BIT32SZ + (uint)Proto.BIT16SZ;
                                for(i = 0; i < f.nwname; i++)
                                        n += (uint)f.wname[i].Length + (uint)Proto.BIT16SZ;
                                break;
                        case (byte)Proto.Topen:
                                n += (uint)Proto.BIT32SZ + (uint)Proto.BIT8SZ;
                                break;
                        case (byte)Proto.Tcreate:
                                n += 2 * (uint)Proto.BIT32SZ + (uint)Proto.BIT8SZ + (uint)Proto.BIT16SZ + (uint)f.name.Length;
                                break;
                        case (byte)Proto.Twrite:
                                n += 2 * (uint)Proto.BIT32SZ + (uint)Proto.BIT64SZ + f.count;
                                break;
                        case (byte)Proto.Tread:
                                n += 2 * (uint)Proto.BIT32SZ + (uint)Proto.BIT64SZ;
                                break;
                        case (byte)Proto.Tclunk:
                        case (byte)Proto.Tremove:
                        case (byte)Proto.Tstat:
                        case (byte)Proto.Rwrite:
                                n += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Twstat:
                                n += (uint)Proto.BIT32SZ + 2 * (uint)Proto.BIT16SZ + f.nstat;
                                break;

                        case (byte)Proto.Rerror:
                                n += (uint)Proto.BIT16SZ + (uint)f.ename.Length;
                                break;
                        case (byte)Proto.Rflush:
                        case (byte)Proto.Rclunk:
                        case (byte)Proto.Rremove:
                        case (byte)Proto.Rwstat:
                                break;
                        case (byte)Proto.Rauth:
                        case (byte)Proto.Rattach:
                                n += (uint)Proto.QIDSZ;
                                break;
                        case (byte)Proto.Rwalk:
                                n += (uint)Proto.BIT16SZ + f.nwqid * (uint)Proto.QIDSZ;
                                break;
                        case (byte)Proto.Ropen:
                        case (byte)Proto.Rcreate:
                                n += (uint)Proto.QIDSZ + (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Rread:
                                n += (uint)Proto.BIT32SZ + f.count;
                                break;
                        case (byte)Proto.Rstat:
                                n += (uint)Proto.BIT16SZ + f.nstat;
                                break;
                        }

                        return n;
                }

                public uint ConvS2M(Fcall f, Byte[] pkt)
                {
                        uint size, i, pp;

                        size = SizeS2M(f);
                        if(size == 0)
                                return 0;
                        if(size > pkt.Length)
                                return 0;
                        pp = 0;
                        Putuint(pkt, pp, size);
                        pp += (uint)Proto.BIT32SZ;
                        pkt[pp] = f.type;
                        pp += (uint)Proto.BIT8SZ;
                        Putushort(pkt, pp, f.tag);
                        pp += (uint)Proto.BIT16SZ;

                        switch(f.type) {
                        default:
                                return 0;
                        case (byte)Proto.Tversion:
                                Putuint(pkt, pp, f.msize);
                                pp += (uint)Proto.BIT32SZ;
                                Putstring(pkt, pp, f.version);
                                pp += (uint)Proto.BIT16SZ + (uint)f.version.Length;
                                break;
                        case (byte)Proto.Tflush:
                                Putushort(pkt, pp, f.oldtag);
                                pp += (uint)Proto.BIT16SZ;
                                break;
                        case (byte)Proto.Tauth:
                                Putuint(pkt, pp, (uint)f.afid);
                                pp += (uint)Proto.BIT32SZ;
                                Putstring(pkt, pp, f.uname);
                                pp += (uint)Proto.BIT16SZ + (uint)f.uname.Length;
                                Putstring(pkt, pp, f.aname);
                                pp += (uint)Proto.BIT16SZ + (uint)f.aname.Length;
                                break;
                        case (byte)Proto.Tattach:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                Putuint(pkt, pp, (uint)f.afid);
                                pp += (uint)Proto.BIT32SZ;
                                Putstring(pkt, pp, f.uname);
                                pp += (uint)Proto.BIT16SZ + (uint)f.uname.Length;
                                Putstring(pkt, pp, f.aname);
                                pp += (uint)Proto.BIT16SZ + (uint)f.aname.Length;
                                break;
                        case (byte)Proto.Twalk:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                Putuint(pkt, pp, (uint)f.newfid);
                                pp += (uint)Proto.BIT32SZ;
                                Putushort(pkt, pp, f.nwname);
                                pp += (uint)Proto.BIT16SZ;
                                if(f.nwname > (uint)Proto.MAXWELEM)
                                        return 0;
                                for(i = 0; i < f.nwname; i++) {
                                        Putstring(pkt, pp, f.wname[i]);
                                        pp += (uint)Proto.BIT16SZ + (uint)f.wname[i].Length;
                                }
                                break;
                        case (byte)Proto.Topen:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                pkt[pp] = f.mode;
                                pp += (uint)Proto.BIT8SZ;
                                break;
                        case (byte)Proto.Tcreate:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                Putstring(pkt, pp, f.name);
                                pp += (uint)Proto.BIT16SZ + (uint)f.name.Length;
                                Putuint(pkt, pp, f.perm);
                                pp += (uint)Proto.BIT32SZ;
                                pkt[pp] = f.mode;
                                pp += (uint)Proto.BIT8SZ;
                                break;
                        case (byte)Proto.Tread:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                Putulong(pkt, pp, f.offset);
                                pp += (uint)Proto.BIT64SZ;
                                Putuint(pkt, pp, f.count);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Twrite:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                Putulong(pkt, pp, f.offset);
                                pp += (uint)Proto.BIT64SZ;
                                Putuint(pkt, pp, f.count);
                                pp += (uint)Proto.BIT32SZ;
                                Array.Copy(f.data, 0, pkt, pp, f.count);
                                pp += f.count;
                                break;
                        case (byte)Proto.Tclunk:
                        case (byte)Proto.Tremove:
                        case (byte)Proto.Tstat:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Twstat:
                                Putuint(pkt, pp, (uint)f.fid);
                                pp += (uint)Proto.BIT32SZ;
                                Putushort(pkt, pp, f.nstat);
                                pp += (uint)Proto.BIT16SZ;
                                Array.Copy(f.stat, 0, pkt, pp, f.nstat);
                                pp += f.nstat;
                                break;

                        case (byte)Proto.Rversion:
                                Putuint(pkt, pp, f.msize);
                                pp += (uint)Proto.BIT32SZ;
                                Putstring(pkt, pp, f.version);
                                pp += (uint)Proto.BIT16SZ + (uint)f.version.Length;
                                break;
                        case (byte)Proto.Rerror:
                                Putstring(pkt, pp, f.ename);
                                pp += (uint)Proto.BIT16SZ + (uint)f.ename.Length;
                                break;
                        case (byte)Proto.Rflush:
                        case (byte)Proto.Rclunk:
                        case (byte)Proto.Rremove:
                        case (byte)Proto.Rwstat:
                                break;
                        case (byte)Proto.Rauth:
                                Putqid(pkt, pp, f.aqid);
                                pp += (uint)Proto.QIDSZ;
                                break;
                        case (byte)Proto.Rattach:
                                Putqid(pkt, pp, f.qid);
                                pp += (uint)Proto.QIDSZ;
                                break;
                        case (byte)Proto.Rwalk:
                                Putushort(pkt, pp, f.nwqid);
                                pp += (uint)Proto.BIT16SZ;
                                if(f.nwqid > (uint)Proto.MAXWELEM)
                                        return 0;
                                for(i = 0; i < f.nwqid; i++) {
                                        Putqid(pkt, pp, f.wqid[i]);
                                        pp += (uint)Proto.QIDSZ;
                                }
                                break;
                        case (byte)Proto.Ropen:
                        case (byte)Proto.Rcreate:
                                Putqid(pkt, pp, f.qid);
                                pp += (uint)Proto.QIDSZ;
                                Putuint(pkt, pp, f.iounit);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Rread:
                                Putuint(pkt, pp, f.count);
                                pp += (uint)Proto.BIT32SZ;
                                Array.Copy(f.data, 0, pkt, pp, f.count);
                                pp += f.count;
                                break;
                        case (byte)Proto.Rwrite:
                                Putuint(pkt, pp, f.count);
                                pp += (uint)Proto.BIT32SZ;
                                break;
                        case (byte)Proto.Rstat:
                                Putushort(pkt, pp, f.nstat);
                                pp += (uint)Proto.BIT16SZ;
                                Array.Copy(f.stat, 0, pkt, pp, f.nstat);
                                pp += f.nstat;
                                break;
                        }
                        if(size != pp)
                                return 0;
                        return size;
                }

                public Dir ConvM2D(Byte[] stat, uint pp)
                {
                        Dir d;

                        d = new Dir();

                        if(stat.Length < (int)Proto.STATFIXLEN)
                                return d;

                        pp += (uint)Proto.BIT16SZ;
                        d.type = Getushort(stat, pp);
                        pp += (uint)Proto.BIT16SZ;
                        d.dev = Getuint(stat, pp);
                        pp += (uint)Proto.BIT32SZ;
                        d.qid = Getqid(stat, pp);
                        pp += (uint)Proto.QIDSZ;
                        d.mode = Getuint(stat, pp);
                        pp += (uint)Proto.BIT32SZ;
                        d.atime = Getuint(stat, pp);
                        pp += (uint)Proto.BIT32SZ;
                        d.mtime = Getuint(stat, pp);
                        pp += (uint)Proto.BIT32SZ;
                        d.length = Getulong(stat, pp);
                        pp += (uint)Proto.BIT64SZ;
                        d.name = Getstring(stat, pp);
                        pp += (uint)Proto.BIT16SZ + (uint)d.name.Length;
                        d.uid = Getstring(stat, pp);
                        pp += (uint)Proto.BIT16SZ + (uint)d.uid.Length;
                        d.gid = Getstring(stat, pp);
                        pp += (uint)Proto.BIT16SZ + (uint)d.gid.Length;
                        d.muid = Getstring(stat, pp);
                        pp += (uint)Proto.BIT16SZ + (uint)d.muid.Length;

                        d.status = 1;
                        return d;
                }

                public uint SizeD2M(Dir d)
                {
                        return (uint)Proto.STATFIXLEN + (uint)d.name.Length + (uint)d.uid.Length +
                                        (uint)d.gid.Length + (uint)d.muid.Length;
                }

                public uint ConvD2M(Dir d, Byte[] stat)
                {
                        uint pp, len;

                        pp = 0;
                        len = SizeD2M(d);

                        if(len > stat.Length)
                                return 0;

                        Putushort(stat, pp, (ushort)(len - (uint)Proto.BIT16SZ));
                        pp += (uint)Proto.BIT16SZ;
                        Putushort(stat, pp, d.type);
                        pp += (uint)Proto.BIT16SZ;
                        Putuint(stat, pp, d.dev);
                        pp += (uint)Proto.BIT16SZ;
                        stat[pp] = d.qid.type;
                        pp += (uint)Proto.BIT8SZ;
                        Putuint(stat, pp, d.qid.vers);
                        pp += (uint)Proto.BIT32SZ;
                        Putulong(stat, pp, d.qid.path);
                        pp += (uint)Proto.BIT64SZ;
                        Putuint(stat, pp, d.mode);
                        pp += (uint)Proto.BIT32SZ;
                        Putuint(stat, pp, d.atime);
                        pp += (uint)Proto.BIT32SZ;
                        Putuint(stat, pp, d.mtime);
                        pp += (uint)Proto.BIT32SZ;
                        Putulong(stat, pp, d.length);
                        pp += (uint)Proto.BIT64SZ;
                        Putstring(stat, pp, d.name);
                        pp += (uint)Proto.BIT16SZ + (uint)d.name.Length;
                        Putstring(stat, pp, d.uid);
                        pp += (uint)Proto.BIT16SZ + (uint)d.uid.Length;
                        Putstring(stat, pp, d.gid);
                        pp += (uint)Proto.BIT16SZ + (uint)d.gid.Length;
                        Putstring(stat, pp, d.muid);
                        pp += (uint)Proto.BIT16SZ + (uint)d.muid.Length;

                        if(len != pp + 1)
                                return 0;

                        return pp + 1;
                }

                public Dir[] Dols(Byte[] pkt)
                {
                        Dir[] ret;
                        uint pp, i;

                        pp = 0;
                        i = 0;

                        for(i = 0, pp = 0; pp < pkt.Length; i++)
                                pp += Getushort(pkt, pp) + (uint)Proto.BIT16SZ;

                        ret = new Dir[i];
                        i = 0;
                        pp = 0;
                        for(i = 0, pp = 0; pp < pkt.Length; i++) {
                                ret[i] = ConvM2D(pkt, pp);
                                pp += Getushort(pkt, pp) + (uint)Proto.BIT16SZ;
                        }

                        return ret;
                }

                public void Dofid()
                {
                        int cfid;

                        Doclunk(cwd);
                        cfid = cwd;
                        cwd = fid;
                        fid = cfid;
                }

                public void Do9p()
                {
                        ConvS2M(fin, pktin);
                        Send9pmsg(pktin);
                        pktout = Read9pmsg();
                        fout = ConvM2S(pktout);
                }

                public void Doversion()
                {
                        fin.type = (byte)Proto.Tversion;
                        fin.tag = 65535;
                        fin.msize = mmsgsz;
                        fin.version = "9P2000";
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error on Tversion");

                        if(fout.msize < mmsgsz) {
                                mmsgsz = fout.msize;
                                mdatasz = fout.msize + (uint)Proto.IOHDRSIZE;
                        }
                }

                public void Doauth()
                {
                        fin.type = (byte)Proto.Tauth;
                        fin.tag = ++tag;
                        fin.afid = afid;
                        fin.uname = uname;
                        fin.aname = aname;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rauth)
                                throw new Ninepexception("Error, auth not supported for now");
                }

                public void Doattach()
                {
                        fin.type = (byte)Proto.Tattach;
                        fin.tag = ++tag;
                        fin.fid = root;
                        fin.afid = afid;
                        fin.uname = uname;
                        fin.aname = aname;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error, attach failed");
                }

                public void Doswalk(int fid, int newfid, string[] path)
                {
                        fin.type = (byte)Proto.Twalk;
                        fin.tag = ++tag;
                        fin.fid = fid;
                        fin.newfid = newfid;
                        fin.nwname = (ushort)path.Length;
                        fin.wname = path;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error, walk failed");
                }

                public void Dowalk(int fid, int newfid, string[] path)
                {
                        uint i;
                        string[] lss;

                        for(i = 0; i <= path.Length; i += (uint)Proto.MAXWELEM) {
                                lss = new string[(path.Length - i > (uint)Proto.MAXWELEM)
                                                                        ? (uint)Proto.MAXWELEM : path.Length - i];
                                Array.Copy(path, i, lss, 0, lss.Length);
                                Doswalk(fid, newfid, lss);
                                if(fid != root && newfid != ffid)
                                        Dofid();
                        }
                }

                public void Dostat(int fid)
                {
                        fin.type = (byte)Proto.Tstat;
                        fin.tag = ++tag;
                        fin.fid = fid;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error, stat failed");

                        dir = ConvM2D(fout.stat, 0);
                }

                public void Doclunk(int fid)
                {
                        fin.type = (byte)Proto.Tclunk;
                        fin.tag = ++tag;
                        fin.fid = fid;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error, clunk failed");
                }

                public void Doopen(int fid, byte mode)
                {
                        fin.type = (byte)Proto.Topen;
                        fin.tag = ++tag;
                        fin.fid = fid;
                        fin.mode = mode;
                        fin.iounit = 0;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error, open failed");

                        if(fout.iounit != 0) {
                                mmsgsz = fout.iounit + (uint)Proto.IOHDRSIZE;
                                mdatasz = fout.iounit;
                        }
                }

                public void Dosread(int fid, ulong offset, uint count)
                {
                        fin.type = (byte)Proto.Tread;
                        fin.tag = ++tag;
                        fin.fid = fid;
                        fin.offset = offset;
                        fin.count = count;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error, read failed");
                }

                public void Doread(int fid, ulong offset, uint count)
                {
                        Byte[] strip;
                        uint len;

                        len = 0;
                        readbuf = new Byte[count];

                        while(len < count) {
                                Dosread(fid, offset, ((count - len) > mdatasz) ? mdatasz : count);
                                Array.Copy(fout.data, 0, readbuf, len, fout.data.Length);
                                len += (uint)fout.data.Length;
                                if(fout.data.Length != mdatasz && len < count)
                                        break;
                        }

                        if(len < count) {
                                strip = new Byte[len];
                                Array.Copy(readbuf, 0, strip, 0, len);
                                readbuf = strip;
                        }
                }

                public void Doswrite(int fid, ulong offset, uint count, Byte[] data)
                {
                        fin.type = (byte)Proto.Twrite;
                        fin.tag = ++tag;
                        fin.fid = fid;
                        fin.offset = offset;
                        fin.count = count;
                        fin.data = data;
                        Do9p();
                        if(fout.type == (sbyte)Proto.Rerror)
                                throw new Ninepexception("Error, write failed");
                }

                public void Dowrite(int fid, ulong offset, uint count, Byte[] data)
                {
                        Byte[] strip;
                        uint len;

                        len = 0;

                        while(len < count) {
                                strip = new Byte[((count - len) > mdatasz) ? mdatasz : count];
                                Array.Copy(data, len, strip, 0, strip.Length);
                                Doswrite(fid, offset, (uint)strip.Length, strip);
                                len += (uint)strip.Length;
                        }
                }
        }

        class MainClass
        {
                public static void Main(string[] args)
                {
                        ninepc.Ninep test;
                        string cmd, server;
                        int i;
                        uint offset;
                        Dir[] dirs;
                        string[] lss, lsc;

                        test = new ninepc.Ninep();
                        server = "sources.cs.bell-labs.com";

                        try {
                                test.Connect(server, 564);
                                test.Doversion();
                                test.Doauth();
                                test.Doattach();
                                test.Dowalk(test.root, test.cwd, new string[0]);

                                for(;;) {
                                        Console.Write("{0}% ", server);
                                        cmd = Console.ReadLine();
                                        if(cmd.StartsWith("ls")) {
                                                test.Dowalk(test.cwd, test.ffid, new string[] {"."});
                                                test.Doopen(test.ffid, 0x00);
                                                test.Doread(test.ffid, 0, (uint)test.mdatasz);
                                                dirs = test.Dols(test.readbuf);
                                                foreach(Dir d in dirs)
                                                        Console.WriteLine("{0} {1} {2} {3} {4}", test.Modestr(d.mode), d.uid,
                                                                                                                d.gid, d.length, d.name);
                                                test.Doclunk(test.ffid);
                                                continue;
                                        }

                                        if(cmd.StartsWith("cd")) {
                                                lss = cmd.Split(" ".ToCharArray());
                                                if(lss.Length < 2)
                                                        continue;
                                                lsc = lss[1].Split("/".ToCharArray());
                                                test.Dowalk(test.cwd, test.fid, lsc);
                                                continue;
                                        }

                                        if(cmd.StartsWith("cat")) {
                                                lss = cmd.Split(" ".ToCharArray());
                                                Array.Copy(lss, 1, lss, 0, lss.Length - 1);
                                                for(i = 0; i < (lss.Length - 1); i++) {
                                                        offset = 0;
                                                        test.Dowalk(test.cwd, test.ffid, new string[] {lss[i]});
                                                        test.Dostat(test.ffid);
                                                        test.Doopen(test.ffid, 0x00);
                                                        test.Doread(test.ffid, offset, (uint)test.dir.length);
                                                        Console.WriteLine(test.Convstring(test.readbuf));
                                                        test.Doclunk(test.ffid);
                                                }
                                        }

                                        if(cmd.StartsWith("q"))
                                                break;
                                }

                                test.Doclunk(test.cwd);
                                test.Doclunk(test.root);

                                test.Shutdown();
                        } catch(Exception ex) {
                                Console.WriteLine("Error main: {0}", ex.ToString());
                        }
                }
        }
}


C:\Users\Eric\Documents\Visual Studio 2017\Projects\9pc>

No comments:

Post a Comment