Prevent "`bootp_down' was declared implicitly `extern' and later `static'" warning
[oweals/busybox.git] / patches / id_groups_alias.patch
1 Index: coreutils/Config.in
2 ===================================================================
3 RCS file: /var/cvs/busybox/coreutils/Config.in,v
4 retrieving revision 1.24
5 diff -u -r1.24 Config.in
6 --- a/coreutils/Config.in       15 Mar 2004 08:28:19 -0000      1.24
7 +++ b/coreutils/Config.in       1 May 2004 11:39:04 -0000
8 @@ -218,6 +218,14 @@
9         help
10           id displays the current user and group ID names.
11  
12 +config CONFIG_FEATURE_ID_GROUPS_ALIAS
13 +       bool "  Support 'groups' as alias to 'id -Gn'"
14 +       default y
15 +       depends on CONFIG_ID
16 +       help
17 +         Print the groups a user is in.  This is an alias to 'id -Gn' on
18 +         most systems.
19 +
20  config CONFIG_INSTALL
21         bool "install"
22         default n
23 Index: coreutils/id.c
24 ===================================================================
25 RCS file: /var/cvs/busybox/coreutils/id.c,v
26 retrieving revision 1.24
27 diff -u -r1.24 id.c
28 --- a/coreutils/id.c    15 Mar 2004 08:28:20 -0000      1.24
29 +++ b/coreutils/id.c    1 May 2004 11:39:05 -0000
30 @@ -3,6 +3,8 @@
31   * Mini id implementation for busybox
32   *
33   * Copyright (C) 2000 by Randolph Chung <tausq@debian.org>
34 + * Copyright (C) 2004 by Tony J. White <tjw@tjw.org>
35 + * Copyright (C) 2004 by Glenn McGrath <bug1@iinet.net.au>
36   *
37   * This program is free software; you can redistribute it and/or modify
38   * it under the terms of the GNU General Public License as published by
39 @@ -20,7 +22,6 @@
40   *
41   */
42  
43 -/* BB_AUDIT SUSv3 _NOT_ compliant -- option -G is not currently supported. */
44  
45  #include "busybox.h"
46  #include <stdio.h>
47 @@ -33,78 +34,153 @@
48  #include <flask_util.h>
49  #endif
50  
51 -#define JUST_USER         1
52 -#define JUST_GROUP        2
53 -#define PRINT_REAL        4
54 -#define NAME_NOT_NUMBER   8
55 +#define ID_OPT_JUST_USER       1
56 +#define ID_OPT_JUST_GROUP      2
57 +#define ID_OPT_ALL_GROUPS      4
58 +#define ID_OPT_PRINT_REAL      8
59 +#define ID_OPT_NAME_NOT_NUMBER 16
60 +
61 +static void print_groups(unsigned long flags, const char sep)
62 +{
63 +       gid_t gids[64];
64 +       int gid_count;
65 +       int i;
66 +
67 +       gid_count = getgroups(64, gids);
68 +       
69 +       for (i = 0; i < gid_count; i++) {
70 +               struct group *tmp_grp;
71 +
72 +               if (i != 0) {
73 +                       putchar(sep);
74 +               }
75 +               tmp_grp = getgrgid(gids[i]);
76 +               if (flags & ID_OPT_NAME_NOT_NUMBER) {
77 +                       if (tmp_grp == NULL) {
78 +                               continue;
79 +                       }
80 +                       printf("%s", tmp_grp->gr_name);
81 +               } else {
82 +                       printf("%u", gids[i]);
83 +                       if (!(flags & ID_OPT_ALL_GROUPS)) {
84 +                               if (tmp_grp == NULL) {
85 +                                       continue;
86 +                               }
87 +                               printf("(%s)", tmp_grp->gr_name);
88 +                       }
89 +               }
90 +       }
91 +}
92  
93  extern int id_main(int argc, char **argv)
94  {
95 -       char user[9], group[9];
96 -       long pwnam, grnam;
97 -       int uid, gid;
98 -       int flags;
99 +       struct group *grp;
100 +       struct passwd *usr;
101 +       unsigned long flags;
102 +       uid_t uid;
103 +       uid_t gid;
104 +       uid_t euid;
105 +       uid_t egid;
106  #ifdef CONFIG_SELINUX
107         int is_flask_enabled_flag = is_flask_enabled();
108  #endif
109  
110 -       flags = bb_getopt_ulflags(argc, argv, "ugrn");
111 +       bb_opt_complementaly = "u~gG:g~uG:G~ug:~n";
112 +       flags = bb_getopt_ulflags(argc, argv, "ugGrn");
113  
114 -       if (((flags & (JUST_USER | JUST_GROUP)) == (JUST_USER | JUST_GROUP))
115 -               || (argc > optind + 1)
116 -       ) {
117 +       /* Check one and only one context option was given */
118 +       if ((flags & 0x80000000UL) ||
119 +               (flags & (ID_OPT_PRINT_REAL | ID_OPT_ALL_GROUPS)) ||
120 +               ((flags & (ID_OPT_PRINT_REAL | ID_OPT_NAME_NOT_NUMBER)) ==
121 +                       (ID_OPT_PRINT_REAL | ID_OPT_NAME_NOT_NUMBER))) {
122                 bb_show_usage();
123         }
124  
125 +#ifdef CONFIG_FEATURE_ID_GROUPS_ALIAS
126 +       /* groups command is an alias for 'id -Gn' */
127 +       if (bb_applet_name[0] == 'g') {
128 +               flags |= (ID_OPT_ALL_GROUPS + ID_OPT_NAME_NOT_NUMBER);
129 +       }
130 +#endif
131 +
132 +       uid = getuid();
133 +       gid = getgid();
134 +       euid = geteuid();
135 +       egid = getegid();
136 +
137 +       if (flags & ID_OPT_PRINT_REAL) {
138 +               euid = uid;
139 +               egid = gid;
140 +       }
141 +
142         if (argv[optind] == NULL) {
143 -               if (flags & PRINT_REAL) {
144 -                       uid = getuid();
145 -                       gid = getgid();
146 -               } else {
147 -                       uid = geteuid();
148 -                       gid = getegid();
149 -               }
150 -               my_getpwuid(user, uid);
151 +               usr = getpwuid(euid);
152 +               grp = getgrgid(egid);
153         } else {
154 -               safe_strncpy(user, argv[optind], sizeof(user));
155 -           gid = my_getpwnamegid(user);
156 +               usr = getpwnam(argv[optind]);
157 +               grp = getgrnam(argv[optind]);
158         }
159 -       my_getgrgid(group, gid);
160  
161 -       pwnam=my_getpwnam(user);
162 -       grnam=my_getgrnam(group);
163 +       if (usr == NULL) {
164 +               bb_perror_msg_and_die("cannot find user name");
165 +       }
166 +       if (grp == NULL) {
167 +               bb_perror_msg_and_die("cannot find group name");
168 +       }
169  
170 -       if (flags & (JUST_GROUP | JUST_USER)) {
171 -               char *s = group;
172 -               if (flags & JUST_USER) {
173 -                       s = user;
174 -                       grnam = pwnam;
175 +       if (flags & ID_OPT_JUST_USER) {
176 +               if (flags & ID_OPT_NAME_NOT_NUMBER) {
177 +                       printf("%s", grp->gr_name);
178 +               } else {
179 +                       printf("%u", euid);
180                 }
181 -               if (flags & NAME_NOT_NUMBER) {
182 -                       puts(s);
183 +       }
184 +       else if (flags & ID_OPT_JUST_GROUP) {
185 +               if (flags & ID_OPT_NAME_NOT_NUMBER) {
186 +                       printf("%s", grp->gr_name);
187                 } else {
188 -                       printf("%ld\n", grnam);
189 +                       printf("%u", egid);
190                 }
191 +       }
192 +       else if (flags & ID_OPT_ALL_GROUPS) {
193 +               print_groups(flags, ' ');
194         } else {
195 -#ifdef CONFIG_SELINUX
196 -               printf("uid=%ld(%s) gid=%ld(%s)", pwnam, user, grnam, group);
197 -               if(is_flask_enabled_flag)
198 -               {
199 -                       security_id_t mysid = getsecsid();
200 -                       char context[80];
201 -                       int len = sizeof(context);
202 -                       context[0] = '\0';
203 -                       if(security_sid_to_context(mysid, context, &len))
204 -                               strcpy(context, "unknown");
205 -                       printf(" context=%s\n", context);
206 -               }
207 -               else
208 -                       printf("\n");
209 -#else
210 -               printf("uid=%ld(%s) gid=%ld(%s)\n", pwnam, user, grnam, group);
211 -#endif
212 +               printf("uid=%u(%s) gid=%u(%s)", uid, usr->pw_name, gid, grp->gr_name);
213 +               if (uid != euid) {
214 +                       struct passwd *eusr;
215 +                       printf(" euid=%u", euid);
216 +                       eusr = getpwuid(euid);
217 +                       if (eusr != NULL) {
218 +                               printf("(%s)", eusr->pw_name);
219 +                       }
220 +               }
221 +               if (gid != egid) {
222 +                       struct group *egrp;
223 +                       printf(" egid=%u", egid);
224 +                       egrp = getgrgid(egid);
225 +                       if (egrp != NULL) {
226 +                               printf("(%s)", egrp->gr_name);
227 +                       }
228 +               }
229 +               printf(" groups=");
230 +               print_groups(flags, ',');
231 +       }
232  
233 +#ifdef CONFIG_SELINUX
234 +       if (is_flask_enabled_flag)
235 +       {
236 +               security_id_t mysid = getsecsid();
237 +               char context[80];
238 +               int len = sizeof(context);
239 +
240 +               context[0] = '\0';
241 +               if (security_sid_to_context(mysid, len, &len)) {
242 +                       strcpy(context, "unknown");
243 +               }
244 +               printf(" context=%s", context);
245         }
246 +#endif
247  
248 +       putchar('\n');
249         bb_fflush_stdout_and_exit(0);
250  }
251 Index: include/applets.h
252 ===================================================================
253 RCS file: /var/cvs/busybox/include/applets.h,v
254 retrieving revision 1.113
255 diff -u -r1.113 applets.h
256 --- a/include/applets.h 6 Apr 2004 16:59:43 -0000       1.113
257 +++ b/include/applets.h 1 May 2004 11:39:06 -0000
258 @@ -232,6 +232,9 @@
259  #ifdef CONFIG_GREP
260         APPLET(grep, grep_main, _BB_DIR_BIN, _BB_SUID_NEVER)
261  #endif
262 +#if defined(CONFIG_FEATURE_ID_GROUPS_ALIAS)
263 +       APPLET(groups, id_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
264 +#endif
265  #ifdef CONFIG_GUNZIP
266         APPLET(gunzip, gunzip_main, _BB_DIR_BIN, _BB_SUID_NEVER)
267  #endif
268 Index: include/usage.h
269 ===================================================================
270 RCS file: /var/cvs/busybox/include/usage.h,v
271 retrieving revision 1.207
272 diff -u -r1.207 usage.h
273 --- a/include/usage.h   14 Apr 2004 17:59:21 -0000      1.207
274 +++ b/include/usage.h   1 May 2004 11:39:10 -0000
275 @@ -800,6 +800,16 @@
276         "$ grep ^[rR]oo. /etc/passwd\n" \
277         "root:x:0:0:root:/root:/bin/bash\n"
278  
279 +#define groups_trivial_usage \
280 +       " [USERNAME]"
281 +#define groups_full_usage \
282 +       "Print all group names that USERNAME is a member of." 
283 +#define groups_example_usage \
284 +       "$ groups\n" \
285 +       "andersen users\n" \
286 +       "$ groups tjw\n" \
287 +       "tjw users\n"
288 +
289  #define gunzip_trivial_usage \
290         "[OPTION]... FILE"
291  #define gunzip_full_usage \
292 @@ -1035,7 +1045,7 @@
293  #endif
294  
295  #define id_trivial_usage \
296 -       "[OPTIONS]... [USERNAME]"
297 +       "[-Ggu[nr]]] [USERNAME]"
298  #define id_full_usage \
299         "Print information for USERNAME or the current user\n\n" \
300         "Options:\n" \
301 @@ -1043,10 +1053,11 @@
302         "\t-g\tprints only the group ID\n" \
303         "\t-u\tprints only the user ID\n" \
304         "\t-n\tprint a name instead of a number\n" \
305 -       "\t-r\tprints the real user ID instead of the effective ID"
306 +       "\t-r\tprints the real user ID instead of the effective ID\n" \
307 +       "\t-G\tprints all groups the user belongs to"
308  #define id_example_usage \
309         "$ id\n" \
310 -       "uid=1000(andersen) gid=1000(andersen)\n"
311 +       "uid=1000(andersen) gid=1000(andersen) groups=1000(andersen),100(users)\n"
312  
313  #ifdef CONFIG_FEATURE_IFCONFIG_SLIP
314    #define USAGE_SIOCSKEEPALIVE(a) a