commit - 0592b956b4fc5a82ee81a89fcaf0d2e0d9811b1a
commit + c7f145d4ed3211b02d766e9f126e27a3dda1b871
blob - e88277ab8971ae6a3ad23c02cd997b622fa49ba3
blob + 54d846210b8e363b82905263928747b7dc1ee431
--- 9pclib.c
+++ 9pclib.c
}
void
+write_buf(const void *d, uint32_t len)
+{
+ write_32(len);
+ evbuffer_add(evb, d, len);
+}
+
+void
write_64(uint64_t x)
{
x = htole64(x);
}
void
+tcreate(uint32_t fid, const char *name, uint32_t perm, uint8_t mode)
+{
+ uint32_t len;
+ uint16_t nl;
+
+ /* fid[4] name[s] perm[4] mode[1] */
+ nl = strlen(name);
+ len = sizeof(fid) + sizeof(nl) + nl + sizeof(perm) + sizeof(mode);
+ write_hdr_auto(len, Tcreate);
+ write_fid(fid);
+ write_str(nl, name);
+ write_32(perm);
+ write_8(mode);
+}
+
+void
tread(uint32_t fid, uint64_t off, uint32_t count)
{
uint32_t len;
write_off(off);
write_32(count);
}
+
+void
+twrite(uint32_t fid, uint64_t off, const void *data, uint32_t count)
+{
+ uint32_t len;
+
+ /* fid[4] off[8] count[4] data[count] */
+ len = sizeof(fid) + sizeof(off) + sizeof(count) + count;
+ write_hdr_auto(len, Twrite);
+ write_fid(fid);
+ write_off(off);
+ write_buf(data, count);
+}
+
+void
+tremove(uint32_t fid)
+{
+ /* fid[4] */
+ write_hdr_auto(sizeof(fid), Tremove);
+ write_fid(fid);
+}
blob - 96accaa0e329fa150af852aeff826ab2951443c6
blob + 8d393d4f53f13f30a3aaa9af215ca2d5de0f15e7
--- 9pclib.h
+++ 9pclib.h
void write_hdr_auto(uint32_t, uint8_t);
void write_str(uint16_t, const char *);
void write_str_auto(const char *);
+void write_buf(const void *, uint32_t);
void write_64(uint64_t);
void write_32(uint32_t);
void write_16(uint16_t);
void tflush(uint16_t);
void twalk(uint32_t, uint32_t, const char **, size_t);
void topen(uint32_t, uint8_t);
+void tcreate(uint32_t, const char *, uint32_t, uint8_t);
void tread(uint32_t, uint64_t, uint32_t);
+void twrite(uint32_t, uint64_t, const void *, uint32_t);
+void tremove(uint32_t);
#endif
blob - 1d0e23caf45939f884a7e731f4310714f8482dc1
blob + fb0c86530732d462858c57359e8a544d794d6b06
--- kamirepl.1
+++ kamirepl.1
.Sq rclose
to remove the file upon
.Ic clunk .
+.It Ic create Ar fid Ar name Ar perm Ar mode
+Create the file
+.Ar name
+and open it with
+.Ar mode
+as the given
+.Ar fid.
+.Ar perm
+should be used to select the permissions of the file, but is currently
+unused.
.It Ic read Ar fid Ar offset Ar count
Issue a read request for the given
.Ar fid ,
and for
.Ar count
bytes.
+.It Ic write Ar fid Ar offset Ar content
+Writes
+.Ar content
+to
+.Ar fid
+starting at
+.Ar offset .
+.It Ic remove Ar fid
+Delete the file identified by
+.Ar fid
+and close it.
+Even in case of error,
+.Ar fid
+is clunked.
.El
.Sh SEE ALSO
.Xr kamiftp 1
blob - f9827e42cbace60d30b4d786d251025de8e54fae
blob + 37f52de3fe7bbf4220579af0d172e83adb38b7a4
--- kamirepl.c
+++ kamirepl.c
static void excmd_flush(const char **, int);
static void excmd_walk(const char ** , int);
static void excmd_open(const char ** , int);
+static void excmd_create(const char ** , int);
static void excmd_read(const char ** , int);
+static void excmd_write(const char **, int);
static void excmd(const char **, int);
static const char *pp_qid_type(uint8_t);
usage:
log_warnx("usage: open fid mode [flag]");
+}
+
+/* create fid path perm mode */
+static void
+excmd_create(const char **argv, int argc)
+{
+ const char *errstr;
+ uint32_t fid;
+ uint8_t mode = 0;
+
+ if (argc != 5)
+ goto usage;
+
+ fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
+ if (errstr != NULL) {
+ log_warnx("fid is %s: %s", errstr, argv[1]);
+ return;
+ }
+
+ /* parse mode */
+ if (!strcmp("write", argv[4]) || !strcmp("w", argv[4]))
+ mode = KOWRITE;
+ else if (!strcmp("readwrite", argv[4]) || !strcmp("rw", argv[4]))
+ mode = KORDWR;
+ else {
+ log_warnx("invalid mode %s for create", argv[4]);
+ return;
+ }
+
+ tcreate(fid, argv[2], 0, mode);
+ do_send();
+ return;
+
+usage:
+ log_warnx("usage: create fid path perm mode ; perm is unused");
}
+
/* read fid offset count */
static void
excmd_read(const char **argv, int argc)
usage:
log_warnx("usage: read fid offset count");
+}
+
+/* write fid offset content */
+static void
+excmd_write(const char **argv, int argc)
+{
+ uint64_t off;
+ uint32_t fid, count;
+ const char *errstr;
+
+ if (argc != 4)
+ goto usage;
+
+ fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
+ if (errstr != NULL) {
+ log_warnx("fid is %s: %s", errstr, argv[1]);
+ return;
+ }
+
+ /* should really be UINT64_MAX but... */
+ off = strtonum(argv[2], 0, UINT32_MAX, &errstr);
+ if (errstr != NULL) {
+ log_warnx("offset is %s: %s", errstr, argv[2]);
+ return;
+ }
+
+ count = strlen(argv[3]);
+ twrite(fid, off, argv[3], count);
+ do_send();
+ return;
+
+usage:
+ log_warnx("usage: write fid offset content");
}
+/* remove fid */
static void
+excmd_remove(const char **argv, int argc)
+{
+ const char *errstr;
+ uint32_t fid;
+
+ if (argc != 2)
+ goto usage;
+
+ fid = strtonum(argv[1], 0, UINT32_MAX, &errstr);
+ if (errstr != NULL) {
+ log_warnx("fid is %s: %s", errstr, argv[1]);
+ return;
+ }
+
+ tremove(fid);
+ do_send();
+ return;
+
+usage:
+ log_warnx("usage: remove fid");
+}
+
+static void
excmd(const char **argv, int argc)
{
struct cmd {
{"flush", excmd_flush},
{"walk", excmd_walk},
{"open", excmd_open},
+ {"create", excmd_create},
{"read", excmd_read},
+ {"write", excmd_write},
+ /* TODO: stat */
+ {"remove", excmd_remove},
};
size_t i;
break;
case Ropen:
+ case Rcreate:
if (len != QIDSIZE + 4) {
- printf("invalid Ropen: expected %d bytes; "
- "got %u\n", QIDSIZE + 4, len);
+ printf("invalid %s: expected %d bytes; "
+ "got %u\n", pp_msg_type(type), QIDSIZE + 4, len);
break;
}
strvisx(v, d, count, VIS_SAFE | VIS_TAB | VIS_NL | VIS_CSTYLE);
printf("data=%s", v);
free(v);
+
+ break;
+
+ case Rwrite:
+ if (len != sizeof(count)) {
+ printf("invalid Rwrite: expected %zu data bytes; "
+ "got %u\n", sizeof(count), len);
+ break;
+ }
+ memcpy(&count, d, sizeof(count));
+ d += sizeof(count);
+ len -= sizeof(count);
+ count = le32toh(count);
+
+ printf("count=%d", count);
break;
+ case Rremove:
+ if (len != 0)
+ printf("invalid Rremove: %"PRIu32" extra bytes", len);
+ break;
+
case Rerror:
memcpy(&slen, d, sizeof(slen));
d += sizeof(slen);