1 #include "lib.h"
2 #include <string.h>
3 #include <stdlib.h>
4 #include "sys9.h"
5 #include "dir.h"
6
7 enum
8 {
9 DIRSIZE = STATFIXLEN + 16 * 4 /* enough for encoded stat buf + some reasonable strings */
10 };
11
12 Dir*
_dirstat(char * name)13 _dirstat(char *name)
14 {
15 Dir *d;
16 uchar *buf;
17 int n, nd, i;
18
19 nd = DIRSIZE;
20 for(i=0; i<2; i++){ /* should work by the second try */
21 d = malloc(sizeof(Dir) + BIT16SZ +nd);
22 if(d == nil)
23 return nil;
24 buf = (uchar*)&d[1];
25 n = _STAT(name, buf, BIT16SZ+nd);
26 if(n < BIT16SZ){
27 free(d);
28 return nil;
29 }
30 nd = GBIT16((uchar*)buf); /* size needed to store whole stat buffer */
31 if(nd <= n){
32 _convM2D(buf, n, d, (char*)&d[1]);
33 return d;
34 }
35 /* else sizeof(Dir)+BIT16SZ+nd is plenty */
36 free(d);
37 }
38 return nil;
39 }
40
41 int
_dirwstat(char * name,Dir * d)42 _dirwstat(char *name, Dir *d)
43 {
44 uchar *buf;
45 int r;
46
47 r = _sizeD2M(d);
48 buf = malloc(r);
49 if(buf == nil)
50 return -1;
51 _convD2M(d, buf, r);
52 r = _WSTAT(name, buf, r);
53 free(buf);
54 return r;
55 }
56
57 Dir*
_dirfstat(int fd)58 _dirfstat(int fd)
59 {
60 Dir *d;
61 uchar *buf;
62 int n, nd, i;
63
64 nd = DIRSIZE;
65 for(i=0; i<2; i++){ /* should work by the second try */
66 d = malloc(sizeof(Dir) + nd);
67 if(d == nil)
68 return nil;
69 buf = (uchar*)&d[1];
70 n = _FSTAT(fd, buf, nd);
71 if(n < BIT16SZ){
72 free(d);
73 return nil;
74 }
75 nd = GBIT16(buf); /* size needed to store whole stat buffer */
76 if(nd <= n){
77 _convM2D(buf, n, d, (char*)&d[1]);
78 return d;
79 }
80 /* else sizeof(Dir)+nd is plenty */
81 free(d);
82 }
83 return nil;
84 }
85
86 int
_dirfwstat(int fd,Dir * d)87 _dirfwstat(int fd, Dir *d)
88 {
89 uchar *buf;
90 int r;
91
92 r = _sizeD2M(d);
93 buf = malloc(r);
94 if(buf == nil)
95 return -1;
96 _convD2M(d, buf, r);
97 r = _FWSTAT(fd, buf, r);
98 free(buf);
99 return r;
100 }
101
102 void
_nulldir(Dir * d)103 _nulldir(Dir *d)
104 {
105 memset(d, ~0, sizeof(Dir));
106 d->name = d->uid = d->gid = d->muid = "";
107 }
108