_getpw.c 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  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. matched = (memcmp(*pname, f2, (f3-f2)-1)==0);
  92. if(matched){
  93. /* allocate and fill in a Memo structure */
  94. mem = (Memo*)malloc(sizeof(struct Memo));
  95. if(!mem)
  96. return 0;
  97. m = (f3-f2)-1;
  98. if(m > NAMEMAX-1)
  99. m = NAMEMAX-1;
  100. memcpy(mem->name, f2, m);
  101. mem->name[m] = 0;
  102. mem->num = atoi(f1);
  103. m = n-(f4-f1);
  104. if(m > 0){
  105. mem->glist = (char*)malloc(m+1);
  106. if(mem->glist) {
  107. memcpy(mem->glist, f4, m);
  108. mem->glist[m] = 0;
  109. }
  110. } else
  111. mem->glist = 0;
  112. /* prepare for following move-to-front */
  113. if(nmemo == MEMOMAX) {
  114. free(memo[nmemo-1]);
  115. i = nmemo-1;
  116. } else {
  117. i = nmemo++;
  118. }
  119. }
  120. }
  121. if(matched) {
  122. if(matchnum)
  123. *pname = mem->name;
  124. else
  125. *pnum = mem->num;
  126. if(plist)
  127. *plist = mem->glist;
  128. if(i > 0) {
  129. /* make room at front */
  130. for(j = i; j > 0; j--)
  131. memo[j] = memo[j-1];
  132. }
  133. memo[0] = mem;
  134. return 1;
  135. }
  136. return 0;
  137. }
  138. char **
  139. _grpmems(char *list)
  140. {
  141. char **v;
  142. char *p;
  143. static char *holdvec[200];
  144. static char holdlist[1000];
  145. p = list;
  146. v = holdvec;
  147. if(p) {
  148. strncpy(holdlist, list, sizeof(holdlist));
  149. while(v< &holdvec[sizeof(holdvec)]-1 && *p){
  150. *v++ = p;
  151. p = strchr(p, ',');
  152. if(p){
  153. p++;
  154. *p = 0;
  155. }else
  156. break;
  157. }
  158. }
  159. *v = 0;
  160. return holdvec;
  161. }