/*---[ util.c ]-------------------------------------------------------
 * Copyright (C) 2000, 2001 Tomas Junnonen (majix@sci.fi)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Miscellaneous utility functions
 *--------------------------------------------------------------------*/

#include <config.h>
#include <gnome.h>
#include <stdio.h>
#include <errno.h>


#include "util.h"
#include "parse.h"

/* [ check_version ]
 * Check version on the script file. If it was created for the wrong
 * kernel type or the version was < program version, start fresh.
 */
void
check_version (void)
{
	FILE *f;
	gchar *version = "0.0.0";
	gchar buf[512];
	gint wrong_kernel = FALSE;

	f = fopen (FIRESTARTER_RULES_DIR "/firestarter/firewall.sh", "r");

	if (f == NULL) {
		gnome_config_set_bool ("/firestarter/Druid/firsttime", TRUE);
		gnome_config_sync ();
		return;
	}

	while (fgets (buf, 512, f) != NULL) {
		if (strstr (buf, "by Firestarter "))  {
			version = get_text_between (buf, "by Firestarter ", ",");
			if (strstr (buf, "NETFILTER")) {
				if (!detect_netfilter())
					wrong_kernel = TRUE;
			} else
				if (detect_netfilter ())
					wrong_kernel = TRUE;
			break;
		}
	}

	fclose (f);

	if ((g_strcasecmp (version, VERSION) < 0) || wrong_kernel) {
		GtkWidget *dialog;
		GtkWidget *label;
		int button;

		if (!mkdir (FIRESTARTER_RULES_DIR "/firestarter", 00700))
			perror("Failed to firestarter configuration directory");

		dialog = gnome_dialog_new (_("Old version detected"),
			GNOME_STOCK_BUTTON_YES, GNOME_STOCK_BUTTON_NO, NULL);

		label = gtk_label_new (_(
			"\nA firewall created by an older version of "
			"Firestarter has been detected.\n\n"
			"OK to remove old firewall?\n"
			"Old firewall settings will be stored in "
			FIRESTARTER_RULES_DIR "/firestarter/backup"));
		gtk_box_pack_start (GTK_BOX (GNOME_DIALOG (dialog)->vbox),
			label, FALSE, FALSE, 0);
		gtk_widget_show (label);

		button = gnome_dialog_run_and_close (GNOME_DIALOG (dialog));

		switch (button) {
			case 0:
				if (!mkdir (FIRESTARTER_RULES_DIR "/firestarter/backup", 00700))
					perror("Failed to create backup directory");

				rename (FIRESTARTER_RULES_DIR "/firestarter/firewall.sh",
					FIRESTARTER_RULES_DIR "/firestarter/backup/firewall.sh");
				rename (FIRESTARTER_RULES_DIR "/firestarter/allow-all",
					FIRESTARTER_RULES_DIR "/firestarter/backup/allow-all");
				rename (FIRESTARTER_RULES_DIR "/firestarter/deny-all",
					FIRESTARTER_RULES_DIR "/firestarter/backup/deny-all");
				rename (FIRESTARTER_RULES_DIR "/firestarter/allow-service-all",
					FIRESTARTER_RULES_DIR "/firestarter/backup/allow-service-all");
				rename (FIRESTARTER_RULES_DIR "/firestarter/allow-service-machine",
					FIRESTARTER_RULES_DIR "/firestarter/backup/allow-service-machine");
				rename (FIRESTARTER_RULES_DIR "/firestarter/block-ports",
					FIRESTARTER_RULES_DIR "/firestarter/backup/block-ports");
				rename (FIRESTARTER_RULES_DIR "/firestarter/portfw",
					FIRESTARTER_RULES_DIR "/firestarter/backup/portfw");

				gnome_config_set_bool ("/firestarter/Druid/firsttime", TRUE);
				gnome_config_sync ();
				printf ("Scripts moved to " FIRESTARTER_RULES_DIR "/firestarter/backup\n");
				break;

			case 1:
			case -1:
				printf ("Scripts not removed\n");
				break;
		}
	}
}

/* [ detect_netfilter ]
 * Return true if Linux 2.4 or 2.5 kernel found
 */
gboolean
detect_netfilter (void)
{
	FILE *f;
	gchar buf[512];

	/* The detection is only done once */
	static gboolean detected;
	if (detected != NULL)
		return detected;

	f = fopen ("/proc/version", "r");

	/* Look for ipchains */
	if (f == NULL) {
		perror("/proc/version");
		g_print ("Could not determine kernel version,"
			 "defaulting to 2.2/ipchains");
		detected = FALSE;
		return detected;
	}

	/* Look for netfilter */
	while (fgets (buf, 512, f) != NULL) {
		if ((strstr (buf, " 2.4.") != NULL) || (strstr (buf, " 2.5.") != NULL)) {
			g_print ("NETFILTER detected\n");
			system ("/sbin/modprobe --autoclean ip_tables");
			fclose (f);
			detected = TRUE;
			return detected;
		}
	}

	/* If we can't determine the kernel version, assume ipchains */
	g_print ("Couldn't determine kernel version, assuming IPCHAINS\n");
	fclose (f);
	detected = FALSE;
	return FALSE;
}
