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 } 176