|
Message-Id: <1423614776-25579-1-git-send-email-josiahw@gmail.com> Date: Tue, 10 Feb 2015 18:32:55 -0600 From: Josiah Worcester <josiahw@...il.com> To: musl@...ts.openwall.com Cc: Josiah Worcester <josiahw@...il.com> Subject: [PATCH 1/2] Refactor passwd file access code. --- src/passwd/fgetpwent.c | 4 +++- src/passwd/getpw_a.c | 31 +++++++++++++++++++++++++++++++ src/passwd/getpw_r.c | 34 ++++++++++------------------------ src/passwd/getpwent.c | 32 ++++++++++++-------------------- src/passwd/getpwent_a.c | 8 ++++++-- src/passwd/pwf.h | 3 ++- 6 files changed, 64 insertions(+), 48 deletions(-) create mode 100644 src/passwd/getpw_a.c diff --git a/src/passwd/fgetpwent.c b/src/passwd/fgetpwent.c index eb47b2a..fd472a0 100644 --- a/src/passwd/fgetpwent.c +++ b/src/passwd/fgetpwent.c @@ -6,5 +6,7 @@ struct passwd *fgetpwent(FILE *f) static char *line; static struct passwd pw; size_t size=0; - return __getpwent_a(f, &pw, &line, &size); + struct passwd *res; + __getpwent_a(f, &pw, &line, &size, &res); + return res; } diff --git a/src/passwd/getpw_a.c b/src/passwd/getpw_a.c new file mode 100644 index 0000000..21efc5c --- /dev/null +++ b/src/passwd/getpw_a.c @@ -0,0 +1,31 @@ +#include "pwf.h" +#include <pthread.h> + +int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res) +{ + FILE *f; + int cs; + int rv = 0; + + *res = 0; + + pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); + + f = fopen("/etc/passwd", "rbe"); + if (!f) { + rv = errno; + goto done; + } + + while (!(rv = __getpwent_a(f, pw, buf, size, res)) && *res) { + if (name && !strcmp(name, (*res)->pw_name) + || !name && (*res)->pw_uid == uid) + break; + } + fclose(f); + +done: + pthread_setcancelstate(cs, 0); + if (rv) errno = rv; + return rv; +} diff --git a/src/passwd/getpw_r.c b/src/passwd/getpw_r.c index 2855257..1db10db 100644 --- a/src/passwd/getpw_r.c +++ b/src/passwd/getpw_r.c @@ -13,32 +13,18 @@ static int getpw_r(const char *name, uid_t uid, struct passwd *pw, char *buf, si pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &cs); - f = fopen("/etc/passwd", "rbe"); - if (!f) { - rv = errno; - goto done; - } - - *res = 0; - while (__getpwent_a(f, pw, &line, &len)) { - if (name && !strcmp(name, pw->pw_name) - || !name && pw->pw_uid == uid) { - if (size < len) { - rv = ERANGE; - break; - } - *res = pw; - memcpy(buf, line, len); - FIX(name); - FIX(passwd); - FIX(gecos); - FIX(dir); - FIX(shell); - break; - } + rv = __getpw_a(name, uid, pw, &line, &len, res); + if (!rv && size < len) + rv = ERANGE; + if (!rv) { + memcpy(buf, line, len); + FIX(name); + FIX(passwd); + FIX(gecos); + FIX(dir); + FIX(shell); } free(line); - fclose(f); done: pthread_setcancelstate(cs, 0); return rv; diff --git a/src/passwd/getpwent.c b/src/passwd/getpwent.c index c655135..f2bd516 100644 --- a/src/passwd/getpwent.c +++ b/src/passwd/getpwent.c @@ -1,6 +1,9 @@ #include "pwf.h" static FILE *f; +static char *line; +static struct passwd pw; +static size_t size; void setpwent() { @@ -12,34 +15,23 @@ weak_alias(setpwent, endpwent); struct passwd *getpwent() { - static char *line; - static struct passwd pw; - size_t size=0; + struct passwd *res; if (!f) f = fopen("/etc/passwd", "rbe"); if (!f) return 0; - return __getpwent_a(f, &pw, &line, &size); + __getpwent_a(f, &pw, &line, &size, &res); + return res; } struct passwd *getpwuid(uid_t uid) { - struct passwd *pw; - int errno_saved; - setpwent(); - while ((pw=getpwent()) && pw->pw_uid != uid); - errno_saved = errno; - endpwent(); - errno = errno_saved; - return pw; + struct passwd *res; + __getpw_a(0, uid, &pw, &line, &size, &res); + return res; } struct passwd *getpwnam(const char *name) { - struct passwd *pw; - int errno_saved; - setpwent(); - while ((pw=getpwent()) && strcmp(pw->pw_name, name)); - errno_saved = errno; - endpwent(); - errno = errno_saved; - return pw; + struct passwd *res; + __getpw_a(name, 0, &pw, &line, &size, &res); + return res; } diff --git a/src/passwd/getpwent_a.c b/src/passwd/getpwent_a.c index 34842a0..4d84f0d 100644 --- a/src/passwd/getpwent_a.c +++ b/src/passwd/getpwent_a.c @@ -8,14 +8,16 @@ static unsigned atou(char **s) return x; } -struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size) +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 = errno; free(*line); *line = 0; pw = 0; @@ -46,5 +48,7 @@ struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *siz break; } pthread_setcancelstate(cs, 0); - return pw; + *res = pw; + if (rv) errno = rv; + return rv; } diff --git a/src/passwd/pwf.h b/src/passwd/pwf.h index 2d813ad..806ffd3 100644 --- a/src/passwd/pwf.h +++ b/src/passwd/pwf.h @@ -8,6 +8,7 @@ #include <limits.h> #include "libc.h" -struct passwd *__getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size); +int __getpwent_a(FILE *f, struct passwd *pw, char **line, size_t *size, struct passwd **res); +int __getpw_a(const char *name, uid_t uid, struct passwd *pw, char **buf, size_t *size, struct passwd **res); struct group *__getgrent_a(FILE *f, struct group *gr, char **line, size_t *size, char ***mem, size_t *nmem); int __parsespent(char *s, struct spwd *sp); -- 2.1.4
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.