2024-07-09 11:02:46 +03:00

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);
}