/* $Header: uid.c,v 2.1 89/06/09 12:25:41 network Exp $
 *
 * I wish the System V "id" program were universally available; but it
 * isn't, so I've written this replacement.
 *
 * usage: uid [-options]
 *
 * Default action is to print one line in the manner of "id":
 *      uid=201(chip) gid=50(group) euid=0(root) egid=0(root)
 * (Note that the "euid" and "egid" entries are not output if they are
 * the same as the "uid" and "gid" values.)
 *
 * If an option string is specified, it disables the normal behavior in
 * favor of displaying id information, one per line, in the order that
 * the options appear in the option string.  Legal options are:
 *      u       real uid
 *      g       real gid
 *      U       effective uid
 *      G       effective gid
 *
 * NOTE: This program is not a paragon of good style.
 *       It's just something I needed for a Makefile.
 *
 * $Log:	uid.c,v $
 * Revision 2.1  89/06/09  12:25:41  network
 * Update RCS revisions.
 * 
 * Revision 1.3  89/06/09  12:24:00  network
 * Baseline for 2.0 release.
 * 
 */

#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include "config.h"

#ifdef NULL
#undef NULL
#endif
#define NULL 0

extern  struct passwd   *getpwuid();
extern  struct group    *getgrgid();

char    *progname = "uid";

char    *uid_desc();
char    *gid_desc();

main(argc, argv)
int     argc;
char    **argv;
{
	int     uid, gid, euid, egid;
	int     c, lines, errcount;

	uid = getuid();
	gid = getgid();
	euid = geteuid();
	egid = getegid();

	errcount = 0;
	lines = 0;

	while ((c = getopt(argc, argv, "ugUG")) != EOF)
	{
		switch (c)
		{
		case 'u':
			(void) printf("%s\n", uid_desc(uid));
			++lines;
			break;

		case 'g':
			(void) printf("%s\n", gid_desc(gid));
			++lines;
			break;

		case 'U':
			(void) printf("%s\n", uid_desc(euid));
			++lines;
			break;

		case 'G':
			(void) printf("%s\n", gid_desc(egid));
			++lines;
			break;

		case '?':
			++errcount;
			break;
		}
	}

	if (errcount)
	{
		(void) fprintf(stderr, "usage: uid [-ugUG]\n");
		exit(1);
	}

	if (lines == 0)
	{
		(void) printf("uid=%s", uid_desc(uid));
		(void) printf(" gid=%s", gid_desc(gid));

		if (euid != uid)
			(void) printf(" euid=%s", uid_desc(euid));
		if (egid != gid)
			(void) printf(" egid=%s", gid_desc(egid));

		(void) printf("\n");
	}

	exit(0);
	/* NOTREACHED */
}

char *
uid_desc(uid)
int     uid;
{
	struct passwd *pw;
	static char buf[80];

	(void) sprintf(buf, "%d", uid);
	if ((pw = getpwuid(uid)) != NULL)
		(void) sprintf(buf + strlen(buf), "(%s)", pw->pw_name);

	return buf;
}

char *
gid_desc(gid)
int     gid;
{
	struct group *gr;
	static char buf[80];

	(void) sprintf(buf, "%d", gid);
	if ((gr = getgrgid(gid)) != NULL)
		(void) sprintf(buf + strlen(buf), "(%s)", gr->gr_name);

	return buf;
}
