#ifndef lint static char *sccsid = "@(#)pw.c 2.5 (smail) 9/15/87"; #endif #include #include #include #include #include "defs.h" #include char *malloc(); void free(); typedef struct pw_node pwlist; struct pw_node { char *lname; /* login name */ char *fname; /* full name */ int uid; /* user-id */ char *home; /* login name */ pwlist *vlink; /* link to next item */ }; pwlist *pwhead; /* head of linked list */ pwlist *pwparse(); /* head of linked list */ #define PNULL ((pwlist *) 0) char * pwfnam(user) char *user; { pwlist *f; /* ** check for previously cached user */ for(f=pwhead; f != NULL; f=f->vlink) { if(strcmp(user, f->lname) == 0) { return(f->fname); } } /* ** not found parse the password file */ while((f=pwparse()) != PNULL) { if(strcmp(user, f->lname) == 0) { return(f->fname); } } return(NULL); } char * pwuid(uid) int uid; { pwlist *f; /* ** check for previously cached user */ for(f=pwhead; f != NULL; f=f->vlink) { if(uid == f->uid) { return(f->lname); } } /* ** not found parse the password file */ while((f=pwparse()) != PNULL) { if(uid == f->uid) { return(f->lname); } } return(NULL); } #ifndef SENDMAIL char * tilde(user) char *user; { pwlist *f; /* ** check for previously cached user */ for(f=pwhead; f != NULL; f=f->vlink) { if(strcmp(user, f->lname) == 0) { return(f->home); } } /* ** not found parse the password file */ while((f=pwparse()) != PNULL) { if(strcmp(user, f->lname) == 0) { return(f->home); } } return(NULL); } #endif /* not SENDMAIL */ char * fullname(gecos) char *gecos; { static char fname[SMLBUF]; register char *cend; (void) strcpy(fname, gecos); if (cend = index(fname, ',')) *cend = '\0'; if (cend = index(fname, '(')) *cend = '\0'; /* ** Skip USG-style 0000-Name nonsense if necessary. */ if (isdigit(*(cend = fname))) { if ((cend = index(fname, '-')) != NULL) cend++; else /* ** There was no `-' following digits. */ cend = fname; } return (cend); } pwlist * pwparse() { pwlist *f; char *p, *name; struct passwd *pwent, *getpwent(); unsigned int i; static int pw_eof = 0; if((pw_eof == 1) || ((pwent = getpwent()) == (struct passwd *) NULL)) { pw_eof = 1; return(PNULL); } /* ** Get an entry from the password file. ** Parse relevant strings. */ f = (pwlist *) malloc(sizeof(pwlist)); if(f == PNULL) return(PNULL); f->vlink = pwhead; pwhead = f; f->uid = pwent->pw_uid; i=strlen(pwent->pw_name)+1; p = malloc(i); if(p == NULL) return(PNULL); f->lname = strcpy(p, pwent->pw_name); i=strlen(pwent->pw_dir)+1; p = malloc(i); if(p == NULL) return(PNULL); f->home = strcpy(p, pwent->pw_dir); name = fullname(pwent->pw_gecos); i=strlen(name)+1; p = malloc(i); if(p == NULL) return(PNULL); f->fname = strcpy(p, name); return(f); } #ifdef FULLNAME /* ** Resolve a full name to a login name. ** Not too much smarts here. */ char * res_fname(user) register char *user; { long pos, middle, hi, lo; static long pathlength = 0; register char *s; int c; static FILE *file; int flag; char namebuf[SMLBUF], *path; extern enum edebug debug; extern char *fnlist; DEBUG("res_fname: looking for '%s'\n", user); if(pathlength == 0) { /* open file on first use */ if((file=fopen(fnlist, "r")) == NULL) { DEBUG( "can't access %s.\n", fnlist); pathlength = -1; } else { (void) fseek(file, 0L, 2); /* find length */ pathlength = ftell(file); } } if(pathlength == -1 ) return(NULL); lo = 0; hi = pathlength; path = namebuf; (void) strcpy( path, user ); (void) strcat( path, "\t" ); for( ;; ) { pos = middle = ( hi+lo+1 )/2; (void) fseek( file, pos, 0 ); /* find midpoint */ if (pos != 0) /* to beginning of next line */ while( ( c=getc( file ) ) != EOF && c != '\n' ); for( flag = 0, s = path; flag == 0; s++ ) { /* match??? */ if ( *s == '\0' ) { goto solved; } c = getc( file ); flag = lower( c ) - lower( *s ); } if (lo >= middle) /* failure? */ return(NULL); if(c != EOF && flag < 0) /* close window */ lo = middle; else hi = middle - 1; } /* ** Now just copy the result. */ solved: while(((c = getc(file)) != EOF) && (c != '\t') && (c != '\n')) { *path++ = c; } if(path == namebuf) { /* NULL alias field */ return(NULL); } *path = '\0'; if((path = malloc((unsigned) strlen(namebuf)+1)) == NULL) { return(NULL); /* sorry, no memory */ } (void) strcpy(path, namebuf); return(path); } #endif /* FULLNAME */