>From - Tue Dec 16 11:48:45 2003 X-Mozilla-Status: 8001 X-Mozilla-Status2: 00000000 Message-ID: <[EMAIL PROTECTED]> Date: Tue, 16 Dec 2003 11:47:21 -0800 From: Bruce Korb <[EMAIL PROTECTED]> Reply-To: [EMAIL PROTECTED] Sender: [EMAIL PROTECTED] X-Mailer: Mozilla 4.8 [en] (X11; U; SunOS 5.8 sun4u) X-Accept-Language: en MIME-Version: 1.0 To: [EMAIL PROTECTED] Subject: getpwnam(1) ? Content-Type: multipart/mixed; boundary="------------136311A7BB107C214BB1D637"
This is a multi-part message in MIME format. --------------136311A7BB107C214BB1D637 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Hi all, I was writing another shell script and needed a full user name (i.e., the "comment" entry from /etc/passwd). Grepping and sedding is such a nuisance, especially since there is a POSIX lib call to do the job: getwpnam(3). Why not just expose this (and other?) lib/sys calls with a wrapper program? Attached is something I threw together that has the following usage: $ getpwnam -? getpwnam - Get password entries - Ver. 1.2 USAGE: getpwnam [ -<flag> | --<name> ]... [ user-name-or-id ] -n, --name Print the user name -p, --passwd Print the (encrypted) password -u, --uid Print the user id -g, --gname Print the group name -G, --gid Print the group id -N, --gecos Print the real user name (comment string) -d, --dir Print the home directory -s, --shell Print the login shell -A, --all Print everything - prohibits these options: name passwd uid gname gid gecos dir shell -V, --verbose Verbose output -v, --version[=arg] Output version information and exit -?, --help Display usage information and exit -!, --more-help Extended usage information passed thru pager Options are specified by doubled hyphens and their name or by a single hyphen and the flag character. This command uses getpwnam(3) or getpwuid(3) to obtain the requested information from the passwd database. If a user name or user id is not provided, the information for the current user is obtained. The results are printed in the order selected. If you select no options, nothing is printed on success, but the user name/user id will have been validated. please send bug reports to: [EMAIL PROTECTED] $ getpwnam -A bkorb x 4438 fcf 119 Bruce Korb /u/bkorb /bin/ksh $ getpwnam -A -V user name: bkorb password: 'x' (encrypted) user id: 4438 group name: fcf group id: 119 full name: Bruce Korb directory: /u/bkorb login shell: /bin/ksh --------------136311A7BB107C214BB1D637 Content-Type: text/plain; charset=us-ascii; name="getpwnam.c" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="getpwnam.c" #include <sys/types.h> #include <stdlib.h> #include <errno.h> #include <grp.h> #include <limits.h> #include <pwd.h> #ifdef __sun # include <inttypes.h> #else # include <stdint.h> #endif #include "opts.h" void printInfo( struct passwd* pw ); void printInfoVerbosely( struct passwd* pw ); int main( int argc, char** argv ) { static const char zBadUser[] = "%s error: '%s' is not a valid user name or id\n"; uid_t uid = getuid(); struct passwd* pw; char* pzUser; { int ct = optionProcess( &getpwnamOptions, argc, argv ); argc -= ct; pzUser = argv[ ct ]; } switch (argc) { default: fputs( "Error: Too many command line arguments\n", stderr ); USAGE( EXIT_FAILURE ); /* NOTREACHED */ case 1: pw = getpwnam( pzUser ); if (pw != NULL) break; errno = 0; { char* pz; long l = strtol( pzUser, &pz, 0 ); switch (l) { case LONG_MIN: case LONG_MAX: case 0: if (errno != 0) { fprintf( stderr, zBadUser, getpwnamOptions.pzProgName, pzUser ); USAGE( EXIT_FAILURE ); } } uid = (uid_t)l; } /* FALLTHROUGH */ case 0: pw = getpwuid( uid ); if (pw != NULL) break; if (argc == 0) { fprintf( stderr, "%s error: uid %d has no password entry\n", getpwnamOptions.pzProgName, uid ); } else { fprintf( stderr, zBadUser, getpwnamOptions.pzProgName, pzUser ); } return EXIT_FAILURE; } if (selectCt > 0) { if (HAVE_OPT( VERBOSE )) printInfoVerbosely( pw ); else printInfo( pw ); } return EXIT_SUCCESS; } void printInfoVerbosely( struct passwd* pw ) { static const char zBadGrp[] = "%s error: the primary group for %s is invalid\n"; int ix = 0; do { switch (selections[ix]) { case INDEX_OPT_NAME: printf( "user name: %s\n", pw->pw_name ); break; case INDEX_OPT_PASSWD: printf( "password: '%s' (encrypted)\n", pw->pw_passwd ); break; case INDEX_OPT_UID: printf( "user id: %d\n", pw->pw_uid ); break; case INDEX_OPT_GNAME: { struct group* pg = getgrgid( pw->pw_gid ); if (pg == NULL) { fprintf( stderr, zBadGrp, getpwnamOptions.pzProgName, pw->pw_name ); exit( EXIT_FAILURE ); } printf( "group name: %s\n", pg->gr_name ); break; } case INDEX_OPT_GID: printf( "group id: %d\n", pw->pw_gid ); break; case INDEX_OPT_GECOS: printf( "full name: %s\n", pw->pw_gecos ); break; case INDEX_OPT_DIR: printf( "directory: %s\n", pw->pw_dir ); break; case INDEX_OPT_SHELL: printf( "login shell: %s\n", pw->pw_shell ); break; default: fprintf( stderr, "%s error: unknown selection: %d\n", getpwnamOptions.pzProgName, selections[ix] ); exit( EXIT_FAILURE ); } } while (++ix < selectCt); } void printInfo( struct passwd* pw ) { static const char zBadGrp[] = "%s error: the primary group for %s is invalid\n"; int ix = 0; for (;;) { switch (selections[ix]) { case INDEX_OPT_NAME: fputs( pw->pw_name, stdout ); break; case INDEX_OPT_PASSWD: fputs( pw->pw_passwd, stdout ); break; case INDEX_OPT_UID: printf( "%d", pw->pw_uid ); break; case INDEX_OPT_GNAME: { struct group* pg = getgrgid( pw->pw_gid ); if (pg == NULL) { fprintf( stderr, zBadGrp, getpwnamOptions.pzProgName, pw->pw_name ); exit( EXIT_FAILURE ); } fputs( pg->gr_name, stdout ); break; } case INDEX_OPT_GID: printf( "%d", pw->pw_gid ); break; case INDEX_OPT_GECOS: fputs( pw->pw_gecos, stdout ); break; case INDEX_OPT_DIR: fputs( pw->pw_dir, stdout ); break; case INDEX_OPT_SHELL: fputs( pw->pw_shell, stdout ); break; default: fprintf( stderr, "%s error: unknown selection: %d\n", getpwnamOptions.pzProgName, selections[ix] ); exit( EXIT_FAILURE ); } if (++ix >= selectCt) break; fputc( ' ', stdout ); } fputc( '\n', stdout ); } /* * Local Variables: * mode: C * c-file-style: "stroustrup" * tab-width: 4 * indent-tabs-mode: nil * End: * end of getpwnam.c */ --------------136311A7BB107C214BB1D637 Content-Type: text/plain; charset=us-ascii; name="opts.def" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="opts.def" autogen definitions options; copyright = { date = "2003"; owner = "Bruce Korb"; eaddr = "[EMAIL PROTECTED]"; type = gpl; }; /* * $Id: opts.def,v 1.2 2003/05/25 22:51:14 bkorb Exp $ */ prog-name = "getpwnam"; prog-title = "Get password entries"; argument = "[ user-name-or-id ]"; gnu-usage; long-opts; version = `echo "$Revision: 1.2 $" | sed 's/^.*: *//;s/ .*//'`; explain = <<- _EndExplanation_ This command uses getpwnam(3) or getpwuid(3) to obtain the requested information from the passwd database. If a user name or user id is not provided, the information for the current user is obtained. The results are printed in the order selected. If you select no options, nothing is printed on success, but the user name/user id will have been validated. _EndExplanation_; export = <<- _EndExport_ #include <stdio.h> extern int selectCt; int selections[INDEX_OPT_ALL]; _EndExport_; include = <<- _EndInclude_ int selectCt = 0; int selections[INDEX_OPT_ALL] = { 0 }; _EndInclude_; flag = { name = name; value = n; descrip = "Print the user name"; doc = "The user login name will be printed."; flag-code = <<- _EndCode_ int ix = selectCt++; if (selectCt > INDEX_OPT_ALL) { fprintf( stderr, "%s PROGRAM BUG: too many selections\n", pOptions->pzProgName ); exit( 1 ); } selections[ ix ] = pOptDesc->optIndex; _EndCode_; }; flag = { name = passwd; value = p; descrip = "Print the (encrypted) password"; doc = "The encrypted password will be printed."; flag-proc = name; }; flag = { name = uid; value = u; descrip = "Print the user id"; doc = "The numeric user id will be printed."; flag-proc = name; }; flag = { name = gname; value = g; descrip = "Print the group name"; doc = "The name of the user's primary group will be printed."; flag-proc = name; }; flag = { name = gid; value = G; descrip = "Print the group id"; doc = "The numeric primary group id will be printed."; flag-proc = name; }; flag = { name = gecos; value = N; descrip = "Print the real user name (comment string)"; doc = "The real user name will be printed, usually.\n" "It is designated as the account \"comment string\"."; flag-proc = name; }; flag = { name = dir; value = d; descrip = "Print the home directory"; doc = "The user's home directory will be printed."; flag-proc = name; }; flag = { name = shell; value = s; descrip = "Print the login shell"; doc = "The name of the program that is run when the user logs in " "will be printed."; flag-proc = name; }; flag = { name = all; value = A; descrip = "Print everything"; doc = "Print all of the available fields, including the name of\n" "the primary group."; flags-cant = name, passwd, uid, gname, gid, gecos, dir, shell; flag-code = <<- _EndCode_ int sel = INDEX_OPT_NAME; int ix = 0; do { selections[ ix++ ] = sel++; } while ( sel < INDEX_OPT_ALL ); selectCt = ix; _EndCode_; }; flag = { name = verbose; value = V; descrip = "Verbose output"; doc = "Print each item of information on a separate line, with\n" "a short description of each."; }; --------------136311A7BB107C214BB1D637 Content-Type: text/plain; charset=us-ascii; name="getpwnam.mk" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="getpwnam.mk" SRC = getpwnam.c opts.c OBJ = $(SRC:.c=.o) MOD = getpwnam CFLAGS = `autoopts-config cflags` # remove ``-lgen'' when not needed: # LDFLAGS = `autoopts-config static-libs` -lgen TARGETS = $(MOD) $(MOD).1 $(MOD).texi default : $(MOD) all : $(TARGETS) man : $(MOD).1 texi : $(MOD).texi $(MOD) : $(OBJ) $(CC) -o $@ $(OBJ) $(LDFLAGS) $(SRC) : opts.h opts.h : opts.def autogen opts.def $(MOD).1 : opts.def autogen -b$(MOD) -T agman1.tpl opts.def $(MOD).texi : $(MOD) autogen -b$(MOD) -T aginfo.tpl opts.def .c.o : $(CC) -o $@ $(CFLAGS) -c $< clean : rm -f $(OBJ) *~ clobber : clean rm -f $(TARGETS) $(MOD).menu opts.[ch] --------------136311A7BB107C214BB1D637--
_______________________________________________ Bug-coreutils mailing list [EMAIL PROTECTED] http://mail.gnu.org/mailman/listinfo/bug-coreutils