func main() { goopt.Author = "William Pearson" goopt.Version = "Rm" goopt.Summary = "Remove each FILE" goopt.Usage = func() string { return fmt.Sprintf("Usage:\t%s [OPTION]... FILE...\n", os.Args[0]) + goopt.Summary + "\n\n" + goopt.Help() } goopt.Description = func() string { return goopt.Summary + "\n\nUnless --help or --version is passed." } force = goopt.Flag([]string{"-f", "--force"}, nil, "Ignore nonexistent files, don't prompt user", "") prompteach = goopt.Flag([]string{"-i"}, nil, "Prompt before each removal", "") promptonce = goopt.Flag([]string{"-I"}, nil, "Prompt before removing multiple files at once", "") goopt.OptArg([]string{"--interactive"}, "WHEN", "Prompt according to WHEN", setPrompt) /*onefs := goopt.Flag([]string{"--one-file-system"}, nil, "When -r is specified, skip directories on different filesystems", "")*/ nopreserveroot := goopt.Flag([]string{"--no-preserve-root"}, []string{"--preserve-root"}, "Do not treat '/' specially", "Do not remove '/' (This is default)") recurse := goopt.Flag([]string{"-r", "-R", "--recursive"}, nil, "Recursively remove directories and their contents", "") emptydir := goopt.Flag([]string{"-d", "--dir"}, nil, "Remove empty directories", "") verbose := goopt.Flag([]string{"-v", "--verbose"}, nil, "Output each file as it is processed", "") goopt.NoArg([]string{"--version"}, "outputs version information and exits", coreutils.Version) goopt.Parse(nil) promptno := true var filenames []string if len(goopt.Args) == 0 { coreutils.PrintUsage() } coreutils.Preserveroot = !*nopreserveroot coreutils.Silent = *force coreutils.Prompt = *prompteach || *promptonce coreutils.PromptFunc = func(filename string, remove bool) bool { var prompt string if remove { prompt = "Remove " + filename + "?" } else { prompt = "Recurse into " + filename + "?" } var response string trueresponse := "yes" falseresponse := "no" for { fmt.Print(prompt) fmt.Scanln(&response) response = strings.ToLower(response) if strings.Contains(trueresponse, response) { return true } else if strings.Contains(falseresponse, response) || response == "" { return false } } } for i := range goopt.Args { _, err := os.Lstat(goopt.Args[i]) if *force && os.IsNotExist(err) { continue } if err != nil { fmt.Fprintf(os.Stderr, "Error getting file info for '%s': %v\n", goopt.Args[i], err) defer os.Exit(1) continue } filenames = append(filenames, goopt.Args[i]) if *recurse { if coreutils.Recurse(&filenames) { defer os.Exit(1) } } } sort.Strings(filenames) l := len(filenames) - 1 for i := range filenames { fileinfo, err := os.Lstat(filenames[l-i]) if err != nil { fmt.Fprintf(os.Stderr, "Error getting file info for '%s': %v\n", filenames[l-i], err) defer os.Exit(1) continue } isadir := fileinfo.IsDir() if *prompteach || *promptonce && (l-i)%3 == 1 { promptno = coreutils.PromptFunc(filenames[l-i], true) } if !promptno { continue } if !*emptydir && !*recurse && isadir { fmt.Fprintf(os.Stderr, "Could not remove '%s': Is a directory\n", filenames[l-i]) defer os.Exit(1) continue } if *verbose { fmt.Printf("Removing '%s'\n", filenames[l-i]) } err = os.Remove(filenames[l-i]) if err != nil && !(*force && os.IsNotExist(err)) { fmt.Fprintf(os.Stderr, "Could not remove '%s': %v\n", filenames[l-i], err) defer os.Exit(1) } } return }
func main() { goopt.Author = "William Pearson" goopt.Version = "Cp" goopt.Summary = "Copy each SOURCE to DEST" goopt.Usage = func() string { return fmt.Sprintf("Usage:\t%s [OPTION]... SOURCE(...) DEST\n or:\t%s [OPTION]... -t DEST SOURCE\n", os.Args[0], os.Args[0]) + goopt.Summary + "\n\n" + goopt.Help() } goopt.Description = func() string { return goopt.Summary + "\n\nUnless --help or --version is passed." } backup := goopt.Flag([]string{"-b", "--backup"}, nil, "Backup files before overwriting", "") prompt := goopt.Flag([]string{"-i", "--interactive"}, nil, "Prompt before an overwrite. Override -f and -n.", "") noclobber := goopt.Flag([]string{"-n", "--no-clobber"}, []string{"-f", "--force"}, "Do not overwrite", "Never prompt before an overwrite") hardlink := goopt.Flag([]string{"-l", "--link"}, nil, "Make hard links instead of copying", "") nodereference := goopt.Flag([]string{"-P", "--no-dereference"}, []string{"-L", "--dereference"}, "Never follow symlinks", "Always follow symlinks") /*preserve := goopt.Flag([]string{"-p", "--preserve"}, nil, "Preserve mode, ownership and timestamp attributes", "")*/ recurse := goopt.Flag([]string{"-r", "-R", "--recurse"}, nil, "Recursively copy files from SOURCE to TARGET", "") goopt.OptArg([]string{"-S", "--suffix"}, "SUFFIX", "Override the usual backup suffix", setBackupSuffix) symlink := goopt.Flag([]string{"-s", "--symbolic-link"}, nil, "Make symlinks instead of copying", "") goopt.OptArg([]string{"-t", "--target"}, "TARGET", "Set the target with a flag instead of at the end", setTarget) update := goopt.Flag([]string{"-u", "--update"}, nil, "Move only when DEST is missing or older than SOURCE", "") verbose := goopt.Flag([]string{"-v", "--verbose"}, nil, "Output each file as it is processed", "") goopt.NoArg([]string{"--version"}, "outputs version information and exits", coreutils.Version) goopt.Parse(nil) if len(goopt.Args) < 2 { coreutils.PrintUsage() } coreutils.Noderef = *nodereference j := 0 if target == "" { target = goopt.Args[len(goopt.Args)-1] j = 1 } var sources []string for i := range goopt.Args[j:] { sources = append(sources, goopt.Args[i]) if *recurse { if coreutils.Recurse(&sources) { defer os.Exit(1) } } } destinfo, err := coreutils.Stat(target) if err != nil && !os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "Error trying to get info to check if DEST is a directory: %v\n", err) os.Exit(1) } isadir := err == nil && destinfo.IsDir() if (len(goopt.Args) > 2 || (target != goopt.Args[len(goopt.Args)-1] && len(goopt.Args) > 1)) && !isadir { fmt.Fprintf(os.Stderr, "Too many arguments for non-directory destination") os.Exit(1) } for i := range sources { dest := target if sources[i] == "" { continue } destinfo, err := coreutils.Stat(target) exist := !os.IsNotExist(err) if err != nil && exist { fmt.Fprintf(os.Stderr, "Error trying to get info on target: %v\n", err) os.Exit(1) } srcinfo, err := coreutils.Stat(sources[i]) if err != nil { fmt.Fprintf(os.Stderr, "Error trying to get mod time on SRC: %v\n", err) os.Exit(1) } mkdir := false if srcinfo.IsDir() { if isadir { dest = dest + string(os.PathSeparator) + sources[i] } if !*recurse { fmt.Printf("Skipping directory %s\n", sources[i]) continue } mkdir = true } else if isadir { dest = dest + string(os.PathSeparator) + filepath.Base(sources[i]) } newer := true if *update && exist { newer = srcinfo.ModTime().After(destinfo.ModTime()) } if !newer { continue } promptres := true if exist { promptres = !*noclobber if *prompt { promptres = coreutils.PromptFunc(dest, false) } if promptres && *backup { if err = os.Rename(dest, dest+backupsuffix); err != nil { fmt.Fprintf(os.Stderr, "Error while backing up '%s' to '%s': %v\n", dest, dest+backupsuffix, err) defer os.Exit(1) continue } } } if !promptres { continue } switch { case mkdir: if err = os.Mkdir(dest, coreutils.Mode); err != nil { fmt.Fprintf(os.Stderr, "Error while making directory '%s': %v\n", dest, err) defer os.Exit(1) continue } if *verbose { fmt.Printf("Copying directory '%s' to '%s'\n", sources[i], dest) } case *hardlink: if err := os.Link(sources[i], dest); err != nil { fmt.Fprintf(os.Stderr, "Error while linking '%s' to '%s': %v\n", dest, sources[i], err) defer os.Exit(1) continue } if *verbose { fmt.Printf("Linked '%s' to '%s'\n", dest, sources[i]) } case *symlink: if err := os.Symlink(sources[i], dest); err != nil { fmt.Fprintf(os.Stderr, "Error while linking '%s' to '%s': %v\n", dest, sources[i], err) defer os.Exit(1) continue } if *verbose { fmt.Printf("Symlinked '%s' to '%s'\n", dest, sources[i]) } default: source, err := os.Open(sources[i]) if err != nil { fmt.Fprintf(os.Stderr, "Error while opening source file '%s': %v\n", sources[i], err) defer os.Exit(1) continue } filebuf, err := ioutil.ReadAll(source) if err != nil { fmt.Fprintf(os.Stderr, "Error while reading source file, '%s', for copying: %v\n", sources[i], err) defer os.Exit(1) continue } destfile, err := os.Create(dest) if err != nil { fmt.Fprintf(os.Stderr, "Error while creating destination file, '%s': %v\n", dest, err) defer os.Exit(1) continue } destfile.Write(filebuf) if *verbose { fmt.Printf("'%s' copied to '%s'\n", sources[i], dest) } } } return }
func main() { goopt.Author = "William Pearson" goopt.Version = "Mv" goopt.Summary = "Move (rename) each SOURCE to DEST" goopt.Usage = func() string { return fmt.Sprintf("Usage:\t%s [OPTION]... SOURCE(...) DEST\n or:\t%s [OPTION]... -t DEST SOURCE\n", os.Args[0], os.Args[0]) + goopt.Summary + "\n\n" + goopt.Help() } goopt.Description = func() string { return goopt.Summary + "\n\nUnless --help or --version is passed." } prompt := goopt.Flag([]string{"-i", "--interactive"}, nil, "Prompt before an overwrite. Override -f and -n.", "") noclobber := goopt.Flag([]string{"-n", "--no-clobber"}, []string{"-f", "--force"}, "Do not overwrite", "Never prompt before an overwrite") backup := goopt.Flag([]string{"-b", "--backup"}, nil, "Backup files before overwriting", "") goopt.OptArg([]string{"-S", "--suffix"}, "SUFFIX", "Override the usual backup suffix", coreutils.SetBackupSuffix) goopt.OptArg([]string{"-t", "--target"}, "TARGET", "Set the target with a flag instead of at the end", coreutils.SetTarget) update := goopt.Flag([]string{"-u", "--update"}, nil, "Move only when DEST is missing or older than SOURCE", "") verbose := goopt.Flag([]string{"-v", "--verbose"}, nil, "Output each file as it is processed", "") goopt.NoArg([]string{"--version"}, "outputs version information and exits", coreutils.Version) goopt.Parse(nil) if len(goopt.Args) < 2 { coreutils.PrintUsage() } if coreutils.Target == "" { coreutils.Target = goopt.Args[len(goopt.Args)-1] } destinfo, err := os.Lstat(coreutils.Target) if err != nil && !os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "Error trying to get info to check if DEST is a directory: %v\n", err) os.Exit(1) } isadir := err == nil && destinfo.IsDir() if (len(goopt.Args) > 2 || (coreutils.Target != goopt.Args[len(goopt.Args)-1] && len(goopt.Args) > 1)) && !isadir { fmt.Fprintf(os.Stderr, "Too many arguments for non-directory destination") os.Exit(1) } for i := range goopt.Args[1:] { dest := coreutils.Target if isadir { dest = dest + string(os.PathSeparator) + filepath.Base(goopt.Args[i]) } destinfo, err := os.Lstat(dest) exist := !os.IsNotExist(err) newer := true if err != nil && exist { fmt.Fprintf(os.Stderr, "Error trying to get info on target: %v\n", err) os.Exit(1) } if *update && exist { srcinfo, err := os.Lstat(goopt.Args[i]) if err != nil { fmt.Fprintf(os.Stderr, "Error trying to get mod time on SRC: %v\n", err) os.Exit(1) } newer = srcinfo.ModTime().After(destinfo.ModTime()) } if !newer { continue } promptres := true if exist { promptres = !*noclobber if *prompt { promptres = coreutils.PromptFunc(dest, false) } if promptres && *backup { coreutils.Backup(dest) } } if promptres { err = os.Rename(goopt.Args[i], dest) if err != nil { fmt.Fprintf(os.Stderr, "Error while moving '%s' to '%s': %v\n", goopt.Args[i], dest, err) defer os.Exit(1) continue } if *verbose { fmt.Printf("%s -> %s\n", goopt.Args[i], dest) } } } return }
func main() { goopt.Author = "William Pearson" goopt.Version = "Ln" goopt.Summary = "Make a LINK (whose name is optionally specified) to TARGET or make a link in DIRECTORY to each TARGET." goopt.Usage = func() string { return fmt.Sprintf("Usage:\t%s [OPTION]... TARGET (LINK)\n or:\t%s [OPTION]... TARGET... DIRECTORY\n or:\t%s [OPTION]... -t DIRECTORY TARGET...\n", os.Args[0], os.Args[0]) + goopt.Summary + "\n\n" + goopt.Help() } goopt.Description = func() string { return goopt.Summary + "\n\nUnless --help or --version is passed." } backup := goopt.Flag([]string{"-b", "--backup"}, nil, "Backup files before overwriting", "") prompt := goopt.Flag([]string{"-i", "--interactive"}, nil, "Prompt before removing any existing files.", "") force := goopt.Flag([]string{"-f", "--force"}, nil, "Remove existing files which match link names", "") directories := goopt.Flag([]string{"-d", "-F", "--directory"}, nil, "Allow attempts to hard link directories", "") nodereference := goopt.Flag([]string{"-n", "--no-dereference"}, nil, "treat LINK as a normal file if it is a symbolic link", "") logical := goopt.Flag([]string{"-L", "--logical"}, []string{"-P", "--physical"}, "Dereference TARGET if it is a symbolic link", "Make hard links directly to symbolic links. (this is default)") relative := goopt.Flag([]string{"-r", "--relative"}, nil, "Make symbolic links relative to link location", "") symbolic := goopt.Flag([]string{"-s", "--symbolic"}, nil, "Make symbolic links rather than hard links", "") goopt.OptArg([]string{"-S", "--suffix"}, "SUFFIX", "Override the usual backup suffix", coreutils.SetBackupSuffix) goopt.OptArg([]string{"-t", "--target"}, "TARGET", "Set the target with a flag instead of at the end", coreutils.SetTarget) verbose := goopt.Flag([]string{"-v", "--verbose"}, nil, "Output each file as it is processed", "") goopt.NoArg([]string{"--version"}, "outputs version information and exits", coreutils.Version) goopt.Parse(nil) if len(goopt.Args) < 2 { coreutils.PrintUsage() } coreutils.Noderef = *nodereference i := 0 isadir := false exists := false if coreutils.Target == "" { if len(goopt.Args) > 1 { i = 1 coreutils.Target = goopt.Args[len(goopt.Args)-1] } else { coreutils.Target = filepath.Base(goopt.Args[0]) } } else { isadir = true } fileinfo, err := coreutils.Stat(coreutils.Target) if err != nil && !os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "Error getting file info for '%s': %v\n", coreutils.Target, err) os.Exit(1) } if err == nil { exists = true if fileinfo.IsDir() { isadir = true } } for j := range goopt.Args[i:] { coreutils.Noderef = !*logical fileinfo, err = coreutils.Stat(goopt.Args[j]) if err != nil && !os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "Error getting file info for '%s': %v\n", goopt.Args[j], err) defer os.Exit(1) continue } if err == nil && !*symbolic && !*directories && fileinfo.IsDir() { fmt.Fprintf(os.Stderr, "Attempt to hard link a directory") defer os.Exit(1) continue } coreutils.Noderef = *nodereference dest := coreutils.Target if isadir { dest = dest + filepath.Base(goopt.Args[j]) fileinfo, err = coreutils.Stat(dest) if err != nil && !os.IsNotExist(err) { fmt.Fprintf(os.Stderr, "Error getting file info for '%s': %v\n", dest, err) defer os.Exit(1) continue } if err == nil { exists = true } } promptno := true if exists { if *backup { coreutils.Backup(dest) } if *force { os.Remove(dest) } else if *prompt { promptno = coreutils.PromptFunc(dest, false) if promptno { os.Remove(dest) } } if !*relative { dest, err = filepath.Abs(dest) if err != nil { fmt.Fprintf(os.Stderr, "Error making absolute path from '%s'", dest, err) } } } if !promptno { exists = false continue } if *symbolic { os.Symlink(goopt.Args[j], dest) } else { os.Link(goopt.Args[j], dest) } if *verbose { fmt.Printf("'%s' -> '%s'\n", dest, goopt.Args[j]) } exists = false } return }