| #include "pwf.h" |
| #include <pthread.h> |
| |
| static unsigned atou(char **s) |
| { |
| unsigned x; |
| for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0'); |
| return x; |
| } |
| |
| int __getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem, struct group **res) |
| { |
| ssize_t l; |
| char *s, *mems; |
| size_t i; |
| int rv = 0; |
| int cs; |
| pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); |
| for (;;) { |
| if ((l=getline(line, size, f)) < 0) { |
| rv = ferror(f) ? errno : 0; |
| free(*line); |
| *line = 0; |
| gr = 0; |
| goto end; |
| } |
| line[0][l-1] = 0; |
| |
| s = line[0]; |
| gr->gr_name = s++; |
| if (!(s = strchr(s, ':'))) continue; |
| |
| *s++ = 0; gr->gr_passwd = s; |
| if (!(s = strchr(s, ':'))) continue; |
| |
| *s++ = 0; gr->gr_gid = atou(&s); |
| if (*s != ':') continue; |
| |
| *s++ = 0; mems = s; |
| break; |
| } |
| |
| for (*nmem=!!*s; *s; s++) |
| if (*s==',') ++*nmem; |
| free(*mem); |
| *mem = calloc(sizeof(char *), *nmem+1); |
| if (!*mem) { |
| rv = errno; |
| free(*line); |
| *line = 0; |
| gr = 0; |
| goto end; |
| } |
| if (*mems) { |
| mem[0][0] = mems; |
| for (s=mems, i=0; *s; s++) |
| if (*s==',') *s++ = 0, mem[0][++i] = s; |
| mem[0][++i] = 0; |
| } else { |
| mem[0][0] = 0; |
| } |
| gr->gr_mem = *mem; |
| end: |
| pthread_setcancelstate(cs, 0); |
| *res = gr; |
| if(rv) errno = rv; |
| return rv; |
| } |