_getpw.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  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. * Search /adm/users for line with second field == *pname (if
  12. * not NULL), else with first field == *pnum. Return non-zero
  13. * if found, and fill in *pnum, *pname, and *plist to fields
  14. * 1, 2, and 4
  15. */
  16. enum {NAMEMAX = 20, MEMOMAX = 40 };
  17. static char *admusers = "/adm/users";
  18. /* we hold a fixed-length memo list of past lookups, and use a move-to-front
  19. strategy to organize the list
  20. */
  21. typedef struct Memo {
  22. char name[NAMEMAX];
  23. int num;
  24. char *glist;
  25. } Memo;
  26. static Memo *memo[MEMOMAX];
  27. static int nmemo = 0;
  28. int
  29. _getpw(int *pnum, char **pname, char **plist)
  30. {
  31. Dir *d;
  32. int f, n, i, j, matchnum, m, matched;
  33. char *eline, *f1, *f2, *f3, *f4;
  34. Memo *mem;
  35. static char *au = NULL;
  36. vlong length;
  37. if(!pname)
  38. return 0;
  39. if(au == NULL){
  40. d = _dirstat(admusers);
  41. if(d == nil)
  42. return 0;
  43. length = d->length;
  44. free(d);
  45. if((au = (char *)malloc(length+2)) == NULL)
  46. return 0;
  47. f = open(admusers, O_RDONLY);
  48. if(f < 0)
  49. return 0;
  50. n = read(f, au, length);
  51. if(n < 0)
  52. return 0;
  53. au[n] = 0;
  54. }
  55. matchnum = (*pname == NULL);
  56. matched = 0;
  57. /* try using memo */
  58. for(i = 0; i<nmemo; i++) {
  59. mem = memo[i];
  60. if(matchnum)
  61. matched = (mem->num == *pnum);
  62. else
  63. matched = (strcmp(mem->name, *pname) == 0);
  64. if(matched) {
  65. break;
  66. }
  67. }
  68. if(!matched)
  69. for(f1 = au, eline = au; !matched && *eline; f1 = eline+1){
  70. eline = strchr(f1, '\n');
  71. if(!eline)
  72. eline = strchr(f1, 0);
  73. if(*f1 == '#' || *f1 == '\n')
  74. continue;
  75. n = eline-f1;
  76. f2 = memchr(f1, ':', n);
  77. if(!f2)
  78. continue;
  79. f2++;
  80. f3 = memchr(f2, ':', n-(f2-f1));
  81. if(!f3)
  82. continue;
  83. f3++;
  84. f4 = memchr(f3, ':', n-(f3-f1));
  85. if(!f4)
  86. continue;
  87. f4++;
  88. if(matchnum)
  89. matched = (atoi(f1) == *pnum);
  90. else{
  91. int length;
  92. length = f3-f2-1;
  93. matched = length==strlen(*pname) && memcmp(*pname, f2, length)==0;
  94. }
  95. if(matched){
  96. /* allocate and fill in a Memo structure */
  97. mem = (Memo*)malloc(sizeof(struct Memo));
  98. if(!mem)
  99. return 0;
  100. m = (f3-f2)-1;
  101. if(m > NAMEMAX-1)
  102. m = NAMEMAX-1;
  103. memcpy(mem->name, f2, m);
  104. mem->name[m] = 0;
  105. mem->num = atoi(f1);
  106. m = n-(f4-f1);
  107. if(m > 0){
  108. mem->glist = (char*)malloc(m+1);
  109. if(mem->glist) {
  110. memcpy(mem->glist, f4, m);
  111. mem->glist[m] = 0;
  112. }
  113. } else
  114. mem->glist = 0;
  115. /* prepare for following move-to-front */
  116. if(nmemo == MEMOMAX) {
  117. free(memo[nmemo-1]);
  118. i = nmemo-1;
  119. } else {
  120. i = nmemo++;
  121. }
  122. }
  123. }
  124. if(matched) {
  125. if(matchnum)
  126. *pname = mem->name;
  127. else
  128. *pnum = mem->num;
  129. if(plist)
  130. *plist = mem->glist;
  131. if(i > 0) {
  132. /* make room at front */
  133. for(j = i; j > 0; j--)
  134. memo[j] = memo[j-1];
  135. }
  136. memo[0] = mem;
  137. return 1;
  138. }
  139. return 0;
  140. }
  141. char **
  142. _grpmems(char *list)
  143. {
  144. char **v;
  145. char *p;
  146. static char *holdvec[200];
  147. static char holdlist[1000];
  148. p = list;
  149. v = holdvec;
  150. if(p) {
  151. strncpy(holdlist, list, sizeof(holdlist));
  152. while(v< &holdvec[sizeof(holdvec)]-1 && *p){
  153. *v++ = p;
  154. p = strchr(p, ',');
  155. if(p){
  156. p++;
  157. *p = 0;
  158. }else
  159. break;
  160. }
  161. }
  162. *v = 0;
  163. return holdvec;
  164. }