#ifndef _STRUCT_UTMPX_H_
#define _STRUCT_UTMPX_H_

#include "config.h"
#include "includes.h"

/*
 * utmpx-wrapper.h:
 *
 * this is a generic wrapper around the utmpx/utmp functionality
 * that wuzzah needs in order to function.  based on the results
 * of configure, it will try and use whatever functionality the
 * system might have wrt utmpx.  of course it's ugly as all fucking
 * hell, but this is the price to pay for having the rest of the code
 * be completely portable (that is, the stuff that doesn't port easily
 * is isolated)
 *
 */


/*
 * first, let's cover the functions.  if they have utmpx, we're golden,
 * otherwise depending on the level of support we get we're going to have
 * to rely on possibly more of our own homegrown shit.
 */
#ifdef HAVE_UTMPX_H 

# define STRUCT_UTMPX struct utmpx
# define SETUTXENT() setutxent()
# define GETUTXENT() getutxent()
# define ENDUTXENT() endutxent()
# define IS_USER_PROCESS(u) ((u)->ut_type == USER_PROCESS)

#else
# ifdef HAVE_UTMP_H // if they have utmp, things might "just work"

#  define STRUCT_UTMPX struct utmp
#  define SETUTXENT() setutent_wrapper()
#  define GETUTXENT() getutent_wrapper()
#  define ENDUTXENT() endutent_wrapper()

# else // they don't HAVE_UTMP_H
#  error you need utmpx or utmp support to compile wuzzah!
#endif // HAVE_UTMP_H
#endif // HAVE_UTMPX_H


/*
 * Next, let's deal with data members.  this is going to be
 * a little uglier.
 */
#ifdef HAVE_UTMPX_H

#  ifdef HAVE_STRUCT_UTMPX_UT_TYPE
#    define IS_USER_PROCESS(u) ((u)->ut_type == USER_PROCESS)
#  else
#    define IS_USER_PROCESS(u) (1)
#  endif // HAVE_STRUCT_UTMPX_UT_TYPE

#  ifndef HAVE_STRUCT_UTMPX_UT_USER
#    define ut_user ut_name
#  endif // HAVE_STRUCT_UTMPX_UT_USER

#  ifdef HAVE_STRUCT_UTMPX_UT_HOST
#    define UTMPX_HOSTNAME(u) ((u)->ut_host)
#    ifdef HAVE_STRUCT_UTMPX_UT_SYSLEN
#      define UTMPX_HOSTLEN(u) ((u)->ut_syslen)
#    else
#      define UTMPX_HOSTLEN(u) (strlen((u)->ut_host))
#    endif // HAVE_STRUCT_UTMPX_UT_SYSLEN
#  else
#    define UTMPX_HOSTNAME(u) "hostname not retrievable"
#    define UTMPX_HOSTLEN(u) (strlen("hostname not retrievable"))
#  endif // HAVE_STRUCT_UTMPX_UT_HOST

#else
#ifdef HAVE_UTMP_H

#  ifdef HAVE_STRUCT_UTMP_UT_TYPE
#    define IS_USER_PROCESS(u) ((u)->ut_type == USER_PROCESS)
#  else
#    define IS_USER_PROCESS(u) (1)
#  endif // HAVE_STRUCT_UTMP_UT_TYPE

#  ifndef HAVE_STRUCT_UTMP_UT_USER
#    define ut_user ut_name
#  endif // HAVE_STRUCT_UTMP_UT_USER

#  ifdef HAVE_STRUCT_UTMP_UT_HOST
#    define UTMPX_HOSTNAME(u) ((u)->ut_host)
#    ifdef HAVE_STRUCT_UTMP_UT_SYSLEN
#      define UTMPX_HOSTLEN(u) ((u)->ut_syslen)
#    else
#      define UTMPX_HOSTLEN(u) (strlen((u)->ut_host))
#    endif // HAVE_STRUCT_UTMP_UT_SYSLEN
#  else
#    define UTMPX_HOSTNAME(u) "hostname not retrievable"
#    define UTMPX_HOSTLEN(u) (strlen("hostname not retrievable"))
#  endif // HAVE_STRUCT_UTMP_UT_HOST

#endif // HAVE_UTMP_H
#endif // HAVE_UTMPX_H


void setutent_wrapper(void);
STRUCT_UTMPX *getutent_wrapper(void);
void endutent_wrapper(void);

#endif
