1 /* getpwent(), getpwuid(), getpwnam() - password file routines
11 #include <sys/types.h>
18 #define arraysize(a) (sizeof(a) / sizeof((a)[0]))
19 #define arraylimit(a) ((a) + arraysize(a))
21 static char PASSWD
[]= "/etc/passwd"; /* The password file. */
22 static const char *pwfile
; /* Current password file. */
24 static char buf
[1024]; /* Read buffer. */
25 static char pwline
[256]; /* One line from the password file. */
26 static struct passwd entry
; /* Entry to fill and return. */
27 static int pwfd
= -1; /* Filedescriptor to the file. */
28 static char *bufptr
; /* Place in buf. */
29 static ssize_t buflen
= 0; /* Remaining characters in buf. */
30 static char *lineptr
; /* Place in the line. */
33 /* Close the password file. */
43 /* Open the password file. */
45 if (pwfd
>= 0) endpwent();
47 if (pwfile
== nil
) pwfile
= PASSWD
;
49 if ((pwfd
= open(pwfile
, O_RDONLY
)) < 0) return -1;
50 (void) fcntl(pwfd
, F_SETFD
, fcntl(pwfd
, F_GETFD
) | FD_CLOEXEC
);
54 void setpwfile(const char *file
)
55 /* Prepare for reading an alternate password file. */
61 static int getline(void)
62 /* Get one line from the password file, return 0 if bad or EOF. */
68 if ((buflen
= read(pwfd
, buf
, sizeof(buf
))) <= 0)
73 if (lineptr
== arraylimit(pwline
)) return 0;
75 } while ((*lineptr
++ = *bufptr
++) != '\n');
81 static char *scan_colon(void)
82 /* Scan for a field separator in a line, return the start of the field. */
89 if (*lineptr
== 0) return nil
;
90 if (*lineptr
== '\n') break;
91 if (*lineptr
++ == ':') break;
97 struct passwd
*getpwent(void)
98 /* Read one entry from the password file. */
102 /* Open the file if not yet open. */
103 if (pwfd
< 0 && setpwent() < 0) return nil
;
105 /* Until a good line is read. */
107 if (!getline()) return nil
; /* EOF or corrupt. */
109 if ((entry
.pw_name
= scan_colon()) == nil
) continue;
110 if ((entry
.pw_passwd
= scan_colon()) == nil
) continue;
111 if ((p
= scan_colon()) == nil
) continue;
112 entry
.pw_uid
= strtol(p
, nil
, 0);
113 if ((p
= scan_colon()) == nil
) continue;
114 entry
.pw_gid
= strtol(p
, nil
, 0);
115 if ((entry
.pw_gecos
= scan_colon()) == nil
) continue;
116 if ((entry
.pw_dir
= scan_colon()) == nil
) continue;
117 if ((entry
.pw_shell
= scan_colon()) == nil
) continue;
119 if (*lineptr
== 0) return &entry
;
123 struct passwd
*getpwuid(_mnx_Uid_t uid
)
124 /* Return the password file entry belonging to the user-id. */
129 while ((pw
= getpwent()) != nil
&& pw
->pw_uid
!= uid
) {}
134 struct passwd
*getpwnam(const char *name
)
135 /* Return the password file entry belonging to the user name. */
140 while ((pw
= getpwent()) != nil
&& strcmp(pw
->pw_name
, name
) != 0) {}