|
|
1.1 ! root 1: #ifndef lint ! 2: static char *sccsid = "@(#)pw.c 2.5 (smail) 9/15/87"; ! 3: #endif ! 4: ! 5: #include <stdio.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: #include <pwd.h> ! 9: #include "defs.h" ! 10: #include <ctype.h> ! 11: ! 12: char *malloc(); ! 13: void free(); ! 14: ! 15: typedef struct pw_node pwlist; ! 16: ! 17: struct pw_node { ! 18: char *lname; /* login name */ ! 19: char *fname; /* full name */ ! 20: int uid; /* user-id */ ! 21: char *home; /* login name */ ! 22: pwlist *vlink; /* link to next item */ ! 23: }; ! 24: ! 25: pwlist *pwhead; /* head of linked list */ ! 26: pwlist *pwparse(); /* head of linked list */ ! 27: ! 28: #define PNULL ((pwlist *) 0) ! 29: ! 30: char * ! 31: pwfnam(user) ! 32: char *user; ! 33: { ! 34: pwlist *f; ! 35: ! 36: /* ! 37: ** check for previously cached user ! 38: */ ! 39: ! 40: for(f=pwhead; f != NULL; f=f->vlink) { ! 41: if(strcmp(user, f->lname) == 0) { ! 42: return(f->fname); ! 43: } ! 44: } ! 45: /* ! 46: ** not found parse the password file ! 47: */ ! 48: ! 49: while((f=pwparse()) != PNULL) { ! 50: if(strcmp(user, f->lname) == 0) { ! 51: return(f->fname); ! 52: } ! 53: } ! 54: return(NULL); ! 55: } ! 56: ! 57: char * ! 58: pwuid(uid) ! 59: int uid; ! 60: { ! 61: pwlist *f; ! 62: ! 63: /* ! 64: ** check for previously cached user ! 65: */ ! 66: ! 67: for(f=pwhead; f != NULL; f=f->vlink) { ! 68: if(uid == f->uid) { ! 69: return(f->lname); ! 70: } ! 71: } ! 72: /* ! 73: ** not found parse the password file ! 74: */ ! 75: ! 76: while((f=pwparse()) != PNULL) { ! 77: if(uid == f->uid) { ! 78: return(f->lname); ! 79: } ! 80: } ! 81: return(NULL); ! 82: } ! 83: ! 84: #ifndef SENDMAIL ! 85: char * ! 86: tilde(user) ! 87: char *user; ! 88: { ! 89: pwlist *f; ! 90: ! 91: /* ! 92: ** check for previously cached user ! 93: */ ! 94: ! 95: for(f=pwhead; f != NULL; f=f->vlink) { ! 96: if(strcmp(user, f->lname) == 0) { ! 97: return(f->home); ! 98: } ! 99: } ! 100: /* ! 101: ** not found parse the password file ! 102: */ ! 103: ! 104: while((f=pwparse()) != PNULL) { ! 105: if(strcmp(user, f->lname) == 0) { ! 106: return(f->home); ! 107: } ! 108: } ! 109: return(NULL); ! 110: } ! 111: #endif /* not SENDMAIL */ ! 112: ! 113: char * ! 114: fullname(gecos) ! 115: char *gecos; ! 116: { ! 117: static char fname[SMLBUF]; ! 118: register char *cend; ! 119: ! 120: (void) strcpy(fname, gecos); ! 121: if (cend = index(fname, ',')) ! 122: *cend = '\0'; ! 123: if (cend = index(fname, '(')) ! 124: *cend = '\0'; ! 125: /* ! 126: ** Skip USG-style 0000-Name nonsense if necessary. ! 127: */ ! 128: if (isdigit(*(cend = fname))) { ! 129: if ((cend = index(fname, '-')) != NULL) ! 130: cend++; ! 131: else ! 132: /* ! 133: ** There was no `-' following digits. ! 134: */ ! 135: cend = fname; ! 136: } ! 137: return (cend); ! 138: } ! 139: ! 140: pwlist * ! 141: pwparse() ! 142: { ! 143: pwlist *f; ! 144: char *p, *name; ! 145: struct passwd *pwent, *getpwent(); ! 146: unsigned int i; ! 147: static int pw_eof = 0; ! 148: ! 149: if((pw_eof == 1) ! 150: || ((pwent = getpwent()) == (struct passwd *) NULL)) { ! 151: /* We've parsed and cached the entire passwd file. */ ! 152: pw_eof = 1; ! 153: endpwent(); ! 154: return(PNULL); ! 155: } ! 156: /* ! 157: ** Get an entry from the password file. ! 158: ** Parse relevant strings. ! 159: */ ! 160: f = (pwlist *) malloc(sizeof(pwlist)); ! 161: if(f == PNULL) return(PNULL); ! 162: ! 163: f->vlink = pwhead; ! 164: pwhead = f; ! 165: f->uid = pwent->pw_uid; ! 166: ! 167: i=strlen(pwent->pw_name)+1; ! 168: p = malloc(i); ! 169: if(p == NULL) return(PNULL); ! 170: f->lname = strcpy(p, pwent->pw_name); ! 171: ! 172: i=strlen(pwent->pw_dir)+1; ! 173: p = malloc(i); ! 174: if(p == NULL) return(PNULL); ! 175: f->home = strcpy(p, pwent->pw_dir); ! 176: ! 177: name = fullname(pwent->pw_gecos); ! 178: i=strlen(name)+1; ! 179: p = malloc(i); ! 180: if(p == NULL) return(PNULL); ! 181: f->fname = strcpy(p, name); ! 182: return(f); ! 183: } ! 184: ! 185: #ifdef FULLNAME ! 186: /* ! 187: ** Resolve a full name to a login name. ! 188: ** Not too much smarts here. ! 189: */ ! 190: ! 191: char * ! 192: res_fname(user) ! 193: register char *user; ! 194: { ! 195: long pos, middle, hi, lo; ! 196: static long pathlength = 0; ! 197: register char *s; ! 198: int c; ! 199: static FILE *file; ! 200: int flag; ! 201: char namebuf[SMLBUF], *path; ! 202: extern enum edebug debug; ! 203: extern char *fnlist; ! 204: ! 205: ! 206: ! 207: DEBUG("res_fname: looking for '%s'\n", user); ! 208: ! 209: if(pathlength == 0) { /* open file on first use */ ! 210: if((file=fopen(fnlist, "r")) == NULL) { ! 211: DEBUG( "can't access %s.\n", fnlist); ! 212: pathlength = -1; ! 213: } else { ! 214: (void) fseek(file, 0L, 2); /* find length */ ! 215: pathlength = ftell(file); ! 216: } ! 217: } ! 218: ! 219: if(pathlength == -1 ) return(NULL); ! 220: ! 221: lo = 0; ! 222: hi = pathlength; ! 223: path = namebuf; ! 224: ! 225: (void) strcpy( path, user ); ! 226: (void) strcat( path, "\t" ); ! 227: ! 228: for( ;; ) { ! 229: pos = middle = ( hi+lo+1 )/2; ! 230: (void) fseek( file, pos, 0 ); /* find midpoint */ ! 231: if (pos != 0) /* to beginning of next line */ ! 232: while( ( c=getc( file ) ) != EOF && c != '\n' ); ! 233: for( flag = 0, s = path; flag == 0; s++ ) { /* match??? */ ! 234: if ( *s == '\0' ) { ! 235: goto solved; ! 236: } ! 237: c = getc( file ); ! 238: flag = lower( c ) - lower( *s ); ! 239: } ! 240: if (lo >= middle) /* failure? */ ! 241: return(NULL); ! 242: ! 243: if(c != EOF && flag < 0) /* close window */ ! 244: lo = middle; ! 245: else ! 246: hi = middle - 1; ! 247: } ! 248: /* ! 249: ** Now just copy the result. ! 250: */ ! 251: solved: ! 252: while(((c = getc(file)) != EOF) && (c != '\t') && (c != '\n')) { ! 253: *path++ = c; ! 254: } ! 255: ! 256: if(path == namebuf) { /* NULL alias field */ ! 257: return(NULL); ! 258: } ! 259: ! 260: *path = '\0'; ! 261: if((path = malloc((unsigned) strlen(namebuf)+1)) == NULL) { ! 262: return(NULL); /* sorry, no memory */ ! 263: } ! 264: ! 265: (void) strcpy(path, namebuf); ! 266: return(path); ! 267: ! 268: } ! 269: #endif /* FULLNAME */
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.