blob: 20e4c734010586d1430ac44feb28ac33f53cbabe [file] [log] [blame]
// Copyright 2015 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Command p2b is a client for the Pipe2Browser service. It pipes its
// standard input to a Pipe2Browser service.
package main
import (
"flag"
"fmt"
"io"
"os"
"v.io/v23"
"v.io/x/lib/vlog"
"v.io/x/p2b/vdl"
_ "v.io/x/ref/runtime/factories/roaming"
)
const usage = `
%s is a Pipe To Browser client. It allows one to pipe any stdout stream from console to the browser.
Data being piped to the browser then is displayed in a graphical and formatted way by a "viewer".
Usage:
%s [<name>/<viewer>]
For example:
ls -l | p2b users/jane@google.com/chrome/p2b/jane/console
or
cat cat.jpg | p2b users/jane@google.com/chrome/p2b/jane/image
where <name> (users/jane@google.com/chrome/p2b/jane) is the object name where p2b
service is running in the browser. <viewer> (console, image) specifies what
viewer should be used to display the data.
To redirect stderr of a process, in *nix system you can use 2>&1 before piping to P2B.
For example many daemons may write log lines to stderr instead of stdout:
serverd -alsologtostderr=true 2>&1 | users/jane@google.com/chrome/p2b/jane/vlog
`
func Usage() {
fmt.Fprintf(os.Stdout, usage, os.Args[0], os.Args[0])
}
type sender interface {
Send(p []byte) error
}
// viewerPipeStreamWriter adapts ViewerPipeStream to io.Writer
type viewerPipeStreamWriter struct {
sender
}
func (w viewerPipeStreamWriter) Write(p []byte) (n int, err error) {
w.Send(p)
return len(p), nil
}
func main() {
flag.Parse()
flag.Usage = Usage
if flag.NArg() != 1 {
Usage()
return
}
ctx, shutdown, err := v23.TryInit()
if err != nil {
vlog.Errorf("Faile to initialize the vanadium runtime: %v", err)
return
}
defer shutdown()
name := flag.Arg(0)
// bind to the p2b service
s := vdl.ViewerClient(name)
stream, err := s.Pipe(ctx)
if err != nil {
vlog.Errorf("failed to pipe to '%s' please ensure p2b service is running in the browser and name is correct.\nERR:%v", name, err)
return
}
w := viewerPipeStreamWriter{stream.SendStream()}
_, err = io.Copy(w, os.Stdin)
if err != nil {
vlog.Errorf("failed to copy the stdin pipe to the outgoing stream\nERR:%v", err)
return
}
_, err = stream.Finish()
if err != nil {
vlog.Errorf("error finishing stream: %v", err)
return
}
fmt.Println("Finished piping to browser! Thanks for using p2b.")
}