Пример #1
0
        // https://developer.apple.com/library/mac/documentation/networking/Reference/AFP_Reference/Reference/reference.html#//apple_ref/c/func/FPOpenDir

        void T2(object state) {
            Thread.CurrentThread.CurrentUICulture = CultureInfo.InvariantCulture;

            Encoding enc = Encoding.GetEncoding(932);

            ManualResetEvent evExit = new ManualResetEvent(false);

            try {
                using (TcpClient tcp = (TcpClient)state) {
                    NetworkStream st = tcp.GetStream();
                    StreamWriter wr = new StreamWriter(st, Encoding.UTF8);
                    StreamReader rr = new StreamReader(st, Encoding.UTF8, false);

                    ConDyn cd = new ConDyn(cc);
                    String syst = "";
                    using (MyDSI3 comm = new MyDSI3(afp)) {
                        TransmitRes res = comm.Transmit(new DSIGetStatus());
                        if (res.pack.IsResponse && res.pack.ErrorCode == 0) {
                            GetSrvrInfoPack pack = new GetSrvrInfoPack(res.br);
                            if (pack.AFPVersionsList.Contains("AFP2.2")) {

                            }
                            if (pack.AFPVersionsList.Contains("AFPX03")) {
                                cd.AFP30 = true;
                            }
                            if (pack.AFPVersionsList.Contains("AFP3.1")) {
                                cd.AFP31 = true;
                            }
                            syst += " Server: " + pack.ServerName + "\n";
                            syst += " AFPVer:";
                            foreach (String ver in pack.AFPVersionsList) syst += " <" + ver + ">";
                            syst += "\n";
                            syst += "    UAM:";
                            foreach (String ver in pack.UAMsList) syst += " <" + ver + ">";
                        }
                        else {
                            Ut.WriteRes(wr, 500, "AFP server failed: " + new DSIException(res.pack.ErrorCode, res.pack));
                            return;
                        }
                    }
                    String U = String.Empty;
                    String P = String.Empty;
                    IDir root = new DisconnetedRoot();
                    IDir pwd = root;
                    DataConn dc = new DataConn();
                    Int64 ftpRest = 0;
                    IEnt rnfr = null;
                    using (MyDSI3 comm = new MyDSI3(afp)) {
                        Ticker ti = new Ticker(comm, evExit);
                        Ut.WriteRes(wr, 220, "FTP4AFP in UTF-8");
                        while (true) {
                            try {
                                String row = rr.ReadLine();
                                if (row == null) break;
                                Match M;
                                M = Regex.Match(row, "^QUIT", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    Ut.WriteRes(wr, 221, "Goodbye!");
                                    break;
                                }
                                M = Regex.Match(row, "^USER\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    U = M.Groups["a"].Value;
                                    Ut.WriteRes(wr, 331, "Proceed to password.");
                                    continue;
                                }
                                M = Regex.Match(row, "^PASS\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    P = M.Groups["a"].Value;
                                    Uta a = new Uta();
                                    root = pwd = a.Login(comm, cd, U, P);
                                    Ut.WriteRes(wr, 230, "User logged in, proceed.");
                                    continue;
                                }
                                M = Regex.Match(row, "^SYST", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    Ut.WriteRes(wr, 215, typeof(AFPServ).AssemblyQualifiedName + "\n" + Environment.OSVersion + "\n" + "\n" + syst);
                                    continue;
                                }
                                M = Regex.Match(row, "^(XPWD|PWD)", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    MLoc m = MLoc.Ut.Get(pwd);
                                    Ut.WriteRes(wr, 257, "\"" + m.UnixPath + "\" is current directory.");
                                    continue;
                                }
                                M = Regex.Match(row, "^TYPE\\s+(?<a>A|I)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String mode = M.Groups["a"].Value.ToUpperInvariant();
                                    if (mode == "I") dc.TypeI();
                                    if (mode == "A") dc.TypeA();
                                    Ut.WriteRes(wr, 200, "Ok.");
                                    continue;
                                }
                                M = Regex.Match(row, "^PASV", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    dc.Pasv(tcp.Client.LocalEndPoint);

                                    Ut.WriteRes(wr, 227, "Entering Passive Mode (" + dc.GetPasv() + ")");
                                    continue;
                                }
                                M = Regex.Match(row, "^PORT\\s+(?<a>\\d+,\\d+,\\d+,\\d+,\\d+,\\d+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    dc.Port(M.Groups["a"].Value);
                                    Ut.WriteRes(wr, 200, "PORT command successful.");
                                    continue;
                                }
                                M = Regex.Match(row, "^LIST(\\s+(?<a>.+))?\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        IDir newwd = (cwd.Length == 0) ? pwd : TravUt.Cwd(pwd, cwd);

                                        StringWriter ww = new StringWriter();
                                        foreach (IEnt o in newwd.GetEnts()) {
                                            bool isDir = o is IDir;
                                            ww.WriteLine("{0}rw-r--r--    1 0        0      {1,10} {2,-12} {3}"
                                                , isDir ? "d" : "-"
                                                , isDir ? "0" : o.Size.ToString()
                                                , DUt.Format(o.Mt)
                                                , o.Name
                                                );
                                        }
                                        // http://blog.livedoor.jp/kumagai_nori/archives/51660940.html
                                        // http://ash.jp/net/ftp_command.htm
                                        // http://www.atmarkit.co.jp/ait/articles/0307/11/news001.html

                                        // http://www.atmarkit.co.jp/fnetwork/rensai/netpro10/ftp-responsecode.html

                                        // http://maruo.dyndns.org:81/hidesoft/hidesoft_2/x17565.html
                                        // http://www.nsftools.com/tips/MSFTP.htm#dir
                                        Ut.WriteRes(wr, 150, "Opening " + dc.Mode + " mode data connection for LIST");

                                        dc.SendData(wr.Encoding.GetBytes(ww.ToString()));

                                        Ut.WriteRes(wr, 226, "Transfer complete");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 501, err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^MLSD(\\s+(?<a>.+))?\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        IDir newwd = (cwd.Length == 0) ? pwd : TravUt.Cwd(pwd, cwd);

                                        StringWriter ww = new StringWriter();
                                        foreach (IEnt o in newwd.GetEnts()) {
                                            bool isDir = o is IDir;
                                            ww.WriteLine("modify={0};perm={1};size={2};type={3}; {4}"
                                                , o.Mt.HasValue ? String.Format("{0:yyyy}{0:MM}{0:dd}{0:HH}{0:mm}{0:ss}", o.Mt.Value) : ""
                                                , isDir ? "cdelmp" : "dlrw"
                                                , Math.Max(o.Size, 0)
                                                , isDir ? "dir" : "file"
                                                , o.Name
                                                );
                                        }

                                        Ut.WriteRes(wr, 150, "Opening " + dc.Mode + " mode data connection for MLSD");

                                        dc.SendData(wr.Encoding.GetBytes(ww.ToString()));

                                        Ut.WriteRes(wr, 226, "Transfer complete");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 501, err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^CWD\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        IDir newwd = TravUt.Cwd(pwd, cwd);
                                        pwd = newwd;
                                        Ut.WriteRes(wr, 250, "Directory successfully changed.");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^CDUP", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    IDir newwd = pwd.ParentDir;
                                    if (newwd == null) {
                                        Ut.WriteRes(wr, 250, "We are already at root directory.");
                                        continue;
                                    }
                                    else {
                                        pwd = newwd;
                                        Ut.WriteRes(wr, 250, "Directory successfully changed.");
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^OPTS\\s+UTF8\\s+ON\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    Ut.WriteRes(wr, 200, "It is in UTF8 mode.");
                                    wr = new StreamWriter(st, Encoding.UTF8);
                                    rr = new StreamReader(st, Encoding.UTF8, false);
                                    continue;
                                }
                                M = Regex.Match(row, "^OPTS\\s+UTF8\\s+OFF\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    Ut.WriteRes(wr, 200, "It is in " + enc.BodyName + " mode.");
                                    wr = new StreamWriter(st, enc);
                                    rr = new StreamReader(st, enc, false);
                                    continue;
                                }
                                M = Regex.Match(row, "^OPTS\\s+FORKMODE\\s+(?<a>\\d+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    int i = int.Parse(M.Groups["a"].Value);
                                    cd.ForkMode = i;
                                    Ut.WriteRes(wr, 200, "It is in fork mode " + i + ".");
                                    continue;
                                }
                                M = Regex.Match(row, "^FEAT", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    Ut.WriteRes(wr, 211, "Features:| UTF8| MLST modify*;perm*;size*;type*;| FORKMODE| END".Replace("|", "\n"));
                                    continue;
                                }
                                M = Regex.Match(row, "^RETR\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        IEnt source = TravUt.Find(pwd, cwd, false);

                                        if (source is ICanDL) {
                                            using (Stream si = ((ICanDL)source).OpenRead()) {
                                                Ut.WriteRes(wr, 150, "Opening " + dc.Mode + " mode data connection for " + cwd);
                                                si.Position = ftpRest;
                                                dc.SendSt(si);
                                            }
                                        }
                                        else {
                                            Ut.WriteRes(wr, 550, "We can't get \"" + cwd + "\".");
                                            continue;
                                        }
                                        ftpRest = 0;

                                        Ut.WriteRes(wr, 226, "Transfer complete");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^STOR\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        using (Stream os = TravUt.Createf(pwd, cwd, cd)) {
                                            Ut.WriteRes(wr, 150, "Opening " + dc.Mode + " mode data connection for " + cwd);
                                            os.SetLength(ftpRest);
                                            os.Position = ftpRest;
                                            dc.RecvSt(os);
                                        }
                                        ftpRest = 0;

                                        Ut.WriteRes(wr, 226, "Transfer complete");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^APPE\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        using (Stream os = TravUt.Createf(pwd, cwd, cd)) {
                                            Ut.WriteRes(wr, 150, "Opening " + dc.Mode + " mode data connection for " + cwd);
                                            os.Seek(0, SeekOrigin.End);
                                            dc.RecvSt(os);
                                        }

                                        Ut.WriteRes(wr, 226, "Transfer complete");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^MKD\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        TravUt.CreateDir(pwd, cwd);

                                        Ut.WriteRes(wr, 250, "\"" + cwd + "\" created successfully.");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, "\"" + cwd + "\": Unable to create directory. \n" + err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^RMD\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        TravUt.RMDir(pwd, cwd);

                                        Ut.WriteRes(wr, 250, "\"" + cwd + "\" removed successfully.");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, "\"" + cwd + "\": Unable to remove directory. \n" + err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^DELE\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        TravUt.Dele(pwd, cwd, cd);

                                        Ut.WriteRes(wr, 250, "\"" + cwd + "\" removed successfully.");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, "\"" + cwd + "\": Unable to remove directory. \n" + err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^REST\\s+(?<a>\\d+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    ftpRest = Int64.Parse(M.Groups["a"].Value);
                                    Ut.WriteRes(wr, 200, "Ok.");
                                    continue;
                                }
                                M = Regex.Match(row, "^RNFR\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        rnfr = TravUt.Find(pwd, cwd, false);

                                        Ut.WriteRes(wr, 350, "The file exists, continue with RNTO.");
                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, err.Message);
                                        continue;
                                    }
                                }
                                M = Regex.Match(row, "^RNTO\\s+(?<a>.+)\\s*$", RegexOptions.Singleline | RegexOptions.IgnoreCase);
                                if (M.Success) {
                                    String cwd = M.Groups["a"].Value;
                                    try {
                                        MLoc mfrm = MLoc.Ut.Get(rnfr);
                                        String fpfrm = mfrm.UnixPath;

                                        MLoc m = MLoc.Ut.Get(pwd);
                                        String fp2 = UtPLoc.Getfp(m.UnixPath, cwd, cd);

                                        PLoc p1 = new PLoc(fpfrm);
                                        PLoc p2 = new PLoc(fp2);

                                        if (!p1.volume.Equals(p2.volume)) throw new ApplicationException("We have different volumes.");

                                        if (!p1.dir.Equals(p2.dir)) {
                                            MLoc m2 = new MLoc();
                                            m2.VolID = mfrm.VolID;
                                            m2.DirID = mfrm.DirID;
                                            m2.MacVol = mfrm.MacVol;
                                            m2.MacPath = p2.dir.Replace("/", "\0");
                                            Utcmd.Move(comm, mfrm, m2, p2.fname);
                                        }
                                        else {
                                            Utcmd.Rename(comm, mfrm, p2.fname);
                                        }

                                        Ut.WriteRes(wr, 200, "Ok.");

                                        continue;
                                    }
                                    catch (EntNotFoundException err) {
                                        Ut.WriteRes(wr, 550, err.Message);
                                        continue;
                                    }
                                }

                                Ut.WriteRes(wr, 500, "NotImpl Error.");
                            }
                            catch (Exception err) {
                                if (tcp.Connected) {
                                    try {
                                        Ut.WriteRes(wr, 500, err.ToString());
                                    }
                                    catch (IOException) { }
                                }
                                else break;
                            }
                        }
                    }
                    tcp.Close();
                }
            }
            finally {
                evExit.Set();
            }
        }
Пример #2
0
        public static void Move(MyDSI3 comm, MLoc mfrm, MLoc m2, String nam) {
            TransmitRes res1 = comm.Transmit(new DSICommand().WithRequestPayload(new FPMoveAndRename()
                .WithVolumeID(mfrm.VolID)
                .WithSourceDirectoryID(mfrm.DirID)
                .WithSourcePath(mfrm.RawPath)
                .WithDestDirectoryID(m2.DirID)
                .WithDestPath(m2.RawPath)
                .WithNewName(nam)
            ));
            if (res1.pack.IsResponse && res1.pack.ErrorCode == 0) {

            }
            else { throw new DSIException(res1.pack.ErrorCode, res1.pack); }

        }
Пример #3
0
        public static IEnumerable<IEnt> GetEnts310(MLoc m, MyDSI3 comm, ConDyn cd, IDir self) {
            for (uint x = 0; ; ) {
                TransmitRes res1 = comm.Transmit(new DSICommand().WithRequestPayload(new FPEnumerateExt2()
                    .WithPath(m.RawPath)
                    .WithStartIndex(Convert.ToUInt32(1U + x))
                    .WithVolumeID(m.VolID)
                    .WithDirectoryID(m.DirID)
                    .WithFileBitmap(AfpFileBitmap.ExtDataForkLength | AfpFileBitmap.ExtResourceForkLength | AfpFileBitmap.LongName | AfpFileBitmap.NodeID | AfpFileBitmap.ModificationDate)
                    .WithDirectoryBitmap(AfpDirectoryBitmap.NodeID | AfpDirectoryBitmap.LongName | AfpDirectoryBitmap.ModificationDate)
                    ));
                if (res1.pack.ErrorCode == -5018) break;
                if (res1.pack.IsResponse && res1.pack.ErrorCode == 0) {
                }
                else { throw new DSIException(res1.pack.ErrorCode, res1.pack); }

                EnumerateExtPack pack = new EnumerateExtPack(res1.br);

                foreach (FileParameters ent in pack.Ents) {
                    if (ent.IsDirectory) {
                        yield return new MacDir(ent, comm, cd, self);
                    }
                    else {
                        yield return new MacEnt(ent, Forkty.Data, comm, cd, self);
                        if (cd.EnumRes && ((Utfs.ResFork(ent) > 0) || !cd.IfAvail)) yield return new MacEnt(ent, Forkty.Res, comm, cd, self);
                        if (cd.EnumFi) yield return new MacEnt(ent, Forkty.Finder, comm, cd, self);
                    }
                }

                if (pack.ActualCount == 0) break;

                x += pack.ActualCount;
            }
        }
Пример #4
0
 public static IEnumerable<IEnt> GetEnts(MLoc m, MyDSI3 comm, ConDyn cd, IDir self) {
     if (cd.AFP31) return GetEnts310(m, comm, cd, self);
     if (cd.AFP30) return GetEnts300(m, comm, cd, self);
     return GetEnts220(m, comm, cd, self);
 }
Пример #5
0
 public static MLoc GetVol(MacVol vol) {
     MLoc m = new MLoc();
     vol.OpenIt();
     m.MacPath = "";
     m.MacVol = vol.RealName;
     m.VolID = vol.VolID;
     m.DirID = vol.DirID;
     return m;
 }
Пример #6
0
            public static MLoc Get(IEnt p) {
                MLoc m = new MLoc();
                m.MacPath = String.Empty;
                m.MacVol = String.Empty;
                while (p != null) {
                    if (p is MacRoot)
                        break;
                    if (p is MacVol) {
                        MacVol vol = (MacVol)p;
                        vol.OpenIt();
                        m.VolID = vol.VolID;
                        m.DirID = vol.DirID;
                        m.MacVol = p.RealName;
                    }
                    else {
                        m.MacPath = ((String)(p.RealName + ":" + m.MacPath)).TrimEnd(':');
                    }

                    p = p.ParentDir;
                }
                return m;
            }
Пример #7
0
 public MacFiSt(MyDSI3 comm, byte[] fi, MLoc m, bool write) {
     this.comm = comm;
     this.fi = fi;
     this.m = m;
     this.write = write;
     this.open = true;
     this.pos = 0;
 }