From d838c7b80a5f7d9df8415483236bf2ec773cbecd Mon Sep 17 00:00:00 2001 From: Laurent Bercot Date: Sun, 19 Dec 2021 06:27:36 +0000 Subject: Prepare for 0.1.1.0, add utmps-write Signed-off-by: Laurent Bercot --- src/include/utmps/utmps.h | 2 +- src/include/utmps/utmpx.h | 10 +-- src/utmps/deps-exe/utmps-write | 6 ++ src/utmps/utmps-write.c | 149 +++++++++++++++++++++++++++++++++++++++++ src/utmps/utmps_getid.c | 5 +- src/utmps/utmps_getline.c | 5 +- 6 files changed, 169 insertions(+), 8 deletions(-) create mode 100644 src/utmps/deps-exe/utmps-write create mode 100644 src/utmps/utmps-write.c (limited to 'src') 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 +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include +#include +#include + +#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 #include #include + +#include #include #include + #include #include #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 #include #include + +#include #include + #include #include #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) ; -- cgit 1.4.1