about summary refs log tree commit diff
path: root/login
diff options
context:
space:
mode:
authorUlrich Drepper <drepper@redhat.com>1997-06-19 19:11:22 +0000
committerUlrich Drepper <drepper@redhat.com>1997-06-19 19:11:22 +0000
commitd705269e75ff9846000abea981774b381b076482 (patch)
tree7bd717a8489ad113cb0d10b7628a88d6a55cb836 /login
parente7f1f046f51d95d5d05ada3abd3f2e88219118e9 (diff)
downloadglibc-d705269e75ff9846000abea981774b381b076482.tar.gz
glibc-d705269e75ff9846000abea981774b381b076482.tar.xz
glibc-d705269e75ff9846000abea981774b381b076482.zip
1997-06-19 19:38  Ulrich Drepper  <drepper@cygnus.com>

	* features.h: Define __STDC_IEC_559__ and _STDC_IEC_559_COMPLEX__.

	* elf/dl-minimal.c (__dcgettext): Remove assertion.

	* inet/rcmd.c: Correct a few typos.  Reported by Eric Troan.

	* manual/Makefile (distribute): Add dir.
	* manual/dir: New file.

	* math/Makefile (libm-support): Rename s_rinttol, s_rinttoll,
	s_roundtol, and s_roundtoll to s_lrint, s_llrint, s_lround,
	and s_llround respectively.
	(libm-calls): Add e_gamma_r.
	* math/libm-test.c (check_int_exc): New function.
	(signbit_test): Remove test for sign of NaN.
	(gamma_test): Clear exception after test of existence.
	Correct tests and and epsilons.
	(lgamma_test): Likewise.
	(ilogb_test): Correct all tests.
	(scalb_test): Rewrite.
	(rinttol_test): Rename to lrint_test and correct tests.
	(rinttoll_test): Likewise.
	(roundtol_test): Likewise.
	(roundtoll_test): Likewise.
	(main): Call lrint/lround functions instead of rinttol/roundtol.
	* math/math.h: Change prototypes for rinttol/roundtol.
	* math/mathcalls.h: Rearrange prototypes according to ISO C9X draft.
	* sysdeps/generic/mathbits.h: Define FP_ILOGB0 and FP_ILOGBNAN.
	* sysdeps/i386/mathbits.h: Likewise.
	* sysdeps/libm-i387/e_scalb.S: Handle special cases correctly.
	* sysdeps/libm-i387/e_scalbf.S: Likewise.
	* sysdeps/libm-i387/e_scalbl.S: Likewise.
	* sysdeps/libm-i387/s_asinh.S: Handle -inf correctly.
	* sysdeps/libm-i387/s_asinhf.S: Likewise.
	* sysdeps/libm-i387/s_asinhl.S: Likewise.
	* sysdeps/libm-i387/s_ilogb.S: Optimize.
	* sysdeps/libm-i387/s_ilogbf.S: Likewise.
	* sysdeps/libm-i387/s_ilogbl.S: Likewise.
	* sysdeps/libm-i387/s_rinttol.S: Rename to...
	* sysdeps/libm-i387/s_lrint.S: ...this.
	* sysdeps/libm-i387/s_rinttoll.S: Rename to...
	* sysdeps/libm-i387/s_llrint.S: ...this.
	* sysdeps/libm-i387/s_remquo.S: Correctly set sign of remainder.
	* sysdeps/libm-i387/s_remquof.S: Likewise.
	* sysdeps/libm-i387/s_remquol.S: Likewise.
	* sysdeps/libm-i387/e_gamma_r.c: New file.  Implementation of gamma
	function according to ISO C.
	* sysdeps/libm-i387/e_gammaf_r.c: New file.
	* sysdeps/libm-i387/e_gammal_r.c: New file.
	* sysdeps/libm-i387/e_lgamma_r.c: Don't let optimize compile the
	generation of exceptions away.
	* sysdeps/libm-i387/e_lgammaf_r.c: Likewise.
	* sysdeps/libm-i387/k_standard.c: Correct return value for infinity
	points of gamma function when not SVID mode.
	* sysdeps/libm-i387/s_rinttoll.c: Renamed to...
	* sysdeps/libm-i387/s_llrint.c: ...this.
	* sysdeps/libm-i387/s_rinttol.c: Renamed to...
	* sysdeps/libm-i387/s_lrint.c: ...this.
	* sysdeps/libm-i387/s_roundtoll.c: Renamed to...
	* sysdeps/libm-i387/s_llround.c: ...this.
	* sysdeps/libm-i387/s_roundtol.c: Renamed to...
	* sysdeps/libm-i387/s_lround.c: ..this.
	* sysdeps/libm-i387/s_scalbn.c: Change second parameter according to
	ISO C.
	* sysdeps/libm-i387/s_scalbnf.c: Likewise.
	* sysdeps/libm-i387/s_scalbnl.c: Likewise.
	* sysdeps/libm-i387/w_gamma.c: Call __ieee754_gamma_r if library
	mode is not _SVID_.
	* sysdeps/libm-i387/w_gammaf.c: Likewise.
	* sysdeps/libm-i387/w_gammal.c: Likewise.
	* sysdeps/m68k/fpu/__math.h: Rename __rinttol to __lrint and
	rinttol to lrint.
	* sysdeps/m68k/fpu/s_rinttol.c: Renamed to...
	* sysdeps/m68k/fpu/s_lrint.c: ...this.
	* sysdeps/m68k/fpu/s_rinttoll.c: Renamed to...
	* sysdeps/m68k/fpu/s_llrint.c: ...this.

	* md5-crypt/Makefile: Link md5test program with md5.o.

	* stdio-common/temptest.c: Don't use __stdio_gen_tempname which
	is not exported by the libc.so.

	* stdio-common/vfscanf.c: Correct scanning of strings after last
	change.

	* sysdeps/unix/sysv/linux/i386/sysdep.S: Use .comm to define errno.

1997-06-19 07:37  H.J. Lu  <hjl@gnu.ai.mit.edu>

	* time/tzfile.c (__tzfile_read): Store getc () return in int.

1997-06-13  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp/argp-parse.c (argp_version_parser): Include `(PROGRAM ERROR)' in
	the no-version error text to indicate that something's fucked.
	[!_] (N_): New macro.
	(argp_default_options, argp_version_options): Wrap doc strings in N_().

1997-06-12  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp/argp-parse.c (parser_parse_opt): Detect and report unhandled
	options here.
	(parser_parse_arg): Handle ARGP_KEY_ARGS here.
	Adjust NEXT pointer back if we fail to parse anything.
	(parser_parse_next): Simplify arg code.  Leave state NEXT frobbing
	to parser_parse_arg.

1997-06-11  Miles Bader  <miles@gnu.ai.mit.edu>

	* argp/argp.h (ARGP_KEY_ARGS, ARGP_KEY_FINI): New macros.
	* argp/argp-parse.c (parser_finalize): Do another pass over the
	parsers with ARGP_KEY_FINI.

1997-06-18  Miles Bader  <miles@gnu.ai.mit.edu>

	* string/Makefile (routines): Add argz-replace.

1997-06-16 00:16  Miles Bader  <miles@gnu.ai.mit.edu>

	* manual/string.texi (Argz Functions): Document argz_replace.

1997-06-12  Miles Bader  <miles@gnu.ai.mit.edu>

	* string/argz.h (__argz_replace, argz_replace): New declarations.
	* string/argz-replace.c: New file.

1997-06-11  Miles Bader  <miles@gnu.ai.mit.edu>

	* manual/argp.texi (Argp Special Keys): Document ARGP_KEY_ARGS.

1997-06-16 23:08  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* Makeconfig (libc-map): Remove definition.
	* Makerules (libc-map): Define it here, using the full name.
	(load-map-file): Remove case for empty $(..).
	($(common-objpfx)libc.so): Revert last change.

1997-06-17 22:18  Mark Kettenis  <kettenis@phys.uva.nl>

	* login/programs/utmpd.c (main): Improve signal handling.

	* login/programs/request.c (do_setutent, do_updwtmp):
	Allow arbitrary length filenames.
	* login/programs/utmpd.h (setutent_request, updwtmp_request):
	Get rid of fixed length file field.
	* login/utmp_daemon.c (do_setutent, do_updwtmp):
	Allow arbitrary	length filenames.

	* login/programs/request.c (do_pututline):
	Don't fail if connection->position is -1 on entry.

1997-06-15 16:32  Mark Kettenis  <kettenis@phys.uva.nl>

	* login/utmp_file.c (updwtmp_file): Use the same method for
	appending an entry as in pututline_file.

1997-06-11 18:59  Mark Kettenis  <kettenis@phys.uva.nl>

	* login/utmp_file.c (getutent_r_file):
	Use read lock instead of write lock.
	(getutline_r_file, internal_getut_r): Lock utmp file.
	(updwtmp_file): Use fcntl to lock file instead of flock.

1997-06-18 00:11  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* stdio-common/vfscanf.c (inchar, ungetc): Don't count EOF as
	character read in/put back.
	* stdio-common/tstscanf.c: Add test case for this.

1997-06-17 22:17  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* libc.map: Add more symbols.

1997-06-18 12:01  Ulrich Drepper  <drepper@cygnus.com>

	* manual/Makefile (install): Make sure `dir' file exists if we use
	install-info.

1997-06-17 19:32  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* manual/Makefile (info): Depend on dir-add.info.

1997-06-17 17:19  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* elf/ldd.bash.in: Fix spacing in message.

1997-06-17 14:28  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* elf/do-rel.h (elf_dynamic_do_rel): Always use version
	information if available.

1997-06-17 11:34  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sunrpc/Makefile ($(rpcsvc:%.x=$(objpfx)rpcsvc/%.h)): Make
	command non-empty to force make to recheck modification time.
	($(rpcsvc:%.x=$(objpfx)x%.c)): Likewise.

1997-06-17 00:26  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/stub/e_acoshl.c: Set errno to ENOSYS.
	* sysdeps/stub/e_acosl.c: Likewise.
	* sysdeps/stub/e_asinl.c: Likewise.
	* sysdeps/stub/e_atan2l.c: Likewise.
	* sysdeps/stub/e_expl.c: Likewise.
	* sysdeps/stub/e_fmodl.c: Likewise.
	* sysdeps/stub/e_j0l.c: Likewise.
	* sysdeps/stub/e_j1l.c: Likewise.
	* sysdeps/stub/e_jnl.c: Likewise.
	* sysdeps/stub/e_lgammal_r.c: Likewise.
	* sysdeps/stub/e_log10l.c: Likewise.
	* sysdeps/stub/e_logl.c: Likewise.
	* sysdeps/stub/e_powl.c: Likewise.
	* sysdeps/stub/e_rem_pio2l.c: Likewise.
	* sysdeps/stub/e_sqrtl.c: Likewise.
	* sysdeps/stub/k_cosl.c: Likewise.
	* sysdeps/stub/k_rem_pio2l.c: Likewise.
	* sysdeps/stub/k_sinl.c: Likewise.
	* sysdeps/stub/k_tanl.c: Likewise.
	* sysdeps/stub/s_atanl.c: Likewise.
	* sysdeps/stub/s_erfl.c: Likewise.
	* sysdeps/stub/s_exp2.c: Likewise.
	* sysdeps/stub/s_exp2f.c: Likewise.
	* sysdeps/stub/s_exp2l.c: Likewise.
	* sysdeps/stub/s_expm1l.c: Likewise.
	* sysdeps/stub/s_log1pl.c: Likewise.
	* sysdeps/stub/s_log2l.c: Likewise.

1997-06-18 11:46  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/libm-ieee754/w_gamma.c: If _LIB_VERSION is _SVID_ compute
	result as before last change.
	* sysdeps/libm-ieee754/w_gammaf.c: Likewise.
	* sysdeps/libm-ieee754/w_gammal.c: Likewise.

1997-06-16 23:37  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/libm-ieee754/s_remquo.c: Fix off-by-one when computing
	quotient.
	* sysdeps/libm-ieee754/s_remquof.c: Likewise.
	* sysdeps/libm-ieee754/s_remquol.c: Likewise.

	* sysdeps/m68k/fpu/s_remquo.c: Remove FIXME and special case for
	quotient.

	* sysdeps/libm-ieee754/w_gamma.c: Add missing call to exp
	function.  Don't use global signgam.
	* sysdeps/libm-ieee754/w_gammaf.c: Likewise.
	* sysdeps/libm-ieee754/w_gammal.c: Likewise.

	* math/Makefile (libm-calls): Remove w_gamma_r.
	* sysdeps/libm-ieee754/w_gamma_r.c: Remove file.
	* sysdeps/libm-ieee754/w_gammaf_r.c: Remove file.
	* sysdeps/libm-ieee754/w_gammal_r.c: Remove file.

	* math/libm-test.c (atanh_test): Declare x only if needed.
	(signbit_test): Fix typo.
	(gamma_test): Check whether function is implemented.  Add
	epsilons.
	(lgamma_test): Likewise.
	(fmod_test): Add epsilons.
	(exp2_test): Use right function for existence test.

1997-06-07 09:20  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/powerpc/Dist: Add fenv_const.c.
	* sysdeps/unix/sysv/linux/Dist: Add net/if_slip.h.
	* sysdeps/unix/sysv/linux/powerpc/Dist: Add init-first.h and
	syscall.h.
	* sysdeps/unix/sysv/linux/sparc/Dist: Add init-first.h.
	* string/Makefile (distribute): Add tst-svc.expect.
	* nis/Makefile (distribute): Add nis_intern.h and Banner.
	* elf/Makefile (distribute): Add dl-hash.h.
	* Rules (subdir_echo-distinfo): Add headers from $(distribute).

	* login/Makefile (others): Add utmpdump.
	* sysdeps/unix/sysv/linux/Makefile (sysdep_headers): Add
	net/if_slip.h.

	* manual/Makefile (dir-add.texi): Also look in indirectly included
	files.

1997-06-16 23:15  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/configure.in: Remove commands to
	generate stdio_lim.h.
	* sysdeps/unix/sysv/linux/mk-stdiolim.c: Remove.
	* sysdeps/unix/sysv/linux/Makefile: Add rules to generate
	stdio_lim.h here.
	(common-generated): Add generated files.
	(inhibit-stdio_lim): Define.
	* sysdeps/posix/Makefile [$(inhibit-stdio_lim)=yes]: Disable rules
	to generate stdio_lim.h.

	* sysdeps/unix/sysv/linux/Makefile: Suppress inclusion of
	dependecy files if no_deps is set.
	($(objpfx)syscall-%.d): Add header file as target to dependency
	generation.

1997-06-14 19:19  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* sysdeps/unix/sysv/linux/arm/Dist: New file.

1997-06-14 17:59  Andreas Schwab  <schwab@issan.informatik.uni-dortmund.de>

	* extra-lib.mk (others): Depend on versioned shared library, not
	the unversioned one.
	* Makerules (build-shlib): Don't make the version link here.
	($(common-objpfx)libc.so$(libc.so-version)): New rule for libc
	version link.

1997-06-16 03:07  Ulrich Drepper  <drepper@cygnus.com>

	* sysdeps/libm-ieee754/k_standard.c: Undo change of Tue Aug 6
	01:13:56 1996.

	* argp/argp-help.c (argp_args_usage): Supply correct argp to
	filter_doc.
	* argp/argp-help.c (hol_add_cluster): Initialize CL->depth.
	* argp/argp-help.c (_help): Supply STATE to argp_args_usage.
	* argp/argp.h (ARGP_KEY_HELP_ARGS_DOC): New macro.
	* argp/argp-fmtstream.c: Add casts to prevent warnings.
	* argp/argp.h (OPTION_NO_USAGE): New macro.
	* argp/argp-help.c (usage_long_opt, usage_argful_short_opt,
	* argp/argp-fmtstream.c (__argp_fmtstream_update): Account for case
	* argp/argp-help.c <stddef.h>: New include.
	* argp/argp.h (argp_state_help, __argp_state_help, argp_usage,
	* argp/argp.h (argp_program_bug_address): Make const.
	* argp/argp-parse.c (argp_default_parser): Set STATE->name for OPT_PROGNAME.
	* argp/argp-help.c (__argp_error, __argp_failure, __argp_state_help):
	* argp/argp-parse.c (parser_init): Set PARSER->state.flags.
Diffstat (limited to 'login')
-rw-r--r--login/Makefile2
-rw-r--r--login/programs/request.c20
-rw-r--r--login/programs/utmpd.c10
-rw-r--r--login/programs/utmpd.h7
-rw-r--r--login/utmp_daemon.c52
-rw-r--r--login/utmp_file.c89
6 files changed, 116 insertions, 64 deletions
diff --git a/login/Makefile b/login/Makefile
index 916dd6c512..e4f9a9e9be 100644
--- a/login/Makefile
+++ b/login/Makefile
@@ -27,7 +27,7 @@ headers	:= utmp.h utmpbits.h lastlog.h pty.h
 routines := getutent getutent_r getutid getutline getutid_r getutline_r \
 	    utmp_file utmp_daemon utmpname updwtmp
 
-others = utmpd
+others = utmpd utmpdump
 install-sbin = utmpd
 utmpd-routines := connection database error request xtmp
 extra-objs := $(utmpd-routines:=.o)
diff --git a/login/programs/request.c b/login/programs/request.c
index d2c12e68cf..5e6bfa19cf 100644
--- a/login/programs/request.c
+++ b/login/programs/request.c
@@ -182,12 +182,8 @@ do_setutent (client_connection *connection)
   setutent_request *request;
   setutent_reply reply;
 
+  /* The request size varies, so don't check it.  */
   request = (setutent_request *)connection->read_base;
-  if (request->header.size != sizeof (setutent_request))
-    {
-      warning (EINVAL, "invalid request size");
-      return -1;
-    }
 
   /* Initialize reply.  */
   reply.header.version = UTMPD_VERSION;
@@ -195,7 +191,8 @@ do_setutent (client_connection *connection)
   reply.header.type = UTMPD_REQ_SETUTENT;
 
   /* Select database.  */
-  if (!strncmp (request->file, _PATH_UTMP, sizeof request->file))
+  if (!strncmp (request->file, _PATH_UTMP,
+		request->header.size - sizeof (setutent_request)))
     connection->database = utmp_db;
   else
     {
@@ -450,7 +447,7 @@ do_pututline (client_connection *connection)
       goto return_error;
     }
 
-  if (connection->database == NULL || connection->position == -1)
+  if (connection->database == NULL)
     {
       errno = ESRCH;
       goto return_error;
@@ -520,12 +517,8 @@ do_updwtmp (client_connection *connection)
   updwtmp_reply reply;
   utmp_database *database;
 
+  /* The request size varies, so don't check it.  */
   request = (updwtmp_request *)connection->read_base;
-  if (request->header.size != sizeof (updwtmp_request))
-    {
-      warning (EINVAL, "invalid request size");
-      return -1;
-    }
 
   /* Initialize reply.  */
   reply.header.version = UTMPD_VERSION;
@@ -539,7 +532,8 @@ do_updwtmp (client_connection *connection)
     }
 
   /* Select database.  */
-  if (!strncmp (request->file, _PATH_UTMP, sizeof request->file))
+  if (!strncmp (request->file, _PATH_UTMP,
+		request->header.size - sizeof (updwtmp_request)))
     database = utmp_db;
   else
     {
diff --git a/login/programs/utmpd.c b/login/programs/utmpd.c
index ca310a21de..3c8d626a84 100644
--- a/login/programs/utmpd.c
+++ b/login/programs/utmpd.c
@@ -134,8 +134,9 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
     usage (EXIT_SUCCESS);
 
   signal (SIGINT, termination_handler);
+  signal (SIGQUIT, termination_handler);
   signal (SIGTERM, termination_handler);
-
+  
   /* Check if we are already running.  */
   if (check_pid (_PATH_UTMPDPID))
     error (EXIT_FAILURE, 0, "already running");
@@ -168,8 +169,13 @@ warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n\
 
       if (write_pid (_PATH_UTMPDPID) < 0)
 	warning (errno, "%s", _PATH_UTMPDPID);
-    }
 
+      /* Ignore job control signals.  */
+      signal (SIGTTOU, SIG_IGN);
+      signal (SIGTTIN, SIG_IGN);
+      signal (SIGTSTP, SIG_IGN);
+    }
+  
   /* Drop priviliges.  */
   drop_priviliges ();
   
diff --git a/login/programs/utmpd.h b/login/programs/utmpd.h
index 8fbc33c923..ef92a1490b 100644
--- a/login/programs/utmpd.h
+++ b/login/programs/utmpd.h
@@ -22,7 +22,6 @@
 
 /* This is an *internal* header.  */
 
-#include <limits.h>
 #include <stddef.h>
 #include <utmp.h>
 
@@ -68,7 +67,7 @@ typedef struct
 {
   request_header header;
   /* File to use.  */
-  char file[_POSIX_PATH_MAX + 1];
+  char file[0];
 } setutent_request;
 
 typedef struct
@@ -100,10 +99,10 @@ typedef struct
 typedef struct
 {
   request_header header;
-  /* File to use.  */
-  char file[_POSIX_PATH_MAX + 1];
   /* Entry to write.  */
   struct utmp utmp;
+  /* File to use.  */
+  char file[0];
 } updwtmp_request;
 
 
diff --git a/login/utmp_daemon.c b/login/utmp_daemon.c
index 705c8b3de9..e0a20e9a9f 100644
--- a/login/utmp_daemon.c
+++ b/login/utmp_daemon.c
@@ -227,24 +227,35 @@ updwtmp_daemon (const char *file, const struct utmp *utmp)
 static int
 do_setutent (int sock)
 {
-  setutent_request request;
+  setutent_request *request;
   setutent_reply reply;
+  size_t size;
 
-  request.header.version = UTMPD_VERSION;
-  request.header.size = sizeof (setutent_request);
-  request.header.type = UTMPD_REQ_SETUTENT;
-  strncpy (request.file, __libc_utmp_file_name, sizeof request.file);
+  size = sizeof (setutent_request) + strlen (__libc_utmp_file_name) + 1;
+  
+  request = malloc (size);
+  if (request == NULL)
+    return -1;
+  
+  request->header.version = UTMPD_VERSION;
+  request->header.size = size;
+  request->header.type = UTMPD_REQ_SETUTENT;
+  strcpy (request->file, __libc_utmp_file_name);
 
   reply.header.version = UTMPD_VERSION;
   reply.header.size = sizeof (setutent_reply);
   reply.header.type = UTMPD_REQ_SETUTENT;
 
-  if (send_request (sock, &request.header, &reply.header) < 0)
-    return -1;
+  if (send_request (sock, &request->header, &reply.header) < 0)
+    {
+      free (request);
+      return -1;
+    }
 
   if (reply.result < 0)
     __set_errno (reply.errnum);
 
+  free (request);
   return reply.result;
 }
 
@@ -375,25 +386,36 @@ do_pututline (int sock, const struct utmp *utmp)
 static int
 do_updwtmp (int sock, const char *file, const struct utmp *utmp)
 {
-  updwtmp_request request;
+  updwtmp_request *request;
   updwtmp_reply reply;
+  size_t size;
 
-  request.header.version = UTMPD_VERSION;
-  request.header.size = sizeof (updwtmp_request);
-  request.header.type = UTMPD_REQ_UPDWTMP;
-  strncpy (request.file, file, sizeof request.file);
-  memcpy (&request.utmp, utmp, sizeof (struct utmp));
+  size = sizeof (updwtmp_request) + strlen (file) + 1;
+  
+  request = malloc (size);
+  if (request == NULL)
+    return -1;
+  
+  request->header.version = UTMPD_VERSION;
+  request->header.size = size;
+  request->header.type = UTMPD_REQ_UPDWTMP;
+  memcpy (&request->utmp, utmp, sizeof (struct utmp));
+  strcpy (request->file, file);
 
   reply.header.version = UTMPD_VERSION;
   reply.header.size = sizeof (updwtmp_reply);
   reply.header.type = UTMPD_REQ_UPDWTMP;
 
-  if (send_request (sock, &request.header, &reply.header) < 0)
-    return -1;
+  if (send_request (sock, &request->header, &reply.header) < 0)
+    {
+      free (request);
+      return -1;
+    }
 
   if (reply.result < 0)
     __set_errno (reply.errnum);
 
+  free (request);
   return reply.result;
 }
 
diff --git a/login/utmp_file.c b/login/utmp_file.c
index 2026070f14..51b33226e0 100644
--- a/login/utmp_file.c
+++ b/login/utmp_file.c
@@ -24,10 +24,9 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <sys/stat.h>
 #include <unistd.h>
 #include <utmp.h>
-#include <sys/file.h>
-#include <sys/stat.h>
 
 #include "utmp-private.h"
 
@@ -116,7 +115,7 @@ endutent_file (void)
 static int
 getutent_r_file (struct utmp *buffer, struct utmp **result)
 {
-  int nbytes;
+  ssize_t nbytes;
   struct flock fl;			/* Information struct for locking.  */
 
   /* Open utmp file if not already done.  */
@@ -136,7 +135,7 @@ getutent_r_file (struct utmp *buffer, struct utmp **result)
 
   /* Try to get the lock.  */
   memset (&fl, '\0', sizeof (struct flock));
-  fl.l_type = F_WRLCK;
+  fl.l_type = F_RDLCK;
   fl.l_whence = SEEK_SET;
   fcntl (file_fd, F_SETLKW, &fl);
 
@@ -170,12 +169,20 @@ static int
 getutline_r_file (const struct utmp *line, struct utmp *buffer,
 		  struct utmp **result)
 {
+  struct flock fl;
+  
   if (file_fd < 0 || file_offset == -1l)
     {
       *result = NULL;
       return -1;
     }
 
+  /* Try to get the lock.  */
+  memset (&fl, '\0', sizeof (struct flock));
+  fl.l_type = F_RDLCK;
+  fl.l_whence = SEEK_SET;
+  fcntl (file_fd, F_SETLKW, &fl);
+
   while (1)
     {
       /* Read the next entry.  */
@@ -185,7 +192,7 @@ getutline_r_file (const struct utmp *line, struct utmp *buffer,
 	  __set_errno (ESRCH);
 	  file_offset = -1l;
 	  *result = NULL;
-	  return -1;
+	  goto unlock_return;
 	}
       file_offset += sizeof (struct utmp);
 
@@ -203,7 +210,12 @@ getutline_r_file (const struct utmp *line, struct utmp *buffer,
   memcpy (buffer, &last_entry, sizeof (struct utmp));
   *result = buffer;
 
-  return 0;
+unlock_return:
+  /* And unlock the file.  */
+  fl.l_type = F_UNLCK;
+  fcntl (file_fd, F_SETLKW, &fl);
+
+  return ((result == NULL) ? -1 : 0);
 }
 
 
@@ -237,6 +249,15 @@ proc_utmp_eq (const struct utmp *entry, const struct utmp *match)
 static int
 internal_getut_r (const struct utmp *id, struct utmp *buffer)
 {
+  int result = -1;
+  struct flock fl;
+  
+  /* Try to get the lock.  */
+  memset (&fl, '\0', sizeof (struct flock));
+  fl.l_type = F_RDLCK;
+  fl.l_whence = SEEK_SET;
+  fcntl (file_fd, F_SETLKW, &fl);
+
 #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)
@@ -252,7 +273,7 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer)
 	    {
 	      __set_errno (ESRCH);
 	      file_offset = -1l;
-	      return -1;
+	      goto unlock_return;
 	    }
 	  file_offset += sizeof (struct utmp);
 
@@ -274,7 +295,7 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer)
 	    {
 	      __set_errno (ESRCH);
 	      file_offset = -1l;
-	      return -1;
+	      goto unlock_return;
 	    }
 	  file_offset += sizeof (struct utmp);
 
@@ -283,7 +304,14 @@ internal_getut_r (const struct utmp *id, struct utmp *buffer)
 	}
     }
 
-  return 0;
+  result = 0;
+
+unlock_return:
+  /* And unlock the file.  */
+  fl.l_type = F_UNLCK;
+  fcntl (file_fd, F_SETLKW, &fl);
+
+  return result;
 }
 
 
@@ -401,47 +429,50 @@ static int
 updwtmp_file (const char *file, const struct utmp *utmp)
 {
   int result = -1;
-  struct stat st;
-  ssize_t nbytes;
+  struct flock fl;
+  off_t offset;
   int fd;
   
   /* Open WTMP file.  */
-  fd = __open (file, O_WRONLY | O_APPEND);
+  fd = open (file, O_WRONLY);
   if (fd < 0)
     return -1;
 
-  /* Try to lock the file.  */
-  if (__flock (fd, LOCK_EX | LOCK_NB) < 0 && errno != ENOSYS)
+  /* Try to get the lock.  */
+  memset (&fl, '\0', sizeof (struct flock));
+  fl.l_type = F_WRLCK;
+  fl.l_whence = SEEK_SET;
+  fcntl (fd, F_SETLKW, &fl);
+  
+  /* Remember original size of log file.  */
+  offset = lseek (fd, 0, SEEK_END);
+  if (offset % sizeof (struct utmp) != 0)
     {
-      /* Oh, oh.  The file is already locked.  Wait a bit and try again.  */
-      sleep (1);
+      offset -= offset % sizeof (struct utmp);
+      ftruncate (fd, offset);
 
-      /*  This time we ignore the error.  */
-      __flock (fd, LOCK_EX | LOCK_NB);
+      if (lseek (fd, 0, SEEK_END) < 0)
+	goto unlock_return;
     }
 
-  /* Remember original size of log file.  */
-  if (__fstat (fd, &st) < 0)
-    goto fail;
-
   /* 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.  */
-  nbytes = __write (fd, utmp, sizeof (struct utmp));
-  if (nbytes != sizeof (struct utmp))
+  if (write (fd, utmp, sizeof (struct utmp)) != sizeof (struct utmp))
     {
-      ftruncate (fd, st.st_size);
-      goto fail;
+      ftruncate (fd, offset);
+      goto unlock_return;
     }
 
   result = 0;
   
-fail:
+unlock_return:
   /* And unlock the file.  */
-  __flock (fd, LOCK_UN);
+  fl.l_type = F_UNLCK;
+  fcntl (fd, F_SETLKW, &fl);
 
   /* Close WTMP file.  */
-  __close (fd);
+  close (fd);
 
   return result;
 }