Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!mailrus!cs.utexas.edu!usc!sdsu!ucsd!ucrmath!gumby From: gumby@ucrmath.UCR.EDU (john donahue) Newsgroups: comp.unix.xenix Subject: Re: Why is wtmp so big? Summary: It doesn't have to be... Keywords: C source code, set TAB width to *4* before viewing! Message-ID: <2910@ucrmath.UCR.EDU> Date: 6 Dec 89 08:13:47 GMT References: <1226@ispi.UUCP> <413@tabbs.UUCP> Reply-To: gumby@ucrmath.UUCP (john donahue) Distribution: usa Organization: Alchemy Software Designs Lines: 219 Products: Communique On-line Information System In article <413@tabbs.UUCP> aris@tabbs.UUCP (Aris Stathakis) writes: >From article <1226@ispi.UUCP>, by jbayer@ispi.UUCP (Jonathan Bayer): >} rfarris@serene.UUCP (Rick Farris) writes: >} >}>Is this a "log" file, composed of numerous /etc/utmp entries? Can I >}>truncate it by copying /etc/utmp to it? Can I delete it altogether, >}>and let it recreate itself? >} >} If you delete it then it will not be recreated. You can truncate it by >} either copying /etc/utmp to it, or by copying /dev/null to it. > >Is there perhaps any program out there ther truncates the /etc/wtmp >file to the 100 most recent entries? > >Since it is a binary file, this is no trivial task. > >Thanks in advance. > >Aris > >-- >Aris Stathakis | Bang: ..!uunet!ddsw1!olsa99!tabbs!aris or aris@tabbs.UUCP > - Gimme a beer and money sandwich.... Hold the bread - > - Waldo (D.R.) Dobbs Well, I thought about this for a bit and then decided it would be a useful utility to have on my own system. Thus, I sat down and wrote it tonight. It was a pretty fun program to write and I think it works pretty well. Perhaps, if I get feedback saying that it works and there's no problems I'll submit it to alt.sources or something since someone else out there might want to play with it. Let me know what you think and REMEMBER: don't look at the source code now, take it, and then set your TAB width to *4* within "vi" or whatever and THEN look at it (Sorry, I like that size of TAB)! =) Cheers! -- John Donahue -- INET: gumby@ucrmath.ucr.edu UUCP: {ucsd, uci, ucdavis}!ucrmath!gumby "Consequences, schmonsequences, as long as I'm rich" -- Daffy Duck -- Here's the code: /* ** wsize.c - Utility program to truncate the /etc/wtmp log file. ** ** NOTE: To properly view this source, set your TAB width to 4! ** ** This program will, if needed, truncate the /etc/wtmp file to the desired ** length of records. By default, this value is 1000, but may be defined by ** passing the numeric argument during program execution. ** ** The reason this default value is 1000 is that the utmp structure itself ** is VERY small (36 bytes on my system) and a 36K file is trivial when ** most wtmp files usually get to be several hundred thousand before we ** get around to truncating them! Also, I'm not an expert, but "weird" ** things may happen if you delete recent wtmp records, it's best to keep ** the last 1000 or so IMHO. ** ** To compile: cc wsize.c -o wsize ** su to root: chown bin wsize ** chgrp bin wsize ** chmod 700 wsize ** mv wsize /etc ** ** Written By: John Donahue (alchemy!gumby@ucrmath.ucr.edu) on 05-Dec-89 */ #include #include #include #include #include #include #define PASS struct passwd #define STAT struct stat #define UTMP struct utmp #define TMPNAM "/tmp/wtmp" /* ** WSIZE */ main (argc, argv) int argc; /* Argument counter from command line */ char *argv[]; /* Arguments from command line (strings) */ { int fs, ft; /* File descriptors (source, target) */ int wsize; /* Desired size of /etc/wtmp file */ long begin; /* Where to begin copying (lseek value) */ PASS *pwuser; /* Structure containing passwd entry */ PASS *getpwnam (); /* System call to get passwd entry by login */ STAT filestat; /* File statistics structure */ UTMP temp; /* Temporary utmp structure */ /* ** If argument counter equals two, then assume that argument is the desired ** length (in utmp records) of the eventual /etc/wtmp file. */ if (argc == 2) wsize = atoi (argv[1]); else wsize = 1000; /* ** If UID and GID of login "bin" cannot be discerned, then abort program ** as these are necessary arguments for "chown ()" system call later. */ if ((pwuser = getpwnam ("bin")) == (PASS *) 0) { fprintf (stderr, "%s: Cannot locate user \"bin\".\n", argv[0]); exit (1); } /* ** Determine existance and size of current /etc/wtmp file. If it doesn't ** exist, abort program (accounting is not kept on system). If it does, ** make sure there is work to be done (current size is greater than ** desired size). */ if (stat ("/etc/wtmp", &filestat)) { fprintf (stderr, "%s: \"/etc/wtmp\" not present!\n", argv[0]); exit (1); } if (filestat.st_size < (wsize * sizeof (UTMP))) { fprintf (stderr, "%s: \"/etc/wtmp\" too small! (Current size: %d records)\n", argv[0], filestat.st_size / sizeof (UTMP)); exit (1); } /* ** Attempt to open both the existing /etc/wtmp file and a temporary file in ** the /tmp directory. */ if ((fs = open ("/etc/wtmp", O_RDONLY)) == -1) { fprintf (stderr, "%s: Could not open \"/etc/wtmp!\"\n", argv[0]); exit (1); } if ((ft = open (TMPNAM, O_WRONLY | O_CREAT, 0644)) == -1) { fprintf (stderr, "%s: Could not open \"%s!\"\n", argv[0], TMPNAM); close (fs); exit (1); } /* ** Seek to appropriate location within /etc/wtmp file so that copying may ** begin. */ begin = filestat.st_size - (wsize * sizeof (UTMP)); if (lseek (fs, begin, 0) == -1) { fprintf (stderr, "%s: Could not seek \"/etc/wtmp!\"\n", argv[0]); close (fs); close (ft); unlink (TMPNAM); exit (1); } /* ** Copy each record, one at a time, from /etc/wtmp to TMPNAM using successive ** read () and write () system calls. */ while (read (fs, &temp, sizeof (UTMP)) > 0) write (ft, &temp, sizeof (UTMP)); /* ** Close both files and "rename". */ close (fs); close (ft); if (unlink ("/etc/wtmp")) { fprintf (stderr, "%s: Could not unlink \"/etc/wtmp!\"\n", argv[0]); unlink (TMPNAM); exit (1); } if (link (TMPNAM, "/etc/wtmp")) { fprintf (stderr, "%s: Panic! Original wtmp removed, cannot link new!\n", argv[0]); fprintf (stderr, "%s: New wtmp filename is \"%s\", link manually if possible.\n", argv[0], TMPNAM); exit (1); } unlink (TMPNAM); /* ** In case "umask" ruined the intended permissions for the /etc/wtmp file, ** let's set them correctly to make sure. Additionally, the new file may ** be owned by root (since it is assumed that this is going to be executed ** only by root) so let's give it the proper owner and group of "bin". */ chmod ("/etc/wtmp", 00644); chown ("/etc/wtmp", pwuser->pw_uid, pwuser->pw_gid); /* ** Inform user that truncation was successful. */ fprintf (stderr, "%s: \"/etc/wtmp\" successfully truncated to last %d records.\n", argv[0], wsize); exit (0); } /* ** End of wsize.c */