Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/usr.sbin/puffs/mount_9p/nineproto.c,v rcsdiff: /ftp/cvs/cvsroot/src/usr.sbin/puffs/mount_9p/nineproto.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.9 retrieving revision 1.9.70.1 diff -u -p -r1.9 -r1.9.70.1 --- src/usr.sbin/puffs/mount_9p/nineproto.c 2007/11/30 19:02:38 1.9 +++ src/usr.sbin/puffs/mount_9p/nineproto.c 2019/06/10 22:10:35 1.9.70.1 @@ -1,4 +1,4 @@ -/* $NetBSD: nineproto.c,v 1.9 2007/11/30 19:02:38 pooka Exp $ */ +/* $NetBSD: nineproto.c,v 1.9.70.1 2019/06/10 22:10:35 christos Exp $ */ /* * Copyright (c) 2007 Antti Kantee. All Rights Reserved. @@ -27,7 +27,7 @@ #include #ifndef lint -__RCSID("$NetBSD: nineproto.c,v 1.9 2007/11/30 19:02:38 pooka Exp $"); +__RCSID("$NetBSD: nineproto.c,v 1.9.70.1 2019/06/10 22:10:35 christos Exp $"); #endif /* !lint */ #include @@ -117,9 +117,10 @@ do { \ size -= *strsize; \ } while (/*CONSTCOND*/0) int -proto_getstat(struct puffs_framebuf *pb, struct vattr *vap, +proto_getstat(struct puffs_usermount *pu, struct puffs_framebuf *pb, struct vattr *vap, char **name, uint16_t *rs) { + struct puffs9p *p9p = puffs_getspecific(pu); char *uid, *gid; struct qid9p qid; uint64_t flen; @@ -176,10 +177,60 @@ proto_getstat(struct puffs_framebuf *pb, /* muid, not used */ GETSTR(NULL, &v16); + if (p9p->protover == P9PROTO_VERSION_U) { + uint32_t dummy; + GETSTR(NULL, &v16); /* extention[s], not used */ + GETFIELD(p9pbuf_get_4, &dummy, 4); /* n_uid[4], not used */ + GETFIELD(p9pbuf_get_4, &dummy, 4); /* n_gid[4], not used */ + GETFIELD(p9pbuf_get_4, &dummy, 4); /* n_muid[4], not used */ + } return 0; } +static int +proto_rerror(struct puffs_usermount *pu, struct puffs_framebuf *pb, + uint32_t *_errno) +{ + struct puffs9p *p9p = puffs_getspecific(pu); + uint16_t size; + int rv; + char *name; + + /* Skip size[4] Rerror tag[2] */ + rv = puffs_framebuf_seekset(pb, + sizeof(uint32_t) + sizeof(uint8_t) + sizeof(uint16_t)); + if (rv == -1) + return EPROTO; + + rv = p9pbuf_get_str(pb, &name, &size); + if (rv != 0) + return rv; + if (p9p->protover == P9PROTO_VERSION_U) { + rv = p9pbuf_get_4(pb, _errno); + } else { + /* TODO Convert error string to errno */ + rv = EPROTO; + } + + return rv; +} + +int +proto_handle_rerror(struct puffs_usermount *pu, struct puffs_framebuf *pb) +{ + int rv; + uint32_t _errno; + + if (p9pbuf_get_type(pb) != P9PROTO_R_ERROR) + return EPROTO; + + rv = proto_rerror(pu, pb, &_errno); + if (rv == 0) + rv = _errno; + return rv; +} + int proto_cc_dupfid(struct puffs_usermount *pu, p9pfid_t oldfid, p9pfid_t newfid) { @@ -198,7 +249,7 @@ proto_cc_dupfid(struct puffs_usermount * p9pbuf_put_2(pb, 0); GETRESPONSE(pb); - rv = proto_expect_walk_nqids(pb, &qids); + rv = proto_expect_walk_nqids(pu, pb, &qids); if (rv == 0 && qids != 0) rv = EPROTO; @@ -224,7 +275,7 @@ proto_cc_clunkfid(struct puffs_usermount if (waitforit) { if (puffs_framev_enqueue_cc(pcc, p9p->servsock, pb, 0) == 0) { if (p9pbuf_get_type(pb) != P9PROTO_R_CLUNK) - rv = EPROTO; + rv = proto_handle_rerror(pu, pb); } else { rv = errno; } @@ -261,7 +312,7 @@ proto_cc_open(struct puffs_usermount *pu p9pbuf_put_1(pb, mode); GETRESPONSE(pb); if (p9pbuf_get_type(pb) != P9PROTO_R_OPEN) - rv = EPROTO; + rv = proto_handle_rerror(pu, pb); out: puffs_framebuf_destroy(pb); @@ -269,9 +320,10 @@ proto_cc_open(struct puffs_usermount *pu } void -proto_make_stat(struct puffs_framebuf *pb, const struct vattr *vap, - const char *filename, enum vtype vt) +proto_make_stat(struct puffs_usermount *pu, struct puffs_framebuf *pb, + const struct vattr *vap, const char *filename, enum vtype vt) { + struct puffs9p *p9p = puffs_getspecific(pu); struct vattr fakeva; uint32_t mode, atime, mtime; uint64_t flen; @@ -324,6 +376,12 @@ proto_make_stat(struct puffs_framebuf *p p9pbuf_put_str(pb, owner); p9pbuf_put_str(pb, group); p9pbuf_put_str(pb, ""); /* muid */ + if (p9p->protover == P9PROTO_VERSION_U) { + p9pbuf_put_str(pb, P9PROTO_STAT_NOSTR); /* extentions[s] */ + p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* n_uid[4] */ + p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* n_gid[4] */ + p9pbuf_put_4(pb, P9PROTO_STAT_NOVAL4); /* n_muid[4] */ + } curoff = puffs_framebuf_telloff(pb); puffs_framebuf_seekset(pb, startoff); @@ -334,32 +392,35 @@ proto_make_stat(struct puffs_framebuf *p } int -proto_expect_walk_nqids(struct puffs_framebuf *pb, uint16_t *nqids) +proto_expect_walk_nqids(struct puffs_usermount *pu, struct puffs_framebuf *pb, + uint16_t *nqids) { if (p9pbuf_get_type(pb) != P9PROTO_R_WALK) - return EPROTO; + return proto_handle_rerror(pu, pb); return p9pbuf_get_2(pb, nqids); } int -proto_expect_qid(struct puffs_framebuf *pb, uint8_t op, struct qid9p *qid) +proto_expect_qid(struct puffs_usermount *pu, struct puffs_framebuf *pb, + uint8_t op, struct qid9p *qid) { if (p9pbuf_get_type(pb) != op) - return EPROTO; + return proto_handle_rerror(pu, pb); return proto_getqid(pb, qid); } int -proto_expect_stat(struct puffs_framebuf *pb, struct vattr *va) +proto_expect_stat(struct puffs_usermount *pu, struct puffs_framebuf *pb, + struct vattr *va) { uint16_t dummy; int rv; if (p9pbuf_get_type(pb) != P9PROTO_R_STAT) - return EPROTO; + return proto_handle_rerror(pu, pb); if ((rv = p9pbuf_get_2(pb, &dummy))) return rv; - return proto_getstat(pb, va, NULL, NULL); + return proto_getstat(pu, pb, va, NULL, NULL); }