func main() { flag.Parse() naddr := *addr if strings.LastIndex(naddr, ":") == -1 { naddr = naddr + ":5640" } c, err := g9pc.Mount("tcp", naddr, "") if err != nil { log.Fatalf("error mounting %s: %v", naddr, err) } ns := new(g9pc.Ns) root, err := c.Walk("") if err != nil { log.Fatalf("error walking to /: %v", err) } ns.Root = g9pc.NewNsFile(root.File()) ns.Dot = ns.Root if flag.NArg() > 0 { flags := flag.Args() for _, uc := range flags { cmd(ns, uc) } } else { interactive(ns) } return }
func lsone(ns *g9pc.Ns, s string, long bool) { st, err := ns.Stat(s) if err != nil { fmt.Fprintf(os.Stderr, "error stat: %s\n", err) return } if st.Mode&g9p.DMDIR != 0 { file, err := ns.Open(s, g9p.OREAD) if err != nil { fmt.Fprintf(os.Stderr, "error opening dir: %s\n", err) return } defer file.Close() for { d, err := file.Dirread() if err != nil && err != io.EOF { fmt.Fprintf(os.Stderr, "error reading dir: %s\n", err) } if d == nil || len(d) == 0 { break } for _, dir := range d { if long { fmt.Fprintf(os.Stdout, "%s\n", dirtostr(dir)) } else { os.Stdout.WriteString(dir.Name + "\n") } } } } else { fmt.Fprintf(os.Stdout, "%s\n", dirtostr(st)) } }
func cmdread(ns *g9pc.Ns, s []string) { sq, results := seq.NewSequencer() go func() { r := <-results // walk result r = <-results // open result r = <-results // readstream result _, ok := <-results if ok { panic("expected closed") } }() f := ns.SeqWalk(sq, s[0]) sq.Do(f.File(), seq.OpenReq{g9p.OREAD}) rd := f.SeqReadStream(sq, 200, 20) buf := make([]byte, 10) for { n, err := rd.Read(buf) if n == 0 { fmt.Fprintf(os.Stderr, "read error: %v\n", err) break } fmt.Printf("%q\n", buf[0:n]) } rd.Close() sq.Do(f.File(), seq.ClunkReq{}) // strictly speaking unnecessary. sq.Do(nil, nil) sq.Wait() }
// Remove f from remote server func rmone(ns *g9pc.Ns, f string) { err := ns.Remove(f) if err != nil { fmt.Fprintf(os.Stderr, "error in stat %s: %s\n", f, err) return } }
// Copy a remote file to local filesystem func cmdget(ns *g9pc.Ns, s []string) { var from, to string switch len(s) { case 1: from, to = path.Split(path.Clean(s[0])) case 2: from, to = s[0], s[1] default: fmt.Fprintf(os.Stderr, "from arguments; usage: get from to\n") } tofile, err := os.Create(to) if err != nil { fmt.Fprintf(os.Stderr, "error opening %s for writing: %s\n", to, err) return } defer tofile.Close() file, err := ns.Open(from, g9p.OREAD) if err != nil { fmt.Fprintf(os.Stderr, "error opening %s for writing: %s\n", to, err) return } defer file.Close() _, err = io.Copy(tofile, file) if err != nil { fmt.Fprintf(os.Stderr, "error copying: %v\n", err) return } }
// Create a single directory on remote server func mkone(ns *g9pc.Ns, fname string) { file, err := ns.Create(fname, g9p.OREAD, 0777|g9p.DMDIR) if err != nil { fmt.Fprintf(os.Stderr, "error creating directory %s: %s\n", fname, err) return } file.Close() }
// Stat the remote file f func statone(ns *g9pc.Ns, f string) { stat, err := ns.Stat(f) if err != nil { fmt.Fprintf(os.Stderr, "error in stat %s: %s\n", f, err) return } fmt.Fprintf(os.Stdout, "%v\n", stat) }
// Print the contents of f using streaming. func cmdstream(ns *g9pc.Ns, s []string) { for _, fname := range s { r := ns.ReadStream(fname, 20, 10) _, err := io.Copy(os.Stdout, r) if err != nil { fmt.Fprintf(os.Stderr, "error reading %s: %v\n", fname, err) } r.Close() } }
func cmdcd(ns *g9pc.Ns, s []string) { if s == nil { return } d := s[0] err := ns.Chdir(d) if err != nil { fmt.Fprintf(os.Stderr, "chdir: %v\n", err) return } cwd = path.Clean(cwd + "/" + d) }
// Print the contents of f func cmdcat(ns *g9pc.Ns, s []string) { for _, fname := range s { file, err := ns.Open(fname, g9p.OREAD) if err != nil { fmt.Fprintf(os.Stderr, "error opening %s: %s\n", fname, err) continue } defer file.Close() _, err = io.Copy(os.Stdout, file) if err != nil { fmt.Fprintf(os.Stderr, "error: %v\n", err) } } }
func cmdtorture(ns *g9pc.Ns, s []string) { path := "." if len(s) > 0 { path = s[0] } t := &traverser{ out: make(chan string), refc: make(chan int), // tokc: make(chan bool, 2), } if len(s) > 1 { max, err := strconv.Atoi(s[1]) if err != nil { fmt.Fprintf(os.Stderr, "max?: %v\n", err) return } t.tokc = make(chan bool, max) for i := 0; i < max; i++ { t.tokc <- true } } fid, err := ns.Walk(path) if fid == nil { fmt.Fprintf(os.Stderr, "cannot walk to %s: %v\n", s[0], err) return } ref := 1 maxref := 1 go func() { t.traverse(fid, path, "", make(chan bool, 1)) t.refc <- -1 }() for ref > 0 { select { case s := <-t.out: fmt.Print("************ ", s) case r := <-t.refc: ref += r if ref > maxref { maxref = ref } } } fmt.Printf("\n") fmt.Printf("max procs %d\n", maxref) }
// Write the string s to remote file f. Create f if it doesn't exist func writeone(ns *g9pc.Ns, fname, s string) { file, err := ns.Open(fname, g9p.OWRITE|g9p.OTRUNC) if err != nil { file, err = ns.Create(fname, g9p.OWRITE, 0666) if err != nil { fmt.Fprintf(os.Stderr, "error opening %s: %v\n", fname, err) return } } defer file.Close() m, err := file.Write([]byte(s)) if err != nil { fmt.Fprintf(os.Stderr, "error writing to %s: %s\n", fname, err) return } if m != len(s) { fmt.Fprintf(os.Stderr, "short write %s\n", fname) return } }
// Copy a local file to remote server func cmdput(ns *g9pc.Ns, s []string) { var from, to string switch len(s) { case 1: _, to = path.Split(s[0]) to = normpath(to) from = s[0] case 2: from, to = s[0], normpath(s[1]) default: fmt.Fprintf(os.Stderr, "incorrect arguments; usage: put local [remote]\n") } fromfile, err := os.Open(from) if err != nil { fmt.Fprintf(os.Stderr, "error opening %s for reading: %s\n", from, err) return } defer fromfile.Close() file, err := ns.Open(to, g9p.OWRITE|g9p.OTRUNC) if err != nil { file, err = ns.Create(to, g9p.OWRITE, 0666) if err != nil { fmt.Fprintf(os.Stderr, "error opening %s for writing: %s\n", to, err) return } } fmt.Fprintf(os.Stderr, "opened file ok\n") defer file.Close() n, err := Copy(file, fromfile) if err != nil { fmt.Fprintf(os.Stderr, "error copying file: %v (%d bytes copied)\n", err, n) } fmt.Fprintf(os.Stderr, "copied %d bytes\n", n) }