SUMMARY: How to keep /var/adm/wtmp and /var/adm/wtmpx under control

From: Dan Kennedy (DKENNEDY@170systems.com)
Date: Mon May 15 1995 - 23:10:54 CDT


  
My original question asked how I could stop /var/adm/wtmp and
/var/adm/wtmpx from growing indefinetly. I should have been more clear
with my question, but I also wanted to know what the heck these files
were doing there in the first place. In any case, from the responses
I got it sounds like these files are used to keep an historical account
of logins to the system. They are used by the "last" command to
produce a report on previous logins.
 
Since I had never purged these files, they had grown rather large. My
solution then was to purge them with:
 
    cat /dev/null > /var/adm/wtmp
    cat /dev/null > /var/adm/wtmpx
 
Some of the responses suggested linking these files with /dev/null to
prevent them from ever growing. I may do that eventually, but now that
I know what they are for, I haven't decided if I want to get rid of them
altogether.
 
Thanks for these ideas to chaworth@uk.mdis.com, pbrown@econ.yale.edu,
and mark@lochard.com.au.
 
Here is a representative sample of alternative solutions:
 
======================================================================
from rangern@CIRANO.UMontreal.CA...
 
You can create a small script with a cron job (ex.: monthly) to "clean"
these files. Example:
 
hostname=`uname -n`
 
MONTHLY=/local/monthly.0
 
 
#
# Creation of the monthly output file
#
  
        touch $MONTHLY
        echo "Subject: monthly run output for $hostname" >> $MONTHLY
 
 
#
# Rotation of wtmp and wtmpx files
#
 
        echo "" >> $MONTHLY
        echo "Rotating wtmp files:" >> $MONTHLY
        cd /var/adm)
        mv wtmp.5.Z wtmp.6.Z
        mv wtmp.4.Z wtmp.5.Z
        mv wtmp.3.Z wtmp.4.Z
        mv wtmp.2.Z wtmp.3.Z
        mv wtmp.1.Z wtmp.2.Z
        mv wtmp.0.Z wtmp.1.Z
        mv wtmp wtmp.0
        compress -f wtmp.0
        cp /dev/null wtmp
        chmod 644 wtmp
 
        echo "" >> $MONTHLY
        echo "Rotating wtmpx files:" >> $MONTHLY
        cd /var/adm)
        mv wtmpx.5.Z wtmpx.6.Z
        mv wtmpx.4.Z wtmpx.5.Z
        mv wtmpx.3.Z wtmpx.4.Z
        mv wtmpx.2.Z wtmpx.3.Z
        mv wtmpx.1.Z wtmpx.2.Z
        mv wtmpx.0.Z wtmpx.1.Z
        mv wtmpx wtmpx.0
        compress -f wtmpx.0
        cp /dev/null wtmpx
        chmod 644 wtmpx
 
 
#
# Rotation of monthly files
#
  
        cd /local
        rm monthly.5.Z
        mv monthly.4.Z monthly.5.Z
        mv monthly.3.Z monthly.4.Z
        mv monthly.2.Z monthly.3.Z
        mv monthly.1.Z monthly.2.Z
        mv monthly.0.Z monthly.1.Z
        compress -f $MONTHLY
 
======================================================================
from matt@uts.EDU.AU
 
alot of people keep having these problems, one risk you may have is if
you have set up sac/saf wrong. if you have sac/saf listeners going off
the rails, they will make an entry in wtmp/wtmpx every time they
retry (default max retries is 999!). one way to check wether this is
the case is
 
% who -a /var/adm/wtmp
 
and watch out for the scroll.. if you have alot of "tcp" entries, its
because you have a problem with your sac/saf setup. normally the only
machines that need a tcp listener are print servers. if the machine
isnt a print server, tcp listen service can be turned off with the
following command.
 
#sacadm -r -p tcp
 
if the machine is a print server then you need to reconfigure your tcp
listen to not crash. for some odd reason, the way the "User Accounts,
Printer, and Mail Administration" manual advises to setup printers
manually can cause problems.. the log files for the tcp listener are
in /var/saf/tcp/_log (in ASCII). hope this clears up problems for
some.
 
======================================================================
from bernard.drolet@CCG.RNCan.gc.ca
 
I'm using a small C program to trim /var/adm/wtmp and wtmpx.
 
I did get those program from someone on the Internet... I'm running those
every month.
 
Hope it's help!

-- 
Simon-Bernard Drolet                E-mail: bernard.drolet@CCG.RNCan.gc.ca 
Administrateur de systemes Unix     Tel:    (819) 564-5600 ext.4819 
Centre Canadien de Geomatique       Fax:    (819) 564-5698 
2144 King Ouest, suite 010, Sherbrooke, Quebec, Canada, J1J 2E8 
---------- 
X-Sun-Data-Type: c-file 
X-Sun-Data-Name: wtmpcut.c 
X-Sun-Charset: us-ascii 
X-Sun-Content-Lines: 91 
 
/*----------------------------------------------------------------------* 
 *                                                                      * 
 * Description: Source du fichier exec. /equipe/sysadmin/bin/wtmpcut    * 
 *              qui permet de reduire le fichier /var/adm/wtmp en enle- * 
 *              vant toutes les entrees plus vieilles qu'une certaine   * 
 *              date specifiee en parametre. Si aucun parametre n'est   * 
 *              specifie, on utilise une valeur par defaut (DELAIS).    * 
 *                                                                      * 
 *----------------------------------------------------------------------*/ 
 
#include <stdio.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <utmp.h> 
#include <time.h> 
#include <errno.h> 
 
#define DELAIS  (time_t) (90)                           /* en jour */ 
 
int main(argc, argv) 
int argc; 
char **argv; 
{ 
  struct  utmp wtmp_rec; 
  int     old_fd, new_fd; 
  int     wtmp_rec_sz = sizeof(struct utmp); 
  time_t  periode, temps_limite; 
 
 
 
  if (argc > 1) 
      periode = (time_t) atoi(argv[1]); 
  else 
      periode = DELAIS; 
 
  /* 
   * Copie de /var/adm/wtmp dans /tmp/wtmp 
   */ 
  putenv("IFS=' \t\n'");                        /* Securite */ 
  putenv("PATH=/usr/bin");                      /* Securite */ 
  if (system("cp /var/adm/wtmp /tmp/wtmp") < 0) { 
    fprintf(stderr,"%s: Erreur en copiant wtmp dans /tmp.\nBye.\n",argv[0]); 
    exit(1); 
  } /* if */ 
 
  /* 
   *  Calcule du temps limite en time_t   
   */ 
  temps_limite = time(NULL) - (periode * 24 * 3600); 
  fprintf(stdout, 
  "\n%s: la date limite est %s\n", argv[0], asctime(localtime(&temps_limite))); 
 
  /* 
   *  Ouvre le nouveau wtmp en ecriture 
   */ 
  if ((new_fd = open("/var/adm/wtmp", O_WRONLY | O_TRUNC)) < 0) { 
    fprintf(stderr, "%s: Erreur %d d'ouverture de /var/adm/wtmp.\nBye.\n", 
            argv[0], errno); 
    exit(1); 
  } /* if */ 
 
  /* 
   *  Ouvre la copie de wtmp en lecture 
   */ 
  if ((old_fd = open("/tmp/wtmp", O_RDONLY)) < 0) { 
    fprintf(stderr, "%s: Erreur %d d'ouverture de /tmp/wtmp.\nBye.\n", 
            argv[0], errno); 
    exit(1); 
  } /* if */ 
 
  /* 
   * En partant du debut du fichier, on compare les dates 
   * et si elles sont trop vieilles, on les oublies. 
   * Lorsqu'elles sont dans la periode, on les garde dans 
   * le fichier /var/adm/wtmp. 
   */ 
  while (read(old_fd, &wtmp_rec, wtmp_rec_sz) == wtmp_rec_sz) { 
    if (wtmp_rec.ut_time >= temps_limite) { 
      do { 
        if (write(new_fd, &wtmp_rec, wtmp_rec_sz) != wtmp_rec_sz) { 
          fprintf(stderr, "%s: Erreur %d d'ecriture du record.\nBye.",  
                  argv[0], errno); 
          exit(1); 
        } /* if */ 
      } while (read(old_fd, &wtmp_rec, wtmp_rec_sz) == wtmp_rec_sz ); 
    } /* if */ 
  } /* while */ 
 
  exit(0);                                      /* Sortie elegante */ 
 
} /* main() */ 
---------- 
X-Sun-Data-Type: c-file 
X-Sun-Data-Name: wtmpxcut.c 
X-Sun-Charset: us-ascii 
X-Sun-Content-Lines: 89 
 
/*----------------------------------------------------------------------* 
 *                                                                      * 
 * Description: Source du fichier exec. /equipe/sysadmin/bin/wtmpxcut   * 
 *              qui permet de reduire le fichier /var/adm/wtmpx en enle-* 
 *              vant toutes les entrees plus vieilles qu'une certaine   * 
 *              date specifiee en parametre. Si aucun parametre n'est   * 
 *              specifie, on utilise une valeur par defaut (DELAIS).    * 
 *                                                                      * 
 *----------------------------------------------------------------------*/ 
 
#include <stdio.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <utmpx.h> 
#include <time.h> 
#include <errno.h> 
 
#define DELAIS  (time_t) (30)                           /* en jour */ 
 
int main(argc, argv) 
int argc; 
char **argv; 
{ 
  struct  utmpx wtmpx_rec; 
  int     old_fd, new_fd; 
  int     wtmpx_rec_sz = sizeof(wtmpx_rec); 
  time_t  periode, temps_limite; 
 
  if (argc > 1) 
      periode = (time_t) atoi(argv[1]); 
  else 
      periode = DELAIS; 
 
  /* 
  * Copie de /var/adm/wtmpx dans /tmp/wtmpx 
  */ 
  putenv("IFS=' \t\n'");                        /* Securite */ 
  putenv("PATH=/usr/bin");                      /* Securite */ 
  if (system("cp /var/adm/wtmpx /tmp/wtmpx") < 0) { 
    fprintf(stderr,"%s: Erreur en copiant wtmpx dans /tmp.\nBye.\n",argv[0]); 
    exit(1); 
  } /* if */ 
 
  /* 
   *  Calcule du temps limite en time_t   
   */ 
  temps_limite = time(NULL) - (periode * 24 * 3600); 
  fprintf(stdout, 
  "\n%s: la date limite est %s\n", argv[0], asctime(localtime(&temps_limite))); 
 
  /* 
   *  Ouvre le nouveau wtmp en ecriture 
   */ 
  if ((new_fd = open("/var/adm/wtmpx", O_WRONLY | O_TRUNC)) < 0) { 
    fprintf(stderr, "%s: Erreur %d d'ouverture de /var/adm/wtmpx.\nBye.\n", 
            argv[0], errno); 
    exit(1); 
  } /* if */ 
 
  /* 
   *  Ouvre la copie de wtmp en lecture 
   */ 
  if ((old_fd = open("/tmp/wtmpx", O_RDONLY)) < 0) { 
    fprintf(stderr, "%s: Erreur %d d'ouverture de /tmp/wtmpx.\nBye.\n", 
            argv[0], errno); 
    exit(1); 
  } /* if */ 
 
  /* 
   * En partant du debut du fichier, on compare les dates 
   * et si elles sont trop vieilles, on les oublies. 
   * Lorsqu'elles sont dans la periode, on les garde dans 
   * le fichier /var/adm/wtmpx. 
   */ 
  while (read(old_fd, &wtmpx_rec, wtmpx_rec_sz) == wtmpx_rec_sz) { 
    if (wtmpx_rec.ut_xtime >= temps_limite) { 
      do { 
        if (write(new_fd, &wtmpx_rec, wtmpx_rec_sz) != wtmpx_rec_sz) { 
          fprintf(stderr, "%s: Erreur %d d'ecriture du record.\nBye.",  
                  argv[0], errno); 
          exit(1); 
        } /* if */ 
      } while (read(old_fd, &wtmpx_rec, wtmpx_rec_sz) == wtmpx_rec_sz ); 
    } /* if */ 
  } /* while */ 
 
  exit(0);                                      /* Sortie elegante */ 
 
} /* main() */ 
 
======================================================================



This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:10:25 CDT