Logo Search packages:      
Sourcecode: lbcd version File versions  Download package

get_user.c

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "lbcd.h"
#ifdef HAVE_UTMPX_H
#include <utmpx.h>
#endif
#include <utmp.h>
#ifdef HAVE_MALLOC_H
#include <malloc.h>
#endif
#ifdef HAVE_SEARCH_H
#include <search.h>
#endif

#if defined(sparc) && !defined(__SVR4)
ENTRY *hsearch();
#endif

static const char *utmp =
#ifdef HAVE_UTMPX_H
  #ifdef UTMPX_FILE
    UTMPX_FILE
  #else
    "/etc/utmpx"
  #endif
#elif HAVE_UTMP_H
  #ifdef UTMP_FILE
    UTMP_FILE
  #else
    "/etc/utmp"
  #endif
#endif
;

static char *users[512]; /* should be enough for now, change to dynamic */
static int uniq_users=0;

static void
uniq_start(void)
{
  uniq_users = 0;
#ifdef HAVE_HSEARCH
  hcreate(211);  /* nice prime number */
#endif 
}

static void
uniq_end(void)
{
 int i;
#ifdef HAVE_HSEARCH
 hdestroy();
#endif
 if (uniq_users) for (i=0; i<uniq_users; i++) {
    free(users[i]);
    users[i]=NULL;
 }
}

static void
uniq_add(char *name)
{
#ifdef HAVE_HSEARCH
 ENTRY item, *i;
 item.key = name;
 item.data = 0;
 i=hsearch(item,FIND);
 if (i==NULL) { 
    item.key = users[uniq_users] = (char*)malloc(strlen(name)+1);
    strcpy(item.key,name);
    hsearch(item,ENTER);
    ++uniq_users;
  }

#else /* linear search for now */

  int i;
  if (uniq_users) {
     for (i=0; i<uniq_users; i++) {
         if (strcmp(users[i],name)==0) return;
     }
  } 
  users[uniq_users] = (char *)malloc(strlen(name)+1);
  strcpy(users[uniq_users],name);
  ++uniq_users;

#endif
}

static int
uniq_count(void)
{
  return uniq_users;
}

int
get_user_stats(int *total,int *uniq, int *on_console,time_t *user_mtime)
{
  char name[9];
  struct stat sbuf;
#ifndef HAVE_GETUTENT
  struct utmp ut;
  int fd;
#endif

  static int last_total=0,
             last_uniq=0,
             last_on_console=0;
  static time_t last_user_mtime=0;

  *total  = 0;
  *uniq   = 0;
  *on_console = 0;
  *user_mtime = 0;

  if (stat(utmp,&sbuf)==0) {
    *user_mtime = sbuf.st_mtime;
  }

  if (*user_mtime == last_user_mtime) { /* used cached values */ 
    *total      = last_total;
    *uniq       = last_uniq;
    *on_console = last_on_console;
    return 0;
  }

  uniq_start();

  if (stat("/dev/console",&sbuf)==0) {
    if (sbuf.st_uid != 0) *on_console = 1;
  }

#ifdef HAVE_GETUTENT
  {
    struct utmp *ut;
    while((ut = getutent())!=NULL) {

      if (ut->ut_type != USER_PROCESS)
      continue;
      ++(*total);

      if (strncmp(ut->ut_line,"console",7)==0)
      *on_console = 1;
      strncpy(name,ut->ut_user,8);
      name[8]=0;
      uniq_add(name);
    }
    endutent();
}

#else
  fd =open(utmp,O_RDONLY);
  if (fd==-1) {
    util_log_error("can't open %s: %%ms",utmp);
    return -1;
  }

  while (read(fd,(char*)&ut, sizeof(ut))>0) {
#ifndef USER_PROCESS
    if (ut.ut_name[0] == '\0') continue;
#else
    if (ut.ut_type != USER_PROCESS) continue;
#endif
    ++(*total);
    if (strncmp(ut.ut_line,"console",7)==0) *on_console = 1;
    strncpy(name,ut.ut_name,8);
    name[8]=0;
    uniq_add(name);
  }
  close(fd);
#endif /* HAVE_GETUTENT */

  *uniq = uniq_count();
  uniq_end();

  last_total      = *total;
  last_uniq       = *uniq; 
  last_on_console = *on_console;
  last_user_mtime = *user_mtime;

  return 0;  
}

#ifdef MAIN
void
util_log_error(char *fmt, ...) {
}

int
main()
{
  int t,u,oc;
  time_t mtime;

  get_user_stats(&t,&u,&oc,&mtime);
  printf("total = %d  uniq = %d  on_cons = %d\n",t,u,oc);
  return 0;
}
#endif

Generated by  Doxygen 1.6.0   Back to index