From 1f2ff42d4943d0567b33af1dd0b6f4b5b077f025 Mon Sep 17 00:00:00 2001 From: Cameron Katri Date: Sun, 14 Feb 2021 00:26:31 -0500 Subject: Move files around --- getutxent.c | 248 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ utxdb.h | 63 +++++++++++++++ 2 files changed, 311 insertions(+) create mode 100644 getutxent.c create mode 100644 utxdb.h diff --git a/getutxent.c b/getutxent.c new file mode 100644 index 0000000..e0d9932 --- /dev/null +++ b/getutxent.c @@ -0,0 +1,248 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2010 Ed Schouten + * 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. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include "namespace.h" +#include +#include +#include +#include +#include +#include +#include +#include "utxdb.h" +#include "un-namespace.h" + +#ifdef __NO_TLS +static FILE *uf = NULL; +static int udb; +#else +static _Thread_local FILE *uf = NULL; +static _Thread_local int udb; +#endif + +int +setutxdb(int db, const char *file) +{ + struct stat sb; + + switch (db) { + case UTXDB_ACTIVE: + if (file == NULL) + file = _PATH_UTX_ACTIVE; + break; + case UTXDB_LASTLOGIN: + if (file == NULL) + file = _PATH_UTX_LASTLOGIN; + break; + case UTXDB_LOG: + if (file == NULL) + file = _PATH_UTX_LOG; + break; + default: + errno = EINVAL; + return (-1); + } + + if (uf != NULL) + fclose(uf); + uf = fopen(file, "re"); + if (uf == NULL) + return (-1); + + if (db != UTXDB_LOG) { + /* Safety check: never use broken files. */ + if (_fstat(fileno(uf), &sb) != -1 && + sb.st_size % sizeof(struct futx) != 0) { + fclose(uf); + uf = NULL; + errno = EFTYPE; + return (-1); + } + /* Prevent reading of partial records. */ + (void)setvbuf(uf, NULL, _IOFBF, + rounddown(BUFSIZ, sizeof(struct futx))); + } + + udb = db; + return (0); +} + +void +setutxent(void) +{ + + setutxdb(UTXDB_ACTIVE, NULL); +} + +void +endutxent(void) +{ + + if (uf != NULL) { + fclose(uf); + uf = NULL; + } +} + +static int +getfutxent(struct futx *fu) +{ + + if (uf == NULL) + setutxent(); + if (uf == NULL) + return (-1); + + if (udb == UTXDB_LOG) { + uint16_t len; + +retry: + if (fread(&len, sizeof(len), 1, uf) != 1) + return (-1); + len = be16toh(len); + if (len == 0) { + /* + * XXX: Though zero-size records are valid in theory, + * they can never occur in practice. Zero-size records + * indicate file corruption. Seek one byte forward, to + * see if we can find a record there. + */ + ungetc('\0', uf); + goto retry; + } + if (len > sizeof *fu) { + /* Forward compatibility. */ + if (fread(fu, sizeof(*fu), 1, uf) != 1) + return (-1); + fseek(uf, len - sizeof(*fu), SEEK_CUR); + } else { + /* Partial record. */ + memset(fu, 0, sizeof(*fu)); + if (fread(fu, len, 1, uf) != 1) + return (-1); + } + } else { + if (fread(fu, sizeof(*fu), 1, uf) != 1) + return (-1); + } + return (0); +} + +struct utmpx * +getutxent(void) +{ + struct futx fu; + + if (getfutxent(&fu) != 0) + return (NULL); + return (futx_to_utx(&fu)); +} + +struct utmpx * +getutxid(const struct utmpx *id) +{ + struct futx fu; + + for (;;) { + if (getfutxent(&fu) != 0) + return (NULL); + + switch (fu.fu_type) { + case USER_PROCESS: + case INIT_PROCESS: + case LOGIN_PROCESS: + case DEAD_PROCESS: + switch (id->ut_type) { + case USER_PROCESS: + case INIT_PROCESS: + case LOGIN_PROCESS: + case DEAD_PROCESS: + if (memcmp(fu.fu_id, id->ut_id, + MIN(sizeof(fu.fu_id), sizeof(id->ut_id))) == + 0) + goto found; + } + break; + default: + if (fu.fu_type == id->ut_type) + goto found; + break; + } + } + +found: + return (futx_to_utx(&fu)); +} + +struct utmpx * +getutxline(const struct utmpx *line) +{ + struct futx fu; + + for (;;) { + if (getfutxent(&fu) != 0) + return (NULL); + + switch (fu.fu_type) { + case USER_PROCESS: + case LOGIN_PROCESS: + if (strncmp(fu.fu_line, line->ut_line, + MIN(sizeof(fu.fu_line), sizeof(line->ut_line))) == + 0) + goto found; + break; + } + } + +found: + return (futx_to_utx(&fu)); +} + +struct utmpx * +getutxuser(const char *user) +{ + struct futx fu; + + for (;;) { + if (getfutxent(&fu) != 0) + return (NULL); + + switch (fu.fu_type) { + case USER_PROCESS: + if (strncmp(fu.fu_user, user, sizeof(fu.fu_user)) == 0) + goto found; + break; + } + } + +found: + return (futx_to_utx(&fu)); +} diff --git a/utxdb.h b/utxdb.h new file mode 100644 index 0000000..912dd0f --- /dev/null +++ b/utxdb.h @@ -0,0 +1,63 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause-FreeBSD + * + * Copyright (c) 2010 Ed Schouten + * 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 + +#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 utmpx; + +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[16]; + char fu_host[128]; +} __packed; + +void utx_to_futx(const struct utmpx *, struct futx *); +struct utmpx *futx_to_utx(const struct futx *); + +#endif /* !_UTXDB_H_ */ -- cgit v1.2.3-56-ge451