commit 87eb4561ce4a626c6e220f45ecf129c4d9a8886c
parent 514018b292e17629f0f67e5a89816e3e0bd58d39
Author: Kris Maglione <bsdaemon@wmii.de>
Date: Wed, 14 Jun 2006 19:26:35 -0400
Minor change to fcall allocation in preparation for fs2.c/libixp2
Diffstat:
4 files changed, 65 insertions(+), 9 deletions(-)
diff --git a/cmd/wm/fs.c b/cmd/wm/fs.c
@@ -662,13 +662,17 @@ static char *
xwalk(IXPConn *c, Fcall *fcall)
{
IXPMap *m;
+ char *err;
unsigned int qsel, nwqid;
PackedQid wqid[IXP_MAX_WELEM], *qid;
- if(!(m = ixp_server_fid2map(c, fcall->fid)))
- return Enofile;
- if(fcall->fid != fcall->newfid && (ixp_server_fid2map(c, fcall->newfid)))
- return Efidinuse;
+ if(!(m = ixp_server_fid2map(c, fcall->fid))) {
+ err = Enofile;
+ goto Fail;
+ }if(fcall->fid != fcall->newfid && (ixp_server_fid2map(c, fcall->newfid))) {
+ err = Efidinuse;
+ goto Fail;
+ }
for(qsel = 0; qsel < m->nwqid; qsel++)
wqid[qsel].qid = m->wqid[qsel];
@@ -691,8 +695,10 @@ xwalk(IXPConn *c, Fcall *fcall)
fcall->wqid[nwqid] = wqid[qsel].qid = qid->qid;
}
- if(fcall->nwname && !nwqid)
- return Enofile;
+ if(fcall->nwname && !nwqid) {
+ err = Enofile;
+ goto Fail;
+ }
/* a fid will only be valid, if the walk was complete */
if(nwqid == fcall->nwname) {
@@ -708,10 +714,14 @@ xwalk(IXPConn *c, Fcall *fcall)
m->sel = qsel;
m->fid = fcall->newfid;
}
+ free(fcall->wname[0]);
fcall->id = RWALK;
fcall->nwqid = nwqid;
ixp_server_respond_fcall(c, fcall);
return nil;
+Fail:
+ free(fcall->wname[0]);
+ return err;
}
static char *
diff --git a/libixp/convert.c b/libixp/convert.c
@@ -92,6 +92,29 @@ ixp_pack_string(unsigned char **msg, int *msize, const char *s)
}
void
+ixp_unpack_strings(unsigned char **msg, unsigned short n, char **strings) {
+ unsigned char *s = *msg;
+ unsigned int i, size = 0;
+ unsigned short len;
+ /* XXX: a specially crafted packet could make this read past the end of the buffer */
+ for(i=0; i<n; i++) {
+ ixp_unpack_u16(&s, &len);
+ s += len;
+ size += len + 1; /* for '\0' */
+ }
+ /* XXX: we don't really need mallocz here */
+ s = cext_emallocz(size);
+ for(i=0; i < n; i++) {
+ ixp_unpack_u16(msg, &len);
+ memcpy(s, *msg, len);
+ s[len] = '\0';
+ strings[i] = s;
+ *msg += len;
+ s += len + 1;
+ }
+}
+
+void
ixp_unpack_string(unsigned char **msg, char *string, unsigned short stringlen,
unsigned short *len)
{
diff --git a/libixp/ixp.h b/libixp/ixp.h
@@ -132,7 +132,7 @@ typedef struct {
unsigned char mode; /* Tcreate, Topen */
unsigned int newfid; /* Twalk */
unsigned short nwname; /* Twalk */
- char wname[IXP_MAX_WELEM][IXP_MAX_FLEN];/* Twalk */
+ char *wname[IXP_MAX_WELEM];/* Twalk */
unsigned short nwqid; /* Rwalk */
Qid wqid[IXP_MAX_WELEM]; /* Rwalk */
unsigned long long offset; /* Tread, Twrite */
@@ -145,6 +145,7 @@ typedef struct {
typedef struct IXPServer IXPServer;
typedef struct IXPConn IXPConn;
typedef struct IXPMap IXPMap;
+typedef struct Intmap Intmap;
struct IXPMap {
IXPMap *next;
@@ -154,6 +155,20 @@ struct IXPMap {
Qid wqid[IXP_MAX_WELEM];
};
+typedef struct Intlist Intlist;
+struct Intlist
+{
+ unsigned long id;
+ void* aux;
+ Intlist* link;
+};
+
+struct Intmap
+{
+ unsigned long nhash;
+ Intlist **hash;
+};
+
struct IXPConn {
IXPConn *next;
int fd;
@@ -210,6 +225,7 @@ void ixp_unpack_u32(unsigned char **msg, unsigned int *val);
void ixp_pack_u64(unsigned char **msg, int *msize, unsigned long long val);
void ixp_unpack_u64(unsigned char **msg, unsigned long long *val);
void ixp_pack_string(unsigned char **msg, int *msize, const char *s);
+void ixp_unpack_strings(unsigned char **msg, unsigned short n, char **strings);
void ixp_unpack_string(unsigned char **msg, char *string,
unsigned short stringlen, unsigned short *len);
void ixp_pack_data(unsigned char **msg, int *msize, unsigned char *data,
@@ -225,6 +241,14 @@ void ixp_unpack_qid(unsigned char **msg, Qid *qid);
void ixp_pack_stat(unsigned char **msg, int *msize, Stat *stat);
void ixp_unpack_stat(unsigned char **msg, Stat *stat);
+/* intmap.c */
+void initmap(Intmap *m, unsigned long nhash, void *hash);
+void freemap(Intmap *map, void (*destroy)(void*));
+void* lookupkey(Intmap *map, unsigned long id);
+void* insertkey(Intmap *map, unsigned long id, void *v);
+int caninsertkey(Intmap *map, unsigned long id, void *v);
+void* deletekey(Intmap *map, unsigned long id);
+
/* message.c */
unsigned short ixp_sizeof_stat(Stat *stat);
unsigned int ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen);
diff --git a/libixp/message.c b/libixp/message.c
@@ -179,8 +179,7 @@ ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen)
ixp_unpack_u32(&p, &fcall->fid);
ixp_unpack_u32(&p, &fcall->newfid);
ixp_unpack_u16(&p, &fcall->nwname);
- for(i = 0; i < fcall->nwname; i++)
- ixp_unpack_string(&p, fcall->wname[i], IXP_MAX_FLEN, &len);
+ ixp_unpack_strings(&p, fcall->nwname, &fcall->wname);
break;
case RWALK:
ixp_unpack_u16(&p, &fcall->nwqid);