goldfish@CONCOUR.CS.CONCORDIA.CA (03/08/91)
Below are two "shar" files I have created containing a command line
argument handler and two useful routines for handling password queries.
Apologies to all if this is not the correct place to post sources,
however I received several requests on this group and several
suggestions on how to write the programs, so I thought this would be an
appropriate place for the sources.
The routines should work on most-anything that maintains some semblance
of the UNIX /etc/passwd paradigm, except that I have not tested it on
other platforms ... :-( The problem with Sun is that they don't ship a
modern C compiler, just this anachronistic throwback to the days of
Lunar landings and SIXTEEN BIT mainframes.
I also have not had time to get it running on our DECStations, since I
don't remember seeing a debugger which required a manual in a long time
(I currently use DDE and Turbo C). I will re-post this bunch to
Comp.Sources or some-such when I get the time to fix it, however it runs
on Apollo Domain-OS 10.2 RIGHT NOW. so laziness aside, these programs
will work (until HP's next "foot-hunt")
To install these programs, unpack the "shar" files (there are two of
them) into separate directories and edit the "Makefile" in each to point
to things in the right place. (the "userinfo" program needs binaries
from the "argtok" package.)
You should be able to safely run the programs with little fear of
damage, since they never write anywhere save stdout and stderr.
The man pages are self explanatory and give examples of how to use the
programs.
I don't describe myself as an expert "C" hacker, so comments as to form
are welcome.
Since most software usually has a disclaimer:
(-: The author of the software makes no assertions :-)
(-: whatsoever that the software or documentation :-)
(-: contained herein performs according to its :-)
(-: stated function, the function for which its use :-)
(-: is intended, or indeed any useful function :-)
(-: whatsoever. :-)
(-:I am not limiting the use of this code in any :-)
(-: way, or requesting any royalties, however if :-)
(-: anyone has an unmarried Jewish Princess to :-)
(-: spare, I would not complain. If you want to be :-)
(-: nice, leave my name and E-Mail address in the :-)
(-: source code; if you want to be nasty, claim it :-)
(-: was your idea and I rewrote it to add lots of :-)
(-: bugs :-)
Oh YES! if you really want to thank me, send me source of the program
"Shar", my good version dissappeared and this was generated on a PC.
-- Paul Goldsmith
<goldfish@concour.cs.concordia.ca> (514) 848-3031
(Shirley Maclaine told me there would be LIFETIMES like this)
********************* First SHAR file ***********************
#!/bin/sh
echo extracting Makefile ...
cat >Makefile <<xzyyz
# Makefile for userinfo
# -- Goldfish 90/09/14
############################################################
# Global assignments
############################################################
CC=cc
# the preceding assignment points to the "personal"
# include directory
INCLUDE=$(HOME)/Include
# the preceding assignment points to the "personal"
# library directory
LIBRARY=$(HOME)/Lib
# This is the directory to which the "production"
# binary goes
BIN=/site/bin
# This is the directory to which the "production" man
# page goes
MAN=/usr/man/mann
############################################################
# options and flags
############################################################
COMPILEOPTION=-g -I$(INCLUDE)
############################################################
# First action performs the complete compile
############################################################
all: userinfo freeunixno
############################################################
# Compile and link the parts of freeunixno
############################################################
freeunixno: freeunixno.o
$(CC) $(COMPILEOPTION) freeunixno.o $(LIBRARY)/argtok.o $(LIBRARY)/bstran.o -o freeunixno
freeunixno.o: freeunixno.c
$(CC) $(COMPILEOPTION) -c freeunixno.c
freeunixno.c: freeunixno.c,v
co freeunixno.c
############################################################
# Compile and link the parts of userinfo
############################################################
userinfo: userinfo.o
$(CC) $(COMPILEOPTION) userinfo.o $(LIBRARY)/argtok.o $(LIBRARY)/bstran.o -o userinfo
userinfo.o: userinfo.c
$(CC) $(COMPILEOPTION) -c userinfo.c
userinfo.c: userinfo.c,v
co userinfo.c
############################################################
# execute the current version for testing purposes
############################################################
test: testuserinfo testfreeunixno
testuserinfo: userinfo
echo root | ./userinfo root -
./userinfo -pw ./test.pw -all -f 'Name:\t"%u"\tPassword:\t"%p"\
User No:\t"%U"\tGroup:\t"%G"\
GECOS:\
"%i"\
\tName: (last)"%l"\t(first)"%f"\tsub-0:"%0"\
\tOffice:\t"%o"\tsub-1:"%1"\
\tRoom:\t"%r"\tsub-2:"%2"\
\tPhone:\t"%t"\tsub-3:"%3"\
\t\tsub-4:"%4"\
\t\tsub-5:"%5"\
\t\tsub-6:"%6"\
\t\tsub-7:"%7"\
\t\tsub-8:"%8"\
\tID:\t"%I"\tsub-9:"%9"\
Home:\t"%h"\
Shell:\t"%s"'
testfreeunixno: freeunixno
./freeunixno -lo0 -hi20 -count 2
# ./freeunixno -lo0 -hi20
############################################################
# remove re-creatable files
############################################################
clean:
rm *.o *~ *.BAK *.bak arg
############################################################
# install global files onto appropriate libraries
############################################################
production: userinfoproduction freeunixnoproduction
userinfoproduction: $(BIN)/userinfo $(MAN)/userinfo.n
freeunixnoproduction: $(BIN)/freeunixno $(MAN)/freeunixno.n
############################################################
# install userinfo
############################################################
$(BIN)/userinfo: userinfo userinfo.n
cp userinfo $(BIN)/userinfo
userinfo.n: userinfo.n,v
co userinfo.n
$(MAN)/userinfo.n: userinfo.n
cp userinfo.n $(MAN)/userinfo.n
############################################################
# install freeunixno
############################################################
$(BIN)/freeunixno: freeunixno
cp freeunixno $(BIN)/freeunixno
freeunixno.n: freeunixno.n,v
co freeunixno.n
$(MAN)/freeunixno.n: freeunixno.n
cp freeunixno.n $(MAN)/freeunixno.n
############################################################
# end of Makefile
############################################################
xzyyz
echo extracting freeunixno.c ...
cat >freeunixno.c <<xzyyz
#include <stdio.h>
#include <math.h>
#include <pwd.h>
#include <grp.h>
#include "argtok.h"
#include "bstran.h"
#define TRUE 1
#define FALSE 0
#define DEFFMT "%5d\n"
#define DEFLO "0"
#define DEFHI "32767"
#define DEFCOUNT "32767"
#define USERNOSPACE 32768
#define STARTTICK 16
/* purpose: to return a range of unix numbers
*
* comments: This program is used in place of "grep" calls to locate
*
* Notes:
*
* Author: Paul Goldsmith 90/09/13
*/
char *silent;
main(int argc,
char *argv[]
)
{
int i, ihi, ilo, icount;
struct passwd *pass;
char *format = argtok(argc, argv, "-f", DEFFMT);
char *lo = argtok(argc, argv, "-lo", DEFLO);
char *hi = argtok(argc, argv, "-hi", DEFHI);
char *count = argtok(argc, argv, "-count", DEFCOUNT);
char numberspace[USERNOSPACE];
char wkfmt[256];
register int tickcount;
ilo = atoi(lo);
ihi = atoi(hi);
icount = atoi(count);
silent = argtok(argc, argv, "-s", 0);
tickcount = (silent ? -1 : STARTTICK);
while ( pass = getpwent() ) {
if ( ! tickcount--) {
fputc ( '.', stderr );
fflush (stderr);
tickcount = STARTTICK;
}
numberspace[pass->pw_uid]=TRUE;
}
if ( ! silent ) fputc ( '\n', stderr );
if ( strcmp(format, "-") == 0 ) {
format = wkfmt;
}
for ( i = ((ilo>0)?ilo:0) ;
(i <= ((ihi<USERNOSPACE)?ihi:USERNOSPACE) ) && (icount > 0) ;
i++ ){
if ( ! numberspace[i]) {
if ( format == wkfmt ) {
if ( gets (wkfmt) ) {
printf(bstran(wkfmt), i);
}else {
return;
}
}else {
printf(format,i);
}
icount--;
}
}
}
xzyyz
echo extracting test.pw ...
cat >test.pw <<xzyyz
Name:Password:UserNo:GroupNo:LASTNAME firstname, Office, (Room), Phone, fill-4, fill-5, fill-6, fill-7, fill-8, ID Number:/home/path/name:/bin/shell
xzyyz
echo extracting userinfo.c ...
cat >userinfo.c <<xzyyz
/* $Log: userinfo.c,v $
* Revision 1.7 91/01/30 14:22:21 goldfish
* include a "%H" real home token, tidy up docs, use bstran instead of bschar
*
* Revision 1.6 91/01/18 14:13:18 root
* *** empty log message ***
*
* Revision 1.5 91/01/18 14:12:15 root
* remove default trailing newline from format string
*
* Revision 1.4 91/01/17 11:58:59 root
* finetune main.c
*
* Revision 1.3 91/01/16 16:50:01 root
* fix "-version flag"
* fix "-all" flag.
* reformat error messages.
*
* Revision 1.2 91/01/16 16:22:35 root
* cosmetic revisions to accomodate RCS; add a "-version" flag.
*
*/
#include <string.h>
#include <stdio.h>
#include <pwd.h>
#include <grp.h>
#include "argtok.h"
#include "bstran.h"
#include <sys/param.h>
#define TRUE 1
#define FALSE 0
#define DEFFMT "%u:%p:%U:%G:%i:%h:%s\n"
#define INVALIDGROUP "**INVALID**"
#define MAXUSERNAMELEN 127
#define MAXFILENAMELEN 127
#define NULLPWFILE ""
#define VERSION "$Revision: 1.7 $\n"
/* purpose: to query password registry reliably using unix calls
*
* comments: This program is used in place of "grep" calls to locate
* information in the /etc/passwd file. I employs the (hopefully)
* reliable c function call "getpwnam()". Considerable flexibility is
* afforded in interpreting the output. *
*
* Author: Paul Goldsmith 90/07/11
*/
int chdir();
char *getwd();
char *silent;
char *vraipath ( char *name, char *vrainame)
{ if ( ! chdir(name) ) {
if ( getwd (vrainame) ) {
return vrainame ;
}else {
return 0 ;
}
}else {
return 0 ;
}
};
char bschar( char tc )
{ switch (tc) {
case 'n' : return '\n';
case 't' : return '\t';
case 'v' : return '\v';
case 'b' : return '\b';
case 'r' : return '\r';
case 'f' : return '\f';
case 'a' : return '\a';
case '\\' : return '\\';
case '?' : return '\?';
default : return tc ;
}
};
struct gecosfields {
char *firstname;
char *lastname;
char *office;
char *room;
char *phone;
char *spare[5];
char *id;
};
char *eatwhitespace ( char * str)
{ int length;
char *begstr = str;
if ( begstr == 0 ) return 0 ;
while ( isspace(*begstr) ) { begstr++; };
length = strlen(begstr);
while ( --length >= 0 && isspace(begstr[length]) ) { begstr[length] = 0; };
return begstr;
}
void splitgecos ( char *gecos, struct gecosfields *fields )
{ char *dblspc;
fields->lastname = eatwhitespace(strtok(gecos, ","));
dblspc = fields->lastname;
while ( (*dblspc != 0 ) &&
strncmp( " ", dblspc, 2) ) {
dblspc++;
}
if ( *dblspc != 0 ) {
*dblspc = 0;
dblspc += 2;
}
fields->firstname = eatwhitespace(dblspc);
fields->office = eatwhitespace(strtok (0, ","));
fields->room = eatwhitespace(strtok (0, ","));
fields->phone = eatwhitespace(strtok (0, ","));
fields->spare[0] = eatwhitespace(strtok (0, ","));
fields->spare[1] = eatwhitespace(strtok (0, ","));
fields->spare[2] = eatwhitespace(strtok (0, ","));
fields->spare[3] = eatwhitespace(strtok (0, ","));
fields->spare[4] = eatwhitespace(strtok (0, ","));
fields->id = eatwhitespace(strtok (0, ","));
}
printpasswd (char *format, struct passwd *pass)
{ struct group *grp = getgrgid(pass->pw_gid);
struct gecosfields gecos;
char scr[256];
splitgecos( strcpy(scr,pass->pw_gecos), &gecos);
{ char *c;
for (c = format; *c; c++) {
if (*c == '%') {
switch (*(++c)) {
case '%': putchar('%'); break;
case 'u': printf("%s", pass->pw_name); break;
case 'p': printf("%s", pass->pw_passwd); break;
case 'U': printf("%d", pass->pw_uid); break;
case 'G': printf("%d", pass->pw_gid); break;
case 'g': printf("%s", ( (grp) ? (grp->gr_name) : (INVALIDGROUP))
);
break;
/* case 'q': printf("%d", pass->pw_quota); break;
*/
case 'c': printf("%s", pass->pw_comment); break;
case 'i': printf("%s", pass->pw_gecos); break;
case '0':
case 'l': printf("%s", gecos.lastname); break;
case 'f': printf("%s", gecos.firstname); break;
case '1':
case 'o': printf("%s", gecos.office); break;
case '2':
case 'r': printf("%s", gecos.room); break;
case '3':
case 't': printf("%s", gecos.phone); break;
case '4': printf("%s", gecos.spare[0]); break;
case '5': printf("%s", gecos.spare[1]); break;
case '6': printf("%s", gecos.spare[2]); break;
case '7': printf("%s", gecos.spare[3]); break;
case '8': printf("%s", gecos.spare[4]); break;
case '9':
case 'I': printf("%s", gecos.id); break;
case 'h': printf("%s", pass->pw_dir); break;
case 'H': { char path[MAXFILENAMELEN] ;
if ( vraipath( pass->pw_dir, path) )
printf("%s", path);
} break;
case 's': printf("%s", pass->pw_shell); break;
default: putchar('%'); putchar(*c); break;
}
} else {
putchar(*c);
}
}
}
};
printuser (char *format, char *name)
{ struct passwd *pass;
struct group *grp;
struct gecosfields gecos;
if (pass = getpwnam(name)) {
printpasswd( format, pass);
} else if (!silent) {
fprintf(stderr, "user %s not found\n", name);
} };
printall (char *format)
{ struct passwd *pass;
struct group *grp;
struct gecosfields gecos;
while (pass = getpwent() ) {
printpasswd( format, pass);
}
return (int)pass;
};
main(int argc,
char *argv[]
)
{
char **user = 0;
char *pwfile = argtok(argc, argv, "-pw", NULLPWFILE);
char *format = argtok(argc, argv, "-f", DEFFMT);
char *all = argtok(argc, argv, "-all", 0);
char *version = argtok(argc, argv, "-version", 0);
silent = argtok(argc, argv, "-c", 0);
if ( version ) { fputs(VERSION, stderr ); return 0; }
if ( *pwfile ) {
endpwent();
setpwfile(pwfile);
}
if ( all ) {
return printall (format) ;
}else {
for (user = argv, user++; *user; user++) {
if (! strcmp(*user, "-")){
char name[MAXUSERNAMELEN];
while ( gets(name) ) {
printuser (format, name);
}
}else {
printuser (format, *user);
}
}
}
};
xzyyz
echo extracting userinfo.n ...
cat >userinfo.n <<xzyyz
.\" $Log$
.TH USERINFO
.SH NAME
userinfo \- display USER information from
.B /etc/passwd
.SH VERSION
.B $Revision$
.SH SYNOPSIS
.B userinfo
tokenized display of information from
.B /etc/passwd
and
.B /etc/group
files with
.I printf(3)
style output
.SH DESCRIPTION
.I userinfo
is a command which will accept a list of user names
from either the command line or standard input.
The parameter flag "-all" selects all the records
in the password file.
.I userinfo
locates
the users with the
.I getpwnam(3)
and
.I getpwent(3)
calls which on simple non\-networked systems resolves to the files
.I /etc/passwd
and
.I /etc/group.
.I Userinfo
writes the information about the users to
.I stdout.
An optional format string may be given on the command line. It allows
for a mixture of text and fields from
.I /etc/passwd
and
.I /etc/group
to be output in lieu of the default format. The default format is
exactly what appears in the
.I /etc/passwd
file.
This program may be used in place of
.I grep(3)
and
.I awk(3)
calls to locate
information in the
.I /etc/passwd
file. It employs the
reliable
.B c
function call
.I getpwnam(3).
Considerable flexibility is
afforded in interpreting the output.
.br
.SH ARGUMENTS
.B names ... \-
.SH COMMAND LINE OPTIONS
.TP
.B \-
read a list of
names, one per line from
.B stdin;
the
.B \-
argument may appear anywhere in the list of names and will be inserted
in place in that list
.TP
.B \-c
operate silently; omits some optional warning message
.TP
.B \-f
format string
.TP
.B \-pw
name of an alternate password file. The default is:
.I /etc/passwd
.TP
.B \-all
Process
.B all
records in the password file instead of a
selection. This option overrides all selections
.TP
.B \-version
displays the version number and date of
.Iuserinfo
.SH EXECUTION
The parameters are a list of names of the user
being queried. The "-f"
parameter denotes the format string. If it is
omitted, the user
information is written in the format of the
/etc/passwd file. If a
format string is included it is interpreted as
follows:
.TP
.B %u user name
.TP
.B %p password (encrypted)
.TP
.B %U
user number
.TP
.B %G
group number
.TP
.B %g
group name
.TP
.B %q
quota
.TP
.B %c
comment
.TP
.B %i
GECOS fields. The GECOS fields are individually
accessable. Their tokens follow below.
.TP
.B %h
home directory
.TP
.B %H
Fully qualified home directory pathname containing no soft links. Output is a null
string if the pathname does not resolve to a real directory.
.TP
.B %s
shell
.TP
.B %%
"%"
The following fields are components of the GECOS
fields.
.TP
.B %l %0
GECOS last\-name field. (The lastname and
firstname fields are delimited by a doublespace
(" "). This is a local standard only. Also, by
convention, the last name is in uppercase.)
.TP
.B %f
GECOS first\-name field. (See above note
This is a local standard only. Also, by
convention, the last name is in lowercase.)
.TP
.B %o %1
GECOS office field.
.TP
.B %r %2
GECOS room field.
.TP
.B %t %3
GECOS Telephone number field.
.TP
.B %4
GECOS Fourth field (starting from zero).
.TP
.B %5
GECOS Fifth field (starting from zero).
.TP
.B %6
GECOS Sixth field (starting from zero).
.TP
.B %7
GECOS Seventh field (starting from zero). This
field is used locally to hold the Apollo
"organization" field. It does not get coppied
into the actual password file.
.TP
.B %8
GECOS Eighth field (starting from zero). This
field usually contains a "F" if the application
form is correctly submitted, or is blank if no
form has been submitted. <
.TP
.B %I %9
GECOS ID Number field. Locally defined to
contain the unique ID
number for each user. This field is confidential
and must not be imbedded into the public
"/etc/passwd" file.
All other character seqences are printed verbatim.
.SH EXAMPLES:
The following example will print the
.I /etc/passwd
file entry for
.B root
.IP
userinfo root
.P
or
.IP
echo root | userinfo -
.P
The following prints
.I "user is root with home /"
.IP
userinfo root -f \"user is %u with home %h\\n\"
.P
The following prints a list of all account names
with full user name and ID number
.IP
userinfo -all -f \"%u\\t%l\\t%f\\t%i\\n\"
.SH NOTES
Arguments and options may be freely mixed in any
order. See argtok(3), a local package for
command line argument parsing, for details.
Remember to place the \"\\n\" at the end of the
format string, or the entire output will be run
together.
.SH FILES
.B /etc/passwd
.B /etc/group
.PD
.SH SEE ALSO
ypcat(8)[on Sun], grep(1), printf(3)
.SH DIAGNOSTICS
invalid user names will be echoed to
.I stderr
as:
.br
.B user
.I username
.B not found
.br
.
.SH BUGS
User names read from standard input must be
stripped of leading and trailing blanks. The
names are taken verbatim.
Apollo maintains its password registry in a manner that will
occasionally lock it for brief periods of time. The command will
almost never fail on two consecutive tries when the network is
functioning properly.
xzyyz
echo done
exit 0
exit 0
*************** Second SHAR File ***************
#!/bin/sh
echo extracting Makefile ...
cat >Makefile <<xzyyz
# Makefile for argtok
# -- Goldfish 90/09/14
############################################################
# Global assignments
############################################################
CC=cc
# the preceding assignment points to the "personal" include
# directory
INCLUDE=$(HOME)/Include
# the preceding assignment points to the "personal" library
# directory
LIBRARY=$(HOME)/Lib
# This is the directory to which the "production"
BIN=/site/bin
############################################################
# options and flags
############################################################
#COMPILEOPTION=-g
COMPILEOPTION=
############################################################
# First action performs the complete compile
############################################################
all: tools test
############################################################
# Compile and link the parts of the program
############################################################
tools: .o/main.o .o/argtok.o argtok.h .o/bstran.o bstran.h
$(CC) $(COMPILEOPTION) .o/main.o .o/bstran.o .o/argtok.o -o tools
.o/main.o: main.c .o/argtok.o argtok.h .o/bstran.o bstran.h
$(CC) $(COMPILEOPTION) -c main.c -o .o/main.o
.o/argtok.o: argtok.c argtok.h
$(CC) $(COMPILEOPTION) -c argtok.c -o .o/argtok.o
.o/bstran.o: bstran.c bstran.h
$(CC) $(COMPILEOPTION) -c bstran.c -o .o/bstran.o
############################################################
# execute the current version for testing purposes
############################################################
test: tools
echo "hello\\ttab\\nlinebreak" \
| ./tools -a one two three -b=four -c=five -d six -e | fmt
############################################################
# remove re-creatable files
############################################################
clean:
rm -f .o/*.o *~ *.BAK *.bak tools
############################################################
# install global files onto appropriate libraries
############################################################
production: $(INCLUDE)/argtok.h $(LIBRARY)/argtok.o $(INCLUDE)/bstran.h $(LIBRARY)/bstran.o
$(LIBRARY)/argtok.o: .o/argtok.o
cp .o/argtok.o $(LIBRARY)/argtok.o
$(INCLUDE)/argtok.h: argtok.h
cp argtok.h $(INCLUDE)/argtok.h
$(LIBRARY)/bstran.o: .o/bstran.o
cp .o/bstran.o $(LIBRARY)/bstran.o
$(INCLUDE)/bstran.h: bstran.h
cp bstran.h $(INCLUDE)/bstran.h
############################################################
# end of Makefile
############################################################
xzyyz
echo extracting argtok.c ...
cat >argtok.c <<xzyyz
#include "argtok.h"
char *cutfirstelt(char **list)
{ char *first = *list; /* save first element */
while (list[0] = list[1]) list++; /* bump each element back one */
return first;
}
char *ARGTOK(int *argc,
char **argv,
char *token,
char *deflt)
{ char **cur;
char *value = deflt;
int toklen = strlen(token);
for (cur = argv; *cur; cur++) {
if (!strncmp(token, *cur, toklen)) {
if (strlen(*cur) == toklen) { /* token value is next parameter */
if (deflt) cutfirstelt(cur); /* token is not flag; leave */
/* flag on arg list */
value = cutfirstelt(cur); /* cut token value from list */
} else { /* token value is parm tail */
value = cutfirstelt(cur) + toklen; /* cut token parm from list and */
/* set value to parm tail */
};
break;
}
if (!strcmp("--",token) ) break; /* stop scanning at double minus */
}
for (*argc = 0, cur = argv; *(cur++) ; (*argc)++); /* count remaining args */
return value;
};
xzyyz
echo extracting argtok.h ...
cat >argtok.h <<xzyyz
#define ARGDELIM "--"
#define argtok(c,v,t,d) ARGTOK(&(c),v,t,d)
char *ARGTOK( int *argc,
char **argv,
char *token,
char *deflt);
xzyyz
echo extracting bstran.c ...
cat >bstran.c <<xzyyz
#include "bstran.h"
char *bstran( char *ts )
{ char *curin, *curout;
for ( curout = curin = ts ; *curin ; curin++, curout++ ) {
if ( *curin == '\\' ) {
switch ( *(++curin) ) {
case '\000' : *curout = '\000' ; return ts;
case 'n' : *curout = '\n'; break ;
case 't' : *curout = '\t'; break ;
case 'v' : *curout = '\v'; break ;
case 'b' : *curout = '\b'; break ;
case 'r' : *curout = '\r'; break ;
case 'f' : *curout = '\f'; break ;
case 'a' : *curout = '\a'; break ;
case '\\' : *curout = '\\'; break ;
case '?' : *curout = '\?'; break ;
default : *curout = *curin ;
}
} else {
*curout = *curin;
}
}
*curout = '\000';
return ts;
};
xzyyz
echo extracting bstran.h ...
cat >bstran.h <<xzyyz
char *bstran( char *ts );
xzyyz
echo extracting main.c ...
cat >main.c <<xzyyz
#include <stdio.h>
#include "argtok.h"
#include "bstran.h"
#define booltostr(b) (b ? "True" : "False")
main(int argc,
char **argv,
char **envp)
{
char *a, *b, *c, *d, *e, *f, *g;
a = argtok(argc, argv, "-a", "a not found");
b = argtok(argc, argv, "-b", "b not found");
c = argtok(argc, argv, "-c", 0);
d = argtok(argc, argv, "-d", "d not found");
e = argtok(argc, argv, "-e", "e not found");
f = argtok(argc, argv, "-f", "f not found");
g = argtok(argc, argv, "-g", 0);
printf("a=[%s] ", a);
printf("b=[%s] ", b);
printf("c=[%s] ", booltostr(c));
printf("d=[%s] ", d);
printf("e=[%s] ", e);
printf("f=[%s] ", f);
printf("g=[%s] ", booltostr(g));
printf(" %d remaining args", argc);
while (*argv) {
printf(" [%s]", *argv);
argv++;
}
{ char work [256];
while (gets (work)) {
printf ("\ninput is: [%s]\n", work );
printf ("output is: [%s]\n", bstran(work) );
}
}
}
xzyyz
echo done
exit 0
exit 0