diff options
author | Robert de Bath <rdebath@poboxes.com> | 1996-03-24 21:25:23 +0100 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2013-10-23 23:29:54 +0200 |
commit | dcc973ea3e31710429858c99d4f040334ac67c06 (patch) | |
tree | 8883b902eb18eba489957b7f03caa491fd7992a7 /libc/utmp/utent.c | |
parent | fe22c37817ce338fbbc90b239320248c270957fa (diff) | |
download | dev86-dcc973ea3e31710429858c99d4f040334ac67c06.tar.gz |
Import Dev86-0.0.5.tar.gzv0.0.5
Diffstat (limited to 'libc/utmp/utent.c')
-rw-r--r-- | libc/utmp/utent.c | 152 |
1 files changed, 152 insertions, 0 deletions
diff --git a/libc/utmp/utent.c b/libc/utmp/utent.c new file mode 100644 index 0000000..7f9e19a --- /dev/null +++ b/libc/utmp/utent.c @@ -0,0 +1,152 @@ +/* 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); +} + + |