summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/include/utmps/utmps.h2
-rw-r--r--src/include/utmps/utmpx.h10
-rw-r--r--src/utmps/deps-exe/utmps-write6
-rw-r--r--src/utmps/utmps-write.c149
-rw-r--r--src/utmps/utmps_getid.c5
-rw-r--r--src/utmps/utmps_getline.c5
6 files changed, 169 insertions, 8 deletions
diff --git a/src/include/utmps/utmps.h b/src/include/utmps/utmps.h
index 9894276..cc60e9d 100644
--- a/src/include/utmps/utmps.h
+++ b/src/include/utmps/utmps.h
@@ -27,7 +27,7 @@ extern int utmps_getid (utmps *, unsigned short, char const *, struct utmpx *, t
extern int utmps_getline (utmps *, char const *, struct utmpx *, tain const *, tain *) ;
#define utmps_getline_g(a, line, b, deadline) utmps_getline(a, line, b, (deadline), &STAMP)
extern int utmps_putline (utmps *, struct utmpx const *, tain const *, tain *) ;
-#define utmps_putline_g(a, entry, deadline) utmps_putline(a, entry, (deadine), &STAMP)
+#define utmps_putline_g(a, entry, deadline) utmps_putline(a, entry, (deadline), &STAMP)
extern int utmps_updwtmpx (char const *, struct utmpx const *, tain const *, tain *) ;
#define utmps_updwtmpx_g(file, b, deadline) utmps_updwtmpx(file, b, (deadline), &STAMP)
diff --git a/src/include/utmps/utmpx.h b/src/include/utmps/utmpx.h
index 0af2fac..8fa6dd2 100644
--- a/src/include/utmps/utmpx.h
+++ b/src/include/utmps/utmpx.h
@@ -26,18 +26,18 @@ struct utmpx
{
short ut_type ;
pid_t ut_pid ;
- char ut_line[UTMPS_UT_LINESIZE] ;
- char ut_id[UTMPS_UT_IDSIZE] ;
- char ut_user[UTMPS_UT_NAMESIZE] ;
+ char ut_line[UTMPS_UT_LINESIZE] __attribute__((nonstring)) ;
+ char ut_id[UTMPS_UT_IDSIZE] __attribute__((nonstring)) ;
+ char ut_user[UTMPS_UT_NAMESIZE] __attribute__((nonstring)) ;
- char ut_host[UTMPS_UT_HOSTSIZE] ;
+ char ut_host[UTMPS_UT_HOSTSIZE] __attribute__((nonstring)) ;
struct exit_status ut_exit ;
pid_t ut_session ;
struct timeval ut_tv ;
uint32_t ut_addr_v6[4] ;
- char _dummy[20] ;
+ char _dummy[20] __attribute__((nonstring)) ;
} ;
#define EMPTY 0
diff --git a/src/utmps/deps-exe/utmps-write b/src/utmps/deps-exe/utmps-write
new file mode 100644
index 0000000..bdb0ac9
--- /dev/null
+++ b/src/utmps/deps-exe/utmps-write
@@ -0,0 +1,6 @@
+libutmps.a.xyzzy
+${LIBNSSS}
+-lskarnet
+${SOCKET_LIB}
+#{SYSCLOCK_LIB}
+${MAYBEPTHREAD_LIB}
diff --git a/src/utmps/utmps-write.c b/src/utmps/utmps-write.c
new file mode 100644
index 0000000..061a0be
--- /dev/null
+++ b/src/utmps/utmps-write.c
@@ -0,0 +1,149 @@
+/* ISC license. */
+
+#include <unistd.h>
+#include <string.h>
+#include <strings.h>
+#include <stdlib.h>
+#include <pwd.h>
+
+#include <skalibs/sgetopt.h>
+#include <skalibs/strerr2.h>
+#include <skalibs/types.h>
+#include <skalibs/tai.h>
+#include <skalibs/fmtscan.h>
+
+#include <utmps/config.h>
+#include <utmps/utmps.h>
+#include <utmps/utmpx.h>
+
+#define USAGE "utmps-write [ -u ] [ -w ] [ -U utmpd-socket ] [ -W wtmpd-socket ] [ -t timeout ] [ -T timestamp ] [ -h host ] [ -i ip ] [ -l user ] [ -p pid ] id type line"
+#define dieusage() strerr_dieusage(100, USAGE)
+
+typedef struct uttype_s uttype, *uttype_ref ;
+struct uttype_s
+{
+ char const *s ;
+ short type ;
+} ;
+
+static uttype const uttypes[] =
+{
+ { "ACCOUNTING", 9 },
+ { "BOOT_TIME", 2 },
+ { "DEAD_PROCESS", 8 },
+ { "EMPTY", 0 },
+ { "INIT_PROCESS", 5 },
+ { "LOGIN_PROCESS", 6 },
+ { "NEW_TIME", 3 },
+ { "OLD_TIME", 4 },
+ { "RUN_LVL", 1 },
+ { "USER_PROCESS", 7 }
+} ;
+
+static int uttype_cmp (void const *a, void const *b)
+{
+ char const *key = a ;
+ uttype const *element = b ;
+ return strcasecmp(key, element->s) ;
+}
+
+int main (int argc, char const *const *argv)
+{
+ char const *usocket = UTMPS_UTMPD_PATH ;
+ char const *wsocket = UTMPS_WTMPD_PATH ;
+ char const *stamp = 0 ;
+ char const *user = 0 ;
+ char const *ipstr = 0 ;
+ unsigned int what = 0 ;
+ tain tto ;
+ struct utmpx b ;
+ PROG = "utmps-write" ;
+ memset(&b, 0, sizeof(struct utmpx)) ;
+ b.ut_pid = -1 ;
+
+ {
+ unsigned int t = 0 ;
+ subgetopt l = SUBGETOPT_ZERO ;
+ for (;;)
+ {
+ int opt = subgetopt_r(argc, argv, "uwU:W:t:T:h:i:l:p:", &l) ;
+ if (opt == -1) break ;
+ switch (opt)
+ {
+ case 'u' : what |= 1 ; break ;
+ case 'w' : what |= 2 ; break ;
+ case 'U' : usocket = l.arg ; break ;
+ case 'W' : wsocket = l.arg ; break ;
+ case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
+ case 'T' : stamp = l.arg ; break ;
+ case 'h' : strncpy(b.ut_host, l.arg, UTMPS_UT_HOSTSIZE) ; break ;
+ case 'i' : ipstr = l.arg ; break ;
+ case 'l' : user = l.arg ; break ;
+ case 'p' : if (!pid0_scan(l.arg, &b.ut_pid)) dieusage() ; break ;
+ default : dieusage() ;
+ }
+ }
+ argc -= l.ind ; argv += l.ind ;
+ if (t) tain_from_millisecs(&tto, t) ;
+ else tto = tain_infinite_relative ;
+ }
+ if (argc < 3) dieusage() ;
+ if (!what) strerr_dief1x(100, "at least one of -u or -w must be used") ;
+
+ {
+ uttype const *p = bsearch(argv[1], uttypes, sizeof(uttypes) / sizeof(uttype), sizeof(uttype), &uttype_cmp) ;
+ if (!p) strerr_dief2x(100, "invalid ut_type: ", argv[1]) ;
+ b.ut_type = p->type ;
+ }
+ strncpy(b.ut_id, argv[0], UTMPS_UT_IDSIZE) ;
+ strncpy(b.ut_line, argv[2], UTMPS_UT_LINESIZE) ;
+ if (ipstr)
+ {
+ /* ut_addr_v6 is in host byte order, don't ask */
+ size_t len = ip6_scan(ipstr, (char *)b.ut_addr_v6) ;
+ if (!len || ipstr[len])
+ {
+ len = ip4_scan(ipstr, (char *)b.ut_addr_v6) ;
+ if (!len || ipstr[len])
+ strerr_dief2x(100, "invalid IP address: ", ipstr) ;
+ }
+ }
+ if (b.ut_pid == -1) b.ut_pid = getpid() ;
+ if (user) strncpy(b.ut_user, user, UTMPS_UT_NAMESIZE) ;
+ else
+ {
+ struct passwd *pw = getpwuid(getuid()) ;
+ if (pw) strncpy(b.ut_user, pw->pw_name, UTMPS_UT_NAMESIZE) ;
+ }
+ tain_now_set_stopwatch_g() ;
+ tain_add_g(&tto, &tto) ;
+ {
+ tain when ;
+ if (stamp)
+ {
+ size_t n = timestamp_scan(stamp, &when) ;
+ if (!n || stamp[n]) dieusage() ;
+ }
+ else when = STAMP ;
+ if (!timeval_from_tain(&b.ut_tv, &when))
+ strerr_diefu1sys(111, "timeval_from_tain") ;
+ }
+
+ if (what & 1)
+ {
+ utmps a = UTMPS_ZERO ;
+ if (!utmps_start_g(&a, usocket, &tto))
+ strerr_diefu2sys(111, "connect to utmpd at ", usocket) ;
+ if (!utmps_putline_g(&a, &b, &tto))
+ strerr_diefu1sys(111, "write utmp entry") ;
+ utmps_end(&a) ;
+ }
+
+ if (what & 2)
+ {
+ if (!utmps_updwtmpx_g(wsocket, &b, &tto))
+ strerr_diefu2sys(111, "write wtmp entry via wtmpd at ", wsocket) ;
+ }
+
+ return 0 ;
+}
diff --git a/src/utmps/utmps_getid.c b/src/utmps/utmps_getid.c
index 90e7d2a..a341149 100644
--- a/src/utmps/utmps_getid.c
+++ b/src/utmps/utmps_getid.c
@@ -3,8 +3,11 @@
#include <sys/types.h>
#include <string.h>
#include <errno.h>
+
+#include <skalibs/gccattributes.h>
#include <skalibs/types.h>
#include <skalibs/unix-timed.h>
+
#include <utmps/utmpx.h>
#include <utmps/utmps.h>
#include "utmps-internal.h"
@@ -12,7 +15,7 @@
int utmps_getid (utmps *a, unsigned short type, char const *id, struct utmpx *b, tain const *deadline, tain *stamp)
{
ssize_t r ;
- char sbuf[1 + USHORT_PACK + UTMPS_UT_IDSIZE] __attribute__ ((nonstring)) ;
+ char sbuf[1 + USHORT_PACK + UTMPS_UT_IDSIZE] gccattr_nonstring ;
char rbuf[1 + sizeof(struct utmpx)] ;
sbuf[0] = 'i' ;
ushort_pack_big(sbuf + 1, type) ;
diff --git a/src/utmps/utmps_getline.c b/src/utmps/utmps_getline.c
index 6375f5d..5026788 100644
--- a/src/utmps/utmps_getline.c
+++ b/src/utmps/utmps_getline.c
@@ -3,7 +3,10 @@
#include <sys/types.h>
#include <string.h>
#include <errno.h>
+
+#include <skalibs/gccattributes.h>
#include <skalibs/unix-timed.h>
+
#include <utmps/utmpx.h>
#include <utmps/utmps.h>
#include "utmps-internal.h"
@@ -11,7 +14,7 @@
int utmps_getline (utmps *a, char const *line, struct utmpx *b, tain const *deadline, tain *stamp)
{
ssize_t r ;
- char sbuf[1 + UTMPS_UT_LINESIZE] __attribute__ ((nonstring)) ;
+ char sbuf[1 + UTMPS_UT_LINESIZE] gccattr_nonstring ;
char rbuf[1 + sizeof(struct utmpx)] ;
sbuf[0] = 'l' ;
strncpy(sbuf + 1, line, UTMPS_UT_LINESIZE) ;