/* * program to print information about named user(s) * demonstrates mapping user name (etc.) and date * * Matt Bishop, bishop@cs.ucdavis.edu 11/9/96 */ #include #include #include #include #include #include /* * forward declarations */ void setgrent(void); /* initialize group file -- not in grp.h!!! */ void endgrent(void); /* clean up group file -- not in grp.h!!! */ int gettimeofday(struct timeval *, struct timezone *); /* get time of day */ /* * prints the current time of day */ int prdate(void) { struct timeval tod; /* time of day */ struct timezone tz; /* time zone */ char *atod; /* date as a string */ /* * get the time of day */ if (gettimeofday(&tod, &tz) < 0) return(1); /* * convert it to a string and print it */ if ((atod = ctime((time_t *)&tod.tv_sec)) == NULL) atod = "Time not available\n"; printf("%s", atod); return(0); } /* * print secondary group list * this is a list of groups the user is in * name is name of user, gid is his/her GID * if empty list, print *none* */ void prsgid(char *name, int gid) { register struct group *gp; /* points to group info */ register char **p; /* walks user list of group */ register int count = 0; /* how many groups printed */ /* * initialize group file for scan */ setgrent(); /* * loop through groups, looking for this user * in its member list */ while ((gp = getgrent()) != NULL){ for(p = gp->gr_mem; *p; p++) if (strcmp(*p, name) == 0){ /* bingo! */ printf(" %s(%d)", gp->gr_name, gp->gr_gid); count++; break; } } /* * clean up and leave */ endgrent(); if (count == 0) printf(" *none*"); } /* * given a GID gid, print the group name or *unknown* if none * also the GID. */ void grname(int gid) { struct group *gp; /* points to group info */ /* * if you find it, print it; else say *unknown* */ if ((gp = getgrgid(gid)) == NULL) printf("*unknown*(%d)\n", gid); else printf("%s(%d)\n", gp->gr_name, gid); } /* * print user information about user name; if name is number, * take as UID */ void getuinfo(char *name) { register int n = 0; /* UID if name is UID */ register char *s; /* used to check if name is UID or name */ struct passwd *pw; /* points to user info */ /* * get the user information structure */ for(s = name; *s && isdigit(*s); s++) n = n * 10 + *s - '0'; if (!*s){ /* it's an integer */ pw = getpwuid(n); } else{ /* it's not an integer */ pw = getpwnam(name); } /* * check for bad name/UID */ if (pw == NULL){ printf("%s: unknown %s\n", name, *s ? "name" : "UID"); return; } /* * now dump the user information */ printf("user name: %s\n", pw->pw_name); printf("hashed password: %s\n", pw->pw_passwd); printf("UID: %d\n", pw->pw_uid); /* do the principle GID as groupname(gid) */ printf("principle GID: "); grname(pw->pw_gid); /* do the secondary GID as a list of groupname(gid)s */ printf("secondary GIDs:"); prsgid(pw->pw_name, pw->pw_gid); putchar('\n'); printf("GECOS field: %s\n", pw->pw_gecos); printf("home directory: %s\n", pw->pw_dir); printf("login shell: %s\n", pw->pw_shell); } /* * the main routine */ int main(int argc, char *argv[]) { register int i; /* used to walk argument list */ /* * print the date */ if (prdate()){ perror(argv[0]); return(1); } /* * print the user info one user at a time * with a separating header */ for(i = 1; i < argc; i++){ printf("========== %s ==========\n", argv[i]); getuinfo(argv[i]); } return(0); }