From 1d39310d0139426aba46efe41fab643aae87ca9c Mon Sep 17 00:00:00 2001 From: Rhin Date: Sat, 29 Jun 2019 14:47:38 -0500 Subject: [PATCH] Userland: Added flags to id command (#253) Fixes #158. --- Userland/id.cpp | 113 +++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 108 insertions(+), 5 deletions(-) diff --git a/Userland/id.cpp b/Userland/id.cpp index b552f6a528..c5325ea94a 100644 --- a/Userland/id.cpp +++ b/Userland/id.cpp @@ -1,18 +1,102 @@ #include +#include #include #include #include #include -extern "C" int main(int, char**); +static int print_id_objects(); + +static bool flag_print_uid = false; +static bool flag_print_gid = false; +static bool flag_print_name = false; +static bool flag_print_gid_all = false; int main(int argc, char** argv) { - (void)argc; - (void)argv; + static const char* valid_option_characters = "ugGn"; + int opt; + while ((opt = getopt(argc, argv, valid_option_characters)) != -1) { + switch (opt) { + case 'u': + flag_print_uid = true; + break; + case 'g': + flag_print_gid = true; + break; + case 'G': + flag_print_gid_all = true; + break; + case 'n': + flag_print_name = true; + break; + + default: + fprintf(stderr, "usage: ls [-%s] [paths...]\n", valid_option_characters); + return 1; + } + } + + if (flag_print_uid + flag_print_gid + flag_print_gid_all > 1) { + fprintf(stderr, "cannot print \"only\" of more than one choice\n"); + return 1; + } + + int status = print_id_objects(); + return status; +} + +bool print_uid_object(uid_t uid) +{ + if (flag_print_name) { + struct passwd* pw = getpwuid(uid); + printf("%s", pw ? pw->pw_name : "n/a"); + } else + printf("%u", uid); + + return true; +} + +bool print_gid_object(gid_t gid) +{ + if (flag_print_name) { + struct group* gr = getgrgid(gid); + printf("%s", gr ? gr->gr_name : "n/a"); + } else + printf("%u", gid); + return true; +} + +bool print_gid_list() +{ + int extra_gid_count = getgroups(0, nullptr); + if (extra_gid_count) { + auto* extra_gids = (gid_t*)alloca(extra_gid_count * sizeof(gid_t)); + int rc = getgroups(extra_gid_count, extra_gids); + + if (rc < 0) { + perror("\ngetgroups"); + return false; + } + + for (int g = 0; g < extra_gid_count; ++g) { + auto* gr = getgrgid(extra_gids[g]); + if (flag_print_name && gr) + printf("%s", gr->gr_name); + else + printf("%u", extra_gids[g]); + if (g != extra_gid_count - 1) + printf(" "); + } + } + return true; +} + +bool print_full_id_list() +{ + uid_t uid = getuid(); gid_t gid = getgid(); - struct passwd* pw = getpwuid(uid); struct group* gr = getgrgid(gid); @@ -24,7 +108,7 @@ int main(int argc, char** argv) int rc = getgroups(extra_gid_count, extra_gids); if (rc < 0) { perror("\ngetgroups"); - return 1; + return false; } printf(", groups="); for (int g = 0; g < extra_gid_count; ++g) { @@ -37,6 +121,25 @@ int main(int argc, char** argv) printf(","); } } + return true; +} + +int print_id_objects() +{ + if (flag_print_uid) { + if (!print_uid_object(getuid())) + return 1; + } else if (flag_print_gid) { + if (!print_gid_object(getgid())) + return 1; + } else if (flag_print_gid_all) { + if (!print_gid_list()) + return 1; + } else { + if (!print_full_id_list()) + return 1; + } + printf("\n"); return 0; }