1570af302Sopenharmony_ci#include "pwf.h"
2570af302Sopenharmony_ci#include <pthread.h>
3570af302Sopenharmony_ci
4570af302Sopenharmony_cistatic unsigned atou(char **s)
5570af302Sopenharmony_ci{
6570af302Sopenharmony_ci	unsigned x;
7570af302Sopenharmony_ci	for (x=0; **s-'0'<10U; ++*s) x=10*x+(**s-'0');
8570af302Sopenharmony_ci	return x;
9570af302Sopenharmony_ci}
10570af302Sopenharmony_ci
11570af302Sopenharmony_ciint __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res)
12570af302Sopenharmony_ci{
13570af302Sopenharmony_ci	ssize_t l;
14570af302Sopenharmony_ci	char *s;
15570af302Sopenharmony_ci	int rv = 0;
16570af302Sopenharmony_ci	int cs;
17570af302Sopenharmony_ci	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs);
18570af302Sopenharmony_ci	for (;;) {
19570af302Sopenharmony_ci		if ((l=getline(line, size, f)) < 0) {
20570af302Sopenharmony_ci			rv = ferror(f) ? errno : 0;
21570af302Sopenharmony_ci			free(*line);
22570af302Sopenharmony_ci			*line = 0;
23570af302Sopenharmony_ci			pw = 0;
24570af302Sopenharmony_ci			break;
25570af302Sopenharmony_ci		}
26570af302Sopenharmony_ci		line[0][l-1] = 0;
27570af302Sopenharmony_ci
28570af302Sopenharmony_ci		s = line[0];
29570af302Sopenharmony_ci		pw->pw_name = s++;
30570af302Sopenharmony_ci		if (!(s = strchr(s, ':'))) continue;
31570af302Sopenharmony_ci
32570af302Sopenharmony_ci		*s++ = 0; pw->pw_passwd = s;
33570af302Sopenharmony_ci		if (!(s = strchr(s, ':'))) continue;
34570af302Sopenharmony_ci
35570af302Sopenharmony_ci		*s++ = 0; pw->pw_uid = atou(&s);
36570af302Sopenharmony_ci		if (*s != ':') continue;
37570af302Sopenharmony_ci
38570af302Sopenharmony_ci		*s++ = 0; pw->pw_gid = atou(&s);
39570af302Sopenharmony_ci		if (*s != ':') continue;
40570af302Sopenharmony_ci
41570af302Sopenharmony_ci		*s++ = 0; pw->pw_gecos = s;
42570af302Sopenharmony_ci		if (!(s = strchr(s, ':'))) continue;
43570af302Sopenharmony_ci
44570af302Sopenharmony_ci		*s++ = 0; pw->pw_dir = s;
45570af302Sopenharmony_ci		if (!(s = strchr(s, ':'))) continue;
46570af302Sopenharmony_ci
47570af302Sopenharmony_ci		*s++ = 0; pw->pw_shell = s;
48570af302Sopenharmony_ci		break;
49570af302Sopenharmony_ci	}
50570af302Sopenharmony_ci	pthread_setcancelstate(cs, 0);
51570af302Sopenharmony_ci	*res = pw;
52570af302Sopenharmony_ci	if (rv) errno = rv;
53570af302Sopenharmony_ci	return rv;
54570af302Sopenharmony_ci}
55