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