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 "9pclib.h"
24 #include "kamid.h"
25 #include "log.h"
26 #include "utils.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 write_str(strlen(str), str);
71 }
73 void
74 write_64(uint64_t x)
75 {
76 x = htole64(x);
77 evbuffer_add(evb, &x, sizeof(x));
78 }
80 void
81 write_32(uint32_t fid)
82 {
83 fid = htole32(fid);
84 evbuffer_add(evb, &fid, sizeof(fid));
85 }
87 void
88 write_16(uint16_t tag)
89 {
90 tag = htole16(tag);
91 evbuffer_add(evb, &tag, sizeof(tag));
92 }
94 void
95 write_8(uint8_t x)
96 {
97 evbuffer_add(evb, &x, sizeof(x));
98 }
102 void
103 tversion(const char *v, uint32_t msize)
105 uint32_t len;
106 uint16_t sl;
108 sl = strlen(v);
110 /* msize[4] version[s] */
111 len = sizeof(msize) + sizeof(sl) + sl;
112 write_hdr(len, Tversion, NOTAG);
113 write_32(msize);
114 write_str(sl, v);
117 void
118 tattach(uint32_t fid, uint32_t afid, const char *uname, const char *aname)
120 uint32_t len;
121 uint16_t ul, al;
123 ul = strlen(uname);
124 al = strlen(aname);
126 /* fid[4] afid[4] uname[s] aname[s] */
127 len = sizeof(fid) + sizeof(afid) + sizeof(ul) + ul
128 + sizeof(al) + al;
129 write_hdr_auto(len, Tattach);
130 write_fid(fid);
131 write_fid(afid);
132 write_str(ul, uname);
133 write_str(al, aname);
136 void
137 tclunk(uint32_t fid)
139 uint32_t len;
141 /* fid[4] */
142 len = sizeof(fid);
143 write_hdr_auto(len, Tclunk);
144 write_fid(fid);
147 void
148 tflush(uint16_t oldtag)
150 uint32_t len;
152 /* oldtag[2] */
153 len = sizeof(oldtag);
154 write_hdr_auto(len, Tflush);
155 write_tag(oldtag);
158 void
159 twalk(uint32_t fid, uint32_t newfid, const char **wnames, size_t nwname)
161 size_t i;
162 uint32_t len;
164 /* fid[4] newfid[4] nwname[2] nwname*(wname[s]) */
165 len = sizeof(fid) + sizeof(newfid) + 2;
166 for (i = 0; i < nwname; ++i)
167 len += 2 + strlen(wnames[i]);
169 write_hdr_auto(len, Twalk);
170 write_fid(fid);
171 write_fid(newfid);
172 write_16(nwname);
173 for (i = 0; i < nwname; ++i)
174 write_str_auto(wnames[i]);
177 void
178 topen(uint32_t fid, uint8_t mode)
180 uint32_t len;
182 /* fid[4] mode[1] */
183 len = sizeof(fid) + sizeof(mode);
184 write_hdr_auto(len, Topen);
185 write_fid(fid);
186 write_8(mode);
189 void
190 tread(uint32_t fid, uint64_t off, uint32_t count)
192 uint32_t len;
194 /* fid[4] off[8] count[4] */
195 len = sizeof(fid) + sizeof(off) + sizeof(count);
196 write_hdr_auto(len, Tread);
197 write_fid(fid);
198 write_off(off);
199 write_32(count);