From e5888a1ffdae813d7575f5fb02275c6bb07e5199 Mon Sep 17 00:00:00 2001 From: Taru Karttunen Date: Wed, 30 Mar 2011 15:46:40 +0300 Subject: Import sources from 2011-03-30 iso image --- sys/src/ape/lib/ap/plan9/_getpw.c | 174 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 174 insertions(+) create mode 100755 sys/src/ape/lib/ap/plan9/_getpw.c (limited to 'sys/src/ape/lib/ap/plan9/_getpw.c') diff --git a/sys/src/ape/lib/ap/plan9/_getpw.c b/sys/src/ape/lib/ap/plan9/_getpw.c new file mode 100755 index 000000000..151d7f3c8 --- /dev/null +++ b/sys/src/ape/lib/ap/plan9/_getpw.c @@ -0,0 +1,174 @@ +#include "lib.h" +#include +#include +#include +#include +#include +#include +#include "sys9.h" +#include "dir.h" + +/* + * Search /adm/users for line with second field == *pname (if + * not NULL), else with first field == *pnum. Return non-zero + * if found, and fill in *pnum, *pname, and *plist to fields + * 1, 2, and 4 + */ + +enum {NAMEMAX = 20, MEMOMAX = 40 }; + +static char *admusers = "/adm/users"; + +/* we hold a fixed-length memo list of past lookups, and use a move-to-front + strategy to organize the list +*/ +typedef struct Memo { + char name[NAMEMAX]; + int num; + char *glist; +} Memo; + +static Memo *memo[MEMOMAX]; +static int nmemo = 0; + +int +_getpw(int *pnum, char **pname, char **plist) +{ + Dir *d; + int f, n, i, j, matchnum, m, matched; + char *eline, *f1, *f2, *f3, *f4; + Memo *mem; + static char *au = NULL; + vlong length; + + if(!pname) + return 0; + if(au == NULL){ + d = _dirstat(admusers); + if(d == nil) + return 0; + length = d->length; + free(d); + if((au = (char *)malloc(length+2)) == NULL) + return 0; + f = open(admusers, O_RDONLY); + if(f < 0) + return 0; + n = read(f, au, length); + if(n < 0) + return 0; + au[n] = 0; + } + matchnum = (*pname == NULL); + matched = 0; + /* try using memo */ + for(i = 0; inum == *pnum); + else + matched = (strcmp(mem->name, *pname) == 0); + if(matched) { + break; + } + } + if(!matched) + for(f1 = au, eline = au; !matched && *eline; f1 = eline+1){ + eline = strchr(f1, '\n'); + if(!eline) + eline = strchr(f1, 0); + if(*f1 == '#' || *f1 == '\n') + continue; + n = eline-f1; + f2 = memchr(f1, ':', n); + if(!f2) + continue; + f2++; + f3 = memchr(f2, ':', n-(f2-f1)); + if(!f3) + continue; + f3++; + f4 = memchr(f3, ':', n-(f3-f1)); + if(!f4) + continue; + f4++; + if(matchnum) + matched = (atoi(f1) == *pnum); + else{ + int length; + + length = f3-f2-1; + matched = length==strlen(*pname) && memcmp(*pname, f2, length)==0; + } + if(matched){ + /* allocate and fill in a Memo structure */ + mem = (Memo*)malloc(sizeof(struct Memo)); + if(!mem) + return 0; + m = (f3-f2)-1; + if(m > NAMEMAX-1) + m = NAMEMAX-1; + memcpy(mem->name, f2, m); + mem->name[m] = 0; + mem->num = atoi(f1); + m = n-(f4-f1); + if(m > 0){ + mem->glist = (char*)malloc(m+1); + if(mem->glist) { + memcpy(mem->glist, f4, m); + mem->glist[m] = 0; + } + } else + mem->glist = 0; + /* prepare for following move-to-front */ + if(nmemo == MEMOMAX) { + free(memo[nmemo-1]); + i = nmemo-1; + } else { + i = nmemo++; + } + } + } + if(matched) { + if(matchnum) + *pname = mem->name; + else + *pnum = mem->num; + if(plist) + *plist = mem->glist; + if(i > 0) { + /* make room at front */ + for(j = i; j > 0; j--) + memo[j] = memo[j-1]; + } + memo[0] = mem; + return 1; + } + return 0; +} + +char ** +_grpmems(char *list) +{ + char **v; + char *p; + static char *holdvec[200]; + static char holdlist[1000]; + + p = list; + v = holdvec; + if(p) { + strncpy(holdlist, list, sizeof(holdlist)); + while(v< &holdvec[sizeof(holdvec)]-1 && *p){ + *v++ = p; + p = strchr(p, ','); + if(p){ + p++; + *p = 0; + }else + break; + } + } + *v = 0; + return holdvec; +} -- cgit v1.2.3