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