runit

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

utmpset.c (2867B)


      1 #include <fcntl.h>
      2 #include <time.h>
      3 #include <sys/types.h>
      4 #include <sys/stat.h>
      5 #include <unistd.h>
      6 #include <string.h>
      7 #include <utmp.h>
      8 #include "strerr.h"
      9 #include "sgetopt.h"
     10 #include "seek.h"
     11 #include "str.h"
     12 #include "open.h"
     13 #include "byte.h"
     14 #include "lock.h"
     15 
     16 #define USAGE " [-w] line"
     17 #define FATAL "utmpset: fatal: "
     18 #define WARNING "utmpset: warning: "
     19 
     20 static const char *progname;
     21 
     22 static void usage(void) { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
     23 
     24 static int utmp_logout(const char *line)
     25 {
     26   int fd;
     27   struct utmp ut;
     28   time_t t;
     29   int ok =-1;
     30 
     31   if ((fd =open(UTMP_FILE, O_RDWR, 0)) < 0)
     32     strerr_die4sys(111, FATAL, "unable to open ", UTMP_FILE, ": ");
     33   if (lock_ex(fd) == -1)
     34     strerr_die4sys(111, FATAL, "unable to lock: ", UTMP_FILE, ": ");
     35 
     36   while (read(fd, &ut, sizeof(struct utmp)) == sizeof(struct utmp)) {
     37     if (!ut.ut_name[0] || (str_diff(ut.ut_line, line) != 0)) continue;
     38     memset(ut.ut_name, 0, sizeof ut.ut_name);
     39     memset(ut.ut_host, 0, sizeof ut.ut_host);
     40     if (time(&t) == -1) break;
     41     ut.ut_time = t;
     42 #ifdef DEAD_PROCESS
     43     ut.ut_type =DEAD_PROCESS;
     44 #endif
     45     if (lseek(fd, -(off_t)sizeof(struct utmp), SEEK_CUR) == -1) break;
     46     if (write(fd, &ut, sizeof(struct utmp)) != sizeof(struct utmp)) break;
     47     ok =1;
     48     break;
     49   }
     50   close(fd);
     51   return(ok);
     52 }
     53 static int wtmp_logout(const char *line)
     54 {
     55   int fd;
     56   int len;
     57   struct stat st;
     58   struct utmp ut;
     59   time_t t;
     60 
     61   if ((fd = open_append(WTMP_FILE)) == -1)
     62     strerr_die4sys(111, FATAL, "unable to open ", WTMP_FILE, ": ");
     63   if (lock_ex(fd) == -1)
     64     strerr_die4sys(111, FATAL, "unable to lock ", WTMP_FILE, ": ");
     65 
     66   if (fstat(fd, &st) == -1) {
     67     close(fd);
     68     return(-1);
     69   }
     70   memset(&ut, 0, sizeof(struct utmp));
     71   if ((len =str_len(line)) > sizeof ut.ut_line) len =sizeof ut.ut_line -2;
     72   byte_copy(ut.ut_line, len, line);
     73   if (time(&t) == -1) {
     74     close(fd);
     75     return(-1);
     76   }
     77   ut.ut_time = t;
     78 #ifdef DEAD_PROCESS
     79   ut.ut_type =DEAD_PROCESS;
     80 #endif
     81   if (write(fd, &ut, sizeof(struct utmp)) != sizeof(struct utmp)) {
     82     ftruncate(fd, st.st_size);
     83     close(fd);
     84     return(-1);
     85   }
     86   close(fd);
     87   return(1);
     88 }
     89 
     90 int main (int argc, const char * const *argv, const char * const *envp)
     91 {
     92   int opt;
     93   int wtmp =0;
     94 
     95   progname =*argv;
     96 
     97   while ((opt =getopt(argc, argv, "wV")) != opteof) {
     98     switch(opt) {
     99     case 'w':
    100       wtmp =1;
    101       break;
    102     case 'V':
    103       strerr_warn1(VERSION, 0);
    104       __attribute__((fallthrough));
    105     case '?':
    106       usage();
    107     }
    108   }
    109   argv +=optind;
    110 
    111   if (! argv || ! *argv) usage();
    112   if (utmp_logout(*argv) == -1)
    113     strerr_die4x(111, WARNING, "unable to logout line ", *argv,
    114                  " in utmp: no such entry");
    115   if (wtmp)
    116     if (wtmp_logout(*argv) == -1)
    117       strerr_die4sys(111, WARNING,
    118                      "unable to logout line ", *argv, " in wtmp: ");
    119   _exit(0);
    120 }