+ if (argc > 0xff)
+ argc = 0xff; // paranoia
+
+ pkt.magic = ntohs(NSCTL_MAGIC);
+ pkt.type = type;
+ pkt.argc = argc;
+
+ while (argc-- > 0)
+ {
+ char *a = *argv++;
+ int s = strlen(a);
+
+ if (s > sizeof(arg.value))
+ s = sizeof(arg.value); // silently truncate
+
+ arg.len = s;
+ s += sizeof(arg.len);
+
+ if (sz + s > len)
+ return -1; // overflow
+
+ if (arg.len)
+ memcpy(arg.value, a, arg.len);
+
+ memcpy(p, &arg, s);
+ sz += s;
+ p += s;
+ }
+
+ /*
+ * terminate: this is both a sanity check and additionally
+ * ensures that there's a spare byte in the packet to null
+ * terminate the last argument when unpacking (see unpack_control)
+ */
+ if (sz + sizeof(arg.len) > len)
+ return -1; // overflow
+
+ arg.len = 0xff;
+ memcpy(p, &arg.len, sizeof(arg.len));
+
+ sz += sizeof(arg.len);
+ memcpy(data, &pkt, sz);
+
+ return sz;