123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 |
- /* 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 <stdio.h>
- #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_RDWR)) < 0) {
- 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 (const 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(const 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 (const 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(struct utmp), SEEK_CUR);
- if ((ut = getutid(utmp_entry)) != NULL) {
- lseek(ut_fd, (off_t) - sizeof(struct utmp), SEEK_CUR);
- if (write(ut_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
- return NULL;
- } else {
- lseek(ut_fd, (off_t) 0, SEEK_END);
- if (write(ut_fd, utmp_entry, sizeof(struct utmp)) != sizeof(struct utmp))
- return NULL;
- }
- return (struct utmp *)utmp_entry;
- }
- int utmpname (const char *new_ut_name)
- {
- if (new_ut_name != NULL)
- ut_name = new_ut_name;
- if (ut_fd != -1)
- close(ut_fd);
- return 0;
- }
- extern void updwtmp(const char *wtmp_file, const struct utmp *ut)
- {
- int fd;
- fd = open(wtmp_file, O_APPEND | O_WRONLY, 0);
- if (fd >= 0) {
- write(fd, (const char *) ut, sizeof(*ut));
- close(fd);
- }
- }
|