id by Chris Simmons

Just a small note about 'id'... All testing I've been able to perform on my machine in compiling it was done under BONE.

Seeing as how BeOS does not have true multi-user yet, it was impossible for me to simulate the usage of multiple users, groups, the group list functions.

It appears to work as intended, reporting the ID and NAME of the current and requested USERNAME, but further testing is required to be sure.

I've removed the -a argument, and implemented as best as I could this spec:

http://www.opengroup.org/onlinepubs/007904975/utilities/id.html

No effort has been made yet to deal with posix LOCALE issues, yet.


git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6364 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Phil Greenway
2004-01-27 21:02:18 +00:00
parent ce5d0dee99
commit 0202a6eb59
+312
View File
@@ -0,0 +1,312 @@
/*
** Copyright (c) 2004 OBOS
** Permission is hereby granted, free of charge, to any person obtaining a copy
** of this software and associated documentation files (the "Software"), to deal
** in the Software without restriction, including without limitation the rights
** to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
** copies of the Software, and to permit persons to whom the Software is
** furnished to do so, subject to the following conditions:
**
** The above copyright notice and this permission notice shall be included in all
** copies or substantial portions of the Software.
**
** THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
** IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
** FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
** AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
** LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
** OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
** SOFTWARE.
*/
#include <sys/stat.h>
#include <errno.h>
#include <getopt.h>
#include <grp.h>
#include <pwd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
static void print_user_info(int userID, char *suffix);
static void print_group_info(int groupID, char *suffix);
static void print_group_list(int listID);
static void print_combined_info(void);
static void suggest_help(void);
static void usage(void);
static void version(void);
char *progName;
static int gFlag, glFlag, nFlag, rFlag, uFlag;
struct passwd *euidName;
struct passwd *ruidName;
struct group *egidName;
struct group *rgidName;
uid_t eUID;
uid_t rUID;
gid_t eGID;
gid_t rGID;
gid_t groupList;
char *suffix;
static void
print_user_info(int userID, char *suffix) {
struct stat statBuffer;
struct passwd *userIDName;
if ((userIDName = getpwuid(userID)) != NULL) {
if (nFlag)
fprintf(stdout, "%s%s", userIDName->pw_name, suffix);
else
fprintf(stdout, "%u%s", eUID, suffix);
} else
fprintf(stdout, "%-8d%s", statBuffer.st_uid, suffix);
}
static void
print_group_info(int groupID, char *suffix) {
struct stat statBuffer;
struct group *groupIDName;
if ((groupIDName = getgrgid(groupID)) != NULL) {
if (nFlag)
fprintf(stdout, "%s%s", groupIDName->gr_name, suffix);
else
fprintf(stdout, "%u%s", groupID, suffix);
} else
fprintf(stdout, " %-8d%s", statBuffer.st_gid, suffix);
}
static void
print_group_list(int groupID) {
int cnt, id, lastID, nGroups;
gid_t *groups;
long ngroups_max;
ngroups_max = sysconf(NGROUPS_MAX) + 1;
groups = (gid_t *)malloc(ngroups_max *sizeof(gid_t));
nGroups = getgroups(ngroups_max, groups);
suffix = "";
print_group_info(groupID, suffix);
for (lastID = -1, cnt = 0; cnt < ngroups_max; ++cnt) {
if (lastID == (id = groups[cnt]))
continue;
suffix = " ";
print_group_info(id, suffix);
lastID = id;
}
fprintf(stdout, "\n");
}
static void
print_combined_info() {
if ( eUID != rUID ) {
suffix = "";
rFlag = 1;
fprintf(stdout, "uid=");
print_user_info(rUID, suffix);
fprintf(stdout, "(");
nFlag = 1;
print_user_info(rUID, suffix);
fprintf(stdout, ") gid=");
rFlag = 1; nFlag = 0;
print_group_info(rGID, suffix);
fprintf(stdout, "(");
rFlag = 0; nFlag = 1;
print_group_info(eGID, suffix);
fprintf(stdout, ") euid=");
rFlag = 0; nFlag = 0;
print_user_info(eUID, suffix);
fprintf(stdout, "(");
rFlag = 0; nFlag = 1;
print_user_info(eUID, suffix);
fprintf(stdout, ")\n");
} else {
suffix = "";
rFlag = 1;
fprintf(stdout, "uid=");
print_user_info(rUID, suffix);
fprintf(stdout, "(");
nFlag = 1;
print_user_info(rUID, suffix);
fprintf(stdout, ") gid=");
rFlag = 1; nFlag = 0;
print_group_info(rGID, suffix);
fprintf(stdout, "(");
rFlag = 1; nFlag = 1;
print_group_info(rGID, suffix);
fprintf(stdout, ")\n");
}
}
static void
suggest_help(void)
{
(void)fprintf(stdout, "Try `%s --help' for more information.\n", progName);
}
static void
usage(void)
{
fprintf(stdout,
"%s OBOS (http://www.openbeos.org/)
Usage: %s [OPTION]... [USERNAME]
-g, --group print only the group ID
-G, --groups print only the supplementary groups
-n, --name print a name instead of a number, for -ugG
-r, --real print the real ID instead of effective ID, for -ugG
-u, --user print only the user ID
--help display this help and exit
--version output version information and exit
Print information for USERNAME, or the current user.
", progName, progName );
}
static void
version(void)
{
fprintf(stdout, "%s OBOS (http://www.openbeos.org/)\n", progName);
}
int
main(int argc, char *argv[])
{
int argOption;
int indexptr = 0;
char * const * optargv = argv;
struct option groupOption = { "group", no_argument, 0, 1 } ;
struct option groupsOption = { "groups", no_argument, 0, 2 } ;
struct option nameOption = { "name", no_argument, 0, 3 } ;
struct option realOption = { "real", no_argument, 0, 4 } ;
struct option userOption = { "user", no_argument, 0, 5 } ;
struct option helpOption = { "help", no_argument, 0, 6 } ;
struct option versionOption = { "version", no_argument, 0, 7 } ;
struct option options[] = {
groupOption, groupsOption, nameOption, realOption, userOption, helpOption, versionOption, {0}
};
struct passwd *suppliedName;
gFlag = glFlag = nFlag = rFlag = uFlag = 0;
progName = argv[0]; // don't put this before or between structs! werrry bad things happen. ;)
while ((argOption = getopt_long(argc, optargv, "gGnru", options, &indexptr)) != -1) {
switch (argOption) {
case 'g':
gFlag = 1;
break;
case 'G':
glFlag = 1;
break;
case 'n':
nFlag = 1;
break;
case 'r':
rFlag = 1;
break;
case 'u':
uFlag = 1;
break;
default:
switch (options[indexptr].val) {
case 6: // help
usage();
exit(0);
case 7: // version
version();
exit(0);
default:
suggest_help();
exit(0);
}
break;
}
}
if (argc - optind > 1)
usage();
if (argc - optind == 1) {
suppliedName = getpwnam(argv[optind]);
if (suppliedName == NULL) {
fprintf(stderr, "%s: %s: No such user\n", progName, argv[optind]);
suggest_help();
exit(1);
}
rUID = eUID = suppliedName->pw_uid;
rGID = eGID = suppliedName->pw_gid;
} else {
eUID = geteuid ();
rUID = getuid ();
eGID = getegid ();
rGID = getgid ();
euidName = getpwuid(eUID);
ruidName = getpwuid(rUID);
egidName = getgrgid(eGID);
rgidName = getgrgid(rGID);
}
if ( gFlag + glFlag + uFlag > 1 ) {
fprintf(stderr, "%s: cannot print only user and only group\n", progName);
suggest_help();
exit(1);
}
if ( gFlag + glFlag + uFlag == 0 && (rFlag || nFlag)) {
fprintf(stderr, "%s: cannot print only names or real IDs in default format\n", progName);
suggest_help();
exit(1);
}
if (gFlag) {
// group information
suffix = "\n";
if (rFlag)
print_group_info(rUID, suffix);
else
print_group_info(eUID, suffix);
exit(0);
}
if (glFlag) {
// group list
if (rFlag)
print_group_list(rUID);
else
print_group_list(eUID);
exit(0);
}
if (uFlag) {
// user information
suffix = "\n";
if (rFlag)
print_user_info(rUID, suffix);
else
print_user_info(eUID, suffix);
exit(0);
}
// no arguments? print combined info.
print_combined_info();
return B_NO_ERROR;
}