[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
(no subject)
From: |
Bruce Korb |
Subject: |
(no subject) |
Date: |
Tue, 16 Dec 2003 11:50:18 -0800 (PST) |
>From - Tue Dec 16 11:48:45 2003
X-Mozilla-Status: 8001
X-Mozilla-Status2: 00000000
Message-ID: <address@hidden>
Date: Tue, 16 Dec 2003 11:47:21 -0800
From: Bruce Korb <address@hidden>
Reply-To: address@hidden
Sender: address@hidden
X-Mailer: Mozilla 4.8 [en] (X11; U; SunOS 5.8 sun4u)
X-Accept-Language: en
MIME-Version: 1.0
To: address@hidden
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: address@hidden
$ 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 = "address@hidden";
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--
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- (no subject),
Bruce Korb <=