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 18*219b2ee8SDavid du Colombier enum {NAMEMAX = 20, MEMOMAX = 40 }; 19*219b2ee8SDavid du Colombier 203e12c5d1SDavid du Colombier static char *admusers = "/adm/users"; 21*219b2ee8SDavid du Colombier 22*219b2ee8SDavid du Colombier /* we hold a fixed-length memo list of past lookups, and use a move-to-front 23*219b2ee8SDavid du Colombier strategy to organize the list 24*219b2ee8SDavid du Colombier */ 25*219b2ee8SDavid du Colombier typedef struct Memo { 26*219b2ee8SDavid du Colombier char name[NAMEMAX]; 27*219b2ee8SDavid du Colombier int num; 28*219b2ee8SDavid du Colombier char *glist; 29*219b2ee8SDavid du Colombier } Memo; 30*219b2ee8SDavid du Colombier 31*219b2ee8SDavid du Colombier static Memo *memo[MEMOMAX]; 32*219b2ee8SDavid du Colombier static int nmemo = 0; 333e12c5d1SDavid du Colombier 343e12c5d1SDavid du Colombier int 353e12c5d1SDavid du Colombier _getpw(int *pnum, char **pname, char **plist) 363e12c5d1SDavid du Colombier { 373e12c5d1SDavid du Colombier Dir d; 38*219b2ee8SDavid du Colombier int f, n, i, j, matchnum, m, matched; 393e12c5d1SDavid du Colombier char *eline, *f1, *f2, *f3, *f4; 40*219b2ee8SDavid du Colombier Memo *mem; 413e12c5d1SDavid du Colombier static char *au = NULL; 423e12c5d1SDavid du Colombier 433e12c5d1SDavid du Colombier if(!pname) 443e12c5d1SDavid du Colombier return 0; 453e12c5d1SDavid du Colombier if(au == NULL){ 463e12c5d1SDavid du Colombier char cd[DIRLEN]; 473e12c5d1SDavid du Colombier if(_STAT(admusers, cd) < 0) 483e12c5d1SDavid du Colombier return 0; 493e12c5d1SDavid du Colombier convM2D(cd, &d); 503e12c5d1SDavid du Colombier if((au = (char *)malloc(d.length+2)) == NULL) 513e12c5d1SDavid du Colombier return 0; 523e12c5d1SDavid du Colombier f = open(admusers, O_RDONLY); 533e12c5d1SDavid du Colombier if(f < 0) 543e12c5d1SDavid du Colombier return 0; 553e12c5d1SDavid du Colombier n = read(f, au, d.length); 563e12c5d1SDavid du Colombier close(f); 573e12c5d1SDavid du Colombier if(n < 0) 583e12c5d1SDavid du Colombier return 0; 593e12c5d1SDavid du Colombier au[n] = 0; 603e12c5d1SDavid du Colombier } 613e12c5d1SDavid du Colombier matchnum = (*pname == NULL); 623e12c5d1SDavid du Colombier matched = 0; 63*219b2ee8SDavid du Colombier /* try using memo */ 64*219b2ee8SDavid du Colombier for(i = 0; i<nmemo; i++) { 65*219b2ee8SDavid du Colombier mem = memo[i]; 66*219b2ee8SDavid du Colombier if(matchnum) 67*219b2ee8SDavid du Colombier matched = (mem->num == *pnum); 68*219b2ee8SDavid du Colombier else 69*219b2ee8SDavid du Colombier matched = (strcmp(mem->name, *pname) == 0); 70*219b2ee8SDavid du Colombier if(matched) { 71*219b2ee8SDavid du Colombier break; 72*219b2ee8SDavid du Colombier } 73*219b2ee8SDavid du Colombier } 74*219b2ee8SDavid du Colombier if(!matched) 75*219b2ee8SDavid du Colombier for(f1 = au, eline = au; !matched && *eline; f1 = eline+1){ 763e12c5d1SDavid du Colombier eline = strchr(f1, '\n'); 773e12c5d1SDavid du Colombier if(!eline) 783e12c5d1SDavid du Colombier eline = strchr(f1, 0); 793e12c5d1SDavid du Colombier if(*f1 == '#' || *f1 == '\n') 803e12c5d1SDavid du Colombier continue; 813e12c5d1SDavid du Colombier n = eline-f1; 823e12c5d1SDavid du Colombier f2 = memchr(f1, ':', n); 833e12c5d1SDavid du Colombier if(!f2) 843e12c5d1SDavid du Colombier continue; 853e12c5d1SDavid du Colombier f2++; 863e12c5d1SDavid du Colombier f3 = memchr(f2, ':', n-(f2-f1)); 873e12c5d1SDavid du Colombier if(!f3) 883e12c5d1SDavid du Colombier continue; 893e12c5d1SDavid du Colombier f3++; 903e12c5d1SDavid du Colombier f4 = memchr(f3, ':', n-(f3-f1)); 913e12c5d1SDavid du Colombier if(!f4) 923e12c5d1SDavid du Colombier continue; 933e12c5d1SDavid du Colombier f4++; 94*219b2ee8SDavid du Colombier if(matchnum) 95*219b2ee8SDavid du Colombier matched = (atoi(f1) == *pnum); 96*219b2ee8SDavid du Colombier else 97*219b2ee8SDavid du Colombier matched = (memcmp(*pname, f2, (f3-f2)-1)==0); 98*219b2ee8SDavid du Colombier if(matched){ 99*219b2ee8SDavid du Colombier /* allocate and fill in a Memo structure */ 100*219b2ee8SDavid du Colombier mem = (Memo*)malloc(sizeof(struct Memo)); 101*219b2ee8SDavid du Colombier if(!mem) 102*219b2ee8SDavid du Colombier return 0; 1033e12c5d1SDavid du Colombier m = (f3-f2)-1; 104*219b2ee8SDavid du Colombier if(m > NAMEMAX-1) 105*219b2ee8SDavid du Colombier m = NAMEMAX-1; 106*219b2ee8SDavid du Colombier memcpy(mem->name, f2, m); 107*219b2ee8SDavid du Colombier mem->name[m] = 0; 108*219b2ee8SDavid du Colombier mem->num = atoi(f1); 109*219b2ee8SDavid du Colombier m = n-(f4-f1); 110*219b2ee8SDavid du Colombier if(m > 0){ 111*219b2ee8SDavid du Colombier mem->glist = (char*)malloc(m+1); 112*219b2ee8SDavid du Colombier if(mem->glist) { 113*219b2ee8SDavid du Colombier memcpy(mem->glist, f4, m); 114*219b2ee8SDavid du Colombier mem->glist[m] = 0; 1153e12c5d1SDavid du Colombier } 116*219b2ee8SDavid du Colombier } else 117*219b2ee8SDavid du Colombier mem->glist = 0; 118*219b2ee8SDavid du Colombier /* prepare for following move-to-front */ 119*219b2ee8SDavid du Colombier if(nmemo == MEMOMAX) { 120*219b2ee8SDavid du Colombier free(memo[nmemo-1]); 121*219b2ee8SDavid du Colombier i = nmemo-1; 1223e12c5d1SDavid du Colombier } else { 123*219b2ee8SDavid du Colombier i = nmemo++; 124*219b2ee8SDavid du Colombier } 1253e12c5d1SDavid du Colombier } 1263e12c5d1SDavid du Colombier } 1273e12c5d1SDavid du Colombier if(matched) { 128*219b2ee8SDavid du Colombier if(matchnum) 129*219b2ee8SDavid du Colombier *pname = mem->name; 130*219b2ee8SDavid du Colombier else 131*219b2ee8SDavid du Colombier *pnum = mem->num; 132*219b2ee8SDavid du Colombier if(plist) 133*219b2ee8SDavid du Colombier *plist = mem->glist; 134*219b2ee8SDavid du Colombier if(i > 0) { 135*219b2ee8SDavid du Colombier /* make room at front */ 136*219b2ee8SDavid du Colombier for(j = i; j > 0; j--) 137*219b2ee8SDavid du Colombier memo[j] = memo[j-1]; 1383e12c5d1SDavid du Colombier } 139*219b2ee8SDavid du Colombier memo[0] = mem; 140*219b2ee8SDavid du Colombier return 1; 1413e12c5d1SDavid du Colombier } 1423e12c5d1SDavid du Colombier return 0; 1433e12c5d1SDavid du Colombier } 1443e12c5d1SDavid du Colombier 1453e12c5d1SDavid du Colombier char ** 1463e12c5d1SDavid du Colombier _grpmems(char *list) 1473e12c5d1SDavid du Colombier { 1483e12c5d1SDavid du Colombier char **v; 1493e12c5d1SDavid du Colombier char *p; 150*219b2ee8SDavid du Colombier static char *holdvec[200]; 151*219b2ee8SDavid du Colombier static char holdlist[1000]; 1523e12c5d1SDavid du Colombier 1533e12c5d1SDavid du Colombier p = list; 1543e12c5d1SDavid du Colombier v = holdvec; 155*219b2ee8SDavid du Colombier if(p) { 156*219b2ee8SDavid du Colombier strncpy(holdlist, list, sizeof(holdlist)); 1573e12c5d1SDavid du Colombier while(v< &holdvec[sizeof(holdvec)]-1 && *p){ 1583e12c5d1SDavid du Colombier *v++ = p; 1593e12c5d1SDavid du Colombier p = strchr(p, ','); 1603e12c5d1SDavid du Colombier if(p){ 1613e12c5d1SDavid du Colombier p++; 1623e12c5d1SDavid du Colombier *p = 0; 1633e12c5d1SDavid du Colombier }else 1643e12c5d1SDavid du Colombier break; 1653e12c5d1SDavid du Colombier } 166*219b2ee8SDavid du Colombier } 1673e12c5d1SDavid du Colombier *v = 0; 1683e12c5d1SDavid du Colombier return holdvec; 1693e12c5d1SDavid du Colombier } 170