/* groups -- print the groups a user is in This is the groups utility
Copyright (C) 1989-2018 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. */ The GNUv3 license
/* Written by James Youngman based on id.c and groups.sh,
which were written by Arnold Robbins and David MacKenzie. */
#include <config.h> Provides system specific information
#include <stdio.h> Provides standard I/O capability
#include <sys/types.h> Provides system data types
#include <pwd.h> ...!includes auto-comment...
#include <grp.h> ...!includes auto-comment...
#include <getopt.h> ...!includes auto-comment...
#include "system.h" ...!includes auto-comment...
#include "die.h" ...!includes auto-comment...
#include "group-list.h" ...!includes auto-comment...
#include "quote.h" ...!includes auto-comment...
/* The official name of this program (e.g., no 'g' prefix). */
#define PROGRAM_NAME "groups" Line 33
#define AUTHORS \ Line 35
proper_name ("David MacKenzie"), \ Line 36
proper_name ("James Youngman") Line 37
static struct option const longopts[] = Line 40
{
{GETOPT_HELP_OPTION_DECL}, Line 42
{GETOPT_VERSION_OPTION_DECL}, Line 43
{NULL, 0, NULL, 0} Line 44
}; Block 1
void Line 47
usage (int status) Line 48
{
if (status != EXIT_SUCCESS) Line 50
emit_try_help (); ...!common auto-comment...
else Line 52
{
printf (_("Usage: %s [OPTION]... [USERNAME]...\n"), program_name); Line 54
fputs (_("\ Line 55
Print group memberships for each USERNAME or, if no USERNAME is specified, for\ Line 56
\n\
the current process (which may differ if the groups database has changed).\n"), Line 58
stdout); Line 59
fputs (HELP_OPTION_DESCRIPTION, stdout); Line 60
fputs (VERSION_OPTION_DESCRIPTION, stdout); Line 61
emit_ancillary_info (PROGRAM_NAME); Line 62
}
exit (status); Line 64
} Block 2
int
main (int argc, char **argv) Line 68
{
int optc; Line 70
bool ok = true; Line 71
gid_t rgid, egid; Line 72
uid_t ruid; Line 73
initialize_main (&argc, &argv); VMS-specific entry point handling wildcard expansion
set_program_name (argv[0]); Retains program name and discards path
setlocale (LC_ALL, ""); Sets up internationalization (i18n)
bindtextdomain (PACKAGE, LOCALEDIR); Assigns i18n directorySets text domain for _() [gettext()] function
textdomain (PACKAGE); Sets text domain for _() [gettext()] function
atexit (close_stdout); Close stdout on exit (see gnulib)
/* Processing the arguments this way makes groups.c behave differently to
* groups.sh if one of the arguments is "--".
*/
while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1) Line 86
{
switch (optc) Line 88
{
case_GETOPT_HELP_CHAR; Line 90
case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS); Line 91
default: Line 92
usage (EXIT_FAILURE); Line 93
}
}
if (optind == argc) Line 97
{
/* No arguments. Divulge the details of the current process. */
uid_t NO_UID = -1; Line 100
gid_t NO_GID = -1; Line 101
errno = 0; Line 103
ruid = getuid (); Line 104...!syscalls auto-comment...
if (ruid == NO_UID && errno) Line 105
die (EXIT_FAILURE, errno, _("cannot get real UID")); Line 106
errno = 0; Line 108
egid = getegid (); Line 109...!syscalls auto-comment...
if (egid == NO_GID && errno) Line 110
die (EXIT_FAILURE, errno, _("cannot get effective GID")); Line 111
errno = 0; Line 113
rgid = getgid (); Line 114...!syscalls auto-comment...
if (rgid == NO_GID && errno) Line 115
die (EXIT_FAILURE, errno, _("cannot get real GID")); Line 116
if (!print_group_list (NULL, ruid, rgid, egid, true, ' ')) Line 118
ok = false; Line 119
putchar ('\n'); Line 120
}
else Line 122
{
/* At least one argument. Divulge the details of the specified users. */
for ( ; optind < argc; optind++) Line 125
{
struct passwd *pwd = getpwnam (argv[optind]); Line 127
if (pwd == NULL) Line 128
{
error (0, 0, _("%s: no such user"), quote (argv[optind])); Line 130
ok = false; Line 131
continue; Line 132
}
ruid = pwd->pw_uid; Line 134
rgid = egid = pwd->pw_gid; Line 135
printf ("%s : ", argv[optind]); Line 137
if (!print_group_list (argv[optind], ruid, rgid, egid, true, ' ')) Line 138
ok = false; Line 139
putchar ('\n'); Line 140
}
}
return ok ? EXIT_SUCCESS : EXIT_FAILURE; Line 144
} Block 3