| 64 | } |
| 65 | |
| 66 | int |
| 67 | main (int argc, char **argv) |
| 68 | { |
| 69 | initialize_main (&argc, &argv); |
| 70 | set_program_name (argv[0]); |
| 71 | setlocale (LC_ALL, ""); |
| 72 | bindtextdomain (PACKAGE, LOCALEDIR); |
| 73 | textdomain (PACKAGE); |
| 74 | |
| 75 | atexit (close_stdout); |
| 76 | |
| 77 | /* Processing the arguments this way makes groups.c behave differently to |
| 78 | groups.sh if one of the arguments is "--". */ |
| 79 | int optc; |
| 80 | while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1) |
| 81 | { |
| 82 | switch (optc) |
| 83 | { |
| 84 | case_GETOPT_HELP_CHAR; |
| 85 | case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); |
| 86 | default: |
| 87 | usage (EXIT_FAILURE); |
| 88 | } |
| 89 | } |
| 90 | |
| 91 | bool ok = true; |
| 92 | if (optind == argc) |
| 93 | { |
| 94 | /* No arguments. Divulge the details of the current process. */ |
| 95 | uid_t NO_UID = -1; |
| 96 | gid_t NO_GID = -1; |
| 97 | |
| 98 | errno = 0; |
| 99 | uid_t ruid = getuid (); |
| 100 | if (ruid == NO_UID && errno) |
| 101 | error (EXIT_FAILURE, errno, _("cannot get real UID")); |
| 102 | |
| 103 | errno = 0; |
| 104 | gid_t egid = getegid (); |
| 105 | if (egid == NO_GID && errno) |
| 106 | error (EXIT_FAILURE, errno, _("cannot get effective GID")); |
| 107 | |
| 108 | errno = 0; |
| 109 | gid_t rgid = getgid (); |
| 110 | if (rgid == NO_GID && errno) |
| 111 | error (EXIT_FAILURE, errno, _("cannot get real GID")); |
| 112 | |
| 113 | if (!print_group_list (NULL, ruid, rgid, egid, true, ' ')) |
| 114 | ok = false; |
| 115 | putchar ('\n'); |
| 116 | } |
| 117 | else |
| 118 | { |
| 119 | /* At least one argument. Divulge the details of the specified users. */ |
| 120 | for ( ; optind < argc; optind++) |
| 121 | { |
| 122 | struct passwd *pwd = getpwnam (argv[optind]); |
| 123 | if (pwd == NULL) |
nothing calls this directly
no test coverage detected