diff options
Diffstat (limited to 'package/heirloom-cpio/src/utmpx.c')
-rw-r--r-- | package/heirloom-cpio/src/utmpx.c | 252 |
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__ */ |