107 lines
1.9 KiB
C
107 lines
1.9 KiB
C
/*
|
|
* This file is part of the UCB release of Plan 9. It is subject to the license
|
|
* terms in the LICENSE file found in the top-level directory of this
|
|
* distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
|
|
* part of the UCB release of Plan 9, including this file, may be copied,
|
|
* modified, propagated, or distributed except according to the terms contained
|
|
* in the LICENSE file.
|
|
*/
|
|
#define PORTABLE_SYSCALLS
|
|
#include <u.h>
|
|
#include <libc.h>
|
|
#include <9P2000.h>
|
|
|
|
static
|
|
int32_t
|
|
dirpackage(uint8_t *buf, int32_t ts, Dir **d)
|
|
{
|
|
char *s;
|
|
int32_t ss, i, n, nn, m;
|
|
|
|
*d = nil;
|
|
if(ts <= 0)
|
|
return 0;
|
|
|
|
/*
|
|
* first find number of all stats, check they look like stats, & size all associated strings
|
|
*/
|
|
ss = 0;
|
|
n = 0;
|
|
for(i = 0; i < ts; i += m){
|
|
m = BIT16SZ + GBIT16(&buf[i]);
|
|
if(statcheck(&buf[i], m) < 0)
|
|
break;
|
|
ss += m;
|
|
n++;
|
|
}
|
|
|
|
if(i != ts)
|
|
return -1;
|
|
|
|
*d = jehanne_malloc(n * sizeof(Dir) + ss);
|
|
if(*d == nil)
|
|
return -1;
|
|
|
|
/*
|
|
* then convert all buffers
|
|
*/
|
|
s = (char*)*d + n * sizeof(Dir);
|
|
nn = 0;
|
|
for(i = 0; i < ts; i += m){
|
|
m = BIT16SZ + GBIT16((uint8_t*)&buf[i]);
|
|
if(nn >= n || jehanne_convM2D(&buf[i], m, *d + nn, s) != m){
|
|
jehanne_free(*d);
|
|
*d = nil;
|
|
return -1;
|
|
}
|
|
nn++;
|
|
s += m;
|
|
}
|
|
|
|
return nn;
|
|
}
|
|
|
|
int32_t
|
|
jehanne_dirread(int fd, Dir **d)
|
|
{
|
|
uint8_t *buf;
|
|
int32_t ts;
|
|
|
|
buf = jehanne_malloc(DIRMAX);
|
|
if(buf == nil)
|
|
return -1;
|
|
ts = jehanne_read(fd, buf, DIRMAX);
|
|
if(ts >= 0)
|
|
ts = dirpackage(buf, ts, d);
|
|
jehanne_free(buf);
|
|
return ts;
|
|
}
|
|
|
|
int32_t
|
|
jehanne_dirreadall(int fd, Dir **d)
|
|
{
|
|
uint8_t *buf, *nbuf;
|
|
int32_t n, ts;
|
|
|
|
buf = nil;
|
|
ts = 0;
|
|
for(;;){
|
|
nbuf = jehanne_realloc(buf, ts+DIRMAX);
|
|
if(nbuf == nil){
|
|
jehanne_free(buf);
|
|
return -1;
|
|
}
|
|
buf = nbuf;
|
|
n = jehanne_read(fd, buf+ts, DIRMAX);
|
|
if(n <= 0)
|
|
break;
|
|
ts += n;
|
|
}
|
|
if(ts >= 0)
|
|
ts = dirpackage(buf, ts, d);
|
|
jehanne_free(buf);
|
|
if(ts == 0 && n < 0)
|
|
return -1;
|
|
return ts;
|
|
}
|