summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--NEWS8
-rw-r--r--package/deps.mak3
-rw-r--r--package/info2
-rw-r--r--package/modes1
-rw-r--r--package/targets.mak3
-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
11 files changed, 184 insertions, 10 deletions
diff --git a/NEWS b/NEWS
index 2c165e2..0298f9e 100644
--- a/NEWS
+++ b/NEWS
@@ -1,5 +1,13 @@
Changelog for utmps.
+In 0.1.1.0
+----------
+
+ - Bugfixes.
+ - New binary: utmps-write. It's a generic utmp client, writing
+user-defined records to the utmp and/or wtmp databases.
+
+
In 0.1.0.3
----------
diff --git a/package/deps.mak b/package/deps.mak
index 4093dd8..fa85734 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -14,6 +14,7 @@ src/utmps/pututxline.o src/utmps/pututxline.lo: src/utmps/pututxline.c src/utmps
src/utmps/setutxent.o src/utmps/setutxent.lo: src/utmps/setutxent.c src/utmps/utmps-internal.h src/include/utmps/utmps.h src/include/utmps/utmpx.h
src/utmps/updwtmpx.o src/utmps/updwtmpx.lo: src/utmps/updwtmpx.c src/include/utmps/config.h src/include/utmps/utmps.h
src/utmps/utmps-utmpd.o src/utmps/utmps-utmpd.lo: src/utmps/utmps-utmpd.c src/utmps/utmps-internal.h src/include/utmps/utmpx.h
+src/utmps/utmps-write.o src/utmps/utmps-write.lo: src/utmps/utmps-write.c src/include/utmps/config.h src/include/utmps/utmps.h src/include/utmps/utmpx.h
src/utmps/utmps-wtmpd.o src/utmps/utmps-wtmpd.lo: src/utmps/utmps-wtmpd.c src/utmps/utmps-internal.h src/include/utmps/utmpx.h
src/utmps/utmps_end.o src/utmps/utmps_end.lo: src/utmps/utmps_end.c src/include/utmps/utmps.h
src/utmps/utmps_getent.o src/utmps/utmps_getent.lo: src/utmps/utmps_getent.c src/utmps/utmps-internal.h src/include/utmps/utmps.h src/include/utmps/utmpx.h
@@ -38,5 +39,7 @@ libutmps.so.xyzzy: EXTRA_LIBS := -lskarnet
libutmps.so.xyzzy: src/utmps/endutxent.lo src/utmps/getutxent.lo src/utmps/getutxid.lo src/utmps/getutxline.lo src/utmps/logwtmp.lo src/utmps/pututxline.lo src/utmps/setutxent.lo src/utmps/updwtmpx.lo src/utmps/utmpxname.lo src/utmps/utmps_end.lo src/utmps/utmps_getent.lo src/utmps/utmps_getid.lo src/utmps/utmps_getline.lo src/utmps/utmps_here.lo src/utmps/utmps_here_maybe_init.lo src/utmps/utmps_putline.lo src/utmps/utmps_rewind.lo src/utmps/utmps_start.lo src/utmps/utmps_updwtmpx.lo src/utmps/utmps_utmpx_pack.lo src/utmps/utmps_utmpx_unpack.lo
utmps-utmpd: EXTRA_LIBS := -lskarnet ${MAYBEPTHREAD_LIB}
utmps-utmpd: src/utmps/utmps-utmpd.o libutmps.a.xyzzy ${LIBNSSS}
+utmps-write: EXTRA_LIBS := -lskarnet ${SOCKET_LIB} ${MAYBEPTHREAD_LIB}
+utmps-write: src/utmps/utmps-write.o libutmps.a.xyzzy ${LIBNSSS} #{SYSCLOCK_LIB}
utmps-wtmpd: EXTRA_LIBS := -lskarnet ${MAYBEPTHREAD_LIB}
utmps-wtmpd: src/utmps/utmps-wtmpd.o libutmps.a.xyzzy ${LIBNSSS}
diff --git a/package/info b/package/info
index 8c31b77..fc959f2 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=utmps
-version=0.1.0.3
+version=0.1.1.0
category=admin
package_macro_name=UTMPS
diff --git a/package/modes b/package/modes
index 39e777c..e0d2b24 100644
--- a/package/modes
+++ b/package/modes
@@ -1,2 +1,3 @@
utmps-utmpd 0755
utmps-wtmpd 0755
+utmps-write 0755
diff --git a/package/targets.mak b/package/targets.mak
index 3ff5217..1d68e83 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -1,6 +1,7 @@
BIN_TARGETS := \
utmps-utmpd \
-utmps-wtmpd
+utmps-wtmpd \
+utmps-write
LIBEXEC_TARGETS :=
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) ;