13e12c5d1SDavid du Colombier #include "lib.h"
23e12c5d1SDavid du Colombier #include <sys/types.h>
33e12c5d1SDavid du Colombier #include <sys/stat.h>
43e12c5d1SDavid du Colombier #include <fcntl.h>
53e12c5d1SDavid du Colombier #include <stdlib.h>
63e12c5d1SDavid du Colombier #include <string.h>
73e12c5d1SDavid du Colombier #include <unistd.h>
83e12c5d1SDavid du Colombier #include "sys9.h"
93e12c5d1SDavid du Colombier #include "dir.h"
103e12c5d1SDavid du Colombier
113e12c5d1SDavid du Colombier /*
123e12c5d1SDavid du Colombier * Search /adm/users for line with second field == *pname (if
133e12c5d1SDavid du Colombier * not NULL), else with first field == *pnum. Return non-zero
143e12c5d1SDavid du Colombier * if found, and fill in *pnum, *pname, and *plist to fields
153e12c5d1SDavid du Colombier * 1, 2, and 4
163e12c5d1SDavid du Colombier */
173e12c5d1SDavid du Colombier
18219b2ee8SDavid du Colombier enum {NAMEMAX = 20, MEMOMAX = 40 };
19219b2ee8SDavid du Colombier
203e12c5d1SDavid du Colombier static char *admusers = "/adm/users";
21219b2ee8SDavid du Colombier
22219b2ee8SDavid du Colombier /* we hold a fixed-length memo list of past lookups, and use a move-to-front
23219b2ee8SDavid du Colombier strategy to organize the list
24219b2ee8SDavid du Colombier */
25219b2ee8SDavid du Colombier typedef struct Memo {
26219b2ee8SDavid du Colombier char name[NAMEMAX];
27219b2ee8SDavid du Colombier int num;
28219b2ee8SDavid du Colombier char *glist;
29219b2ee8SDavid du Colombier } Memo;
30219b2ee8SDavid du Colombier
31219b2ee8SDavid du Colombier static Memo *memo[MEMOMAX];
32219b2ee8SDavid du Colombier static int nmemo = 0;
333e12c5d1SDavid du Colombier
343e12c5d1SDavid du Colombier int
_getpw(int * pnum,char ** pname,char ** plist)353e12c5d1SDavid du Colombier _getpw(int *pnum, char **pname, char **plist)
363e12c5d1SDavid du Colombier {
379a747e4fSDavid du Colombier Dir *d;
38219b2ee8SDavid du Colombier int f, n, i, j, matchnum, m, matched;
393e12c5d1SDavid du Colombier char *eline, *f1, *f2, *f3, *f4;
40219b2ee8SDavid du Colombier Memo *mem;
413e12c5d1SDavid du Colombier static char *au = NULL;
429a747e4fSDavid du Colombier vlong length;
433e12c5d1SDavid du Colombier
443e12c5d1SDavid du Colombier if(!pname)
453e12c5d1SDavid du Colombier return 0;
463e12c5d1SDavid du Colombier if(au == NULL){
479a747e4fSDavid du Colombier d = _dirstat(admusers);
489a747e4fSDavid du Colombier if(d == nil)
493e12c5d1SDavid du Colombier return 0;
509a747e4fSDavid du Colombier length = d->length;
519a747e4fSDavid du Colombier free(d);
529a747e4fSDavid du Colombier if((au = (char *)malloc(length+2)) == NULL)
533e12c5d1SDavid du Colombier return 0;
543e12c5d1SDavid du Colombier f = open(admusers, O_RDONLY);
553e12c5d1SDavid du Colombier if(f < 0)
563e12c5d1SDavid du Colombier return 0;
579a747e4fSDavid du Colombier n = read(f, au, length);
583e12c5d1SDavid du Colombier if(n < 0)
593e12c5d1SDavid du Colombier return 0;
603e12c5d1SDavid du Colombier au[n] = 0;
613e12c5d1SDavid du Colombier }
623e12c5d1SDavid du Colombier matchnum = (*pname == NULL);
633e12c5d1SDavid du Colombier matched = 0;
64*781103c4SDavid du Colombier mem = nil;
65219b2ee8SDavid du Colombier /* try using memo */
66219b2ee8SDavid du Colombier for(i = 0; i<nmemo; i++) {
67219b2ee8SDavid du Colombier mem = memo[i];
68219b2ee8SDavid du Colombier if(matchnum)
69219b2ee8SDavid du Colombier matched = (mem->num == *pnum);
70219b2ee8SDavid du Colombier else
71219b2ee8SDavid du Colombier matched = (strcmp(mem->name, *pname) == 0);
72219b2ee8SDavid du Colombier if(matched) {
73219b2ee8SDavid du Colombier break;
74219b2ee8SDavid du Colombier }
75219b2ee8SDavid du Colombier }
76219b2ee8SDavid du Colombier if(!matched)
77219b2ee8SDavid du Colombier for(f1 = au, eline = au; !matched && *eline; f1 = eline+1){
783e12c5d1SDavid du Colombier eline = strchr(f1, '\n');
793e12c5d1SDavid du Colombier if(!eline)
803e12c5d1SDavid du Colombier eline = strchr(f1, 0);
813e12c5d1SDavid du Colombier if(*f1 == '#' || *f1 == '\n')
823e12c5d1SDavid du Colombier continue;
833e12c5d1SDavid du Colombier n = eline-f1;
843e12c5d1SDavid du Colombier f2 = memchr(f1, ':', n);
853e12c5d1SDavid du Colombier if(!f2)
863e12c5d1SDavid du Colombier continue;
873e12c5d1SDavid du Colombier f2++;
883e12c5d1SDavid du Colombier f3 = memchr(f2, ':', n-(f2-f1));
893e12c5d1SDavid du Colombier if(!f3)
903e12c5d1SDavid du Colombier continue;
913e12c5d1SDavid du Colombier f3++;
923e12c5d1SDavid du Colombier f4 = memchr(f3, ':', n-(f3-f1));
933e12c5d1SDavid du Colombier if(!f4)
943e12c5d1SDavid du Colombier continue;
953e12c5d1SDavid du Colombier f4++;
96219b2ee8SDavid du Colombier if(matchnum)
97219b2ee8SDavid du Colombier matched = (atoi(f1) == *pnum);
987def40e1SDavid du Colombier else{
997def40e1SDavid du Colombier int length;
1007def40e1SDavid du Colombier
1017def40e1SDavid du Colombier length = f3-f2-1;
1027def40e1SDavid du Colombier matched = length==strlen(*pname) && memcmp(*pname, f2, length)==0;
1037def40e1SDavid du Colombier }
104219b2ee8SDavid du Colombier if(matched){
105219b2ee8SDavid du Colombier /* allocate and fill in a Memo structure */
106219b2ee8SDavid du Colombier mem = (Memo*)malloc(sizeof(struct Memo));
107219b2ee8SDavid du Colombier if(!mem)
108219b2ee8SDavid du Colombier return 0;
1093e12c5d1SDavid du Colombier m = (f3-f2)-1;
110219b2ee8SDavid du Colombier if(m > NAMEMAX-1)
111219b2ee8SDavid du Colombier m = NAMEMAX-1;
112219b2ee8SDavid du Colombier memcpy(mem->name, f2, m);
113219b2ee8SDavid du Colombier mem->name[m] = 0;
114219b2ee8SDavid du Colombier mem->num = atoi(f1);
115219b2ee8SDavid du Colombier m = n-(f4-f1);
116219b2ee8SDavid du Colombier if(m > 0){
117219b2ee8SDavid du Colombier mem->glist = (char*)malloc(m+1);
118219b2ee8SDavid du Colombier if(mem->glist) {
119219b2ee8SDavid du Colombier memcpy(mem->glist, f4, m);
120219b2ee8SDavid du Colombier mem->glist[m] = 0;
1213e12c5d1SDavid du Colombier }
122219b2ee8SDavid du Colombier } else
123219b2ee8SDavid du Colombier mem->glist = 0;
124219b2ee8SDavid du Colombier /* prepare for following move-to-front */
125219b2ee8SDavid du Colombier if(nmemo == MEMOMAX) {
126219b2ee8SDavid du Colombier free(memo[nmemo-1]);
127219b2ee8SDavid du Colombier i = nmemo-1;
1283e12c5d1SDavid du Colombier } else {
129219b2ee8SDavid du Colombier i = nmemo++;
130219b2ee8SDavid du Colombier }
1313e12c5d1SDavid du Colombier }
1323e12c5d1SDavid du Colombier }
1333e12c5d1SDavid du Colombier if(matched) {
134219b2ee8SDavid du Colombier if(matchnum)
135219b2ee8SDavid du Colombier *pname = mem->name;
136219b2ee8SDavid du Colombier else
137219b2ee8SDavid du Colombier *pnum = mem->num;
138219b2ee8SDavid du Colombier if(plist)
139219b2ee8SDavid du Colombier *plist = mem->glist;
140219b2ee8SDavid du Colombier if(i > 0) {
141219b2ee8SDavid du Colombier /* make room at front */
142219b2ee8SDavid du Colombier for(j = i; j > 0; j--)
143219b2ee8SDavid du Colombier memo[j] = memo[j-1];
1443e12c5d1SDavid du Colombier }
145219b2ee8SDavid du Colombier memo[0] = mem;
146219b2ee8SDavid du Colombier return 1;
1473e12c5d1SDavid du Colombier }
1483e12c5d1SDavid du Colombier return 0;
1493e12c5d1SDavid du Colombier }
1503e12c5d1SDavid du Colombier
1513e12c5d1SDavid du Colombier char **
_grpmems(char * list)1523e12c5d1SDavid du Colombier _grpmems(char *list)
1533e12c5d1SDavid du Colombier {
1543e12c5d1SDavid du Colombier char **v;
1553e12c5d1SDavid du Colombier char *p;
156219b2ee8SDavid du Colombier static char *holdvec[200];
157219b2ee8SDavid du Colombier static char holdlist[1000];
1583e12c5d1SDavid du Colombier
1593e12c5d1SDavid du Colombier p = list;
1603e12c5d1SDavid du Colombier v = holdvec;
161219b2ee8SDavid du Colombier if(p) {
162219b2ee8SDavid du Colombier strncpy(holdlist, list, sizeof(holdlist));
1633e12c5d1SDavid du Colombier while(v< &holdvec[sizeof(holdvec)]-1 && *p){
1643e12c5d1SDavid du Colombier *v++ = p;
1653e12c5d1SDavid du Colombier p = strchr(p, ',');
1663e12c5d1SDavid du Colombier if(p){
1673e12c5d1SDavid du Colombier p++;
1683e12c5d1SDavid du Colombier *p = 0;
1693e12c5d1SDavid du Colombier }else
1703e12c5d1SDavid du Colombier break;
1713e12c5d1SDavid du Colombier }
172219b2ee8SDavid du Colombier }
1733e12c5d1SDavid du Colombier *v = 0;
1743e12c5d1SDavid du Colombier return holdvec;
1753e12c5d1SDavid du Colombier }
176