home *** CD-ROM | disk | FTP | other *** search
- Path: comp-sources-3b1
- From: dave@galaxia.network23.com (David H. Brierley)
- Subject: v02i028: Trim wtmp file to a manageable size, Part01/01
- Newsgroups: comp.sources.3b1
- Approved: dave@galaxia.network23.com
- X-Checksum-Snefru: eb2b7a6f 8fa448ad 75249185 aa982262
-
- Submitted-by: dave@galaxia.network23.com (David H. Brierley)
- Posting-number: Volume 2, Issue 28
- Archive-name: wtrim/part01
-
- This is the README file for the Dave Brierley collection of miscellaneous
- source programs. The collection is posted in seven separate pieces but
- all of the source came from the "misc" directory on my machine. As a result
- of this, there is only one README file and only one Makefile, although each
- of the seven postings will contain a copy of these two files. I suggest
- that you obtain (or save) as many of these postings as you are interested
- in, unpack them all in a single directory, and then compile the sources.
- Note that some of the programs are actually shell scripts and therefore do
- not need compilation.
-
- wclipper.c
- A program to read in the wtmp file and output the tail end of it. Useful
- if you want to maintain an N-day history of who has been using your system.
- The output size can be specified in terms of days or kbytes.
-
- wtmp.fix.sh
- A shell script to control the operation of wclipper.
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 1 (of 1)."
- # Contents: MANIFEST Makefile README wclipper.c wtmp.fix.sh
- # Wrapped by dave@galaxia on Tue Jul 21 10:48:15 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'MANIFEST' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'MANIFEST'\"
- else
- echo shar: Extracting \"'MANIFEST'\" \(251 characters\)
- sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
- X File Name Archive # Description
- X-----------------------------------------------------------
- X MANIFEST 1
- X Makefile 1
- X README 1
- X wclipper.c 1
- X wtmp.fix.sh 1
- END_OF_FILE
- if test 251 -ne `wc -c <'MANIFEST'`; then
- echo shar: \"'MANIFEST'\" unpacked with wrong size!
- fi
- # end of 'MANIFEST'
- fi
- if test -f 'Makefile' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'Makefile'\"
- else
- echo shar: Extracting \"'Makefile'\" \(374 characters\)
- sed "s/^X//" >'Makefile' <<'END_OF_FILE'
- XCFLAGS = -O
- X
- Xall: bsdln disktest email ndf techo wclipper
- X
- Xbsdln: bsdln.o
- X $(CC) bsdln.o
- X mv a.out bsdln
- X
- Xdisktest: disktest.o
- X $(CC) disktest.o
- X mv a.out disktest
- X
- Xemail: email.o
- X $(CC) email.o
- X mv a.out email
- X
- Xndf: ndf.o
- X $(CC) ndf.o
- X mv a.out ndf
- X
- Xtecho: techo.o
- X $(CC) techo.o
- X mv a.out techo
- X
- Xwclipper: wclipper.o
- X $(CC) wclipper.o
- X mv a.out wclipper
- X
- END_OF_FILE
- if test 374 -ne `wc -c <'Makefile'`; then
- echo shar: \"'Makefile'\" unpacked with wrong size!
- fi
- # end of 'Makefile'
- fi
- if test -f 'README' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'README'\"
- else
- echo shar: Extracting \"'README'\" \(4280 characters\)
- sed "s/^X//" >'README' <<'END_OF_FILE'
- XThis is the README file for the Dave Brierley collection of miscellaneous
- Xsource programs. The collection is posted in seven separate pieces but
- Xall of the source came from the "misc" directory on my machine. As a result
- Xof this, there is only one README file and only one Makefile, although each
- Xof the seven postings will contain a copy of these two files. I suggest
- Xthat you obtain (or save) as many of these postings as you are interested
- Xin, unpack them all in a single directory, and then compile the sources.
- XNote that some of the programs are actually shell scripts and therefore do
- Xnot need compilation.
- X
- XINSTALLATION INSTRUCTIONS:
- X1. Compile all the source programs by typing "make all". Edit the Makefile
- X if you did not unpack all seven of the pieces. Note that the Makefile
- X does not contain explicit commands for using the shared library. I always
- X depend on "ccc" to do this for me.
- X2. Copy the resultant executables to your favorite bin directory. I always
- X use "/usr/local/bin".
- X3. Copy the various shell scripts to the bin directory and make then executable
- X using the chmod command. The shell scripts are all distributed with a
- X suffix of ".sh". I suggest you remove this suffix when you install it, but
- X that is entirely up to you.
- X
- X
- XDescription of programs included in this package. There is a line of dashes
- Xseparating each of the seven pieces.
- X
- Xbsdln.c
- X A version of the ln command that follows the BSD behaviour. I.e. if the
- X target file exists, the command will fail. The standard 3b1 version will
- X remove the target.
- X
- X--------------------------------------------------------------------------
- X
- Xinstall.sh
- X A shell script version of the BSD install command.
- X
- Xnull.sh
- X Zero out one or more files.
- X
- Xtolower.sh
- X Convert file names to lower case. Requires ksh.
- X
- Xtoupper.sh
- X Convert file names to upper case. Requires ksh.
- X
- X--------------------------------------------------------------------------
- X
- Xndf.c
- X Almost emulates the BSD df command. I say "almost" because I chose to
- X display the numbers in terms of blocks instead of kbytes since everything
- X else on the machine displays sizes in blocks. Supports the "-i" option
- X to displays inode information. Also supports specifying any random
- X directory as an argument and it will figure out what file system it is.
- X
- X--------------------------------------------------------------------------
- X
- Xdisktest.c
- X A program used by the format script to test the floppy disk to be doubly
- X sure that it is usable.
- X
- Xformat.sh
- X Format a floppy disk. Asks questions to determine desired parameters, such
- X as number of cylinders and number of sectors. Will optionally run an
- X intensive surface test of the floppy (see disktest.c), build a file system
- X structure, and make the floppy bootable. The main processing is done in a
- X loop so you can format multiple floppies easily.
- X
- Xnewfs.sh
- X Reads the VHB from the floppy and then builds a file system structure on it.
- X
- X--------------------------------------------------------------------------
- X
- Xtecho.c
- X A version of echo that allows direct access to termcap capabilities. A lot
- X easier to use than intermixing calls to echo with calls to tput.
- X
- Xtecho.1
- X Hey, I actually wrote a man page for this one!
- X
- X--------------------------------------------------------------------------
- X
- Xwclipper.c
- X A program to read in the wtmp file and output the tail end of it. Useful
- X if you want to maintain an N-day history of who has been using your system.
- X The output size can be specified in terms of days or kbytes.
- X
- Xwtmp.fix.sh
- X A shell script to control the operation of wclipper.
- X
- X--------------------------------------------------------------------------
- X
- Xemail.c
- X A version of the "email" program. This program should be installed as
- X /usr/bin/email and it will be used by pcmgr (or by smgr) when you click
- X on the envelope icon. It provides a safe interface to the mail program
- X by making sure the uid is set correctly and by doing a chdir to the
- X users home directory (both of which are already being done by pcmgr).
- X This version also provides a unique feature of reading an "rc" file
- X from the users home directory (~/.email.rc), which can be used to specify
- X what mail program to use. See the sample provided.
- X
- Xemail.rc
- X Sample .email.rc file.
- END_OF_FILE
- if test 4280 -ne `wc -c <'README'`; then
- echo shar: \"'README'\" unpacked with wrong size!
- fi
- # end of 'README'
- fi
- if test -f 'wclipper.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'wclipper.c'\"
- else
- echo shar: Extracting \"'wclipper.c'\" \(8993 characters\)
- sed "s/^X//" >'wclipper.c' <<'END_OF_FILE'
- X/*--------------------------------------------------------------
- X*
- X* Program: wclipper
- X*
- X* This program is used to sanely trim the wtmp file by removing
- X* entries from the beginning. Options allow for trimming the
- X* file based on the time stamps in the entries or simply keeping
- X* the last N blocks of the file.
- X*
- X* David H. Brierley
- X* Raytheon Submarine Signal Division
- X* Portsmouth, RI 02871
- X*
- X*--------------------------------------------------------------*/
- X
- X#include <stdio.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <utmp.h>
- X#ifdef BSD
- X# include <strings.h>
- X# include <sys/time.h>
- X#else
- X# include <string.h>
- X# include <time.h>
- X#endif
- X
- X#define UBLOCK 4096
- X#define UBUFSIZ UBLOCK * sizeof (struct utmp)
- X#define WTMPFILE "/usr/adm/wtmp"
- X
- Xstruct utmp *utmp;
- Xstruct utmp ubuffer[UBLOCK];
- X
- X#ifndef lint
- Xextern char *optarg;
- X#else
- Xstatic char *optarg;
- X#endif
- X
- Xextern char *malloc ();
- Xextern long lseek ();
- Xextern time_t time ();
- Xextern void exit ();
- Xextern void perror ();
- X
- Xmain (argc, argv)
- Xint argc;
- Xchar *argv[];
- X{
- X int optch;
- X int skip_size;
- X int verbose;
- X time_t now;
- X time_t clip_time;
- X long clip_size;
- X char *infile;
- X char *outfile;
- X
- X skip_size = 10240;
- X (void) time (&now);
- X clip_time = 0;
- X clip_size = 0;
- X verbose = 0;
- X infile = WTMPFILE;
- X outfile = NULL;
- X
- X /*
- X * Scan the argument list
- X */
- X while ((optch = getopt (argc, argv, "i:o:d:h:k:s:v")) != EOF) {
- X switch (optch) {
- X case 'd': /* trim at this many days */
- X clip_time = atoi (optarg) * 24;
- X break;
- X case 'h': /* trim at this many hours */
- X clip_time = atoi (optarg);
- X break;
- X case 'k': /* keep this many Kbytes of data */
- X clip_size = atoi (optarg);
- X break;
- X case 's': /* number of entries to skip while scanning */
- X skip_size = atoi (optarg);
- X break;
- X case 'i': /* name of input file */
- X infile = malloc ((unsigned) strlen (optarg) + 1);
- X (void) strcpy (infile, optarg);
- X break;
- X case 'o': /* name of output file */
- X outfile = malloc ((unsigned) strlen (optarg) + 1);
- X (void) strcpy (outfile, optarg);
- X break;
- X case 'v': /* produce verbose output */
- X verbose = 1;
- X break;
- X default:
- X (void) printf ("Usage: %s: %s\n",
- X "-ofilename [-ifilename] [-dN] [-hN] [-kN] [-sN]",
- X argv[0]);
- X exit (1);
- X }
- X }
- X
- X /*
- X * Error if no output file was specified. Input file defaults to
- X * /usr/adm/wtmp.
- X */
- X if (outfile == NULL) {
- X (void) printf ("Error: no output file specified\n");
- X exit (1);
- X }
- X
- X /*
- X * If no clip time or clip size is given, default action is to clip file
- X * at seven days.
- X */
- X if ((clip_time == 0) && (clip_size == 0)) {
- X clip_time = 7 * 24;
- X }
- X
- X /*
- X * Make sure the user did not give both a time and size clip amount
- X */
- X if ((clip_size > 0) && (clip_time > 0)) {
- X (void) printf ("Error: -s option conflicts with -d/-h\n");
- X exit (1);
- X }
- X
- X /*
- X * Do the size clipping. This is the easiest case
- X */
- X if (clip_size > 0) {
- X size_clipper (infile, outfile, clip_size, verbose);
- X exit (0);
- X }
- X
- X /*
- X * Convert the time spec into seconds and do the clipping
- X */
- X if (clip_time > 0) {
- X clip_time *= 3600; /* convert hours to seconds */
- X if (clip_time > now) {
- X (void) printf ("Error: time spec is greater than current time\n");
- X exit (1);
- X }
- X clip_time = now - clip_time; /* keep records newer than clip_time */
- X time_clipper (infile, outfile, clip_time, skip_size, verbose);
- X exit (0);
- X }
- X
- X /*
- X * If I get to here, something is wrong so print a message
- X */
- X (void) printf ("Error: invalid combo of options, no action performed\n");
- X return (1);
- X
- X}
- X
- Xsize_clipper (infile, outfile, size, verbose)
- Xchar *infile;
- Xchar *outfile;
- Xlong size;
- Xint verbose;
- X{
- X struct stat sbuf;
- X int nbytes;
- X int fd1;
- X int fd2;
- X
- X size *= 1024; /* convert Kbytes to bytes */
- X size /= sizeof (struct utmp); /* How many utmp records is that? */
- X size *= sizeof (struct utmp); /* convert back to bytes */
- X
- X if (verbose) {
- X (void) printf ("trimming file to %d bytes (%d records)\n",
- X size, size / sizeof (struct utmp));
- X }
- X if (stat (infile, &sbuf) == -1) {
- X perror ("wclipper");
- X (void) printf ("Unable to stat file '%s'\n",
- X infile);
- X exit (1);
- X }
- X if ((fd1 = open (infile, 0)) == -1) {
- X perror ("wclipper");
- X (void) printf ("Unable to open file '%s' for input\n",
- X infile);
- X exit (1);
- X }
- X (void) umask (0); /* make sure umask does not interfere */
- X if ((fd2 = creat (outfile, (int) (sbuf.st_mode & 0777))) == -1) {
- X perror ("wclipper");
- X (void) printf ("Unable to create output file '%s'\n",
- X outfile);
- X exit (1);
- X }
- X if (sbuf.st_size > size) {
- X size = sbuf.st_size - size;
- X if (lseek (fd1, size, 0) == -1) {
- X perror ("wclipper");
- X (void) printf ("I/O error seeking to position %ld in file %s\n",
- X size, infile);
- X (void) close (fd1);
- X (void) close (fd2);
- X exit (1);
- X }
- X }
- X while ((nbytes = read (fd1, (char *) ubuffer, UBUFSIZ)) > 0) {
- X if (write (fd2, (char *) ubuffer, (unsigned) nbytes) != nbytes) {
- X perror ("wclipper");
- X (void) printf ("I/O error writing %d bytes to file %s\n",
- X nbytes, outfile);
- X (void) close (fd1);
- X (void) close (fd2);
- X exit (1);
- X }
- X }
- X
- X if (close (fd1) == -1) {
- X perror ("wclipper");
- X (void) printf ("I/O error reported while closing file %s\n",
- X infile);
- X (void) close (fd2);
- X exit (1);
- X }
- X if (close (fd2) == -1) {
- X perror ("wclipper");
- X (void) printf ("I/O error reported while closing file %s\n",
- X outfile);
- X exit (1);
- X }
- X if (verbose) {
- X (void) printf ("copy completed successfully\n");
- X }
- X}
- X
- Xtime_clipper (infile, outfile, clip_time, skip_size, verbose)
- Xchar *infile;
- Xchar *outfile;
- Xtime_t clip_time;
- Xint skip_size;
- Xint verbose;
- X{
- X struct stat sbuf;
- X long seekamt;
- X long seekpos;
- X int fd1;
- X int fd2;
- X int nbytes;
- X
- X if (verbose) {
- X (void) printf ("trimming file at %s",
- X ctime (&clip_time));
- X }
- X if ((fd1 = open (infile, 0)) == -1) {
- X (void) printf ("Unable to open file '%s' for input\n",
- X infile);
- X exit (1);
- X }
- X if (stat (infile, &sbuf) == -1) {
- X (void) printf ("Unable to stat file '%s'\n",
- X infile);
- X exit (1);
- X }
- X (void) umask (0); /* make sure umask does not interfere */
- X if ((fd2 = creat (outfile, (int) (sbuf.st_mode & 0777))) == -1) {
- X (void) printf ("Unable to create output file '%s'\n",
- X outfile);
- X exit (1);
- X }
- X seekamt = skip_size * sizeof (struct utmp);
- X seekpos = 0;
- X while (1) {
- X if (verbose) {
- X (void) printf ("seeking to record %d: ",
- X seekpos / sizeof (struct utmp));
- X (void) fflush (stdout);
- X }
- X if (lseek (fd1, seekpos, 0) == -1) {
- X (void) printf ("I/O error seeking to position %ld in file %s\n",
- X seekpos, infile);
- X exit (1);
- X }
- X nbytes = read (fd1, (char *) ubuffer, sizeof (struct utmp));
- X if (nbytes != sizeof (struct utmp)) {
- X (void) printf ("I/O error reading input file %s\n",
- X infile);
- X exit (1);
- X }
- X utmp = ubuffer;
- X if (verbose) {
- X (void) printf ("time stamp = %s",
- X ctime (&utmp -> ut_time));
- X }
- X if (utmp -> ut_time >= clip_time) {
- X if ((skip_size == 1) || (seekpos == 0)) {
- X break;
- X }
- X skip_size /= 2;
- X seekpos -= seekamt;
- X if (seekpos < 0) {
- X seekpos = 0;
- X }
- X if (skip_size < 1) {
- X skip_size = 1;
- X }
- X seekamt = skip_size * sizeof (struct utmp);
- X }
- X while ((seekpos + seekamt > sbuf.st_size) && (skip_size > 1)) {
- X skip_size /= 2;
- X seekamt = skip_size * sizeof (struct utmp);
- X }
- X seekpos += seekamt;
- X }
- X
- X if (lseek (fd1, seekpos, 0) == -1) {
- X (void) printf ("I/O error seeking to position %ld in file %s\n",
- X seekpos, infile);
- X exit (1);
- X }
- X
- X if (verbose) {
- X (void) printf ("begin copying at record number %d\n",
- X seekpos / sizeof (struct utmp));
- X }
- X
- X while ((nbytes = read (fd1, (char *) ubuffer, UBUFSIZ)) > 0) {
- X if (write (fd2, (char *) ubuffer, (unsigned) nbytes) != nbytes) {
- X perror ("wclipper");
- X (void) printf ("I/O error writing %d bytes to file %s\n",
- X nbytes, outfile);
- X (void) close (fd1);
- X (void) close (fd2);
- X exit (1);
- X }
- X }
- X
- X if (close (fd1) == -1) {
- X perror ("wclipper");
- X (void) printf ("I/O error reported while closing file %s\n",
- X infile);
- X (void) close (fd2);
- X exit (1);
- X }
- X if (close (fd2) == -1) {
- X perror ("wclipper");
- X (void) printf ("I/O error reported while closing file %s\n",
- X outfile);
- X exit (1);
- X }
- X if (verbose) {
- X (void) printf ("copy completed successfully\n");
- X }
- X}
- END_OF_FILE
- if test 8993 -ne `wc -c <'wclipper.c'`; then
- echo shar: \"'wclipper.c'\" unpacked with wrong size!
- fi
- # end of 'wclipper.c'
- fi
- if test -f 'wtmp.fix.sh' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'wtmp.fix.sh'\"
- else
- echo shar: Extracting \"'wtmp.fix.sh'\" \(362 characters\)
- sed "s/^X//" >'wtmp.fix.sh' <<'END_OF_FILE'
- X: 'sh or ksh'
- Xtrap ':' ERR
- Xif test $(/bin/who | wc -l) -ne 0; then exit 0; fi
- Xgetoff.sh 000
- Xsleep 30
- Xif test $(/bin/who | wc -l) -ne 0; then exit 0; fi
- X/usr/local/bin/wclipper -i/etc/wtmp -o/tmp/wtmp -d14 -v
- XST=$?
- Xgeton.sh 000
- Xif test ${ST} -ne 0; then exit ${ST}; fi
- Xmv /etc/wtmp /etc/wtmp.old;mv /tmp/wtmp /etc/wtmp
- Xchmod 644 /etc/wtmp
- Xrm /etc/wtmp.old
- Xexit 0
- END_OF_FILE
- if test 362 -ne `wc -c <'wtmp.fix.sh'`; then
- echo shar: \"'wtmp.fix.sh'\" unpacked with wrong size!
- fi
- chmod +x 'wtmp.fix.sh'
- # end of 'wtmp.fix.sh'
- fi
- echo shar: End of archive 1 \(of 1\).
- cp /dev/null ark1isdone
- MISSING=""
- for I in 1 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have the archive.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
- --
- David H. Brierley
- Home: dave@galaxia.network23.com; Work: dhb@quahog.ssd.ray.com
- Send comp.sources.3b1 submissions to comp-sources-3b1@galaxia.network23.com
- %% Can I be excused, my brain is full. **
-