Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include <u.h>
2
#include <libc.h>
3
#include <fcall.h>
4
 
5
static
6
long
7
dirpackage(uchar *buf, long ts, Dir **d)
8
{
9
	char *s;
10
	long ss, i, n, nn, m;
11
 
12
	*d = nil;
13
	if(ts <= 0)
14
		return 0;
15
 
16
	/*
17
	 * first find number of all stats, check they look like stats, & size all associated strings
18
	 */
19
	ss = 0;
20
	n = 0;
21
	for(i = 0; i < ts; i += m){
22
		m = BIT16SZ + GBIT16(&buf[i]);
23
		if(statcheck(&buf[i], m) < 0)
24
			break;
25
		ss += m;
26
		n++;
27
	}
28
 
29
	if(i != ts)
30
		return -1;
31
 
32
	*d = malloc(n * sizeof(Dir) + ss);
33
	if(*d == nil)
34
		return -1;
35
 
36
	/*
37
	 * then convert all buffers
38
	 */
39
	s = (char*)*d + n * sizeof(Dir);
40
	nn = 0;
41
	for(i = 0; i < ts; i += m){
42
		m = BIT16SZ + GBIT16((uchar*)&buf[i]);
43
		if(nn >= n || convM2D(&buf[i], m, *d + nn, s) != m){
44
			free(*d);
45
			*d = nil;
46
			return -1;
47
		}
48
		nn++;
49
		s += m;
50
	}
51
 
52
	return nn;
53
}
54
 
55
long
56
dirread(int fd, Dir **d)
57
{
58
	uchar *buf;
59
	long ts;
60
 
61
	buf = malloc(DIRMAX);
62
	if(buf == nil)
63
		return -1;
64
	ts = read(fd, buf, DIRMAX);
65
	if(ts >= 0)
66
		ts = dirpackage(buf, ts, d);
67
	free(buf);
68
	return ts;
69
}
70
 
71
long
72
dirreadall(int fd, Dir **d)
73
{
74
	uchar *buf, *nbuf;
75
	long n, ts;
76
 
77
	buf = nil;
78
	ts = 0;
79
	for(;;){
80
		nbuf = realloc(buf, ts+DIRMAX);
81
		if(nbuf == nil){
82
			free(buf);
83
			return -1;
84
		}
85
		buf = nbuf;
86
		n = read(fd, buf+ts, DIRMAX);
87
		if(n <= 0)
88
			break;
89
		ts += n;
90
	}
91
	if(ts >= 0)
92
		ts = dirpackage(buf, ts, d);
93
	free(buf);
94
	if(ts == 0 && n < 0)
95
		return -1;
96
	return ts;
97
}