commit 7477765db204689787ff26151d59c43cc0fbc803
parent 7497a4c48a1db5f92e2a007eb2f3f91f07b85d66
Author: sqweek <sqweek@gmail.com>
Date: Sat, 20 Sep 2008 22:51:02 +0800
Add wstat support.
Diffstat:
3 files changed, 65 insertions(+), 25 deletions(-)
diff --git a/include/ixp.h b/include/ixp.h
@@ -7,7 +7,7 @@
#include <sys/types.h>
#include <sys/select.h>
-#define IXP_API 97
+#define IXP_API 105
/* Gunk */
#if defined(IXP_NEEDAPI) && IXP_API < IXP_NEEDAPI
@@ -271,6 +271,21 @@ struct IxpQid {
uchar dir_type;
};
+/* stat structure */
+struct IxpStat {
+ ushort type;
+ ulong dev;
+ IxpQid qid;
+ ulong mode;
+ ulong atime;
+ ulong mtime;
+ uvlong length;
+ char* name;
+ char* uid;
+ char* gid;
+ char* muid;
+};
+
typedef struct IxpFHdr IxpFHdr;
typedef struct IxpFError IxpFError;
typedef struct IxpFROpen IxpFRAttach;
@@ -290,7 +305,7 @@ typedef struct IxpFIO IxpFTRead;
typedef struct IxpFVersion IxpFTVersion;
typedef struct IxpFTWalk IxpFTWalk;
typedef struct IxpFIO IxpFTWrite;
-typedef struct IxpFRStat IxpFTWstat;
+typedef struct IxpFTWStat IxpFTWStat;
typedef struct IxpFAttach IxpFAttach;
typedef struct IxpFIO IxpFIO;
typedef struct IxpFVersion IxpFVersion;
@@ -356,6 +371,10 @@ struct IxpFRStat {
ushort nstat;
uchar* stat;
};
+struct IxpFTWStat {
+ IxpFHdr hdr;
+ IxpStat stat;
+};
#if defined(IXP_NEEDAPI) && IXP_NEEDAPI <= 89
/* from fcall(3) in plan9port */
typedef struct IxpFcall IxpFcall;
@@ -406,10 +425,13 @@ struct IxpFcall {
ulong count; /* Tread, Twrite, Rread */
char *data; /* Twrite, Rread */
)
- STRUCT ( /* Twstat, Rstat */
+ STRUCT ( /* Rstat */
ushort nstat;
uchar *stat;
)
+ STRUCT ( /* Twstat */
+ IxpStat st;
+ )
)
};
#else
@@ -431,7 +453,7 @@ union IxpFcall {
IxpFTCreate topen;
IxpFTWalk twalk;
IxpFRWalk rwalk;
- IxpFRStat twstat;
+ IxpFTWStat twstat;
IxpFRStat rstat;
IxpFIO twrite;
IxpFIO rwrite;
@@ -441,21 +463,6 @@ union IxpFcall {
};
#endif
-/* stat structure */
-struct IxpStat {
- ushort type;
- ulong dev;
- IxpQid qid;
- ulong mode;
- ulong atime;
- ulong mtime;
- uvlong length;
- char* name;
- char* uid;
- char* gid;
- char* muid;
-};
-
struct IxpConn {
IxpServer* srv;
void* aux;
@@ -564,6 +571,7 @@ struct Ixp9Srv {
void (*stat)(Ixp9Req *r);
void (*walk)(Ixp9Req *r);
void (*write)(Ixp9Req *r);
+ void (*wstat)(Ixp9Req *r);
void (*freefid)(IxpFid *f);
};
diff --git a/libixp/message.c b/libixp/message.c
@@ -159,11 +159,13 @@ ixp_pfcall(IxpMsg *msg, Fcall *fcall) {
ixp_pu16(msg, &fcall->rstat.nstat);
ixp_pdata(msg, (char**)&fcall->rstat.stat, fcall->rstat.nstat);
break;
- case TWStat:
+ case TWStat: {
+ ushort size;
ixp_pu32(msg, &fcall->hdr.fid);
- ixp_pu16(msg, &fcall->twstat.nstat);
- ixp_pdata(msg, (char**)&fcall->twstat.stat, fcall->twstat.nstat);
+ ixp_pu16(msg, &size);
+ ixp_pstat(msg, &fcall->twstat.stat);
break;
+ }
}
}
diff --git a/libixp/request.c b/libixp/request.c
@@ -310,7 +310,34 @@ handlereq(Ixp9Req *r) {
}
pc->srv->write(r);
break;
- /* Still to be implemented: wstat, auth */
+ case TWStat:
+ if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.hdr.fid))) {
+ respond(r, Enofid);
+ return;
+ }
+ if((ushort)~r->ifcall.twstat.stat.type) {
+ respond(r, "wstat of type");
+ return;
+ }
+ if((uint)~r->ifcall.twstat.stat.dev) {
+ respond(r, "wstat of dev");
+ return;
+ }
+ if((uchar)~r->ifcall.twstat.stat.qid.type || (ulong)~r->ifcall.twstat.stat.qid.version || (uvlong)~r->ifcall.twstat.stat.qid.path) {
+ respond(r, "wstat of qid");
+ return;
+ }
+ if(r->ifcall.twstat.stat.muid && r->ifcall.twstat.stat.muid[0]) {
+ respond(r, "wstat of muid");
+ return;
+ }
+ if((ulong)~r->ifcall.twstat.stat.mode && ((r->ifcall.twstat.stat.mode&DMDIR)>>24) != r->fid->qid.type&QTDIR) {
+ respond(r, "wstat on DMDIR bit");
+ return;
+ }
+ pc->srv->wstat(r);
+ break;
+ /* Still to be implemented: auth */
}
}
@@ -386,10 +413,13 @@ respond(Ixp9Req *r, const char *error) {
if((r->oldreq = lookupkey(&pc->tagmap, r->ifcall.tflush.oldtag)))
respond(r->oldreq, Eintr);
break;
+ case TWStat:
+ ixp_freestat(&r->ifcall.twstat.stat);
+ break;
case TRead:
case TStat:
- break;
- /* Still to be implemented: wstat, auth */
+ break;
+ /* Still to be implemented: auth */
}
r->ofcall.hdr.tag = r->ifcall.hdr.tag;