Example #1
0
        public TargetExistsAction TargetExists(string file, DateTime sourceTime, long sourceSize, DateTime targetTime, long targetSize, bool multiple)
        {
            const int          padding    = 14;
            const int          minEllipse = 22;
            const string       fmt        = "Target file \"{0}\" already exists";
            TargetExistsAction result     = TargetExistsAction.Cancel;

            var msg = String.Format(fmt, file);

            if (msg.Length > Terminal.Cols - padding)
            {
                msg = String.Format(fmt, file.Ellipsize(Terminal.Cols - 8 - fmt.Length));
            }

            var d = new Dialog(msg.Length + padding, 13 + (multiple ? 3 : 0), "File exists");

            d.ErrorColors();
            d.Add(new Label(2, 1, msg));
            // TODO: compute what changes actually matter (year, month, day, hour, minute)
            d.Add(new Label(2, 3, String.Format("Source date: {0}, size {1}", sourceTime, sourceSize)));
            d.Add(new Label(2, 4, String.Format("Target date: {0}, size {1}", targetTime, targetSize)));
            d.Add(new Label(2, 6, "Override this target?"));
            MakeButton(d, 24, 6, "Yes", () => result    = TargetExistsAction.Overwrite);
            MakeButton(d, 32, 6, "No", () => result     = TargetExistsAction.Skip);
            MakeButton(d, 39, 6, "Append", () => result = TargetExistsAction.Append);
            if (multiple)
            {
                d.Add(new Label(2, 8, "Override all targets?"));
                MakeButton(d, 24, 8, "aLl", () => result             = TargetExistsAction.AlwaysOverwrite);
                MakeButton(d, 32, 8, "Update", () => result          = TargetExistsAction.AlwaysUpdate);
                MakeButton(d, 43, 8, "None", () => result            = TargetExistsAction.AlwaysSkip);
                MakeButton(d, 24, 9, "if Size differs", () => result = TargetExistsAction.AlwaysUpdateOnSizeMismatch);
            }
            MakeButton(d, (d.w - 4 - "Cancel".Length) / 2, 8 + (multiple ? 3 : 0), "Cancel", () => {
            });
            Terminal.Run(d);
            return(result);
        }
Example #2
0
        bool CopyFile(string source_absolute_path, string target_path)
        {
            bool ret           = false;
            bool target_exists = false;
            // Stat target
            Stat tstat;

            lock (this)
                ProcessedFiles++;

            while (Syscall.stat(target_path, out tstat) == 0)
            {
                if (tstat.st_mode.HasFlag(FilePermissions.S_IFDIR))
                {
                    if (ShouldRetryOperation("Target file is a directory", "Source file \"{0}\"",
                                             Path.GetFileName(source_absolute_path)))
                    {
                        continue;
                    }
                    return(false);
                }
                else
                {
                    target_exists = true;
                }
                break;
            }

            // Open Source
            int source_fd;

            while (true)
            {
                source_fd = Syscall.open(source_absolute_path, OpenFlags.O_RDONLY, (FilePermissions)0);
                if (source_fd != -1)
                {
                    break;
                }

                if (ShouldRetryOperation("While opening \"{0}\"", target_path))
                {
                    continue;
                }
                return(false);
            }
            Stat stat;

            while (true)
            {
                if (Syscall.fstat(source_fd, out stat) != -1)
                {
                    break;
                }

                if (ShouldRetryOperation("While probing for state of \"{0}\"", target_path))
                {
                    continue;
                }
                goto close_source;
            }

            // Make sure we are not overwriting the same file
            if (stat.st_dev == tstat.st_dev && stat.st_ino == tstat.st_ino)
            {
                Interaction.Error("Can not copy a file into itself");
                skip = true;
                goto close_source;
            }

            lock (this) {
                CurrentFileProgress = 0;
                CurrentFileSize     = tstat.st_size;
            }

            if (target_exists)
            {
                if (target_exists_action < TargetExistsAction.AlwaysOverwrite)
                {
                    target_exists_action = Interaction.TargetExists(
                        target_path,
                        NativeConvert.ToDateTime(stat.st_mtime), stat.st_size,
                        NativeConvert.ToDateTime(tstat.st_mtime), tstat.st_size, Interaction.Count > 1);
                }

                if (target_exists_action == TargetExistsAction.Cancel)
                {
                    goto close_source;
                }

                if (target_exists_action == TargetExistsAction.Skip)
                {
                    goto close_source;
                }
            }

            // Open target
            int target_fd;

            switch (target_exists_action)
            {
            case TargetExistsAction.AlwaysUpdate:
                if (stat.st_mtime > tstat.st_mtime)
                {
                    goto case TargetExistsAction.Overwrite;
                }
                skip = true;
                goto close_source;

            case TargetExistsAction.AlwaysUpdateOnSizeMismatch:
                if (stat.st_size != tstat.st_size)
                {
                    goto case TargetExistsAction.Overwrite;
                }
                skip = true;
                goto close_source;


            // Real cancels are taken care of immediately after the dialog
            // this means: never used, target does not exist.
            case TargetExistsAction.Cancel:
            case TargetExistsAction.AlwaysOverwrite:
            case TargetExistsAction.Overwrite:
                target_fd = Syscall.open(target_path, OpenFlags.O_CREAT | OpenFlags.O_WRONLY, FilePermissions.S_IWUSR);
                break;

            case TargetExistsAction.Append:
                target_fd = Syscall.open(target_path, OpenFlags.O_APPEND, FilePermissions.S_IWUSR);
                break;

            default:
                throw new Exception(String.Format("Internal error: unhandled TargetExistsAction value {0}", target_exists_action));
            }

            while (true)
            {
                if (target_fd != -1)
                {
                    break;
                }
                if (ShouldRetryOperation("While creating \"{0}\"", target_path))
                {
                    continue;
                }
                goto close_source;
            }

            AllocateBuffer();
            long n;

            do
            {
                while (true)
                {
                    n = Syscall.read(source_fd, io_buffer, COPY_BUFFER_SIZE);

                    if (n != -1)
                    {
                        break;
                    }

                    if (ShouldRetryOperation("While reading \"{0}\"", Path.GetFileName(source_absolute_path)))
                    {
                        continue;
                    }
                    goto close_both;
                }
                while (true)
                {
                    long count = Syscall.write(target_fd, io_buffer, (ulong)n);
                    if (count != -1)
                    {
                        break;
                    }

                    if (ShouldRetryOperation("While writing \"{0}\"", target_path))
                    {
                        continue;
                    }
                    goto close_both;
                }
                lock (this) {
                    ProcessedBytes  += n;
                    CurrentFileSize += n;
                }
            } while (n != 0);

            // File mode
            while (true)
            {
                n = Syscall.fchmod(target_fd, stat.st_mode);
                if (n == 0)
                {
                    break;
                }

                if (ShouldRetryOperation("Setting permissions on \"{0}\"", target_path))
                {
                    continue;
                }

                goto close_both;
            }

            // The following are not considered errors if we can not set them
            ret = true;

            // preserve owner and group if running as root
            if (Syscall.geteuid() == 0)
            {
                Syscall.fchown(target_fd, stat.st_uid, stat.st_gid);
            }

            // Set file time
            Timeval[] dates = new Timeval [2] {
                new Timeval()
                {
                    tv_sec = stat.st_atime
                },
                new Timeval()
                {
                    tv_sec = stat.st_mtime
                }
            };
            Syscall.futimes(target_fd, dates);

close_both:
            Syscall.close(target_fd);
close_source:
            Syscall.close(source_fd);
            return(ret);
        }
Example #3
0
File: fileops.cs Project: arg/mc
        bool CopyFile(string source_absolute_path, string target_path)
        {
            bool ret = false;
            bool target_exists = false;
            // Stat target
            Stat tstat;

            lock (this)
                ProcessedFiles++;

            while (Syscall.stat (target_path, out tstat) == 0){
                if (tstat.st_mode.HasFlag (FilePermissions.S_IFDIR)){
                    if (ShouldRetryOperation ("Target file is a directory", "Source file \"{0}\"",
                                  Path.GetFileName (source_absolute_path)))
                        continue;
                    return false;
                } else {
                    target_exists = true;
                }
                break;
            }

            // Open Source
            int source_fd;
            while (true){
                source_fd = Syscall.open (source_absolute_path, OpenFlags.O_RDONLY, (FilePermissions) 0);
                if (source_fd != -1)
                    break;

                if (ShouldRetryOperation ("While opening \"{0}\"", target_path))
                    continue;
                return false;
            }
            Stat stat;
            while (true){
                if (Syscall.fstat (source_fd, out stat) != -1)
                    break;

                if (ShouldRetryOperation ("While probing for state of \"{0}\"", target_path))
                    continue;
                goto close_source;
            }

            // Make sure we are not overwriting the same file
            if (stat.st_dev == tstat.st_dev && stat.st_ino == tstat.st_ino){
                Interaction.Error ("Can not copy a file into itself");
                skip = true;
                goto close_source;
            }

            lock (this){
                CurrentFileProgress = 0;
                CurrentFileSize = tstat.st_size;
            }

            if (target_exists){
                if (target_exists_action < TargetExistsAction.AlwaysOverwrite){
                    target_exists_action = Interaction.TargetExists (
                        target_path,
                        NativeConvert.ToDateTime (stat.st_mtime), stat.st_size,
                        NativeConvert.ToDateTime (tstat.st_mtime), tstat.st_size, Interaction.Count > 1);
                }

                if (target_exists_action == TargetExistsAction.Cancel)
                    goto close_source;

                if (target_exists_action == TargetExistsAction.Skip)
                    goto close_source;
            }

            // Open target
            int target_fd;

            switch (target_exists_action){
            case TargetExistsAction.AlwaysUpdate:
                if (stat.st_mtime > tstat.st_mtime)
                    goto case TargetExistsAction.Overwrite;
                skip = true;
                goto close_source;

            case TargetExistsAction.AlwaysUpdateOnSizeMismatch:
                if (stat.st_size != tstat.st_size)
                    goto case TargetExistsAction.Overwrite;
                skip = true;
                goto close_source;

                // Real cancels are taken care of immediately after the dialog
                // this means: never used, target does not exist.
            case TargetExistsAction.Cancel:
            case TargetExistsAction.AlwaysOverwrite:
            case TargetExistsAction.Overwrite:
                target_fd = Syscall.open (target_path, OpenFlags.O_CREAT | OpenFlags.O_WRONLY, FilePermissions.S_IWUSR);
                break;

            case TargetExistsAction.Append:
                target_fd = Syscall.open (target_path, OpenFlags.O_APPEND, FilePermissions.S_IWUSR);
                break;
            default:
                throw new Exception (String.Format ("Internal error: unhandled TargetExistsAction value {0}", target_exists_action));
            }

            while (true){

                if (target_fd != -1)
                    break;
                if (ShouldRetryOperation ("While creating \"{0}\"", target_path))
                    continue;
                goto close_source;
            }

            AllocateBuffer ();
            long n;

            do {
                while (true){
                    n = Syscall.read (source_fd, io_buffer, COPY_BUFFER_SIZE);

                    if (n != -1)
                        break;

                    if (ShouldRetryOperation ("While reading \"{0}\"", Path.GetFileName (source_absolute_path)))
                        continue;
                    goto close_both;
                }
                while (true){
                    long count = Syscall.write (target_fd, io_buffer, (ulong) n);
                    if (count != -1)
                        break;

                    if (ShouldRetryOperation ("While writing \"{0}\"", target_path))
                        continue;
                    goto close_both;
                }
                lock (this){
                    ProcessedBytes += n;
                    CurrentFileSize += n;
                }
            } while (n != 0);

            // File mode
            while (true){
                n = Syscall.fchmod (target_fd, stat.st_mode);
                if (n == 0)
                    break;

                if (ShouldRetryOperation ("Setting permissions on \"{0}\"", target_path))
                    continue;

                goto close_both;
            }

            // The following are not considered errors if we can not set them
            ret = true;

            // preserve owner and group if running as root
            if (Syscall.geteuid () == 0)
                Syscall.fchown (target_fd, stat.st_uid, stat.st_gid);

            // Set file time
            Timeval [] dates = new Timeval [2] {
                new Timeval () { tv_sec = stat.st_atime },
                new Timeval () { tv_sec = stat.st_mtime }
            };
            Syscall.futimes (target_fd, dates);

            close_both:
            Syscall.close (target_fd);
            close_source:
            Syscall.close (source_fd);
            return ret;
        }