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