xref: /inferno-os/lib9/convD2M.c (revision 37da2899f40661e3e9631e497da8dc59b971cbd0)
1 #include	"lib9.h"
2 #include	"fcall.h"
3 
4 uint
sizeD2M(Dir * d)5 sizeD2M(Dir *d)
6 {
7 	char *sv[4];
8 	int i, ns;
9 
10 	sv[0] = d->name;
11 	sv[1] = d->uid;
12 	sv[2] = d->gid;
13 	sv[3] = d->muid;
14 
15 	ns = 0;
16 	for(i = 0; i < 4; i++)
17 		if(sv[i])
18 			ns += strlen(sv[i]);
19 
20 	return STATFIXLEN + ns;
21 }
22 
23 uint
convD2M(Dir * d,uchar * buf,uint nbuf)24 convD2M(Dir *d, uchar *buf, uint nbuf)
25 {
26 	uchar *p, *ebuf;
27 	char *sv[4];
28 	int i, ns, nsv[4], ss;
29 
30 	if(nbuf < BIT16SZ)
31 		return 0;
32 
33 	p = buf;
34 	ebuf = buf + nbuf;
35 
36 	sv[0] = d->name;
37 	sv[1] = d->uid;
38 	sv[2] = d->gid;
39 	sv[3] = d->muid;
40 
41 	ns = 0;
42 	for(i = 0; i < 4; i++){
43 		if(sv[i])
44 			nsv[i] = strlen(sv[i]);
45 		else
46 			nsv[i] = 0;
47 		ns += nsv[i];
48 	}
49 
50 	ss = STATFIXLEN + ns;
51 
52 	/* set size befor erroring, so user can know how much is needed */
53 	/* note that length excludes count field itself */
54 	PBIT16(p, ss-BIT16SZ);
55 	p += BIT16SZ;
56 
57 	if(ss > nbuf)
58 		return BIT16SZ;
59 
60 	PBIT16(p, d->type);
61 	p += BIT16SZ;
62 	PBIT32(p, d->dev);
63 	p += BIT32SZ;
64 	PBIT8(p, d->qid.type);
65 	p += BIT8SZ;
66 	PBIT32(p, d->qid.vers);
67 	p += BIT32SZ;
68 	PBIT64(p, d->qid.path);
69 	p += BIT64SZ;
70 	PBIT32(p, d->mode);
71 	p += BIT32SZ;
72 	PBIT32(p, d->atime);
73 	p += BIT32SZ;
74 	PBIT32(p, d->mtime);
75 	p += BIT32SZ;
76 	PBIT64(p, d->length);
77 	p += BIT64SZ;
78 
79 	for(i = 0; i < 4; i++){
80 		ns = nsv[i];
81 		if(p + ns + BIT16SZ > ebuf)
82 			return 0;
83 		PBIT16(p, ns);
84 		p += BIT16SZ;
85 		if(ns)
86 			memmove(p, sv[i], ns);
87 		p += ns;
88 	}
89 
90 	if(ss != p - buf)
91 		return 0;
92 
93 	return p - buf;
94 }
95