commit c7f145d4ed3211b02d766e9f126e27a3dda1b871 from: Omar Polo date: Mon Dec 20 19:53:42 2021 UTC add Tcreate, Twrite and Tremove commit - 0592b956b4fc5a82ee81a89fcaf0d2e0d9811b1a commit + c7f145d4ed3211b02d766e9f126e27a3dda1b871 blob - e88277ab8971ae6a3ad23c02cd997b622fa49ba3 blob + 54d846210b8e363b82905263928747b7dc1ee431 --- 9pclib.c +++ 9pclib.c @@ -71,6 +71,13 @@ write_str_auto(const char *str) } 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); @@ -187,6 +194,22 @@ topen(uint32_t fid, uint8_t mode) } 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; @@ -198,3 +221,24 @@ tread(uint32_t fid, uint64_t off, uint32_t count) 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 @@ -30,6 +30,7 @@ void write_hdr(uint32_t, uint8_t, uint16_t); 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); @@ -45,6 +46,9 @@ void tclunk(uint32_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 @@ -105,6 +105,16 @@ to truncate the file or .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 , @@ -115,6 +125,20 @@ at 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 @@ -79,7 +79,9 @@ static void excmd_clunk(const char **, int); 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); @@ -535,8 +537,44 @@ excmd_open(const char **argv, int argc) 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) @@ -573,9 +611,66 @@ 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 { @@ -588,7 +683,11 @@ excmd(const char **argv, int argc) {"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; @@ -736,9 +835,10 @@ pp_msg(uint32_t len, uint8_t type, uint16_t tag, const 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; } @@ -777,9 +877,29 @@ pp_msg(uint32_t len, uint8_t type, uint16_t tag, const 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);