diff options
Diffstat (limited to 'lib9p/srv.c')
-rw-r--r-- | lib9p/srv.c | 51 |
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); |