9fans.net/go@v0.0.5/plan9/client/fsys.go (about)

     1  // +build !plan9
     2  
     3  package client
     4  
     5  import (
     6  	"strings"
     7  
     8  	"9fans.net/go/plan9"
     9  )
    10  
    11  type Fsys struct {
    12  	root *Fid
    13  }
    14  
    15  func (c *Conn) Auth(uname, aname string) (*Fid, error) {
    16  	conn, err := c.conn()
    17  	if err != nil {
    18  		return nil, err
    19  	}
    20  	afidnum, err := conn.newfidnum()
    21  	if err != nil {
    22  		return nil, err
    23  	}
    24  	tx := &plan9.Fcall{Type: plan9.Tauth, Afid: afidnum, Uname: uname, Aname: aname}
    25  	rx, err := conn.rpc(tx, nil)
    26  	if err != nil {
    27  		conn.putfidnum(afidnum)
    28  		return nil, err
    29  	}
    30  	return conn.newFid(afidnum, rx.Qid), nil
    31  }
    32  
    33  func (c *Conn) Attach(afid *Fid, user, aname string) (*Fsys, error) {
    34  	conn, err := c.conn()
    35  	if err != nil {
    36  		return nil, err
    37  	}
    38  	fidnum, err := conn.newfidnum()
    39  	if err != nil {
    40  		return nil, err
    41  	}
    42  	tx := &plan9.Fcall{Type: plan9.Tattach, Afid: plan9.NOFID, Fid: fidnum, Uname: user, Aname: aname}
    43  	if afid != nil {
    44  		tx.Afid = afid.fid
    45  	}
    46  	rx, err := conn.rpc(tx, nil)
    47  	if err != nil {
    48  		conn.putfidnum(fidnum)
    49  		return nil, err
    50  	}
    51  	return &Fsys{conn.newFid(fidnum, rx.Qid)}, nil
    52  }
    53  
    54  var accessOmode = [8]uint8{
    55  	0,
    56  	plan9.OEXEC,
    57  	plan9.OWRITE,
    58  	plan9.ORDWR,
    59  	plan9.OREAD,
    60  	plan9.OEXEC, // only approximate
    61  	plan9.ORDWR,
    62  	plan9.ORDWR, // only approximate
    63  }
    64  
    65  func (fs *Fsys) Access(name string, mode int) error {
    66  	if mode == plan9.AEXIST {
    67  		_, err := fs.Stat(name)
    68  		return err
    69  	}
    70  	fid, err := fs.Open(name, accessOmode[mode&7])
    71  	if fid != nil {
    72  		fid.Close()
    73  	}
    74  	return err
    75  }
    76  
    77  func (fs *Fsys) Create(name string, mode uint8, perm plan9.Perm) (*Fid, error) {
    78  	i := strings.LastIndex(name, "/")
    79  	var dir, elem string
    80  	if i < 0 {
    81  		elem = name
    82  	} else {
    83  		dir, elem = name[0:i], name[i+1:]
    84  	}
    85  	fid, err := fs.root.Walk(dir)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	err = fid.Create(elem, mode, perm)
    90  	if err != nil {
    91  		fid.Close()
    92  		return nil, err
    93  	}
    94  	return fid, nil
    95  }
    96  
    97  func (fs *Fsys) Open(name string, mode uint8) (*Fid, error) {
    98  	fid, err := fs.root.Walk(name)
    99  	if err != nil {
   100  		return nil, err
   101  	}
   102  	if err := fid.Open(mode); err != nil {
   103  		fid.Close()
   104  		return nil, err
   105  	}
   106  	return fid, nil
   107  }
   108  
   109  func (fs *Fsys) Remove(name string) error {
   110  	fid, err := fs.root.Walk(name)
   111  	if err != nil {
   112  		return err
   113  	}
   114  	return fid.Remove()
   115  }
   116  
   117  func (fs *Fsys) Stat(name string) (*plan9.Dir, error) {
   118  	fid, err := fs.root.Walk(name)
   119  	if err != nil {
   120  		return nil, err
   121  	}
   122  	d, err := fid.Stat()
   123  	fid.Close()
   124  	return d, err
   125  }
   126  
   127  func (fs *Fsys) Wstat(name string, d *plan9.Dir) error {
   128  	fid, err := fs.root.Walk(name)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	err = fid.Wstat(d)
   133  	fid.Close()
   134  	return err
   135  }
   136  
   137  // Close closes the Fid underlying fs.
   138  func (fs *Fsys) Close() error {
   139  	return fs.root.Close()
   140  }