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 <endian.h>
20 #include <inttypes.h>
21 #include <string.h>
23 #include "kami.h"
24 #include "log.h"
25 #include "utils.h"
27 #include "9pclib.h"
29 uint16_t iota_tag;
31 struct evbuffer *evb;
33 void
34 write_hdr(uint32_t len, uint8_t type, uint16_t tag)
35 {
36 len += HEADERSIZE;
38 log_debug("enqueuing a packet; len=%"PRIu32" type=%d[%s] tag=%d",
39 len, type, pp_msg_type(type), tag);
41 len = htole32(len);
42 /* type is one byte, no endiannes issues */
43 tag = htole16(tag);
45 evbuffer_add(evb, &len, sizeof(len));
46 evbuffer_add(evb, &type, sizeof(type));
47 evbuffer_add(evb, &tag, sizeof(tag));
48 }
50 void
51 write_hdr_auto(uint32_t len, uint8_t type)
52 {
53 if (++iota_tag == NOTAG)
54 ++iota_tag;
55 write_hdr(len, type, iota_tag);
56 }
58 void
59 write_str(uint16_t len, const char *str)
60 {
61 uint16_t l = len;
63 len = htole16(len);
64 evbuffer_add(evb, &len, sizeof(len));
65 evbuffer_add(evb, str, l);
66 }
68 void
69 write_str_auto(const char *str)
70 {
71 if (str == NULL)
72 write_16(0);
73 else
74 write_str(strlen(str), str);
75 }
77 void
78 write_buf(const void *d, uint32_t len)
79 {
80 write_32(len);
81 evbuffer_add(evb, d, len);
82 }
84 void
85 write_64(uint64_t x)
86 {
87 x = htole64(x);
88 evbuffer_add(evb, &x, sizeof(x));
89 }
91 void
92 write_32(uint32_t fid)
93 {
94 fid = htole32(fid);
95 evbuffer_add(evb, &fid, sizeof(fid));
96 }
98 void
99 write_16(uint16_t tag)
101 tag = htole16(tag);
102 evbuffer_add(evb, &tag, sizeof(tag));
105 void
106 write_8(uint8_t x)
108 evbuffer_add(evb, &x, sizeof(x));
113 void
114 tversion(const char *v, uint32_t msize)
116 uint32_t len;
117 uint16_t sl;
119 sl = strlen(v);
121 /* msize[4] version[s] */
122 len = sizeof(msize) + sizeof(sl) + sl;
123 write_hdr(len, Tversion, NOTAG);
124 write_32(msize);
125 write_str(sl, v);
128 void
129 tattach(uint32_t fid, uint32_t afid, const char *uname, const char *aname)
131 uint32_t len;
132 uint16_t ul, al;
134 ul = strlen(uname);
135 al = strlen(aname);
137 /* fid[4] afid[4] uname[s] aname[s] */
138 len = sizeof(fid) + sizeof(afid) + sizeof(ul) + ul
139 + sizeof(al) + al;
140 write_hdr_auto(len, Tattach);
141 write_fid(fid);
142 write_fid(afid);
143 write_str(ul, uname);
144 write_str(al, aname);
147 void
148 tclunk(uint32_t fid)
150 uint32_t len;
152 /* fid[4] */
153 len = sizeof(fid);
154 write_hdr_auto(len, Tclunk);
155 write_fid(fid);
158 void
159 tflush(uint16_t oldtag)
161 uint32_t len;
163 /* oldtag[2] */
164 len = sizeof(oldtag);
165 write_hdr_auto(len, Tflush);
166 write_tag(oldtag);
169 void
170 twalk(uint32_t fid, uint32_t newfid, const char **wnames, size_t nwname)
172 size_t i;
173 uint32_t len;
175 /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
176 len = sizeof(fid) + sizeof(newfid) + 2;
177 for (i = 0; i < nwname; ++i)
178 len += 2 + strlen(wnames[i]);
180 write_hdr_auto(len, Twalk);
181 write_fid(fid);
182 write_fid(newfid);
183 write_16(nwname);
184 for (i = 0; i < nwname; ++i)
185 write_str_auto(wnames[i]);
188 void
189 topen(uint32_t fid, uint8_t mode)
191 uint32_t len;
193 /* fid[4] mode[1] */
194 len = sizeof(fid) + sizeof(mode);
195 write_hdr_auto(len, Topen);
196 write_fid(fid);
197 write_8(mode);
200 void
201 tcreate(uint32_t fid, const char *name, uint32_t perm, uint8_t mode)
203 uint32_t len;
204 uint16_t nl;
206 /* fid[4] name[s] perm[4] mode[1] */
207 nl = strlen(name);
208 len = sizeof(fid) + sizeof(nl) + nl + sizeof(perm) + sizeof(mode);
209 write_hdr_auto(len, Tcreate);
210 write_fid(fid);
211 write_str(nl, name);
212 write_32(perm);
213 write_8(mode);
216 void
217 tread(uint32_t fid, uint64_t off, uint32_t count)
219 uint32_t len;
221 /* fid[4] off[8] count[4] */
222 len = sizeof(fid) + sizeof(off) + sizeof(count);
223 write_hdr_auto(len, Tread);
224 write_fid(fid);
225 write_off(off);
226 write_32(count);
229 void
230 twrite(uint32_t fid, uint64_t off, const void *data, uint32_t count)
232 uint32_t len;
234 /* fid[4] off[8] count[4] data[count] */
235 len = sizeof(fid) + sizeof(off) + sizeof(count) + count;
236 write_hdr_auto(len, Twrite);
237 write_fid(fid);
238 write_off(off);
239 write_buf(data, count);
242 void
243 tstat(uint32_t fid)
245 /* fid[4] */
246 write_hdr_auto(sizeof(fid), Tstat);
247 write_fid(fid);
250 void
251 twstat(uint32_t fid, const struct np_stat *st)
253 uint32_t len;
254 uint16_t stlen, n;
256 /* fid[4] stat[n] */
258 stlen = NPSTATSIZ(0, 0, 0, 0);
259 if (st->name != NULL)
260 stlen += strlen(st->name);
261 if (st->uid != NULL)
262 stlen += strlen(st->uid);
263 if (st->gid != NULL)
264 stlen += strlen(st->gid);
265 if (st->muid != NULL)
266 stlen += strlen(st->muid);
268 n = sizeof(stlen) + stlen;
269 len = sizeof(fid) + sizeof(n) + n;
271 write_hdr_auto(len, Twstat);
272 write_fid(fid);
273 write_16(n);
274 write_16(stlen);
275 write_16(st->type);
276 write_32(st->dev);
278 write_8(st->qid.type);
279 write_32(st->qid.vers);
280 write_64(st->qid.path);
282 write_32(st->mode);
283 write_32(st->atime);
284 write_32(st->mtime);
285 write_64(st->length);
287 write_str_auto(st->name);
288 write_str_auto(st->uid);
289 write_str_auto(st->gid);
290 write_str_auto(st->muid);
293 void
294 tremove(uint32_t fid)
296 /* fid[4] */
297 write_hdr_auto(sizeof(fid), Tremove);
298 write_fid(fid);