getgrent_a.c 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. #include "pwf.h"
  2. #include <pthread.h>
  3. static unsigned atou(char **s)
  4. {
  5. unsigned x;
  6. for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
  7. return x;
  8. }
  9. int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res)
  10. {
  11. ssize_t l;
  12. char *s, *mems;
  13. size_t i;
  14. int rv = 0;
  15. int cs;
  16. pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
  17. for (;;) {
  18. if ((l=getline(line, size, f)) < 0) {
  19. rv = ferror(f) ? errno : 0;
  20. free(*line);
  21. *line = 0;
  22. gr = 0;
  23. goto end;
  24. }
  25. line[0][l-1] = 0;
  26. s = line[0];
  27. gr->gr_name = s++;
  28. if (!(s = strchr(s, ':'))) continue;
  29. *s++ = 0; gr->gr_passwd = s;
  30. if (!(s = strchr(s, ':'))) continue;
  31. *s++ = 0; gr->gr_gid = atou(&s);
  32. if (*s != ':') continue;
  33. *s++ = 0; mems = s;
  34. break;
  35. }
  36. for (*nmem=!!*s; *s; s++)
  37. if (*s==',') ++*nmem;
  38. free(*mem);
  39. *mem = calloc(sizeof(char *), *nmem+1);
  40. if (!*mem) {
  41. rv = errno;
  42. free(*line);
  43. *line = 0;
  44. gr = 0;
  45. goto end;
  46. }
  47. if (*mems) {
  48. mem[0][0] = mems;
  49. for (s=mems, i=0; *s; s++)
  50. if (*s==',') *s++ = 0, mem[0][++i] = s;
  51. mem[0][++i] = 0;
  52. } else {
  53. mem[0][0] = 0;
  54. }
  55. gr->gr_mem = *mem;
  56. end:
  57. pthread_setcancelstate(cs, 0);
  58. *res = gr;
  59. if(rv) errno = rv;
  60. return rv;
  61. }