[PATCH] 9p2000.u support for libixp-0.4

13 views
Skip to first unread message

jyujin

unread,
Jan 30, 2008, 10:20:03 AM1/30/08
to 9p-hackers
Hello dear group members,,

I've written the patch below to allow 9p2000.u semantics for
libixp-0.4. I know it's not the cleanest patch, and I do realise that
true plan9 fans will probably not have much use for this since with
most applications for the 9p2000 protocol none of the unix extensions
make any sense, however I was writing this for a different project and
a nice fella on IRC said I should probably post this patch here.

The bad thing about the patch is that it's server-side only (no
9p2000.u support when using libixp to write a client), and it needs
some cooperation from the programmer to work properly; to be precise,
the fs_stat() and fs_read() functions need to check the Ixp9Req
structure's "dotu" field. If that's nonzero, then instead of ixp_pstat
and ixp_sizeof_stat, one would need to use the functions
ixp_pstat_dotu and ixp_sizeof_stat_dotu instead when constructing
reply messages.
No idea how to get it cleaner since neither of the two functions here
get a pointer that would contain any request or connection data, so no
way to tell them which functions would need to be used... but this
method definitely seems to work just fine with v9fs.

I hope this'll help anyone, maybe spark some interest in a cleaner
solution. It's definitely all I needed, so maybe someone else will
find it useful too.

Merry Hacking,
Magnus Deininger

#################################### PATCH #########################

diff -ur libixp-0.4.old/include/ixp.h libixp-0.4/include/ixp.h
--- libixp-0.4.old/include/ixp.h 2007-11-05 15:36:22 +0100
+++ libixp-0.4/include/ixp.h 2008-01-27 21:42:32 +0100
@@ -181,6 +181,8 @@
# define DMSETGID P9_DMSETGID
#endif

+#define ERRUNDEF 0x0 /* 9P2000.u extension */
+
#ifdef IXP_P9_STRUCTS
# define IxpFcall Fcall
# define IxpFid Fid
@@ -258,6 +260,12 @@
char *uid;
char *gid;
char *muid;
+
+ /* 9P2000.u extensions */
+ char *extension;
+ uint n_uid;
+ uint n_gid;
+ uint n_muid;
};

struct IxpConn {
@@ -270,6 +278,9 @@

/* Implementation details, do not use */
IxpConn *next;
+
+ /* 9P2000.u extensions */
+ char dotu;
};

struct IxpServer {
@@ -349,6 +360,9 @@
IxpFcall ofcall;
void *aux;

+ /* 9P2000.u */
+ char dotu;
+
/* Implementation details */
Ixp9Conn *conn;
};
@@ -439,6 +453,7 @@
void ixp_pqid(IxpMsg *msg, IxpQid *qid);
void ixp_pqids(IxpMsg *msg, ushort *num, IxpQid qid[]);
void ixp_pstat(IxpMsg *msg, IxpStat *stat);
+void ixp_pstat_dotu(IxpMsg *msg, IxpStat *stat);

/* error.h */
char *ixp_errbuf(void);
@@ -452,11 +467,13 @@

/* message.c */
ushort ixp_sizeof_stat(IxpStat *stat);
+ushort ixp_sizeof_stat_dotu(IxpStat *stat);
IxpMsg ixp_message(uchar *data, uint length, uint mode);
void ixp_freestat(IxpStat *s);
void ixp_freefcall(IxpFcall *fcall);
uint ixp_msg2fcall(IxpMsg *msg, IxpFcall *fcall);
uint ixp_fcall2msg(IxpMsg *msg, IxpFcall *fcall);
+uint ixp_fcall2msg_dotu(IxpMsg *msg, IxpFcall *fcall);

/* server.c */
IxpConn *ixp_listen(IxpServer *s, int fd, void *aux,
diff -ur libixp-0.4.old/include/ixp_fcall.h libixp-0.4/include/
ixp_fcall.h
--- libixp-0.4.old/include/ixp_fcall.h 2008-01-20 00:28:04 +0100
+++ libixp-0.4/include/ixp_fcall.h 2008-01-27 21:27:02 +0100
@@ -13,6 +13,7 @@

/* Rerror */
char *ename;
+ ushort eerrno; /* 9P2000.u */

/* Ropen, Rcreate */
IxpQid qid; /* +Rattach */
diff -ur libixp-0.4.old/include/ixp_local.h libixp-0.4/include/
ixp_local.h
--- libixp-0.4.old/include/ixp_local.h 2007-11-05 15:36:22 +0100
+++ libixp-0.4/include/ixp_local.h 2008-01-29 03:33:25 +0100
@@ -1,6 +1,6 @@
#define IXP_NO_P9_
#define IXP_P9_STRUCTS
-#include <ixp.h>
+#include "ixp.h"

#define thread ixp_thread

diff -ur libixp-0.4.old/libixp/convert.c libixp-0.4/libixp/convert.c
--- libixp-0.4.old/libixp/convert.c 2007-11-05 15:36:22 +0100
+++ libixp-0.4/libixp/convert.c 2008-01-27 21:09:17 +0100
@@ -195,3 +195,31 @@
ixp_pstring(msg, &stat->gid);
ixp_pstring(msg, &stat->muid);
}
+
+/* 9P2000.u extensions */
+
+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);
+}
diff -ur libixp-0.4.old/libixp/fcall.h libixp-0.4/libixp/fcall.h
--- libixp-0.4.old/libixp/fcall.h 2007-11-05 15:36:22 +0100
+++ libixp-0.4/libixp/fcall.h 2008-01-27 21:26:55 +0100
@@ -13,6 +13,7 @@
};
struct { /* Rerror */
char *ename;
+ ushort eerrno; /* 9P2000.u */
};
struct { /* Ropen, Rcreate */
IxpQid qid; /* +Rattach */
diff -ur libixp-0.4.old/libixp/fcall.h.nounion libixp-0.4/libixp/
fcall.h.nounion
--- libixp-0.4.old/libixp/fcall.h.nounion 2007-11-05 15:36:22 +0100
+++ libixp-0.4/libixp/fcall.h.nounion 2008-01-27 21:26:51 +0100
@@ -13,6 +13,7 @@

/* Rerror */
char *ename;
+ ushort eerrno; /* 9P2000.u */

/* Ropen, Rcreate */
IxpQid qid; /* +Rattach */
diff -ur libixp-0.4.old/libixp/ixp_fcall.h libixp-0.4/libixp/
ixp_fcall.h
--- libixp-0.4.old/libixp/ixp_fcall.h 2007-11-05 15:36:22 +0100
+++ libixp-0.4/libixp/ixp_fcall.h 2008-01-27 21:27:46 +0100
@@ -13,6 +13,7 @@

/* Rerror */
char *ename;
+ ushort eerrno; /* 9P2000.u */

/* Ropen, Rcreate */
IxpQid qid; /* +Rattach */
diff -ur libixp-0.4.old/libixp/message.c libixp-0.4/libixp/message.c
--- libixp-0.4.old/libixp/message.c 2007-11-05 15:36:22 +0100
+++ libixp-0.4/libixp/message.c 2008-01-27 21:29:21 +0100
@@ -200,3 +200,61 @@

return msg->pos - msg->data;
}
+
+/* 9P2000.u extensions */
+
+ushort
+ixp_sizeof_stat_dotu(Stat * stat) {
+ return SWord /* size */
+ + SWord /* type */
+ + SDWord /* dev */
+ + SQid /* qid */
+ + 3 * SDWord /* mode, atime, mtime */
+ + SQWord /* length */
+ + SString(stat->name)
+ + SString(stat->uid)
+ + SString(stat->gid)
+ + SString(stat->muid)
+ + SString(stat->extension)
+ + SDWord /* n_uid */
+ + SDWord /* n_gid */
+ + SDWord /* n_muid */;
+}
+
+void
+ixp_pfcall_dotu(IxpMsg *msg, Fcall *fcall) {
+ switch (fcall->type) {
+ case RError:
+ ixp_pu8(msg, &fcall->type);
+ ixp_pu16(msg, &fcall->tag);
+
+ ixp_pstring(msg, &fcall->ename);
+ ixp_pu16(msg, &fcall->eerrno);
+ break;
+
+ default:
+ ixp_pfcall(msg, fcall);
+ }
+}
+
+uint
+ixp_fcall2msg_dotu(IxpMsg *msg, Fcall *fcall) {
+ uint size;
+
+ msg->end = msg->data + msg->size;
+ msg->pos = msg->data + SDWord;
+ msg->mode = MsgPack;
+ ixp_pfcall_dotu(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;
+}
diff -ur libixp-0.4.old/libixp/request.c libixp-0.4/libixp/request.c
--- libixp-0.4.old/libixp/request.c 2007-11-05 15:36:22 +0100
+++ libixp-0.4/libixp/request.c 2008-01-27 21:44:39 +0100
@@ -122,6 +122,7 @@
req->srv = pc->srv;
req->ifcall = fcall;
pc->conn = c;
+ req->dotu = (pc->conn && pc->conn->dotu) ? 1 : 0;

if(caninsertkey(&pc->tagmap, fcall.tag, req) == 0) {
respond(req, Eduptag);
@@ -154,7 +155,11 @@
r->ofcall.version = "9P";
else if(!strcmp(r->ifcall.version, "9P2000"))
r->ofcall.version = "9P2000";
- else
+ else if(!strcmp(r->ifcall.version, "9P2000.u")) {
+ r->ofcall.version = "9P2000.u";
+ if (pc->conn)
+ pc->conn->dotu = 1;
+ } else
r->ofcall.version = "unknown";
r->ofcall.msize = r->ifcall.msize;
respond(r, nil);
@@ -395,11 +400,19 @@
deletekey(&pc->tagmap, r->ifcall.tag);;

if(pc->conn) {
- thread->lock(&pc->wlock);
- msize = ixp_fcall2msg(&pc->wmsg, &r->ofcall);
- if(ixp_sendmsg(pc->conn->fd, &pc->wmsg) != msize)
- ixp_hangup(pc->conn);
- thread->unlock(&pc->wlock);
+ if (pc->conn->dotu) {
+ thread->lock(&pc->wlock);
+ msize = ixp_fcall2msg_dotu(&pc->wmsg, &r->ofcall);
+ if(ixp_sendmsg(pc->conn->fd, &pc->wmsg) != msize)
+ ixp_hangup(pc->conn);
+ thread->unlock(&pc->wlock);
+ } else {
+ thread->lock(&pc->wlock);
+ msize = ixp_fcall2msg(&pc->wmsg, &r->ofcall);
+ if(ixp_sendmsg(pc->conn->fd, &pc->wmsg) != msize)
+ ixp_hangup(pc->conn);
+ thread->unlock(&pc->wlock);
+ }
}

switch(r->ofcall.type) {
diff -ur libixp-0.4.old/libixp/server.c libixp-0.4/libixp/server.c
--- libixp-0.4.old/libixp/server.c 2007-11-05 15:36:22 +0100
+++ libixp-0.4/libixp/server.c 2008-01-29 03:33:25 +0100
@@ -15,7 +15,7 @@
) {
IxpConn *c;

- c = emallocz(sizeof(IxpConn));
+ c = emallocz(sizeof(IxpConn)+1);
c->fd = fd;
c->aux = aux;
c->srv = s;
Reply all
Reply to author
Forward
0 new messages