/*
*
* sqlsyslogd
*
* $Log: sqlsyslogd.c,v $
* Revision 1.2  2002/01/05 16:29:36  venglin
* Bugfix
*
* Revision 1.1.1.1  2001/05/21 15:31:50  venglin
* initial import into CVS
*
*
*/

#include <mysql/mysql.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <pwd.h>
#include <sys/types.h>

#define CR		13
#define LF		10

MYSQL db;

static const char rcsid[] =
  "$Id: sqlsyslogd.c,v 1.2 2002/01/05 16:29:36 venglin Exp $";

void usage(av0)
char *av0;
{
	fprintf(stderr, "usage: %s [-h hostname] <-u username> [-p]"
				" <-t table> [database]\n\n", av0);
	exit(0);
}	

void cleanup(x)
int x;
{
	mysql_close(&db);
	exit(0);
}

char *password(void)
{
	FILE *fp;
	static char passwd[BUFSIZ/16];
	char *p;

	if ((fp=fopen(CONF, "r")) == NULL)
		return NULL;

	fgets(passwd, sizeof(passwd), fp);

	if ((p = index(passwd, CR)))
		*p = '\0';
	if ((p = index(passwd, LF)))
		*p = '\0';

	fclose(fp);

	return passwd;
}
	

int main(argc, argv)
int argc;
char **argv;
{
	extern char *optarg;
	extern int optind;
        int ch;
	char buf[BUFSIZ], querybuf[BUFSIZ+100];
	char *loghost, *host, *user, *passwd, *av0, *table, *logprog, *logmesg;
	struct passwd *pw;
	gid_t nobodygid;
	uid_t nobodyuid;

	av0 = argv[0];
	loghost = host = user = passwd = table = logprog = logmesg = NULL;

	while ((ch = getopt(argc, argv, "h:u:pt:")) != -1)
		switch((char)ch)
		{
			case 'h':
				host = optarg;
				break;

			case 'u':
				user = optarg;
				break;

			case 'p':
				passwd = password();
				break;

			case 't':
				table = optarg;
				break;

			case '?':
			default:
					(void)usage(av0);
		}

	argc -= optind;
	argv += optind;

	if (!user || !table)
		(void)usage(av0);

	if (argc < 1)
		(void)usage(av0);

	if ((pw = getpwnam("nobody")) == NULL)
	{
		perror("getpwnam");
		exit(1);
	}

	nobodyuid = pw->pw_uid;
	nobodygid = pw->pw_gid;

	if (setgid(nobodygid) == -1)
	{
		perror("setgid");
		exit(1);
        }

	if (getgid() != nobodygid)
	{
		fprintf(stderr, "getgid() != nobodygid\n");
		exit(1);
	}

	if (setuid(nobodyuid) == -1)
	{
		perror("setuid");
		exit(1);
	}

	if (getuid() != nobodyuid)
	{
		fprintf(stderr, "getuid() != nobodyuid\n");
		exit(1);
	}

	mysql_init(&db);

	if (!mysql_real_connect(&db, host, user, passwd, *argv, 0, NULL, 0))
	{
		fprintf(stderr, "failed to connect to database: %s\n",
			mysql_error(&db));
		exit(1);
	}

	signal(SIGHUP, cleanup);
	signal(SIGINT, cleanup);
	signal(SIGQUIT, cleanup);
	signal(SIGTERM, cleanup);
	signal(SIGSEGV, cleanup);
	signal(SIGBUS, cleanup);

	while(fgets(buf, sizeof(buf), stdin))
	{
		if (strlen(buf) > 18)
		{
			loghost = strtok(buf + 16, " ");
			logprog = strtok(NULL, ":");
			logmesg = buf + 16 + strlen(loghost) +
				strlen(logprog) + 3;

			if (loghost && logprog && logmesg)
			{
				snprintf(querybuf, sizeof(querybuf),
					"INSERT INTO %s (timestamp, host, "
					"prog, mesg) VALUES ('%.15s', '%s', "
					"'%s', '%s')", table, buf,
					loghost, logprog, logmesg);

				if (mysql_query(&db, querybuf))
					fprintf(stderr, "failed to run "
						"query: %s\n",
						mysql_error(&db));
			}
		}
	}

	mysql_close(&db);

	exit(0);
}
