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 <endian.h>
18 #include <event.h>
19 #include <inttypes.h>
20 #include <string.h>
22 #include "9pclib.h"
23 #include "kami.h"
24 #include "log.h"
25 #include "utils.h"
27 uint16_t iota_tag;
29 struct evbuffer *evb;
31 void
32 write_hdr(uint32_t len, uint8_t type, uint16_t tag)
33 {
34 len += HEADERSIZE;
36 log_debug("enqueuing a packet; len=%"PRIu32" type=%d[%s] tag=%d",
37 len, type, pp_msg_type(type), tag);
39 len = htole32(len);
40 /* type is one byte, no endiannes issues */
41 tag = htole16(tag);
43 evbuffer_add(evb, &len, sizeof(len));
44 evbuffer_add(evb, &type, sizeof(type));
45 evbuffer_add(evb, &tag, sizeof(tag));
46 }
48 void
49 write_hdr_auto(uint32_t len, uint8_t type)
50 {
51 if (++iota_tag == NOTAG)
52 ++iota_tag;
53 write_hdr(len, type, iota_tag);
54 }
56 void
57 write_str(uint16_t len, const char *str)
58 {
59 uint16_t l = len;
61 len = htole16(len);
62 evbuffer_add(evb, &len, sizeof(len));
63 evbuffer_add(evb, str, l);
64 }
66 void
67 write_str_auto(const char *str)
68 {
69 write_str(strlen(str), str);
70 }
72 void
73 write_buf(const void *d, uint32_t len)
74 {
75 write_32(len);
76 evbuffer_add(evb, d, len);
77 }
79 void
80 write_64(uint64_t x)
81 {
82 x = htole64(x);
83 evbuffer_add(evb, &x, sizeof(x));
84 }
86 void
87 write_32(uint32_t fid)
88 {
89 fid = htole32(fid);
90 evbuffer_add(evb, &fid, sizeof(fid));
91 }
93 void
94 write_16(uint16_t tag)
95 {
96 tag = htole16(tag);
97 evbuffer_add(evb, &tag, sizeof(tag));
98 }
100 void
101 write_8(uint8_t x)
103 evbuffer_add(evb, &x, sizeof(x));
108 void
109 tversion(const char *v, uint32_t msize)
111 uint32_t len;
112 uint16_t sl;
114 sl = strlen(v);
116 /* msize[4] version[s] */
117 len = sizeof(msize) + sizeof(sl) + sl;
118 write_hdr(len, Tversion, NOTAG);
119 write_32(msize);
120 write_str(sl, v);
123 void
124 tattach(uint32_t fid, uint32_t afid, const char *uname, const char *aname)
126 uint32_t len;
127 uint16_t ul, al;
129 ul = strlen(uname);
130 al = strlen(aname);
132 /* fid[4] afid[4] uname[s] aname[s] */
133 len = sizeof(fid) + sizeof(afid) + sizeof(ul) + ul
134 + sizeof(al) + al;
135 write_hdr_auto(len, Tattach);
136 write_fid(fid);
137 write_fid(afid);
138 write_str(ul, uname);
139 write_str(al, aname);
142 void
143 tclunk(uint32_t fid)
145 uint32_t len;
147 /* fid[4] */
148 len = sizeof(fid);
149 write_hdr_auto(len, Tclunk);
150 write_fid(fid);
153 void
154 tflush(uint16_t oldtag)
156 uint32_t len;
158 /* oldtag[2] */
159 len = sizeof(oldtag);
160 write_hdr_auto(len, Tflush);
161 write_tag(oldtag);
164 void
165 twalk(uint32_t fid, uint32_t newfid, const char **wnames, size_t nwname)
167 size_t i;
168 uint32_t len;
170 /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
171 len = sizeof(fid) + sizeof(newfid) + 2;
172 for (i = 0; i < nwname; ++i)
173 len += 2 + strlen(wnames[i]);
175 write_hdr_auto(len, Twalk);
176 write_fid(fid);
177 write_fid(newfid);
178 write_16(nwname);
179 for (i = 0; i < nwname; ++i)
180 write_str_auto(wnames[i]);
183 void
184 topen(uint32_t fid, uint8_t mode)
186 uint32_t len;
188 /* fid[4] mode[1] */
189 len = sizeof(fid) + sizeof(mode);
190 write_hdr_auto(len, Topen);
191 write_fid(fid);
192 write_8(mode);
195 void
196 tcreate(uint32_t fid, const char *name, uint32_t perm, uint8_t mode)
198 uint32_t len;
199 uint16_t nl;
201 /* fid[4] name[s] perm[4] mode[1] */
202 nl = strlen(name);
203 len = sizeof(fid) + sizeof(nl) + nl + sizeof(perm) + sizeof(mode);
204 write_hdr_auto(len, Tcreate);
205 write_fid(fid);
206 write_str(nl, name);
207 write_32(perm);
208 write_8(mode);
211 void
212 tread(uint32_t fid, uint64_t off, uint32_t count)
214 uint32_t len;
216 /* fid[4] off[8] count[4] */
217 len = sizeof(fid) + sizeof(off) + sizeof(count);
218 write_hdr_auto(len, Tread);
219 write_fid(fid);
220 write_off(off);
221 write_32(count);
224 void
225 twrite(uint32_t fid, uint64_t off, const void *data, uint32_t count)
227 uint32_t len;
229 /* fid[4] off[8] count[4] data[count] */
230 len = sizeof(fid) + sizeof(off) + sizeof(count) + count;
231 write_hdr_auto(len, Twrite);
232 write_fid(fid);
233 write_off(off);
234 write_buf(data, count);
237 void
238 tstat(uint32_t fid)
240 /* fid[4] */
241 write_hdr_auto(sizeof(fid), Tstat);
242 write_fid(fid);
245 void
246 tremove(uint32_t fid)
248 /* fid[4] */
249 write_hdr_auto(sizeof(fid), Tremove);
250 write_fid(fid);