From: zaphod@ctrg.rri.uwo.ca (Lance R. Bailey)
Subject: Re: wtmp, btmp getting to big !!!
Reply-To: zaphod@ctrg.rri.uwo.ca
Organization: University of Western Ontario
Distribution: na
Date: Wed, 16 Dec 1992 10:45:46 GMT

In article <9235110.26727@mulga.cs.mu.OZ.AU> minh@lis.rch.unimelb.edu.au (Minh  
Tran) writes:
>	Is there way to delete entries in wtmp, btmp, they are really
>	chewing up space, thanks.

the traditional way is to cp /dev/null or otherwise zap them out. infact,
accounting zaps them out daily. unfortunatly, this means that you have NO 
record of who was last on and when.

i have a program called startwtmp which massages the wtmp file into keeping
records of the last time anyone was on the machine. it's been running for 
years on my systems each night. handles up to 1000 uids, easily expanded.

i attach it below the sig.
--
Lance R. Bailey  System/Network Manager         Robarts Research Institute
     NeXT/email: zaphod@ctrg.rri.uwo.ca    box: Clinical Trials Resources Group
            fax: +1 519 663 3789                P.O. Box 5015, 100 Perth Dr.
            vox: +1 519 663 3787 x4108          London, Canada N6A 5K8
She's human...well, she's a lawyer, but reasonably human. -Professor Ralph  
Noble

#include <stdio.h>
#include <sys/types.h>
#include <utmp.h>
#include <time.h>

extern struct utmp *getutent();
int compareutmp();

#define MAXUSER 8
#define MAXENTRIES 1000

main(argc,argv) char **argv; int argc;
{   struct utmp *utent;
    struct utmp utsave[MAXENTRIES];
    struct utmp utlogin;
    int nEnt=0,i;

    utmpname(argv[1]); utent = getutent();

    while (utent != NULL)
    {   if (utent->ut_type != USER_PROCESS && utent->ut_type != BOOT_TIME)
        {   if (utent->ut_type == LOGIN_PROCESS) utlogin = *utent;
            utent = getutent(); continue;
        }

        if (!strncmp(utent->ut_user,"INVALID",7)) {utent =  
getutent();continue;}

        if (utent->ut_type == USER_PROCESS)
        {   if ((i,i=finduser(utent,utsave,nEnt))<0) utsave[nEnt++]=*utent; 
            else utsave[i] = *utent;
        }
        else utsave[nEnt++]=*utent;   /* save all boots */

        utent = getutent();
    }

    qsort(utsave,nEnt,sizeof(struct utmp),compareutmp);
    for (i=0;i<nEnt;i++)
    {   write(1,utsave[i],sizeof(struct utmp));
        if (utsave[i].ut_type == BOOT_TIME) continue;
/*
 * check the utmp for this entry, if none, fake a login process
 */
        if (!utmpEnt(utsave[i]))
        {   strncpy(utlogin.ut_id,utsave[i].ut_id,4);
            strncpy(utlogin.ut_line,utsave[i].ut_line,12);
            utlogin.ut_time = utsave[i].ut_time+1;
            write(1,utlogin,sizeof(struct utmp));
        }
    }

    exit(0);
}



int compareutmp(a,b) struct utmp a,b;
{  if (a.ut_time < b.ut_time ) return -1;
   if (a.ut_time > b.ut_time ) return 1;
   return 0;
}



finduser(e,l,n) struct utmp *e;
                struct utmp l[MAXENTRIES];
    int n;
{   while (n>=0) 
    {   if (!strncmp(e->ut_user,l[n].ut_user,MAXUSER)) return n;
        n--;
    }
    return -1;
}



utmpEnt(id) struct utmp id;
{   struct utmp *uts;

    utmpname("/etc/utmp");
    if (uts,uts=getutline(id)) if(id.ut_pid==uts->ut_pid){endutent();return 1;}

    endutent(); return 0;
}




/*
 * EOF
 */

Xref: sparky comp.sys.hp:14183 comp.unix.admin:6690