| #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 __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res) |
| { |
| ssize_t l; |
| char *s; |
| 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; |
| pw = 0; |
| break; |
| } |
| line[0][l-1] = 0; |
| |
| s = line[0]; |
| pw->pw_name = s++; |
| if (!(s = strchr(s, ':'))) continue; |
| |
| *s++ = 0; pw->pw_passwd = s; |
| if (!(s = strchr(s, ':'))) continue; |
| |
| *s++ = 0; pw->pw_uid = atou(&s); |
| if (*s != ':') continue; |
| |
| *s++ = 0; pw->pw_gid = atou(&s); |
| if (*s != ':') continue; |
| |
| *s++ = 0; pw->pw_gecos = s; |
| if (!(s = strchr(s, ':'))) continue; |
| |
| *s++ = 0; pw->pw_dir = s; |
| if (!(s = strchr(s, ':'))) continue; |
| |
| *s++ = 0; pw->pw_shell = s; |
| break; |
| } |
| pthread_setcancelstate(cs, 0); |
| *res = pw; |
| if (rv) errno = rv; |
| return rv; |
| } |