Use utmpx instead of utmp

If your utmp files are generated with programs linked against glibc
then musl-libc might not be able to parse the records correctly.  This is
because the fields `ut_session' and `ut_tv' must be the same size when
compiled in x86 and x86_64.  This is a requirement by glibc that musl does
not fulfil for good reasons.
This commit is contained in:
sin 2013-10-08 16:15:08 +01:00
parent c0ae036bd2
commit 85a0e49c33

View File

@ -4,7 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <utmp.h> #include <utmpx.h>
#include "util.h" #include "util.h"
static void static void
@ -16,13 +16,14 @@ usage(void)
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
struct utmp usr; struct utmpx utx;
FILE *ufp; FILE *ufp;
struct sysinfo info; struct sysinfo info;
time_t tmptime; time_t tmptime;
struct tm *now; struct tm *now;
unsigned int days, hours, minutes; unsigned int days, hours, minutes;
int nusers = 0; int nusers = 0;
size_t n;
ARGBEGIN { ARGBEGIN {
default: default:
@ -47,14 +48,15 @@ main(int argc, char *argv[])
printf("%d min, ", minutes); printf("%d min, ", minutes);
if ((ufp = fopen("/var/run/utmp", "r"))) { if ((ufp = fopen("/var/run/utmp", "r"))) {
while(fread(&usr, sizeof(usr), 1, ufp) == 1) { while ((n = fread(&utx, sizeof(utx), 1, ufp)) > 0) {
if (!*usr.ut_name || !*usr.ut_line || if (!utx.ut_user[0])
usr.ut_line[0] == '~')
continue; continue;
if (strcmp(usr.ut_name, "LOGIN") == 0) if (utx.ut_type != USER_PROCESS)
continue; continue;
nusers++; nusers++;
} }
if (ferror(ufp))
eprintf("/var/run/utmp: read error:");
fclose(ufp); fclose(ufp);
printf(" %d user%s, ", nusers, nusers > 1 ? "s" : ""); printf(" %d user%s, ", nusers, nusers > 1 ? "s" : "");
} }