#include #include #include #include #include #include #include Result luna_main(int argc, char** argv) { StringView user_and_group; StringView path; os::ArgumentParser parser; parser.add_description("Change the owner and group of a file."_sv); parser.add_system_program_info("chown"_sv); parser.add_positional_argument(user_and_group, "owner"_sv, true); parser.add_positional_argument(path, "path"_sv, true); parser.parse(argc, argv); u32 uid = -1; Option gid = -1; auto names = TRY(user_and_group.split_once(':')); if (names.size() > 1) { auto& group = names[1]; if (group.is_empty()) { gid = {}; } else { auto rc = group.view().to_uint(); if (rc.has_value()) { gid = (u32)rc.value(); } else { struct group* grp = getgrnam(group.chars()); if (!grp) { fprintf(stderr, "%s: unknown group %s!\n", argv[0], group.chars()); return 1; } gid = grp->gr_gid; } } } if (names.size() > 0) { auto& owner = names[0]; if (!owner.is_empty()) { auto rc = owner.view().to_uint(); if (rc.has_value()) { uid = (u32)rc.value(); } else { struct passwd* pw = getpwnam(owner.chars()); if (!pw) { fprintf(stderr, "%s: unknown user %s!\n", argv[0], owner.chars()); return 1; } uid = pw->pw_uid; } if (!gid.has_value()) { struct passwd* pw = getpwuid(uid); if (!pw) { fprintf(stderr, "%s: unknown user id %u!\n", argv[0], uid); return 1; } gid = pw->pw_gid; } } } if (chown(path.chars(), uid, gid.value_or(-1)) < 0) { perror("chown"); return 1; } return 0; }