commit 02e0a1de08e9f5a9ffff983c1f9ddce8bbd2ed7c
parent 2c98e18a33a95269a17a6c4e7e5d2c86a1b7bfdc
Author: sin <sin@2f30.org>
Date:   Thu, 27 Feb 2014 14:27:28 +0000
Import id(1) from sbase
Diffstat:
| M | Makefile | | | 1 | + | 
| A | id.1 | | | 18 | ++++++++++++++++++ | 
| A | id.c | | | 132 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
3 files changed, 151 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -27,6 +27,7 @@ SRC = \
 	free.c              \
 	getty.c             \
 	halt.c              \
+	id.c                \
 	insmod.c            \
 	lsmod.c             \
 	lsusb.c             \
diff --git a/id.1 b/id.1
@@ -0,0 +1,18 @@
+.TH ID 1 sbase\-VERSION
+.SH NAME
+id \- print real and effective user and group IDs
+.SH SYNOPSIS
+.B id
+.RB [ -G ]
+.RB [ user | uid ]
+.SH DESCRIPTION
+Print user and group information of the calling process to standard output.
+If a login name or uid is specified, the user and group information of that
+user is displayed.
+.SH OPTIONS
+.TP
+.B \-G
+Display group information as whitespace separated numbers, in no particular
+order.
+.SH SEE ALSO
+.IR who(1)
diff --git a/id.c b/id.c
@@ -0,0 +1,132 @@
+/* See LICENSE file for copyright and license details. */
+#include <sys/types.h>
+#include <errno.h>
+#include <unistd.h>
+#include <pwd.h>
+#include <grp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <ctype.h>
+#include "util.h"
+
+static void groupid(struct passwd *pw);
+static void user(struct passwd *pw);
+static void userid(uid_t id);
+static void usernam(const char *nam);
+
+static void
+usage(void)
+{
+	eprintf("usage: %s [-G] [user | uid]\n", argv0);
+}
+
+static int Gflag = 0;
+
+int
+main(int argc, char *argv[])
+{
+	ARGBEGIN {
+	case 'G':
+		Gflag = 1;
+		break;
+	default:
+		usage();
+	} ARGEND;
+
+	errno = 0;
+	switch (argc) {
+	case 0:
+		userid(getuid());
+		break;
+	case 1:
+		/* user names can't begin [0-9] */
+		if (isdigit(argv[0][0]))
+			userid(estrtol(argv[0], 0));
+		else
+			usernam(argv[0]);
+		break;
+	default:
+		usage();
+	}
+
+	return EXIT_SUCCESS;
+}
+
+static void
+groupid(struct passwd *pw)
+{
+	gid_t gid, groups[NGROUPS_MAX];
+	int ngroups;
+	int i;
+
+	ngroups = NGROUPS_MAX;
+	getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
+	for (i = 0; i < ngroups; i++) {
+		gid = groups[i];
+		printf("%u", gid);
+		if (i < ngroups - 1)
+			putchar(' ');
+	}
+	putchar('\n');
+}
+
+static void
+usernam(const char *nam)
+{
+	struct passwd *pw;
+
+	errno = 0;
+	pw = getpwnam(nam);
+	if (errno != 0)
+		eprintf("getpwnam %s:", nam);
+	else if (!pw)
+		eprintf("getpwnam %s: no such user\n", nam);
+	if (Gflag)
+		groupid(pw);
+	else
+		user(pw);
+}
+
+static void
+userid(uid_t id)
+{
+	struct passwd *pw;
+
+	errno = 0;
+	pw = getpwuid(id);
+	if (errno != 0)
+		eprintf("getpwuid %d:", id);
+	else if (!pw)
+		eprintf("getpwuid %d: no such user\n", id);
+	if (Gflag)
+		groupid(pw);
+	else
+		user(pw);
+}
+
+static void
+user(struct passwd *pw)
+{
+	struct group *gr;
+	gid_t gid, groups[NGROUPS_MAX];
+	int ngroups;
+	int i;
+
+	printf("uid=%u(%s)", pw->pw_uid, pw->pw_name);
+	printf(" gid=%u", pw->pw_gid);
+	if (!(gr = getgrgid(pw->pw_gid)))
+		eprintf("getgrgid:");
+	printf("(%s)", gr->gr_name);
+
+	ngroups = NGROUPS_MAX;
+	getgrouplist(pw->pw_name, pw->pw_gid, groups, &ngroups);
+	for (i = 0; i < ngroups; i++) {
+		gid = groups[i];
+		printf("%s%u", !i ? " groups=" : ",", gid);
+		if (!(gr = getgrgid(gid)))
+			eprintf("getgrgid:");
+		printf("(%s)", gr->gr_name);
+	}
+	putchar('\n');
+}