Blob


1 /*
2 * Copyright (c) 2021 Omar Polo <op@omarpolo.com>
3 *
4 * Permission to use, copy, modify, and distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
7 *
8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15 */
17 #include "compat.h"
19 #include <inttypes.h>
20 #include <string.h>
22 #include "kami.h"
23 #include "log.h"
24 #include "utils.h"
26 #include "9pclib.h"
28 uint16_t iota_tag;
30 struct evbuffer *evb;
32 void
33 write_hdr(uint32_t len, uint8_t type, uint16_t tag)
34 {
35 len += HEADERSIZE;
37 log_debug("enqueuing a packet; len=%"PRIu32" type=%d[%s] tag=%d",
38 len, type, pp_msg_type(type), tag);
40 len = htole32(len);
41 /* type is one byte, no endiannes issues */
42 tag = htole16(tag);
44 evbuffer_add(evb, &len, sizeof(len));
45 evbuffer_add(evb, &type, sizeof(type));
46 evbuffer_add(evb, &tag, sizeof(tag));
47 }
49 void
50 write_hdr_auto(uint32_t len, uint8_t type)
51 {
52 if (++iota_tag == NOTAG)
53 ++iota_tag;
54 write_hdr(len, type, iota_tag);
55 }
57 void
58 write_str(uint16_t len, const char *str)
59 {
60 uint16_t l = len;
62 len = htole16(len);
63 evbuffer_add(evb, &len, sizeof(len));
64 evbuffer_add(evb, str, l);
65 }
67 void
68 write_str_auto(const char *str)
69 {
70 if (str == NULL)
71 write_16(0);
72 else
73 write_str(strlen(str), str);
74 }
76 void
77 write_buf(const void *d, uint32_t len)
78 {
79 write_32(len);
80 evbuffer_add(evb, d, len);
81 }
83 void
84 write_64(uint64_t x)
85 {
86 x = htole64(x);
87 evbuffer_add(evb, &x, sizeof(x));
88 }
90 void
91 write_32(uint32_t fid)
92 {
93 fid = htole32(fid);
94 evbuffer_add(evb, &fid, sizeof(fid));
95 }
97 void
98 write_16(uint16_t tag)
99 {
100 tag = htole16(tag);
101 evbuffer_add(evb, &tag, sizeof(tag));
104 void
105 write_8(uint8_t x)
107 evbuffer_add(evb, &x, sizeof(x));
112 void
113 tversion(const char *v, uint32_t msize)
115 uint32_t len;
116 uint16_t sl;
118 sl = strlen(v);
120 /* msize[4] version[s] */
121 len = sizeof(msize) + sizeof(sl) + sl;
122 write_hdr(len, Tversion, NOTAG);
123 write_32(msize);
124 write_str(sl, v);
127 void
128 tattach(uint32_t fid, uint32_t afid, const char *uname, const char *aname)
130 uint32_t len;
131 uint16_t ul, al;
133 ul = strlen(uname);
134 al = strlen(aname);
136 /* fid[4] afid[4] uname[s] aname[s] */
137 len = sizeof(fid) + sizeof(afid) + sizeof(ul) + ul
138 + sizeof(al) + al;
139 write_hdr_auto(len, Tattach);
140 write_fid(fid);
141 write_fid(afid);
142 write_str(ul, uname);
143 write_str(al, aname);
146 void
147 tclunk(uint32_t fid)
149 uint32_t len;
151 /* fid[4] */
152 len = sizeof(fid);
153 write_hdr_auto(len, Tclunk);
154 write_fid(fid);
157 void
158 tflush(uint16_t oldtag)
160 uint32_t len;
162 /* oldtag[2] */
163 len = sizeof(oldtag);
164 write_hdr_auto(len, Tflush);
165 write_tag(oldtag);
168 void
169 twalk(uint32_t fid, uint32_t newfid, const char **wnames, size_t nwname)
171 size_t i;
172 uint32_t len;
174 /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
175 len = sizeof(fid) + sizeof(newfid) + 2;
176 for (i = 0; i < nwname; ++i)
177 len += 2 + strlen(wnames[i]);
179 write_hdr_auto(len, Twalk);
180 write_fid(fid);
181 write_fid(newfid);
182 write_16(nwname);
183 for (i = 0; i < nwname; ++i)
184 write_str_auto(wnames[i]);
187 void
188 topen(uint32_t fid, uint8_t mode)
190 uint32_t len;
192 /* fid[4] mode[1] */
193 len = sizeof(fid) + sizeof(mode);
194 write_hdr_auto(len, Topen);
195 write_fid(fid);
196 write_8(mode);
199 void
200 tcreate(uint32_t fid, const char *name, uint32_t perm, uint8_t mode)
202 uint32_t len;
203 uint16_t nl;
205 /* fid[4] name[s] perm[4] mode[1] */
206 nl = strlen(name);
207 len = sizeof(fid) + sizeof(nl) + nl + sizeof(perm) + sizeof(mode);
208 write_hdr_auto(len, Tcreate);
209 write_fid(fid);
210 write_str(nl, name);
211 write_32(perm);
212 write_8(mode);
215 void
216 tread(uint32_t fid, uint64_t off, uint32_t count)
218 uint32_t len;
220 /* fid[4] off[8] count[4] */
221 len = sizeof(fid) + sizeof(off) + sizeof(count);
222 write_hdr_auto(len, Tread);
223 write_fid(fid);
224 write_off(off);
225 write_32(count);
228 void
229 twrite(uint32_t fid, uint64_t off, const void *data, uint32_t count)
231 uint32_t len;
233 /* fid[4] off[8] count[4] data[count] */
234 len = sizeof(fid) + sizeof(off) + sizeof(count) + count;
235 write_hdr_auto(len, Twrite);
236 write_fid(fid);
237 write_off(off);
238 write_buf(data, count);
241 void
242 tstat(uint32_t fid)
244 /* fid[4] */
245 write_hdr_auto(sizeof(fid), Tstat);
246 write_fid(fid);
249 void
250 twstat(uint32_t fid, const struct np_stat *st)
252 uint32_t len;
253 uint16_t stlen, n;
255 /* fid[4] stat[n] */
257 stlen = NPSTATSIZ(0, 0, 0, 0);
258 if (st->name != NULL)
259 stlen += strlen(st->name);
260 if (st->uid != NULL)
261 stlen += strlen(st->uid);
262 if (st->gid != NULL)
263 stlen += strlen(st->gid);
264 if (st->muid != NULL)
265 stlen += strlen(st->muid);
267 n = sizeof(stlen) + stlen;
268 len = sizeof(fid) + sizeof(n) + n;
270 write_hdr_auto(len, Twstat);
271 write_fid(fid);
272 write_16(n);
273 write_16(stlen);
274 write_16(st->type);
275 write_32(st->dev);
277 write_8(st->qid.type);
278 write_32(st->qid.vers);
279 write_64(st->qid.path);
281 write_32(st->mode);
282 write_32(st->atime);
283 write_32(st->mtime);
284 write_64(st->length);
286 write_str_auto(st->name);
287 write_str_auto(st->uid);
288 write_str_auto(st->gid);
289 write_str_auto(st->muid);
292 void
293 tremove(uint32_t fid)
295 /* fid[4] */
296 write_hdr_auto(sizeof(fid), Tremove);
297 write_fid(fid);