|
|
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.