作者:Christopheraburn
项目:cliv
func NewDup(from, to string) Redirs {
switch from {
case "1", "2":
default:
dbg.Warn("%s: unknown dup %s", addr, from)
nerrors++
return nil
}
switch to {
case "1", "2":
default:
dbg.Warn("%s: unknown dup %s", addr, to)
nerrors++
return nil
}
if from == to {
dbg.Warn("%s: stupid dup %s %s", addr, from, to)
nerrors++
return nil
}
return []*Redir{
{
From: int(from[0] - '0'),
To: int(to[0] - '0'),
Name: "|=",
},
}
}
作者:Christopheraburn
项目:cliv
// If ln is "path addr" and addr is of the form
// net ! addr ! proto ! tree ! path
// or
// /one/path
// the dial the tree and walk to the path.
func specialForm(ln string) (string, zx.Dir) {
if len(ln)==0 || ln[0]!='/' {
return "", nil
}
toks := strings.Fields(ln)
if len(toks)!=2 || len(toks[0])==0 || len(toks[1])==0 {
return "", nil
}
p, addr := toks[0], toks[1]
if addr[0] == '/' {
addr = "*!*!lfs!main!" + addr
}
atoks := strings.SplitN(addr, "!", -1)
if len(atoks) < 2 {
return "", nil
}
t, err := rfs.Import(addr)
if err != nil {
dbg.Warn("ns: %s: import: %s", ln, err)
return "", nil
}
path := "/"
if len(atoks)>=5 && atoks[2]!="lfs" {
path = atoks[4]
}
d, err := zx.Stat(t, path)
if err != nil {
dbg.Warn("ns: %s: stat: %s", ln, err)
return "", nil
}
return p, d
}
作者:Christopheraburn
项目:cliv
/*
Authenticate the wax server. To be called early within the
handler function for wax pages. It returns false if auth failed
and the handler should return without handling anything.
When TLS is disabled, or there's no key file, auth is considered ok.
*/
func Auth(w http.ResponseWriter, r *http.Request) bool {
if auth.TLSserver == nil || !auth.Enabled {
return true
}
clive, err := r.Cookie("clive")
if err != nil {
dbg.Warn("wax/auth: no cookie: %s", err)
failed(w)
return false
}
toks := strings.SplitN(string(clive.Value), ":", 2)
if len(toks) < 2 {
dbg.Warn("wax/auth: wrong cookie")
failed(w)
return false
}
ch, resp := toks[0], toks[1]
u, ok := auth.ChallengeResponseOk("wax", ch, resp)
if !ok {
dbg.Warn("wax/auth: failed for %s", u)
failed(w)
return false
}
return ok
}
作者:Christopheraburn
项目:cliv
// Make a new repl for the given name and local and remote tree addresses.
// Pred defaults to exclude all dot files and dirs: 'name~^\.&prune|true'
func New(name, pred, laddr, raddr string) (*Repl, error) {
r := &Repl{
Name: name,
Laddr: laddr,
Raddr: raddr,
pred: pred,
}
r.vprintf = dbg.FlagPrintf(os.Stdout, &r.Verb)
if err := r.dial(); err != nil {
return nil, err
}
var err, rerr error
r.Ldb, err = sync.NewDB(name + "[" + laddr + "]", pred, r.lfs)
if err != nil {
dbg.Warn("%s: %s", laddr, err)
}
r.Rdb, rerr = sync.NewDB(name + "[" + raddr + "]", pred, r.rfs)
if rerr != nil {
err = rerr
dbg.Warn("%s: %s", raddr, rerr)
}
r.Ldb.Pred = r.pred
r.Rdb.Pred = r.pred
return r, err
}
作者:Christopheraburn
项目:cliv
func main() {
defer dbg.Exits("")
os.Args[0] = "zxdump"
dfltdump := zx.Path(dbg.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", &Verbose)
opts.NewFlag("D", "debug", &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, or empty if none", &Dump)
args, err := opts.Parse(os.Args)
if err != nil {
dbg.Warn("%s", err)
opts.Usage()
dbg.Exits(err)
}
if len(Xcludes) == 0 {
Xcludes = []string{".*", "tmp.*", "*.tmp"}
}
Xcludes = append(Xcludes, "tmp")
if len(args) == 0 {
dbg.Warn("arguments missing")
opts.Usage()
dbg.Exits("usage")
}
if Skip && Once {
dbg.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] = path.Base(al[0])
}
t, err := lfs.New(al[0], al[1], lfs.RO)
if err != nil {
dbg.Warn("%s: %s", al[0], err)
continue
}
t.ReadAttrs(true)
nt++
go dump(Dump, t, ec)
}
if nt == 0 {
dbg.Fatal("no trees to dump")
}
for nt > 0 {
<-ec
nt--
}
}
作者:Christopheraburn
项目:cliv
/*
Start the wax web server.
*/
func Serve(port string) error {
startedlk.Lock()
defer startedlk.Unlock()
if started {
return fmt.Errorf("already started")
}
started = true
http.HandleFunc("/js/", jsHandler)
if auth.TLSserver != nil {
dbg.Warn("wax: listening at https://%s:%s\n", dbg.Sys, port)
return http.ListenAndServeTLS(port, auth.ServerPem, auth.ServerKey, nil)
}
dbg.Warn("wax: listening at http://%s:%s\n", dbg.Sys, port)
return http.ListenAndServe(port, nil)
}
作者:Christopheraburn
项目:cliv
/*
Check out to see if resp is the expected response for the ch challenge on
the named auth domain.
Returns the user who authenticates and the status for authentication.
Always returns true when Auth is not enabled.
*/
func ChallengeResponseOk(name, ch, resp string) (user string, ok bool) {
u := dbg.Usr
if !Enabled {
return u, true
}
if keys==nil || iv==nil {
return u, false
}
u = keys[0].Uid
key := keys[0].Key
if name!="" && name!="default" {
var err error
ks, err := LoadKey(KeyDir(), name)
if err != nil {
dbg.Warn("auth: loadkey %s: %s", name, err)
return u, false
}
u, key = ks[0].Uid, ks[0].Key
}
chresp, ok := encrypt(key, iv, []byte(ch))
if !ok || len(chresp)==0 {
return u, false
}
return u, fmt.Sprintf("%x", chresp) == resp
}
作者:Christopheraburn
项目:cliv
func NewRedir(from, name string, app bool) Redirs {
if len(from) == 0 {
return nil
}
if len(from) > 1 {
rdr := NewRedir(from[:1], name, app)
for i := 1; i < len(from); i++ {
rdr = append(rdr, NewDup(from[i:i+1], from[:1])...)
}
return rdr
}
switch from {
case "0", "1", "2":
default:
dbg.Warn("%s: unknown redirect %c", addr, from)
nerrors++
return nil
}
return []*Redir{
{
From: int(from[0] - '0'),
Name: name,
App: app,
},
}
}
作者:Christopheraburn
项目:cliv
// called from yacc, to execute a top-level node.
func (nd *Nd) Exec() error {
if nd==nil || nd.Kind==Nnone || nd.Kind==Nnop {
return nil
}
var err error
switch nd.Kind {
case Npipe:
nd.mkExec(os.Stdin, os.Stdout, os.Stderr, Argv...)
err = nd.xPipe()
if err == nil {
if nd.async() {
bg.Add(nd)
go func() {
err := nd.wait()
bg.Del(nd, err)
}()
} else {
err = nd.wait()
}
}
case Nset:
nd.mkExec(os.Stdin, os.Stdout, os.Stderr, Argv...)
nd.xSet()
err = nd.wait()
default:
dbg.Warn("%s not yet implemented", nd.Kind)
err = dbg.ErrBug
}
setsts(err)
return err
}
作者:Christopheraburn
项目:cliv
func TestWait(t *testing.T) {
os.Args[0] = "app.test"
t.Skip("this is not a test")
Debug = testing.Verbose()
defer Exiting()
c := New()
c.Args = []string{"proc1"}
wc := make(chan *Ctx)
Printf("getting ctx\n")
go func() {
c := New()
c.Args = []string{"proc2"}
defer Exiting()
defer dbg.Warn("D2")
wc <- c
Printf("print2\n")
Fatal("ouch")
dprintf("end2\n")
}()
cc := <-wc
Printf("got ctx\n")
<-cc.Wait
Warn("cc sts %v\n", cerror(cc.Wait))
Fatal("fatal")
dprintf("end\n")
}
作者:Christopheraburn
项目:cliv
func lfscache(t zx.Tree, fn func()) (zx.Tree, func(), error) {
m, err := lfs.New("clfs", lfsdir, lfs.RW)
if err != nil {
return nil, nil, fmt.Errorf("lfs", err)
}
m.SaveAttrs(true)
m.IOstats = &zx.IOstats{}
m.Dbg = zdebug
ncfs.Debug = zdebug
xfs, err := ncfs.New("cfs", m, t, rflag)
if err != nil {
return nil, nil, fmt.Errorf("cfs: %s", err)
}
st := &zx.IOstats{}
xfs.IOstats = st
if xaddr != "" {
serve(xfs, xaddr)
}
if sflag {
xfn := func() {
st.Averages()
dbg.Warn("%s iostats:\n%s\n", xfs.Name(), st)
if fn != nil {
fn()
}
}
return xfs, xfn, nil
}
return xfs, fn, nil
}
作者:Christopheraburn
项目:cliv
// no locks, used only at init time
func (t *Fs) reloadChild(f *mFile) {
ds, err := zx.GetDir(t.lfs, f.d["path"])
if err != nil {
dbg.Warn("%s: reload: %s", t.name, err)
return
}
for _, d := range ds {
if d["path"] == "/Ctl" || d["path" ] == "/Chg" {
continue
}
cf := &mFile{
name: d["name"],
d: zx.Dir{
"name": d["name"],
"path": d["path"],
"spath": d["path"],
"tpath": t.path,
"type": d["type"],
"Wuid": d["Wuid"],
"Sum": d["Sum"],
},
}
for k, v := range d.UsrAttrs() {
cf.d[k] = v
}
f.child = append(f.child, cf)
if cf.d["type"] == "d" {
t.reloadChild(cf)
}
}
}
作者:Christopheraburn
项目:cliv
func usage(err error) {
dbg.Warn("%s", err)
opts.Usage()
fmt.Fprintf(os.Stderr, "\tspec is name | name!file | name!file!flags \n")
fmt.Fprintf(os.Stderr, "\tspec flags are ro | rw | ncro | ncrw \n")
dbg.Exits(err)
}
作者:Christopheraburn
项目:cliv
func ExampleNew() {
// create a tree
fs, err := New("example mfs")
if err != nil {
dbg.Fatal("lfs: %s", err)
}
dbg.Warn("fs %s ready", fs)
// Now use it...
}
作者:Christopheraburn
项目:cliv
func (c *FileInfo) checkClean() {
if c.state != CClean && c.state != CUnread && !c.busy {
dbg.Warn("%s: not clean and not busy: %s", c.path, c.state)
panic("bugs")
}
for _, cc := range c.child {
cc.checkClean()
}
}
作者:Christopheraburn
项目:cliv
func ExampleNew() {
// create a tree rooted at /bin in RO mode
fs, err := New("example lfs", "/bin", RO)
if err != nil {
dbg.Fatal("lfs: %s", err)
}
dbg.Warn("fs %s ready", fs)
// Now use it...
}
作者:Christopheraburn
项目:cliv
func (l *lex) source(what string) {
dat, err := ioutil.ReadFile(what)
if err != nil {
dbg.Warn("open: %s: %s", what, err)
return
}
l.in = append([]inText{bytes.NewBuffer(dat)}, l.in...)
l.saddr = append([]Addr{l.Addr}, l.saddr...)
l.Addr = Addr{what, 1}
}
作者:Christopheraburn
项目:cliv
func errc(tag string, ec chan error, nc chan int) {
n := 0
for e := range ec {
if e != nil && e.Error() != "pruned" {
n++
dbg.Warn("%s: %s", tag, e)
}
}
nc <- n
}
作者:Christopheraburn
项目:cliv
// Facade that serves t at the given address by using the ds
// to serve and calling Serve for each client.
func Server(t zx.Tree, addr string) {
dbg.Warn("serve %s at %s...", t.Name(), addr)
cc, ec, err := ds.Serve(os.Args[0], addr)
if err != nil {
dbg.Warn("serve: %s", err)
return
}
go func() {
for c := range cc {
if c != nil {
go serveFor(t, *c)
}
}
if err := cerror(cc); err != nil {
dbg.Warn("serve: %s", err)
}
close(ec, "done")
}()
}
作者:Christopheraburn
项目:cliv
func ExampleLfs_Stat() {
var fs *Lfs // = New("tag", path, RO|RW)
dirc := fs.Stat("/ls")
dir := <-dirc
if dir == nil {
dbg.Fatal("stat: %s", cerror(dirc))
}
dbg.Warn("stat was %s", dir)
}