added gentoo ebuilds
[libmixp.git] / libmixp / message.c
blob50455ba2e9527787cbc5fdbe33ee13c23bb60972
1 /* Copyright ©2007 Kris Maglione <fbsdaemon@gmail.com>
2 * See LICENSE file for license details.
3 */
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <string.h>
7 #include "mixp_local.h"
8 #include <9p-mixp/convert.h>
9 #include <9p-mixp/stat.h>
11 #include "util.h"
13 enum {
14 SByte = 1,
15 SWord = 2,
16 SDWord = 4,
17 SQWord = 8,
20 #define SString(s) (SWord + strlen(s))
21 enum {
22 SQid = SByte + SDWord + SQWord,
25 MIXP_MESSAGE
26 mixp_message(char *data, size_t length, unsigned int mode) {
27 MIXP_MESSAGE m;
29 m.data = data;
30 m.pos = data;
31 m.end = data + length;
32 m.size = length;
33 m.mode = mode;
34 return m;
37 void
38 mixp_stat_free(MIXP_STAT *s) {
39 if (s!=NULL)
41 MIXP_FREE(s->name);
42 MIXP_FREE(s->uid);
43 MIXP_FREE(s->gid);
44 MIXP_FREE(s->muid);
48 void
49 mixp_fcall_free(IxpFcall *fcall)
51 if (fcall == NULL)
53 // fprintf(stderr,"mixp_fcall_free() got an NULL pointer\n");
54 return;
57 switch(fcall->type)
59 case P9_RStat:
60 MIXP_FREE(fcall->Rstat.stat);
61 break;
62 case P9_RRead:
63 MIXP_FREE(fcall->Rread.data);
64 break;
65 case P9_RVersion:
66 MIXP_FREE(fcall->Rversion.version);
67 break;
68 case P9_RError:
69 MIXP_FREE(fcall->Rerror.ename);
70 break;
72 #ifdef _DEBUG
73 fprintf(stderr,"WARN: incomplete mixp_fcall_free()\n");
74 #endif
75 // MIXP_FREE(fcall);
78 size_t
79 mixp_stat_sizeof(MIXP_STAT * stat) {
80 return SWord /* size */
81 + SWord /* type */
82 + SDWord /* dev */
83 + SQid /* qid */
84 + 3 * SDWord /* mode, atime, mtime */
85 + SQWord /* length */
86 + SString(stat->name)
87 + SString(stat->uid)
88 + SString(stat->gid)
89 + SString(stat->muid);
92 const char* fcall_type2str(int type)
94 switch (type)
96 case P9_TVersion: return "[TVersion]";
97 case P9_RVersion: return "[RVersion]";
98 case P9_TAuth: return "[TAuth] ";
99 case P9_RAuth: return "[RAuth] ";
100 case P9_TAttach: return "[TAttach] ";
101 case P9_RAttach: return "[RAttach] ";
102 case P9_TOpen: return "[TOpen] ";
103 case P9_ROpen: return "[ROpen] ";
104 case P9_TRead: return "[TRead] ";
105 case P9_RRead: return "[RRead] ";
106 case P9_TWrite: return "[TWrite] ";
107 case P9_RWrite: return "[RWrite] ";
108 case P9_TFlush: return "[TFlush] ";
109 case P9_RError: return "[RError] ";
110 case P9_TWalk: return "[TWalk] ";
111 case P9_RWalk: return "[RWalk] ";
112 case P9_TCreate: return "[TCreate] ";
113 case P9_RCreate: return "[RCreate] ";
114 case P9_TClunk: return "[TClunk] ";
115 case P9_RClunk: return "[RClunk] ";
116 case P9_TRemove: return "[TRemove] ";
117 case P9_TStat: return "[TStat] ";
118 case P9_RStat: return "[RStat] ";
119 case P9_TWStat: return "[TWStat] ";
120 default: return "(unknown) ";
124 #define _MSGDUMP(fmt...) \
125 if (mixp_dump) \
127 fprintf(stderr,"%s %s %-5d tag=%-5d ", \
128 (msg->mode==MsgUnpack) ? ">>":"<<", \
129 fcall_type2str(fcall->type), \
130 (msg->end - msg->data), \
131 fcall->tag \
132 ); \
133 fprintf(stderr,fmt); \
134 fprintf(stderr,"\n"); \
137 void
138 ixp_pfcall(MIXP_MESSAGE *msg, IxpFcall *fcall)
140 mixp_pu8(msg, &fcall->type);
141 mixp_pu16(msg, &fcall->tag);
144 printf("ixp_pfcall() %s tag=%d type=%d %s\n",
145 ((msg->mode==MsgPack) ? "PACK" : ((msg->mode==MsgUnpack) ? "UNPACK" : "???")),
146 fcall->tag,
147 fcall->type,
148 fcall_type2str(fcall->type));
150 switch (fcall->type) {
151 case P9_TVersion:
152 mixp_pu32(msg, &fcall->Tversion.msize);
153 mixp_pstring(msg, &fcall->Tversion.version);
154 _MSGDUMP("msize=%d version=\"%s\"", fcall->Tversion.msize, fcall->Tversion.version);
155 break;
156 case P9_RVersion:
157 mixp_pu32(msg, &fcall->Rversion.msize);
158 mixp_pstring(msg, &fcall->Rversion.version);
159 _MSGDUMP("msize=%d version=\"%s\"", fcall->Tversion.msize, fcall->Tversion.version);
160 break;
161 case P9_TAuth:
162 mixp_pu32(msg, &fcall->Tauth.afid);
163 mixp_pstring(msg, &fcall->Tauth.uname);
164 mixp_pstring(msg, &fcall->Tauth.aname);
165 _MSGDUMP("afid=%d uname=\"%s\" aname=\"%s\"", fcall->Tauth.afid, fcall->Tauth.uname, fcall->Tauth.aname);
166 break;
167 case P9_RAuth:
168 mixp_pqid(msg, &fcall->Rauth.aqid);
169 _MSGDUMP(" ");
170 break;
171 case P9_RAttach:
172 mixp_pqid(msg, &fcall->Rattach.qid);
173 _MSGDUMP(" ");
174 break;
175 case P9_TAttach:
176 mixp_pu32(msg, &fcall->fid);
177 mixp_pu32(msg, &fcall->Tattach.afid);
178 mixp_pstring(msg, &fcall->Tattach.uname);
179 mixp_pstring(msg, &fcall->Tattach.aname);
180 _MSGDUMP("fid=%d afid=%d uname=\"%s\" aname=\"%s\"", fcall->fid, fcall->Tattach.afid, fcall->Tattach.uname, fcall->Tattach.aname);
181 break;
182 case P9_RError:
183 mixp_pstring(msg, &fcall->Rerror.ename);
184 _MSGDUMP("ename=\"%s\"", fcall->Rerror.ename);
185 break;
186 case P9_TFlush:
187 mixp_pu16(msg, &fcall->Tflush.oldtag);
188 _MSGDUMP("oldtag=%d", fcall->Tflush.oldtag);
189 break;
190 case P9_TWalk:
191 mixp_pu32(msg, &fcall->fid);
192 mixp_pu32(msg, &fcall->Twalk.newfid);
193 mixp_pstrings(msg, &fcall->Twalk.nwname, fcall->Twalk.wname);
195 char _dumpbuf[65535] = {0};
196 int _x;
197 for (_x=0; _x<fcall->Twalk.nwname; _x++)
199 if (_x) strcat(_dumpbuf,", ");
200 strcat(_dumpbuf,"\"");
201 strcat(_dumpbuf,fcall->Twalk.wname[_x]);
202 strcat(_dumpbuf,"\"");
204 _MSGDUMP("fid=%d newfid=%d nwname[]={ %s }", fcall->fid, fcall->Twalk.newfid, _dumpbuf);
206 break;
207 case P9_RWalk:
208 mixp_pqids(msg, &fcall->Rwalk.nwqid, fcall->Rwalk.wqid);
209 _MSGDUMP("nwqid=%d", fcall->Rwalk.nwqid);
210 break;
211 case P9_TOpen:
212 mixp_pu32(msg, &fcall->fid);
213 mixp_pu8(msg, &fcall->Topen.mode);
214 _MSGDUMP("fid=%d mode=%d", fcall->fid, fcall->Topen.mode);
215 break;
216 case P9_ROpen:
217 mixp_pqid(msg, &fcall->Ropen.qid);
218 mixp_pu32(msg, &fcall->Ropen.iounit);
219 _MSGDUMP("iounit=%d", fcall->Ropen.iounit);
220 break;
221 case P9_RCreate:
222 mixp_pqid(msg, &fcall->Rcreate.qid);
223 mixp_pu32(msg, &fcall->Rcreate.iounit);
224 _MSGDUMP("iounit=%d", fcall->Rcreate.iounit);
225 break;
226 case P9_TCreate:
227 mixp_pu32(msg, &fcall->fid);
228 mixp_pstring(msg, &fcall->Tcreate.name);
229 mixp_pu32(msg, &fcall->Tcreate.perm);
230 mixp_pu8(msg, &fcall->Tcreate.mode);
231 _MSGDUMP("fid=%d name=\"%s\" perm=%d mode=%d", fcall->fid, fcall->Tcreate.name, fcall->Tcreate.perm, fcall->Tcreate.mode);
232 break;
233 case P9_TRead:
234 mixp_pu32(msg, &fcall->fid);
235 mixp_pu64(msg, &fcall->Tread.offset);
236 mixp_pu32(msg, &fcall->Tread.count);
237 _MSGDUMP("fid=%d offset=%llu count=%u", fcall->fid, fcall->Tread.offset, fcall->Tread.count);
238 break;
239 case P9_RRead:
240 mixp_pu32(msg, &fcall->Rread.count);
241 mixp_pdata(msg, &fcall->Rread.data, fcall->Rread.count);
242 _MSGDUMP("count=%d", fcall->Rread.count);
243 break;
244 case P9_TWrite:
245 mixp_pu32(msg, &fcall->fid);
246 mixp_pu64(msg, &fcall->Twrite.offset);
247 mixp_pu32(msg, &fcall->Twrite.count);
248 mixp_pdata(msg, &fcall->Twrite.data, fcall->Twrite.count);
249 _MSGDUMP("fid=%u offset=%llu count=%u", fcall->fid, fcall->Twrite.offset, fcall->Twrite.count);
250 break;
251 case P9_RWrite:
252 mixp_pu32(msg, &fcall->Rwrite.count);
253 _MSGDUMP("count=%d", fcall->Rwrite.count);
254 break;
255 case P9_RClunk:
256 mixp_pu32(msg, &fcall->fid);
257 _MSGDUMP("fid=%d", fcall->fid);
258 break;
259 case P9_TClunk:
260 mixp_pu32(msg, &fcall->fid);
261 _MSGDUMP("fid=%d", fcall->fid);
262 break;
263 case P9_TRemove:
264 mixp_pu32(msg, &fcall->fid);
265 _MSGDUMP("fid=%d", fcall->fid);
266 break;
267 case P9_TStat:
268 mixp_pu32(msg, &fcall->fid);
269 _MSGDUMP("fid=%d", fcall->fid);
270 break;
271 case P9_RStat:
272 mixp_pu16(msg, &fcall->Rstat.nstat);
273 mixp_pdata(msg, (char**)&fcall->Rstat.stat, fcall->Rstat.nstat);
274 _MSGDUMP("nstat=%d", fcall->Rstat.nstat);
275 break;
276 case P9_TWStat:
277 mixp_pu32(msg, &fcall->fid);
278 mixp_pu16(msg, &fcall->Twstat.nstat);
279 mixp_pdata(msg, (char**)&fcall->Twstat.stat, fcall->Twstat.nstat);
280 _MSGDUMP("fid=%d nstat=%d", fcall->fid, fcall->Twstat.nstat);
281 break;
282 default:
283 _MSGDUMP(" unhandled type %d", fcall->type);
287 size_t
288 ixp_fcall2msg(MIXP_MESSAGE *msg, IxpFcall *fcall)
290 size_t size;
292 msg->end = msg->data + msg->size;
293 msg->pos = msg->data + SDWord;
294 msg->mode = MsgPack;
295 ixp_pfcall(msg, fcall);
297 if(msg->pos > msg->end)
298 return 0;
300 msg->end = msg->pos;
301 size = msg->end - msg->data;
303 msg->pos = msg->data;
304 mixp_pu32(msg, &size);
306 msg->pos = msg->data;
307 return size;
310 size_t
311 ixp_msg2fcall(MIXP_MESSAGE *msg, IxpFcall *fcall)
313 msg->pos = msg->data + SDWord;
314 msg->mode = MsgUnpack;
315 ixp_pfcall(msg, fcall);
317 if(msg->pos > msg->end)
318 return 0;
320 return msg->pos - msg->data;