I have a couple of accounts scattered across various random Linux boxes, and as a grateful and polite user, I do my best to pitch in and help with things like system security and keeping the filesystem neat and tidy. To assist me in both tasks, I whipped up a small set of programs and scripts that mail me the logs of the day as well as rotate them out when they get too large for their own good. I realize that IRIX already has such nifty functions set up for it, but the distributions of Linux I keep running into don't have any such luxuries set up. So I made my own, and I put them here because I figured maybe some other Linux user like myself might have a need for them. Why are they a bad idea? Because in certain respect, they complicate matters and function in that sort of "Swiss watch" fashion where things are constantly ticking back and forth and moving in and out. The setup could be simpler, but it's not.
There are two programs here, one a C program and one a shell script. The C program stemmed out of an attempt to make a Linux version of the IRIX "stat" command, and the shell script was just a more convenient way of doing things. All you do is run them from cron with an appropriate timing interval so things don't conflict. There's no need to restart (well, no need to kill -HUP at least) the daemon using the logs since the technique of catting /dev/null to the log effectively erases it without changing its file descriptor information so the daemon doesn't lose track of it. It's pretty straightforward what happens here; the "process" script mails all the logs generated since it was last run on a log specified on the command line, and concatenates that log onto a larger log file. The "rotate" command checks the specified file against the specified size, and if it is too large, renames by appending a .old extension to it, and then creates a new zero-size file with the original name.
If for some reason you implement these programs, please e-mail me and let me know. I'm just curious. No, they aren't the best bits of programming on the planet, and yes, you could easily do it all through Perl with more finesse, but like most of my software ideas, they spring out of programming exercises. Should compile under IRIX 6.3 and Linux, though it's mainly meant for use with Linux.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#ifdef __linux__
#include <sys/stat.h>
#include <unistd.h>
#elif defined(__sgi)
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#endif
int main(int argc, char *argv[])
{
struct
stat target;
char ext[]
= ".old";
char *newfile;
size_t
length;
int rotatesize;
if (argc
!= 3)
{
fprintf(stderr, "Usage: %s <file> <value>\n", argv[0]);
fprintf(stderr, " <file> is the name of the file to rotate.\n");
fprintf(stderr, " <value> is the size (in bytes) the file
must\n");
fprintf(stderr, "
be greater than for rotation.\n");
exit(-1);
}
if (stat(argv[1],
&target))
{
perror("Unable to open file");
exit(-1);
}
rotatesize
= atoi(argv[2]);
if (rotatesize
<= target.st_size)
{
length = strlen(argv[1]);
if ((newfile = (char *) malloc(length * sizeof(char))) == NULL)
{
fprintf(stderr, "Malloc failed, don't ask me why.\n");
exit(-1);
}
strcpy(newfile, argv[1]);
strcat(newfile, ext);
if (rename(argv[1], newfile))
{
perror("Error renaming original file");
exit(-1);
}
if ((creat(argv[1], target.st_mode)) < 0)
{
perror("Error creating new file");
exit(-1);
}
exit(0);
}
else
{
exit(1);
}
}
#!/bin/sh
#
# Usage: process <file to process> <account
to mail>
#
if [ -s $1 ]
then
/bin/mail
-s "$1" $2 < $1
cat $1
>> $1.log
cat /dev/null
> $1
fi
# Process the logs, e-mail the day's logs to root.
30 01 * * * /usr/local/sbin/process
/var/log/messages root
32 01 * * * /usr/local/sbin/process
/var/log/syslog root
33 01 * * * /usr/local/sbin/process
/var/log/xferlog root
37 01 * * * /usr/local/sbin/process
/var/log/maillog root
#
# Rotate the larger log files as necessary.
01 04 * * 0 /usr/local/sbin/rotate
/var/log/messages.log 10240
02 04 * * 0 /usr/local/sbin/rotate
/var/log/syslog.log 10240
03 04 * * 0 /usr/local/sbin/rotate
/var/log/xferlog.log 10240
04 04 * * 0 /usr/local/sbin/rotate
/var/log/maillog.log 10240