utils/src/id.c

295 lines
6.2 KiB
C

/* $Id$ */
/* Copyright (c) 2007 Pierre Pronchery <khorben@defora.org> */
/* This file is part of DeforaOS Unix utils */
/* utils is not free software; you can redistribute it and/or modify it under
* the terms of the Creative Commons Attribution-NonCommercial-ShareAlike 3.0
* Unported as published by the Creative Commons organization.
*
* utils 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 Creative Commons Attribution-NonCommercial-
* ShareAlike 3.0 Unported license for more details.
*
* You should have received a copy of the Creative Commons Attribution-
* NonCommercial-ShareAlike 3.0 along with utils; if not, browse to
* http://creativecommons.org/licenses/by-nc-sa/3.0/ */
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
/* id */
static int _id_error(char const * message, int ret);
static int _id_G(char * user, int flagn);
static int _id_g(char const * user, int flagn, int flagr);
static int _id_u(char const * user, int flagn, int flagr);
static int _id_all(char * user);
static int _id(char * user, int flag, int flagn, int flagr)
{
if(flag == 'G')
return _id_G(user, flagn);
if(flag == 'g')
return _id_g(user, flagn, flagr);
if(flag == 'u')
return _id_u(user, flagn, flagr);
return _id_all(user);
}
/* _id_error */
static int _id_error(char const * message, int ret)
{
fputs("id: ", stderr);
perror(message);
return ret;
}
/* _id_G */
static int _id_G(char * user, int flagn)
{
struct group * gr;
char ** p;
if(user == NULL)
{
if((gr = getgrgid(getegid())) == NULL)
return _id_error("getgrgid", 1);
if(getegid() != getgid())
{
if(flagn == 0)
printf("%u %u", (unsigned)getegid(),
(unsigned)getgid());
else
{
puts(gr->gr_name);
if((gr = getgrgid(getgid())) == NULL)
{
putc('\n', stdout);
return _id_error("getgrgid", 1);
}
printf(" %s", gr->gr_name);
}
}
else
{
if(flagn == 0)
printf("%u", (unsigned)getgid());
else
puts(gr->gr_name);
}
}
else
{
if((gr = getgrnam(user)) == NULL)
return _id_error(user, 1);
if(flagn == 0)
printf("%u", (unsigned)gr->gr_gid);
else
puts(gr->gr_name);
}
if((user = strdup(gr->gr_name)) == NULL)
return _id_error("strdup", 1);
setgrent();
for(gr = getgrent(); gr != NULL; gr = getgrent())
{
for(p = gr->gr_mem; *p != NULL; p++)
{
if(strcmp(user, *p) == 0)
{
if(flagn == 0)
printf(" %u", (unsigned)gr->gr_gid);
else
printf(" %s", gr->gr_name);
}
}
}
putc('\n', stdout);
endgrent();
free(user);
return 0;
}
/* _id_g */
static int _id_g(char const * user, int flagn, int flagr)
{
struct group * gr;
if(user == NULL)
{
if(flagn == 0)
{
printf("%u\n", flagr ? (unsigned)getegid()
: (unsigned)getgid());
return 0;
}
if((gr = getgrgid(flagr ? getegid() : getgid())) == NULL)
return _id_error("getgrgid", 1);
printf("%s\n", gr->gr_name);
return 0;
}
if((gr = getgrnam(user)) == NULL)
return _id_error("getgrnam", 1);
if(flagn == 0)
printf("%u\n", (unsigned)gr->gr_gid);
else
printf("%s\n", gr->gr_name);
return 0;
}
/* _id_u */
static int _id_u(char const * user, int flagn, int flagr)
{
struct passwd * passwd;
if(user == NULL)
{
if(flagn == 0)
{
printf("%u\n", flagr ? geteuid() : getuid());
return 0;
}
if((passwd = getpwuid(flagr ? geteuid() : getuid())) == NULL)
return _id_error("getpwuid", 1);
printf("%s\n", passwd->pw_name);
return 0;
}
if((passwd = getpwnam(user)) == NULL)
return _id_error("getpwnam", 1);
if(flagn == 0)
printf("%u\n", passwd->pw_uid);
else
printf("%s\n", passwd->pw_name);
return 0;
}
/* _id_all */
static struct group * _print_gid(gid_t gid);
static int _id_all(char * user)
{
struct passwd * pw;
struct group * gr;
char ** p;
if(user == NULL)
{
if((pw = getpwuid(getuid())) == NULL)
{
putc('\n', stdout);
return _id_error("geteuid", 1);
}
printf("uid=%u(%s) ", (unsigned)pw->pw_uid, pw->pw_name);
if((gr = _print_gid(pw->pw_gid)) == NULL)
return 1;
if((user = strdup(gr->gr_name)) == NULL)
{
putc('\n', stdout);
return _id_error("strdup", 1);
}
if(geteuid() != getuid())
{
if((pw = getpwuid(geteuid())) == NULL)
{
putc('\n', stdout);
return _id_error("geteuid", 1);
}
printf(" euid=%u(%s) e", (unsigned)pw->pw_uid,
pw->pw_name);
if(_print_gid(pw->pw_gid) == NULL)
return 1;
}
}
else
{
if((pw = getpwnam(user)) == NULL)
return _id_error("getpwnam", 1);
printf("uid=%u(%s) ", (unsigned)pw->pw_uid, pw->pw_name);
if((gr = _print_gid(pw->pw_gid)) == NULL)
return 1;
if((user = strdup(gr->gr_name)) == NULL)
{
putc('\n', stdout);
return _id_error("strdup", 1);
}
}
printf("%s%u(%s)", " groups=", (unsigned)pw->pw_gid, user);
setgrent();
for(gr = getgrent(); gr != NULL; gr = getgrent())
for(p = gr->gr_mem; *p != NULL; p++)
if(strcmp(user, *p) == 0)
printf(",%u(%s)", (unsigned)gr->gr_gid,
gr->gr_name);
putc('\n', stdout);
endgrent();
free(user);
return 0;
}
/* _print_gid */
static struct group * _print_gid(gid_t gid)
{
struct group * gr;
if((gr = getgrgid(gid)) == NULL)
{
putc('\n', stdout);
_id_error("getgrgid", 0);
}
else
printf("gid=%u(%s)", gr->gr_gid, gr->gr_name);
return gr;
}
/* usage */
static int _usage(void)
{
fputs("Usage: id [-Ggu][-nr] [user]\n\
-G output all different group IDs\n\
-g output only the effective group ID\n\
-u output only the effective user ID\n\
-n output the name as a string\n\
-r output the real ID instead of the effective ID\n", stderr);
return 1;
}
/* main */
int main(int argc, char * argv[])
{
int o;
int flag = 0;
int flagn = 0;
int flagr = 0;
while((o = getopt(argc, argv, "Ggunr")) != -1)
switch(o)
{
case 'G':
case 'g':
case 'u':
flag = o;
break;
case 'n':
flagn = 1;
break;
case 'r':
flagr = 1;
break;
default:
return _usage();
}
if(optind == argc)
return _id(NULL, flag, flagn, flagr) == 0 ? 0 : 2;
if(optind + 1 == argc)
return _id(argv[optind], flag, flagn, flagr) == 0 ? 0 : 2;
return _usage();
}