uint ixp_recvmsg(int fd, IxpMsg *msg) { enum { SSize = 4 }; uint msize, size; msg->mode = MsgUnpack; msg->pos = msg->data; msg->end = msg->data + msg->size; if(readn(fd, msg, SSize) != SSize) return 0; msg->pos = msg->data; ixp_pu32(msg, &msize); size = msize - SSize; if(msg->pos + size >= msg->end) { werrstr("message too large"); return 0; } if(readn(fd, msg, size) != size) { werrstr("message incomplete"); return 0; } msg->end = msg->pos; return msize; }
void ixp_pstat_dotu(IxpMsg *msg, Stat *stat) { ushort size; if(msg->mode == MsgPack) size = ixp_sizeof_stat_dotu(stat) - 2; ixp_pu16(msg, &size); ixp_pu16(msg, &stat->type); ixp_pu32(msg, &stat->dev); ixp_pqid(msg, &stat->qid); ixp_pu32(msg, &stat->mode); ixp_pu32(msg, &stat->atime); ixp_pu32(msg, &stat->mtime); ixp_pu64(msg, &stat->length); ixp_pstring(msg, &stat->name); ixp_pstring(msg, &stat->uid); ixp_pstring(msg, &stat->gid); ixp_pstring(msg, &stat->muid); ixp_pstring(msg, &stat->extension); ixp_pu32(msg, &stat->n_uid); ixp_pu32(msg, &stat->n_gid); ixp_pu32(msg, &stat->n_muid); }
/** * Function: ixp_fcall2msg * Function: ixp_msg2fcall * * These functions pack or unpack a 9P protocol message. The * message is set to the appropriate mode and its position is * set to the begining of its buffer. * * Returns: * These functions return the size of the message on * success and 0 on failure. * See also: * F<IxpMsg>, F<ixp_pfcall> */ uint ixp_fcall2msg(IxpMsg *msg, IxpFcall *fcall) { uint32_t size; msg->end = msg->data + msg->size; msg->pos = msg->data + SDWord; msg->mode = MsgPack; ixp_pfcall(msg, fcall); if(msg->pos > msg->end) return 0; msg->end = msg->pos; size = msg->end - msg->data; msg->pos = msg->data; ixp_pu32(msg, &size); msg->pos = msg->data; return size; }
void ixp_pfcall(IxpMsg *msg, IxpFcall *fcall) { ixp_pu8(msg, &fcall->hdr.type); ixp_pu16(msg, &fcall->hdr.tag); switch (fcall->hdr.type) { case TVersion: case RVersion: ixp_pu32(msg, &fcall->version.msize); ixp_pstring(msg, &fcall->version.version); break; case TAuth: ixp_pu32(msg, &fcall->tauth.afid); ixp_pstring(msg, &fcall->tauth.uname); ixp_pstring(msg, &fcall->tauth.aname); break; case RAuth: ixp_pqid(msg, &fcall->rauth.aqid); break; case RAttach: ixp_pqid(msg, &fcall->rattach.qid); break; case TAttach: ixp_pu32(msg, &fcall->hdr.fid); ixp_pu32(msg, &fcall->tattach.afid); ixp_pstring(msg, &fcall->tattach.uname); ixp_pstring(msg, &fcall->tattach.aname); break; case RError: ixp_pstring(msg, &fcall->error.ename); break; case TFlush: ixp_pu16(msg, &fcall->tflush.oldtag); break; case TWalk: ixp_pu32(msg, &fcall->hdr.fid); ixp_pu32(msg, &fcall->twalk.newfid); ixp_pstrings(msg, &fcall->twalk.nwname, fcall->twalk.wname, nelem(fcall->twalk.wname)); break; case RWalk: ixp_pqids(msg, &fcall->rwalk.nwqid, fcall->rwalk.wqid, nelem(fcall->rwalk.wqid)); break; case TOpen: ixp_pu32(msg, &fcall->hdr.fid); ixp_pu8(msg, &fcall->topen.mode); break; case ROpen: case RCreate: ixp_pqid(msg, &fcall->ropen.qid); ixp_pu32(msg, &fcall->ropen.iounit); break; case TCreate: ixp_pu32(msg, &fcall->hdr.fid); ixp_pstring(msg, &fcall->tcreate.name); ixp_pu32(msg, &fcall->tcreate.perm); ixp_pu8(msg, &fcall->tcreate.mode); break; case TRead: ixp_pu32(msg, &fcall->hdr.fid); ixp_pu64(msg, &fcall->tread.offset); ixp_pu32(msg, &fcall->tread.count); break; case RRead: ixp_pu32(msg, &fcall->rread.count); ixp_pdata(msg, &fcall->rread.data, fcall->rread.count); break; case TWrite: ixp_pu32(msg, &fcall->hdr.fid); ixp_pu64(msg, &fcall->twrite.offset); ixp_pu32(msg, &fcall->twrite.count); ixp_pdata(msg, &fcall->twrite.data, fcall->twrite.count); break; case RWrite: ixp_pu32(msg, &fcall->rwrite.count); break; case TClunk: case TRemove: case TStat: ixp_pu32(msg, &fcall->hdr.fid); break; case RStat: ixp_pu16(msg, &fcall->rstat.nstat); ixp_pdata(msg, (char**)&fcall->rstat.stat, fcall->rstat.nstat); break; case TWStat: { uint16_t size; ixp_pu32(msg, &fcall->hdr.fid); ixp_pu16(msg, &size); ixp_pstat(msg, &fcall->twstat.stat); break; } } }
void ixp_pqid(IxpMsg *msg, Qid *qid) { ixp_pu8(msg, &qid->type); ixp_pu32(msg, &qid->version); ixp_pu64(msg, &qid->path); }