Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "lib.h"
2
#include <sys/types.h>
3
#include <sys/stat.h>
4
#include <fcntl.h>
5
#include <stdlib.h>
6
#include <string.h>
7
#include <unistd.h>
8
#include "sys9.h"
9
#include "dir.h"
10
 
11
/*
12
 * Search /adm/users for line with second field ==  *pname (if
13
 * not NULL), else with first field == *pnum.  Return non-zero
14
 * if found, and fill in *pnum, *pname, and *plist to fields
15
 * 1, 2, and 4
16
 */
17
 
18
enum {NAMEMAX = 20, MEMOMAX = 40 };
19
 
20
static char *admusers = "/adm/users";
21
 
22
/* we hold a fixed-length memo list of past lookups, and use a move-to-front
23
    strategy to organize the list
24
*/
25
typedef struct Memo {
26
	char		name[NAMEMAX];
27
	int		num;
28
	char		*glist;
29
} Memo;
30
 
31
static Memo *memo[MEMOMAX];
32
static int nmemo = 0;
33
 
34
int
35
_getpw(int *pnum, char **pname, char **plist)
36
{
37
	Dir *d;
38
	int f, n, i, j, matchnum, m, matched;
39
	char *eline, *f1, *f2, *f3, *f4;
40
	Memo *mem;
41
	static char *au = NULL;
42
	vlong length;
43
 
44
	if(!pname)
45
		return 0;
46
	if(au == NULL){
47
		d = _dirstat(admusers);
48
		if(d == nil)
49
			return 0;
50
		length = d->length;
51
		free(d);
52
		if((au = (char *)malloc(length+2)) == NULL)
53
			return 0;
54
		f = open(admusers, O_RDONLY);
55
		if(f < 0)
56
			return 0;
57
		n = read(f, au, length);
58
		if(n < 0)
59
			return 0;
60
		au[n] = 0;
61
	}
62
	matchnum = (*pname == NULL);
63
	matched = 0;
64
	mem = nil;
65
	/* try using memo */
66
	for(i = 0; i<nmemo; i++) {
67
		mem = memo[i];
68
		if(matchnum)
69
			matched = (mem->num == *pnum);
70
		else
71
			matched = (strcmp(mem->name, *pname) == 0);
72
		if(matched) {
73
			break;
74
		}
75
	}
76
	if(!matched)
77
		for(f1 = au, eline = au; !matched && *eline; f1 = eline+1){
78
			eline = strchr(f1, '\n');
79
			if(!eline)
80
				eline = strchr(f1, 0);
81
			if(*f1 == '#' || *f1 == '\n')
82
				continue;
83
			n = eline-f1;
84
			f2 = memchr(f1, ':', n);
85
			if(!f2)
86
				continue;
87
			f2++;
88
			f3 = memchr(f2, ':', n-(f2-f1));
89
			if(!f3)
90
				continue;
91
			f3++;
92
			f4 = memchr(f3, ':', n-(f3-f1));
93
			if(!f4)
94
				continue;
95
			f4++;
96
			if(matchnum)
97
				matched = (atoi(f1) == *pnum);
98
			else{
99
				int length;
100
 
101
				length = f3-f2-1;
102
				matched = length==strlen(*pname) && memcmp(*pname, f2, length)==0;
103
			}
104
			if(matched){
105
				/* allocate and fill in a Memo structure */
106
				mem = (Memo*)malloc(sizeof(struct Memo));
107
				if(!mem)
108
					return 0;
109
				m = (f3-f2)-1;
110
				if(m > NAMEMAX-1)
111
					m = NAMEMAX-1;
112
				memcpy(mem->name, f2, m);
113
				mem->name[m] = 0;
114
				mem->num = atoi(f1);
115
				m = n-(f4-f1);
116
				if(m > 0){
117
					mem->glist = (char*)malloc(m+1);
118
					if(mem->glist) {
119
						memcpy(mem->glist, f4, m);
120
						mem->glist[m] = 0;
121
					}
122
				} else
123
					mem->glist = 0;
124
				/* prepare for following move-to-front */
125
				if(nmemo == MEMOMAX) {
126
					free(memo[nmemo-1]);
127
					i = nmemo-1;
128
				} else {
129
					i = nmemo++;
130
				}
131
			}
132
		}
133
	if(matched) {
134
		if(matchnum)
135
			*pname = mem->name;
136
		else
137
			*pnum = mem->num;
138
		if(plist)
139
			*plist = mem->glist;
140
		if(i > 0) {
141
			/* make room at front */
142
			for(j = i; j > 0; j--)
143
				memo[j] = memo[j-1];
144
		}
145
		memo[0] = mem;
146
		return 1;
147
	}
148
	return 0;
149
}
150
 
151
char **
152
_grpmems(char *list)
153
{
154
	char **v;
155
	char *p;
156
	static char *holdvec[200];
157
	static char holdlist[1000];
158
 
159
	p = list;
160
	v = holdvec;
161
	if(p) {
162
		strncpy(holdlist, list, sizeof(holdlist));
163
		while(v< &holdvec[sizeof(holdvec)]-1 && *p){
164
			*v++ = p;
165
			p = strchr(p, ',');
166
			if(p){
167
				p++;
168
				*p = 0;
169
			}else
170
				break;
171
		}
172
	}
173
	*v = 0;
174
	return holdvec;
175
}