master xplshn/aruu / cmd / posix / id.c
  1/* See LICENSE file for copyright and license details. */
  2
  3#include <sys/types.h>
  4
  5#include <ctype.h>
  6#include <errno.h>
  7#include <grp.h>
  8#include <limits.h>
  9#include <pwd.h>
 10#include <stdio.h>
 11#include <stdlib.h>
 12#include <unistd.h>
 13
 14#include "util.h"
 15
 16static void groupid(struct passwd *pw);
 17static void user(struct passwd *pw);
 18static void userid(uid_t id);
 19static void usernam(const char *nam);
 20
 21static int gflag = 0;
 22static int uflag = 0;
 23static int Gflag = 0;
 24static int nflag = 0;
 25
 26static void
 27groupid(struct passwd *pw)
 28{
 29  gid_t         gid, groups[NGROUPS_MAX];
 30  struct group *gr;
 31  int           ngroups;
 32  int           i;
 33
 34  ngroups = NGROUPS_MAX;
 35  getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
 36  for (i = 0; i < ngroups; i++) {
 37    gid = groups[i];
 38    if (nflag) {
 39      if (!(gr = getgrgid(gid)))
 40        eprintf("getgrgid:");
 41      printf("%s", gr->gr_name);
 42    } else
 43      printf("%u", gid);
 44
 45    if (i < ngroups - 1)
 46      putchar(' ');
 47  }
 48  putchar('\n');
 49}
 50
 51static void
 52user(struct passwd *pw)
 53{
 54  struct group *gr;
 55  gid_t         gid, groups[NGROUPS_MAX];
 56  int           ngroups;
 57  int           i;
 58
 59  if (uflag) {
 60    if (nflag)
 61      printf("%s\n", pw->pw_name);
 62    else
 63      printf("%u\n", pw->pw_uid);
 64    return;
 65  } else if (gflag) {
 66    if (nflag) {
 67      if (!(gr = getgrgid(pw->pw_gid)))
 68        eprintf("getgrgid:");
 69      printf("%s\n", gr->gr_name);
 70    } else
 71      printf("%u\n", pw->pw_gid);
 72    return;
 73  }
 74
 75  printf("uid=%u(%s)", pw->pw_uid, pw->pw_name);
 76  printf(" gid=%u", pw->pw_gid);
 77  if (!(gr = getgrgid(pw->pw_gid)))
 78    eprintf("getgrgid:");
 79  printf("(%s)", gr->gr_name);
 80
 81  ngroups = NGROUPS_MAX;
 82  getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
 83  for (i = 0; i < ngroups; i++) {
 84    gid = groups[i];
 85    printf("%s%u", !i ? " groups=" : ",", gid);
 86    if (!(gr = getgrgid(gid)))
 87      eprintf("getgrgid:");
 88    printf("(%s)", gr->gr_name);
 89  }
 90  putchar('\n');
 91}
 92
 93static void
 94usernam(const char *nam)
 95{
 96  struct passwd *pw;
 97
 98  errno = 0;
 99  pw    = getpwnam(nam);
100  if (!pw) {
101    if (errno)
102      eprintf("getpwnam %s:", nam);
103    else
104      eprintf("getpwnam %s: no such user\n", nam);
105  }
106  if (Gflag)
107    groupid(pw);
108  else
109    user(pw);
110}
111
112static void
113userid(uid_t id)
114{
115  struct passwd *pw;
116
117  errno = 0;
118  pw    = getpwuid(id);
119  if (!pw) {
120    if (errno)
121      eprintf("getpwuid %d:", id);
122    else
123      eprintf("getpwuid %d: no such user\n", id);
124  }
125  if (Gflag)
126    groupid(pw);
127  else
128    user(pw);
129}
130
131static void
132usage(void)
133{
134  eprintf("usage: %s [-n] [-g | -u | -G] [user | uid]\n", argv0);
135}
136
137// ?man id: print user and group ids
138// ?man arguments: user | uid
139// ?man display real and effective user and group identities
140int
141main(int argc, char *argv[])
142{
143  ARGBEGIN
144  {
145    // ?man -g: specify option flag
146    case 'g':
147      gflag = 1;
148      break;
149    // ?man -u: unbuffered output
150    case 'u':
151      uflag = 1;
152      break;
153    // ?man -G: specify option flag
154    case 'G':
155      Gflag = 1;
156      break;
157    // ?man -n: print line numbers or counts
158    case 'n':
159      nflag = 1;
160      break;
161    default:
162      usage();
163  }
164  ARGEND;
165
166  /* ensure that only one of -g, -u, or -G was specified */
167  if (gflag + uflag + Gflag > 1)
168    usage();
169
170  switch (argc) {
171    case 0:
172      userid(getuid());
173      break;
174    case 1:
175      /* user names can't begin [0-9] */
176      if (isdigit(argv[0][0]))
177        userid(estrtol(argv[0], 0));
178      else
179        usernam(argv[0]);
180      break;
181    default:
182      usage();
183  }
184
185  return 0;
186}