xref: /plan9/sys/src/ape/lib/ap/plan9/dirstat.c (revision 16a961bdb6a291dd2ca1e8266b5a1eba656ecc70)
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