svn commit: r201619 - user/ed/utmpx/lib/libc/gen

Ed Schouten ed at FreeBSD.org
Tue Jan 5 22:53:20 UTC 2010


Author: ed
Date: Tue Jan  5 22:53:20 2010
New Revision: 201619
URL: http://svn.freebsd.org/changeset/base/201619

Log:
  Partially implement pututxline().
  
  Right now it only writes entries to the lastlog and wtmp files, called
  utx.lastlogin and utx.log.

Added:
  user/ed/utmpx/lib/libc/gen/pututxline.c   (contents, props changed)
  user/ed/utmpx/lib/libc/gen/utxdb.h   (contents, props changed)
Modified:
  user/ed/utmpx/lib/libc/gen/Makefile.inc
  user/ed/utmpx/lib/libc/gen/getutxent.c

Modified: user/ed/utmpx/lib/libc/gen/Makefile.inc
==============================================================================
--- user/ed/utmpx/lib/libc/gen/Makefile.inc	Tue Jan  5 22:50:36 2010	(r201618)
+++ user/ed/utmpx/lib/libc/gen/Makefile.inc	Tue Jan  5 22:53:20 2010	(r201619)
@@ -23,7 +23,7 @@ SRCS+=  __getosreldate.c __xuname.c \
 	lockf.c lrand48.c mrand48.c nftw.c nice.c \
 	nlist.c nrand48.c opendir.c \
 	pause.c pmadvise.c popen.c posix_spawn.c \
-	psignal.c pw_scan.c pwcache.c \
+	psignal.c pututxline.c pw_scan.c pwcache.c \
 	raise.c readdir.c readpassphrase.c rewinddir.c \
 	scandir.c seed48.c seekdir.c sem.c semctl.c \
 	setdomainname.c sethostname.c setjmperr.c setmode.c \

Modified: user/ed/utmpx/lib/libc/gen/getutxent.c
==============================================================================
--- user/ed/utmpx/lib/libc/gen/getutxent.c	Tue Jan  5 22:50:36 2010	(r201618)
+++ user/ed/utmpx/lib/libc/gen/getutxent.c	Tue Jan  5 22:53:20 2010	(r201619)
@@ -58,13 +58,6 @@ getutxline(const struct utmpx *line)
 	return (NULL);
 }
 
-struct utmpx *
-pututxline(const struct utmpx *utmpx)
-{
-
-	return (NULL);
-}
-
 void
 setutxent(void)
 {

Added: user/ed/utmpx/lib/libc/gen/pututxline.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/ed/utmpx/lib/libc/gen/pututxline.c	Tue Jan  5 22:53:20 2010	(r201619)
@@ -0,0 +1,183 @@
+/*-
+ * Copyright (c) 2010 Ed Schouten <ed at FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <fcntl.h>
+#include <string.h>
+#include <unistd.h>
+#include <utmpx.h>
+#include "utxdb.h"
+
+static int
+utx_to_futx(const struct utmpx *ut, struct futx *fu)
+{
+
+	memset(fu, 0, sizeof *fu);
+
+	switch (ut->ut_type) {
+	case BOOT_TIME:
+	case OLD_TIME:
+	case NEW_TIME:
+	/* Extension: shutdown time. */
+	case SHUTDOWN_TIME:
+		break;
+	case USER_PROCESS:
+		UTOF_STRING(ut, fu, id);
+		UTOF_STRING(ut, fu, user);
+		UTOF_STRING(ut, fu, line);
+		/* Extension: host name. */
+		UTOF_STRING(ut, fu, host);
+		UTOF_PID(ut, fu);
+		break;
+#if 0
+	case INIT_PROCESS:
+		UTOF_STRING(ut, fu, id);
+		UTOF_PID(ut, fu);
+		break;
+	case LOGIN_PROCESS:
+		UTOF_STRING(ut, fu, id);
+		UTOF_STRING(ut, fu, user);
+		UTOF_PID(ut, fu);
+		break;
+#endif
+	case DEAD_PROCESS:
+		UTOF_STRING(ut, fu, id);
+		UTOF_PID(ut, fu);
+		break;
+	default:
+		return (-1);
+	}
+
+	UTOF_TYPE(ut, fu);
+	UTOF_TV(ut, fu);
+
+	return (0);
+}
+
+static void
+utx_active_add(const struct futx *fu)
+{
+}
+
+static int
+utx_active_remove(const struct futx *fu)
+{
+
+	return (0);
+}
+
+static void
+utx_lastlogin_add(const struct futx *fu)
+{
+	int fd;
+	struct futx fe;
+
+	/*
+	 * Write an entry to lastlogin.  Overwrite the entry if the
+	 * current user already has an entry.  If not, append a new
+	 * entry.
+	 */
+	fd = open(_PATH_UTX_LASTLOGIN, O_CREAT|O_RDWR, 0644);
+	if (fd < 0)
+		return;
+	if (lockf(fd, F_LOCK, 0) == -1) {
+		close(fd);
+		return;
+	}
+	while (read(fd, &fe, sizeof fe) == sizeof fe) {
+		if (strncmp(fu->fu_user, fe.fu_user, sizeof fe.fu_user) == 0) {
+			lseek(fd, -sizeof fe, SEEK_CUR);
+			break;
+		}
+	}
+	write(fd, fu, sizeof *fu);
+	lockf(fd, F_ULOCK, 0);
+	close(fd);
+}
+
+static void
+utx_log_add(const struct futx *fu)
+{
+	struct {
+		uint16_t	len;
+		struct futx	data;
+	} __packed r;
+	size_t l;
+	int f;
+
+	/*
+	 * Append an entry to the log file.  We only need to append
+	 * records to this file, so to conserve space, trim any trailing
+	 * zero-bytes.  Prepend a length field, indicating the record of
+	 * the length, excluding the length field itself.
+	 */
+	for (l = sizeof *fu; l > 0 && ((char *)fu)[l - 1] == '\0'; l--);
+	r.len = htobe16(l);
+	memcpy(&r.data, fu, l);
+
+	f = open(_PATH_UTX_LOG, O_CREAT|O_WRONLY|O_APPEND, 0644);
+	if (f < 0)
+		return;
+	write(f, &r, sizeof r.len + l);
+	close(f);
+}
+
+struct utmpx *
+pututxline(const struct utmpx *utmpx)
+{
+	struct futx fu;
+
+	if (utx_to_futx(utmpx, &fu) != 0)
+		return (NULL);
+	
+	switch (utmpx->ut_type) {
+	case BOOT_TIME:
+	case OLD_TIME:
+	case NEW_TIME:
+	case SHUTDOWN_TIME:
+		utx_log_add(&fu);
+		break;
+	case USER_PROCESS:
+		utx_active_add(&fu);
+		utx_lastlogin_add(&fu);
+		utx_log_add(&fu);
+		break;
+#if 0
+	case INIT_PROCESS:
+	case LOGIN_PROCESS:
+#endif
+	case DEAD_PROCESS:
+		if (utx_active_remove(&fu) != 0)
+			return (NULL);
+		utx_log_add(&fu);
+	}
+
+	return (NULL);
+}

Added: user/ed/utmpx/lib/libc/gen/utxdb.h
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ user/ed/utmpx/lib/libc/gen/utxdb.h	Tue Jan  5 22:53:20 2010	(r201619)
@@ -0,0 +1,74 @@
+/*-
+ * Copyright (c) 2010 Ed Schouten <ed at FreeBSD.org>
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
+ *
+ * $FreeBSD$
+ */
+
+#ifndef _UTXDB_H_
+#define	_UTXDB_H_
+
+#include <sys/cdefs.h>
+#include <sys/endian.h>
+#include <sys/param.h>
+#include <stdint.h>
+
+#define	_PATH_UTX_ACTIVE	"/var/run/utx.active"
+#define	_PATH_UTX_LASTLOGIN	"/var/log/utx.lastlogin"
+#define	_PATH_UTX_LOG		"/var/log/utx.log"
+
+/*
+ * Entries in struct futx are ordered by how often they are used.  In
+ * utx.log only entries will be written until the last non-zero byte,
+ * which means we want to put the hostname at the end. Most primitive
+ * records only store a ut_type and ut_tv, which means we want to store
+ * those at the front.
+ */
+
+struct futx {
+	uint8_t		fu_type;
+	uint64_t	fu_tv;
+	char		fu_id[8];
+	uint32_t	fu_pid;
+	char		fu_user[32];
+	char		fu_line[32];
+	char		fu_host[256];
+} __packed;
+
+#define	UTOF_STRING(ut, fu, field) do { \
+	strncpy((fu)->fu_ ## field, (ut)->ut_ ## field,		\
+	    MIN(sizeof (fu)->fu_ ## field, sizeof (ut)->ut_ ## field));	\
+} while (0)
+#define	UTOF_PID(ut, fu) do { \
+	(fu)->fu_pid = htobe32((ut)->ut_pid);				\
+} while (0)
+#define	UTOF_TYPE(ut, fu) do { \
+	(fu)->fu_type = (ut)->ut_type;					\
+} while (0)
+#define	UTOF_TV(ut, fu) do { \
+	(fu)->fu_tv = htobe64((uint64_t)(ut)->ut_tv.tv_sec * 1000000 +	\
+	    (uint64_t)(ut)->ut_tv.tv_usec);				\
+} while (0)
+
+#endif /* !_UTXDB_H_ */


More information about the svn-src-user mailing list