示例#1
0
// Exec actually performs the head
func (head *SomeHead) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	//TODO do something here!
	if len(head.Filenames) > 0 {
		for _, fileName := range head.Filenames {
			file, err := os.Open(fileName)
			if err != nil {
				return err, 1
			}
			//err = headFile(file, head, invocation.MainPipe.Out)
			err = head.head(invocation.MainPipe.Out, file)
			if err != nil {
				file.Close()
				return err, 1
			}
			err = file.Close()
			if err != nil {
				return err, 1
			}
		}
	} else {
		//stdin ..
		err := head.head(invocation.MainPipe.Out, invocation.MainPipe.In)
		if err != nil {
			return err, 1
		}
	}
	return nil, 0
}
示例#2
0
// Exec actually performs the tee
func (tee *SomeTee) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	flag := os.O_CREATE
	if tee.isAppend {
		flag = flag | os.O_APPEND
	}
	writeables := uggo.ToWriteableOpeners(tee.args, flag, 0666)
	files, err := uggo.OpenAll(writeables)
	if err != nil {
		return err, 1
	}
	writers := []io.Writer{invocation.MainPipe.Out}
	for _, file := range files {
		writers = append(writers, file)
	}
	multiwriter := io.MultiWriter(writers...)
	_, err = io.Copy(multiwriter, invocation.MainPipe.In)
	if err != nil {
		return err, 1
	}
	for _, file := range files {
		err = file.Close()
		if err != nil {
			return err, 1
		}
	}
	return nil, 0

}
示例#3
0
// Exec actually performs the dirname
func (dirname *SomeDirname) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	for _, f := range dirname.Filenames {
		dir := path.Dir(f)
		fmt.Fprintln(invocation.MainPipe.Out, dir)
	}
	return nil, 0
}
示例#4
0
// Exec actually performs the pwd
func (pwd *SomePwd) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	wd, err := os.Getwd()
	if err != nil {
		return err, 1
	}
	fmt.Fprintln(invocation.MainPipe.Out, wd)
	return nil, 0
}
示例#5
0
// Exec actually performs the zip
func (z *SomeZip) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	err := ZipItems(z.zipFilename, z.items)
	if err != nil {
		return err, 1
	}
	return nil, 0

}
示例#6
0
// Exec actually performs the touch
func (touch *SomeTouch) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	for _, filename := range touch.args {
		err := touchFile(filename)
		if err != nil {
			return err, 1
		}
	}
	return nil, 0
}
示例#7
0
func (cat *SomeCat) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	if len(cat.FileNames) > 0 {
		for _, fileName := range cat.FileNames {
			file, err := os.Open(fileName)
			if err != nil {
				return err, 1
			} else {
				if cat.isStraightCopy() {
					_, err = io.Copy(invocation.MainPipe.Out, file)
					if err != nil {
						return err, 1
					}
				} else {
					scanner := bufio.NewScanner(file)
					line := 1
					var prefix string
					var suffix string
					for scanner.Scan() {
						text := scanner.Text()
						if !cat.IsSqueezeBlank || len(strings.TrimSpace(text)) > 0 {
							if cat.IsNumber {
								prefix = fmt.Sprintf("%d ", line)
							} else {
								prefix = ""
							}
							if cat.IsShowEnds {
								suffix = "$"
							} else {
								suffix = ""
							}
							fmt.Fprintf(invocation.MainPipe.Out, "%s%s%s\n", prefix, text, suffix)
						}
						line++
					}
					err := scanner.Err()
					if err != nil {
						return err, 1
					}
				}
				file.Close()
			}
		}
	} else {
		_, err := io.Copy(invocation.MainPipe.Out, invocation.MainPipe.In)
		if err != nil {
			return err, 1
		}
	}
	return nil, 0
}
示例#8
0
// Exec actually performs the which
func (which *SomeWhich) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	path := os.Getenv("PATH")
	if runtime.GOOS == "windows" {
		path = ".;" + path
	}
	pl := filepath.SplitList(path)
	for _, arg := range which.args {
		checkPathParts(arg, pl, which, invocation.MainPipe.Out)
	}
	return nil, 0

}
示例#9
0
// Invoke actually carries out the command
func (tr *SomeTr) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	tr.Preprocess()
	fu := func(inPipe io.Reader, outPipe2 io.Writer, errPipe io.Writer, line []byte) error {
		//println("tr processing line")
		//outline := line
		var buffer bytes.Buffer
		remainder := string(line)
		for len(remainder) > 0 {
			trimLeft := 1
			nextPart := remainder[:trimLeft]
			for reg, v := range tr.translations {
				//fmt.Printf("Translation '%v'=>'%s' on '%s'\n", reg, v, remainder)
				match := reg.MatchString(remainder)
				if match {
					toReplace := reg.FindString(remainder)
					replacement := reg.ReplaceAllString(toReplace, v)
					//fmt.Printf("Replace %s=>%s\n", toReplace, replacement)
					nextPart = replacement
					//if squeezing has taken place, remove more leading chars accordingly
					trimLeft = len(toReplace)
					if !tr.IsComplement {
						break
					}
				} else if tr.IsComplement {
					// this is a double-negative - non-match of negative-regex.
					// This implies that set1 matches the current input character.
					// So, keep it as-is and break out of the loop.
					trimLeft = 1
					nextPart = remainder[:trimLeft]
					break
				}
			}

			remainder = remainder[trimLeft:]
			buffer.WriteString(nextPart)
		}
		out := buffer.String()
		_, err := fmt.Fprintln(outPipe2, out)
		return err
	}
	err := someutils.LineProcessor(invocation.MainPipe.In, invocation.MainPipe.Out, invocation.ErrPipe.Out, fu)
	if err != nil {
		return err, 1
	}
	return nil, 0
}
示例#10
0
// Exec actually performs the unzip
func (unzip *SomeUnzip) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	if unzip.isTest {
		err := TestItems(unzip.zipname, unzip.files, invocation.MainPipe.Out, invocation.ErrPipe.Out)
		if err != nil {
			return err, 1
		}
	} else {
		err := UnzipItems(unzip.zipname, unzip.destDir, unzip.files, invocation.ErrPipe.Out)
		if err != nil {
			return err, 1
		}
	}
	return nil, 0
}
示例#11
0
// Exec actually performs the xargs
func (xargs *SomeXargs) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	util := xargs.utilFactory()
	args := xargs.newArgset(util.Name())
	reader := bufio.NewReader(invocation.MainPipe.In)
	cont := true
	count := 0
	maxCount := 5
	for cont {
		if count >= maxCount {
			count = 0
			//fmt.Fprintf(errPipe, "args for '%s': %v\n", util.Name(), args)
			err, code := util.ParseFlags(args, invocation.ErrPipe.Out)
			if err != nil {
				return err, code
			}
			err, code = util.Invoke(invocation)
			if err != nil {
				return err, code
			}
		}
		line, _, err := reader.ReadLine()
		if err == io.EOF {
			cont = false
		} else if err != nil {
			return err, 1
		} else {
			args = append(args, string(line))
			if err != nil {
				return err, 1
			}
			count++
		}
	}
	//still more args to process
	if count > 0 {
		//fmt.Fprintf(errPipe, "args for '%s': %v\n", util.Name(), args)
		err, code := util.ParseFlags(args, invocation.ErrPipe.Out)
		if err != nil {
			return err, code
		}
		err, code = util.Invoke(invocation)
		return err, code
	}
	return nil, 0
}
示例#12
0
// Exec actually performs the gunzip
func (gunzip *SomeGunzip) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	if gunzip.IsTest {
		err := TestGzipItems(gunzip.Filenames)
		if err != nil {
			return err, 1
		}
	} else {
		err := gunzip.gunzipItems(invocation.MainPipe.In, invocation.MainPipe.Out, invocation.ErrPipe.Out)
		if err != nil {
			return err, 1
		}
	}
	return nil, 0

}
示例#13
0
// Exec actually performs the cp
func (cp *SomeCp) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	for _, srcGlob := range cp.SrcGlobs {
		srces, err := filepath.Glob(srcGlob)
		if err != nil {
			return err, 1
		}
		for _, src := range srces {
			err = copyFile(src, cp.Dest, cp)
			if err != nil {
				return err, 1
			}
		}
	}
	return nil, 0
}
示例#14
0
// Exec actually performs the rm
func (rm *SomeRm) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	for _, fileGlob := range rm.fileGlobs {
		files, err := filepath.Glob(fileGlob)
		if err != nil {
			return err, 1
		}
		for _, file := range files {
			err := delete(file, rm.IsRecursive)
			if err != nil {
				return err, 1
			}
		}
	}

	return nil, 0
}
示例#15
0
// Exec actually performs the basename
func (basename *SomeBasename) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	if basename.RelativeTo != "" {
		last := strings.LastIndex(basename.RelativeTo, basename.InputPath)
		base := basename.InputPath[:last]
		_, err := fmt.Fprintln(invocation.MainPipe.Out, base)
		if err != nil {
			return err, 1
		}
	} else {
		_, err := fmt.Fprintln(invocation.MainPipe.Out, path.Base(basename.InputPath))
		if err != nil {
			return err, 1
		}
	}
	return nil, 0
}
示例#16
0
// Exec actually performs the sleep
func (sleep *SomeSleep) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	var unitDur time.Duration
	switch sleep.unit {
	case "d":
		unitDur = time.Hour * 24
	case "s":
		unitDur = time.Second
	case "m":
		unitDur = time.Minute
	case "h":
		unitDur = time.Hour
	default:
		return errors.New("Invalid time interval " + sleep.unit), 1
	}
	time.Sleep(time.Duration(sleep.amount) * unitDur)
	return nil, 0

}
示例#17
0
// Exec actually performs the tar
func (t *SomeTar) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	//overrideable??
	destDir := "."
	if t.IsCreate {
		//OK
		//fmt.Printf("Create %s\n", t.ArchiveFilename)
		err := TarItems(t.ArchiveFilename, t.args, t, invocation.MainPipe.Out)
		if err != nil {
			return err, 1
		}
	} else if t.IsAppend {
		//hmm is this OK with STDIN??
		if t.ArchiveFilename == "" {
			return errors.New("Filename (-f) must be provided in Append mode"), 1
		}
		//OK
		//fmt.Printf("Append %s\n", t.ArchiveFilename)
		err := TarItems(t.ArchiveFilename, t.args, t, invocation.MainPipe.Out)
		if err != nil {
			return err, 1
		}
	} else if t.IsList {
		//fmt.Println("List", t.ArchiveFilename)
		err := TestTarItems(t.ArchiveFilename, t.args, invocation.MainPipe.In, invocation.MainPipe.Out)
		if err != nil {
			return err, 1
		}
	} else if t.IsExtract {
		//fmt.Println("Extract", t.ArchiveFilename)
		err := UntarItems(t.ArchiveFilename, destDir, t.args, t, invocation.MainPipe.In, invocation.MainPipe.Out)
		if err != nil {
			return err, 1
		}
	} else {
		return errors.New("You must use ONLY one of -c, -t or -x (create, list or extract), plus -f"), 1
	}
	return nil, 0
}
示例#18
0
// Exec actually performs the exec
func (exe *SomeExec) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	cmd := exec.Command(exe.args[0], exe.args[1:]...)
	cmd.Stdin = invocation.MainPipe.In
	cmd.Stdout = invocation.MainPipe.Out
	cmd.Stderr = invocation.ErrPipe.Out
	err := cmd.Start()
	if err != nil {
		return err, 1
	}
	err = cmd.Wait()
	exitSuccess := cmd.ProcessState.Success()
	var exitCode int
	if exitSuccess {
		exitCode = 0
	} else {
		// There should be a way to get the proper status on Unix.
		exitCode = 1
	}
	return err, exitCode
}
示例#19
0
// Exec actually performs the mv
func (mv *SomeMv) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	for _, srcGlob := range mv.srcGlobs {
		srces, err := filepath.Glob(srcGlob)
		if err != nil {
			return err, 1
		}
		if len(srces) < 1 {
			return errors.New(fmt.Sprintf("Source glob '%s' does not match any files\n", srcGlob)), 1
		}

		for _, src := range srces {
			err = moveFile(src, mv.dest)
			if err != nil {
				fmt.Fprintf(invocation.ErrPipe.Out, "Error %v\n", err)
				return err, 1
			}
		}
	}
	return nil, 0

}
示例#20
0
// Exec actually performs the grep
func (grep *SomeGrep) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	reg, err := compile(grep.pattern, grep)
	if err != nil {
		return err, 1
	}
	if len(grep.globs) > 0 {
		files := []string{}
		for _, glob := range grep.globs {
			results, err := filepath.Glob(glob)
			if err != nil {
				return err, 1
			}
			if len(results) < 1 { //no match
				return errors.New("grep: cannot access " + glob + ": No such file or directory"), 1
			}
			files = append(files, results...)
		}
		err = grepAll(reg, files, grep, invocation.MainPipe.Out)
		if err != nil {
			return err, 1
		}
	} else {
		if uggo.IsPipingStdin() {
			//check STDIN
			err = grepReader(invocation.MainPipe.In, "", reg, grep, invocation.MainPipe.Out)
			if err != nil {
				return err, 1
			}
		} else {
			//NOT piping.
			return errors.New("Not enough args"), 1
		}
	}
	return nil, 0
}
示例#21
0
// Exec actually performs the ls
func (ls *SomeLs) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	out := tabwriter.NewWriter(invocation.MainPipe.Out, 4, 4, 1, ' ', 0)
	args, err := getDirList(ls.globs, ls, invocation.MainPipe.In, invocation.MainPipe.Out, invocation.ErrPipe.Out)
	if err != nil {
		return err, 1
	}

	counter := 0
	lastWasDir := false
	for i, arg := range args {
		if !strings.HasPrefix(arg, ".") || ls.AllFiles ||
			strings.HasPrefix(arg, "..") || "." == arg {
			argInfo, err := os.Stat(arg)
			if err != nil {
				fmt.Fprintln(invocation.ErrPipe.Out, "stat failed for ", arg)
				return err, 1
			}
			if argInfo.IsDir() {
				if len(args) > 1 { //if more than one, print dir name before contents
					if i > 0 {
						fmt.Fprintf(out, "\n")
					}
					if !lastWasDir {
						fmt.Fprintf(out, "\n")
					}
					fmt.Fprintf(out, "%s:\n", arg)
				}
				dir := arg

				//show . and ..
				if ls.AllFiles {
					df, err := os.Stat(filepath.Dir(dir))
					if err != nil {
						fmt.Fprintf(out, "Error opening parent dir: %v", err)
					} else {
						printEntry("..", df, out, ls, &counter)
					}
					df, err = os.Stat(dir)
					if err != nil {
						fmt.Fprintf(out, "Error opening dir: %v", err)
					} else {
						printEntry(".", df, out, ls, &counter)
					}
				}

				err := list(out, invocation.ErrPipe.Out, dir, "", ls, &counter)
				if err != nil {
					return err, 1
				}
				if len(args) > 1 {
					fmt.Fprintf(out, "\n")
				}
			} else {

				listItem(argInfo, out, invocation.ErrPipe.Out, filepath.Dir(arg), "", ls, &counter)
			}
			lastWasDir = argInfo.IsDir()
		}
	}
	out.Flush()
	return nil, 0

}
示例#22
0
// Exec actually performs the tail
func (tail *SomeTail) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	if len(tail.Filenames) > 0 {
		for _, fileName := range tail.Filenames {
			finf, err := os.Stat(fileName)
			if err != nil {
				return err, 1
			}
			file, err := os.Open(fileName)
			if err != nil {
				return err, 1
			}
			seek := int64(0)
			if finf.Size() > 10000 {
				//just get last 10K (good enough for now)
				seek = finf.Size() - 10000
				_, err = file.Seek(seek, 0)
				if err != nil {
					return err, 1
				}
			}
			end, err := tailReader(file, seek, tail, invocation.MainPipe.Out)
			if err != nil {
				file.Close()
				return err, 1
			}
			err = file.Close()
			if err != nil {
				return err, 1
			}
			if tail.FollowByName {
				sleepIntervalMs := time.Duration(tail.SleepInterval * 1000)
				for {
					//sleep n.x seconds
					//use milliseconds to get some accuracy with the int64
					time.Sleep(sleepIntervalMs * time.Millisecond)
					finf, err := os.Stat(fileName)
					if err != nil {
						return err, 1
					}
					file, err := os.Open(fileName)
					if err != nil {
						return err, 1
					}
					_, err = file.Seek(end, 0)
					if err != nil {
						return err, 1
					}
					if finf.Size() > end {
						end, err = tailReader(file, end, tail, invocation.MainPipe.Out)
						if err != nil {
							file.Close()
							return err, 1
						}
					} else {
						//TODO start again
					}
					err = file.Close()
					if err != nil {
						return err, 1
					}
				}
			}
		}
	} else {
		//stdin ..
		_, err := tailReader(invocation.MainPipe.In, 0, tail, invocation.MainPipe.Out)
		if err != nil {
			return err, 1
		}
	}
	return nil, 0
}
示例#23
0
// Exec actually performs the wc
func (wc *SomeWc) Invoke(invocation *someutils.Invocation) (error, int) {
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	if len(wc.args) > 0 {
		//treat no args as all args
		if !wc.IsWords && !wc.IsLines && !wc.IsBytes {
			wc.IsWords = true
			wc.IsLines = true
			wc.IsBytes = true
		}
		for _, fileName := range wc.args {
			bytes := int64(0)
			words := int64(0)
			lines := int64(0)
			//get byte count
			file, err := os.Open(fileName)
			if err != nil {
				return err, 1
			}
			err = countWords(file, wc, &bytes, &words, &lines)
			if err != nil {
				file.Close()
				return err, 1
			}
			err = file.Close()
			if err != nil {
				return err, 1
			}
			if wc.IsWords && !wc.IsLines && !wc.IsBytes {
				fmt.Fprintf(invocation.MainPipe.Out, "%d %s\n", words, fileName)
			} else if !wc.IsWords && wc.IsLines && !wc.IsBytes {
				fmt.Fprintf(invocation.MainPipe.Out, "%d %s\n", lines, fileName)
			} else if !wc.IsWords && !wc.IsLines && wc.IsBytes {
				fmt.Fprintf(invocation.MainPipe.Out, "%d %s\n", bytes, fileName)
			} else {
				fmt.Fprintf(invocation.MainPipe.Out, "%d %d %d %s\n", lines, words, bytes, fileName)
			}
		}
	} else {
		//stdin ..
		if !wc.IsWords && !wc.IsLines && !wc.IsBytes {
			wc.IsWords = true
		}
		bytes := int64(0)
		words := int64(0)
		lines := int64(0)
		err := countWords(invocation.MainPipe.In, wc, &bytes, &words, &lines)
		if err != nil {
			return err, 1
		}
		if wc.IsWords && !wc.IsLines && !wc.IsBytes {
			fmt.Fprintf(invocation.MainPipe.Out, "%d\n", words)
		} else if !wc.IsWords && wc.IsLines && !wc.IsBytes {
			fmt.Fprintf(invocation.MainPipe.Out, "%d\n", lines)
		} else if !wc.IsWords && !wc.IsLines && wc.IsBytes {
			fmt.Fprintf(invocation.MainPipe.Out, "%d\n", bytes)
		} else {
			fmt.Fprintf(invocation.MainPipe.Out, "%d %d %d\n", lines, words, bytes)
		}
	}
	return nil, 0

}
示例#24
0
// Exec actually performs the gzip
func (gz *SomeGzip) Invoke(invocation *someutils.Invocation) (error, int) {
	//fmt.Printf("invocation: %+v\n", invocation)
	//fmt.Printf("gz: %+v\n", gz)
	invocation.ErrPipe.Drain()
	invocation.AutoHandleSignals()
	if len(gz.Filenames) < 1 {
		//pipe in?
		var writer io.Writer
		var outputFilename string
		if gz.outFile != "" {
			outputFilename = gz.outFile
			var err error
			writer, err = os.Create(outputFilename)
			if err != nil {
				return err, 1
			}
		} else {
			//	fmt.Printf("stdin to stdout: %+v\n", gz)
			outputFilename = "S" //seems to be the default used by gzip
			writer = invocation.MainPipe.Out
		}
		err := gz.doGzip(invocation.MainPipe.In, writer, filepath.Base(outputFilename))
		if err != nil {
			return err, 1
		}
	} else {
		//todo make sure it closes saved file cleanly
		for _, inputFilename := range gz.Filenames {
			inputFile, err := os.Open(inputFilename)
			if err != nil {
				return err, 1
			}
			defer inputFile.Close()

			var writer io.Writer
			if !gz.IsStdout {
				outputFilename := inputFilename + ".gz"
				gzf, err := os.Create(outputFilename)
				if err != nil {
					return err, 1
				}
				defer gzf.Close()
				writer = gzf
			} else {
				writer = invocation.MainPipe.Out
			}
			err = gz.doGzip(inputFile, writer, filepath.Base(inputFilename))
			if err != nil {
				return err, 1
			}

			err = inputFile.Close()
			if err != nil {
				return err, 1
			}

			// only remove source if specified and possible
			if !gz.IsKeep && !gz.IsStdout {
				err = os.Remove(inputFilename)
				if err != nil {
					return err, 1
				}
			}
		}
	}
	return nil, 0
}