Major `cat` improvements
[lab.git] / id.c
blobf466d881293d1467eb6bb387df59a2c40247b156
1 /* `id.c` - return user identity
2 Copyright (c) 2022, Alan Potteiger
3 See `LICENSE` for copyright and license details */
5 #define _POSIX_C_SOURCE 200809L
7 #include <stdio.h>
8 #include <unistd.h>
9 #include <errno.h>
10 #include <pwd.h>
11 #include <grp.h>
13 static const char *usage = {
14 "usage: id [user]\n"
15 "id -G [-n] [user]\n"
16 "id -g [-nr] [user]\n"
17 "id -u [-nr] [user]\n"
20 int
21 main(int argc, char *argv[])
23 char ch;
24 int all, Gflag, gflag, nflag, rflag, uflag;
25 char *user;
26 struct passwd *pwd;
27 struct group *grp;
28 uid_t uid;
29 gid_t gid;
30 gid_t *groups;
31 int ngroups;
34 all = Gflag = gflag = uflag = nflag = rflag = 0;
35 user = NULL;
36 pwd = NULL;
37 ngroups = 0;
38 groups = NULL;
40 while ((ch = getopt(argc, argv, "Ggunr")) != -1) {
41 switch (ch) {
42 case 'G':
43 Gflag = 1;
44 break;
45 case 'g':
46 gflag = 1;
47 break;
48 case 'n':
49 nflag = 1;
50 break;
51 case 'r':
52 rflag = 1;
53 break;
54 case 'u':
55 uflag = 1;
56 break;
57 case '?':
58 default:
59 fputs(usage, stderr);
60 return 1;
64 /* some options should be mutually exclusive */
65 if ((Gflag && gflag) || (Gflag && uflag) || (gflag && uflag)) {
66 fputs(usage, stderr);
67 return 1;
69 /* -n and -r are useless without any of the main flags */
70 if (Gflag == 0 && gflag == 0 && uflag == 0) {
71 if (nflag == 1 || rflag == 1) {
72 fputs(usage, stderr);
73 return 1;
75 if (nflag == 0 && rflag == 0)
76 all = 1;
79 argc -= optind;
80 argv += optind;
82 /* obtain passwd struct if user name provided */
83 if (argc > 0) {
84 user = argv[0];
85 errno = 0;
86 pwd = getpwnam(user);
87 if (pwd == NULL) {
88 if (errno != 0)
89 perror("id");
90 else
91 fprintf(stderr, "id: user %s does not exist\n",
92 user);
93 return 1;
95 } else {
96 user = getlogin();
99 if (user == NULL) {
100 fputs("id: cannot obtain login information\n", stderr);
101 return 1;
104 /* TODO: no flag functionality */
106 if (Gflag) {
107 if (pwd != NULL)
108 gid = pwd->pw_gid;
109 else {
110 gid = getgid();
113 /* TODO: Gflag functionality */
116 if (gflag) {
117 if (pwd != NULL) {
118 gid = pwd->pw_gid;
119 } else {
120 if (rflag)
121 gid = getgid();
122 else
123 gid = geteuid();
126 if (nflag) {
127 grp = getgrgid(gid);
128 printf("%s\n", grp->gr_name);
129 return 0;
132 printf("%u\n", gid);
133 return 0;
136 if (uflag) {
137 if (nflag) {
138 printf("%s\n", user);
139 return 0;
142 if (pwd != NULL) {
143 uid = pwd->pw_uid;
144 } else {
145 if (rflag)
146 uid = getuid();
147 else
148 uid = geteuid();
151 printf("%u\n", uid);
152 return 0;
155 return 0;