Make utmp-handling more standards-compliant.
As utmpx is standardized by POSIX, first attempt to access the utmpx database using the standard getutxent() function. If we don't have utmpx, fall back to some simple utmp code that accesses the database manually. This code has been compile-tested on FreeBSD 8 (utmp), FreeBSD 9 (utmpx) and Ubuntu Linux 11.10 (utmpx).
This commit is contained in:
parent
edf041dc7a
commit
67b476efe0
|
@ -74,7 +74,7 @@ case $host_os in
|
|||
esac
|
||||
AC_MSG_RESULT([$SRC_OS])
|
||||
|
||||
AC_CHECK_HEADERS(libproc.h valgrind/valgrind.h)
|
||||
AC_CHECK_HEADERS(utmp.h utmpx.h libproc.h valgrind/valgrind.h)
|
||||
if test $ac_cv_header_libproc_h = yes; then
|
||||
AC_DEFINE(DARWIN_HAS_LIBPROC_H, [1], [sigar named them DARWIN_HAS_... instead of HAVE_])
|
||||
fi
|
||||
|
|
136
src/sigar.c
136
src/sigar.c
|
@ -30,6 +30,11 @@
|
|||
#ifndef WIN32
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#if defined(HAVE_UTMPX_H)
|
||||
# include <utmpx.h>
|
||||
#elif defined(HAVE_UTMP_H)
|
||||
# include <utmp.h>
|
||||
#endif
|
||||
|
||||
#include "sigar.h"
|
||||
#include "sigar_private.h"
|
||||
|
@ -1024,40 +1029,7 @@ SIGAR_DECLARE(int) sigar_who_list_destroy(sigar_t *sigar,
|
|||
return SIGAR_OK;
|
||||
}
|
||||
|
||||
#ifdef DARWIN
|
||||
#include <AvailabilityMacros.h>
|
||||
#endif
|
||||
#ifdef MAC_OS_X_VERSION_10_5
|
||||
# if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
|
||||
# define SIGAR_NO_UTMP
|
||||
# endif
|
||||
/* else 10.4 and earlier or compiled with -mmacosx-version-min=10.3 */
|
||||
#endif
|
||||
|
||||
#if defined(__sun)
|
||||
# include <utmpx.h>
|
||||
# define SIGAR_UTMP_FILE _UTMPX_FILE
|
||||
# define ut_time ut_tv.tv_sec
|
||||
#elif defined(WIN32)
|
||||
/* XXX may not be the default */
|
||||
#define SIGAR_UTMP_FILE "C:\\cygwin\\var\\run\\utmp"
|
||||
#define UT_LINESIZE 16
|
||||
#define UT_NAMESIZE 16
|
||||
#define UT_HOSTSIZE 256
|
||||
#define UT_IDLEN 2
|
||||
#define ut_name ut_user
|
||||
|
||||
struct utmp {
|
||||
short ut_type;
|
||||
int ut_pid;
|
||||
char ut_line[UT_LINESIZE];
|
||||
char ut_id[UT_IDLEN];
|
||||
time_t ut_time;
|
||||
char ut_user[UT_NAMESIZE];
|
||||
char ut_host[UT_HOSTSIZE];
|
||||
long ut_addr;
|
||||
};
|
||||
#elif defined(NETWARE)
|
||||
#if defined(NETWARE)
|
||||
static char *getpass(const char *prompt)
|
||||
{
|
||||
static char password[BUFSIZ];
|
||||
|
@ -1067,109 +1039,48 @@ static char *getpass(const char *prompt)
|
|||
|
||||
return (char *)&password;
|
||||
}
|
||||
#elif !defined(SIGAR_NO_UTMP)
|
||||
# include <utmp.h>
|
||||
# ifdef UTMP_FILE
|
||||
# define SIGAR_UTMP_FILE UTMP_FILE
|
||||
# else
|
||||
# define SIGAR_UTMP_FILE _PATH_UTMP
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(DARWIN)
|
||||
# define ut_user ut_name
|
||||
#endif
|
||||
|
||||
#ifdef DARWIN
|
||||
/* XXX from utmpx.h; sizeof changed in 10.5 */
|
||||
/* additionally, utmpx does not work on 10.4 */
|
||||
#define SIGAR_HAS_UTMPX
|
||||
#define _PATH_UTMPX "/var/run/utmpx"
|
||||
#define _UTX_USERSIZE 256 /* matches MAXLOGNAME */
|
||||
#define _UTX_LINESIZE 32
|
||||
#define _UTX_IDSIZE 4
|
||||
#define _UTX_HOSTSIZE 256
|
||||
struct utmpx {
|
||||
char ut_user[_UTX_USERSIZE]; /* login name */
|
||||
char ut_id[_UTX_IDSIZE]; /* id */
|
||||
char ut_line[_UTX_LINESIZE]; /* tty name */
|
||||
pid_t ut_pid; /* process id creating the entry */
|
||||
short ut_type; /* type of this entry */
|
||||
struct timeval ut_tv; /* time entry was created */
|
||||
char ut_host[_UTX_HOSTSIZE]; /* host name */
|
||||
__uint32_t ut_pad[16]; /* reserved for future use */
|
||||
};
|
||||
#define ut_xtime ut_tv.tv_sec
|
||||
#define UTMPX_USER_PROCESS 7
|
||||
/* end utmpx.h */
|
||||
#define SIGAR_UTMPX_FILE _PATH_UTMPX
|
||||
#endif
|
||||
|
||||
#if !defined(NETWARE) && !defined(_AIX)
|
||||
|
||||
#define WHOCPY(dest, src) \
|
||||
SIGAR_SSTRCPY(dest, src); \
|
||||
if (sizeof(src) < sizeof(dest)) \
|
||||
dest[sizeof(src)] = '\0'
|
||||
|
||||
#ifdef SIGAR_HAS_UTMPX
|
||||
static int sigar_who_utmpx(sigar_t *sigar,
|
||||
static int sigar_who_utmp(sigar_t *sigar,
|
||||
sigar_who_list_t *wholist)
|
||||
{
|
||||
FILE *fp;
|
||||
struct utmpx ut;
|
||||
#if defined(HAVE_UTMPX_H)
|
||||
struct utmpx *ut;
|
||||
|
||||
if (!(fp = fopen(SIGAR_UTMPX_FILE, "r"))) {
|
||||
return errno;
|
||||
}
|
||||
setutxent();
|
||||
|
||||
while (fread(&ut, sizeof(ut), 1, fp) == 1) {
|
||||
while ((ut = getutxent()) != NULL) {
|
||||
sigar_who_t *who;
|
||||
|
||||
if (*ut.ut_user == '\0') {
|
||||
if (*ut->ut_user == '\0') {
|
||||
continue;
|
||||
}
|
||||
|
||||
#ifdef UTMPX_USER_PROCESS
|
||||
if (ut.ut_type != UTMPX_USER_PROCESS) {
|
||||
if (ut->ut_type != USER_PROCESS) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
|
||||
SIGAR_WHO_LIST_GROW(wholist);
|
||||
who = &wholist->data[wholist->number++];
|
||||
|
||||
WHOCPY(who->user, ut.ut_user);
|
||||
WHOCPY(who->device, ut.ut_line);
|
||||
WHOCPY(who->host, ut.ut_host);
|
||||
WHOCPY(who->user, ut->ut_user);
|
||||
WHOCPY(who->device, ut->ut_line);
|
||||
WHOCPY(who->host, ut->ut_host);
|
||||
|
||||
who->time = ut.ut_xtime;
|
||||
who->time = ut->ut_tv.tv_sec;
|
||||
}
|
||||
|
||||
fclose(fp);
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SIGAR_NO_UTMP) && defined(SIGAR_HAS_UTMPX)
|
||||
#define sigar_who_utmp sigar_who_utmpx
|
||||
#else
|
||||
static int sigar_who_utmp(sigar_t *sigar,
|
||||
sigar_who_list_t *wholist)
|
||||
{
|
||||
endutxent();
|
||||
#elif defined(HAVE_UTMP_H)
|
||||
FILE *fp;
|
||||
#ifdef __sun
|
||||
/* use futmpx w/ pid32_t for sparc64 */
|
||||
struct futmpx ut;
|
||||
#else
|
||||
struct utmp ut;
|
||||
#endif
|
||||
if (!(fp = fopen(SIGAR_UTMP_FILE, "r"))) {
|
||||
#ifdef SIGAR_HAS_UTMPX
|
||||
/* Darwin 10.5 */
|
||||
return sigar_who_utmpx(sigar, wholist);
|
||||
#endif
|
||||
|
||||
if (!(fp = fopen(_PATH_UTMP, "r"))) {
|
||||
return errno;
|
||||
}
|
||||
|
||||
|
@ -1189,7 +1100,7 @@ static int sigar_who_utmp(sigar_t *sigar,
|
|||
SIGAR_WHO_LIST_GROW(wholist);
|
||||
who = &wholist->data[wholist->number++];
|
||||
|
||||
WHOCPY(who->user, ut.ut_user);
|
||||
WHOCPY(who->user, ut.ut_name);
|
||||
WHOCPY(who->device, ut.ut_line);
|
||||
WHOCPY(who->host, ut.ut_host);
|
||||
|
||||
|
@ -1197,11 +1108,10 @@ static int sigar_who_utmp(sigar_t *sigar,
|
|||
}
|
||||
|
||||
fclose(fp);
|
||||
#endif
|
||||
|
||||
return SIGAR_OK;
|
||||
}
|
||||
#endif /* SIGAR_NO_UTMP */
|
||||
#endif /* NETWARE */
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
|
|
Loading…
Reference in New Issue