wmii/libixp/message.c

318 lines
8.8 KiB
C

/*
* (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
* See LICENSE file for license details.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "ixp.h"
#define IXP_QIDSZ (sizeof(unsigned char) + sizeof(unsigned int)\
+ sizeof(unsigned long long))
static unsigned short
sizeof_string(const char *s)
{
return sizeof(unsigned short) + strlen(s);
}
unsigned short
ixp_sizeof_stat(Stat * stat)
{
return IXP_QIDSZ
+ 2 * sizeof(unsigned short)
+ 4 * sizeof(unsigned int)
+ sizeof(unsigned long long)
+ sizeof_string(stat->name)
+ sizeof_string(stat->uid)
+ sizeof_string(stat->gid)
+ sizeof_string(stat->muid);
}
unsigned int
ixp_fcall_to_msg(void *msg, Fcall *fcall, unsigned int msglen)
{
unsigned int i, msize =
sizeof(unsigned char) + sizeof(unsigned short) +
sizeof(unsigned int);
void *p = msg;
switch (fcall->id) {
case TVERSION:
case RVERSION:
msize += sizeof(unsigned int) + sizeof_string(fcall->version);
break;
case TAUTH:
msize +=
sizeof(unsigned int) + sizeof_string(fcall->uname) +
sizeof_string(fcall->aname);
break;
case RAUTH:
case RATTACH:
msize += IXP_QIDSZ;
break;
case TATTACH:
msize +=
2 * sizeof(unsigned int) + sizeof_string(fcall->uname) +
sizeof_string(fcall->aname);
break;
case RERROR:
msize += sizeof_string(fcall->errstr);
break;
case RWRITE:
case TCLUNK:
case TREMOVE:
case TSTAT:
msize += sizeof(unsigned int);
break;
case TWALK:
msize += sizeof(unsigned short) + 2 * sizeof(unsigned int);
for(i = 0; i < fcall->nwname; i++)
msize += sizeof_string(fcall->wname[i]);
break;
case TFLUSH:
msize += sizeof(unsigned short);
break;
case RWALK:
msize += sizeof(unsigned short) + fcall->nwqid * IXP_QIDSZ;
break;
case TOPEN:
msize += sizeof(unsigned int) + sizeof(unsigned char);
break;
case ROPEN:
case RCREATE:
msize += IXP_QIDSZ + sizeof(unsigned int);
break;
case TCREATE:
msize +=
sizeof(unsigned char) + 2 * sizeof(unsigned int) +
sizeof_string(fcall->name);
break;
case TREAD:
msize += 2 * sizeof(unsigned int) + sizeof(unsigned long long);
break;
case RREAD:
msize += sizeof(unsigned int) + fcall->count;
break;
case TWRITE:
msize +=
2 * sizeof(unsigned int) + sizeof(unsigned long long) +
fcall->count;
break;
case RSTAT:
msize += sizeof(unsigned short) + ixp_sizeof_stat(&fcall->stat);
break;
case TWSTAT:
msize += sizeof(unsigned int) + sizeof(unsigned short) + ixp_sizeof_stat(&fcall->stat);
break;
default:
break;
}
if(msize > msglen)
return 0;
p = ixp_enc_prefix(p, msize, fcall->id, fcall->tag);
switch (fcall->id) {
case TVERSION:
case RVERSION:
p = ixp_enc_u32(p, fcall->maxmsg);
p = ixp_enc_string(p, fcall->version);
break;
case TAUTH:
p = ixp_enc_u32(p, fcall->afid);
p = ixp_enc_string(p, fcall->uname);
p = ixp_enc_string(p, fcall->aname);
break;
case RAUTH:
p = ixp_enc_qid(p, &fcall->aqid);
break;
case RATTACH:
p = ixp_enc_qid(p, &fcall->qid);
break;
case TATTACH:
p = ixp_enc_u32(p, fcall->fid);
p = ixp_enc_u32(p, fcall->afid);
p = ixp_enc_string(p, fcall->uname);
p = ixp_enc_string(p, fcall->aname);
break;
case RERROR:
p = ixp_enc_string(p, fcall->errstr);
break;
case TFLUSH:
p = ixp_enc_u16(p, fcall->oldtag);
break;
case TWALK:
p = ixp_enc_u32(p, fcall->fid);
p = ixp_enc_u32(p, fcall->newfid);
p = ixp_enc_u16(p, fcall->nwname);
for(i = 0; i < fcall->nwname; i++)
p = ixp_enc_string(p, fcall->wname[i]);
break;
case RWALK:
p = ixp_enc_u16(p, fcall->nwqid);
for(i = 0; i < fcall->nwqid; i++)
p = ixp_enc_qid(p, &fcall->wqid[i]);
break;
case TOPEN:
p = ixp_enc_u32(p, fcall->fid);
p = ixp_enc_u8(p, fcall->mode);
break;
case ROPEN:
case RCREATE:
p = ixp_enc_qid(p, &fcall->qid);
p = ixp_enc_u32(p, fcall->iounit);
break;
case TCREATE:
p = ixp_enc_u32(p, fcall->fid);
p = ixp_enc_string(p, fcall->name);
p = ixp_enc_u32(p, fcall->perm);
p = ixp_enc_u8(p, fcall->mode);
break;
case TREAD:
p = ixp_enc_u32(p, fcall->fid);
p = ixp_enc_u64(p, fcall->offset);
p = ixp_enc_u32(p, fcall->count);
break;
case RREAD:
p = ixp_enc_u32(p, fcall->count);
p = ixp_enc_data(p, fcall->data, fcall->count);
break;
case TWRITE:
p = ixp_enc_u32(p, fcall->fid);
p = ixp_enc_u64(p, fcall->offset);
p = ixp_enc_u32(p, fcall->count);
p = ixp_enc_data(p, fcall->data, fcall->count);
break;
case RWRITE:
p = ixp_enc_u32(p, fcall->count);
break;
case TCLUNK:
case TREMOVE:
case TSTAT:
p = ixp_enc_u32(p, fcall->fid);
break;
case RSTAT:
p = ixp_enc_u16(p, ixp_sizeof_stat(&fcall->stat));
p = ixp_enc_stat(p, &fcall->stat);
break;
case TWSTAT:
p = ixp_enc_u32(p, fcall->fid);
p = ixp_enc_u16(p, ixp_sizeof_stat(&fcall->stat));
p = ixp_enc_stat(p, &fcall->stat);
break;
}
if(msg + msize == p)
return msize;
return 0;
}
unsigned int
ixp_msg_to_fcall(Fcall *fcall, void *msg, unsigned int msglen)
{
unsigned int i, msize;
unsigned short len;
void *p = ixp_dec_prefix(msg, &msize, &fcall->id, &fcall->tag);
if(msize > msglen) /* bad message */
return 0;
switch (fcall->id) {
case TVERSION:
case RVERSION:
p = ixp_dec_u32(p, &fcall->maxmsg);
p = ixp_dec_string(p, fcall->version, sizeof(fcall->version), &len);
break;
case TAUTH:
p = ixp_dec_u32(p, &fcall->afid);
p = ixp_dec_string(p, fcall->uname, sizeof(fcall->uname), &len);
p = ixp_dec_string(p, fcall->aname, sizeof(fcall->aname), &len);
break;
case RAUTH:
p = ixp_dec_qid(p, &fcall->aqid);
break;
case RATTACH:
p = ixp_dec_qid(p, &fcall->qid);
break;
case TATTACH:
p = ixp_dec_u32(p, &fcall->fid);
p = ixp_dec_u32(p, &fcall->afid);
p = ixp_dec_string(p, fcall->uname, sizeof(fcall->uname), &len);
p = ixp_dec_string(p, fcall->aname, sizeof(fcall->aname), &len);
break;
case RERROR:
p = ixp_dec_string(p, fcall->errstr, sizeof(fcall->errstr), &len);
break;
case TFLUSH:
p = ixp_dec_u16(p, &fcall->oldtag);
break;
case TWALK:
p = ixp_dec_u32(p, &fcall->fid);
p = ixp_dec_u32(p, &fcall->newfid);
p = ixp_dec_u16(p, &fcall->nwname);
for(i = 0; i < fcall->nwname; i++) {
p = ixp_dec_string(p, fcall->wname[i], IXP_MAX_FLEN, &len);
}
break;
case RWALK:
p = ixp_dec_u16(p, &fcall->nwqid);
for(i = 0; i < fcall->nwqid; i++)
p = ixp_dec_qid(p, &fcall->wqid[i]);
break;
case TOPEN:
p = ixp_dec_u32(p, &fcall->fid);
p = ixp_dec_u8(p, &fcall->mode);
break;
case ROPEN:
case RCREATE:
p = ixp_dec_qid(p, &fcall->qid);
p = ixp_dec_u32(p, &fcall->iounit);
break;
case TCREATE:
p = ixp_dec_u32(p, &fcall->fid);
p = ixp_dec_string(p, fcall->name, sizeof(fcall->name), &len);
p = ixp_dec_u32(p, &fcall->perm);
p = ixp_dec_u8(p, &fcall->mode);
break;
case TREAD:
p = ixp_dec_u32(p, &fcall->fid);
p = ixp_dec_u64(p, &fcall->offset);
p = ixp_dec_u32(p, &fcall->count);
break;
case RREAD:
p = ixp_dec_u32(p, &fcall->count);
p = ixp_dec_data(p, fcall->data, fcall->count);
break;
case TWRITE:
p = ixp_dec_u32(p, &fcall->fid);
p = ixp_dec_u64(p, &fcall->offset);
p = ixp_dec_u32(p, &fcall->count);
p = ixp_dec_data(p, fcall->data, fcall->count);
break;
case RWRITE:
p = ixp_dec_u32(p, &fcall->count);
break;
case TCLUNK:
case TREMOVE:
case TSTAT:
p = ixp_dec_u32(p, &fcall->fid);
break;
case RSTAT:
p = ixp_dec_u16(p, &len);
p = ixp_dec_stat(p, &fcall->stat);
break;
case TWSTAT:
p = ixp_dec_u32(p, &fcall->fid);
p = ixp_dec_u16(p, &len);
p = ixp_dec_stat(p, &fcall->stat);
break;
}
if(msg + msize == p)
return msize;
return 0;
}