diff options
Diffstat (limited to 'libc/misc/utmp')
-rw-r--r-- | libc/misc/utmp/Makefile | 43 | ||||
-rw-r--r-- | libc/misc/utmp/utent.c | 135 |
2 files changed, 178 insertions, 0 deletions
diff --git a/libc/misc/utmp/Makefile b/libc/misc/utmp/Makefile new file mode 100644 index 000000000..01b070f3e --- /dev/null +++ b/libc/misc/utmp/Makefile @@ -0,0 +1,43 @@ +# Makefile for uClibc +# +# Copyright (C) 2000 by Lineo, inc. +# +# This program is free software; you can redistribute it and/or modify it under +# the terms of the GNU Library General Public License as published by the Free +# Software Foundation; either version 2 of the License, or (at your option) any +# later version. +# +# This program is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +# FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more +# details. +# +# You should have received a copy of the GNU Library General Public License +# along with this program; if not, write to the Free Software Foundation, Inc., +# 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# +# Derived in part from the Linux-8086 C library, the GNU C Library, and several +# other sundry sources. Files within this library are copyright by their +# respective copyright holders. + +TOPDIR=../../ +include $(TOPDIR)Rules.mak +LIBC=$(TOPDIR)libc.a + +CSRC=utent.c +COBJS=$(patsubst %.c,%.o, $(CSRC)) +OBJS=$(COBJS) + +all: $(LIBC) + +$(LIBC): ar-target + +ar-target: $(OBJS) + $(AR) $(ARFLAGS) $(LIBC) $(OBJS) + +$(COBJS): + $(CC) $(CFLAGS) $< -c $*.c -o $*.o + $(STRIPTOOL) -x -R .note -R .comment $*.o + +clean: + rm -f *.[oa] *~ core diff --git a/libc/misc/utmp/utent.c b/libc/misc/utmp/utent.c new file mode 100644 index 000000000..f9d098fb3 --- /dev/null +++ b/libc/misc/utmp/utent.c @@ -0,0 +1,135 @@ +/* utent.c <ndf@linux.mit.edu> */ +/* Let it be known that this is very possibly the worst standard ever. HP-UX + does one thing, someone else does another, linux another... If anyone + actually has the standard, please send it to me. + + Note that because of the way this stupid stupid standard works, you + have to call endutent() to close the file even if you've not called + setutent -- getutid and family use the same file descriptor. */ + +#include <unistd.h> +#include <fcntl.h> +#include <paths.h> +#include <errno.h> +#include <string.h> +#include <utmp.h> + +static const char *ut_name = _PATH_UTMP; + +static int ut_fd = -1; + +struct utmp *__getutent(int utmp_fd) +{ + static struct utmp utmp; + if (read(utmp_fd, (char *) &utmp, sizeof(struct utmp)) != + sizeof(struct utmp)) return NULL; + + return &utmp; +} + +void setutent(void) +{ + if (ut_fd != -1) + close(ut_fd); + if ((ut_fd = open(ut_name, O_RDONLY)) < 0) { + perror("setutent: Can't open utmp file"); + ut_fd = -1; + } +} + +void endutent(void) +{ + if (ut_fd != -1) + close(ut_fd); + ut_fd = -1; +} + +struct utmp *getutent(void) +{ + if (ut_fd == -1) + setutent(); + if (ut_fd == -1) + return NULL; + return __getutent(ut_fd); +} + +struct utmp *getutid(struct utmp *utmp_entry) +{ + struct utmp *utmp; + + if (ut_fd == -1) + setutent(); + if (ut_fd == -1) + return NULL; + + while ((utmp = __getutent(ut_fd)) != NULL) { + if ((utmp_entry->ut_type == RUN_LVL || + utmp_entry->ut_type == BOOT_TIME || + utmp_entry->ut_type == NEW_TIME || + utmp_entry->ut_type == OLD_TIME) && + utmp->ut_type == utmp_entry->ut_type) return utmp; + if ((utmp_entry->ut_type == INIT_PROCESS || + utmp_entry->ut_type == DEAD_PROCESS || + utmp_entry->ut_type == LOGIN_PROCESS || + utmp_entry->ut_type == USER_PROCESS) && + !strcmp(utmp->ut_id, utmp_entry->ut_id)) return utmp; + } + + return NULL; +} + +struct utmp *getutline(struct utmp *utmp_entry) +{ + struct utmp *utmp; + + if (ut_fd == -1) + setutent(); + if (ut_fd == -1) + return NULL; + +#if 0 + /* This is driving me nuts. It's not an implementation problem - + it's a matter of how things _SHOULD_ behave. Groan. */ + lseek(ut_fd, SEEK_CUR, -sizeof(struct utmp)); +#endif + + while ((utmp = __getutent(ut_fd)) != NULL) { + if ((utmp->ut_type == USER_PROCESS || + utmp->ut_type == LOGIN_PROCESS) && + !strcmp(utmp->ut_line, utmp_entry->ut_line)) return utmp; + } + + return NULL; +} + +struct utmp *pututline(struct utmp *utmp_entry) +{ + struct utmp *ut; + + /* Ignore the return value. That way, if they've already positioned + the file pointer where they want it, everything will work out. */ + (void) lseek(ut_fd, (off_t) - sizeof(utmp_entry), SEEK_CUR); + + if ((ut = getutid(utmp_entry)) != NULL) { + lseek(ut_fd, (off_t) - sizeof(utmp_entry), SEEK_CUR); + if (write(ut_fd, (char *) utmp_entry, sizeof(utmp_entry)) + != sizeof(utmp_entry)) + return NULL; + } else { + lseek(ut_fd, (off_t) 0, SEEK_END); + if (write(ut_fd, (char *) utmp_entry, sizeof(utmp_entry)) + != sizeof(utmp_entry)) + return NULL; + } + + return utmp_entry; +} + +void utmpname(const char *new_ut_name) +{ + if (new_ut_name != NULL) + ut_name = new_ut_name; + + if (ut_fd != -1) + close(ut_fd); +} |