Beispiel #1
0
func main() {
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	cmd.UnixIO("err")
	args := opts.Parse()
	if len(args) == 1 && ismode(args[0]) {
		args = append([]string{"mode"}, args...)
	}
	if len(args) == 0 || len(args)%2 != 0 {
		cmd.Warn("wrong number of arguments")
		opts.Usage()
	}
	nd := chd(args...)

	in := cmd.In("in")
	var err error
	for m := range in {
		switch d := m.(type) {
		case zx.Dir:
			cmd.Dprintf("got %T %s\n", d, d["Upath"])
			if cerr := ch(d, nd); cerr != nil {
				cmd.Warn("%s", cerr)
				err = cerr
			}
		default:
			// ignored
			cmd.Dprintf("got %T\n", m)
		}
	}
	if err != nil {
		cmd.Exit(err)
	}
}
Beispiel #2
0
// Authenticate a websocket before servicing it.
func AuthWebSocketHandler(h websocket.Handler) http.HandlerFunc {
	hndler := func(w http.ResponseWriter, r *http.Request) {
		if auth.TLSserver != nil && auth.Enabled {
			clive, err := r.Cookie("clive")
			if err != nil {
				cmd.Warn("wax/auth: no cookie: %s", err)
				http.Error(w, "auth failed", 403)
				return
			}
			toks := strings.SplitN(string(clive.Value), ":", 2)
			if len(toks) < 2 {
				cmd.Warn("wax/auth: wrong cookie")
				http.Error(w, "auth failed", 403)
				return
			}
			ch, resp := toks[0], toks[1]
			u, ok := auth.ChallengeResponseOk("wax", ch, resp)
			if !ok {
				cmd.Warn("wax/auth: failed for %s", u)
				http.Error(w, "auth failed", 403)
				return
			}
		}
		s := websocket.Server{Handler: h, Handshake: checkOrigin}
		s.ServeHTTP(w, r)
	}
	return hndler
}
Beispiel #3
0
// Authenticate before calling the handler.
// When TLS is disabled, or there's no key file, auth is considered ok.
func AuthHandler(fn http.HandlerFunc) http.HandlerFunc {
	return func(w http.ResponseWriter, r *http.Request) {
		if auth.TLSserver == nil || !auth.Enabled {
			fn(w, r)
			return
		}
		clive, err := r.Cookie("clive")
		if err != nil {
			cmd.Warn("wax/auth: no cookie: %s", err)
			authFailed(w, r)
			return
		}
		toks := strings.SplitN(string(clive.Value), ":", 2)
		if len(toks) < 2 {
			cmd.Warn("wax/auth: wrong cookie")
			authFailed(w, r)
			return
		}
		ch, resp := toks[0], toks[1]
		u, ok := auth.ChallengeResponseOk("wax", ch, resp)
		if !ok {
			cmd.Warn("wax/auth: failed for %s", u)
			authFailed(w, r)
			return
		}
		// TODO: We should decorate r adding the user id to
		// the url as a query, so fn can inspect the query and
		// know which user did auth.
		fn(w, r)
	}
}
Beispiel #4
0
func main() {
	cmd.UnixIO("err")
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("v", "verbose", &c.Verb)
	opts.NewFlag("x", "exclude", &excl)
	opts.NewFlag("n", "print just replica names when used to list replicas", &nflag)
	opts.NewFlag("m", "move existing replica client/server paths to the given ones", &mflag)
	opts.NewFlag("u", "don't use unix out", &notux)
	args := opts.Parse()
	if !notux {
		cmd.UnixIO("out")
	}
	if mflag {
		if len(args) != 3 {
			cmd.Warn("-m needs all arguments")
			opts.Usage()
		}
		err := mv(args[0], args[1], args[2])
		if err != nil {
			cmd.Fatal(err)
		}
		cmd.Exit(nil)
	}
	var err error
	switch len(args) {
	case 0:
		for _, nm := range names() {
			if nflag {
				cmd.Printf("%s\n", nm)
				continue
			}
			if err2 := list(nm); err2 != nil {
				cmd.Warn("%s: %s", nm, err2)
				if err == nil {
					err = err2
				}
			}
		}
	case 1:
		err = list(args[0])
	case 3:
		err = mk(args[0], args[1], args[2])
	default:
		opts.Usage()
	}
	if err != nil {
		cmd.Fatal(err)
	}
	cmd.Exit(nil)
}
Beispiel #5
0
func main() {
	cmd.UnixIO()
	dfltdir := auth.KeyDir()
	dir = dfltdir
	opts.NewFlag("d", "adir: clive auth dir", &dir)
	opts.NewFlag("f", "force write of key file when file already exists", &force)
	args := opts.Parse()
	if len(args) < 3 {
		opts.Usage()
	}
	name, user, secret := args[0], args[1], args[2]
	groups := args[3:]
	file := auth.KeyFile(dir, name)
	fi, _ := os.Stat(file)
	if fi != nil && !force {
		cmd.Fatal("key file already exists")
	}
	err := auth.SaveKey(dir, name, user, secret, groups...)
	if err != nil {
		cmd.Fatal("%s: %s", file, err)
	}
	ks, err := auth.LoadKey(dir, name)
	if err != nil {
		cmd.Fatal("can't load key: %s", err)
	}
	for _, k := range ks {
		if k.Uid == user {
			cmd.Warn("%s", file)
			return
		}
	}
	cmd.Fatal("bad user")
}
Beispiel #6
0
func main() {
	cmd.UnixIO("err")
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("u", "unix IO", &ux)
	opts.NewFlag("g", "get contents", &gflag)
	if cmd.Args()[0] == "gf" {
		gflag = true
	}
	args := opts.Parse()
	if ux {
		cmd.UnixIO()
	}
	if len(args) == 0 {
		args = append(args, ".,1")
	}

	var dc <-chan face{}
	if !gflag {
		dc = cmd.Dirs(args...)
	} else {
		dc = cmd.Files(args...)
	}

	out := cmd.Out("out")
	var err error
	for m := range dc {
		cmd.Dprintf("got %T\n", m)
		switch m := m.(type) {
		case error:
			err = m
			cmd.Warn("%s", m)
			if !ux {
				m := fmt.Errorf("%s: %s", cmd.Args()[0], m)
				if ok := out <- m; !ok {
					close(dc, cerror(out))
				}
			}
		case zx.Dir:
			if !ux {
				if ok := out <- m; !ok {
					close(dc, cerror(out))
				}
			} else {
				printf("%s\n", m.Fmt())
			}
		case []byte:
			if ok := out <- m; !ok {
				close(dc, cerror(out))
			}
		}
	}
	if err := cerror(dc); err != nil {
		if !ux {
			out <- fmt.Errorf("%s: %s", cmd.Args()[0], err)
		}
		cmd.Exit(err)
	}
	cmd.Exit(err)
}
Beispiel #7
0
func edit(t *ink.Txt) {
	in := t.Events()
	for ev := range in {
		cmd.Warn("got text: %v", ev.Args)
		switch ev.Args[0] {
		case "start":
			continue
			// Example: keep only a single view
			vs := t.Views()
			for _, v := range vs {
				if v != ev.Src {
					t.CloseView(v)
				}
			}
			// Example: do some edits from the program.
			go edits(t)
		case "tag":
			if len(ev.Args) == 1 || ev.Args[1] != "Del" {
				continue
			}
			t.Close()
		case "end":
			// Example: delete the text when all views are gone
			vs := t.Views()
			cmd.Dprintf("views %v\n", t.Views())
			if len(vs) == 0 {
				t.Close()
				return
			}
		}
	}
}
Beispiel #8
0
// Run path in the current app context.
func main() {
	cmd.UnixIO("err")
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("r", "dir: print paths relative to dir", &dir)
	opts.NewFlag("d", "print parent directories", &dflag)
	opts.NewFlag("b", "print base names", &bflag)
	args := opts.Parse()
	if ux {
		cmd.UnixIO()
	}
	if dir != "" && (dflag || bflag) {
		cmd.Warn("incompatible flags")
		opts.Usage()
	}
	if dflag && bflag {
		cmd.Warn("incompatible flags")
		opts.Usage()
	}
	if dir != "" {
		dir = cmd.AbsPath(dir)
	}
	var sts error
	for _, n := range args {
		n = cmd.AbsPath(n)
		switch {
		case dir != "":
			r, err := filepath.Rel(dir, n)
			if err != nil {
				sts = err
				cmd.Warn("%s: %s", n, err)
			} else {
				n = r
			}
		case dflag:
			n = fpath.Dir(n)
		case bflag:
			n = fpath.Base(n)
		}
		cmd.Printf("%s\n", n)
	}
	cmd.Exit(sts)
}
Beispiel #9
0
// Run print lines in the current app context.
func main() {
	c := cmd.AppCtx()
	cmd.UnixIO("err")
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("1", "collect all files (not one msg per file)", &one)
	ux := false
	opts.NewFlag("u", "use unix out", &ux)
	args := opts.Parse()
	if ux {
		cmd.UnixIO("out")
	}
	if len(args) != 0 {
		cmd.SetIn("in", cmd.Files(args...))
	}
	buf := &bytes.Buffer{}
	in := cmd.In("in")
	out := cmd.Out("out")
	for m := range in {
		switch m := m.(type) {
		case []byte:
			buf.Write(m)
		case zx.Dir:
			if !one && buf.Len() > 0 {
				if ok := out <- buf.Bytes(); !ok {
					close(in, cerror(out))
					break
				}
				buf = &bytes.Buffer{}
			}
			if !one && !ux {
				if ok := out <- m; !ok {
					close(in, cerror(out))
					break
				}
			}
		case error:
			cmd.Warn("%s", m)
		default:
			cmd.Dprintf("ignored %T\n", m)
			if !ux {
				if ok := out <- m; !ok {
					close(in, cerror(out))
					break
				}
			}
		}
	}
	if buf.Len() > 0 {
		out <- buf.Bytes()
	}
	if err := cerror(in); err != nil {
		cmd.Fatal(err)
	}
}
Beispiel #10
0
func main() {
	cmd.UnixIO()
	c := cmd.AppCtx()
	dfltdump := Path(u.Home, "dump")
	opts.NewFlag("s", "don't dump right now, wait until next at 5am", &Skip)
	opts.NewFlag("1", "dump once and exit", &Once)
	opts.NewFlag("v", "verbose", &c.Verb)
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("x", "expr: files excluded (.*, tmp.* if none given); tmp always excluded.", &Xcludes)
	Dump = dfltdump
	opts.NewFlag("d", "dir: where to keep the dump, ~/dump if none", &Dump)
	args := opts.Parse()
	if len(Xcludes) == 0 {
		Xcludes = []string{".*", "tmp.*", "*.tmp"}
	}
	Xcludes = append(Xcludes, "tmp")
	if len(args) == 0 {
		cmd.Warn("arguments missing")
		opts.Usage()
	}
	if Skip && Once {
		cmd.Fatal("can't skip the current dump and dump once now")
	}
	nt := 0
	ec := make(chan bool)
	for i := 0; i < len(args); i++ {
		al := strings.SplitN(args[i], "!", 2)
		if len(al) == 1 {
			al = append(al, al[0])
			al[0] = fpath.Base(al[0])
		}
		t, err := zux.NewZX(al[1])
		if err != nil {
			dbg.Warn("%s: %s", al[0], err)
			continue
		}
		t.Tag = al[0]
		t.Flags.Set("rdonly", true)
		nt++
		go dump(Dump, t.Tag, t, ec)
	}
	if nt == 0 {
		cmd.Fatal("no trees to dump")
	}
	for nt > 0 {
		<-ec
		nt--
	}
}
Beispiel #11
0
func mktest(t *testing.T, tdir string, excl ...string) (*DB, func()) {
	cmd.UnixIO("in", "out", "err")
	cmd.Warn("testing")
	os.Args[0] = "repl.test"
	fstest.Verb = testing.Verbose()
	os.RemoveAll(tdir)
	os.Remove(tdb)
	fstest.MkTree(t, tdir)
	fn := func() {
		os.RemoveAll(tdir)
		os.RemoveAll(tdb)
	}
	db := mkdb(t, tdir, excl...)
	return db, fn
}
Beispiel #12
0
func names() []string {
	ds, err := ioutil.ReadDir("/u/lib/repl")
	if err != nil {
		cmd.Warn("/u/lib/repl: %s", err)
		return nil
	}
	nms := []string{}
	for _, d := range ds {
		if nm := d.Name(); strings.HasSuffix(nm, ".ldb") {
			nm = nm[:len(nm)-4]
			nms = append(nms, nm)
		}
	}
	return nms
}
Beispiel #13
0
func kq(dir, wcmd string) {
	w, err := fswatch.New()
	if err != nil {
		cmd.Fatal("kqueue: %s", err)
	}

	cmd.Dprintf("(re)read %s\n", dir)
	if err := w.Add(dir); err != nil {
		cmd.Fatal("kqueue: %s", err)
	}
	if err != nil {
		cmd.Fatal("watch: %s", err)
	}
	var pc chan string
	if once {
		w.Once()
	}
	pc = w.Changes()
	for p := range pc {
		if wcmd == "" {
			cmd.Warn("%s", p)
			continue
		}
		cln := strings.Replace(wcmd, "%", p, -1)
		cmd.Dprintf("run %s\n", cln)
		out, err := exec.Command("sh", "-c", cln).CombinedOutput()
		cmd.Out("out") <- out
		if err != nil {
			cmd.Warn("run: %s", err)
		}
	}
	if err := cerror(pc); err != nil {
		cmd.Fatal(err)
	}
	cmd.Exit(nil)
}
Beispiel #14
0
func bshift(x *xEnv, args ...string) error {
	if len(args) > 2 {
		cmd.Warn("usage: shift [var]")
		return nil
	}
	v := "argv"
	if len(args) == 2 {
		v = args[1]
	}
	argv := cmd.GetEnvList(v)
	if len(argv) > 0 {
		cmd.SetEnvList(v, argv[1:])
	}
	return nil
}
Beispiel #15
0
func buttons(bs *ink.ButtonSet, rs *ink.RadioSet, t *ink.Txt) {
	in := bs.Events()
	rs.SendEventsTo(in)
	for ev := range in {
		cmd.Warn("buttons: %v", ev.Args)
		if ev.Args[0] == "Set" {
			s := style
			if bold {
				s += "b"
			}
			if italic {
				s += "i"
			}
			t.SetFont(s)
		}
	}
}
Beispiel #16
0
func main() {
	cmd.UnixIO()
	local := false
	opts.NewFlag("p", "port: port used (8080 by default)", &port)
	opts.NewFlag("t", "port: TLS port (8083 by default)", &tport)
	opts.NewFlag("l", "localhost and TLS only", &local)
	args := opts.Parse()
	switch len(args) {
	case 0:
		if local {
			dir = "/zx"
		}
	case 1:
		dir = args[0]
	default:
		cmd.Warn("too many arguments")
		opts.Usage()
	}
	cert := "/zx/lib/webcert.pem"
	key := "/zx/lib/webcert.key"
	addr := ":"
	go func() {
		err := http.ListenAndServeTLS(addr+tport, cert, key, http.FileServer(http.Dir(dir)))
		if err != nil {
			cmd.Fatal(err)
		}
	}()
	go func() {
		if local {
			return
		}
		err := http.ListenAndServe(addr+port, http.FileServer(http.Dir(dir)))
		if err != nil {
			cmd.Fatal(err)
		}
	}()
	c := make(chan bool)
	<-c
}
Beispiel #17
0
// Run cols in the current app context.
func main() {
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("w", "wid: set max line width", &wid)
	opts.NewFlag("n", "ncols: set number of columns", &ncols)
	opts.NewFlag("u", "use unix output", &ux)
	cmd.UnixIO("err")
	args := opts.Parse()
	if ux {
		cmd.UnixIO("out")
	}
	if len(args) != 0 {
		cmd.SetIn("in", cmd.Files(args...))
	}
	in := cmd.In("in")
	for m := range in {
		switch m := m.(type) {
		default:
			// ignored & forwarded
			cmd.Dprintf("got %T\n", m)
			continue
		case zx.Dir:
			cmd.Dprintf("got %T %s\n", m, m["Upath"])
			add(strings.TrimSpace(m["name"]))
		case error:
			if m != nil {
				cmd.Warn("%s", m)
			}
		case []byte:
			cmd.Dprintf("got %T [%d]\n", m, len(m))
			words := strings.Fields(strings.TrimSpace(string(m)))
			add(words...)
		}
	}
	col()
	if err := cerror(in); err != nil {
		cmd.Fatal("in %s", err)
	}
}
Beispiel #18
0
func find(dump, dpref, rel string, dc chan<- zx.Dir, ufile zx.Dir) {
	droot := fpath.Join(dump, dpref)
	years, err := cmd.GetDir(droot)
	if err != nil {
		cmd.Warn("%s", err)
		return
	}
	for i := len(years) - 1; i >= 0; i-- {
		year := years[i]["name"]
		if ignored(year, "") {
			continue
		}
		ypath := years[i]["path"]
		days, err := cmd.GetDir(ypath)
		if err != nil {
			cmd.Warn("%s: %s", ypath, err)
			continue
		}
		lastsz, lastmt, lastm := "", "", ""
		for j := len(days) - 1; j >= 0; j-- {
			day := days[j]["name"]
			if ignored(year, day) {
				continue
			}
			fpath := fpath.Join(days[j]["path"], rel)
			d, err := cmd.Stat(fpath)
			if err != nil {
				if !force {
					cmd.Dprintf("find: %s", err)
					return
				}
				continue
			}
			newm, newsz, newmt := d["mode"], d["size"], d["mtime"]
			if newsz == lastsz && newmt == lastmt && newm == lastm {
				continue
			}
			lastm, lastsz, lastmt = newm, newsz, newmt
			d["upath"] = ufile["path"]
			d["uupath"] = ufile["upath"]
			if ok := dc <- d; !ok {
				return
			}
			if !all {
				return
			}
		}
	}
}

func report(dc chan zx.Dir, donec chan bool) {
	last := ""
	for d := range dc {
		if last == "" {
			last = d["Upath"]
			if last == "" {
				last = d["path"]
			}
		}
		p := d["path"]
		cmd.Dprintf("found '%s'\n", p)
		var err error
		switch {
		case xcmd != "":
			_, err = cmd.Printf("%s %s %s\n", xcmd, p, last)
		case dflag:
			dcmd := fmt.Sprintf(`9 diff -n %s %s`, p, last)
			_, err = cmd.Printf("%s\n", dcmd)
			if err != nil {
				cmd.Warn("diff: %s", err)
				continue
			}
		case lflag:
			_, err = cmd.Printf("%s\n", d.Fmt())
		case cflag:
			_, err = cmd.Printf("cp %s %s\n", p, d["Upath"])
		default:
			_, err = cmd.Printf("%s\n", d["path"])
		}
		if err != nil {
			close(dc, err)
		}
		last = p
	}
	close(donec, cerror(dc))
}

func hist(in <-chan face{}) error {
	dc := make(chan zx.Dir)
	ec := make(chan bool)
	go report(dc, ec)
	var sts error
	for m := range in {
		switch m := m.(type) {
		case zx.Dir:
			cmd.Dprintf("got %T %s\n", m, m["path"])
			file := m["path"]
			if m["upath"] == "" {
				m["upath"] = m["path"]
			}
			ddir := dump
			dpref := ""
			rel := ""
			switch {
			case zx.HasPrefix(file, "/zx"):
				if ddir == "" {
					ddir = "/dump"
				}
				dpref = "/zx"
				rel = zx.Suffix(file, "/zx")
			case zx.HasPrefix(file, "/u/gosrc/src/clive"):
				if ddir == "" {
					ddir = "/u/dump"
				}
				dpref = "clive"
				rel = zx.Suffix(file, "/u/gosrc/src/clive")
			case zx.HasPrefix(file, "/u"):
				if ddir == "" {
					ddir = "/u/dump"
				}
				els := zx.Elems(file)
				if len(els) < 3 {
					cmd.Warn("%s: too few path elements", m["upath"])
					sts = errNoDump
					continue
				}
				dpref = els[1]
				rel = zx.Path(els[2:]...)
			default:
				cmd.Warn("%s: %s", m["upath"], errNoDump)
				sts = errNoDump
				continue
			}
			find(ddir, dpref, rel, dc, m.Dup())
		default:
			cmd.Dprintf("got %T\n", m)

		}
	}
	close(dc, cerror(in))
	<-ec
	if sts == nil {
		sts = cerror(ec)
	}
	if sts == nil {
		sts = cerror(in)
	}
	return sts
}

// Run cnt in the current app context.
func main() {
	c := cmd.AppCtx()
	cmd.UnixIO("err")
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("f", "force search past file removals", &force)
	opts.NewFlag("l", "produce a long listing (or print just the name)", &lflag)
	opts.NewFlag("c", "copy the file from the dump", &cflag)
	opts.NewFlag("d", "print file differences", &dflag)
	opts.NewFlag("x", "cmd: print lines to execute this command between versions", &xcmd)
	opts.NewFlag("a", "list all copies that differ, not just the last one.", &all)
	opts.NewFlag("p", "dumpdir: path to dump (default is /dump or /u/dump)", &dump)
	t := time.Now()
	when := t
	opts.NewFlag("w", "date: backward search start time (default is now)", &when)
	ux := false
	opts.NewFlag("u", "unix IO", &ux)
	args := opts.Parse()
	if (all && cflag) || (force && !all) {
		cmd.Warn("incompatible flags")
		opts.Usage()
	}
	if ux {
		cmd.UnixIO("out")
	}
	lastyear = ""
	lastday = ""
	if !t.Equal(when) {
		y := when.Year()
		m := when.Month()
		d := when.Day()
		if y == 0 {
			y = t.Year()
		}
		lastyear = fmt.Sprintf("%04d", y)
		lastday = fmt.Sprintf("%02d%02d", m, d)
	}
	if len(args) != 0 {
		cmd.SetIn("in", cmd.Dirs(args...))
	}
	in := cmd.In("in")
	if err := hist(in); err != nil {
		cmd.Fatal(err)
	}
}
Beispiel #19
0
func main() {
	cmd.UnixIO()
	opts.AddUsage("\tspec is name | name!file | name!file!flags \n")
	opts.AddUsage("\tspec flags are ro | rw | ncro | ncrw \n")
	port = "8002"
	addr = "*!*!zx"
	opts.NewFlag("p", "port: tcp server port (8002 by default)", &port)
	opts.NewFlag("a", "addr: service address (*!*!zx by default)", &addr)
	opts.NewFlag("s", "use writesync for caches", &wsync)
	c := cmd.AppCtx()
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("A", "auth debug", &auth.Debug)
	opts.NewFlag("v", "report users logged in/out (verbose)", &c.Verb)
	opts.NewFlag("Z", "verbose debug", &Zdebug)
	opts.NewFlag("n", "no auth", &noauth)
	args := opts.Parse()
	if len(args) == 0 {
		cmd.Warn("missing arguments")
		opts.Usage()
	}
	c.Debug = c.Debug || Zdebug
	auth.Debug = c.Debug

	trs := map[string]zx.Fs{}
	ros := map[bool]string{false: "rw", true: "ro"}
	cs := map[bool]string{false: "uncached", true: "cached"}
	rotrs := map[string]bool{}
	var mainfs zx.Fs
	for i := 0; i < len(args); i++ {
		al := strings.Split(args[i], "!")
		if len(al) == 1 {
			al = append(al, al[0])
			al[0] = fpath.Base(al[0])
		}
		if _, ok := trs[al[0]]; ok {
			cmd.Warn("dup tree name %s", al[0])
			continue
		}
		ronly := false
		caching := true
		if len(al) == 3 && strings.Contains(al[2], "ro") {
			ronly = true
		}
		if len(al) == 3 && strings.Contains(al[2], "nc") {
			caching = false
		}
		fp, _ := filepath.Abs(al[1])
		t, err := zux.NewZX(fp)
		if err != nil {
			cmd.Warn("%s: %s", al[0], err)
			continue
		}
		t.Tag = al[0]
		cmd.Warn("%s %s %s", al[0], ros[ronly], cs[caching])
		var x zx.Fs = t
		if caching {
			x, err = zxc.New(t)
			if err != nil {
				dbg.Warn("%s: zxc: %s", al[0], err)
				continue
			}
			if Zdebug {
				x.(*zxc.Fs).Debug = true
			}
			if wsync {
				x.(*zxc.Fs).Flags.Set("writesync", true)
			}
		} else if Zdebug {
			x.(*zux.Fs).Debug = true
		}
		trs[t.Tag] = x
		if i == 0 {
			mainfs = x
		}
		rotrs[t.Tag] = ronly
	}
	if len(trs) == 0 {
		cmd.Fatal("no trees to serve")
	}
	if _, ok := trs["main"]; !ok {
		trs["main"] = mainfs
	}
	vprintf("serve %s...", addr)
	srv, err := rzx.NewServer(addr, auth.TLSserver)
	if err != nil {
		cmd.Fatal("serve: %s", err)
	}
	if noauth {
		srv.NoAuth()
	}
	if c.Debug {
		srv.Debug = true
	}
	for nm, fs := range trs {
		if cfs, ok := fs.(*zxc.Fs); ok {
			cfs.Flags.Add("debug", &srv.Debug)
			cfs.Flags.Add("zdebug", &cfs.Debug)
		} else if lfs, ok := fs.(*zux.Fs); ok {
			lfs.Flags.Add("debug", &srv.Debug)
			lfs.Flags.Add("zdebug", &lfs.Debug)
		}
		if rotrs[nm] {
			fs = zx.MakeRO(fs)
			trs[nm] = fs
		}
		if err := srv.Serve(nm, fs); err != nil {
			cmd.Fatal("serve: %s: %s", nm, err)
		}
	}
	if err := srv.Wait(); err != nil {
		cmd.Fatal("srv: %s", err)
	}
}
Beispiel #20
0
// Run rem in the current app context.
func main() {
	c := cmd.AppCtx()
	cmd.UnixIO("err")
	opts.NewFlag("D", "debug", &c.Debug)
	opts.NewFlag("v", "verbose; print the calls made in the order they are made.", &c.Verb)
	opts.NewFlag("a", "remove all", &aflag)
	opts.NewFlag("f", "quiet, called 'force' in unix", &fflag)
	opts.NewFlag("n", "dry run; report removes but do not do them", &dry)
	args := opts.Parse()
	if len(args) != 0 {
		cmd.SetIn("in", cmd.Dirs(args...))
	}
	c.Verb = c.Verb || dry
	in := cmd.In("in")
	var err error
	for m := range in {
		switch d := m.(type) {
		case zx.Dir:
			cmd.Dprintf("got %T %s\n", d, d["upath"])
			dirs = append(dirs, d)
		case error:
			cmd.Warn("%s", d)
		default:
			// ignored
			cmd.Dprintf("ignored %T\n", m)
		}
	}
	if aflag {
		for i := 0; i < len(dirs); i++ {
			if dirs[i] == nil {
				continue
			}
			pi := dirs[i]["path"]
			for j := 1; j < len(dirs); j++ {
				if i == j || dirs[j] == nil {
					continue
				}
				pj := dirs[j]["path"]
				if zx.HasPrefix(pj, pi) {
					dirs[j] = nil
				}
			}
		}
	}
	for i := len(dirs) - 1; i >= 0; i-- {
		if dirs[i] == nil {
			continue
		}
		if cerr := rmf(dirs[i]); cerr != nil {
			if !fflag {
				cmd.Warn("%s", cerr)
				err = cerr
			}
		}
	}
	if err == nil {
		err = cerror(in)
		if err != nil {
			cmd.Fatal(err)
		}
	}
	cmd.Exit(err)
}
Beispiel #21
0
func pull1(name string) error {
	if !strings.ContainsRune(name, '/') {
		name = "/u/lib/repl/" + name
	}
	tr, err := repl.Load(name)
	if err != nil {
		cmd.Warn("load %s: %s", name, err)
		return err
	}
	defer tr.Close()
	c := cmd.AppCtx()
	if c.Debug {
		tr.Ldb.DumpTo(os.Stderr)
		tr.Rdb.DumpTo(os.Stderr)
	}
	if nflag {
		var cc <-chan repl.Chg
		switch {
		case aflag:
			cc, err = tr.AllPullChanges()
		default:
			cc, err = tr.PullChanges()
		}
		if err != nil {
			cmd.Warn("pull changes %s: %s", name, err)
			return err
		}
		for c := range cc {
			cmd.Printf("%s\n", c)
		}
		return nil
	}
	var cc chan repl.Chg
	dc := make(chan bool)
	if c.Verb {
		cc = make(chan repl.Chg)
		go func() {
			for c := range cc {
				cmd.Printf("%s\n", c)
			}
			close(dc)
		}()
	} else {
		close(dc)
	}
	switch {
	case aflag:
		err = tr.PullAll(cc)
	case bflag:
		err = tr.BlindPull(cc)
	default:
		err = tr.Pull(cc)
	}
	<-dc
	if err != nil {
		cmd.Warn("pull %s: %s", name, err)
	}
	if err2 := tr.Save(name); err2 != nil {
		cmd.Warn("save %s: %s", name, err2)
		if err == nil {
			err = err2
		}
	}
	return err
}