/* PIPServer - A deamon for finger protocol v2
 *
 * Copyright (C) 1999 Michael Baumer <baumi@vis.ethz.ch>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 * Boston, MA 02111-1307, USA.
 */

#include <config.h>

#include <time.h>

#include "finger.h"
#include "statusdb.h"
#include "local_user.h"
#include "utmplib.h"

/* NetBSD is a pleasure */
#ifndef HAVE_UT_USER
#define ut_user ut_name
#endif

extern char hostname[64];
extern login_info * gnufinger_read_utmp(login_info *loginlist, int sorted);
extern time_t get_tty_idletime(char *devname);

login_info * read_utmp(int sorted)
{
  struct my_utmp *ut;
  login_info *current, *tmp;
  login_info first;
  time_t idle;
  finger_userinfo *finfo;
  time_t idlemax;

  /* todo: make this an option */
  idlemax = 600; /* 10min */

  /* first read in the people from the database */
  /* But only if we are the sitehost */
  if (config.clusterType == 2)
    first.next = read_utmp_db(1); 
  else
    first.next = NULL;
  
  /* Gnufinger Compatibility mode ? */
  if (config.gnufinger)
    return gnufinger_read_utmp(first.next, sorted);

  my_setutent();

  current = &first;
  while (current->next) 
    current = current->next;

  while((ut = my_getutent())) {
#ifdef HAVE_UT_TYPE   
    if (ut->ut_type == USER_PROCESS) {
#endif      
      /* On some systems the following is useful */
      if (!*ut->ut_user)
	continue;

      if (sorted) {
	/* check if we already have that user */
	tmp = first.next;
	while(tmp) {
	  if (!strcmp(tmp->login_user, ut->ut_user)) {
	    
	    /* check for smallest idle time */
	    /* also set hostname to host with smaller idle time */
	    idle = get_tty_idletime(ut->ut_line);
	    if (idle < tmp->idle_time) {
	      tmp->idle_time = idle;
	      strcpy(tmp->hostname, hostname);
#ifdef HAVE_UT_HOST
	      if (strlen(ut->ut_host)<1)
		strcpy(tmp->fromhost, "Console");
	      else
		strcpy(tmp->fromhost, ut->ut_host);
#else
	      strcpy(tmp->fromhost, "(unknown)");
#endif
	      if (tmp->idle_time < idlemax) 
		strcpy(tmp->status, "active");
	      else
		strcpy(tmp->status, "idle");
	    }
	    
	    /* check for the earliest login time */
	    if (tmp->login_time > ut->ut_time)
	      tmp->login_time = ut->ut_time;

	    break;
	  }
	  tmp = tmp->next;
	}
	if (tmp) 
	  continue;
      }

      /* get realname from /etc/passwd */
      /* This also checks for system accounts and ~/.nofinger */
      finfo = pwd_search_login(ut->ut_user, 0);
      if (!finfo)
	continue;

      /* we use ut_time and ut_user */
  
      current->next = (login_info *)malloc(sizeof(login_info));
      memset(current->next, 0, sizeof(login_info));
      current = current->next;
      current->login_time = ut->ut_time;
      current->idle_time = get_tty_idletime(ut->ut_line);
      strncpy(current->login_user, ut->ut_user, UT_NAMESIZE - 1);
      strcpy(current->realname, finfo->pw_realname);       
      if (current->idle_time < idlemax) 
	strcpy(current->status, "active");
      else
	strcpy(current->status, "idle");
#ifdef HAVE_UT_HOST
      if (strlen(ut->ut_host)<1)
	strcpy(current->fromhost, "Console");
      else
	strcpy(current->fromhost, ut->ut_host);
#else
      strcpy(current->fromhost, "(unknown)");
#endif
 
      /* Host someone is on */

      /* this is always localhost, since we are reading the local utmp */
      /* For other hosts see the online db */
      strcpy(current->hostname, hostname);
#ifdef HAVE_UT_TYPE
    }
#endif
  }
  
  my_endutent();

  return(first.next);
}


syntax highlighted by Code2HTML, v. 0.9.1