
/*
 *  TRIMFILE file1 file2 .. filen -lines
 *
 *  (C) Copyright 1989-1990 by Matthew Dillon,  All Rights Reserved.
 *
 *  Trims the specified files to the specified number of lines.  Each
 *  file is read and the last N lines written back.
 *
 *  Normally used to trim log files based on a crontab entry.  If no
 *  -lines argument is given the file is trimmed to 100 lines.
 *
 *  Each line may be up to 255 characters in length.
 */

#include <stdio.h>
#include <stdlib.h>

#define LINSIZE 256

char	**LineBuf;
long	Lines = 100;

void	MemErr();
void	TrimFile();

void
main(ac, av)
char *av[];
{
    short i;
    for (i = 1; i < ac; ++i) {
	if (av[i][0] == '-')
	    Lines = atol(av[i] + 1);
    }
    if (Lines < 0) {
	fprintf(stderr, "Illegal line specification %d\n", Lines);
	exit(1);
    }

    /*
     *	Allocating one more than necessary handles the Lines == 0 case
     *	as well as supplying a scratch buffer for the last fgets that
     *	fails.
     */

    LineBuf = malloc(sizeof(char *) * (Lines + 1));
    if (LineBuf == NULL)
	MemErr();
    for (i = 0; i <= Lines; ++i) {
	LineBuf[i] = malloc(LINSIZE);
	if (LineBuf[i] == NULL)
	    MemErr();
    }
    for (i = 1; i < ac; ++i) {
	char *ptr = av[i];

	if (*ptr == '-')
	    continue;
	TrimFile(ptr);
    }
}

void
MemErr()
{
    fprintf(stderr, "Not enough memory!\n");
    exit(1);
}

void
TrimFile(name)
char *name;
{
    FILE *fi = fopen(name, "r");
    long rep;
    long i;

    if (fi == NULL)
	return;

    i = 0;
    rep = 0;
    while (fgets(LineBuf[i], LINSIZE, fi)) {
	if (++i > Lines) {
	    i = 0;
	    rep = 1;
	}
    }
    fclose(fi);

    if (rep == 0)
	return;

    if (fi = fopen(name, "w")) {
	long j;
	for (j = Lines; j; --j) {
	    if (++i > Lines)
		i = 0;
	    fputs(LineBuf[i], fi);
	}
	fclose(fi);
    }
}

