aboutsummaryrefslogtreecommitdiff
path: root/REORG.TODO/login
diff options
context:
space:
mode:
Diffstat (limited to 'REORG.TODO/login')
-rw-r--r--REORG.TODO/login/Makefile73
-rw-r--r--REORG.TODO/login/Versions54
-rw-r--r--REORG.TODO/login/endutxent.c26
-rw-r--r--REORG.TODO/login/forkpty.c54
-rw-r--r--REORG.TODO/login/getlogin.c31
-rw-r--r--REORG.TODO/login/getlogin_r.c35
-rw-r--r--REORG.TODO/login/getlogin_r_chk.c28
-rw-r--r--REORG.TODO/login/getpt.c42
-rw-r--r--REORG.TODO/login/getutent.c44
-rw-r--r--REORG.TODO/login/getutent_r.c183
-rw-r--r--REORG.TODO/login/getutid.c42
-rw-r--r--REORG.TODO/login/getutid_r.c62
-rw-r--r--REORG.TODO/login/getutline.c43
-rw-r--r--REORG.TODO/login/getutline_r.c45
-rw-r--r--REORG.TODO/login/getutmp.c45
-rw-r--r--REORG.TODO/login/getutmpx.c47
-rw-r--r--REORG.TODO/login/getutxent.c26
-rw-r--r--REORG.TODO/login/getutxid.c26
-rw-r--r--REORG.TODO/login/getutxline.c26
-rw-r--r--REORG.TODO/login/grantpt.c32
-rw-r--r--REORG.TODO/login/lastlog.h4
-rw-r--r--REORG.TODO/login/login.c143
-rw-r--r--REORG.TODO/login/login_tty.c76
-rw-r--r--REORG.TODO/login/logout.c72
-rw-r--r--REORG.TODO/login/logwtmp.c55
-rw-r--r--REORG.TODO/login/openpty.c140
-rw-r--r--REORG.TODO/login/programs/pt_chown.c215
-rw-r--r--REORG.TODO/login/programs/utmpdump.c99
-rw-r--r--REORG.TODO/login/ptsname.c44
-rw-r--r--REORG.TODO/login/ptsname_r_chk.c28
-rw-r--r--REORG.TODO/login/pty.h48
-rw-r--r--REORG.TODO/login/pututxline.c26
-rw-r--r--REORG.TODO/login/setlogin.c29
-rw-r--r--REORG.TODO/login/setutxent.c26
-rw-r--r--REORG.TODO/login/tst-getlogin.c60
-rw-r--r--REORG.TODO/login/tst-grantpt.c81
-rw-r--r--REORG.TODO/login/tst-ptsname.c107
-rw-r--r--REORG.TODO/login/tst-utmp.c403
-rw-r--r--REORG.TODO/login/tst-utmpx.c2
-rw-r--r--REORG.TODO/login/unlockpt.c32
-rw-r--r--REORG.TODO/login/updwtmp.c34
-rw-r--r--REORG.TODO/login/updwtmpx.c26
-rw-r--r--REORG.TODO/login/utmp-private.h53
-rw-r--r--REORG.TODO/login/utmp.h96
-rw-r--r--REORG.TODO/login/utmp_file.c524
-rw-r--r--REORG.TODO/login/utmpname.c76
-rw-r--r--REORG.TODO/login/utmpxname.c26
47 files changed, 3489 insertions, 0 deletions
diff --git a/REORG.TODO/login/Makefile b/REORG.TODO/login/Makefile
new file mode 100644
index 0000000000..011724cb5d
--- /dev/null
+++ b/REORG.TODO/login/Makefile
@@ -0,0 +1,73 @@
+# Copyright (C) 1996-2017 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 Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 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
+# Lesser General Public License for more details.
+
+# You should have received a copy of the GNU Lesser General Public
+# License along with the GNU C Library; if not, see
+# <http://www.gnu.org/licenses/>.
+
+#
+# Sub-makefile for login portion of the library.
+#
+
+subdir := login
+
+include ../Makeconfig
+
+headers := utmp.h bits/utmp.h lastlog.h pty.h
+
+routines := getlogin getlogin_r setlogin getlogin_r_chk \
+ getutent getutent_r getutid getutline getutid_r getutline_r \
+ utmp_file utmpname updwtmp getpt grantpt unlockpt ptsname \
+ ptsname_r_chk
+
+CFLAGS-grantpt.c = -DLIBEXECDIR='"$(libexecdir)"'
+
+others = utmpdump
+
+ifeq (yes,$(build-pt-chown))
+others += pt_chown
+others-pie = pt_chown
+install-others-programs = $(inst_libexecdir)/pt_chown
+endif
+
+subdir-dirs = programs
+vpath %.c programs
+
+tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname tst-getlogin
+
+# Build the -lutil library with these extra functions.
+extra-libs := libutil
+extra-libs-others := $(extra-libs)
+
+libutil-routines:= login login_tty logout logwtmp openpty forkpty
+
+include ../Rules
+
+CFLAGS-getpt.c = -fexceptions
+
+ifeq (yesyes,$(have-fpie)$(build-shared))
+pt_chown-cflags += $(pie-ccflag)
+endif
+ifeq (yes,$(have-libcap))
+libcap = -lcap
+endif
+CFLAGS-pt_chown.c = $(pt_chown-cflags)
+LDLIBS-pt_chown = $(libcap)
+ifeq (yesyes,$(have-fpie)$(build-shared))
+LDFLAGS-pt_chown = -Wl,-z,now
+endif
+
+# pt_chown needs to be setuid root.
+$(inst_libexecdir)/pt_chown: $(objpfx)pt_chown $(+force)
+ $(make-target-directory)
+ -$(INSTALL_PROGRAM) -m 4755 -o root $< $@
diff --git a/REORG.TODO/login/Versions b/REORG.TODO/login/Versions
new file mode 100644
index 0000000000..475fcf063f
--- /dev/null
+++ b/REORG.TODO/login/Versions
@@ -0,0 +1,54 @@
+libc {
+ GLIBC_2.0 {
+ # e*
+ endutent;
+
+ # g*
+ getlogin; getlogin_r; getutent; getutent_r; getutid; getutid_r; getutline;
+ getutline_r;
+
+ # p*
+ pututline;
+
+ # s*
+ setlogin;
+ setutent;
+
+ # u*
+ updwtmp; utmpname;
+ }
+ GLIBC_2.1 {
+ # e*
+ endutxent;
+
+ # g*
+ getpt; getutxent; getutxid; getutxline; grantpt;
+
+ # p*
+ ptsname; ptsname_r; pututxline;
+
+ # s*
+ setutxent;
+
+ # u*
+ unlockpt; updwtmpx; utmpxname;
+ }
+ GLIBC_2.1.1 {
+ # g*
+ getutmpx; getutmp;
+ }
+ GLIBC_2.2.1 {
+ # p*
+ posix_openpt;
+ }
+ GLIBC_2.4 {
+ __getlogin_r_chk;
+ __ptsname_r_chk;
+ }
+}
+
+libutil {
+ GLIBC_2.0 {
+ forkpty; login; login_tty; logout; logwtmp; openpty;
+ }
+}
diff --git a/REORG.TODO/login/endutxent.c b/REORG.TODO/login/endutxent.c
new file mode 100644
index 0000000000..e8a351a230
--- /dev/null
+++ b/REORG.TODO/login/endutxent.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+void
+endutxent (void)
+{
+ __endutent ();
+}
diff --git a/REORG.TODO/login/forkpty.c b/REORG.TODO/login/forkpty.c
new file mode 100644
index 0000000000..cb1ddab7ad
--- /dev/null
+++ b/REORG.TODO/login/forkpty.c
@@ -0,0 +1,54 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <sys/types.h>
+#include <termios.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <pty.h>
+
+int
+forkpty (int *amaster, char *name, const struct termios *termp,
+ const struct winsize *winp)
+{
+ int master, slave, pid;
+
+ if (openpty (&master, &slave, name, termp, winp) == -1)
+ return -1;
+
+ switch (pid = fork ())
+ {
+ case -1:
+ close (master);
+ close (slave);
+ return -1;
+ case 0:
+ /* Child. */
+ close (master);
+ if (login_tty (slave))
+ _exit (1);
+
+ return 0;
+ default:
+ /* Parent. */
+ *amaster = master;
+ close (slave);
+
+ return pid;
+ }
+}
diff --git a/REORG.TODO/login/getlogin.c b/REORG.TODO/login/getlogin.c
new file mode 100644
index 0000000000..2743578d16
--- /dev/null
+++ b/REORG.TODO/login/getlogin.c
@@ -0,0 +1,31 @@
+/* Copyright (C) 1991-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stddef.h>
+#include <errno.h>
+#include <unistd.h>
+
+/* Return the login name of the user, or NULL if it can't be determined.
+ The returned pointer, if not NULL, is good only until the next call. */
+char *
+getlogin (void)
+{
+ __set_errno (ENOSYS);
+ return NULL;
+}
+
+stub_warning (getlogin)
diff --git a/REORG.TODO/login/getlogin_r.c b/REORG.TODO/login/getlogin_r.c
new file mode 100644
index 0000000000..209d78ffce
--- /dev/null
+++ b/REORG.TODO/login/getlogin_r.c
@@ -0,0 +1,35 @@
+/* Reentrant function to return the current login name. Stub version.
+ Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Return at most NAME_LEN characters of the login name of the user in NAME.
+ If it cannot be determined or some other error occurred, return the error
+ code. Otherwise return 0. */
+int
+__getlogin_r (char *name, size_t name_len)
+{
+ __set_errno (ENOSYS);
+ return errno;
+}
+libc_hidden_def (__getlogin_r)
+weak_alias (__getlogin_r, getlogin_r)
+libc_hidden_weak (getlogin_r)
+
+stub_warning (getlogin_r)
diff --git a/REORG.TODO/login/getlogin_r_chk.c b/REORG.TODO/login/getlogin_r_chk.c
new file mode 100644
index 0000000000..5e98e5ad48
--- /dev/null
+++ b/REORG.TODO/login/getlogin_r_chk.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2005-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+
+
+int
+__getlogin_r_chk (char *buf, size_t buflen, size_t nreal)
+{
+ if (buflen > nreal)
+ __chk_fail ();
+
+ return getlogin_r (buf, buflen);
+}
diff --git a/REORG.TODO/login/getpt.c b/REORG.TODO/login/getpt.c
new file mode 100644
index 0000000000..aa859725b0
--- /dev/null
+++ b/REORG.TODO/login/getpt.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <errno.h>
+
+/* Open the master side of a pseudoterminal and return its file
+ descriptor, or -1 on error. */
+int
+__getpt (void)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+weak_alias (__getpt, getpt)
+
+/* We cannot define posix_openpt in general for BSD systems. */
+int
+__posix_openpt (int oflag)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+weak_alias (__posix_openpt, posix_openpt)
+
+stub_warning (getpt)
+stub_warning (posix_openpt)
diff --git a/REORG.TODO/login/getutent.c b/REORG.TODO/login/getutent.c
new file mode 100644
index 0000000000..114f7dbbc7
--- /dev/null
+++ b/REORG.TODO/login/getutent.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <utmp.h>
+
+
+/* Local buffer to store the result. */
+libc_freeres_ptr (static struct utmp *buffer);
+
+
+struct utmp *
+__getutent (void)
+{
+ struct utmp *result;
+
+ if (buffer == NULL)
+ {
+ buffer = (struct utmp *) malloc (sizeof (struct utmp));
+ if (buffer == NULL)
+ return NULL;
+ }
+
+ if (__getutent_r (buffer, &result) < 0)
+ return NULL;
+
+ return result;
+}
+weak_alias (__getutent, getutent)
diff --git a/REORG.TODO/login/getutent_r.c b/REORG.TODO/login/getutent_r.c
new file mode 100644
index 0000000000..62272a2841
--- /dev/null
+++ b/REORG.TODO/login/getutent_r.c
@@ -0,0 +1,183 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>
+ and Paul Janzen <pcj@primenet.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <libc-lock.h>
+#include <stdlib.h>
+#include <utmp.h>
+
+#include "utmp-private.h"
+
+
+/* Functions defined here. */
+static int setutent_unknown (void);
+static int getutent_r_unknown (struct utmp *buffer, struct utmp **result);
+static int getutid_r_unknown (const struct utmp *line, struct utmp *buffer,
+ struct utmp **result);
+static int getutline_r_unknown (const struct utmp *id, struct utmp *buffer,
+ struct utmp **result);
+static struct utmp *pututline_unknown (const struct utmp *data);
+static void endutent_unknown (void);
+
+/* Initial Jump table. */
+const struct utfuncs __libc_utmp_unknown_functions =
+{
+ setutent_unknown,
+ getutent_r_unknown,
+ getutid_r_unknown,
+ getutline_r_unknown,
+ pututline_unknown,
+ endutent_unknown,
+ NULL
+};
+
+/* Currently selected backend. */
+const struct utfuncs *__libc_utmp_jump_table = &__libc_utmp_unknown_functions;
+
+/* We need to protect the opening of the file. */
+__libc_lock_define_initialized (, __libc_utmp_lock attribute_hidden)
+
+
+static int
+setutent_unknown (void)
+{
+ int result;
+
+ result = (*__libc_utmp_file_functions.setutent) ();
+ if (result)
+ __libc_utmp_jump_table = &__libc_utmp_file_functions;
+
+ return result;
+}
+
+
+static int
+getutent_r_unknown (struct utmp *buffer, struct utmp **result)
+{
+ /* The backend was not yet initialized. */
+ if (setutent_unknown ())
+ return (*__libc_utmp_jump_table->getutent_r) (buffer, result);
+
+ /* Not available. */
+ *result = NULL;
+ return -1;
+}
+
+
+static int
+getutid_r_unknown (const struct utmp *id, struct utmp *buffer,
+ struct utmp **result)
+{
+ /* The backend was not yet initialized. */
+ if (setutent_unknown ())
+ return (*__libc_utmp_jump_table->getutid_r) (id, buffer, result);
+
+ /* Not available. */
+ *result = NULL;
+ return -1;
+}
+
+
+static int
+getutline_r_unknown (const struct utmp *line, struct utmp *buffer,
+ struct utmp **result)
+{
+ /* The backend was not yet initialized. */
+ if (setutent_unknown ())
+ return (*__libc_utmp_jump_table->getutline_r) (line, buffer, result);
+
+ /* Not available. */
+ *result = NULL;
+ return -1;
+}
+
+
+static struct utmp *
+pututline_unknown (const struct utmp *data)
+{
+ /* The backend was not yet initialized. */
+ if (setutent_unknown ())
+ return (*__libc_utmp_jump_table->pututline) (data);
+
+ /* Not available. */
+ return NULL;
+}
+
+
+static void
+endutent_unknown (void)
+{
+ /* Nothing to do. */
+}
+
+
+void
+__setutent (void)
+{
+ __libc_lock_lock (__libc_utmp_lock);
+
+ (*__libc_utmp_jump_table->setutent) ();
+
+ __libc_lock_unlock (__libc_utmp_lock);
+}
+weak_alias (__setutent, setutent)
+
+
+int
+__getutent_r (struct utmp *buffer, struct utmp **result)
+{
+ int retval;
+
+ __libc_lock_lock (__libc_utmp_lock);
+
+ retval = (*__libc_utmp_jump_table->getutent_r) (buffer, result);
+
+ __libc_lock_unlock (__libc_utmp_lock);
+
+ return retval;
+}
+weak_alias (__getutent_r, getutent_r)
+
+
+struct utmp *
+__pututline (const struct utmp *data)
+{
+ struct utmp *buffer;
+
+ __libc_lock_lock (__libc_utmp_lock);
+
+ buffer = (*__libc_utmp_jump_table->pututline) (data);
+
+ __libc_lock_unlock (__libc_utmp_lock);
+
+ return buffer;
+}
+weak_alias (__pututline, pututline)
+
+
+void
+__endutent (void)
+{
+ __libc_lock_lock (__libc_utmp_lock);
+
+ (*__libc_utmp_jump_table->endutent) ();
+ __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
+
+ __libc_lock_unlock (__libc_utmp_lock);
+}
+weak_alias (__endutent, endutent)
diff --git a/REORG.TODO/login/getutid.c b/REORG.TODO/login/getutid.c
new file mode 100644
index 0000000000..003bc657e6
--- /dev/null
+++ b/REORG.TODO/login/getutid.c
@@ -0,0 +1,42 @@
+/* Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <utmp.h>
+
+
+/* Local buffer to store the result. */
+libc_freeres_ptr (static struct utmp *buffer);
+
+struct utmp *
+__getutid (const struct utmp *id)
+{
+ struct utmp *result;
+
+ if (buffer == NULL)
+ {
+ buffer = (struct utmp *) malloc (sizeof (struct utmp));
+ if (buffer == NULL)
+ return NULL;
+ }
+ if (__getutid_r (id, buffer, &result) < 0)
+ return NULL;
+
+ return result;
+}
+weak_alias (__getutid, getutid)
diff --git a/REORG.TODO/login/getutid_r.c b/REORG.TODO/login/getutid_r.c
new file mode 100644
index 0000000000..f82301322f
--- /dev/null
+++ b/REORG.TODO/login/getutid_r.c
@@ -0,0 +1,62 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>
+ and Paul Janzen <pcj@primenet.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <libc-lock.h>
+#include <errno.h>
+#include <stdlib.h>
+#include <utmp.h>
+
+#include "utmp-private.h"
+
+
+/* We have to use the lock in getutent_r.c. */
+__libc_lock_define (extern, __libc_utmp_lock attribute_hidden)
+
+
+int
+__getutid_r (const struct utmp *id, struct utmp *buffer, struct utmp **result)
+{
+#if (_HAVE_UT_ID - 0) && (_HAVE_UT_TYPE - 0)
+ int retval;
+
+ /* Test whether ID has any of the legal types. */
+ if (id->ut_type != RUN_LVL && id->ut_type != BOOT_TIME
+ && id->ut_type != OLD_TIME && id->ut_type != NEW_TIME
+ && id->ut_type != INIT_PROCESS && id->ut_type != LOGIN_PROCESS
+ && id->ut_type != USER_PROCESS && id->ut_type != DEAD_PROCESS)
+ /* No, using '<' and '>' for the test is not possible. */
+ {
+ __set_errno (EINVAL);
+ *result = NULL;
+ return -1;
+ }
+
+ __libc_lock_lock (__libc_utmp_lock);
+
+ retval = (*__libc_utmp_jump_table->getutid_r) (id, buffer, result);
+
+ __libc_lock_unlock (__libc_utmp_lock);
+
+ return retval;
+#else /* !_HAVE_UT_ID && !_HAVE_UT_TYPE */
+ __set_errno (ENOSYS);
+ return -1;
+#endif
+}
+weak_alias (__getutid_r, getutid_r)
diff --git a/REORG.TODO/login/getutline.c b/REORG.TODO/login/getutline.c
new file mode 100644
index 0000000000..f5291e8a8e
--- /dev/null
+++ b/REORG.TODO/login/getutline.c
@@ -0,0 +1,43 @@
+/* Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <utmp.h>
+
+
+/* Local buffer to store the result. */
+libc_freeres_ptr (static struct utmp *buffer);
+
+
+struct utmp *
+__getutline (const struct utmp *line)
+{
+ struct utmp *result;
+
+ if (buffer == NULL)
+ {
+ buffer = (struct utmp *) malloc (sizeof (struct utmp));
+ if (buffer == NULL)
+ return NULL;
+ }
+ if (__getutline_r (line, buffer, &result) < 0)
+ return NULL;
+
+ return result;
+}
+weak_alias (__getutline, getutline)
diff --git a/REORG.TODO/login/getutline_r.c b/REORG.TODO/login/getutline_r.c
new file mode 100644
index 0000000000..1a6f1688ee
--- /dev/null
+++ b/REORG.TODO/login/getutline_r.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>
+ and Paul Janzen <pcj@primenet.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <libc-lock.h>
+#include <utmp.h>
+
+#include "utmp-private.h"
+
+
+/* We have to use the lock in getutent_r.c. */
+__libc_lock_define (extern, __libc_utmp_lock attribute_hidden)
+
+
+int
+__getutline_r (const struct utmp *line, struct utmp *buffer,
+ struct utmp **result)
+{
+ int retval;
+
+ __libc_lock_lock (__libc_utmp_lock);
+
+ retval = (*__libc_utmp_jump_table->getutline_r) (line, buffer, result);
+
+ __libc_lock_unlock (__libc_utmp_lock);
+
+ return retval;
+}
+weak_alias (__getutline_r, getutline_r)
diff --git a/REORG.TODO/login/getutmp.c b/REORG.TODO/login/getutmp.c
new file mode 100644
index 0000000000..4160cf589a
--- /dev/null
+++ b/REORG.TODO/login/getutmp.c
@@ -0,0 +1,45 @@
+/* Copyright (C) 1999-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <utmp.h>
+#include <utmpx.h>
+
+/* Copy the information in UTMPX to UTMP. */
+void
+getutmp (const struct utmpx *utmpx, struct utmp *utmp)
+{
+#if _HAVE_UT_TYPE - 0
+ utmp->ut_type = utmpx->ut_type;
+#endif
+#if _HAVE_UT_PID - 0
+ utmp->ut_pid = utmpx->ut_pid;
+#endif
+ memcpy (utmp->ut_line, utmpx->ut_line, sizeof (utmp->ut_line));
+ memcpy (utmp->ut_user, utmpx->ut_user, sizeof (utmp->ut_user));
+#if _HAVE_UT_ID - 0
+ memcpy (utmp->ut_id, utmpx->ut_id, sizeof (utmp->ut_id));
+#endif
+#if _HAVE_UT_HOST - 0
+ memcpy (utmp->ut_host, utmpx->ut_host, sizeof (utmp->ut_host));
+#endif
+#if _HAVE_UT_TV - 0
+ utmp->ut_tv = utmpx->ut_tv;
+#else
+ utmp->ut_time = utmpx->ut_time;
+#endif
+}
diff --git a/REORG.TODO/login/getutmpx.c b/REORG.TODO/login/getutmpx.c
new file mode 100644
index 0000000000..77dc78cc3e
--- /dev/null
+++ b/REORG.TODO/login/getutmpx.c
@@ -0,0 +1,47 @@
+/* Copyright (C) 1999-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <utmp.h>
+#include <utmpx.h>
+
+/* Copy the information in UTMP to UTMPX. */
+void
+getutmpx (const struct utmp *utmp, struct utmpx *utmpx)
+{
+ memset (utmpx, 0, sizeof (struct utmpx));
+
+#if _HAVE_UT_TYPE - 0
+ utmpx->ut_type = utmp->ut_type;
+#endif
+#if _HAVE_UT_PID - 0
+ utmpx->ut_pid = utmp->ut_pid;
+#endif
+ memcpy (utmpx->ut_line, utmp->ut_line, sizeof (utmp->ut_line));
+ memcpy (utmpx->ut_user, utmp->ut_user, sizeof (utmp->ut_user));
+#if _HAVE_UT_ID - 0
+ memcpy (utmpx->ut_id, utmp->ut_id, sizeof (utmp->ut_id));
+#endif
+#if _HAVE_UT_HOST - 0
+ memcpy (utmpx->ut_host, utmp->ut_host, sizeof (utmp->ut_host));
+#endif
+#if _HAVE_UT_TV - 0
+ utmpx->ut_tv = utmp->ut_tv;
+#else
+ utmpx->ut_time = utmp->ut_time;
+#endif
+}
diff --git a/REORG.TODO/login/getutxent.c b/REORG.TODO/login/getutxent.c
new file mode 100644
index 0000000000..89bdb2e271
--- /dev/null
+++ b/REORG.TODO/login/getutxent.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+getutxent (void)
+{
+ return (struct utmpx *) __getutent ();
+}
diff --git a/REORG.TODO/login/getutxid.c b/REORG.TODO/login/getutxid.c
new file mode 100644
index 0000000000..435c96d0ef
--- /dev/null
+++ b/REORG.TODO/login/getutxid.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+getutxid (const struct utmpx *id)
+{
+ return (struct utmpx *) __getutid ((const struct utmp *) id);
+}
diff --git a/REORG.TODO/login/getutxline.c b/REORG.TODO/login/getutxline.c
new file mode 100644
index 0000000000..f71a43011f
--- /dev/null
+++ b/REORG.TODO/login/getutxline.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+getutxline (const struct utmpx *line)
+{
+ return (struct utmpx *) __getutline ((const struct utmp *) line);
+}
diff --git a/REORG.TODO/login/grantpt.c b/REORG.TODO/login/grantpt.c
new file mode 100644
index 0000000000..badc004083
--- /dev/null
+++ b/REORG.TODO/login/grantpt.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <errno.h>
+
+/* Given a fd on a master pseudoterminal, chown the file associated
+ with the slave to the calling process, and set its group and
+ mode appropriately. Note that this is an unprivileged operation. */
+int
+grantpt (int fd __attribute__ ((unused)))
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+stub_warning (grantpt)
diff --git a/REORG.TODO/login/lastlog.h b/REORG.TODO/login/lastlog.h
new file mode 100644
index 0000000000..8cc4254364
--- /dev/null
+++ b/REORG.TODO/login/lastlog.h
@@ -0,0 +1,4 @@
+/* This header file is used in 4.3BSD to define `struct lastlog',
+ which we define in <bits/utmp.h>. */
+
+#include <utmp.h>
diff --git a/REORG.TODO/login/login.c b/REORG.TODO/login/login.c
new file mode 100644
index 0000000000..b8171de83c
--- /dev/null
+++ b/REORG.TODO/login/login.c
@@ -0,0 +1,143 @@
+/* Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <utmp.h>
+
+
+/* Return the result of ttyname in the buffer pointed to by TTY, which should
+ be of length BUF_LEN. If it is too long to fit in this buffer, a
+ sufficiently long buffer is allocated using malloc, and returned in TTY.
+ 0 is returned upon success, -1 otherwise. */
+static int
+tty_name (int fd, char **tty, size_t buf_len)
+{
+ int rv; /* Return value. 0 = success. */
+ char *buf = *tty; /* Buffer for ttyname, initially the user's. */
+
+ for (;;)
+ {
+ char *new_buf;
+
+ if (buf_len)
+ {
+ rv = ttyname_r (fd, buf, buf_len);
+
+ if (rv != 0 || memchr (buf, '\0', buf_len))
+ /* We either got an error, or we succeeded and the
+ returned name fit in the buffer. */
+ break;
+
+ /* Try again with a longer buffer. */
+ buf_len += buf_len; /* Double it */
+ }
+ else
+ /* No initial buffer; start out by mallocing one. */
+ buf_len = 128; /* First time guess. */
+
+ if (buf != *tty)
+ /* We've already malloced another buffer at least once. */
+ new_buf = realloc (buf, buf_len);
+ else
+ new_buf = malloc (buf_len);
+ if (! new_buf)
+ {
+ rv = -1;
+ __set_errno (ENOMEM);
+ break;
+ }
+ buf = new_buf;
+ }
+
+ if (rv == 0)
+ *tty = buf; /* Return buffer to the user. */
+ else if (buf != *tty)
+ free (buf); /* Free what we malloced when returning an error. */
+
+ return rv;
+}
+
+void
+login (const struct utmp *ut)
+{
+#ifdef PATH_MAX
+ char _tty[PATH_MAX + UT_LINESIZE];
+#else
+ char _tty[512 + UT_LINESIZE];
+#endif
+ char *tty = _tty;
+ int found_tty;
+ const char *ttyp;
+ struct utmp copy = *ut;
+
+ /* Fill in those fields we supply. */
+#if _HAVE_UT_TYPE - 0
+ copy.ut_type = USER_PROCESS;
+#endif
+#if _HAVE_UT_PID - 0
+ copy.ut_pid = getpid ();
+#endif
+
+ /* Seek tty. */
+ found_tty = tty_name (STDIN_FILENO, &tty, sizeof (_tty));
+ if (found_tty < 0)
+ found_tty = tty_name (STDOUT_FILENO, &tty, sizeof (_tty));
+ if (found_tty < 0)
+ found_tty = tty_name (STDERR_FILENO, &tty, sizeof (_tty));
+
+ if (found_tty >= 0)
+ {
+ /* We only want to insert the name of the tty without path.
+ But take care of name like /dev/pts/3. */
+ if (strncmp (tty, "/dev/", 5) == 0)
+ ttyp = tty + 5; /* Skip the "/dev/". */
+ else
+ ttyp = basename (tty);
+
+ /* Position to record for this tty. */
+ strncpy (copy.ut_line, ttyp, UT_LINESIZE);
+
+ /* Tell that we want to use the UTMP file. */
+ if (utmpname (_PATH_UTMP) == 0)
+ {
+ /* Open UTMP file. */
+ setutent ();
+
+ /* Write the entry. */
+ pututline (&copy);
+
+ /* Close UTMP file. */
+ endutent ();
+ }
+
+ if (tty != _tty)
+ free (tty); /* Free buffer malloced by tty_name. */
+ }
+ else
+ /* We provide a default value so that the output does not contain
+ an random bytes in this field. */
+ strncpy (copy.ut_line, "???", UT_LINESIZE);
+
+ /* Update the WTMP file. Here we have to add a new entry. */
+ updwtmp (_PATH_WTMP, &copy);
+}
diff --git a/REORG.TODO/login/login_tty.c b/REORG.TODO/login/login_tty.c
new file mode 100644
index 0000000000..a94f5cb861
--- /dev/null
+++ b/REORG.TODO/login/login_tty.c
@@ -0,0 +1,76 @@
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. 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.
+ * 4. Neither the name of the University 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 THE REGENTS 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 THE REGENTS 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)login_tty.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+#include <errno.h>
+#include <sys/param.h>
+#include <sys/ioctl.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <utmp.h>
+
+int
+login_tty (int fd)
+{
+ (void) setsid();
+#ifdef TIOCSCTTY
+ if (ioctl(fd, TIOCSCTTY, (char *)NULL) == -1)
+ return (-1);
+#else
+ {
+ /* This might work. */
+ char *fdname = ttyname (fd);
+ int newfd;
+ if (fdname)
+ {
+ if (fd != 0)
+ (void) close (0);
+ if (fd != 1)
+ (void) close (1);
+ if (fd != 2)
+ (void) close (2);
+ newfd = open (fdname, O_RDWR);
+ (void) close (newfd);
+ }
+ }
+#endif
+ while (dup2(fd, 0) == -1 && errno == EBUSY)
+ ;
+ while (dup2(fd, 1) == -1 && errno == EBUSY)
+ ;
+ while (dup2(fd, 2) == -1 && errno == EBUSY)
+ ;
+ if (fd > 2)
+ (void) close(fd);
+ return (0);
+}
+libutil_hidden_def (login_tty)
diff --git a/REORG.TODO/login/logout.c b/REORG.TODO/login/logout.c
new file mode 100644
index 0000000000..6a8ce265ee
--- /dev/null
+++ b/REORG.TODO/login/logout.c
@@ -0,0 +1,72 @@
+/* Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <string.h>
+#include <utmp.h>
+#include <sys/time.h>
+
+int
+logout (const char *line)
+{
+ struct utmp tmp, utbuf;
+ struct utmp *ut;
+ int result = 0;
+
+ /* Tell that we want to use the UTMP file. */
+ if (utmpname (_PATH_UTMP) == -1)
+ return 0;
+
+ /* Open UTMP file. */
+ setutent ();
+
+ /* Fill in search information. */
+#if _HAVE_UT_TYPE - 0
+ tmp.ut_type = USER_PROCESS;
+#endif
+ strncpy (tmp.ut_line, line, sizeof tmp.ut_line);
+
+ /* Read the record. */
+ if (getutline_r (&tmp, &utbuf, &ut) >= 0)
+ {
+ /* Clear information about who & from where. */
+ memset (ut->ut_name, '\0', sizeof ut->ut_name);
+#if _HAVE_UT_HOST - 0
+ memset (ut->ut_host, '\0', sizeof ut->ut_host);
+#endif
+#if _HAVE_UT_TV - 0
+ struct timeval tv;
+ __gettimeofday (&tv, NULL);
+ ut->ut_tv.tv_sec = tv.tv_sec;
+ ut->ut_tv.tv_usec = tv.tv_usec;
+#else
+ ut->ut_time = time (NULL);
+#endif
+#if _HAVE_UT_TYPE - 0
+ ut->ut_type = DEAD_PROCESS;
+#endif
+
+ if (pututline (ut) != NULL)
+ result = 1;
+ }
+
+ /* Close UTMP file. */
+ endutent ();
+
+ return result;
+}
diff --git a/REORG.TODO/login/logwtmp.c b/REORG.TODO/login/logwtmp.c
new file mode 100644
index 0000000000..b62c887adf
--- /dev/null
+++ b/REORG.TODO/login/logwtmp.c
@@ -0,0 +1,55 @@
+/* Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <string.h>
+#include <sys/time.h>
+#include <time.h>
+#include <unistd.h>
+#include <utmp.h>
+
+
+void
+logwtmp (const char *line, const char *name, const char *host)
+{
+ struct utmp ut;
+
+ /* Set information in new entry. */
+ memset (&ut, 0, sizeof (ut));
+#if _HAVE_UT_PID - 0
+ ut.ut_pid = getpid ();
+#endif
+#if _HAVE_UT_TYPE - 0
+ ut.ut_type = name[0] ? USER_PROCESS : DEAD_PROCESS;
+#endif
+ strncpy (ut.ut_line, line, sizeof ut.ut_line);
+ strncpy (ut.ut_name, name, sizeof ut.ut_name);
+#if _HAVE_UT_HOST - 0
+ strncpy (ut.ut_host, host, sizeof ut.ut_host);
+#endif
+
+#if _HAVE_UT_TV - 0
+ struct timeval tv;
+ __gettimeofday (&tv, NULL);
+ ut.ut_tv.tv_sec = tv.tv_sec;
+ ut.ut_tv.tv_usec = tv.tv_usec;
+#else
+ ut.ut_time = time (NULL);
+#endif
+
+ updwtmp (_PATH_WTMP, &ut);
+}
diff --git a/REORG.TODO/login/openpty.c b/REORG.TODO/login/openpty.c
new file mode 100644
index 0000000000..41ab0483e2
--- /dev/null
+++ b/REORG.TODO/login/openpty.c
@@ -0,0 +1,140 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <pty.h>
+#include <stdlib.h>
+#include <string.h>
+#include <termios.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+
+/* Return the result of ptsname_r in the buffer pointed to by PTS,
+ which should be of length BUF_LEN. If it is too long to fit in
+ this buffer, a sufficiently long buffer is allocated using malloc,
+ and returned in PTS. 0 is returned upon success, -1 otherwise. */
+static int
+pts_name (int fd, char **pts, size_t buf_len)
+{
+ int rv;
+ char *buf = *pts;
+
+ for (;;)
+ {
+ char *new_buf;
+
+ if (buf_len)
+ {
+ rv = ptsname_r (fd, buf, buf_len);
+
+ if (rv != 0 || memchr (buf, '\0', buf_len))
+ /* We either got an error, or we succeeded and the
+ returned name fit in the buffer. */
+ break;
+
+ /* Try again with a longer buffer. */
+ buf_len += buf_len; /* Double it */
+ }
+ else
+ /* No initial buffer; start out by mallocing one. */
+ buf_len = 128; /* First time guess. */
+
+ if (buf != *pts)
+ /* We've already malloced another buffer at least once. */
+ new_buf = realloc (buf, buf_len);
+ else
+ new_buf = malloc (buf_len);
+ if (! new_buf)
+ {
+ rv = -1;
+ __set_errno (ENOMEM);
+ break;
+ }
+ buf = new_buf;
+ }
+
+ if (rv == 0)
+ *pts = buf; /* Return buffer to the user. */
+ else if (buf != *pts)
+ free (buf); /* Free what we malloced when returning an error. */
+
+ return rv;
+}
+
+/* Create pseudo tty master slave pair and set terminal attributes
+ according to TERMP and WINP. Return handles for both ends in
+ AMASTER and ASLAVE, and return the name of the slave end in NAME. */
+int
+openpty (int *amaster, int *aslave, char *name,
+ const struct termios *termp, const struct winsize *winp)
+{
+#ifdef PATH_MAX
+ char _buf[PATH_MAX];
+#else
+ char _buf[512];
+#endif
+ char *buf = _buf;
+ int master, slave;
+
+ master = getpt ();
+ if (master == -1)
+ return -1;
+
+ if (grantpt (master))
+ goto fail;
+
+ if (unlockpt (master))
+ goto fail;
+
+ if (pts_name (master, &buf, sizeof (_buf)))
+ goto fail;
+
+ slave = open (buf, O_RDWR | O_NOCTTY);
+ if (slave == -1)
+ {
+ if (buf != _buf)
+ free (buf);
+
+ goto fail;
+ }
+
+ /* XXX Should we ignore errors here? */
+ if (termp)
+ tcsetattr (slave, TCSAFLUSH, termp);
+#ifdef TIOCSWINSZ
+ if (winp)
+ ioctl (slave, TIOCSWINSZ, winp);
+#endif
+
+ *amaster = master;
+ *aslave = slave;
+ if (name != NULL)
+ strcpy (name, buf);
+
+ if (buf != _buf)
+ free (buf);
+ return 0;
+
+ fail:
+ close (master);
+ return -1;
+}
+libutil_hidden_def (openpty)
diff --git a/REORG.TODO/login/programs/pt_chown.c b/REORG.TODO/login/programs/pt_chown.c
new file mode 100644
index 0000000000..f12064bea5
--- /dev/null
+++ b/REORG.TODO/login/programs/pt_chown.c
@@ -0,0 +1,215 @@
+/* pt_chmod - helper program for `grantpt'.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by C. Scott Ananian <cananian@alumni.princeton.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <argp.h>
+#include <errno.h>
+#include <error.h>
+#include <grp.h>
+#include <libintl.h>
+#include <locale.h>
+#include <signal.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#ifdef HAVE_LIBCAP
+# include <sys/capability.h>
+# include <sys/prctl.h>
+#endif
+
+#include "pty-private.h"
+
+/* Get libc version number. */
+#include "../version.h"
+
+#define PACKAGE _libc_intl_domainname
+
+/* Name and version of program. */
+static void print_version (FILE *stream, struct argp_state *state);
+void (*argp_program_version_hook) (FILE *, struct argp_state *) = print_version;
+
+/* Function to print some extra text in the help message. */
+static char *more_help (int key, const char *text, void *input);
+
+/* Data structure to communicate with argp functions. */
+static struct argp argp =
+{
+ NULL, NULL, NULL, NULL, NULL, more_help
+};
+
+
+/* Print the version information. */
+static void
+print_version (FILE *stream, struct argp_state *state)
+{
+ fprintf (stream, "pt_chown %s%s\n", PKGVERSION, VERSION);
+ fprintf (stream, gettext ("\
+Copyright (C) %s Free Software Foundation, Inc.\n\
+This is free software; see the source for copying conditions. There is NO\n\
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
+"), "2017");
+}
+
+static char *
+more_help (int key, const char *text, void *input)
+{
+ char *cp;
+ char *tp;
+
+ switch (key)
+ {
+ case ARGP_KEY_HELP_PRE_DOC:
+ asprintf (&cp, gettext ("\
+Set the owner, group and access permission of the slave pseudo\
+ terminal corresponding to the master pseudo terminal passed on\
+ file descriptor `%d'. This is the helper program for the\
+ `grantpt' function. It is not intended to be run directly from\
+ the command line.\n"),
+ PTY_FILENO);
+ return cp;
+ case ARGP_KEY_HELP_EXTRA:
+ /* We print some extra information. */
+ if (asprintf (&tp, gettext ("\
+For bug reporting instructions, please see:\n\
+%s.\n"), REPORT_BUGS_TO) < 0)
+ return NULL;
+ if (asprintf (&cp, gettext ("\
+The owner is set to the current user, the group is set to `%s',\
+ and the access permission is set to `%o'.\n\n\
+%s"),
+ TTY_GROUP, S_IRUSR|S_IWUSR|S_IWGRP, tp) < 0)
+ {
+ free (tp);
+ return NULL;
+ }
+ return cp;
+ default:
+ break;
+ }
+ return (char *) text;
+}
+
+static int
+do_pt_chown (void)
+{
+ char *pty;
+ struct stat64 st;
+ struct group *p;
+ gid_t gid;
+
+ /* Check that PTY_FILENO is a valid master pseudo terminal. */
+ pty = ptsname (PTY_FILENO);
+ if (pty == NULL)
+ return errno == EBADF ? FAIL_EBADF : FAIL_EINVAL;
+
+ /* Check that the returned slave pseudo terminal is a
+ character device. */
+ if (stat64 (pty, &st) < 0 || !S_ISCHR (st.st_mode))
+ return FAIL_EINVAL;
+
+ /* Get the group ID of the special `tty' group. */
+ p = getgrnam (TTY_GROUP);
+ gid = p ? p->gr_gid : getgid ();
+
+ /* Set the owner to the real user ID, and the group to that special
+ group ID. */
+ if (chown (pty, getuid (), gid) < 0)
+ return FAIL_EACCES;
+
+ /* Set the permission mode to readable and writable by the owner,
+ and writable by the group. */
+ if ((st.st_mode & ACCESSPERMS) != (S_IRUSR|S_IWUSR|S_IWGRP)
+ && chmod (pty, S_IRUSR|S_IWUSR|S_IWGRP) < 0)
+ return FAIL_EACCES;
+
+ return 0;
+}
+
+
+int
+main (int argc, char *argv[])
+{
+ uid_t euid = geteuid ();
+ uid_t uid = getuid ();
+ int remaining;
+ sigset_t signalset;
+
+ /* Clear any signal mask from the parent process. */
+ sigemptyset (&signalset);
+ sigprocmask (SIG_SETMASK, &signalset, NULL);
+
+ if (argc == 1 && euid == 0)
+ {
+#ifdef HAVE_LIBCAP
+ /* Drop privileges. */
+ if (uid != euid)
+ {
+ static const cap_value_t cap_list[] =
+ { CAP_CHOWN, CAP_FOWNER };
+# define ncap_list (sizeof (cap_list) / sizeof (cap_list[0]))
+ cap_t caps = cap_init ();
+ if (caps == NULL)
+ return FAIL_ENOMEM;
+
+ /* There is no reason why these should not work. */
+ cap_set_flag (caps, CAP_PERMITTED, ncap_list, cap_list, CAP_SET);
+ cap_set_flag (caps, CAP_EFFECTIVE, ncap_list, cap_list, CAP_SET);
+
+ int res = cap_set_proc (caps);
+
+ cap_free (caps);
+
+ if (__glibc_unlikely (res != 0))
+ return FAIL_EXEC;
+ }
+#endif
+
+ /* Normal invocation of this program is with no arguments and
+ with privileges. */
+ return do_pt_chown ();
+ }
+
+ /* We aren't going to be using privileges, so drop them right now. */
+ setuid (uid);
+
+ /* Set locale via LC_ALL. */
+ setlocale (LC_ALL, "");
+
+ /* Set the text message domain. */
+ textdomain (PACKAGE);
+
+ /* parse and process arguments. */
+ argp_parse (&argp, argc, argv, 0, &remaining, NULL);
+
+ if (remaining < argc)
+ {
+ /* We should not be called with any non-option parameters. */
+ error (0, 0, gettext ("too many arguments"));
+ argp_help (&argp, stdout, ARGP_HELP_SEE | ARGP_HELP_EXIT_ERR,
+ program_invocation_short_name);
+ return EXIT_FAILURE;
+ }
+
+ /* Check if we are properly installed. */
+ if (euid != 0)
+ error (FAIL_EXEC, 0, gettext ("needs to be installed setuid `root'"));
+
+ return EXIT_SUCCESS;
+}
diff --git a/REORG.TODO/login/programs/utmpdump.c b/REORG.TODO/login/programs/utmpdump.c
new file mode 100644
index 0000000000..35bf0f9c27
--- /dev/null
+++ b/REORG.TODO/login/programs/utmpdump.c
@@ -0,0 +1,99 @@
+/* utmpdump - dump utmp-like files.
+ Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <unistd.h>
+#include <utmp.h>
+
+static void
+print_entry (struct utmp *up)
+{
+ /* Mixed 32-/64-bit systems may have timeval structs of different sixe
+ but need struct utmp to be the same size. So in 64-bit up->ut_tv may
+ not be a timeval but a struct of __int32_t's. This would cause a compile
+ time warning and a formating error when 32-bit int is passed where
+ a 64-bit long is expected. So copy up->up_tv to a temporary timeval.
+ This is 32-/64-bit agnostic and expands the timeval fields to the
+ expected size as needed. */
+ struct timeval temp_tv;
+ temp_tv.tv_sec = up->ut_tv.tv_sec;
+ temp_tv.tv_usec = up->ut_tv.tv_usec;
+
+ (printf) (
+ /* The format string. */
+#if _HAVE_UT_TYPE
+ "[%d] "
+#endif
+#if _HAVE_UT_PID
+ "[%05d] "
+#endif
+#if _HAVE_UT_ID
+ "[%-4.4s] "
+#endif
+ "[%-8.8s] [%-12.12s]"
+#if _HAVE_UT_HOST
+ " [%-16.16s]"
+#endif
+ " [%-15.15s]"
+#if _HAVE_UT_TV
+ " [%ld]"
+#endif
+ "\n"
+ /* The arguments. */
+#if _HAVE_UT_TYPE
+ , up->ut_type
+#endif
+#if _HAVE_UT_PID
+ , up->ut_pid
+#endif
+#if _HAVE_UT_ID
+ , up->ut_id
+#endif
+ , up->ut_user, up->ut_line
+#if _HAVE_UT_HOST
+ , up->ut_host
+#endif
+#if _HAVE_UT_TV
+ , 4 + ctime (&temp_tv.tv_sec)
+ , (long int) temp_tv.tv_usec
+#else
+ , 4 + ctime (&up->ut_time)
+#endif
+ );
+}
+
+int
+main (int argc, char *argv[])
+{
+ struct utmp *up;
+
+ if (argc > 1)
+ utmpname (argv[1]);
+
+ setutent ();
+
+ while ((up = getutent ()))
+ print_entry (up);
+
+ endutent ();
+
+ return EXIT_SUCCESS;
+}
diff --git a/REORG.TODO/login/ptsname.c b/REORG.TODO/login/ptsname.c
new file mode 100644
index 0000000000..c9da2dc6ad
--- /dev/null
+++ b/REORG.TODO/login/ptsname.c
@@ -0,0 +1,44 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+/* Given the file descriptor of a master pty, return the pathname
+ of the associated slave. */
+
+char *
+ptsname (int fd __attribute__ ((unused)))
+{
+ __set_errno (ENOSYS);
+ return NULL;
+}
+
+int
+__ptsname_r (int fd __attribute__ ((unused)),
+ char *buf __attribute__ ((unused)),
+ size_t len __attribute__ ((unused)))
+{
+ __set_errno (ENOSYS);
+ return ENOSYS;
+}
+weak_alias (__ptsname_r, ptsname_r)
+
+stub_warning(ptsname)
+stub_warning(ptsname_r)
diff --git a/REORG.TODO/login/ptsname_r_chk.c b/REORG.TODO/login/ptsname_r_chk.c
new file mode 100644
index 0000000000..cfabdc941f
--- /dev/null
+++ b/REORG.TODO/login/ptsname_r_chk.c
@@ -0,0 +1,28 @@
+/* Copyright (C) 2005-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+
+
+int
+__ptsname_r_chk (int fd, char *buf, size_t buflen, size_t nreal)
+{
+ if (buflen > nreal)
+ __chk_fail ();
+
+ return __ptsname_r (fd, buf, buflen);
+}
diff --git a/REORG.TODO/login/pty.h b/REORG.TODO/login/pty.h
new file mode 100644
index 0000000000..f4327508aa
--- /dev/null
+++ b/REORG.TODO/login/pty.h
@@ -0,0 +1,48 @@
+/* Functions for pseudo TTY handling.
+ Copyright (C) 1996-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _PTY_H
+#define _PTY_H 1
+
+#include <features.h>
+
+struct termios;
+struct winsize;
+
+#include <termios.h>
+#include <sys/ioctl.h>
+
+
+__BEGIN_DECLS
+
+/* Create pseudo tty master slave pair with NAME and set terminal
+ attributes according to TERMP and WINP and return handles for both
+ ends in AMASTER and ASLAVE. */
+extern int openpty (int *__amaster, int *__aslave, char *__name,
+ const struct termios *__termp,
+ const struct winsize *__winp) __THROW;
+
+/* Create child process and establish the slave pseudo terminal as the
+ child's controlling terminal. */
+extern int forkpty (int *__amaster, char *__name,
+ const struct termios *__termp,
+ const struct winsize *__winp) __THROW;
+
+__END_DECLS
+
+#endif /* pty.h */
diff --git a/REORG.TODO/login/pututxline.c b/REORG.TODO/login/pututxline.c
new file mode 100644
index 0000000000..08ab1bf4fa
--- /dev/null
+++ b/REORG.TODO/login/pututxline.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+struct utmpx *
+pututxline (const struct utmpx *utmpx)
+{
+ return (struct utmpx *) __pututline ((const struct utmp *) utmpx);
+}
diff --git a/REORG.TODO/login/setlogin.c b/REORG.TODO/login/setlogin.c
new file mode 100644
index 0000000000..4601d99591
--- /dev/null
+++ b/REORG.TODO/login/setlogin.c
@@ -0,0 +1,29 @@
+/* Copyright (C) 1991-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <unistd.h>
+
+/* Set the login name returned by `getlogin'. */
+int
+setlogin (const char *name)
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+stub_warning (setlogin)
diff --git a/REORG.TODO/login/setutxent.c b/REORG.TODO/login/setutxent.c
new file mode 100644
index 0000000000..6c742f76a6
--- /dev/null
+++ b/REORG.TODO/login/setutxent.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+void
+setutxent (void)
+{
+ return __setutent ();
+}
diff --git a/REORG.TODO/login/tst-getlogin.c b/REORG.TODO/login/tst-getlogin.c
new file mode 100644
index 0000000000..5675fef0e0
--- /dev/null
+++ b/REORG.TODO/login/tst-getlogin.c
@@ -0,0 +1,60 @@
+/* Copyright (C) 1999-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <unistd.h>
+#include <stdio.h>
+#include <string.h>
+
+static int
+do_test (void)
+{
+ char *login;
+ int errors = 0;
+
+ login = getlogin ();
+ if (login == NULL)
+ puts ("getlogin returned NULL, no further tests");
+ else
+ {
+ char name[1024];
+ int ret;
+
+ printf ("getlogin returned: `%s'\n", login);
+
+ ret = getlogin_r (name, sizeof (name));
+ if (ret == 0)
+ {
+ printf ("getlogin_r returned: `%s'\n", name);
+ if (strcmp (name, login) != 0)
+ {
+ puts ("Error: getlogin and getlogin_r returned different names");
+ ++errors;
+ }
+ }
+ else
+ {
+ printf ("Error: getlogin_r returned: %d (%s)\n",
+ ret, strerror (ret));
+ ++errors;
+ }
+ }
+
+ return errors != 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/REORG.TODO/login/tst-grantpt.c b/REORG.TODO/login/tst-grantpt.c
new file mode 100644
index 0000000000..65bb344909
--- /dev/null
+++ b/REORG.TODO/login/tst-grantpt.c
@@ -0,0 +1,81 @@
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+
+static int
+test_ebadf (void)
+{
+ int fd, ret, err;
+
+ fd = posix_openpt (O_RDWR);
+ if (fd == -1)
+ {
+ printf ("posix_openpt(O_RDWR) failed\nerrno %d (%s)\n",
+ errno, strerror (errno));
+ /* We don't fail because of this; maybe the system does not have
+ SUS pseudo terminals. */
+ return 0;
+ }
+ unlockpt (fd);
+ close (fd);
+
+ ret = grantpt (fd);
+ err = errno;
+ if (ret != -1 || err != EBADF)
+ {
+ printf ("grantpt(): expected: return = %d, errno = %d\n", -1, EBADF);
+ printf (" got: return = %d, errno = %d\n", ret, err);
+ return 1;
+ }
+ return 0;
+}
+
+static int
+test_einval (void)
+{
+ int fd, ret, err;
+ const char file[] = "./grantpt-einval";
+
+ fd = open (file, O_RDWR | O_CREAT, 0600);
+ if (fd == -1)
+ {
+ printf ("open(\"%s\", O_RDWR) failed\nerrno %d (%s)\n",
+ file, errno, strerror (errno));
+ return 0;
+ }
+ unlink (file);
+
+ ret = grantpt (fd);
+ err = errno;
+ if (ret != -1 || err != EINVAL)
+ {
+ printf ("grantpt(): expected: return = %d, errno = %d\n", -1, EINVAL);
+ printf (" got: return = %d, errno = %d\n", ret, err);
+ ret = 1;
+ }
+ else
+ ret = 0;
+
+ close (fd);
+
+ return ret;
+}
+
+static int
+do_test (void)
+{
+ int result = 0;
+
+ result += test_ebadf ();
+ result += test_einval ();
+
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/REORG.TODO/login/tst-ptsname.c b/REORG.TODO/login/tst-ptsname.c
new file mode 100644
index 0000000000..96f0449788
--- /dev/null
+++ b/REORG.TODO/login/tst-ptsname.c
@@ -0,0 +1,107 @@
+/* Test for ptsname/ptsname_r.
+ Copyright (C) 2014-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Aurelien Jarno <aurelien@aurel32.net>, 2014.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#define DEV_TTY "/dev/tty"
+#define PTSNAME_EINVAL "./ptsname-einval"
+
+static int
+do_single_test (int fd, char *buf, size_t buflen, int expected_err)
+{
+
+ int ret = ptsname_r (fd, buf, buflen);
+ int err = errno;
+
+ if (expected_err == 0)
+ {
+ if (ret != 0)
+ {
+ printf ("ptsname_r: expected: return = 0\n");
+ printf (" got: return = %d, errno = %d (%s)\n",
+ ret, err, strerror (err));
+ return 1;
+ }
+ }
+ else
+ {
+ if (ret == 0 || errno != expected_err)
+ {
+ printf ("ptsname_r: expected: return = %d, errno = %d (%s)\n",
+ -1, expected_err, strerror (expected_err));
+ printf (" got: return = %d, errno = %d (%s)\n",
+ ret, err, strerror (err));
+ return 1;
+ }
+ }
+
+ return 0;
+}
+
+static int
+do_test (void)
+{
+ char buf[512];
+ int result = 0;
+
+ /* Tests with a real PTS master. */
+ int fd = posix_openpt (O_RDWR);
+ if (fd != -1)
+ {
+ result |= do_single_test (fd, buf, sizeof (buf), 0);
+ result |= do_single_test (fd, buf, 1, ERANGE);
+ close (fd);
+ }
+ else
+ printf ("posix_openpt (O_RDWR) failed\nerrno %d (%s)\n",
+ errno, strerror (errno));
+
+ /* Test with a terminal device which is not a PTS master. */
+ fd = open (DEV_TTY, O_RDONLY);
+ if (fd != -1)
+ {
+ result |= do_single_test (fd, buf, sizeof (buf), ENOTTY);
+ close (fd);
+ }
+ else
+ printf ("open (\"%s\", O_RDWR) failed\nerrno %d (%s)\n",
+ DEV_TTY, errno, strerror (errno));
+
+ /* Test with a file. */
+ fd = open (PTSNAME_EINVAL, O_RDWR | O_CREAT, 0600);
+ if (fd != -1)
+ {
+ result |= do_single_test (fd, buf, sizeof (buf), ENOTTY);
+ close (fd);
+ unlink (PTSNAME_EINVAL);
+ }
+ else
+ printf ("open (\"%s\", O_RDWR | OCREAT) failed\nerrno %d (%s)\n",
+ PTSNAME_EINVAL, errno, strerror (errno));
+
+ return result;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/REORG.TODO/login/tst-utmp.c b/REORG.TODO/login/tst-utmp.c
new file mode 100644
index 0000000000..01771df740
--- /dev/null
+++ b/REORG.TODO/login/tst-utmp.c
@@ -0,0 +1,403 @@
+/* Tests for UTMP functions.
+ Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <errno.h>
+#include <error.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <time.h>
+
+#ifdef UTMPX
+# include <utmpx.h>
+# define utmp utmpx
+# define utmpname utmpxname
+# define setutent setutxent
+# define getutent getutxent
+# define endutent endutxent
+# define getutline getutxline
+# define getutid getutxid
+# define pututline pututxline
+#else
+# include <utmp.h>
+#endif
+
+
+#if defined UTMPX || _HAVE_UT_TYPE
+
+/* Prototype for our test function. */
+static int do_test (int argc, char *argv[]);
+
+/* We have a preparation function. */
+static void do_prepare (int argc, char *argv[]);
+#define PREPARE do_prepare
+
+/* This defines the `main' function and some more. */
+#include <test-skeleton.c>
+
+
+/* These are for the temporary file we generate. */
+char *name;
+int fd;
+
+static void
+do_prepare (int argc, char *argv[])
+{
+ size_t name_len;
+
+ name_len = strlen (test_dir);
+ name = xmalloc (name_len + sizeof ("/utmpXXXXXX"));
+ mempcpy (mempcpy (name, test_dir, name_len),
+ "/utmpXXXXXX", sizeof ("/utmpXXXXXX"));
+
+ /* Open our test file. */
+ fd = mkstemp (name);
+ if (fd == -1)
+ error (EXIT_FAILURE, errno, "cannot open test file `%s'", name);
+ add_temp_file (name);
+}
+
+struct utmp entry[] =
+{
+#if defined UTMPX || _HAVE_UT_TV
+#define UT(a) .ut_tv = { .tv_sec = (a)}
+#else
+#define UT(a) .ut_time = (a)
+#endif
+
+ { .ut_type = BOOT_TIME, .ut_pid = 1, UT(1000) },
+ { .ut_type = RUN_LVL, .ut_pid = 1, UT(2000) },
+ { .ut_type = INIT_PROCESS, .ut_pid = 5, .ut_id = "si", UT(3000) },
+ { .ut_type = LOGIN_PROCESS, .ut_pid = 23, .ut_line = "tty1", .ut_id = "1",
+ .ut_user = "LOGIN", UT(4000) },
+ { .ut_type = USER_PROCESS, .ut_pid = 24, .ut_line = "tty2", .ut_id = "2",
+ .ut_user = "albert", UT(8000) },
+ { .ut_type = USER_PROCESS, .ut_pid = 196, .ut_line = "ttyp0", .ut_id = "p0",
+ .ut_user = "niels", UT(10000) },
+ { .ut_type = DEAD_PROCESS, .ut_line = "ttyp1", .ut_id = "p1", UT(16000) },
+ { .ut_type = EMPTY },
+ { .ut_type = EMPTY }
+};
+int num_entries = sizeof entry / sizeof (struct utmp);
+
+time_t entry_time = 20000;
+pid_t entry_pid = 234;
+
+static int
+do_init (void)
+{
+ int n;
+
+ setutent ();
+
+ for (n = 0; n < num_entries; n++)
+ {
+ if (pututline (&entry[n]) == NULL)
+ {
+ error (0, errno, "cannot write UTMP entry");
+ return 1;
+ }
+ }
+
+ endutent ();
+
+ return 0;
+}
+
+
+static int
+do_check (void)
+{
+ struct utmp *ut;
+ int n;
+
+ setutent ();
+
+ n = 0;
+ while ((ut = getutent ()))
+ {
+ if (n < num_entries &&
+ memcmp (ut, &entry[n], sizeof (struct utmp)))
+ {
+ error (0, 0, "UTMP entry does not match");
+ return 1;
+ }
+
+ n++;
+ }
+
+ if (n != num_entries)
+ {
+ error (0, 0, "number of UTMP entries is incorrect");
+ return 1;
+ }
+
+ endutent ();
+
+ return 0;
+}
+
+static int
+simulate_login (const char *line, const char *user)
+{
+ int n;
+
+ for (n = 0; n < num_entries; n++)
+ {
+ if (strcmp (line, entry[n].ut_line) == 0 ||
+ entry[n].ut_type == DEAD_PROCESS)
+ {
+ if (entry[n].ut_pid == DEAD_PROCESS)
+ entry[n].ut_pid = (entry_pid += 27);
+ entry[n].ut_type = USER_PROCESS;
+ strncpy (entry[n].ut_user, user, sizeof (entry[n].ut_user));
+#if defined UTMPX || _HAVE_UT_TV - 0
+ entry[n].ut_tv.tv_sec = (entry_time += 1000);
+#else
+ entry[n].ut_time = (entry_time += 1000);
+#endif
+ setutent ();
+
+ if (pututline (&entry[n]) == NULL)
+ {
+ error (0, errno, "cannot write UTMP entry");
+ return 1;
+ }
+
+ endutent ();
+
+ return 0;
+ }
+ }
+
+ error (0, 0, "no entries available");
+ return 1;
+}
+
+static int
+simulate_logout (const char *line)
+{
+ int n;
+
+ for (n = 0; n < num_entries; n++)
+ {
+ if (strcmp (line, entry[n].ut_line) == 0)
+ {
+ entry[n].ut_type = DEAD_PROCESS;
+ strncpy (entry[n].ut_user, "", sizeof (entry[n].ut_user));
+#if defined UTMPX || _HAVE_UT_TV - 0
+ entry[n].ut_tv.tv_sec = (entry_time += 1000);
+#else
+ entry[n].ut_time = (entry_time += 1000);
+#endif
+ setutent ();
+
+ if (pututline (&entry[n]) == NULL)
+ {
+ error (0, errno, "cannot write UTMP entry");
+ return 1;
+ }
+
+ endutent ();
+
+ return 0;
+ }
+ }
+
+ error (0, 0, "no entry found for `%s'", line);
+ return 1;
+}
+
+static int
+check_login (const char *line)
+{
+ struct utmp *up;
+ struct utmp ut;
+ int n;
+
+ setutent ();
+
+ strcpy (ut.ut_line, line);
+ up = getutline (&ut);
+ if (up == NULL)
+ {
+ error (0, errno, "cannot get entry for line `%s'", line);
+ return 1;
+ }
+
+ endutent ();
+
+ for (n = 0; n < num_entries; n++)
+ {
+ if (strcmp (line, entry[n].ut_line) == 0)
+ {
+ if (memcmp (up, &entry[n], sizeof (struct utmp)))
+ {
+ error (0, 0, "UTMP entry does not match");
+ return 1;
+ }
+
+ return 0;
+ }
+ }
+
+ error (0, 0, "bogus entry for line `%s'", line);
+ return 1;
+}
+
+static int
+check_logout (const char *line)
+{
+ struct utmp ut;
+
+ setutent ();
+
+ strcpy (ut.ut_line, line);
+ if (getutline (&ut) != NULL)
+ {
+ error (0, 0, "bogus login entry for `%s'", line);
+ return 1;
+ }
+
+ endutent ();
+
+ return 0;
+}
+
+static int
+check_id (const char *id)
+{
+ struct utmp *up;
+ struct utmp ut;
+ int n;
+
+ setutent ();
+
+ ut.ut_type = USER_PROCESS;
+ strcpy (ut.ut_id, id);
+ up = getutid (&ut);
+ if (up == NULL)
+ {
+ error (0, errno, "cannot get entry for ID `%s'", id);
+ return 1;
+ }
+
+ endutent ();
+
+ for (n = 0; n < num_entries; n++)
+ {
+ if (strcmp (id, entry[n].ut_id) == 0)
+ {
+ if (memcmp (up, &entry[n], sizeof (struct utmp)))
+ {
+ error (0, 0, "UTMP entry does not match");
+ return 1;
+ }
+
+ return 0;
+ }
+ }
+
+ error (0, 0, "bogus entry for ID `%s'", id);
+ return 1;
+}
+
+static int
+check_type (int type)
+{
+ struct utmp *up;
+ struct utmp ut;
+ int n;
+
+ setutent ();
+
+ ut.ut_type = type;
+ up = getutid (&ut);
+ if (up == NULL)
+ {
+ error (0, errno, "cannot get entry for type `%d'", type);
+ return 1;
+ }
+
+ endutent ();
+
+ for (n = 0; n < num_entries; n++)
+ {
+ if (type == entry[n].ut_type)
+ {
+ if (memcmp (up, &entry[n], sizeof (struct utmp)))
+ {
+ error (0, 0, "UTMP entry does not match");
+ return 1;
+ }
+
+ return 0;
+ }
+ }
+
+ error (0, 0, "bogus entry for type `%d'", type);
+ return 1;
+}
+
+static int
+do_test (int argc, char *argv[])
+{
+ int result = 0;
+
+ utmpname (name);
+
+ result |= do_init ();
+ result |= do_check ();
+
+ result |= simulate_login ("tty1", "erwin");
+ result |= do_check ();
+
+ result |= simulate_login ("ttyp1", "paul");
+ result |= do_check ();
+
+ result |= simulate_logout ("tty2");
+ result |= do_check ();
+
+ result |= simulate_logout ("ttyp0");
+ result |= do_check ();
+
+ result |= simulate_login ("ttyp2", "richard");
+ result |= do_check ();
+
+ result |= check_login ("tty1");
+ result |= check_logout ("ttyp0");
+ result |= check_id ("p1");
+ result |= check_id ("2");
+ result |= check_id ("si");
+ result |= check_type (BOOT_TIME);
+ result |= check_type (RUN_LVL);
+
+ return result;
+}
+
+#else
+
+/* No field 'ut_type' in struct utmp. */
+int
+main (void)
+{
+ return 0;
+}
+
+#endif
diff --git a/REORG.TODO/login/tst-utmpx.c b/REORG.TODO/login/tst-utmpx.c
new file mode 100644
index 0000000000..edb5551d71
--- /dev/null
+++ b/REORG.TODO/login/tst-utmpx.c
@@ -0,0 +1,2 @@
+#define UTMPX
+#include "tst-utmp.c"
diff --git a/REORG.TODO/login/unlockpt.c b/REORG.TODO/login/unlockpt.c
new file mode 100644
index 0000000000..fd31855790
--- /dev/null
+++ b/REORG.TODO/login/unlockpt.c
@@ -0,0 +1,32 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Zack Weinberg <zack@rabi.phys.columbia.edu>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <stdlib.h>
+#include <errno.h>
+
+/* Given a fd on a master pseudoterminal, clear a kernel lock so that
+ the slave can be opened. This is to avoid a race between opening the
+ master and calling grantpt() to take possession of the slave. */
+int
+unlockpt (int fd __attribute__ ((unused)))
+{
+ __set_errno (ENOSYS);
+ return -1;
+}
+
+stub_warning (unlockpt)
diff --git a/REORG.TODO/login/updwtmp.c b/REORG.TODO/login/updwtmp.c
new file mode 100644
index 0000000000..7788614ed3
--- /dev/null
+++ b/REORG.TODO/login/updwtmp.c
@@ -0,0 +1,34 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+
+#include "utmp-private.h"
+
+#ifndef TRANSFORM_UTMP_FILE_NAME
+# define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name)
+#endif
+
+void
+__updwtmp (const char *wtmp_file, const struct utmp *utmp)
+{
+ const char *file_name = TRANSFORM_UTMP_FILE_NAME (wtmp_file);
+
+ (*__libc_utmp_file_functions.updwtmp) (file_name, utmp);
+}
+weak_alias (__updwtmp, updwtmp)
diff --git a/REORG.TODO/login/updwtmpx.c b/REORG.TODO/login/updwtmpx.c
new file mode 100644
index 0000000000..5877303401
--- /dev/null
+++ b/REORG.TODO/login/updwtmpx.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+void
+updwtmpx (const char *wtmpx_file, const struct utmpx *utmpx)
+{
+ __updwtmp (wtmpx_file, (const struct utmp *) utmpx);
+}
diff --git a/REORG.TODO/login/utmp-private.h b/REORG.TODO/login/utmp-private.h
new file mode 100644
index 0000000000..3c9dcb9803
--- /dev/null
+++ b/REORG.TODO/login/utmp-private.h
@@ -0,0 +1,53 @@
+/* Internal definitions and declarations for UTMP functions.
+ Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>
+ and Paul Janzen <pcj@primenet.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _UTMP_PRIVATE_H
+#define _UTMP_PRIVATE_H 1
+
+#include <utmp.h>
+#include <libc-lock.h>
+
+/* The structure describing the functions in a backend. */
+struct utfuncs
+{
+ int (*setutent) (void);
+ int (*getutent_r) (struct utmp *, struct utmp **);
+ int (*getutid_r) (const struct utmp *, struct utmp *, struct utmp **);
+ int (*getutline_r) (const struct utmp *, struct utmp *, struct utmp **);
+ struct utmp *(*pututline) (const struct utmp *);
+ void (*endutent) (void);
+ int (*updwtmp) (const char *, const struct utmp *);
+};
+
+/* The tables from the services. */
+extern const struct utfuncs __libc_utmp_file_functions attribute_hidden;
+extern const struct utfuncs __libc_utmp_unknown_functions attribute_hidden;
+
+/* Currently selected backend. */
+extern const struct utfuncs *__libc_utmp_jump_table attribute_hidden;
+
+/* Current file name. */
+extern const char *__libc_utmp_file_name attribute_hidden;
+
+/* Locks access to the global data. */
+__libc_lock_define (extern, __libc_utmp_lock attribute_hidden)
+
+
+#endif /* utmp-private.h */
diff --git a/REORG.TODO/login/utmp.h b/REORG.TODO/login/utmp.h
new file mode 100644
index 0000000000..c1a0448065
--- /dev/null
+++ b/REORG.TODO/login/utmp.h
@@ -0,0 +1,96 @@
+/* Copyright (C) 1993-2017 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#ifndef _UTMP_H
+#define _UTMP_H 1
+
+#include <features.h>
+
+#include <sys/types.h>
+
+
+__BEGIN_DECLS
+
+/* Get system dependent values and data structures. */
+#include <bits/utmp.h>
+
+/* Compatibility names for the strings of the canonical file names. */
+#define UTMP_FILE _PATH_UTMP
+#define UTMP_FILENAME _PATH_UTMP
+#define WTMP_FILE _PATH_WTMP
+#define WTMP_FILENAME _PATH_WTMP
+
+
+
+/* Make FD be the controlling terminal, stdin, stdout, and stderr;
+ then close FD. Returns 0 on success, nonzero on error. */
+extern int login_tty (int __fd) __THROW;
+
+
+/* Write the given entry into utmp and wtmp. */
+extern void login (const struct utmp *__entry) __THROW;
+
+/* Write the utmp entry to say the user on UT_LINE has logged out. */
+extern int logout (const char *__ut_line) __THROW;
+
+/* Append to wtmp an entry for the current time and the given info. */
+extern void logwtmp (const char *__ut_line, const char *__ut_name,
+ const char *__ut_host) __THROW;
+
+/* Append entry UTMP to the wtmp-like file WTMP_FILE. */
+extern void updwtmp (const char *__wtmp_file, const struct utmp *__utmp)
+ __THROW;
+
+/* Change name of the utmp file to be examined. */
+extern int utmpname (const char *__file) __THROW;
+
+/* Read next entry from a utmp-like file. */
+extern struct utmp *getutent (void) __THROW;
+
+/* Reset the input stream to the beginning of the file. */
+extern void setutent (void) __THROW;
+
+/* Close the current open file. */
+extern void endutent (void) __THROW;
+
+/* Search forward from the current point in the utmp file until the
+ next entry with a ut_type matching ID->ut_type. */
+extern struct utmp *getutid (const struct utmp *__id) __THROW;
+
+/* Search forward from the current point in the utmp file until the
+ next entry with a ut_line matching LINE->ut_line. */
+extern struct utmp *getutline (const struct utmp *__line) __THROW;
+
+/* Write out entry pointed to by UTMP_PTR into the utmp file. */
+extern struct utmp *pututline (const struct utmp *__utmp_ptr) __THROW;
+
+
+#ifdef __USE_MISC
+/* Reentrant versions of the file for handling utmp files. */
+extern int getutent_r (struct utmp *__buffer, struct utmp **__result) __THROW;
+
+extern int getutid_r (const struct utmp *__id, struct utmp *__buffer,
+ struct utmp **__result) __THROW;
+
+extern int getutline_r (const struct utmp *__line,
+ struct utmp *__buffer, struct utmp **__result) __THROW;
+
+#endif /* Use misc. */
+
+__END_DECLS
+
+#endif /* utmp.h */
diff --git a/REORG.TODO/login/utmp_file.c b/REORG.TODO/login/utmp_file.c
new file mode 100644
index 0000000000..240e0e3c10
--- /dev/null
+++ b/REORG.TODO/login/utmp_file.c
@@ -0,0 +1,524 @@
+/* Copyright (C) 1996-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Ulrich Drepper <drepper@cygnus.com>
+ and Paul Janzen <pcj@primenet.com>, 1996.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <assert.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmp.h>
+#include <not-cancel.h>
+#include <kernel-features.h>
+#include <sigsetops.h>
+
+#include "utmp-private.h"
+#include "utmp-equal.h"
+
+
+/* Descriptor for the file and position. */
+static int file_fd = -1;
+static bool file_writable;
+static off64_t file_offset;
+
+/* Cache for the last read entry. */
+static struct utmp last_entry;
+
+
+/* Locking timeout. */
+#ifndef TIMEOUT
+# define TIMEOUT 10
+#endif
+
+/* Do-nothing handler for locking timeout. */
+static void timeout_handler (int signum) {};
+
+/* LOCK_FILE(fd, type) failure_statement
+ attempts to get a lock on the utmp file referenced by FD. If it fails,
+ the failure_statement is executed, otherwise it is skipped.
+ LOCKING_FAILED()
+ jumps into the UNLOCK_FILE macro and ensures cleanup of LOCK_FILE.
+ UNLOCK_FILE(fd)
+ unlocks the utmp file referenced by FD and performs the cleanup of
+ LOCK_FILE.
+ */
+#define LOCK_FILE(fd, type) \
+{ \
+ struct flock fl; \
+ struct sigaction action, old_action; \
+ unsigned int old_timeout; \
+ \
+ /* Cancel any existing alarm. */ \
+ old_timeout = alarm (0); \
+ \
+ /* Establish signal handler. */ \
+ action.sa_handler = timeout_handler; \
+ __sigemptyset (&action.sa_mask); \
+ action.sa_flags = 0; \
+ __sigaction (SIGALRM, &action, &old_action); \
+ \
+ alarm (TIMEOUT); \
+ \
+ /* Try to get the lock. */ \
+ memset (&fl, '\0', sizeof (struct flock)); \
+ fl.l_type = (type); \
+ fl.l_whence = SEEK_SET; \
+ if (fcntl_not_cancel ((fd), F_SETLKW, &fl) < 0)
+
+#define LOCKING_FAILED() \
+ goto unalarm_return
+
+#define UNLOCK_FILE(fd) \
+ /* Unlock the file. */ \
+ fl.l_type = F_UNLCK; \
+ fcntl_not_cancel ((fd), F_SETLKW, &fl); \
+ \
+ unalarm_return: \
+ /* Reset the signal handler and alarm. We must reset the alarm \
+ before resetting the handler so our alarm does not generate a \
+ spurious SIGALRM seen by the user. However, we cannot just set \
+ the user's old alarm before restoring the handler, because then \
+ it's possible our handler could catch the user alarm's SIGARLM \
+ and then the user would never see the signal he expected. */ \
+ alarm (0); \
+ __sigaction (SIGALRM, &old_action, NULL); \
+ if (old_timeout != 0) \
+ alarm (old_timeout); \
+} while (0)
+
+
+/* Functions defined here. */
+static int setutent_file (void);
+static int getutent_r_file (struct utmp *buffer, struct utmp **result);
+static int getutid_r_file (const struct utmp *key, struct utmp *buffer,
+ struct utmp **result);
+static int getutline_r_file (const struct utmp *key, struct utmp *buffer,
+ struct utmp **result);
+static struct utmp *pututline_file (const struct utmp *data);
+static void endutent_file (void);
+static int updwtmp_file (const char *file, const struct utmp *utmp);
+
+/* Jump table for file functions. */
+const struct utfuncs __libc_utmp_file_functions =
+{
+ setutent_file,
+ getutent_r_file,
+ getutid_r_file,
+ getutline_r_file,
+ pututline_file,
+ endutent_file,
+ updwtmp_file
+};
+
+
+#ifndef TRANSFORM_UTMP_FILE_NAME
+# define TRANSFORM_UTMP_FILE_NAME(file_name) (file_name)
+#endif
+
+static int
+setutent_file (void)
+{
+ if (file_fd < 0)
+ {
+ const char *file_name;
+
+ file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name);
+
+ file_writable = false;
+ file_fd = open_not_cancel_2
+ (file_name, O_RDONLY | O_LARGEFILE | O_CLOEXEC);
+ if (file_fd == -1)
+ return 0;
+ }
+
+ __lseek64 (file_fd, 0, SEEK_SET);
+ file_offset = 0;
+
+ /* Make sure the entry won't match. */
+#if _HAVE_UT_TYPE - 0
+ last_entry.ut_type = -1;
+#else
+ last_entry.ut_line[0] = '\177';
+# if _HAVE_UT_ID - 0
+ last_entry.ut_id[0] = '\0';
+# endif
+#endif
+
+ return 1;
+}
+
+
+static int
+getutent_r_file (struct utmp *buffer, struct utmp **result)
+{
+ ssize_t nbytes;
+
+ assert (file_fd >= 0);
+
+ if (file_offset == -1l)
+ {
+ /* Not available. */
+ *result = NULL;
+ return -1;
+ }
+
+ LOCK_FILE (file_fd, F_RDLCK)
+ {
+ nbytes = 0;
+ LOCKING_FAILED ();
+ }
+
+ /* Read the next entry. */
+ nbytes = read_not_cancel (file_fd, &last_entry, sizeof (struct utmp));
+
+ UNLOCK_FILE (file_fd);
+
+ if (nbytes != sizeof (struct utmp))
+ {
+ if (nbytes != 0)
+ file_offset = -1l;
+ *result = NULL;
+ return -1;
+ }
+
+ /* Update position pointer. */
+ file_offset += sizeof (struct utmp);
+
+ memcpy (buffer, &last_entry, sizeof (struct utmp));
+ *result = buffer;
+
+ return 0;
+}
+
+
+static int
+internal_getut_r (const struct utmp *id, struct utmp *buffer,
+ bool *lock_failed)
+{
+ int result = -1;
+
+ LOCK_FILE (file_fd, F_RDLCK)
+ {
+ *lock_failed = true;
+ LOCKING_FAILED ();
+ }
+
+#if _HAVE_UT_TYPE - 0
+ if (id->ut_type == RUN_LVL || id->ut_type == BOOT_TIME
+ || id->ut_type == OLD_TIME || id->ut_type == NEW_TIME)
+ {
+ /* Search for next entry with type RUN_LVL, BOOT_TIME,
+ OLD_TIME, or NEW_TIME. */
+
+ while (1)
+ {
+ /* Read the next entry. */
+ if (read_not_cancel (file_fd, buffer, sizeof (struct utmp))
+ != sizeof (struct utmp))
+ {
+ __set_errno (ESRCH);
+ file_offset = -1l;
+ goto unlock_return;
+ }
+ file_offset += sizeof (struct utmp);
+
+ if (id->ut_type == buffer->ut_type)
+ break;
+ }
+ }
+ else
+#endif /* _HAVE_UT_TYPE */
+ {
+ /* Search for the next entry with the specified ID and with type
+ INIT_PROCESS, LOGIN_PROCESS, USER_PROCESS, or DEAD_PROCESS. */
+
+ while (1)
+ {
+ /* Read the next entry. */
+ if (read_not_cancel (file_fd, buffer, sizeof (struct utmp))
+ != sizeof (struct utmp))
+ {
+ __set_errno (ESRCH);
+ file_offset = -1l;
+ goto unlock_return;
+ }
+ file_offset += sizeof (struct utmp);
+
+ if (__utmp_equal (buffer, id))
+ break;
+ }
+ }
+
+ result = 0;
+
+unlock_return:
+ UNLOCK_FILE (file_fd);
+
+ return result;
+}
+
+
+/* For implementing this function we don't use the getutent_r function
+ because we can avoid the reposition on every new entry this way. */
+static int
+getutid_r_file (const struct utmp *id, struct utmp *buffer,
+ struct utmp **result)
+{
+ assert (file_fd >= 0);
+
+ if (file_offset == -1l)
+ {
+ *result = NULL;
+ return -1;
+ }
+
+ /* We don't have to distinguish whether we can lock the file or
+ whether there is no entry. */
+ bool lock_failed = false;
+ if (internal_getut_r (id, &last_entry, &lock_failed) < 0)
+ {
+ *result = NULL;
+ return -1;
+ }
+
+ memcpy (buffer, &last_entry, sizeof (struct utmp));
+ *result = buffer;
+
+ return 0;
+}
+
+
+/* For implementing this function we don't use the getutent_r function
+ because we can avoid the reposition on every new entry this way. */
+static int
+getutline_r_file (const struct utmp *line, struct utmp *buffer,
+ struct utmp **result)
+{
+ assert (file_fd >= 0);
+
+ if (file_offset == -1l)
+ {
+ *result = NULL;
+ return -1;
+ }
+
+ LOCK_FILE (file_fd, F_RDLCK)
+ {
+ *result = NULL;
+ LOCKING_FAILED ();
+ }
+
+ while (1)
+ {
+ /* Read the next entry. */
+ if (read_not_cancel (file_fd, &last_entry, sizeof (struct utmp))
+ != sizeof (struct utmp))
+ {
+ __set_errno (ESRCH);
+ file_offset = -1l;
+ *result = NULL;
+ goto unlock_return;
+ }
+ file_offset += sizeof (struct utmp);
+
+ /* Stop if we found a user or login entry. */
+ if (
+#if _HAVE_UT_TYPE - 0
+ (last_entry.ut_type == USER_PROCESS
+ || last_entry.ut_type == LOGIN_PROCESS)
+ &&
+#endif
+ !strncmp (line->ut_line, last_entry.ut_line, sizeof line->ut_line))
+ break;
+ }
+
+ memcpy (buffer, &last_entry, sizeof (struct utmp));
+ *result = buffer;
+
+unlock_return:
+ UNLOCK_FILE (file_fd);
+
+ return ((*result == NULL) ? -1 : 0);
+}
+
+
+static struct utmp *
+pututline_file (const struct utmp *data)
+{
+ struct utmp buffer;
+ struct utmp *pbuf;
+ int found;
+
+ assert (file_fd >= 0);
+
+ if (! file_writable)
+ {
+ /* We must make the file descriptor writable before going on. */
+ const char *file_name = TRANSFORM_UTMP_FILE_NAME (__libc_utmp_file_name);
+
+ int new_fd = open_not_cancel_2
+ (file_name, O_RDWR | O_LARGEFILE | O_CLOEXEC);
+ if (new_fd == -1)
+ return NULL;
+
+ if (__lseek64 (new_fd, __lseek64 (file_fd, 0, SEEK_CUR), SEEK_SET) == -1
+ || __dup2 (new_fd, file_fd) < 0)
+ {
+ close_not_cancel_no_status (new_fd);
+ return NULL;
+ }
+ close_not_cancel_no_status (new_fd);
+ file_writable = true;
+ }
+
+ /* Find the correct place to insert the data. */
+ if (file_offset > 0
+ && (
+#if _HAVE_UT_TYPE - 0
+ (last_entry.ut_type == data->ut_type
+ && (last_entry.ut_type == RUN_LVL
+ || last_entry.ut_type == BOOT_TIME
+ || last_entry.ut_type == OLD_TIME
+ || last_entry.ut_type == NEW_TIME))
+ ||
+#endif
+ __utmp_equal (&last_entry, data)))
+ found = 1;
+ else
+ {
+ bool lock_failed = false;
+ found = internal_getut_r (data, &buffer, &lock_failed);
+
+ if (__builtin_expect (lock_failed, false))
+ {
+ __set_errno (EAGAIN);
+ return NULL;
+ }
+ }
+
+ LOCK_FILE (file_fd, F_WRLCK)
+ {
+ pbuf = NULL;
+ LOCKING_FAILED ();
+ }
+
+ if (found < 0)
+ {
+ /* We append the next entry. */
+ file_offset = __lseek64 (file_fd, 0, SEEK_END);
+ if (file_offset % sizeof (struct utmp) != 0)
+ {
+ file_offset -= file_offset % sizeof (struct utmp);
+ __ftruncate64 (file_fd, file_offset);
+
+ if (__lseek64 (file_fd, 0, SEEK_END) < 0)
+ {
+ pbuf = NULL;
+ goto unlock_return;
+ }
+ }
+ }
+ else
+ {
+ /* We replace the just read entry. */
+ file_offset -= sizeof (struct utmp);
+ __lseek64 (file_fd, file_offset, SEEK_SET);
+ }
+
+ /* Write the new data. */
+ if (write_not_cancel (file_fd, data, sizeof (struct utmp))
+ != sizeof (struct utmp))
+ {
+ /* If we appended a new record this is only partially written.
+ Remove it. */
+ if (found < 0)
+ (void) __ftruncate64 (file_fd, file_offset);
+ pbuf = NULL;
+ }
+ else
+ {
+ file_offset += sizeof (struct utmp);
+ pbuf = (struct utmp *) data;
+ }
+
+ unlock_return:
+ UNLOCK_FILE (file_fd);
+
+ return pbuf;
+}
+
+
+static void
+endutent_file (void)
+{
+ assert (file_fd >= 0);
+
+ close_not_cancel_no_status (file_fd);
+ file_fd = -1;
+}
+
+
+static int
+updwtmp_file (const char *file, const struct utmp *utmp)
+{
+ int result = -1;
+ off64_t offset;
+ int fd;
+
+ /* Open WTMP file. */
+ fd = open_not_cancel_2 (file, O_WRONLY | O_LARGEFILE);
+ if (fd < 0)
+ return -1;
+
+ LOCK_FILE (fd, F_WRLCK)
+ LOCKING_FAILED ();
+
+ /* Remember original size of log file. */
+ offset = __lseek64 (fd, 0, SEEK_END);
+ if (offset % sizeof (struct utmp) != 0)
+ {
+ offset -= offset % sizeof (struct utmp);
+ __ftruncate64 (fd, offset);
+
+ if (__lseek64 (fd, 0, SEEK_END) < 0)
+ goto unlock_return;
+ }
+
+ /* Write the entry. If we can't write all the bytes, reset the file
+ size back to the original size. That way, no partial entries
+ will remain. */
+ if (write_not_cancel (fd, utmp, sizeof (struct utmp))
+ != sizeof (struct utmp))
+ {
+ __ftruncate64 (fd, offset);
+ goto unlock_return;
+ }
+
+ result = 0;
+
+unlock_return:
+ UNLOCK_FILE (fd);
+
+ /* Close WTMP file. */
+ close_not_cancel_no_status (fd);
+
+ return result;
+}
diff --git a/REORG.TODO/login/utmpname.c b/REORG.TODO/login/utmpname.c
new file mode 100644
index 0000000000..74a4caf71b
--- /dev/null
+++ b/REORG.TODO/login/utmpname.c
@@ -0,0 +1,76 @@
+/* Copyright (C) 1997-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1997.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <libc-lock.h>
+#include <stdlib.h>
+#include <string.h>
+#include <utmp.h>
+
+#include "utmp-private.h"
+
+
+/* This is the default name. */
+static const char default_file_name[] = _PATH_UTMP;
+
+/* Current file name. */
+const char *__libc_utmp_file_name = (const char *) default_file_name;
+
+/* We have to use the lock in getutent_r.c. */
+__libc_lock_define (extern, __libc_utmp_lock attribute_hidden)
+
+
+int
+__utmpname (const char *file)
+{
+ int result = -1;
+
+ __libc_lock_lock (__libc_utmp_lock);
+
+ /* Close the old file. */
+ (*__libc_utmp_jump_table->endutent) ();
+ __libc_utmp_jump_table = &__libc_utmp_unknown_functions;
+
+ if (strcmp (file, __libc_utmp_file_name) != 0)
+ {
+ if (strcmp (file, default_file_name) == 0)
+ {
+ free ((char *) __libc_utmp_file_name);
+
+ __libc_utmp_file_name = default_file_name;
+ }
+ else
+ {
+ char *file_name = __strdup (file);
+ if (file_name == NULL)
+ /* Out of memory. */
+ goto done;
+
+ if (__libc_utmp_file_name != default_file_name)
+ free ((char *) __libc_utmp_file_name);
+
+ __libc_utmp_file_name = file_name;
+ }
+ }
+
+ result = 0;
+
+done:
+ __libc_lock_unlock (__libc_utmp_lock);
+ return result;
+}
+weak_alias (__utmpname, utmpname)
diff --git a/REORG.TODO/login/utmpxname.c b/REORG.TODO/login/utmpxname.c
new file mode 100644
index 0000000000..90497b91bb
--- /dev/null
+++ b/REORG.TODO/login/utmpxname.c
@@ -0,0 +1,26 @@
+/* Copyright (C) 1998-2017 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by Mark Kettenis <kettenis@phys.uva.nl>, 1998.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, see
+ <http://www.gnu.org/licenses/>. */
+
+#include <utmp.h>
+#include <utmpx.h>
+
+int
+utmpxname (const char *file)
+{
+ return __utmpname (file);
+}