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 /* try using memo */ 65 for(i = 0; i<nmemo; i++) { 66 mem = memo[i]; 67 if(matchnum) 68 matched = (mem->num == *pnum); 69 else 70 matched = (strcmp(mem->name, *pname) == 0); 71 if(matched) { 72 break; 73 } 74 } 75 if(!matched) 76 for(f1 = au, eline = au; !matched && *eline; f1 = eline+1){ 77 eline = strchr(f1, '\n'); 78 if(!eline) 79 eline = strchr(f1, 0); 80 if(*f1 == '#' || *f1 == '\n') 81 continue; 82 n = eline-f1; 83 f2 = memchr(f1, ':', n); 84 if(!f2) 85 continue; 86 f2++; 87 f3 = memchr(f2, ':', n-(f2-f1)); 88 if(!f3) 89 continue; 90 f3++; 91 f4 = memchr(f3, ':', n-(f3-f1)); 92 if(!f4) 93 continue; 94 f4++; 95 if(matchnum) 96 matched = (atoi(f1) == *pnum); 97 else 98 matched = (memcmp(*pname, f2, (f3-f2)-1)==0); 99 if(matched){ 100 /* allocate and fill in a Memo structure */ 101 mem = (Memo*)malloc(sizeof(struct Memo)); 102 if(!mem) 103 return 0; 104 m = (f3-f2)-1; 105 if(m > NAMEMAX-1) 106 m = NAMEMAX-1; 107 memcpy(mem->name, f2, m); 108 mem->name[m] = 0; 109 mem->num = atoi(f1); 110 m = n-(f4-f1); 111 if(m > 0){ 112 mem->glist = (char*)malloc(m+1); 113 if(mem->glist) { 114 memcpy(mem->glist, f4, m); 115 mem->glist[m] = 0; 116 } 117 } else 118 mem->glist = 0; 119 /* prepare for following move-to-front */ 120 if(nmemo == MEMOMAX) { 121 free(memo[nmemo-1]); 122 i = nmemo-1; 123 } else { 124 i = nmemo++; 125 } 126 } 127 } 128 if(matched) { 129 if(matchnum) 130 *pname = mem->name; 131 else 132 *pnum = mem->num; 133 if(plist) 134 *plist = mem->glist; 135 if(i > 0) { 136 /* make room at front */ 137 for(j = i; j > 0; j--) 138 memo[j] = memo[j-1]; 139 } 140 memo[0] = mem; 141 return 1; 142 } 143 return 0; 144 } 145 146 char ** 147 _grpmems(char *list) 148 { 149 char **v; 150 char *p; 151 static char *holdvec[200]; 152 static char holdlist[1000]; 153 154 p = list; 155 v = holdvec; 156 if(p) { 157 strncpy(holdlist, list, sizeof(holdlist)); 158 while(v< &holdvec[sizeof(holdvec)]-1 && *p){ 159 *v++ = p; 160 p = strchr(p, ','); 161 if(p){ 162 p++; 163 *p = 0; 164 }else 165 break; 166 } 167 } 168 *v = 0; 169 return holdvec; 170 } 171