summaryrefslogtreecommitdiff
path: root/libc/pwd_grp
diff options
context:
space:
mode:
authorDavid McCullough <davidm@snapgear.com>2002-01-17 06:26:05 +0000
committerDavid McCullough <davidm@snapgear.com>2002-01-17 06:26:05 +0000
commit23457259675d4a21f6840a30e2b41014540eab2d (patch)
tree1e29e4b02bd95566e6aea0205d4e8b564c5ce853 /libc/pwd_grp
parent47e0a8060499c822772437a3ca1765297857c131 (diff)
* Added /etc/shadow support (Config selectable)
* Moved some file paths from code into <paths.h>
Diffstat (limited to 'libc/pwd_grp')
-rw-r--r--libc/pwd_grp/Makefile6
-rw-r--r--libc/pwd_grp/__getspent_r.c57
-rw-r--r--libc/pwd_grp/__sgetspent_r.c161
-rw-r--r--libc/pwd_grp/fgetspent.c45
-rw-r--r--libc/pwd_grp/getgrgid.c3
-rw-r--r--libc/pwd_grp/getgrnam.c3
-rw-r--r--libc/pwd_grp/getpwnam.c4
-rw-r--r--libc/pwd_grp/getpwuid.c4
-rw-r--r--libc/pwd_grp/getspnam.c61
-rw-r--r--libc/pwd_grp/getspuid.c50
-rw-r--r--libc/pwd_grp/grent.c3
-rw-r--r--libc/pwd_grp/initgroups.c3
-rw-r--r--libc/pwd_grp/lckpwdf.c163
-rw-r--r--libc/pwd_grp/putspent.c79
-rw-r--r--libc/pwd_grp/pwent.c3
-rw-r--r--libc/pwd_grp/sgetspent.c41
-rw-r--r--libc/pwd_grp/spent.c71
17 files changed, 748 insertions, 9 deletions
diff --git a/libc/pwd_grp/Makefile b/libc/pwd_grp/Makefile
index f9b49c461..5efa1414e 100644
--- a/libc/pwd_grp/Makefile
+++ b/libc/pwd_grp/Makefile
@@ -27,6 +27,12 @@ include $(TOPDIR)Rules.mak
CSRC= pwent.c getpwnam.c getpwuid.c putpwent.c getpw.c fgetpwent.c \
__getgrent.c grent.c getgrnam.c getgrgid.c fgetgrent.c \
initgroups.c __getpwent_r.c
+
+ifeq ($(HAS_SHADOW),true)
+CSRC+= lckpwdf.c spent.c getspnam.c getspuid.c putspent.c sgetspent.c \
+ fgetspent.c __getspent_r.c __sgetspent_r.c
+endif
+
COBJS=$(patsubst %.c,%.o, $(CSRC))
OBJS=$(COBJS)
diff --git a/libc/pwd_grp/__getspent_r.c b/libc/pwd_grp/__getspent_r.c
new file mode 100644
index 000000000..d8e1fbdce
--- /dev/null
+++ b/libc/pwd_grp/__getspent_r.c
@@ -0,0 +1,57 @@
+/*
+ * __getspent_r.c - Based on __getpwent_r.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include <shadow.h>
+
+
+int __getspent_r(struct spwd * spwd, char * line_buff, size_t buflen, int spwd_fd)
+{
+ char *endptr;
+ int line_len;
+
+ /* We use the restart label to handle malformatted lines */
+ restart:
+ /* Read the shadow line into the static buffer using a minimal of
+ syscalls. */
+ if ((line_len = read(spwd_fd, line_buff, buflen)) <= 0)
+ return -1;
+ endptr = strchr(line_buff, '\n');
+ if (endptr != NULL)
+ lseek(spwd_fd, (long) (1 + endptr - (line_buff + line_len)),
+ SEEK_CUR);
+ else { /* The line is too long - skip it. :-\ */
+
+ do {
+ if ((line_len = read(spwd_fd, line_buff, buflen)) <= 0)
+ return -1;
+ } while (!(endptr = strchr(line_buff, '\n')));
+ lseek(spwd_fd, (long) (endptr - line_buff) - line_len + 1,
+ SEEK_CUR);
+ goto restart;
+ }
+
+ if (__sgetspent_r(line_buff, spwd, line_buff, buflen) < 0)
+ goto restart;
+
+ return 0;
+}
diff --git a/libc/pwd_grp/__sgetspent_r.c b/libc/pwd_grp/__sgetspent_r.c
new file mode 100644
index 000000000..f2cd73195
--- /dev/null
+++ b/libc/pwd_grp/__sgetspent_r.c
@@ -0,0 +1,161 @@
+/*
+ * __sgetspent_r.c - Based on __getpwent_r.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <shadow.h>
+
+
+int __sgetspent_r(const char * string, struct spwd * spwd, char * line_buff, size_t buflen)
+{
+ char *field_begin;
+ char *endptr;
+ char *lstchg_ptr=NULL;
+ char *min_ptr=NULL;
+ char *max_ptr=NULL;
+ char *warn_ptr=NULL;
+ char *inact_ptr=NULL;
+ char *expire_ptr=NULL;
+ char *flag_ptr=NULL;
+ int i;
+
+ if (string != line_buff) {
+ if (strlen(string) >= buflen)
+ return -1;
+ strcpy(line_buff, string);
+ }
+
+ if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' ||
+ *line_buff == '\t')
+ return -1;
+
+ field_begin = strchr(line_buff, '\n');
+ if (field_begin != NULL)
+ *field_begin = '\0';
+
+ /* We've read the line; now parse it. */
+ field_begin = line_buff;
+ for (i = 0; i < 9; i++) {
+ switch (i) {
+ case 0:
+ spwd->sp_namp = field_begin;
+ break;
+ case 1:
+ spwd->sp_pwdp = field_begin;
+ break;
+ case 2:
+ lstchg_ptr = field_begin;
+ break;
+ case 3:
+ min_ptr = field_begin;
+ break;
+ case 4:
+ max_ptr = field_begin;
+ break;
+ case 5:
+ warn_ptr = field_begin;
+ break;
+ case 6:
+ inact_ptr = field_begin;
+ break;
+ case 7:
+ expire_ptr = field_begin;
+ break;
+ case 8:
+ flag_ptr = field_begin;
+ break;
+ }
+ if (i < 8) {
+ field_begin = strchr(field_begin, ':');
+ if (field_begin == NULL) {
+ if (i==4 || i==7)
+ break;
+ return -1;
+ }
+ *field_begin++ = '\0';
+ }
+ }
+
+ if (*lstchg_ptr == '\0') {
+ spwd->sp_lstchg = -1;
+ } else {
+ spwd->sp_lstchg = (gid_t) strtoul(lstchg_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ return -1;
+ }
+
+ if (*min_ptr == '\0') {
+ spwd->sp_min = -1;
+ } else {
+ spwd->sp_min = (gid_t) strtoul(min_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ return -1;
+ }
+
+ if (*max_ptr == '\0') {
+ spwd->sp_max = -1;
+ } else {
+ spwd->sp_max = (gid_t) strtoul(max_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ return -1;
+ }
+
+ if (warn_ptr == NULL) {
+ /* Support for old format */
+ spwd->sp_warn = -1;
+ spwd->sp_inact = -1;
+ spwd->sp_expire = -1;
+ spwd->sp_flag = 0;
+ }
+ else {
+ if (*warn_ptr == '\0') {
+ spwd->sp_warn = -1;
+ } else {
+ spwd->sp_warn = (gid_t) strtoul(warn_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ return -1;
+ }
+
+ if (*inact_ptr == '\0') {
+ spwd->sp_inact = -1;
+ } else {
+ spwd->sp_inact = (gid_t) strtoul(inact_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ return -1;
+ }
+
+ if (*expire_ptr == '\0') {
+ spwd->sp_expire = -1;
+ } else {
+ spwd->sp_expire = (gid_t) strtoul(expire_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ return -1;
+ }
+
+ if (flag_ptr==NULL || *flag_ptr=='\0') {
+ spwd->sp_flag = ~0ul;
+ } else {
+ spwd->sp_flag = (gid_t) strtoul(flag_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ return -1;
+ }
+ }
+
+ return 0;
+}
diff --git a/libc/pwd_grp/fgetspent.c b/libc/pwd_grp/fgetspent.c
new file mode 100644
index 000000000..cf949065f
--- /dev/null
+++ b/libc/pwd_grp/fgetspent.c
@@ -0,0 +1,45 @@
+/*
+ * fgetspent.c - Based on fgetpwent.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <shadow.h>
+
+#define PWD_BUFFER_SIZE 256
+
+int fgetspent_r (FILE *file, struct spwd *spwd,
+ char *buff, size_t buflen, struct spwd **crap)
+{
+ if (file == NULL) {
+ __set_errno(EINTR);
+ return -1;
+ }
+ return(__getspent_r(spwd, buff, buflen, fileno(file)));
+}
+
+struct spwd *fgetspent(FILE * file)
+{
+ static char line_buff[PWD_BUFFER_SIZE];
+ static struct spwd spwd;
+
+ if (fgetspent_r(file, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) {
+ return &spwd;
+ }
+ return NULL;
+}
diff --git a/libc/pwd_grp/getgrgid.c b/libc/pwd_grp/getgrgid.c
index 70e7152ce..f41e305ef 100644
--- a/libc/pwd_grp/getgrgid.c
+++ b/libc/pwd_grp/getgrgid.c
@@ -22,6 +22,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <grp.h>
+#include <paths.h>
#include "config.h"
struct group *getgrgid(const gid_t gid)
@@ -29,7 +30,7 @@ struct group *getgrgid(const gid_t gid)
struct group *group;
int grp_fd;
- if ((grp_fd = open("/etc/group", O_RDONLY)) < 0)
+ if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0)
return NULL;
while ((group = __getgrent(grp_fd)) != NULL)
diff --git a/libc/pwd_grp/getgrnam.c b/libc/pwd_grp/getgrnam.c
index 705342489..77301797c 100644
--- a/libc/pwd_grp/getgrnam.c
+++ b/libc/pwd_grp/getgrnam.c
@@ -23,6 +23,7 @@
#include <errno.h>
#include <fcntl.h>
#include <grp.h>
+#include <paths.h>
#include "config.h"
struct group *getgrnam(const char *name)
@@ -35,7 +36,7 @@ struct group *getgrnam(const char *name)
return NULL;
}
- if ((grp_fd = open("/etc/group", O_RDONLY)) < 0)
+ if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0)
return NULL;
while ((group = __getgrent(grp_fd)) != NULL)
diff --git a/libc/pwd_grp/getpwnam.c b/libc/pwd_grp/getpwnam.c
index f5ad9ca1d..36f6f0942 100644
--- a/libc/pwd_grp/getpwnam.c
+++ b/libc/pwd_grp/getpwnam.c
@@ -23,9 +23,9 @@
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
+#include <paths.h>
#include "config.h"
-
#define PWD_BUFFER_SIZE 256
/* file descriptor for the password file currently open */
@@ -43,7 +43,7 @@ int getpwnam_r (const char *name, struct passwd *password,
return -1;
}
- if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0)
+ if ((passwd_fd = open(_PATH_PASSWD, O_RDONLY)) < 0)
return -1;
while (__getpwent_r(password, buff, buflen, passwd_fd) != -1)
diff --git a/libc/pwd_grp/getpwuid.c b/libc/pwd_grp/getpwuid.c
index 101d668ae..4d6d60ee8 100644
--- a/libc/pwd_grp/getpwuid.c
+++ b/libc/pwd_grp/getpwuid.c
@@ -22,9 +22,9 @@
#include <unistd.h>
#include <fcntl.h>
#include <pwd.h>
+#include <paths.h>
#include "config.h"
-
#define PWD_BUFFER_SIZE 256
/* file descriptor for the password file currently open */
@@ -36,7 +36,7 @@ int getpwuid_r (uid_t uid, struct passwd *password,
{
int passwd_fd;
- if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0)
+ if ((passwd_fd = open(_PATH_PASSWD, O_RDONLY)) < 0)
return -1;
while (__getpwent_r(password, buff, buflen, passwd_fd) != -1)
diff --git a/libc/pwd_grp/getspnam.c b/libc/pwd_grp/getspnam.c
new file mode 100644
index 000000000..3865a0dc5
--- /dev/null
+++ b/libc/pwd_grp/getspnam.c
@@ -0,0 +1,61 @@
+/*
+ * getspnam.c - Based on getpwnam.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <shadow.h>
+
+#define PWD_BUFFER_SIZE 256
+
+int getspnam_r (const char *name, struct spwd *spwd,
+ char *buff, size_t buflen, struct spwd **crap)
+{
+ int spwd_fd;
+
+ if (name == NULL) {
+ __set_errno(EINVAL);
+ return -1;
+ }
+
+ if ((spwd_fd = open(_PATH_SHADOW, O_RDONLY)) < 0)
+ return -1;
+
+ while (__getspent_r(spwd, buff, buflen, spwd_fd) != -1)
+ if (!strcmp(spwd->sp_namp, name)) {
+ close(spwd_fd);
+ return 0;
+ }
+
+ close(spwd_fd);
+ return -1;
+}
+
+struct spwd *getspnam(const char *name)
+{
+ static char line_buff[PWD_BUFFER_SIZE];
+ static struct spwd spwd;
+
+ if (getspnam_r(name, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) {
+ return &spwd;
+ }
+ return NULL;
+}
+
diff --git a/libc/pwd_grp/getspuid.c b/libc/pwd_grp/getspuid.c
new file mode 100644
index 000000000..2f01cdca0
--- /dev/null
+++ b/libc/pwd_grp/getspuid.c
@@ -0,0 +1,50 @@
+/*
+ * getspuid.c - Based on getpwuid.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <pwd.h>
+#include <shadow.h>
+
+#define PWD_BUFFER_SIZE 256
+
+int getspuid_r (uid_t uid, struct spwd *spwd,
+ char *buff, size_t buflen, struct spwd **crap)
+{
+ char pwd_buff[PWD_BUFFER_SIZE];
+ struct passwd password;
+
+ if (getpwuid_r(uid, &password, pwd_buff, PWD_BUFFER_SIZE, NULL) < 0)
+ return -1;
+
+ return getspnam_r(password.pw_name, spwd, buff, buflen, crap);
+}
+
+struct spwd *getspuid(uid_t uid)
+{
+ static char line_buff[PWD_BUFFER_SIZE];
+ static struct spwd spwd;
+
+ if (getspuid_r(uid, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) {
+ return &spwd;
+ }
+ return NULL;
+}
+
diff --git a/libc/pwd_grp/grent.c b/libc/pwd_grp/grent.c
index 8e4af5143..973213f83 100644
--- a/libc/pwd_grp/grent.c
+++ b/libc/pwd_grp/grent.c
@@ -27,6 +27,7 @@
#include <unistd.h>
#include <fcntl.h>
#include <grp.h>
+#include <paths.h>
#include "config.h"
static int grp_fd = -1;
@@ -35,7 +36,7 @@ void setgrent(void)
{
if (grp_fd != -1)
close(grp_fd);
- grp_fd = open("/etc/group", O_RDONLY);
+ grp_fd = open(_PATH_GROUP, O_RDONLY);
}
void endgrent(void)
diff --git a/libc/pwd_grp/initgroups.c b/libc/pwd_grp/initgroups.c
index 04de22632..87a6b569d 100644
--- a/libc/pwd_grp/initgroups.c
+++ b/libc/pwd_grp/initgroups.c
@@ -22,6 +22,7 @@
#include <string.h>
#include <fcntl.h>
#include <grp.h>
+#include <paths.h>
#include "config.h"
int initgroups(__const char *user, gid_t gid)
@@ -38,7 +39,7 @@ int initgroups(__const char *user, gid_t gid)
int grp_fd;
- if ((grp_fd = open("/etc/group", O_RDONLY)) < 0)
+ if ((grp_fd = open(_PATH_GROUP, O_RDONLY)) < 0)
return -1;
num_groups = 0;
diff --git a/libc/pwd_grp/lckpwdf.c b/libc/pwd_grp/lckpwdf.c
new file mode 100644
index 000000000..2f55ff65a
--- /dev/null
+++ b/libc/pwd_grp/lckpwdf.c
@@ -0,0 +1,163 @@
+/* Handle locking of password file.
+ Copyright (C) 1996, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <fcntl.h>
+#include <shadow.h>
+#include <signal.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/file.h>
+#include <paths.h>
+
+/* How long to wait for getting the lock before returning with an
+ error. */
+#define TIMEOUT 15 /* sec */
+
+/* File descriptor for lock file. */
+static int lock_fd = -1;
+
+/* Prototypes for local functions. */
+static void noop_handler __P ((int __sig));
+
+
+int
+lckpwdf ()
+{
+ int flags;
+ sigset_t saved_set; /* Saved set of caught signals. */
+ struct sigaction saved_act; /* Saved signal action. */
+ sigset_t new_set; /* New set of caught signals. */
+ struct sigaction new_act; /* New signal action. */
+ struct flock fl; /* Information struct for locking. */
+ int result;
+
+ if (lock_fd != -1)
+ /* Still locked by own process. */
+ return -1;
+
+ lock_fd = open (_PATH_PASSWD, O_WRONLY);
+ if (lock_fd == -1)
+ /* Cannot create lock file. */
+ return -1;
+
+ /* Make sure file gets correctly closed when process finished. */
+ flags = fcntl (lock_fd, F_GETFD, 0);
+ if (flags == -1) {
+ /* Cannot get file flags. */
+ close(lock_fd);
+ lock_fd = -1;
+ return -1;
+ }
+ flags |= FD_CLOEXEC; /* Close on exit. */
+ if (fcntl (lock_fd, F_SETFD, flags) < 0) {
+ /* Cannot set new flags. */
+ close(lock_fd);
+ lock_fd = -1;
+ return -1;
+ }
+
+ /* Now we have to get exclusive write access. Since multiple
+ process could try this we won't stop when it first fails.
+ Instead we set a timeout for the system call. Once the timer
+ expires it is likely that there are some problems which cannot be
+ resolved by waiting.
+
+ It is important that we don't change the signal state. We must
+ restore the old signal behaviour. */
+ memset (&new_act, '\0', sizeof (struct sigaction));
+ new_act.sa_handler = noop_handler;
+ sigfillset (&new_act.sa_mask);
+ new_act.sa_flags = 0ul;
+
+ /* Install new action handler for alarm and save old. */
+ if (sigaction (SIGALRM, &new_act, &saved_act) < 0) {
+ /* Cannot install signal handler. */
+ close(lock_fd);
+ lock_fd = -1;
+ return -1;
+ }
+
+ /* Now make sure the alarm signal is not blocked. */
+ sigemptyset (&new_set);
+ sigaddset (&new_set, SIGALRM);
+ if (sigprocmask (SIG_UNBLOCK, &new_set, &saved_set) < 0) {
+ sigaction (SIGALRM, &saved_act, NULL);
+ close(lock_fd);
+ lock_fd = -1;
+ return -1;
+ }
+
+ /* Start timer. If we cannot get the lock in the specified time we
+ get a signal. */
+ alarm (TIMEOUT);
+
+ /* Try to get the lock. */
+ memset (&fl, '\0', sizeof (struct flock));
+ fl.l_type = F_WRLCK;
+ fl.l_whence = SEEK_SET;
+ result = fcntl (lock_fd, F_SETLKW, &fl);
+
+ /* Clear alarm. */
+ alarm (0);
+
+ /* Restore old set of handled signals. We don't need to know
+ about the current one.*/
+ sigprocmask (SIG_SETMASK, &saved_set, NULL);
+
+ /* Restore old action handler for alarm. We don't need to know
+ about the current one. */
+ sigaction (SIGALRM, &saved_act, NULL);
+
+ if (result < 0) {
+ close(lock_fd);
+ lock_fd = -1;
+ return -1;
+ }
+
+ return 0;
+}
+
+
+int
+ulckpwdf ()
+{
+ int result;
+
+ if (lock_fd == -1) {
+ /* There is no lock set. */
+ result = -1;
+ }
+ else {
+ result = close (lock_fd);
+
+ /* Mark descriptor as unused. */
+ lock_fd = -1;
+ }
+
+ return result;
+}
+
+
+static void
+noop_handler (sig)
+ int sig;
+{
+ /* We simply return which makes the `fcntl' call return with an error. */
+}
diff --git a/libc/pwd_grp/putspent.c b/libc/pwd_grp/putspent.c
new file mode 100644
index 000000000..a4626e1b4
--- /dev/null
+++ b/libc/pwd_grp/putspent.c
@@ -0,0 +1,79 @@
+/* Copyright (C) 1991, 1992, 1996, 1997, 1998 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include <shadow.h>
+
+#define _S(x) x ? x : ""
+
+
+/* Write an entry to the given stream.
+ This must know the format of the password file. */
+int
+putspent (const struct spwd *p, FILE *stream)
+{
+ int errors = 0;
+
+ if (fprintf (stream, "%s:%s:", p->sp_namp, _S (p->sp_pwdp)) < 0)
+ ++errors;
+
+ if ((p->sp_lstchg != (long int) -1
+ && fprintf (stream, "%ld:", p->sp_lstchg) < 0)
+ || (p->sp_lstchg == (long int) -1
+ && putc (':', stream) == EOF))
+ ++errors;
+
+ if ((p->sp_min != (long int) -1
+ && fprintf (stream, "%ld:", p->sp_min) < 0)
+ || (p->sp_min == (long int) -1
+ && putc (':', stream) == EOF))
+ ++errors;
+
+ if ((p->sp_max != (long int) -1
+ && fprintf (stream, "%ld:", p->sp_max) < 0)
+ || (p->sp_max == (long int) -1
+ && putc (':', stream) == EOF))
+ ++errors;
+
+ if ((p->sp_warn != (long int) -1
+ && fprintf (stream, "%ld:", p->sp_warn) < 0)
+ || (p->sp_warn == (long int) -1
+ && putc (':', stream) == EOF))
+ ++errors;
+
+ if ((p->sp_inact != (long int) -1
+ && fprintf (stream, "%ld:", p->sp_inact) < 0)
+ || (p->sp_inact == (long int) -1
+ && putc (':', stream) == EOF))
+ ++errors;
+
+ if ((p->sp_expire != (long int) -1
+ && fprintf (stream, "%ld:", p->sp_expire) < 0)
+ || (p->sp_expire == (long int) -1
+ && putc (':', stream) == EOF))
+ ++errors;
+
+ if (p->sp_flag != ~0ul
+ && fprintf (stream, "%ld", p->sp_flag) < 0)
+ ++errors;
+
+ if (putc ('\n', stream) == EOF)
+ ++errors;
+
+ return errors ? -1 : 0;
+}
diff --git a/libc/pwd_grp/pwent.c b/libc/pwd_grp/pwent.c
index e4a17e2b3..804bd8957 100644
--- a/libc/pwd_grp/pwent.c
+++ b/libc/pwd_grp/pwent.c
@@ -23,6 +23,7 @@
#include <errno.h>
#include <pwd.h>
#include <fcntl.h>
+#include <paths.h>
#include "config.h"
/*
@@ -43,7 +44,7 @@ void setpwent(void)
if (pw_fd != -1)
close(pw_fd);
- pw_fd = open("/etc/passwd", O_RDONLY);
+ pw_fd = open(_PATH_PASSWD, O_RDONLY);
}
void endpwent(void)
diff --git a/libc/pwd_grp/sgetspent.c b/libc/pwd_grp/sgetspent.c
new file mode 100644
index 000000000..6f80c87d6
--- /dev/null
+++ b/libc/pwd_grp/sgetspent.c
@@ -0,0 +1,41 @@
+/*
+ * sgetspent.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <shadow.h>
+
+#define PWD_BUFFER_SIZE 256
+
+int sgetspent_r (const char *string, struct spwd *spwd,
+ char *buff, size_t buflen, struct spwd **crap)
+{
+ return(__sgetspent_r(string, spwd, buff, buflen));
+}
+
+struct spwd *sgetspent(const char *string)
+{
+ static char line_buff[PWD_BUFFER_SIZE];
+ static struct spwd spwd;
+
+ if (sgetspent_r(string, &spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) {
+ return &spwd;
+ }
+ return NULL;
+}
diff --git a/libc/pwd_grp/spent.c b/libc/pwd_grp/spent.c
new file mode 100644
index 000000000..196a952bd
--- /dev/null
+++ b/libc/pwd_grp/spent.c
@@ -0,0 +1,71 @@
+/*
+ * spent.c - Based on pwent.c
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <shadow.h>
+#include <fcntl.h>
+
+/*
+ * setspent(), endspent(), and getspent() are included in the same object
+ * file, since one cannot be used without the other two, so it makes sense to
+ * link them all in together.
+ */
+
+#define PWD_BUFFER_SIZE 256
+
+/* file descriptor for the password file currently open */
+static int spwd_fd = -1;
+
+void setspent(void)
+{
+ if (spwd_fd != -1)
+ close(spwd_fd);
+
+ spwd_fd = open(_PATH_SHADOW, O_RDONLY);
+}
+
+void endspent(void)
+{
+ if (spwd_fd != -1)
+ close(spwd_fd);
+ spwd_fd = -1;
+}
+
+int getspent_r (struct spwd *spwd, char *buff,
+ size_t buflen, struct spwd **crap)
+{
+ if (spwd_fd != -1 && __getspent_r(spwd, buff, buflen, spwd_fd) != -1) {
+ return 0;
+ }
+ return -1;
+}
+
+struct spwd *getspent(void)
+{
+ static char line_buff[PWD_BUFFER_SIZE];
+ static struct spwd spwd;
+
+ if (getspent_r(&spwd, line_buff, PWD_BUFFER_SIZE, NULL) != -1) {
+ return &spwd;
+ }
+ return NULL;
+}
+