131 lines
2.2 KiB
C
131 lines
2.2 KiB
C
#include <grp.h>
|
|
#include <pwd.h>
|
|
#include <stdio.h>
|
|
#include <errno.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <limits.h>
|
|
#include <sys/types.h>
|
|
|
|
char g_flag;
|
|
char G_flag;
|
|
char n_flag;
|
|
char r_flag;
|
|
char u_flag;
|
|
|
|
int print_groups(const struct passwd *pwd, const char *fmt, const int flag) {
|
|
gid_t groups[NGROUPS_MAX];
|
|
int ngroups = NGROUPS_MAX;
|
|
if (getgrouplist(pwd->pw_name, pwd->pw_gid, groups, &ngroups) < 0)
|
|
return 1;
|
|
|
|
for (int i = 0; i < ngroups; i++) {
|
|
struct group *grp = getgrgid(groups[i]);
|
|
if (grp && !n_flag)
|
|
printf("%u", groups[i]);
|
|
|
|
if ((!r_flag && n_flag) || flag)
|
|
printf(fmt, grp->gr_name);
|
|
|
|
if (g_flag && i == 0)
|
|
break;
|
|
|
|
putchar(' ');
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int ids(uid_t uid, struct passwd *pwd) {
|
|
if (u_flag) {
|
|
if (n_flag)
|
|
printf("%s", pwd->pw_name);
|
|
|
|
else
|
|
printf("%u", uid);
|
|
}
|
|
|
|
else if (G_flag || g_flag)
|
|
print_groups(pwd, "%s", 0);
|
|
|
|
putchar('\n');
|
|
return 0;
|
|
}
|
|
|
|
int def_ids(uid_t uid, struct passwd *pwd) {
|
|
printf("uid=%d(%s) gid=%d", uid, pwd->pw_name, pwd->pw_gid);
|
|
struct group *grp = getgrgid(pwd->pw_gid);
|
|
if (grp)
|
|
printf("(%s)", grp->gr_name);
|
|
|
|
printf(" groups=");
|
|
print_groups(pwd, "(%s)", 1);
|
|
|
|
putchar('\n');
|
|
return 0;
|
|
}
|
|
|
|
void usage(int sig) {
|
|
puts("id [gGurn] [user]\n\t-u User ID\n\t-g Group ID\n\t-G Supplementary group IDs\n\t-n Print names instead of numbers\n\t-r Print real ID instead of effective ID");
|
|
exit(sig);
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
int opt;
|
|
while ((opt = getopt(argc, argv, "gGnru")) != -1) {
|
|
switch (opt) {
|
|
case 'g':
|
|
if (G_flag || u_flag)
|
|
usage(1);
|
|
|
|
g_flag = 1;
|
|
break;
|
|
|
|
case 'G':
|
|
if (g_flag || u_flag)
|
|
usage(1);
|
|
|
|
G_flag = 1;
|
|
break;
|
|
|
|
case 'u':
|
|
if (G_flag || g_flag)
|
|
usage(1);
|
|
|
|
u_flag = 1;
|
|
break;
|
|
|
|
case 'r':
|
|
r_flag = 1;
|
|
break;
|
|
|
|
case 'n':
|
|
n_flag = 1;
|
|
break;
|
|
|
|
default:
|
|
usage(0);
|
|
}
|
|
}
|
|
|
|
argv += optind;
|
|
argc -= optind;
|
|
|
|
uid_t uid = getuid();
|
|
struct passwd *pwd = getpwuid(uid);
|
|
if (argv[0] != NULL)
|
|
pwd = getpwnam(argv[0]);
|
|
|
|
if (!pwd) {
|
|
fprintf(stderr, "id: %s\n", strerror(errno));
|
|
return 1;
|
|
}
|
|
|
|
if (u_flag || G_flag || g_flag)
|
|
return ids(uid, pwd);
|
|
|
|
return def_ids(uid, pwd);
|
|
}
|