Example #1
0
int
get_boottime(struct timeval *tv)
{
    struct utmpx *ut, key;

    memset(&key, 0, sizeof(key));
    key.ut_type = BOOT_TIME;
    if ((ut = getutxid(&key)) != NULL) {
	tv->tv_sec = ut->ut_tv.tv_sec;
	tv->tv_usec = ut->ut_tv.tv_usec;
	endutxent();
    }
    return ut != NULL;
}
Example #2
0
static void
utmpx_write_entry(short type, const char *msg, time_t tstamp)
{
	struct utmpx u;
	struct utmpx *oup;
	size_t tmplen;

	bzero(&u, sizeof (struct utmpx));

	u.ut_id[0] = u.ut_id[1] = u.ut_id[2] = u.ut_id[3] = '\0';
	u.ut_pid = 0;

	u.ut_exit.e_termination = WTERMSIG(0);
	u.ut_exit.e_exit = WEXITSTATUS(0);
	u.ut_type = type;
	u.ut_tv.tv_sec = tstamp;

	MUTEX_LOCK(&utmpx_lock);
	setutxent();

	if ((oup = getutxid(&u)) != NULL) {
		bcopy(oup->ut_user, u.ut_user, sizeof (u.ut_user));
		bcopy(oup->ut_line, u.ut_line, sizeof (u.ut_line));
		bcopy(oup->ut_host, u.ut_host, sizeof (u.ut_host));

		tmplen = strlen(u.ut_host);
		if (tmplen)
			u.ut_syslen = min(tmplen + 1, sizeof (u.ut_host));
		else
			u.ut_syslen =  0;
	}

	(void) sprintf(u.ut_line, "%.12s", msg);

	if (pututxline(&u) == NULL) {
		endutxent();
		MUTEX_UNLOCK(&utmpx_lock);

		return;
	}

	updwtmpx(WTMPX_FILE, &u);

	endutxent();
	MUTEX_UNLOCK(&utmpx_lock);

	utmpx_check();
}
Example #3
0
File: irix.c Project: rra/lbcd
/*
 * Get the system uptime and return it in the boottime parameter.  Returns 0
 * on success and -1 on failure.
 */
int
kernel_getboottime(time_t *boottime)
{
    struct utmpx query, *result;

    query.ut_type = BOOT_TIME;
    setutxent();
    result = getutxid(&query);
    endutxent();
    if (result == NULL) {
        syswarn("getutxid failed to find BOOT_TIME");
        return -1;
    }
    *boottime = result->ut_tv.tv_sec;
    return 0;
}
Example #4
0
bool
get_boottime(struct timespec *ts)
{
    struct utmpx *ut, key;
    debug_decl(get_boottime, SUDOERS_DEBUG_UTIL)

    memset(&key, 0, sizeof(key));
    key.ut_type = BOOT_TIME;
    setutxent();
    if ((ut = getutxid(&key)) != NULL) {
	sudo_debug_printf(SUDO_DEBUG_DEBUG|SUDO_DEBUG_LINENO,
	    "BOOT_TIME: %lld, %ld", (long long)ut->ut_tv.tv_sec,
	    (long)ut->ut_tv.tv_usec);
	TIMEVAL_TO_TIMESPEC(&ut->ut_tv, ts);
    }
    endutxent();
    debug_return_bool(ut != NULL);
}
Example #5
0
static int get_run_level(void)
{
#if defined(HAVE_UTMPX_H) && defined(RUN_LVL)
	int res=0;
	struct utmpx *ut,tmp;

	setutxent();
	tmp.ut_type=RUN_LVL;
	ut=getutxid(&tmp);
	if(!ut)
	{
		endutxent();
		return 5;
	}
	res=ut->ut_pid & 0xff;
	endutxent();
	//g_message("runlevel %c\n",res);
	return res;
#else
	return 5;
#endif
}
Example #6
0
char
platform_get_runlevel()
{
	char runlevel;
	struct utmpx ut, *utp = NULL;

	MUTEX_LOCK(utmp_lock);

	memset(&ut, 0, sizeof(ut));
	ut.ut_type = RUN_LVL;

	setutxent();
	utp = getutxid(&ut);
	if (utp->ut_type == RUN_LVL &&
	    sscanf(utp->ut_line, "run-level %c", &runlevel) != 1)
			runlevel = 'u';
	endutxent();

	MUTEX_UNLOCK(utmp_lock);

	return runlevel;
}
struct utmpx *pututxline(struct utmpx *ut) {
  struct utmpx *tmp, ut_copy, *retval = 0, *result;
  int e;
  ssize_t bytes_written;
  sigset_t oldset, *savedset;

  /* It's kosher to call this function with a pointer to our own static
   * utmp structure, so work with a copy of "ut" */

  memcpy (&ut_copy, ut, sizeof (struct utmpx));

  savedset = __utmp_block_signals (&oldset);

  /* Seek to the current record before searching. */
  lseek (fd, utmp_current, SEEK_SET);
  if ((tmp = getutxid(&ut_copy))) {
    lseek(fd, - (off_t)sizeof(struct utmpx), SEEK_CUR);
    result = __utmp_io (fd, &ut_copy, sizeof(struct utmpx),
	    &utmp_current, F_WRLCK);
    e = errno;
  } else {
    utmp_current = lseek(fd, 0, SEEK_END);
    result = __utmp_io (fd, &ut_copy, sizeof(struct utmpx),
	    &utmp_current, F_WRLCK);
    e = errno;
  }
  if (savedset)
      sigprocmask (SIG_SETMASK, savedset, 0);

  if (result) {
      retval = ut;
  }

  memcpy (ut, &ut_copy, sizeof (struct utmpx));
  errno = e;
  return retval;
}
Example #8
0
/* EXTPROTO */
void
rxvt_cleanutent(rxvt_t *r)
{
#ifdef UTEMPTER_SUPPORT
    utempter_remove_record (PVTS(r)->cmd_fd);
#else	/* UTEMPTER_SUPPORT */

#ifdef HAVE_STRUCT_UTMP
    struct utmp    *ut = &(PVTS(r)->ut);
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    struct utmpx   *tmputx, *utx = &(PVTS(r)->utx);
#endif

#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
    MEMSET(ut, 0, sizeof(struct utmp));
    setutent();
    STRNCPY(ut->ut_id, PVTS(r)->ut_id, sizeof(ut->ut_id));
    ut->ut_type = USER_PROCESS;
    {
	struct utmp    *tmput = getutid(ut);

	if (tmput)	/* position to entry in utmp file */
	    ut = tmput;
    }
    ut->ut_type = DEAD_PROCESS;
# else 
    MEMSET(ut->ut_name, 0, sizeof(ut->ut_name));
#  ifdef HAVE_UTMP_HOST
    MEMSET(ut->ut_host, 0, sizeof(ut->ut_host));
#  endif
# endif
    ut->ut_time = time(NULL);
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, PVTS(r)->ut_id, sizeof(utx->ut_id));
    utx->ut_type = USER_PROCESS;
    if ((tmputx = getutxid(utx)))   /* position to entry in utmp file */
	utx = tmputx;
    utx->ut_type = DEAD_PROCESS;
# ifdef HAVE_UTMPX_SESSION
    utx->ut_session = getsid(0);
# endif
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
#endif

    /*
     * Write ending wtmp entry
     */
#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (ISSET_OPTION(r, Opt_loginShell))
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
#  ifdef HAVE_UPDWTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
#  else
	pututxline (utx);
#  endif
# endif
    }
#endif

    /*
     * Write utmp entry
     */
#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
    if (ut->ut_pid == PVTS(r)->cmd_pid)
	pututline(ut);
    endutent();
# else
    MEMSET(ut, 0, sizeof(struct utmp));
    rxvt_write_bsd_utmp(PVTS(r)->utmp_pos, ut);
# endif
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    if (utx->ut_pid == PVTS(r)->cmd_pid)
	pututxline(utx);
    endutxent();
#endif

#endif	/* UTEMPTER_SUPPORT */
}
Example #9
0
/*
 * remove utmp and wtmp entries
 */
void
ptytty_unix::logout ()
{
  if (!cmd_pid)
    return;

#ifdef HAVE_STRUCT_UTMP
  struct utmp *tmput, *ut = &this->ut;
#endif
#ifdef HAVE_STRUCT_UTMPX
  struct utmpx *tmputx, *utx = &this->utx;
#endif

#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
  memset (ut, 0, sizeof (struct utmp));
  setutent ();
  strncpy (ut->ut_id, this->ut_id, sizeof (ut->ut_id));
  ut->ut_type = USER_PROCESS;
  if ((tmput = getutid (ut)))		/* position to entry in utmp file */
    ut = tmput;
  ut->ut_type = DEAD_PROCESS;
# else
  memset (ut->ut_name, 0, sizeof (ut->ut_name));
#  ifdef HAVE_UTMP_HOST
  memset (ut->ut_host, 0, sizeof (ut->ut_host));
#  endif
# endif
  ut->ut_time = time (NULL);
#endif

#ifdef HAVE_STRUCT_UTMPX
  memset (utx, 0, sizeof (struct utmpx));
  setutxent ();
  strncpy (utx->ut_id, this->ut_id, sizeof (utx->ut_id));
  utx->ut_type = USER_PROCESS;
  if ((tmputx = getutxid (utx)))	/* position to entry in utmp file */
    utx = tmputx;
  utx->ut_type = DEAD_PROCESS;
# if HAVE_UTMPX_SESSION
  utx->ut_session = getsid (0);
# endif
  utx->ut_tv.tv_sec = time (NULL);
  utx->ut_tv.tv_usec = 0;
#endif

  /*
   * Write ending wtmp entry
   */
#ifdef WTMP_SUPPORT
#ifdef LOG_ONLY_ON_LOGIN
  if (login_shell)
#endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
      updwtmp (WTMP_FILE, ut);
#  else
      update_wtmp (WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX)
      updwtmpx (WTMPX_FILE, utx);
# endif
    }
#endif

  /*
   * Write utmp entry
   */
#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
  if (ut->ut_pid == cmd_pid)
    pututline (ut);
  endutent ();
# else
  memset (ut, 0, sizeof (struct utmp));
  write_bsd_utmp (utmp_pos, ut);
# endif
#endif
#ifdef HAVE_STRUCT_UTMPX
  if (utx->ut_pid == cmd_pid)
    pututxline (utx);
  endutxent ();
#endif

  cmd_pid = 0;
}
Example #10
0
/*
 * make and write utmp and wtmp entries
 */
void
ptytty_unix::login (int cmd_pid, bool login_shell, const char *hostname)
{
  const char *pty = name;

  if (!pty || !*pty)
    return;

  this->cmd_pid     = cmd_pid;
  this->login_shell = login_shell;

#ifdef HAVE_STRUCT_UTMP
  struct utmp *ut = &this->ut;
#endif
#ifdef HAVE_STRUCT_UTMPX
  struct utmpx *utx = &this->utx;
#endif
  int i;
  struct passwd *pwent = getpwuid (getuid ());
  const char *name = (pwent && pwent->pw_name) ? pwent->pw_name : "?";

  if (!strncmp (pty, "/dev/", 5))
    pty += 5;		/* skip /dev/ prefix */

#if defined(HAVE_UTMP_PID) || defined(HAVE_STRUCT_UTMPX)
  if (!strncmp (pty, "pty", 3) || !strncmp (pty, "tty", 3))
    strncpy (ut_id, pty + 3, sizeof (ut_id));
  else if (sscanf (pty, "pts/%d", &i) == 1)
    sprintf (ut_id, "vt%02x", (i & 0xff));	/* sysv naming */
  else
    {
      ptytty_warn ("can't parse tty name \"%s\", not adding utmp entry.\n", pty);
      return;
    }
#endif

#ifdef HAVE_STRUCT_UTMP
  memset (ut, 0, sizeof (struct utmp));
# ifdef HAVE_UTMP_PID
  setutent ();
  strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id));
  ut->ut_type = DEAD_PROCESS;
  getutid (ut);		/* position to entry in utmp file */
# endif
#endif

#ifdef HAVE_STRUCT_UTMPX
  memset (utx, 0, sizeof (struct utmpx));
  setutxent ();
  strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id));
  utx->ut_type = DEAD_PROCESS;
  getutxid (utx);		/* position to entry in utmp file */
#endif

#ifdef HAVE_STRUCT_UTMP
  strncpy (ut->ut_line, pty, sizeof (ut->ut_line));
# ifdef HAVE_UTMP_HOST
  strncpy (ut->ut_host, hostname, sizeof (ut->ut_host));
# endif
  ut->ut_time = time (NULL);
# ifdef HAVE_UTMP_PID
  strncpy (ut->ut_user, name, sizeof (ut->ut_user));
  strncpy (ut->ut_id, ut_id, sizeof (ut->ut_id));
  ut->ut_pid = cmd_pid;
  ut->ut_type = USER_PROCESS;
  pututline (ut);
  endutent ();			/* close the file */
  utmp_pos = 0;
# else
  strncpy (ut->ut_name, name, sizeof (ut->ut_name));
# endif
#endif

#ifdef HAVE_STRUCT_UTMPX
  strncpy (utx->ut_line, pty, sizeof (utx->ut_line));
  strncpy (utx->ut_user, name, sizeof (utx->ut_user));
  strncpy (utx->ut_id, ut_id, sizeof (utx->ut_id));
# if HAVE_UTMPX_SESSION
  utx->ut_session = getsid (0);
# endif
  utx->ut_tv.tv_sec = time (NULL);
  utx->ut_tv.tv_usec = 0;
  utx->ut_pid = cmd_pid;
# ifdef HAVE_UTMPX_HOST
  strncpy (utx->ut_host, hostname, sizeof (utx->ut_host));
#  if 0
  {
    char           *colon;

    if ((colon = strrchr (ut->ut_host, ':')) != NULL)
      *colon = '\0';
  }
#  endif
# endif
  utx->ut_type = USER_PROCESS;
  pututxline (utx);
  endutxent ();		/* close the file */
  utmp_pos = 0;
#endif

#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
  {
# if 1
    int fdstdin = dup (STDIN_FILENO);
    dup2 (tty, STDIN_FILENO);

    i = ttyslot ();
    if (write_bsd_utmp (i, ut))
      utmp_pos = i;

    dup2 (fdstdin, STDIN_FILENO);
    close (fdstdin);
# endif
  }
#endif

#ifdef WTMP_SUPPORT
#ifdef LOG_ONLY_ON_LOGIN
  if (login_shell)
#endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
      updwtmp (WTMP_FILE, ut);
#  else
      update_wtmp (WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX)
      updwtmpx (WTMPX_FILE, utx);
# endif
    }
#endif
#if defined(LASTLOG_SUPPORT) && defined(LASTLOG_FILE)
#ifdef LOG_ONLY_ON_LOGIN
  if (login_shell)
#endif
    update_lastlog (LASTLOG_FILE, pty, hostname);
#endif
}
Example #11
0
struct utmpx *
pututxline(const struct utmpx *utx)
{
	struct passwd *pw;
	struct lastlogx ll;
	struct utmpx temp, *u = NULL;
	int gotlock = 0;

	_DIAGASSERT(utx != NULL);

	if (utx == NULL)
		return NULL;

	if (utx->ut_type == USER_PROCESS) {
		ll.ll_tv = utx->ut_tv;
		strcpy(ll.ll_host, utx->ut_host);
		strcpy(ll.ll_line, utx->ut_line);
		pw = getpwnam(utx->ut_name);
		if (pw != NULL)
			updlastlogx(_PATH_LASTLOGX, pw->pw_uid, &ll);
	}

	if (strcmp(_PATH_UTMPX, utfile) == 0)
		if ((fp != NULL && readonly) || (fp == NULL && geteuid() != 0))
			return utmp_update(utx);


	(void)memcpy(&temp, utx, sizeof(temp));

	if (fp == NULL) {
		(void)getutxent();
		if (fp == NULL || readonly)
			return NULL;
	}

	if (getutxid(&temp) == NULL) {
		setutxent();
		if (getutxid(&temp) == NULL) {
			if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
				return NULL;
			gotlock++;
			if (fseeko(fp, (off_t)0, SEEK_END) == -1)
				goto fail;
		}
	}

	if (!gotlock) {
		/* we are not appending */
		if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
			return NULL;
	}

	if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
		goto fail;

	if (fflush(fp) == -1)
		goto fail;

	u = memcpy(&ut, &temp, sizeof(ut));
fail:
	if (gotlock) {
		if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
			return NULL;
	}
	return u;
}
struct utmpx *
pututxline(const struct utmpx *utx)
{
	struct utmpx temp, *u = NULL;
	int gotlock = 0;

	_DIAGASSERT(utx != NULL);

	if (utx == NULL)
		return NULL;

	if (strcmp(_PATH_UTMPX, utfile) == 0) {
		if (geteuid() == 0) {
			if (fp != NULL && readonly)
				endutxent();
		} else {
			if (fp == NULL || readonly)
				return utmp_update(utx);
		}
	}


	(void)memcpy(&temp, utx, sizeof(temp));

	if (fp == NULL) {
		(void)getutxent();
		if (fp == NULL || readonly)
			return NULL;
	}

	if (getutxid(&temp) == NULL) {
		setutxent();
		if (getutxid(&temp) == NULL) {
			if (lockf(fileno(fp), F_LOCK, (off_t)0) == -1)
				return NULL;
			gotlock++;
			if (fseeko(fp, (off_t)0, SEEK_END) == -1)
				goto fail;
		}
	}

	if (!gotlock) {
		/* we are not appending */
		if (fseeko(fp, -(off_t)sizeof(ut), SEEK_CUR) == -1)
			return NULL;
	}

	if (version == 1)
		new2old(&temp);
	if (fwrite(&temp, sizeof (temp), 1, fp) != 1)
		goto fail;

	if (fflush(fp) == -1)
		goto fail;

	u = memcpy(&ut, &temp, sizeof(ut));
fail:
	if (gotlock) {
		if (lockf(fileno(fp), F_ULOCK, (off_t)0) == -1)
			return NULL;
	}
	return u;
}
Example #13
0
File: logging.C Project: RAD16/rxit
void
ptytty_unix::log_session (bool login, const char *hostname)
{
  struct passwd *pwent = getpwuid (getuid ());
  const char *user = (pwent && pwent->pw_name) ? pwent->pw_name : "?";

  const char *pty = name;

  if (!strncmp (pty, "/dev/", 5))
    pty += 5;		/* skip /dev/ prefix */

#ifdef HAVE_STRUCT_UTMP
  struct utmp *tmput;
  struct utmp ut;
  fill_utmp (&ut, login, cmd_pid, pty, user, hostname);
#endif

#ifdef HAVE_STRUCT_UTMPX
  struct utmpx *tmputx;
  struct utmpx utx;
  fill_utmpx (&utx, login, cmd_pid, pty, user, hostname);
#endif

#ifdef HAVE_STRUCT_UTMP
# ifdef HAVE_UTMP_PID
  setutent ();
  if (login || ((tmput = getutid (&ut)) && tmput->ut_pid == cmd_pid))
    pututline (&ut);
  endutent ();
# else
  write_bsd_utmp (utmp_pos, &ut);
# endif
#endif

#ifdef HAVE_STRUCT_UTMPX
  setutxent ();
  if (login || ((tmputx = getutxid (&utx)) && tmputx->ut_pid == cmd_pid))
    pututxline (&utx);
  endutxent ();
#endif

#ifdef WTMP_SUPPORT
  if (login_shell)
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
      updwtmp (WTMP_FILE, &ut);
#  else
      update_wtmp (WTMP_FILE, &ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && defined(HAVE_UPDWTMPX)
      updwtmpx (WTMPX_FILE, &utx);
# endif
    }
#endif

#ifdef LASTLOG_SUPPORT
  if (login_shell)
    if (login)
      {
        if (pwent)
          update_lastlog (pty, hostname);
        else
          PTYTTY_WARN ("no entry in password file, not updating lastlog.\n");
      }
#endif
}
Example #14
0
/* EXTPROTO */
void
rxvt_makeutent(rxvt_t *r, const char *pty, const char *hostname)
{
#ifdef UTEMPTER_SUPPORT
    utempter_add_record (PVTS(r)->cmd_fd, hostname);
#else	/* UTEMPTER_SUPPORT */

#ifdef HAVE_STRUCT_UTMP
    struct utmp    *ut = &(PVTS(r)->ut);
#endif
#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    struct utmpx   *utx = &(PVTS(r)->utx);
#endif
#ifdef HAVE_UTMP_PID
    int             i;
#endif
    char            ut_id[5];
    struct passwd  *pwent = getpwuid(getuid());

    if (!STRNCMP(pty, "/dev/", 5))
	pty += 5;	/* skip /dev/ prefix */

    if (!STRNCMP(pty, "pty", 3) || !STRNCMP(pty, "tty", 3)) {
	STRNCPY(ut_id, (pty + 3), sizeof(ut_id));
    }
#ifdef HAVE_UTMP_PID
    else if (sscanf(pty, "pts/%d", &i) == 1)
	sprintf(ut_id, "vt%02x", (i & 0xff));	/* sysv naming */
#endif
    else if (STRNCMP(pty, "pty", 3) && STRNCMP(pty, "tty", 3)) {
	rxvt_msg (DBG_ERROR, DBG_LOGGING, "can't parse tty name \"%s\"", pty);
	return;
    }

#ifdef HAVE_STRUCT_UTMP
    MEMSET(ut, 0, sizeof(struct utmp));
# ifdef HAVE_UTMP_PID
    setutent();
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_type = DEAD_PROCESS;
    getutid(ut);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
    utx->ut_type = DEAD_PROCESS;
    getutxid(utx);	/* position to entry in utmp file */
    STRNCPY(PVTS(r)->ut_id, ut_id, sizeof(PVTS(r)->ut_id));
#endif

#ifdef HAVE_STRUCT_UTMP
    STRNCPY(ut->ut_line, pty, sizeof(ut->ut_line));
    ut->ut_time = time(NULL);
# ifdef HAVE_UTMP_PID
    STRNCPY(ut->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_user));
    STRNCPY(ut->ut_id, ut_id, sizeof(ut->ut_id));
    ut->ut_time = time(NULL);
    ut->ut_pid = PVTS(r)->cmd_pid;
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
    ut->ut_type = USER_PROCESS;
    pututline(ut);
    endutent();		/* close the file */
    PVTS(r)->utmp_pos = 0;
# else
    STRNCPY(ut->ut_name, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(ut->ut_name));
#  ifdef HAVE_UTMP_HOST
    STRNCPY(ut->ut_host, hostname, sizeof(ut->ut_host));
#  endif
# endif
#endif

#if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
    STRNCPY(utx->ut_line, pty, sizeof(utx->ut_line));
    STRNCPY(utx->ut_user, (pwent && pwent->pw_name) ? pwent->pw_name : "?",
        sizeof(utx->ut_user));
    STRNCPY(utx->ut_id, ut_id, sizeof(utx->ut_id));
# ifdef HAVE_UTMPX_SESSION
    utx->ut_session = getsid(0);
# endif
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
    utx->ut_pid = PVTS(r)->cmd_pid;
# ifdef HAVE_UTMPX_HOST
    STRNCPY(utx->ut_host, hostname, sizeof(utx->ut_host));
# endif
    utx->ut_type = USER_PROCESS;
    pututxline(utx);
    endutxent();	/* close the file */
    PVTS(r)->utmp_pos = 0;
#endif

#if defined(HAVE_STRUCT_UTMP) && !defined(HAVE_UTMP_PID)
    {
	int             i;
# ifdef HAVE_TTYSLOT
	i = ttyslot();
	if (rxvt_write_bsd_utmp(i, ut))
	    PVTS(r)->utmp_pos = i;
# else
	FILE           *fd0;

	if (NOT_NULL(fd0 = fopen(TTYTAB_FILENAME, "r"))) {
	    char            buf[256], name[256];

	    buf[sizeof(buf) - 1] = '\0';
	    for (i = 1; NOT_NULL(fgets(buf, sizeof(buf) - 1, fd0)); ) {
		if (*buf == '#' || sscanf(buf, "%s", name) != 1)
		    continue;
		if (!STRCMP(ut->ut_line, name)) {
		    if (!rxvt_write_bsd_utmp(i, ut))
			i = 0;
		    PVTS(r)->utmp_pos = i;
		    fclose(fd0);
		    break;
		}
		i++;
	    }
	    fclose(fd0);
	}
# endif
    }
#endif

#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (ISSET_OPTION(r, Opt_loginShell))
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# if defined(HAVE_STRUCT_UTMPX) && !defined(HAVE_STRUCT_UTMP)
#  ifdef HAVE_UPDWTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
#  else
	pututxline (utx);
#  endif
# endif
    }
#endif

#endif	/* UTEMPTER_SUPPORT */

#if defined(LASTLOG_SUPPORT) && defined(RXVT_LASTLOG_FILE)
    if (ISSET_OPTION(r, Opt_loginShell))
	rxvt_update_lastlog(RXVT_LASTLOG_FILE, pty, hostname);
#endif

}
Example #15
0
void
utmpx_set_runlevel(char runlevel, char oldrl, boolean_t do_bump)
{
	struct utmpx u;
	struct utmpx *oup;
	size_t tmplen;
	int i;

	if (runlevel == 's')
		runlevel = 'S';
	if (oldrl == 's')
		oldrl = 'S';

	bzero(&u, sizeof (struct utmpx));

	u.ut_id[0] = u.ut_id[1] = u.ut_id[2] = u.ut_id[3] = '\0';
	u.ut_pid = 0;
	u.ut_type = RUN_LVL;

	(void) time(&u.ut_tv.tv_sec);

	MUTEX_LOCK(&utmpx_lock);
	setutxent();

	if ((oup = getutxid(&u)) != NULL) {
		bcopy(oup->ut_host, u.ut_host, sizeof (u.ut_host));
		bcopy(oup->ut_line, u.ut_line, sizeof (u.ut_line));
		bcopy(oup->ut_user, u.ut_user, sizeof (u.ut_user));

		tmplen = strlen(u.ut_host);
		if (tmplen)
			u.ut_syslen = min(tmplen + 1, sizeof (u.ut_host));
		else
			u.ut_syslen =  0;
	}

	if (oldrl != '\0')
		u.ut_exit.e_exit = oldrl;
	else if (oup != NULL)
		u.ut_exit.e_exit = oup->ut_exit.e_termination;
	else
		u.ut_exit.e_exit = '0';

	u.ut_exit.e_termination = runlevel;

	for (i = 0; rlevels[i] != '\0'; ++i) {
		if (rlevels[i] == runlevel)
			break;
	}

	u.ut_pid = n_prev[i];

	if (do_bump) {
		for (i = 0; rlevels[i] != '\0'; ++i) {
			if (rlevels[i] == u.ut_exit.e_exit)
				break;
		}

		++n_prev[i];
	}

	(void) sprintf(u.ut_line, RUNLVL_MSG, runlevel);

	if (pututxline(&u) == NULL) {
		endutxent();
		MUTEX_UNLOCK(&utmpx_lock);

		return;
	}

	updwtmpx(WTMPX_FILE, &u);

	endutxent();
	MUTEX_UNLOCK(&utmpx_lock);

	utmpx_check();
}
Example #16
0
/*
 * Update wtmp and utmp logs.
 */
static void log_utmp(struct login_context *cxt)
{
	struct utmpx ut;
	struct utmpx *utp;
	struct timeval tv;

	utmpxname(_PATH_UTMP);
	setutxent();

	/* Find pid in utmp.
	 *
	 * login sometimes overwrites the runlevel entry in /var/run/utmp,
	 * confusing sysvinit. I added a test for the entry type, and the
	 * problem was gone. (In a runlevel entry, st_pid is not really a pid
	 * but some number calculated from the previous and current runlevel.)
	 * -- Michael Riepe <*****@*****.**>
	 */
	while ((utp = getutxent()))
		if (utp->ut_pid == cxt->pid
		    && utp->ut_type >= INIT_PROCESS
		    && utp->ut_type <= DEAD_PROCESS)
			break;

	/* If we can't find a pre-existing entry by pid, try by line.
	 * BSD network daemons may rely on this. */
	if (utp == NULL && cxt->tty_name) {
		setutxent();
		ut.ut_type = LOGIN_PROCESS;
		str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));
		utp = getutxline(&ut);
	}

	/* If we can't find a pre-existing entry by pid and line, try it by id.
	 * Very stupid telnetd daemons don't set up utmp at all. (kzak) */
	if (utp == NULL && cxt->tty_number) {
	     setutxent();
	     ut.ut_type = DEAD_PROCESS;
	     str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
	     utp = getutxid(&ut);
	}

	if (utp)
		memcpy(&ut, utp, sizeof(ut));
	else
		/* some gettys/telnetds don't initialize utmp... */
		memset(&ut, 0, sizeof(ut));

	if (cxt->tty_number && ut.ut_id[0] == 0)
		str2memcpy(ut.ut_id, cxt->tty_number, sizeof(ut.ut_id));
	if (cxt->username)
		str2memcpy(ut.ut_user, cxt->username, sizeof(ut.ut_user));
	if (cxt->tty_name)
		str2memcpy(ut.ut_line, cxt->tty_name, sizeof(ut.ut_line));

	gettimeofday(&tv, NULL);
	ut.ut_tv.tv_sec = tv.tv_sec;
	ut.ut_tv.tv_usec = tv.tv_usec;
	ut.ut_type = USER_PROCESS;
	ut.ut_pid = cxt->pid;
	if (cxt->hostname) {
		str2memcpy(ut.ut_host, cxt->hostname, sizeof(ut.ut_host));
		if (*cxt->hostaddress)
			memcpy(&ut.ut_addr_v6, cxt->hostaddress,
			       sizeof(ut.ut_addr_v6));
	}

	pututxline(&ut);
	endutxent();

	updwtmpx(_PATH_WTMP, &ut);
}
Example #17
0
int
utmpx_mark_init(pid_t pid, char *prefix)
{
	struct utmpx ut, *oldu;
	int tmplen;
	int ret;

	while (st->st_initial && !utmpx_truncated)
		(void) usleep(200 * USEC_PER_MSEC);

	/*
	 * Clean out any preexisting records for this PID, as they must be
	 * inaccurate.
	 */
	utmpx_mark_dead(pid, 0, B_TRUE);

	/*
	 * Construct a new record with the appropriate prefix.
	 */
	(void) memset(&ut, 0, sizeof (ut));
	(void) strncpy(ut.ut_user, ".startd", sizeof (ut.ut_user));
	ut.ut_pid = pid;

	ut.ut_id[0] = ut.ut_id[1] = ut.ut_id[2] = ut.ut_id[3] = (char)SC_WILDC;

	for (ret = 0; ret < strlen(prefix); ret++)
		ut.ut_id[ret] = prefix[ret];

	ut.ut_type = INIT_PROCESS;
	(void) time(&ut.ut_tv.tv_sec);

	for (;;) {
		MUTEX_LOCK(&utmpx_lock);
		setutxent();

		if ((oldu = getutxid(&ut)) != NULL) {
			/*
			 * Copy in the old "line" and "host" fields.
			 */
			bcopy(oldu->ut_line, ut.ut_line, sizeof (ut.ut_line));
			bcopy(oldu->ut_host, ut.ut_host, sizeof (ut.ut_host));
			ut.ut_syslen = (tmplen = strlen(ut.ut_host)) ?
			    min(tmplen + 1, sizeof (ut.ut_host)) : 0;
		}

		if (makeutx(&ut) != NULL)
			break;

		if (errno != EROFS)
			log_framework(LOG_WARNING,
			    "makeutx failed, retrying: %s\n", strerror(errno));

		MUTEX_UNLOCK(&utmpx_lock);

		(void) sleep(1);
	}

	updwtmpx(WTMPX_FILE, &ut);

	endutxent();
	MUTEX_UNLOCK(&utmpx_lock);

	return (ret);
}
Example #18
0
uint64
System_Uptime(void)
{
   uint64 uptime = -1;

#ifdef USERWORLD
   {
      VmkuserStatus_Code status;
      uint64 sysUptime;
      status = VmkuserUptime_GetUptime(&sysUptime);
      if (VmkuserStatus_IsOK(status)) {
         uptime = sysUptime / 10000;
      }
   }
#elif defined(__linux__)
   {
      FILE *procStream;
      char *buf = NULL;
      size_t bufSize;
      uint64 sec;
      unsigned int csec;

      if (((procStream = Posix_Fopen("/proc/uptime", "r")) != NULL) &&
          (StdIO_ReadNextLine(procStream, &buf, 80, &bufSize) == StdIO_Success) &&
          (sscanf(buf, "%"FMT64"u.%2u", &sec, &csec) == 2)) {
         uptime = sec * 100 + csec;
      } else {
         Warning("%s: Unable to parse /proc/uptime.\n", __func__);
      }

      free(buf);

      if (procStream) {
         fclose(procStream);
      }
   }
#elif defined sun || defined __APPLE__
   {
      struct utmpx *boot, tmp;

      tmp.ut_type = BOOT_TIME;
      if ((boot = getutxid(&tmp)) != NULL) {
         struct timeval now;
         struct timeval *boottime = &boot->ut_tv;

         gettimeofday(&now, NULL);
         uptime =
            (now.tv_sec * 100 + now.tv_usec / 10000) -
            (boottime->tv_sec * 100 + boottime->tv_usec / 10000);
      } else {
         Warning("%s: Unable to determine boot time.\n", __func__);
      }

      endutxent();
   }
#else // FreeBSD
   {
      /*
       * FreeBSD: src/usr.bin/w/w.c rev 1.59:
       *   "Obtain true uptime through clock_gettime(CLOCK_MONOTONIC,
       *    struct *timespec) instead of subtracting 'bootime' from 'now'."
       */
      struct timespec ts;

      if (clock_gettime(CLOCK_MONOTONIC, &ts) != -1) {
         uptime = ts.tv_sec * 100 + ts.tv_nsec / 10000000;
      } else {
         Warning("%s: clock_gettime: %d\n", __func__, errno);
      }
   }
#endif

   return uptime;
}
Example #19
0
int	SYSTEM_BOOTTIME(AGENT_REQUEST *request, AGENT_RESULT *result)
{
	int	ret = SYSINFO_RET_FAIL;

#ifdef HAVE_ZONE_H
	if (GLOBAL_ZONEID == getzoneid())
	{
#endif
		kstat_ctl_t	*kc;
		kstat_t		*kp;
		kstat_named_t	*kn;

		if (NULL == (kc = kstat_open()))
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot open kernel statistics facility: %s",
					zbx_strerror(errno)));
			return ret;
		}

		if (NULL == (kp = kstat_lookup(kc, "unix", 0, "system_misc")))
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot look up in kernel statistics facility: %s",
					zbx_strerror(errno)));
			goto clean;
		}

		if (-1 == kstat_read(kc, kp, 0))
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot read from kernel statistics facility: %s",
					zbx_strerror(errno)));
			goto clean;
		}

		if (NULL == (kn = (kstat_named_t *)kstat_data_lookup(kp, "boot_time")))
		{
			SET_MSG_RESULT(result, zbx_dsprintf(NULL, "Cannot look up data in kernel statistics facility:"
					" %s", zbx_strerror(errno)));
			goto clean;
		}

		SET_UI64_RESULT(result, get_kstat_numeric_value(kn));
		ret = SYSINFO_RET_OK;
clean:
		kstat_close(kc);
#ifdef HAVE_ZONE_H
	}
	else
	{
		struct utmpx	utmpx_local, *utmpx;

		utmpx_local.ut_type = BOOT_TIME;

		setutxent();

		if (NULL != (utmpx = getutxid(&utmpx_local)))
		{
			SET_UI64_RESULT(result, utmpx->ut_xtime);
			ret = SYSINFO_RET_OK;
		}
		else
			SET_MSG_RESULT(result, zbx_strdup(NULL, "Cannot obtain system boot time."));

		endutxent();
	}
#endif
	return ret;
}
Example #20
0
int
rckrunlevel(void)
{
	struct utmpx utmpx;
	struct utmpx *putmpx;
	char	ans[MAX_INPUT];
	char	*pt;
	char	*rstates;
	int	n;
	char	*uxstate;

	if (ADM(runlevel, "nocheck")) {
		return (0);
	}

	pt = getenv("RSTATES");
	if (pt == NULL) {
		return (0);
	}

	utmpx.ut_type = RUN_LVL;
	putmpx = getutxid(&utmpx);
	if (putmpx == NULL) {
		progerr(ERR_RUNSTATE);
		return (99);
	}
	uxstate = strtok(&putmpx->ut_line[10], " \t\n");

	rstates = qstrdup(pt);
	if ((pt = strtok(pt, " \t\n, ")) == NULL)
		return (0); /* no list is no list */
	do {
		if (strcmp(pt, uxstate) == 0) {
			free(rstates);
			return (0);
		}
	} while (pt = strtok(NULL, " \t\n, "));

	if (preremoveCheck == B_FALSE) {
		msgtext = MSG_PKGREMOVE_RUNLEVEL;
		ptext(stderr, msgtext, uxstate);
	} else {
		(void) fprintf(stdout, "runlevel=%s", uxstate);
	}

	pt = strtok(rstates, " \t\n, ");
	do {
		if (preremoveCheck == B_FALSE) {
			ptext(stderr, "\\t%s", pt);
		} else {
			(void) fprintf(stdout, ":%s", pt);
		}
	} while (pt = strtok(NULL, " \t\n, "));

	if (preremoveCheck == B_TRUE) {
		(void) fprintf(stdout, "\n");
	}

	free(rstates);

	if (ADM(runlevel, "quit")) {
		return (4);
	}

	if (echoGetFlag() == B_FALSE) {
		return (5);
	}

	msgtext = NULL;

	n = ckyorn(ans, NULL, NULL, HLP_PKGREMOVE_RUNLEVEL,
	    ASK_PKGREMOVE_CONTINUE);

	if (n != 0) {
		return (n);
	}

	if (strchr("yY", *ans) == NULL) {
		return (3);
	}

	return (0);
}
Example #21
0
/* EXTPROTO */
void
rxvt_cleanutent(rxvt_t *r)
{
#ifdef HAVE_STRUCT_UTMP
    struct utmp    *tmput, *ut = &(r->h->ut);
#endif
#ifdef HAVE_STRUCT_UTMPX
    struct utmpx   *tmputx, *utx = &(r->h->utx);
#endif

#ifdef HAVE_STRUCT_UTMP
# ifdef RXVT_UTMP_PID
    MEMSET(ut, 0, sizeof(struct utmp));
    setutent();
    STRNCPY(ut->ut_id, r->h->ut_id, sizeof(ut->ut_id));
    ut->ut_type = USER_PROCESS;
    if ((tmput = getutid(ut)))	/* position to entry in utmp file */
	ut = tmput;
    ut->ut_type = DEAD_PROCESS;
# else 
    MEMSET(ut->ut_name, 0, sizeof(ut->ut_name));
    MEMSET(ut->ut_host, 0, sizeof(ut->ut_host));
# endif
    ut->ut_time = time(NULL);
#endif

#ifdef HAVE_STRUCT_UTMPX
    MEMSET(utx, 0, sizeof(struct utmpx));
    setutxent();
    STRNCPY(utx->ut_id, r->h->ut_id, sizeof(utx->ut_id));
    utx->ut_type = USER_PROCESS;
    if ((tmputx = getutxid(utx)))	/* position to entry in utmp file */
	utx = tmputx;
    utx->ut_type = DEAD_PROCESS;
    utx->ut_session = getsid(0);
    utx->ut_tv.tv_sec = time(NULL);
    utx->ut_tv.tv_usec = 0;
#endif

    /*
     * Write ending wtmp entry
     */
#ifdef WTMP_SUPPORT
# ifdef WTMP_ONLY_ON_LOGIN
    if (r->Options & Opt_loginShell)
# endif
    {
# ifdef HAVE_STRUCT_UTMP
#  ifdef HAVE_UPDWTMP
	updwtmp(RXVT_WTMP_FILE, ut);
#  else
	rxvt_update_wtmp(RXVT_WTMP_FILE, ut);
#  endif
# endif
# ifdef HAVE_STRUCT_UTMPX
	updwtmpx(RXVT_WTMPX_FILE, utx);
# endif
#endif
    }

    /*
     * Write utmp entry
     */
#ifdef HAVE_STRUCT_UTMP
# ifdef RXVT_UTMP_PID
    if (ut->ut_pid == r->h->cmd_pid)
	pututline(ut);
    endutent();
# else
    if (r->h->utmp_pos > 0) {
	MEMSET(ut, 0, sizeof(struct utmp));
	rxvt_write_bsd_utmp(r->h->utmp_pos, ut);
    }
# endif
#endif
#ifdef HAVE_STRUCT_UTMPX
    if (utx->ut_pid == r->h->cmd_pid)
	pututxline(utx);
    endutxent();
#endif
}
Example #22
0
int
main (int argc, char **argv)
{
#if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE)
	int		utmp;
#endif
#ifndef USE_UTMPX
	int		wtmp;
#endif
	time_t		current_time;
#ifdef USE_UTMP
	struct utmp	utmp_entry;
#endif
#ifdef USE_UTMPX
	struct utmpx	utmpx_entry;
#endif
	char *		line = NULL;

	program_name = argv[0];
	while (*++argv && **argv == '-') {
		switch (*++*argv) {
		case 'w':
			wtmp_file = getstring (&argv, &wflag);
			if (!strcmp (wtmp_file, "none"))
				wtmp_none = 1;
#if defined(USE_UTMPX) && defined(HAVE_UPDWTMPX)
			else
				wtmpx_file = wtmp_file;
#endif
			break;
		case 'u':
			utmp_file = getstring (&argv, &uflag);
			if (!strcmp (utmp_file, "none"))
				utmp_none = 1;
#if defined(USE_UTMPX) && defined(HAVE_UTMPXNAME)
			else
				utmpx_file = utmp_file;
#endif
			break;
#ifdef USE_LASTLOG
		case 'L':
			llog_file = getstring (&argv, &Lflag);
			if (!strcmp (llog_file, "none"))
				llog_none = 1;
			break;
#endif
		case 't':
			ttys_file = getstring (&argv, &tflag);
			break;
		case 'l':
			line = getstring (&argv, &lflag);
			break;
		case 'h':
			host_name = getstring (&argv, &hflag);
			break;
		case 's':
#if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE)
			slot_number = atoi (getstring (&argv, &sflag));
#endif
			break;
		case 'x':
			xservers_file = getstring (&argv, &xflag);
			break;
		case 'a':
			aflag++;
			break;
		case 'd':
			dflag++;
			break;
		case 'V':
			printf("%s\n", PACKAGE_STRING);
			exit (0);
		default:
			fprintf (stderr, "%s: unrecognized option '%s'\n",
				 program_name, argv[0]);
			usage (1);
		}
	}
	user_name = *argv++;
	if (user_name == NULL) {
		fprintf (stderr, "%s: missing required user-name argument\n",
			 program_name);
		usage (1);
	}
	if (*argv != NULL) {
		fprintf (stderr, "%s: unrecognized argument '%s'\n",
			 program_name, argv[0]);
		usage (1);
	}
	/*
	 * complain if neither aflag nor dflag are set,
	 * or if both are set.
	 */
	if (!(aflag ^ dflag)) {
		fprintf (stderr, "%s: must specify exactly one of -a or -d\n",
			 program_name);
		usage (1);
	}
	if (xflag && !lflag) {
		fprintf (stderr, "%s: must specify -l when -x is used\n",
			 program_name);
		usage (1);
	}
	/* set up default file names */
	if (!wflag) {
		wtmp_file = WTMP_FILE;
#if defined(USE_UTMPX) && defined(HAVE_UPDWTMPX)
		wtmpx_file = WTMPX_FILE;
#endif
	}
	if (!uflag) {
		utmp_file = UTMP_FILE;
#if defined(USE_UTMPX) && defined(HAVE_UTMPXNAME)
		utmpx_file = UTMPX_FILE;
#endif
	}
#ifdef USE_LASTLOG
	if (!Lflag)
		llog_file = LLOG_FILE;
#endif
#if defined(USE_UTMP) && !defined(HAVE_PUTUTLINE)
	if (!tflag)
		ttys_file = TTYS_FILE;
	if (!sflag && !utmp_none) {
		if (xflag)
			sysnerr (slot_number = Xslot (ttys_file, xservers_file, line, host_name, aflag), "Xslot");
		else
			sysnerr (slot_number = ttyslot (), "ttyslot");
	}
#endif
	if (!lflag) {
		sysnerr ((line = ttyname (0)) != NULL, "ttyname");
		if (strncmp(line, "/dev/", 5) == 0)
			line += 5;
	}
	time (&current_time);
#ifdef USE_UTMP
	set_utmp (&utmp_entry, line, user_name, host_name, current_time, aflag);
#endif

#ifdef USE_UTMPX
	/* need to set utmpxname() before calling set_utmpx() for
	   UtmpxIdOpen to work */
# ifdef HAVE_UTMPXNAME
	if (utmpx_file != NULL) {
		utmpxname (utmpx_file);
	}
# endif
	set_utmpx (&utmpx_entry, line, user_name,
		   host_name, current_time, aflag);
#endif

	if (!utmp_none) {
#ifdef USE_UTMPX
# ifdef HAVE_UTMPXNAME
		if (utmpx_file != NULL)
# endif
		{
			setutxent ();
			(void) getutxid (&utmpx_entry);
			pututxline (&utmpx_entry);
			endutxent ();
		}
#endif
#ifdef USE_UTMP
# ifdef HAVE_PUTUTLINE
		utmpname (utmp_file);
		setutent ();
		(void) getutid (&utmp_entry);
		pututline (&utmp_entry);
		endutent ();
# else
		utmp = open (utmp_file, O_RDWR);
		if (utmp != -1) {
			syserr ((int) lseek (utmp, (long) slot_number * sizeof (struct utmp), 0), "lseek");
			sysnerr (write (utmp, (char *) &utmp_entry, sizeof (utmp_entry))
					== sizeof (utmp_entry), "write utmp entry");
			close (utmp);
		}
# endif
#endif /* USE_UTMP */
	}
	if (!wtmp_none) {
#ifdef USE_UTMPX
# ifdef HAVE_UPDWTMPX
		if (wtmpx_file != NULL) {
			updwtmpx(wtmpx_file, &utmpx_entry);
		}
# endif
#else
		wtmp = open (wtmp_file, O_WRONLY|O_APPEND);
		if (wtmp != -1) {
			sysnerr (write (wtmp, (char *) &utmp_entry, sizeof (utmp_entry))
					== sizeof (utmp_entry), "write wtmp entry");
			close (wtmp);
		}
#endif
	}
#ifdef USE_LASTLOG
	if (aflag && !llog_none) {
		int llog;
		struct passwd *pwd = getpwnam(user_name);

		sysnerr( pwd != NULL, "get user id");
		llog = open (llog_file, O_RDWR);

		if (llog != -1) {
			struct lastlog ll;

			sysnerr (lseek(llog, (long) (pwd->pw_uid*sizeof(ll)), 0)
					!= -1, "seeking lastlog entry");
			memset(&ll, 0, sizeof(ll));
			ll.ll_time = current_time;
			if (line)
			 (void) strncpy (ll.ll_line, line, sizeof (ll.ll_line));
			if (host_name)
			 (void) strncpy (ll.ll_host, host_name, sizeof (ll.ll_host));

			sysnerr (write (llog, (char *) &ll, sizeof (ll))
					== sizeof (ll), "write lastlog entry");
			close (llog);
		}
	}
#endif
	return 0;
}