aboutsummaryrefslogtreecommitdiff
path: root/libpwdgrp
diff options
context:
space:
mode:
authorGravatar Robert Griebl <griebl@gmx.de>2002-06-04 20:45:46 +0000
committerGravatar Robert Griebl <griebl@gmx.de>2002-06-04 20:45:46 +0000
commit1fca558799350fb6caff97f55aa6d1237b08fccb (patch)
treebd211c50ca4a34fd4c6317696c62564fb77171e9 /libpwdgrp
parentea1a63a2011a44b143cc46c7d80a8152f5358e24 (diff)
downloadbusybox-1fca558799350fb6caff97f55aa6d1237b08fccb.tar.gz
busybox-1fca558799350fb6caff97f55aa6d1237b08fccb.tar.bz2
Bigger patch for (partial) tinylogin integration
- Made a new dir loginutils - Moved all applets from pwd_grp to loginutils - Added new applets su.c login.c to loginutils - Made a new dir libpwdgrp - Moved everything from pwd_grp/libpwd_grp there - Added shadow.c to libpwdgrp - Removed dir pwd_grp - Added usage strings for login and su to usage.h - Changed main Makefile to reflect the dir rearrangements [Parts of this patch may overlap with my other two patches]
Diffstat (limited to 'libpwdgrp')
-rw-r--r--libpwdgrp/Makefile30
-rw-r--r--libpwdgrp/Makefile.in35
-rw-r--r--libpwdgrp/__getgrent.c204
-rw-r--r--libpwdgrp/__getpwent.c115
-rw-r--r--libpwdgrp/fgetgrent.c35
-rw-r--r--libpwdgrp/fgetpwent.c35
-rw-r--r--libpwdgrp/getgrgid.c44
-rw-r--r--libpwdgrp/getgrnam.c50
-rw-r--r--libpwdgrp/getpw.c47
-rw-r--r--libpwdgrp/getpwnam.c51
-rw-r--r--libpwdgrp/getpwuid.c44
-rw-r--r--libpwdgrp/grent.c54
-rw-r--r--libpwdgrp/initgroups.c115
-rw-r--r--libpwdgrp/putpwent.c39
-rw-r--r--libpwdgrp/pwent.c58
-rw-r--r--libpwdgrp/setgroups.c42
-rw-r--r--libpwdgrp/shadow.c302
17 files changed, 1300 insertions, 0 deletions
diff --git a/libpwdgrp/Makefile b/libpwdgrp/Makefile
new file mode 100644
index 000000000..2708027ec
--- /dev/null
+++ b/libpwdgrp/Makefile
@@ -0,0 +1,30 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2002 Erik Andersen <andersee@debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+TOPDIR:= ../
+LIBPWDGRP_DIR:=./
+include $(TOPDIR).config
+include $(TOPDIR)Rules.mak
+include Makefile.in
+all: $(libraries-y)
+-include $(TOPDIR).depend
+
+clean:
+ rm -f *.o *.a $(AR_TARGET)
+
diff --git a/libpwdgrp/Makefile.in b/libpwdgrp/Makefile.in
new file mode 100644
index 000000000..970457112
--- /dev/null
+++ b/libpwdgrp/Makefile.in
@@ -0,0 +1,35 @@
+# Makefile for busybox
+#
+# Copyright (C) 1999-2002 Erik Andersen <andersee@debian.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program 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
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+
+LIBPWDGRP_AR:=libpwdgrp.a
+ifndef $(LIBPWDGRP_DIR)
+LIBPWDGRP_DIR:=$(TOPDIR)libpwdgrp/
+endif
+
+LIBPWDGRP-y:=
+LIBPWDGRP-$(CONFIG_USE_BB_PWD_GRP) += __getgrent.o __getgrent.o __getpwent.o\
+ fgetgrent.o fgetpwent.o getgrgid.o getgrnam.o getpw.o getpwnam.o \
+ getpwuid.o grent.o initgroups.o putpwent.o pwent.o setgroups.o
+LIBPWDGRP-$(CONFIG_USE_BB_SHADOW) += shadow.o
+
+libraries-y+=$(LIBPWDGRP_DIR)$(LIBPWDGRP_AR)
+
+$(LIBPWDGRP_DIR)$(LIBPWDGRP_AR): $(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP-y))
+ $(AR) -ro $@ $(patsubst %,$(LIBPWDGRP_DIR)%, $(LIBPWDGRP-y))
+
diff --git a/libpwdgrp/__getgrent.c b/libpwdgrp/__getgrent.c
new file mode 100644
index 000000000..571da3fc3
--- /dev/null
+++ b/libpwdgrp/__getgrent.c
@@ -0,0 +1,204 @@
+/*
+ * __getgrent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <string.h>
+#include "grp.h"
+
+/*
+ * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer
+ * so that lines of any length can be used. On very very small systems,
+ * you may want to leave this undefined becasue it will make the grp functions
+ * somewhat larger (because of the inclusion of malloc and the code necessary).
+ * On larger systems, you will want to define this, because grp will _not_
+ * deal with long lines gracefully (they will be skipped).
+ */
+#undef GR_SCALE_DYNAMIC
+
+#ifndef GR_SCALE_DYNAMIC
+/*
+ * If scaling is not dynamic, the buffers will be statically allocated, and
+ * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of
+ * characters per line in the group file. GR_MAX_MEMBERS is the maximum
+ * number of members of any given group.
+ */
+#define GR_MAX_LINE_LEN 128
+/* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */
+#define GR_MAX_MEMBERS 11
+
+#endif /* !GR_SCALE_DYNAMIC */
+
+
+/*
+ * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate
+ * space for it's GID array before calling setgroups(). This is probably
+ * unnecessary scalage, so it's undefined by default.
+ */
+#undef GR_DYNAMIC_GROUP_LIST
+
+#ifndef GR_DYNAMIC_GROUP_LIST
+/*
+ * GR_MAX_GROUPS is the size of the static array initgroups() uses for
+ * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined.
+ */
+#define GR_MAX_GROUPS 64
+
+#endif /* !GR_DYNAMIC_GROUP_LIST */
+
+
+/*
+ * This is the core group-file read function. It behaves exactly like
+ * getgrent() except that it is passed a file descriptor. getgrent()
+ * is just a wrapper for this function.
+ */
+struct group *__getgrent(int grp_fd)
+{
+#ifndef GR_SCALE_DYNAMIC
+ static char line_buff[GR_MAX_LINE_LEN];
+ static char *members[GR_MAX_MEMBERS];
+#else
+ static char *line_buff = NULL;
+ static char **members = NULL;
+ short line_index;
+ short buff_size;
+#endif
+ static struct group group;
+ register char *ptr;
+ char *field_begin;
+ short member_num;
+ char *endptr;
+ int line_len;
+
+
+ /* We use the restart label to handle malformatted lines */
+ restart:
+#ifdef GR_SCALE_DYNAMIC
+ line_index = 0;
+ buff_size = 256;
+#endif
+
+#ifndef GR_SCALE_DYNAMIC
+ /* Read the line into the static buffer */
+ if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0)
+ return NULL;
+ field_begin = strchr(line_buff, '\n');
+ if (field_begin != NULL)
+ lseek(grp_fd, (long) (1 + field_begin - (line_buff + line_len)),
+ SEEK_CUR);
+ else { /* The line is too long - skip it :-\ */
+
+ do {
+ if ((line_len = read(grp_fd, line_buff, GR_MAX_LINE_LEN)) <= 0)
+ return NULL;
+ } while (!(field_begin = strchr(line_buff, '\n')));
+ lseek(grp_fd, (long) ((field_begin - line_buff) - line_len + 1),
+ SEEK_CUR);
+ goto restart;
+ }
+ if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' ||
+ *line_buff == '\t')
+ goto restart;
+ *field_begin = '\0';
+
+#else /* !GR_SCALE_DYNAMIC */
+ line_buff = realloc(line_buff, buff_size);
+ while (1) {
+ if ((line_len = read(grp_fd, line_buff + line_index,
+ buff_size - line_index)) <= 0)
+ return NULL;
+ field_begin = strchr(line_buff, '\n');
+ if (field_begin != NULL) {
+ lseek(grp_fd,
+ (long) (1 + field_begin -
+ (line_len + line_index + line_buff)), SEEK_CUR);
+ *field_begin = '\0';
+ if (*line_buff == '#' || *line_buff == ' '
+ || *line_buff == '\n' || *line_buff == '\t')
+ goto restart;
+ break;
+ } else { /* Allocate some more space */
+
+ line_index = buff_size;
+ buff_size += 256;
+ line_buff = realloc(line_buff, buff_size);
+ }
+ }
+#endif /* GR_SCALE_DYNAMIC */
+
+ /* Now parse the line */
+ group.gr_name = line_buff;
+ ptr = strchr(line_buff, ':');
+ if (ptr == NULL)
+ goto restart;
+ *ptr++ = '\0';
+
+ group.gr_passwd = ptr;
+ ptr = strchr(ptr, ':');
+ if (ptr == NULL)
+ goto restart;
+ *ptr++ = '\0';
+
+ field_begin = ptr;
+ ptr = strchr(ptr, ':');
+ if (ptr == NULL)
+ goto restart;
+ *ptr++ = '\0';
+
+ group.gr_gid = (gid_t) strtoul(field_begin, &endptr, 10);
+ if (*endptr != '\0')
+ goto restart;
+
+ member_num = 0;
+ field_begin = ptr;
+
+#ifndef GR_SCALE_DYNAMIC
+ while ((ptr = strchr(ptr, ',')) != NULL) {
+ *ptr = '\0';
+ ptr++;
+ members[member_num] = field_begin;
+ field_begin = ptr;
+ member_num++;
+ }
+ if (*field_begin == '\0')
+ members[member_num] = NULL;
+ else {
+ members[member_num] = field_begin;
+ members[member_num + 1] = NULL;
+ }
+#else /* !GR_SCALE_DYNAMIC */
+ if (members != NULL)
+ free(members);
+ members = (char **) malloc((member_num + 1) * sizeof(char *));
+ for ( ; field_begin && *field_begin != '\0'; field_begin = ptr) {
+ if ((ptr = strchr(field_begin, ',')) != NULL)
+ *ptr++ = '\0';
+ members[member_num++] = field_begin;
+ members = (char **) realloc(members,
+ (member_num + 1) * sizeof(char *));
+ }
+ members[member_num] = NULL;
+#endif /* GR_SCALE_DYNAMIC */
+
+ group.gr_mem = members;
+ return &group;
+}
diff --git a/libpwdgrp/__getpwent.c b/libpwdgrp/__getpwent.c
new file mode 100644
index 000000000..e406b8824
--- /dev/null
+++ b/libpwdgrp/__getpwent.c
@@ -0,0 +1,115 @@
+/*
+ * __getpwent.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include "pwd.h"
+
+#define PWD_BUFFER_SIZE 256
+
+/* This isn't as flash as my previous version -- it doesn't dynamically
+ scale down the gecos on too-long lines, but it also makes fewer syscalls,
+ so it's probably nicer. Write me if you want the old version. Maybe I
+ should include it as a build-time option... ?
+ -Nat <ndf@linux.mit.edu> */
+
+struct passwd *__getpwent(int pwd_fd)
+{
+ static char line_buff[PWD_BUFFER_SIZE];
+ static struct passwd passwd;
+ char *field_begin;
+ char *endptr;
+ char *gid_ptr=NULL;
+ char *uid_ptr=NULL;
+ int line_len;
+ int i;
+
+ /* We use the restart label to handle malformatted lines */
+ restart:
+ /* Read the passwd line into the static buffer using a minimal of
+ syscalls. */
+ if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0)
+ return NULL;
+ field_begin = strchr(line_buff, '\n');
+ if (field_begin != NULL)
+ lseek(pwd_fd, (long) (1 + field_begin - (line_buff + line_len)),
+ SEEK_CUR);
+ else { /* The line is too long - skip it. :-\ */
+
+ do {
+ if ((line_len = read(pwd_fd, line_buff, PWD_BUFFER_SIZE)) <= 0)
+ return NULL;
+ } while (!(field_begin = strchr(line_buff, '\n')));
+ lseek(pwd_fd, (long) (field_begin - line_buff) - line_len + 1,
+ SEEK_CUR);
+ goto restart;
+ }
+ if (*line_buff == '#' || *line_buff == ' ' || *line_buff == '\n' ||
+ *line_buff == '\t')
+ goto restart;
+ *field_begin = '\0';
+
+ /* We've read the line; now parse it. */
+ field_begin = line_buff;
+ for (i = 0; i < 7; i++) {
+ switch (i) {
+ case 0:
+ passwd.pw_name = field_begin;
+ break;
+ case 1:
+ passwd.pw_passwd = field_begin;
+ break;
+ case 2:
+ uid_ptr = field_begin;
+ break;
+ case 3:
+ gid_ptr = field_begin;
+ break;
+ case 4:
+ passwd.pw_gecos = field_begin;
+ break;
+ case 5:
+ passwd.pw_dir = field_begin;
+ break;
+ case 6:
+ passwd.pw_shell = field_begin;
+ break;
+ }
+ if (i < 6) {
+ field_begin = strchr(field_begin, ':');
+ if (field_begin == NULL)
+ goto restart;
+ *field_begin++ = '\0';
+ }
+ }
+ passwd.pw_gid = (gid_t) strtoul(gid_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ goto restart;
+
+ passwd.pw_uid = (uid_t) strtoul(uid_ptr, &endptr, 10);
+ if (*endptr != '\0')
+ goto restart;
+
+ return &passwd;
+}
diff --git a/libpwdgrp/fgetgrent.c b/libpwdgrp/fgetgrent.c
new file mode 100644
index 000000000..c5d63e05f
--- /dev/null
+++ b/libpwdgrp/fgetgrent.c
@@ -0,0 +1,35 @@
+/*
+ * fgetgrent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include "grp.h"
+
+struct group *fgetgrent(FILE * file)
+{
+ if (file == NULL) {
+ errno = EINTR;
+ return NULL;
+ }
+
+ return __getgrent(fileno(file));
+}
diff --git a/libpwdgrp/fgetpwent.c b/libpwdgrp/fgetpwent.c
new file mode 100644
index 000000000..6537600ff
--- /dev/null
+++ b/libpwdgrp/fgetpwent.c
@@ -0,0 +1,35 @@
+/*
+ * fgetpwent.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <errno.h>
+#include <stdio.h>
+#include "pwd.h"
+
+struct passwd *fgetpwent(FILE * file)
+{
+ if (file == NULL) {
+ errno = EINTR;
+ return NULL;
+ }
+
+ return __getpwent(fileno(file));
+}
diff --git a/libpwdgrp/getgrgid.c b/libpwdgrp/getgrgid.c
new file mode 100644
index 000000000..e70346a77
--- /dev/null
+++ b/libpwdgrp/getgrgid.c
@@ -0,0 +1,44 @@
+/*
+ * getgrgid.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "grp.h"
+
+struct group *getgrgid(const gid_t gid)
+{
+ struct group *group;
+ int grp_fd;
+
+ if ((grp_fd = open("/etc/group", O_RDONLY)) < 0)
+ return NULL;
+
+ while ((group = __getgrent(grp_fd)) != NULL)
+ if (group->gr_gid == gid) {
+ close(grp_fd);
+ return group;
+ }
+
+ close(grp_fd);
+ return NULL;
+}
diff --git a/libpwdgrp/getgrnam.c b/libpwdgrp/getgrnam.c
new file mode 100644
index 000000000..62b2b26ca
--- /dev/null
+++ b/libpwdgrp/getgrnam.c
@@ -0,0 +1,50 @@
+/*
+ * getgrnam.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "grp.h"
+
+struct group *getgrnam(const char *name)
+{
+ int grp_fd;
+ struct group *group;
+
+ if (name == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if ((grp_fd = open("/etc/group", O_RDONLY)) < 0)
+ return NULL;
+
+ while ((group = __getgrent(grp_fd)) != NULL)
+ if (!strcmp(group->gr_name, name)) {
+ close(grp_fd);
+ return group;
+ }
+
+ close(grp_fd);
+ return NULL;
+}
diff --git a/libpwdgrp/getpw.c b/libpwdgrp/getpw.c
new file mode 100644
index 000000000..ca11188aa
--- /dev/null
+++ b/libpwdgrp/getpw.c
@@ -0,0 +1,47 @@
+/*
+ * getpw.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <sys/types.h>
+#include <errno.h>
+#include <stdio.h>
+#include "pwd.h"
+
+int getpw(uid_t uid, char *buf)
+{
+ struct passwd *passwd;
+
+ if (buf == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ if ((passwd = getpwuid(uid)) == NULL)
+ return -1;
+
+ if (sprintf (buf, "%s:%s:%u:%u:%s:%s:%s", passwd->pw_name, passwd->pw_passwd,
+ passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, passwd->pw_dir,
+ passwd->pw_shell) < 0) {
+ errno = ENOBUFS;
+ return -1;
+ }
+
+ return 0;
+}
diff --git a/libpwdgrp/getpwnam.c b/libpwdgrp/getpwnam.c
new file mode 100644
index 000000000..88a31f8c2
--- /dev/null
+++ b/libpwdgrp/getpwnam.c
@@ -0,0 +1,51 @@
+/*
+ * getpwnam.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include "pwd.h"
+
+
+struct passwd *getpwnam(const char *name)
+{
+ int passwd_fd;
+ struct passwd *passwd;
+
+ if (name == NULL) {
+ errno = EINVAL;
+ return NULL;
+ }
+
+ if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0)
+ return NULL;
+
+ while ((passwd = __getpwent(passwd_fd)) != NULL)
+ if (!strcmp(passwd->pw_name, name)) {
+ close(passwd_fd);
+ return passwd;
+ }
+
+ close(passwd_fd);
+ return NULL;
+}
diff --git a/libpwdgrp/getpwuid.c b/libpwdgrp/getpwuid.c
new file mode 100644
index 000000000..776ed12da
--- /dev/null
+++ b/libpwdgrp/getpwuid.c
@@ -0,0 +1,44 @@
+/*
+ * getpwuid.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include "pwd.h"
+
+struct passwd *getpwuid(uid_t uid)
+{
+ int passwd_fd;
+ struct passwd *passwd;
+
+ if ((passwd_fd = open("/etc/passwd", O_RDONLY)) < 0)
+ return NULL;
+
+ while ((passwd = __getpwent(passwd_fd)) != NULL)
+ if (passwd->pw_uid == uid) {
+ close(passwd_fd);
+ return passwd;
+ }
+
+ close(passwd_fd);
+ return NULL;
+}
diff --git a/libpwdgrp/grent.c b/libpwdgrp/grent.c
new file mode 100644
index 000000000..5b1cb6823
--- /dev/null
+++ b/libpwdgrp/grent.c
@@ -0,0 +1,54 @@
+/*
+ * grent.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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.
+ *
+ */
+
+/*
+ * setgrent(), endgrent(), and getgrent() are mutually-dependent functions,
+ * so they are all included in the same object file, and thus all linked
+ * in together.
+ */
+
+#include "busybox.h"
+
+#include <unistd.h>
+#include <fcntl.h>
+#include "grp.h"
+
+static int grp_fd = -1;
+
+void setgrent(void)
+{
+ if (grp_fd != -1)
+ close(grp_fd);
+ grp_fd = open("/etc/group", O_RDONLY);
+}
+
+void endgrent(void)
+{
+ if (grp_fd != -1)
+ close(grp_fd);
+ grp_fd = -1;
+}
+
+struct group *getgrent(void)
+{
+ if (grp_fd == -1)
+ return NULL;
+ return __getgrent(grp_fd);
+}
diff --git a/libpwdgrp/initgroups.c b/libpwdgrp/initgroups.c
new file mode 100644
index 000000000..9b5dcbcb2
--- /dev/null
+++ b/libpwdgrp/initgroups.c
@@ -0,0 +1,115 @@
+/*
+ * initgroups.c - This file is part of the libc-8086/grp package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <unistd.h>
+#include <string.h>
+#include <fcntl.h>
+#include "grp.h"
+
+/*
+ * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer
+ * so that lines of any length can be used. On very very small systems,
+ * you may want to leave this undefined becasue it will make the grp functions
+ * somewhat larger (because of the inclusion of malloc and the code necessary).
+ * On larger systems, you will want to define this, because grp will _not_
+ * deal with long lines gracefully (they will be skipped).
+ */
+#undef GR_SCALE_DYNAMIC
+
+#ifndef GR_SCALE_DYNAMIC
+/*
+ * If scaling is not dynamic, the buffers will be statically allocated, and
+ * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of
+ * characters per line in the group file. GR_MAX_MEMBERS is the maximum
+ * number of members of any given group.
+ */
+#define GR_MAX_LINE_LEN 128
+/* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */
+#define GR_MAX_MEMBERS 11
+
+#endif /* !GR_SCALE_DYNAMIC */
+
+
+/*
+ * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate
+ * space for it's GID array before calling setgroups(). This is probably
+ * unnecessary scalage, so it's undefined by default.
+ */
+#undef GR_DYNAMIC_GROUP_LIST
+
+#ifndef GR_DYNAMIC_GROUP_LIST
+/*
+ * GR_MAX_GROUPS is the size of the static array initgroups() uses for
+ * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined.
+ */
+#define GR_MAX_GROUPS 64
+
+#endif /* !GR_DYNAMIC_GROUP_LIST */
+
+int initgroups(__const char *user, gid_t gid)
+{
+ register struct group *group;
+
+#ifndef GR_DYNAMIC_GROUP_LIST
+ gid_t group_list[GR_MAX_GROUPS];
+#else
+ gid_t *group_list = NULL;
+#endif
+ register char **tmp_mem;
+ int num_groups;
+ int grp_fd;
+
+
+ if ((grp_fd = open("/etc/group", O_RDONLY)) < 0)
+ return -1;
+
+ num_groups = 0;
+#ifdef GR_DYNAMIC_GROUP_LIST
+ group_list = (gid_t *) realloc(group_list, 1);
+#endif
+ group_list[num_groups] = gid;
+#ifndef GR_DYNAMIC_GROUP_LIST
+ while (num_groups < GR_MAX_GROUPS &&
+ (group = __getgrent(grp_fd)) != NULL)
+#else
+ while ((group = __getgrent(grp_fd)) != NULL)
+#endif
+ {
+ if (group->gr_gid != gid);
+ {
+ tmp_mem = group->gr_mem;
+ while (*tmp_mem != NULL) {
+ if (!strcmp(*tmp_mem, user)) {
+ num_groups++;
+#ifdef GR_DYNAMIC_GROUP_LIST
+ group_list = (gid_t *) realloc(group_list, num_groups *
+ sizeof(gid_t *));
+#endif
+ group_list[num_groups] = group->gr_gid;
+ }
+ tmp_mem++;
+ }
+ }
+ }
+ close(grp_fd);
+ return setgroups(num_groups, group_list);
+}
diff --git a/libpwdgrp/putpwent.c b/libpwdgrp/putpwent.c
new file mode 100644
index 000000000..88dffc952
--- /dev/null
+++ b/libpwdgrp/putpwent.c
@@ -0,0 +1,39 @@
+/*
+ * putpwent.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <stdio.h>
+#include <errno.h>
+#include "pwd.h"
+
+int putpwent(const struct passwd *passwd, FILE * f)
+{
+ if (passwd == NULL || f == NULL) {
+ errno = EINVAL;
+ return -1;
+ }
+ if (fprintf (f, "%s:%s:%u:%u:%s:%s:%s\n", passwd->pw_name, passwd->pw_passwd,
+ passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, passwd->pw_dir,
+ passwd->pw_shell) < 0)
+ return -1;
+
+ return 0;
+}
diff --git a/libpwdgrp/pwent.c b/libpwdgrp/pwent.c
new file mode 100644
index 000000000..84bd6176b
--- /dev/null
+++ b/libpwdgrp/pwent.c
@@ -0,0 +1,58 @@
+/*
+ * pwent.c - This file is part of the libc-8086/pwd package for ELKS,
+ * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>.
+ *
+ * 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 "busybox.h"
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include "pwd.h"
+#include <fcntl.h>
+
+/*
+ * setpwent(), endpwent(), and getpwent() 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.
+ */
+
+/* file descriptor for the password file currently open */
+static int pw_fd = -1;
+
+void setpwent(void)
+{
+ if (pw_fd != -1)
+ close(pw_fd);
+
+ pw_fd = open("/etc/passwd", O_RDONLY);
+}
+
+void endpwent(void)
+{
+ if (pw_fd != -1)
+ close(pw_fd);
+ pw_fd = -1;
+}
+
+struct passwd *getpwent(void)
+{
+ if (pw_fd != -1)
+ return (__getpwent(pw_fd));
+ return NULL;
+}
diff --git a/libpwdgrp/setgroups.c b/libpwdgrp/setgroups.c
new file mode 100644
index 000000000..c9b86f016
--- /dev/null
+++ b/libpwdgrp/setgroups.c
@@ -0,0 +1,42 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Taken from the set of syscalls for uClibc
+ *
+ * Copyright (C) 1999,2000,2001 by Erik Andersen <andersee@debian.org>
+ * <andersen@lineo.com>, <andersee@debian.org>
+ *
+ * This program 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 program 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 program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+#include "busybox.h"
+
+#include <errno.h>
+#include <unistd.h>
+#include <features.h>
+#include <sys/types.h>
+/* Kernel headers before 2.1.mumble need this on the Alpha to get
+ _syscall* defined. */
+#define __LIBRARY__
+#include <sys/syscall.h>
+#if __GNU_LIBRARY__ < 5
+/* This is needed for libc5 */
+#include <asm/unistd.h>
+#endif
+#include "grp.h"
+
+//#define __NR_setgroups 81
+_syscall2(int, setgroups, size_t, size, const gid_t *, list);
+
diff --git a/libpwdgrp/shadow.c b/libpwdgrp/shadow.c
new file mode 100644
index 000000000..6cf195e4a
--- /dev/null
+++ b/libpwdgrp/shadow.c
@@ -0,0 +1,302 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * Copyright 1989 - 1994, Julianne Frances Haugh
+ * <jockgrrl@austin.rr.com>, <jfh@austin.ibm.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* TODO: fgetspent_r.c getspent_r.c getspnam_r.c sgetspent_r.c
+ * lckpwdf ulckpwdf
+ */
+
+#include "busybox.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "shadow.h"
+
+static FILE *shadow;
+static char spwbuf[BUFSIZ];
+static struct spwd spwd;
+
+#define FIELDS 9
+#define OFIELDS 5
+
+/* setspent - initialize access to shadow text and DBM files */
+void setspent(void)
+{
+ if (shadow) {
+ rewind(shadow);
+ } else {
+ if ((shadow = fopen("/etc/shadow", "r")) == NULL)
+ perror_msg_and_die("/etc/shadow");
+ }
+}
+
+/* endspent - terminate access to shadow text and DBM files */
+void endspent(void)
+{
+ if (shadow)
+ (void) fclose(shadow);
+ shadow = (FILE *) 0;
+}
+
+/* getspent - get a (struct spwd *) from the current shadow file */
+struct spwd *getspent(void)
+{
+ if (!shadow)
+ setspent();
+ return (fgetspent(shadow));
+}
+
+/* getspnam - get a shadow entry by name */
+struct spwd *getspnam(const char *name)
+{
+ struct spwd *sp;
+
+ if (!name || !strlen(name))
+ return NULL;
+
+ setspent();
+ while ((sp = getspent()) != NULL) {
+ if (strcmp(name, sp->sp_namp) == 0)
+ break;
+ }
+ endspent();
+ return (sp);
+}
+
+
+/* sgetspent - convert string in shadow file format to (struct spwd *) */
+/* returns NULL on error */
+struct spwd *sgetspent(const char *string)
+{
+ char *fields[FIELDS];
+ char *cp;
+ char *cpp;
+ int i;
+
+ /*
+ * Copy string to local buffer. It has to be tokenized and we
+ * have to do that to our private copy.
+ */
+
+ if (strlen(string) >= sizeof spwbuf)
+ /* return 0; */
+ return NULL;
+ strcpy(spwbuf, string);
+
+ if ((cp = strrchr(spwbuf, '\n')))
+ *cp = '\0';
+
+ /*
+ * Tokenize the string into colon separated fields. Allow up to
+ * FIELDS different fields.
+ */
+
+ for (cp = spwbuf, i = 0; *cp && i < FIELDS; i++) {
+ fields[i] = cp;
+ while (*cp && *cp != ':')
+ cp++;
+
+ if (*cp)
+ *cp++ = '\0';
+ }
+
+ /*
+ * It is acceptable for the last SVR4 field to be blank. This
+ * results in the loop being terminated early. In which case,
+ * we just make the last field be blank and be done with it.
+ */
+
+ if (i == (FIELDS - 1))
+ fields[i++] = cp;
+
+ if ((cp && *cp) || (i != FIELDS && i != OFIELDS))
+ /* return 0; */
+ return NULL;
+
+ /*
+ * Start populating the structure. The fields are all in
+ * static storage, as is the structure we pass back. If we
+ * ever see a name with '+' as the first character, we try
+ * to turn on NIS processing.
+ */
+
+ spwd.sp_namp = fields[0];
+ spwd.sp_pwdp = fields[1];
+
+ /*
+ * Get the last changed date. For all of the integer fields,
+ * we check for proper format. It is an error to have an
+ * incorrectly formatted number, unless we are using NIS.
+ */
+
+ if ((spwd.sp_lstchg = strtol(fields[2], &cpp, 10)) == 0 && *cpp) {
+ /* return 0; */
+ return NULL;
+ } else if (fields[2][0] == '\0')
+ spwd.sp_lstchg = -1;
+
+ /*
+ * Get the minimum period between password changes.
+ */
+
+ if ((spwd.sp_min = strtol(fields[3], &cpp, 10)) == 0 && *cpp) {
+ /* return 0; */
+ return NULL;
+ } else if (fields[3][0] == '\0')
+ spwd.sp_min = -1;
+
+ /*
+ * Get the maximum number of days a password is valid.
+ */
+
+ if ((spwd.sp_max = strtol(fields[4], &cpp, 10)) == 0 && *cpp) {
+ /* return 0; */
+ return NULL;
+ } else if (fields[4][0] == '\0')
+ spwd.sp_max = -1;
+
+ /*
+ * If there are only OFIELDS fields (this is a SVR3.2 /etc/shadow
+ * formatted file), initialize the other field members to -1.
+ */
+
+ if (i == OFIELDS) {
+ spwd.sp_warn = spwd.sp_inact = spwd.sp_expire = spwd.sp_flag = -1;
+
+ return &spwd;
+ }
+
+ /*
+ * The rest of the fields are mandatory for SVR4, but optional
+ * for anything else. However, if one is present the others
+ * must be as well.
+ */
+
+ /*
+ * Get the number of days of password expiry warning.
+ */
+
+ if ((spwd.sp_warn = strtol(fields[5], &cpp, 10)) == 0 && *cpp) {
+ /* return 0; */
+ return NULL;
+ } else if (fields[5][0] == '\0')
+ spwd.sp_warn = -1;
+
+ /*
+ * Get the number of days of inactivity before an account is
+ * disabled.
+ */
+
+ if ((spwd.sp_inact = strtol(fields[6], &cpp, 10)) == 0 && *cpp) {
+ /* return 0; */
+ return NULL;
+ } else if (fields[6][0] == '\0')
+ spwd.sp_inact = -1;
+
+ /*
+ * Get the number of days after the epoch before the account is
+ * set to expire.
+ */
+
+ if ((spwd.sp_expire = strtol(fields[7], &cpp, 10)) == 0 && *cpp) {
+ /* return 0; */
+ return NULL;
+ } else if (fields[7][0] == '\0')
+ spwd.sp_expire = -1;
+
+ /*
+ * This field is reserved for future use. But it isn't supposed
+ * to have anything other than a valid integer in it.
+ */
+
+ if ((spwd.sp_flag = strtol(fields[8], &cpp, 10)) == 0 && *cpp) {
+ /* return 0; */
+ return NULL;
+ } else if (fields[8][0] == '\0')
+ spwd.sp_flag = -1;
+
+ return (&spwd);
+}
+
+/* fgetspent - get an entry from an /etc/shadow formatted stream */
+struct spwd *fgetspent(FILE *fp)
+{
+ char buf[BUFSIZ];
+ char *cp;
+
+ if (!fp)
+ /* return (0); */
+ return NULL;
+
+ if (fgets(buf, sizeof buf, fp) != (char *) 0) {
+ if ((cp = strchr(buf, '\n')))
+ *cp = '\0';
+ return (sgetspent(buf));
+ }
+ /* return 0; */
+ return NULL;
+}
+
+/*
+ * putspent - put a (struct spwd *) into the (FILE *) you provide.
+ *
+ * this was described in shadow_.h but not implemented, so here
+ * I go. -beppu
+ *
+ */
+int putspent(const struct spwd *sp, FILE *fp)
+{
+ int ret;
+
+ /* seek to end */
+ ret = fseek(fp, 0, SEEK_END);
+ if (ret == -1) {
+ /* return -1; */
+ return 1;
+ }
+
+ /* powered by fprintf */
+ fprintf(fp, "%s:%s:%ld:%ld:%ld:%ld:%ld:%ld:%s\n", sp->sp_namp, /* login name */
+ sp->sp_pwdp, /* encrypted password */
+ sp->sp_lstchg, /* date of last change */
+ sp->sp_min, /* minimum number of days between changes */
+ sp->sp_max, /* maximum number of days between changes */
+ sp->sp_warn, /* number of days of warning before password expires */
+ sp->sp_inact, /* number of days after password expires until
+ the account becomes unusable */
+ sp->sp_expire, /* days since 1/1/70 until account expires */
+ "");
+ return 0;
+}
+
+