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

     1  package plan9
     2  
     3  import (
     4  	"fmt"
     5  	"strconv"
     6  )
     7  
     8  type ProtocolError string
     9  
    10  func (e ProtocolError) Error() string {
    11  	return string(e)
    12  }
    13  
    14  const (
    15  	STATMAX = 65535
    16  )
    17  
    18  type Dir struct {
    19  	Type   uint16
    20  	Dev    uint32
    21  	Qid    Qid
    22  	Mode   Perm
    23  	Atime  uint32
    24  	Mtime  uint32
    25  	Length uint64
    26  	Name   string
    27  	Uid    string
    28  	Gid    string
    29  	Muid   string
    30  }
    31  
    32  var nullDir = Dir{
    33  	^uint16(0),
    34  	^uint32(0),
    35  	Qid{^uint64(0), ^uint32(0), ^uint8(0)},
    36  	^Perm(0),
    37  	^uint32(0),
    38  	^uint32(0),
    39  	^uint64(0),
    40  	"",
    41  	"",
    42  	"",
    43  	"",
    44  }
    45  
    46  func (d *Dir) Null() {
    47  	*d = nullDir
    48  }
    49  
    50  func pdir(b []byte, d *Dir) []byte {
    51  	n := len(b)
    52  	b = pbit16(b, 0) // length, filled in later
    53  	b = pbit16(b, d.Type)
    54  	b = pbit32(b, d.Dev)
    55  	b = pqid(b, d.Qid)
    56  	b = pperm(b, d.Mode)
    57  	b = pbit32(b, d.Atime)
    58  	b = pbit32(b, d.Mtime)
    59  	b = pbit64(b, d.Length)
    60  	b = pstring(b, d.Name)
    61  	b = pstring(b, d.Uid)
    62  	b = pstring(b, d.Gid)
    63  	b = pstring(b, d.Muid)
    64  	pbit16(b[0:n], uint16(len(b)-(n+2)))
    65  	return b
    66  }
    67  
    68  func (d *Dir) Bytes() ([]byte, error) {
    69  	return pdir(nil, d), nil
    70  }
    71  
    72  func UnmarshalDir(b []byte) (d *Dir, err error) {
    73  	defer func() {
    74  		if v := recover(); v != nil {
    75  			d = nil
    76  			err = ProtocolError("malformed Dir")
    77  		}
    78  	}()
    79  
    80  	n, b := gbit16(b)
    81  	if int(n) != len(b) {
    82  		panic(1)
    83  	}
    84  
    85  	d = new(Dir)
    86  	d.Type, b = gbit16(b)
    87  	d.Dev, b = gbit32(b)
    88  	d.Qid, b = gqid(b)
    89  	d.Mode, b = gperm(b)
    90  	d.Atime, b = gbit32(b)
    91  	d.Mtime, b = gbit32(b)
    92  	d.Length, b = gbit64(b)
    93  	d.Name, b = gstring(b)
    94  	d.Uid, b = gstring(b)
    95  	d.Gid, b = gstring(b)
    96  	d.Muid, b = gstring(b)
    97  
    98  	if len(b) != 0 {
    99  		panic(1)
   100  	}
   101  	return d, nil
   102  }
   103  
   104  func (d *Dir) String() string {
   105  	return fmt.Sprintf("'%s' '%s' '%s' '%s' q %v m %#o at %d mt %d l %d t %d d %d",
   106  		d.Name, d.Uid, d.Gid, d.Muid, d.Qid, d.Mode,
   107  		d.Atime, d.Mtime, d.Length, d.Type, d.Dev)
   108  }
   109  
   110  func dumpsome(b []byte) string {
   111  	if len(b) > 64 {
   112  		b = b[0:64]
   113  	}
   114  
   115  	printable := true
   116  	for _, c := range b {
   117  		if (c != 0 && c != '\n' && c != '\t' && c < ' ') || c > 127 {
   118  			printable = false
   119  			break
   120  		}
   121  	}
   122  
   123  	if printable {
   124  		return strconv.Quote(string(b))
   125  	}
   126  	return fmt.Sprintf("%x", b)
   127  }
   128  
   129  type Perm uint32
   130  
   131  type permChar struct {
   132  	bit Perm
   133  	c   rune
   134  }
   135  
   136  var permChars = []permChar{
   137  	permChar{DMDIR, 'd'},
   138  	permChar{DMAPPEND, 'a'},
   139  	permChar{DMAUTH, 'A'},
   140  	permChar{DMDEVICE, 'D'},
   141  	permChar{DMSOCKET, 'S'},
   142  	permChar{DMNAMEDPIPE, 'P'},
   143  	permChar{0, '-'},
   144  	permChar{DMEXCL, 'l'},
   145  	permChar{DMSYMLINK, 'L'},
   146  	permChar{0, '-'},
   147  	permChar{0400, 'r'},
   148  	permChar{0, '-'},
   149  	permChar{0200, 'w'},
   150  	permChar{0, '-'},
   151  	permChar{0100, 'x'},
   152  	permChar{0, '-'},
   153  	permChar{0040, 'r'},
   154  	permChar{0, '-'},
   155  	permChar{0020, 'w'},
   156  	permChar{0, '-'},
   157  	permChar{0010, 'x'},
   158  	permChar{0, '-'},
   159  	permChar{0004, 'r'},
   160  	permChar{0, '-'},
   161  	permChar{0002, 'w'},
   162  	permChar{0, '-'},
   163  	permChar{0001, 'x'},
   164  	permChar{0, '-'},
   165  }
   166  
   167  func (p Perm) String() string {
   168  	s := ""
   169  	did := false
   170  	for _, pc := range permChars {
   171  		if p&pc.bit != 0 {
   172  			did = true
   173  			s += string(pc.c)
   174  		}
   175  		if pc.bit == 0 {
   176  			if !did {
   177  				s += string(pc.c)
   178  			}
   179  			did = false
   180  		}
   181  	}
   182  	return s
   183  }
   184  
   185  func gperm(b []byte) (Perm, []byte) {
   186  	p, b := gbit32(b)
   187  	return Perm(p), b
   188  }
   189  
   190  func pperm(b []byte, p Perm) []byte {
   191  	return pbit32(b, uint32(p))
   192  }
   193  
   194  type Qid struct {
   195  	Path uint64
   196  	Vers uint32
   197  	Type uint8
   198  }
   199  
   200  func (q Qid) String() string {
   201  	t := ""
   202  	if q.Type&QTDIR != 0 {
   203  		t += "d"
   204  	}
   205  	if q.Type&QTAPPEND != 0 {
   206  		t += "a"
   207  	}
   208  	if q.Type&QTEXCL != 0 {
   209  		t += "l"
   210  	}
   211  	if q.Type&QTAUTH != 0 {
   212  		t += "A"
   213  	}
   214  	return fmt.Sprintf("(%.16x %d %s)", q.Path, q.Vers, t)
   215  }
   216  
   217  func gqid(b []byte) (Qid, []byte) {
   218  	var q Qid
   219  	q.Type, b = gbit8(b)
   220  	q.Vers, b = gbit32(b)
   221  	q.Path, b = gbit64(b)
   222  	return q, b
   223  }
   224  
   225  func pqid(b []byte, q Qid) []byte {
   226  	b = pbit8(b, q.Type)
   227  	b = pbit32(b, q.Vers)
   228  	b = pbit64(b, q.Path)
   229  	return b
   230  }