Beispiel #1
0
 static void Main(string[] args)
 {
     MainClass mc = new MainClass();
     mc.Run(args);
 }
Beispiel #2
0
        /// <summary>
        /// Returns offset in p array
        /// </summary>
        /// <param name="offset"></param>
        /// <param name="length"></param>
        /// <returns></returns>
        public int MapPtr(int offset, int length)
        {
            int numberOfReadBytes;
            int windowStart, readStart;
            int windowSize, readSize, readOffset;

            if (length == 0)
            {
                return(-1);
            }

            if (length > (this.fileSize - offset))
            {
                length = this.fileSize - offset;
            }

            if (offset >= this.pOffset && offset + length <= this.pOffset + this.pLength)
            {
                return(offset - this.pOffset);
            }

            windowStart = offset;
            windowSize  = this.defaultWindowSize;
            if (windowStart + windowSize > this.fileSize)
            {
                windowSize = this.fileSize - windowStart;
            }
            if (offset + length > windowStart + windowSize)
            {
                windowSize = (offset + length) - windowStart;
            }

            if (windowSize > this.pSize)
            {
                ExtendArray(ref p, windowSize);
                this.pSize = windowSize;
            }

            if (windowStart >= this.pOffset &&
                windowStart < this.pOffset + this.pLength &&
                windowStart + windowSize >= this.pOffset + this.pLength)
            {
                readStart  = this.pOffset + this.pLength;
                readOffset = readStart - windowStart;
                readSize   = windowSize - readOffset;
                MemoryMove(ref this.p, this.p, (this.pLength - readOffset), readOffset);
            }
            else
            {
                readStart  = windowStart;
                readSize   = windowSize;
                readOffset = 0;
            }
            if (readSize <= 0)
            {
                Log.WriteLine("Warning: unexpected read size of " + readSize + " in MapPtr");
            }
            else
            {
                if (this.pFileDescriptorOffset != readStart)
                {
                    if (this.fileDescriptor.Seek(readStart, SeekOrigin.Begin) != readStart)
                    {
                        MainClass.Exit("Seek failed in MapPtr", null);
                    }
                    this.pFileDescriptorOffset = readStart;
                }

                if ((numberOfReadBytes = fileDescriptor.Read(this.p, readOffset, readSize)) != readSize)
                {
                    //if (numberOfReadBytes < 0) //@fixed Read never returns <0 so status is false all the time
                    //{
                    //    numberOfReadBytes = 0;
                    //    status = true;
                    //}
                    FillMemory(ref this.p, readOffset + numberOfReadBytes, 0, readSize - numberOfReadBytes);
                }
                this.pFileDescriptorOffset += numberOfReadBytes;
            }

            this.pOffset = windowStart;
            this.pLength = windowSize;
            return(offset - this.pOffset);
        }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="options"></param>
        /// <returns></returns>
        public bool LoadParm(Options options)
        {
            lock (this)
            {
                // TODO: path length
                if (confFile == null || confFile.CompareTo(String.Empty) == 0 || !File.Exists(confFile))
                {
                    MainClass.Exit("Can't find .conf file: " + confFile, null);
                    return(false);
                }
                try
                {
                    using (var cf = new System.IO.StreamReader(confFile))
                    {
                        Module mod = null;

                        if (Modules == null)
                        {
                            Modules = new List <Module>();
                        }

                        lock (cf)
                        {
                            while (true)
                            {
                                string line = cf.ReadLine();
                                if (line == null)
                                {
                                    break;
                                }
                                line = line.Trim();
                                if (line.CompareTo(String.Empty) != 0 && line[0] != ';' && line[0] != '#')
                                {
                                    if (line[0] == '[' && line[line.Length - 1] == ']')
                                    {
                                        line = line.TrimStart('[').TrimEnd(']');
                                        int numberModule = -1;
                                        if ((numberModule = GetNumberModule(line)) >= 0)
                                        {
                                            mod = GetModule(numberModule);
                                        }
                                        else
                                        {
                                            mod = new Module(line);
                                            Modules.Add(mod);
                                        }
                                    }
                                    else
                                    {
                                        if (mod != null)
                                        {
                                            string[] parm = line.Split('=');
                                            if (parm.Length > 2)
                                            {
                                                continue;
                                            }
                                            parm[0] = parm[0].Trim().ToLower();
                                            parm[1] = parm[1].Trim();
                                            switch (parm[0])
                                            {
                                            case "path":
                                                mod.Path = parm[1].Replace(@"\", "/");
                                                break;

                                            case "comment":
                                                mod.Comment = parm[1];
                                                break;

                                            case "read only":
                                                mod.ReadOnly = (parm[1].CompareTo("false") == 0) ? false : true;
                                                break;

                                            case "write only":
                                                mod.WriteOnly = (parm[1].CompareTo("true") == 0) ? true : false;
                                                break;

                                            case "hosts allow":
                                                mod.HostsAllow = parm[1];
                                                break;

                                            case "hosts deny":
                                                mod.HostsDeny = parm[1];
                                                break;

                                            case "auth users":
                                                mod.AuthUsers = parm[1];
                                                break;

                                            case "secrets file":
                                                mod.SecretsFile = Path.GetFileName(parm[1]);
                                                break;

                                            default:
                                                continue;
                                            }
                                        }
                                        else
                                        {
                                            string[] parm = line.Split('=');
                                            if (parm.Length > 2)
                                            {
                                                continue;
                                            }
                                            parm[0] = parm[0].Trim();
                                            parm[1] = parm[1].Trim();
                                            switch (parm[0])
                                            {
                                            case "log file":
                                                string logFile = parm[1];
                                                try
                                                {
                                                    options.logFile = new FileStream(logFile, FileMode.OpenOrCreate | FileMode.Append, FileAccess.Write);
                                                }
                                                catch (Exception e)
                                                {
                                                    Log.Write(e.Message);
                                                }
                                                break;

                                            case "port":
                                                port = parm[1];
                                                options.rsyncPort = Convert.ToInt32(port);
                                                break;

                                            case "address":
                                                options.bindAddress = address = parm[1];
                                                break;

                                            default:
                                                continue;
                                            }
                                        }
                                    }
                                }
                            }
                            cf.Close();
                        }
                    }
                }
                catch
                {
                    MainClass.Exit("failed to open: " + confFile, null);
                    return(false);
                }
            }
            return(true);
        }
Beispiel #4
0
        public int ReceiveFiles(ClientInfo cInfo, ArrayList fileList, string localName)
        {
            FStat      st = new FStat();
            FileStruct file;
            IOStream   f = cInfo.IoStream;

            string fileName;
            string fNameCmp = "", fNameTmp = "";
            bool   saveMakeBackups = options.makeBackups;
            int    i, phase = 0;
            bool   recv_ok;

            if (options.verbose > 2)
            {
                Log.WriteLine("ReceiveFiles(" + fileList.Count + ") starting");
            }
            while (true)
            {
                i = f.readInt();
                if (i == -1)
                {
                    if (phase != 0)
                    {
                        break;
                    }

                    phase = 1;
                    checkSum.cSumLength = CheckSum.SUM_LENGTH;
                    if (options.verbose > 2)
                    {
                        Log.WriteLine("ReceiveFiles phase=" + phase);
                    }
                    f.writeInt(0);                     //send_msg DONE
                    if (options.keepPartial)
                    {
                        options.makeBackups = false;
                    }
                    continue;
                }

                if (i < 0 || i >= fileList.Count)
                {
                    MainClass.Exit("Invalid file index " + i + " in receiveFiles (count=" + fileList.Count + ")", cInfo);
                }

                file = ((FileStruct)fileList[i]);

                Options.stats.currentFileIndex = i;
                Options.stats.numTransferredFiles++;
                Options.stats.totalTransferredSize += file.length;

                if (localName != null && localName.CompareTo("") != 0)
                {
                    fileName = localName;
                }
                else
                {
                    fileName = Path.Combine(options.dir, LocalizePath(cInfo, file.FNameTo().Replace(":", "")).Replace("\\", "/"));
                    //fileName = Path.Combine(options.dir, file.FNameTo().Replace(":","")).Replace("\\", "/");
                    // TODO: path length
                    FileSystem.Directory.CreateDirectory(Path.Combine(options.dir, LocalizePath(cInfo, file.dirName.Replace(":", ""))).Replace("\\", "/"));
                    Log.WriteLine(Path.Combine(options.dir, file.dirName));
                    //FileSystem.Directory.CreateDirectory(Path.Combine(options.dir,file.dirName.Replace(":","")).Replace("\\", "/"));
                }

                if (options.dryRun)
                {
                    if (!options.amServer && options.verbose > 0)
                    {
                        Log.WriteLine(fileName);
                    }
                    continue;
                }

                if (options.verbose > 2)
                {
                    Log.WriteLine("receiveFiles(" + fileName + ")");
                }

                if (options.partialDir != null && options.partialDir.CompareTo("") != 0)
                {
                }
                else
                {
                    fNameCmp = fileName;
                }

                FileStream fd1 = null;
                try
                {
                    fd1 = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read);
                }
                catch (FileNotFoundException)
                {
                    fNameCmp = fileName;
                    try
                    {
                        fd1 = new FileStream(fNameCmp, FileMode.Open, FileAccess.Read);
                    }
                    catch (FileNotFoundException)
                    {
                    }
                }  catch (Exception e)
                {
                    Log.Write(e.Message);
                }
                try
                {
                    FileSystem.FileInfo fi = new FileSystem.FileInfo(fNameCmp);
                    // TODO: path length
                    st.size = fi.Length;
                }
                catch {}

                String     tempFileName = getTmpName(fileName);
                FileStream fd2          = null;
                fd2 = new FileStream(tempFileName, FileMode.OpenOrCreate, FileAccess.Write);

                if (!options.amServer && options.verbose > 0)
                {
                    Log.WriteLine(fileName);
                }

                /* recv file data */
                recv_ok = ReceiveData(cInfo, fNameCmp, fd1, st.size,
                                      fileName, fd2, file.length);

                if (fd1 != null)
                {
                    fd1.Close();
                }
                if (fd2 != null)
                {
                    fd2.Close();
                }
                // TODO: path length
                FileSystem.File.Copy(tempFileName, fileName, true);
                // TODO: path length
                FileSystem.File.Delete(tempFileName);
                if (recv_ok || options.inplace)
                {
                    FinishTransfer(fileName, fNameTmp, file, recv_ok);
                }
            }
            options.makeBackups = saveMakeBackups;

            if (options.deleteAfter && options.recurse && localName == null && fileList.Count > 0)
            {
                DeleteFiles(fileList);
            }

            if (options.verbose > 2)
            {
                Log.WriteLine("ReceiveFiles finished");
            }

            return(0);
        }
Beispiel #5
0
        public bool ReceiveData(ClientInfo cInfo, string fileNameR, Stream fdR, long sizeR, string fileName, Stream fd, int totalSize)
        {
            IOStream f = cInfo.IoStream;

            byte[]    file_sum1 = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[]    file_sum2 = new byte[CheckSum.MD4_SUM_LENGTH];
            byte[]    data      = new byte[Match.CHUNK_SIZE];
            SumStruct sum       = new SumStruct();
            MapFile   mapBuf    = null;
            Sender    sender    = new Sender(options);

            sender.ReadSumHead(cInfo, ref sum);
            int    offset = 0;
            UInt32 len;

            if (fdR != null && sizeR > 0)
            {
                int mapSize = (int)Math.Max(sum.bLength * 2, 16 * 1024);
                mapBuf = new MapFile(fdR, (int)sizeR, mapSize, (int)sum.bLength);
                if (options.verbose > 2)
                {
                    Log.WriteLine("recv mapped " + fileNameR + " of size " + sizeR);
                }
                ;
            }
            Sum s = new Sum(options);

            s.Init(options.checksumSeed);

            int   i;
            Token token = new Token(options);

            while ((i = token.ReceiveToken(f, ref data, 0)) != 0)
            {
                if (options.doProgress)
                {
                    Progress.ShowProgress(offset, totalSize);
                }

                if (i > 0)
                {
                    if (options.verbose > 3)
                    {
                        Log.WriteLine("data recv " + i + " at " + offset);
                    }
                    Options.stats.literalData += i;
                    s.Update(data, 0, i);
                    if (fd != null && FileIO.WriteFile(fd, data, 0, i) != i)
                    {
                        goto report_write_error;
                    }
                    offset += i;
                    continue;
                }

                i = -(i + 1);
                int offset2 = (int)(i * sum.bLength);
                len = sum.bLength;
                if (i == sum.count - 1 && sum.remainder != 0)
                {
                    len = sum.remainder;
                }

                Options.stats.matchedData += len;

                if (options.verbose > 3)
                {
                    Log.WriteLine("chunk[" + i + "] of size " + len + " at " + offset2 + " offset=" + offset);
                }

                byte[] map = null;
                int    off = 0;
                if (mapBuf != null)
                {
                    off = mapBuf.MapPtr(offset2, (int)len);
                    map = mapBuf.p;

                    token.SeeToken(map, offset, (int)len);
                    s.Update(map, off, (int)len);
                }

                if (options.inplace)
                {
                    if (offset == offset2 && fd != null)
                    {
                        offset += (int)len;
                        if (fd.Seek(len, SeekOrigin.Current) != offset)
                        {
                            MainClass.Exit("seek failed on " + Util.fullFileName(fileName), cInfo);
                        }
                        continue;
                    }
                }
                if (fd != null && FileIO.WriteFile(fd, map, off, (int)len) != (int)len)
                {
                    goto report_write_error;
                }
                offset += (int)len;
            }

            if (options.doProgress)
            {
                Progress.EndProgress(totalSize);
            }
            if (fd != null && offset > 0 && FileIO.SparseEnd(fd) != 0)
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), cInfo);
            }

            file_sum1 = s.End();

            if (mapBuf != null)
            {
                mapBuf = null;
            }

            file_sum2 = f.ReadBuf(CheckSum.MD4_SUM_LENGTH);
            if (options.verbose > 2)
            {
                Log.WriteLine("got fileSum");
            }
            if (fd != null && Util.MemCmp(file_sum1, 0, file_sum2, 0, CheckSum.MD4_SUM_LENGTH) != 0)
            {
                return(false);
            }
            return(true);

report_write_error:
            {
                MainClass.Exit("write failed on " + Util.fullFileName(fileName), cInfo);
            }
            return(true);
        }
Beispiel #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="clientInfo"></param>
        /// <param name="moduleNumber"></param>
        /// <returns></returns>
        public static void RsyncModule(ClientInfo clientInfo, int moduleNumber) //@fixed Why return something if result not used?
        {
            string   path     = Daemon.config.GetModule(moduleNumber).Path;
            string   name     = Daemon.config.GetModuleName(moduleNumber);
            IOStream ioStream = clientInfo.IoStream;
            Options  options  = clientInfo.Options;

            string[] args = new string[Options.MAX_ARGS];
            int      argc = 0, maxArgs = Options.MAX_ARGS;
            string   line = String.Empty;

            if (path[0] == '/')
            {
                path = path.Remove(0, 1);
            }
            path = path.Replace("\n", String.Empty);

            Access ac = new Access();

            if (!ac.AllowAccess(options.remoteAddr, options.remoteHost, Daemon.config.GetHostsAllow(moduleNumber), Daemon.config.GetHostsDeny(moduleNumber)))
            {
                Log.Write("rsync denied on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")");
                ioStream.IOPrintf("@ERROR: access denied to " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n");
                return;
            }

            if (!Authentication.AuthorizeServer(clientInfo, moduleNumber, options.remoteAddr, "@RSYNCD: AUTHREQD "))
            {
                Log.Write("auth failed on module " + name + " from " + options.remoteHost + " (" + options.remoteAddr + ")\n");
                ioStream.IOPrintf("@ERROR: auth failed on module " + name + "\n");
                return;
            }
            // TODO: path length
            if (Directory.Exists(path))
            {
                ioStream.IOPrintf("@RSYNCD: OK\n");
            }
            else
            {
                try
                {
                    // TODO: path length
                    Directory.CreateDirectory(path);
                    ioStream.IOPrintf("@RSYNCD: OK\n");
                }
                catch (Exception)
                {
                    ioStream.IOPrintf("@ERROR: Path not found\n");
                    MainClass.Exit("@ERROR: Path not found: " + path, clientInfo);
                }
            }
            options.amServer = true;    //to fix error in SetupProtocol
            options.dir      = path;

            while (true)
            {
                line = ioStream.ReadLine();
                line = line.Substring(0, line.Length - 1);
                if (line.CompareTo(String.Empty) == 0)
                {
                    break;
                }
                if (argc == maxArgs)
                {
                    maxArgs += Options.MAX_ARGS;
                    MapFile.ExtendArray(ref args, maxArgs);
                }
                args[argc++] = line;
            }
            args[argc++] = path;

            options.verbose = 0;
            int argsNotUsed = CommandLineParser.ParseArguments(args, options);

            if (argsNotUsed == -1)
            {
                MainClass.Exit("Error parsing options", clientInfo);
            }
            string[] args2 = new string[argsNotUsed];
            for (int i = 0; i < argsNotUsed; i++)
            {
                args2[i] = args[args.Length - argsNotUsed + i];
            }

            MainClass.SetupProtocol(clientInfo);
            ioStream.IOStartMultiplexOut();
            Daemon.StartServer(clientInfo, args2);
        }