Commit Diff


commit - 0b3307f125b145279ce3601d3adc20373666734b
commit + 983e73a671a59d3996137c7e7044929167855f4a
blob - 42e5e3b2b029cd0c5d7d1055ef9ee8dfb6ec8a54
blob + c48be0ead8bf4c0eefb746bba331fa166ccd8dd0
--- script.c
+++ script.c
@@ -547,6 +547,9 @@ ppf_val(FILE *f, struct value *val)
 			    i == val->v.msg.len-1 ? "" : " ");
 		fprintf(f, ")");
 		break;
+	case V_QIDVEC:
+		fprintf(f, "qids[n=%zu]", val->v.qidvec.len);
+		break;
 	default:
 		fprintf(f, "<unknown value>");
 		break;
@@ -688,7 +691,9 @@ val_cast(struct value *a, int totype)
 int
 val_faccess(struct value *a, const char *field, struct value *ret)
 {
-	uint8_t	mtype;
+	uint8_t		 mtype;
+	uint16_t	 len;
+	const char	*errstr;
 
 #define MSGTYPE(m) *(m.msg + 4)	/* skip the length */
 
@@ -725,10 +730,43 @@ val_faccess(struct value *a, const char *field, struct
 		} else if (!strcmp(field, "qid") && mtype == Rattach) {
 			ret->type = V_QID;
 			memcpy(&ret->v.qid, &a->v.msg.msg[7], QIDSIZE);
+			return EVAL_OK;
+		} else if (!strcmp(field, "nwqid") && mtype == Rwalk) {
+			ret->type = V_U16;
+			memcpy(&ret->v.u16, &a->v.msg.msg[7], 2);
+			ret->v.u16 = le16toh(ret->v.u16);
 			return EVAL_OK;
+		} else if (!strcmp(field, "wqid") && mtype == Rwalk) {
+			ret->type = V_QIDVEC;
+			ret->v.qidvec.start = &a->v.msg.msg[9];
+			memcpy(&len, &a->v.msg.msg[7], 2);
+			len = le16toh(len);
+			ret->v.qidvec.len = len;
+			return EVAL_OK;
 		}
 		break;
+
+	case V_QIDVEC:
+		len = strtonum(field, 0, MAXWELEM, &errstr);
+		if (errstr != NULL) {
+			before_printing();
+			printf("can't access qid #%s: %s\n", field, errstr);
+			return EVAL_ERR;
+		}
 
+		if (len >= a->v.qidvec.len) {
+			before_printing();
+			printf("can't access qid #%d: out-of-bound "
+			    "(max %zu)\n", len, a->v.qidvec.len);
+			return EVAL_ERR;
+		}
+
+		ret->type = V_QID;
+		memcpy(&ret->v.qid, a->v.qidvec.start + len * QIDSIZE,
+		    QIDSIZE);
+
+                return EVAL_OK;
+
 	default:
 		break;
 	}
blob - b92f93be2f080881f2d911f7d46d321466083e93
blob + 298daacfc8f6e07c07e14fb0d53b538fd8e07a75
--- script.h
+++ script.h
@@ -31,6 +31,7 @@ enum {
 
 	/* foreign */
 	V_MSG,
+	V_QIDVEC,
 	V_QID,
 
 	/* casted */
@@ -51,6 +52,10 @@ struct value {
 			uint8_t	*msg;
 			size_t	 len;
 		} msg;
+		struct {
+			uint8_t	*start;
+			size_t	 len;
+		} qidvec;
 		uint8_t		 qid[QIDSIZE];
 	} v;
 };
@@ -66,6 +71,7 @@ enum {
 	OP_CMP_EQ,
 	OP_FACCESS,
 	OP_SFAIL,
+	OP_VARGS,
 };
 
 struct proc;
@@ -173,6 +179,7 @@ struct op	*op_cmp_eq(struct op *, struct op *);
 struct op	*op_cast(struct op *, int);
 struct op	*op_faccess(struct op *, char *);
 struct op	*op_sfail(struct op *, char *);
+struct op	*op_vargs(void);
 
 void		 ppf_val(FILE *, struct value *);
 void		 pp_val(struct value *);