// copy dispatches copy-funcs according to the mode.
// Because this "copy" could be called recursively,
// "info" MUST be given here, NOT nil.
copy dispatches copy-funcs according to the mode.
Because this "copy" could be called recursively,
"info" MUST be given here, NOT nil.
// copy dispatches copy - funcs according to the mode . // Because this " copy " could be called recursively // " info " MUST be given here NOT nil .
func copy(src, dest string, info os.FileInfo) error {
	var err error
	if info.Mode().IsRegular() {
		err = fcopy(src, dest, info)
	} else if info.IsDir() {
		err = dcopy(src, dest, info)
	} else {
		for fileType, handler := range FileTypeCopyHandlers {
			if info.Mode()&fileType != 0 {
				err = handler(src, dest, info)
				break
			}
		}
		err = &UnsupportedFileTypeError{
			mode: info.Mode(),
			path: src,
		}
	}
	if err != nil {
		return err
	}
	var errs []error
	if PreservePermissions {
		if info.Mode()&os.ModeSymlink == 0 {
			err = os.Chmod(dest, info.Mode().Perm())
			if err != nil {
				err = fmt.Errorf("could not restore permissions '%s' for file %s: %w", info.Mode().Perm().String(), dest, err)
				errs = append(errs, err)
			}
		}
	}
	var stat *syscall.Stat_t
	if PreserveOwner || PreserveTime {
		stat, _ = info.Sys().(*syscall.Stat_t)
	}
	if PreserveOwner {
		if stat != nil {
			err = os.Lchown(dest, int(stat.Uid), int(stat.Gid))
			if err != nil {
				err = fmt.Errorf("could not restore owner %d:%d for file %s: %w", stat.Uid, stat.Gid, dest, err)
			}
		} else {
			err = fmt.Errorf("could not restore owner for file %s: %w", dest, err)
		}
		if err != nil {
			errs = append(errs, err)
		}
	}
	if PreserveTime {
		if info.Mode()&os.ModeSymlink == 0 {
			if stat != nil {
				atime := time.Unix(int64(stat.Atim.Sec), int64(stat.Atim.Nsec))
				mtime := info.ModTime()
				err = os.Chtimes(dest, atime, mtime)
				if err != nil {
					err = fmt.Errorf("could not restore timestamp '%s' for file %s: %w", info.ModTime().String(), dest, err)
				}
			} else {
				err = fmt.Errorf("could not restore timestamp for file %s: %w", dest, err)
			}
			if err != nil {
				errs = append(errs, err)
			}
		}
	}
	if len(errs) > 0 {
		return &FileCopyTasksError{
			path:   dest,
			errors: errs,
		}
	} else {
		return nil
	}
}
func copy ( src , dest string , info os . FileInfo ) error { var err error if info . Mode ( ) . IsRegular ( ) { err = fcopy ( src , dest , info ) } else if info . IsDir ( ) { err = dcopy ( src , dest , info ) } else { for fileType , handler := range FileTypeCopyHandlers { if info . Mode ( ) & fileType != 0 { err = handler ( src , dest , info ) break } } err = & UnsupportedFileTypeError { mode : info . Mode ( ) , path : src , } } if err != nil { return err } var errs [ ] error if PreservePermissions { if info . Mode ( ) & os . ModeSymlink == 0 { err = os . Chmod ( dest , info . Mode ( ) . Perm ( ) ) if err != nil { err = fmt . Errorf ( " " , info . Mode ( ) . Perm ( ) . String ( ) , dest , err ) errs = append ( errs , err ) } } } var stat * syscall . Stat_t if PreserveOwner || PreserveTime { stat , _ = info . Sys ( ) . ( * syscall . Stat_t ) } if PreserveOwner { if stat != nil { err = os . Lchown ( dest , int ( stat . Uid ) , int ( stat . Gid ) ) if err != nil { err = fmt . Errorf ( " " , stat . Uid , stat . Gid , dest , err ) } } else { err = fmt . Errorf ( " " , dest , err ) } if err != nil { errs = append ( errs , err ) } } if PreserveTime { if info . Mode ( ) & os . ModeSymlink == 0 { if stat != nil { atime := time . Unix ( int64 ( stat . Atim . Sec ) , int64 ( stat . Atim . Nsec ) ) mtime := info . ModTime ( ) err = os . Chtimes ( dest , atime , mtime ) if err != nil { err = fmt . Errorf ( " " , info . ModTime ( ) . String ( ) , dest , err ) } } else { err = fmt . Errorf ( " " , dest , err ) } if err != nil { errs = append ( errs , err ) } } } if len ( errs ) > 0 { return & FileCopyTasksError { path : dest , errors : errs , } } else { return nil } }
copy dispatches copy-funcs according to the mode.
copy dispatches copy - funcs according to the mode .
// Symbolic links do not have modes, they reflect the permission of the target // For now, we cannot change a symlink times, we need os.LChtimes. Simply ignore.