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 "uw_tmp.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 const char *progname;
21 
usage(void)22 void usage(void) { strerr_die4x(1, "usage: ", progname, USAGE, "\n"); }
23 
utmp_logout(const char * line)24 int utmp_logout(const char *line) {
25 
26 #ifdef _UW_TMP_UTMPX
27   int ok = 1; /* do_nada(); */
28 #else /* _UW_TMP_UTMP */
29 
30   int fd;
31   uw_tmp ut;
32   int ok =-1;
33 
34   if ((fd =open(UW_TMP_UFILE, O_RDWR, 0)) < 0)
35     strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_UFILE, ": ");
36   if (lock_ex(fd) == -1)
37     strerr_die4sys(111, FATAL, "unable to lock: ", UW_TMP_UFILE, ": ");
38 
39   while (read(fd, &ut, sizeof(uw_tmp)) == sizeof(uw_tmp)) {
40     if (!ut.ut_name[0] || (str_diff(ut.ut_line, line) != 0)) continue;
41     memset(ut.ut_name, 0, sizeof ut.ut_name);
42     memset(ut.ut_host, 0, sizeof ut.ut_host);
43     if (time(&ut.ut_time) == -1) break;
44 #ifdef DEAD_PROCESS
45     ut.ut_type =DEAD_PROCESS;
46 #endif
47     if (lseek(fd, -(off_t)sizeof(uw_tmp), SEEK_CUR) == -1) break;
48     if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) break;
49     ok =1;
50     break;
51   }
52   close(fd);
53 #endif /* _UW_TMP_UTMPX */
54   return(ok);
55 }
wtmp_logout(const char * line)56 int wtmp_logout(const char *line) {
57 #ifdef _UW_TMP_UTMPX
58   return 1; /* do_nada(); */
59 #else /* _UW_TMP_UTMP */
60   int fd;
61   int len;
62   struct stat st;
63   uw_tmp ut;
64 
65   if ((fd = open_append(UW_TMP_WFILE)) == -1)
66     strerr_die4sys(111, FATAL, "unable to open ", UW_TMP_WFILE, ": ");
67   if (lock_ex(fd) == -1)
68     strerr_die4sys(111, FATAL, "unable to lock ", UW_TMP_WFILE, ": ");
69 
70   if (fstat(fd, &st) == -1) {
71     close(fd);
72     return(-1);
73   }
74   memset(&ut, 0, sizeof(uw_tmp));
75   if ((len =str_len(line)) > sizeof ut.ut_line) len =sizeof ut.ut_line -2;
76   byte_copy(ut.ut_line, len, line);
77   if (time(&ut.ut_time) == -1) {
78     close(fd);
79     return(-1);
80   }
81 #ifdef DEAD_PROCESS
82   ut.ut_type =DEAD_PROCESS;
83 #endif
84   if (write(fd, &ut, sizeof(uw_tmp)) != sizeof(uw_tmp)) {
85     ftruncate(fd, st.st_size);
86     close(fd);
87     return(-1);
88   }
89   close(fd);
90   return(1);
91 #endif /* _UW_TMP_UTMPX */
92 }
93 
main(int argc,const char * const * argv,const char * const * envp)94 int main (int argc, const char * const *argv, const char * const *envp) {
95   int opt;
96   int wtmp =0;
97 
98   progname =*argv;
99 
100   while ((opt =getopt(argc, argv, "wV")) != opteof) {
101     switch(opt) {
102     case 'w':
103       wtmp =1;
104       break;
105     case 'V':
106       strerr_warn1("$Id: cb399098f794012a7f5e6a3a7090b2d53b86c08c $", 0);
107     case '?':
108       usage();
109     }
110   }
111   argv +=optind;
112 
113   if (! argv || ! *argv) usage();
114   if (utmp_logout(*argv) == -1)
115     strerr_die4x(111, WARNING, "unable to logout line ", *argv,
116                  " in utmp: no such entry");
117   if (wtmp)
118     if (wtmp_logout(*argv) == -1)
119       strerr_die4sys(111, WARNING,
120                      "unable to logout line ", *argv, " in wtmp: ");
121   _exit(0);
122 }
123