qio: Remove q->len
[akaros.git] / kern / src / ns / convM2kdirent.c
1
2 #include <vfs.h>
3 #include <kfs.h>
4 #include <slab.h>
5 #include <kmalloc.h>
6 #include <kref.h>
7 #include <string.h>
8 #include <stdio.h>
9 #include <assert.h>
10 #include <error.h>
11 #include <cpio.h>
12 #include <pmap.h>
13 #include <smp.h>
14 #include <ip.h>
15
16 /* Special akaros edition. */
17 /* akaros does not (yet) pass as much info as plan 9 does,
18  * and it still has stuff I'm not happy about like an inode number.
19  */
20 #if 0
21 struct kdirent {
22         __ino64_t d_ino;                        /* inod
23                                                                    e number */
24         __off64_t d_off;                        /* offs
25                                                                    et to the next dirent */
26         unsigned short d_reclen;        /* length of th
27                                                                    is record */
28         unsigned char d_type;
29         char d_name[MAX_FILENAME_SZ + 1];       /* filename */
30 } __attribute__ ((aligned(8)));
31
32 #endif
33
34 unsigned int convM2kdirent(uint8_t * buf, unsigned int nbuf, struct kdirent *kd,
35                                                    char *strs)
36 {
37         uint8_t *p, *ebuf;
38         char *sv[4];
39         int i, ns;
40         uint32_t junk;
41         printd("%s >>>>>>>>>nbuf %d STATFIXLEN %d\n", __func__, nbuf, STATFIXLEN);
42         if (nbuf < STATFIXLEN)
43                 return 0;
44
45         p = buf;
46         ebuf = buf + nbuf;
47
48         p += BIT16SZ;   /* ignore size */
49         kd->d_type = GBIT16(p);
50         p += BIT16SZ;
51         junk = GBIT32(p);
52         p += BIT32SZ;
53         junk = GBIT8(p);
54         p += BIT8SZ;
55         junk = GBIT32(p);
56         p += BIT32SZ;
57         kd->d_ino = GBIT64(p);
58         p += BIT64SZ;
59         junk /* mode */  = GBIT32(p);
60         p += BIT32SZ;
61         junk /*d->atime */  = GBIT32(p);
62         p += BIT32SZ;
63         junk /*d->mtime */  = GBIT32(p);
64         p += BIT32SZ;
65         junk /*d->length */  = GBIT64(p);
66         p += BIT64SZ;
67
68         /* for now, uids in akaros are ints. Does not
69          * matter; kdirents are limited in what they tell you.
70          * get the name, ignore the rest. Maybe we can
71          * fix this later.
72          */
73         for (i = 0; i < 4; i++) {
74                 if (p + BIT16SZ > ebuf)
75                         return 0;
76                 ns = GBIT16(p);
77                 p += BIT16SZ;
78                 if (p + ns > ebuf)
79                         return 0;
80                 if (strs) {
81                         sv[i] = strs;
82                         memmove(strs, p, ns);
83                         strs += ns;
84                         *strs++ = '\0';
85                 }
86                 if (i == 0) {
87                         kd->d_reclen = ns;
88                         printd("memmove %p %p %d\n", kd->d_name, p, ns);
89                         memmove(kd->d_name, p, ns);
90                         kd->d_name[ns] = 0;
91                 }
92                 p += ns;
93         }
94
95         printd("%s returns %d %s\n", __func__, p - buf, kd->d_name);
96         return p - buf;
97 }
98
99 static int mode_9ns_to_posix(int mode_9ns)
100 {
101         int mode_posix = 0;
102
103         if (mode_9ns & DMDIR)
104                 mode_posix |= __S_IFDIR;
105         else if (mode_9ns & DMSYMLINK)
106                 mode_posix |= __S_IFLNK;
107         else
108                 mode_posix |= __S_IFREG;
109         if (mode_9ns & DMREADABLE)
110                 mode_posix |= __S_READABLE;
111         if (mode_9ns & DMWRITABLE)
112                 mode_posix |= __S_WRITABLE;
113         mode_posix |= mode_9ns & 0777;
114         return mode_posix;
115 }
116
117 unsigned int convM2kstat(uint8_t * buf, unsigned int nbuf, struct kstat *ks)
118 {
119         uint8_t *p, *ebuf;
120         char *sv[4];
121         int i, ns;
122         uint32_t junk;
123
124         if (nbuf < STATFIXLEN)
125                 return 0;
126
127         p = buf;
128         ebuf = buf + nbuf;
129
130         p += BIT16SZ;   /* ignore size */
131         junk /*kd->d_type */  = GBIT16(p);
132         p += BIT16SZ;
133         ks->st_rdev = ks->st_dev = GBIT32(p);
134         p += BIT32SZ;
135         junk /*qid.type */  = GBIT8(p);
136         p += BIT8SZ;
137         junk /*qid.vers */  = GBIT32(p);
138         p += BIT32SZ;
139         ks->st_ino = GBIT64(p);
140         p += BIT64SZ;
141         ks->st_mode = mode_9ns_to_posix(GBIT32(p));
142         p += BIT32SZ;
143         ks->st_atim.tv_sec = GBIT32(p);
144         p += BIT32SZ;
145         ks->st_mtim.tv_sec = GBIT32(p);
146         p += BIT32SZ;
147         ks->st_size = GBIT64(p);
148         p += BIT64SZ;
149         ks->st_blksize = 512;
150         ks->st_blocks = ROUNDUP(ks->st_size, ks->st_blksize) / ks->st_blksize;
151
152         ks->st_nlink = 2;       // links make no sense any more.
153         ks->st_uid = ks->st_gid = 0;
154
155         return p - buf;
156 }