summaryrefslogtreecommitdiff
path: root/package/heirloom-cpio/src/utmpx.c
diff options
context:
space:
mode:
Diffstat (limited to 'package/heirloom-cpio/src/utmpx.c')
-rw-r--r--package/heirloom-cpio/src/utmpx.c252
1 files changed, 252 insertions, 0 deletions
diff --git a/package/heirloom-cpio/src/utmpx.c b/package/heirloom-cpio/src/utmpx.c
new file mode 100644
index 000000000..d88a627a7
--- /dev/null
+++ b/package/heirloom-cpio/src/utmpx.c
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2004 Gunnar Ritter
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute
+ * it freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source distribution.
+ */
+/* Sccsid @(#)utmpx.c 1.13 (gritter) 12/16/07 */
+
+#include <stdio.h>
+
+#if defined (__FreeBSD__) || defined (__dietlibc__) || defined (__NetBSD__) || \
+ defined (__UCLIBC__) || defined (__OpenBSD__) || \
+ defined (__DragonFly__) || \
+ defined (__APPLE__) && \
+ (__MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_OS_X_VERSION_10_5)
+#include <sys/types.h>
+#include <sys/time.h>
+#include <utmp.h>
+#include <string.h>
+
+#include "utmpx.h"
+
+static FILE *utfp;
+static struct utmpx utx;
+static const char *utmpfile = _PATH_UTMP;
+
+static FILE *
+init(void)
+{
+ if (utfp == NULL && (utfp = fopen(utmpfile, "r+")) == NULL)
+ if ((utfp = fopen(utmpfile, "r")) == NULL)
+ return NULL;
+ return utfp;
+}
+
+static struct utmpx *
+utmp2utmpx(struct utmpx *ux, const struct utmp *up)
+{
+#ifndef __dietlibc__
+ memset(ux, 0, sizeof *ux);
+ ux->ut_tv.tv_sec = up->ut_time;
+ memcpy(ux->ut_line, up->ut_line, UT_LINESIZE);
+ memcpy(ux->ut_user, up->ut_name, UT_NAMESIZE);
+ memcpy(ux->ut_host, up->ut_host, UT_HOSTSIZE);
+ if (strcmp(up->ut_line, "~") == 0)
+ ux->ut_type = BOOT_TIME;
+ else if (strcmp(up->ut_line, "|") == 0)
+ ux->ut_type = OLD_TIME;
+ else if (strcmp(up->ut_line, "}") == 0)
+ ux->ut_type = NEW_TIME;
+ else if (*up->ut_name == 0)
+ ux->ut_type = DEAD_PROCESS;
+ else
+ ux->ut_type = USER_PROCESS;
+#else /* __dietlibc__ */
+ *ux = *up;
+#endif /* __dietlibc__ */
+ return ux;
+}
+
+static struct utmp *
+utmpx2utmp(struct utmp *up, const struct utmpx *ux)
+{
+#ifndef __dietlibc__
+ memset(up, 0, sizeof *up);
+ up->ut_time = ux->ut_tv.tv_sec;
+ switch (ux->ut_type) {
+ case DEAD_PROCESS:
+ memcpy(up->ut_line, ux->ut_line, UT_LINESIZE);
+ break;
+ default:
+ case EMPTY:
+ case INIT_PROCESS:
+ case LOGIN_PROCESS:
+ case RUN_LVL:
+ case ACCOUNTING:
+ return NULL;
+ case BOOT_TIME:
+ strcpy(up->ut_name, "reboot");
+ strcpy(up->ut_line, "~");
+ break;
+ case OLD_TIME:
+ strcpy(up->ut_name, "date");
+ strcpy(up->ut_line, "|");
+ break;
+ case NEW_TIME:
+ strcpy(up->ut_name, "date");
+ strcpy(up->ut_line, "{");
+ break;
+ case USER_PROCESS:
+ memcpy(up->ut_line, ux->ut_line, UT_LINESIZE);
+ memcpy(up->ut_name, ux->ut_user, UT_NAMESIZE);
+ memcpy(up->ut_host, ux->ut_host, UT_HOSTSIZE);
+ }
+#else /* __dietlibc__ */
+ *up = *ux;
+#endif /* __dietlibc__ */
+ return up;
+}
+
+struct utmpx *
+getutxent(void)
+{
+ static struct utmp zero;
+ struct utmp ut;
+
+ if (init() == NULL)
+ return NULL;
+ do {
+ if (fread(&ut, sizeof ut, 1, utfp) != 1)
+ return NULL;
+ } while (memcmp(&ut, &zero, sizeof ut) == 0);
+ return utmp2utmpx(&utx, &ut);
+}
+
+struct utmpx *
+getutxline(const struct utmpx *ux)
+{
+ struct utmp ut;
+
+ if (init() == NULL)
+ return NULL;
+ fseek(utfp, 0, SEEK_SET);
+ while (fread(&ut, sizeof ut, 1, utfp) == 1) {
+ utmp2utmpx(&utx, &ut);
+ if ((utx.ut_type == LOGIN_PROCESS ||
+ utx.ut_type == USER_PROCESS) &&
+ strcmp(ut.ut_line, utx.ut_line) == 0)
+ return &utx;
+ }
+ return NULL;
+}
+
+struct utmpx *
+getutxid(const struct utmpx *ux)
+{
+#ifdef __dietlibc__
+ struct utmp ut;
+#endif
+
+ if (init() == NULL)
+ return NULL;
+#ifdef __dietlibc__
+ fseek(utfp, 0, SEEK_SET);
+ while (fread(&ut, sizeof ut, 1, utfp) == 1) {
+ utmp2utmpx(&utx, &ut);
+ switch (ux->ut_type) {
+ case BOOT_TIME:
+ case OLD_TIME:
+ case NEW_TIME:
+ if (ux->ut_type == utx.ut_type)
+ return &utx;
+ break;
+ case INIT_PROCESS:
+ case LOGIN_PROCESS:
+ case USER_PROCESS:
+ case DEAD_PROCESS:
+ if (ux->ut_type == utx.ut_type &&
+ ux->ut_id == utx.ut_id)
+ return &utx;
+ break;
+ }
+ }
+#endif /* __dietlibc__ */
+ return NULL;
+}
+
+void
+setutxent(void)
+{
+ if (init() == NULL)
+ return;
+ fseek(utfp, 0, SEEK_SET);
+}
+
+void
+endutxent(void)
+{
+ FILE *fp;
+
+ if (init() == NULL)
+ return;
+ fp = utfp;
+ utfp = NULL;
+ fclose(fp);
+}
+
+int
+utmpxname(const char *name)
+{
+ utmpfile = strdup(name);
+ return 0;
+}
+
+extern struct utmpx *
+pututxline(const struct utmpx *up)
+{
+ struct utmp ut;
+ struct utmpx *rp;
+
+ if (init() == NULL)
+ return NULL;
+ /*
+ * Cannot use getutxid() because there is no id field. Use
+ * the equivalent of getutxline() instead.
+ */
+ while (fread(&ut, sizeof ut, 1, utfp) == 1) {
+ if (strncmp(ut.ut_line, up->ut_line, UT_LINESIZE) == 0) {
+ fseek(utfp, -sizeof ut, SEEK_CUR);
+ break;
+ }
+ }
+ fflush(utfp);
+ if (utmpx2utmp(&ut, up) == NULL)
+ rp = NULL;
+ else if (fwrite(&ut, sizeof ut, 1, utfp) == 1) {
+ utx = *up;
+ rp = &utx;
+ } else
+ rp = NULL;
+ fflush(utfp);
+ return rp;
+}
+
+extern void
+updwtmpx(const char *name, const struct utmpx *up)
+{
+ FILE *fp;
+
+ if ((fp = fopen(name, "a")) == NULL)
+ return;
+ fwrite(up, sizeof *up, 1, fp);
+ fclose(fp);
+}
+
+#endif /* __FreeBSD__ || __dietlibc__ || __NetBSD__ || __UCLIBC__ ||
+ __OpenBSD__ || __DragonFly__ || __APPLE__ */