package main import ( "bytes" "flag" //"fmt" "io" "log" "os" "os/exec" ) func Execute(output_buffer *bytes.Buffer, stack ...*exec.Cmd) (err error) { var error_buffer bytes.Buffer pipe_stack := make([]*io.PipeWriter, len(stack)-1) idx := 0 for ; idx < len(stack)-1; idx++ { stdin_pipe, stdout_pipe := io.Pipe() stack[idx].Stdout = stdout_pipe stack[idx].Stderr = &error_buffer stack[idx+1].Stdin = stdin_pipe pipe_stack[idx] = stdout_pipe } stack[idx].Stdout = output_buffer stack[idx].Stderr = &error_buffer if err := call(stack, pipe_stack); err != nil { log.Fatalln(error_buffer.String(), err) } return err } func call(stack []*exec.Cmd, pipes []*io.PipeWriter) (err error) { if stack[0].Process == nil { if err = stack[0].Start(); err != nil { return err } } if len(stack) > 1 { if err = stack[1].Start(); err != nil { return err } defer func() { if err == nil { pipes[0].Close() err = call(stack[1:], pipes[1:]) } }() } return stack[0].Wait() } func main() { var selection string flag.Parse() switch specified := flag.Arg(0); specified { case "": //fmt.Printf("Specified: %q\n", specified) var b1 bytes.Buffer if err := Execute(&b1, exec.Command("qubes-gopass-client", "list", "-f"), exec.Command("tail", "-n", "+2"), exec.Command("zenity", "--list", "--width=666", "--height=999", "--title", "Select a Password", "--column", "Password"), ); err != nil { log.Fatalln(err) } selection = b1.String() default: //fmt.Printf("Specified: %q\n", specified) selection = specified } var b2 bytes.Buffer if err := Execute(&b2, exec.Command("qubes-gopass-client", "show", "-o", selection), exec.Command("timeout", "--preserve-status", "66", "xclip", "-quiet", "-in", "-sensitive", "-selection", "clipboard"), ); err != nil { log.Fatalln(err) } b2.WriteString("password paste complete\n") io.Copy(os.Stdout, &b2) }