Path: utzoo!news-server.csri.toronto.edu!cs.utexas.edu!uunet!stanford.edu!agate!ucbvax!CONCOUR.CS.CONCORDIA.CA!goldfish From: goldfish@CONCOUR.CS.CONCORDIA.CA Newsgroups: comp.sys.apollo Subject: Registry propagation delays (with code ; LOOONG) Message-ID: <9103081042.aa05116@concour.cs.concordia.ca> Date: 8 Mar 91 15:42:27 GMT Sender: daemon@ucbvax.BERKELEY.EDU Organization: The Internet Lines: 989 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 (514) 848-3031 (Shirley Maclaine told me there would be LIFETIMES like this) ********************* First SHAR file *********************** #!/bin/sh echo extracting Makefile ... cat >Makefile <freeunixno.c < #include #include #include #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 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 <userinfo.c < #include #include #include #include "argtok.h" #include "bstran.h" #include #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 <Makefile <argtok.c <argtok.h <bstran.c <bstran.h <main.c < #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