func get(root, cwd client.Fid, cmdline string) (client.Fid, error) { args, err := parseCommandLine(cmdline) if err != nil { return cwd, err } cmd := kingpin.New("get", "") remote := cmd.Arg("remote", "remote filename").Required().String() local := cmd.Arg("local", "local filename").Required().String() _, err = cmd.Parse(args) if err != nil { return cwd, err } remotepath, absolute := parsepath(*remote) lf, err := os.Create(*local) if err != nil { return cwd, err } f := cwd if absolute { f = root } f, _, err = f.Walk(remotepath) if err != nil { return cwd, err } defer f.Clunk() stat, err := f.Stat() if err != nil { return cwd, err } if stat.Mode&qp.DMDIR != 0 { return cwd, errors.New("file is a directory") } _, _, err = f.Open(qp.OREAD) if err != nil { return cwd, err } fmt.Fprintf(os.Stderr, "Downloading: %s to %s [%dB]", *remote, *local, stat.Length) wf := client.WrappedFid{Fid: f} strs, err := wf.ReadAll() if err != nil { return cwd, err } fmt.Fprintf(os.Stderr, " - Downloaded %dB.\n", len(strs)) for len(strs) > 0 { n, err := lf.Write(strs) if err != nil { return cwd, err } strs = strs[n:] } return cwd, nil }
func ls(root, cwd client.Fid, cmdline string) (client.Fid, error) { path, absolute := parsepath(cmdline) f := cwd if absolute { f = root } var err error f, _, err = f.Walk(path) if err != nil { return cwd, err } defer f.Clunk() _, _, err = f.Open(qp.OREAD) if err != nil { return cwd, err } wf := client.WrappedFid{Fid: f} b, err := wf.ReadAll() if err != nil { return cwd, err } stats, err := readdir(b) if err != nil { return cwd, err } // Sort the stats. We sort alphabetically with directories first. var sortedstats []qp.Stat selectedstat := -1 for len(stats) > 0 { for i := range stats { if selectedstat == -1 { // Nothing was selected, so we automatically win. selectedstat = i continue } isfile1 := stats[i].Mode&qp.DMDIR == 0 isfile2 := stats[selectedstat].Mode&qp.DMDIR == 0 if isfile1 && !isfile2 { // The previously selected file is a dir, and we got a file, so // we lose. continue } if !isfile1 && isfile2 { // The previously selected file is a file, and we got a dir, so // we win. selectedstat = i continue } if stats[i].Name < stats[selectedstat].Name { // We're both of the same type, but our name has lower value, so // we win. selectedstat = i continue } // We're not special, so we lose by default. } // Append to sorted list, cut from previous list and reset selection. sortedstats = append(sortedstats, stats[selectedstat]) stats = append(stats[:selectedstat], stats[selectedstat+1:]...) selectedstat = -1 } for _, stat := range sortedstats { fmt.Printf("%s %10d %10d %s\n", permToString(stat.Mode), stat.Qid.Version, stat.Length, stat.Name) } return cwd, nil }