This is getpwwho.c in view mode; [Download] [Up]
/* * Copyright (c) 1990 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. * * THE SOFTWARE IS PROVIDED "AS IS" AND CARNEGIE MELLON UNIVERSITY * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT * SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE FOR ANY SPECIAL, DIRECT, * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * * Users of this software agree to return to Carnegie Mellon any * improvements or extensions that they make and grant Carnegie the * rights to redistribute these changes. * * Export of this software is permitted only after complying with the * regulations of the U.S. Deptartment of Commerce relating to the * Export of Technical Data. */ /* ********************************************************************** * HISTORY * $Log: getpwwho.c,v $ * Revision 1.3 90/12/11 17:55:13 mja * Add copyright/disclaimer for distribution. * * 11-Aug-88 Glenn Marcy (gm0w) at Carnegie-Mellon University * Mapped ulstr to strcase compare. * * 05-Mar-86 Glenn Marcy (gm0w) at Carnegie-Mellon University * Removed all special gecos code for 4.2 version. * * 03-Jan-86 Rudy Nedved (ern) at Carnegie-Mellon University * Basically the entire module was re-written. Parts of the getpwambig * routine are from the old package but that is it. The new code was * written using the CMU TOPS-10 SAIL library algorithm for parsing * account file names. The original motivation for this routine was * based on the visible actions of that algorithm, it might as well * used the actually algorithm. * * Hopefully all the compatibility issues have been handled. The * getpwwho(NULL) behavior is handled and the special loading of * middle names into the first name is handled. * * I would have coded the routine to really handle things in a mail * context but that is suppose to be handled by the network name * database. * * 06-Jan-84 Eric Patterson (egp) at Carnegie-Mellon University * Fixed bug: if a string exactly matches some name, but is also a * substring of some other name, no ambiguity is observed. * * 18-Dec-81 Mike Accetta (mja) at Carnegie-Mellon University * Fixed two bugs: * 1) adjusted length passed to FoldEQ() to a maximum so that login name * comparison never succeeds on a partial match. * 2) added check for exact match after IsName() succeeds in case the * full name is a substring of some other full name with which it * would otherwise be ambiguous. * * 07-Dec-81 James Gosling (jag) at Carnegie-Mellon University * Now does case-folded compares on login ID's. eg. "ern" and "ERN" * match. * * 11-Dec-80 Mike Accetta(mja) at Carnegie-Mellon University * Changed to convert all separator characters to spaces when * copying name into internal buffer so that dots in names with * more than two parts will match password file entries. * * 03-Dec-80 Mike Accetta (mja) at Carnegie-Mellon University * Changed to treat everything before last blank in name as first * name and modified to close password file when called with null * pointer. * * 29-Nov-80 Mike Accetta (mja) at Carnegie-Mellon University * Changed to allow '.' as separator in names. * * 07-Nov-80 Mike Accetta (mja) at Carnegie-Mellon University * Removed reference to (extinct) alias name. * ********************************************************************** */ #include <stdio.h> #include <ctype.h> #include <pwd.h> extern struct passwd *getpwent(); #define MAXNAME 100 static char FirstPart[MAXNAME],LastPart[MAXNAME]; static char ThisFirst[MAXNAME],ThisLast[MAXNAME]; static int ExactFirst,ExactLast; static int MatchLevel,Matches,ambigstate; /* * break the supplied name down in to last name and first name(s). * Translate dots into spaces. Note: middle names are part of the * first name. */ static BreakDown(name,firsts,last) char *name,*firsts,*last; { register char *p,*lp; strncpy(firsts,name,MAXNAME); lp = (char *)0; p = firsts; while (*p) { if (*p == '.' || *p == ' ') { *(lp = p++) = ' '; } else p++; } if (lp != (char *)0) { strncpy(last,lp+1,MAXNAME); *lp = '\0'; } else { strncpy(last,firsts,MAXNAME); *firsts = '\0'; } } /* * We could just do a getpwuid() at the end of the name search * but this causes alot of extra time spent and for mail and finger * clients this is highly irritating especially on a loaded machine * with many entries in the /etc/passwd file. On of these days, an * additional binary index will be available making lookups on uid * and login names fast. */ static pw_entry_save(bufp,valp) char **bufp; register char *valp; { register char *p; p = *bufp; while ((*p++ = *valp++) != '\0'); *bufp = p; } static struct passwd *copypw(pw) struct passwd *pw; { static struct passwd mypw; static char mybuf[BUFSIZ+1]; char *p; mypw = *pw; /* copy things like pw_uid, pw_gid, etc. */ p = mybuf; mypw.pw_name = p; pw_entry_save(&p,pw->pw_name); mypw.pw_passwd = p; pw_entry_save(&p,pw->pw_passwd); mypw.pw_comment = p; pw_entry_save(&p,pw->pw_comment); mypw.pw_gecos = p; pw_entry_save(&p,pw->pw_gecos); mypw.pw_dir = p; pw_entry_save(&p,pw->pw_dir); mypw.pw_shell = p; pw_entry_save(&p,pw->pw_shell); return &mypw; } static struct passwd *scanpw(stop) int stop; { struct passwd *bestpw,*pw; bestpw = (struct passwd *) 0; while (pw = getpwent()) { /* handle login ids, exact Matches win always */ if (*FirstPart == '\0' && strcasecmp(LastPart,pw->pw_name) == 0) { Matches = 1; MatchLevel = 7777777; /* large number */ return copypw(pw); } /* check out names */ BreakDown(pw->pw_gecos,ThisFirst,ThisLast); if (namecheck(ThisLast,LastPart,ExactLast)) { /* last match */ if (namecheck(ThisFirst,FirstPart,ExactFirst)) { /* both match */ if (!ExactLast) if (strcasecmp(ThisLast,LastPart) == 0) ExactLast = 1; if (ExactLast && !ExactFirst) if (strcasecmp(ThisFirst,FirstPart) == 0) ExactFirst = 1; /* see if we got something better */ if (MatchLevel < (ExactFirst + ExactLast)) { MatchLevel = ExactFirst + ExactLast; bestpw = copypw(pw); Matches = 1; if (stop) return bestpw; } else if (MatchLevel == (ExactFirst + ExactLast)) { Matches++; bestpw = copypw(pw); if (stop) return bestpw; } } } } return bestpw; } struct passwd *getpwwho (name) char *name; { struct passwd *pw; /* initialize a few things */ MatchLevel = -1; Matches = 0; ExactFirst = ExactLast = 0; ambigstate = -1; /* NULL for a name is a no-op...used to clear some internal state */ if (name == NULL) return (struct passwd *) 0; /* break down the probe name for comparisons */ BreakDown(name,FirstPart,LastPart); /* now search thru the password file for Matches */ setpwent(); pw = scanpw(0); endpwent(); /* see what we got */ if (Matches == 0) return (struct passwd *)0; else if (Matches == 1) return pw; ambigstate = 0; return (struct passwd *)-1; } struct passwd *getpwambig () { struct passwd *pw; if (ambigstate < 0) return 0; if (ambigstate++ == 0) { Matches = 0; setpwent(); } pw = scanpw(1); if (pw == 0) { ambigstate = -1; endpwent(); } return pw; } static namecheck(a,b,exact) char *a, *b; int exact; { if (exact) return(strcasecmp(a,b) == 0); if (*b == 0) return 1; return(strncasecmp(a,b,strlen(b)) == 0); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.