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