summaryrefslogtreecommitdiff
path: root/lib9p/srv.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r--lib9p/srv.c51
1 files changed, 37 insertions, 14 deletions
diff --git a/lib9p/srv.c b/lib9p/srv.c
index 96954aa..fd8e662 100644
--- a/lib9p/srv.c
+++ b/lib9p/srv.c
@@ -165,7 +165,7 @@ static inline enum srv_filetype srv_qid_filetype(struct lib9p_qid qid) {
return SRV_FILETYPE_FILE;
}
-static inline bool srv_check_perm(struct srv_req *ctx, struct lib9p_stat *stat, uint8_t action) {
+static inline bool srv_check_perm(struct srv_req *ctx, struct lib9p_srv_stat *stat, uint8_t action) {
assert(ctx);
assert(stat);
assert(action);
@@ -964,10 +964,10 @@ static void handle_Twalk(struct srv_req *ctx,
}
if (new_pathinfo->type == SRV_FILETYPE_DIR) {
- struct lib9p_stat stat = LO_CALL(new_pathinfo->file, stat, ctx);
+ struct lib9p_srv_stat stat = LO_CALL(new_pathinfo->file, stat, ctx);
if (lib9p_ctx_has_error(&ctx->basectx))
break;
- lib9p_stat_assert(stat);
+ lib9p_srv_stat_assert(stat);
if (!srv_check_perm(ctx, &stat, 0b001)) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EACCES, "you do not have execute permission on that directory");
@@ -1033,10 +1033,10 @@ static void handle_Topen(struct srv_req *ctx,
if (reqmode & LIB9P_O_RCLOSE) {
struct srv_pathinfo *parent = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
assert(parent);
- struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, ctx);
+ struct lib9p_srv_stat parent_stat = LO_CALL(parent->file, stat, ctx);
if (lib9p_ctx_has_error(&ctx->basectx))
goto topen_return;
- lib9p_stat_assert(parent_stat);
+ lib9p_srv_stat_assert(parent_stat);
if (!srv_check_perm(ctx, &parent_stat, 0b010)) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EACCES, "permission denied to remove-on-close");
@@ -1044,10 +1044,10 @@ static void handle_Topen(struct srv_req *ctx,
}
fidflags |= FIDFLAG_RCLOSE;
}
- struct lib9p_stat stat = LO_CALL(pathinfo->file, stat, ctx);
+ struct lib9p_srv_stat stat = LO_CALL(pathinfo->file, stat, ctx);
if (lib9p_ctx_has_error(&ctx->basectx))
goto topen_return;
- lib9p_stat_assert(stat);
+ lib9p_srv_stat_assert(stat);
if ((stat.mode & LIB9P_DM_EXCL) && pathinfo->io_refcount) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EEXIST, "exclusive file is already opened");
@@ -1140,6 +1140,26 @@ static void handle_Tcreate(struct srv_req *ctx,
srv_respond(ctx, create, &resp);
}
+static inline struct lib9p_stat srv_stat_to_net_stat(struct lib9p_srv_stat in) {
+ return (struct lib9p_stat){
+ .qid = in.qid,
+ .mode = in.mode,
+ .atime = in.atime_sec,
+ .mtime = in.mtime_sec,
+ .length = in.size,
+ .name = in.name,
+ .owner_uname = in.owner_uid.name,
+ .owner_gname = in.owner_gid.name,
+ .last_modifier_uname = in.last_modifier_uid.name,
+#if CONFIG_9P_ENABLE_9P2000_u
+ .owner_unum = in.owner_uid.num,
+ .owner_gnum = in.owner_gid.num,
+ .last_modifier_unum = in.last_modifier_uid.num,
+ .extension = in.extension,
+#endif
+ };
+}
+
static void handle_Tread(struct srv_req *ctx,
struct lib9p_msg_Tread *req) {
srv_handler_common(ctx, read, req);
@@ -1195,7 +1215,7 @@ static void handle_Tread(struct srv_req *ctx,
}
if (!member_dirent.name.len)
break;
- struct lib9p_stat member_stat;
+ struct lib9p_srv_stat member_stat;
struct srv_pathinfo *member_pathinfo = map_load(&ctx->parent_sess->paths, member_dirent.qid.path);
if (member_pathinfo) {
member_stat = LO_CALL(member_pathinfo->file, stat, ctx);
@@ -1216,8 +1236,9 @@ static void handle_Tread(struct srv_req *ctx,
lib9p_ctx_clear_error(&ctx->basectx);
break;
}
- lib9p_stat_assert(member_stat);
- uint32_t nbytes = lib9p_stat_marshal(&ctx->basectx, req->count-resp.count, &member_stat,
+ lib9p_srv_stat_assert(member_stat);
+ struct lib9p_stat member_netstat = srv_stat_to_net_stat(member_stat);
+ uint32_t nbytes = lib9p_stat_marshal(&ctx->basectx, req->count-resp.count, &member_netstat,
(uint8_t *)&resp.data[resp.count]);
if (!LO_IS_NULL(member_file))
LO_CALL(member_file, free);
@@ -1327,7 +1348,7 @@ static void handle_Tremove(struct srv_req *ctx,
}
struct srv_pathinfo *parent = map_load(&ctx->parent_sess->paths, pathinfo->parent_dir);
assert(parent);
- struct lib9p_stat parent_stat = LO_CALL(parent->file, stat, ctx);
+ struct lib9p_srv_stat parent_stat = LO_CALL(parent->file, stat, ctx);
if (!lib9p_ctx_has_error(&ctx->basectx) && !srv_check_perm(ctx, &parent_stat, 0b010)) {
lib9p_error(&ctx->basectx,
LIB9P_ERRNO_L_EACCES, "you do not have write permission on the parent directory");
@@ -1355,9 +1376,11 @@ static void handle_Tstat(struct srv_req *ctx,
assert(pathinfo);
ctx->user = srv_userid_incref(fidinfo->user);
- resp.stat = LO_CALL(pathinfo->file, stat, ctx);
- if (!lib9p_ctx_has_error(&ctx->basectx))
- lib9p_stat_assert(resp.stat);
+ struct lib9p_srv_stat stat = LO_CALL(pathinfo->file, stat, ctx);
+ if (lib9p_ctx_has_error(&ctx->basectx))
+ goto tstat_return;
+ lib9p_srv_stat_assert(stat);
+ resp.stat = srv_stat_to_net_stat(stat);
tstat_return:
if (ctx->user)
ctx->user = srv_userid_decref(ctx->user);