/*---[ druid.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.
 *
 * The druid/wizard functions
 *--------------------------------------------------------------------*/

#include "scriptwriter.h"
#include "firestarter.h"
#include "portfw.h"
#include <libgnomeui/gnome-window-icon.h>

static GdkImlibImage *image;
static GdkImlibImage *watermark;
static GdkColor white;
static GdkColor black;
GList *devicelist = NULL;
gboolean advanced = FALSE;
gboolean masq = TRUE;
gboolean tos = TRUE;

void
quit_druid (GtkWidget *app)
{
	gtk_widget_destroy (app);
	gtk_widget_destroyed (NULL, &app);
}

/* [ sensitivity_flip ]
 * Flips the sensitivity of a given widget
 */
static void
sensitivity_flip (GtkWidget *widget)
{
	if (GTK_WIDGET_IS_SENSITIVE (widget))
		gtk_widget_set_sensitive (widget, FALSE);
	else
		gtk_widget_set_sensitive (widget, TRUE);
}

/* [ device_exists ]
 * If name is a valid network device, it is added to devicelist
 */
static GList*
device_exists (gchar *name)
{
	FILE *f = fopen ("/proc/net/dev", "r");
	gchar buf[512];
	gint l = strlen (name);
	gchar *bp;

	g_assert (f);

	while (fgets (buf, 512, f) != NULL) {
		bp = buf;
		while (*bp == ' ')
			bp++;
		if (strncmp (bp, name, l) == 0 && bp[l] == ':') {
			fclose (f);
			devicelist = g_list_append (devicelist, name);
			return (devicelist);
		}
	}
	fclose(f);
	return (devicelist);
}

/* [ fill_devicelist ]
 * Fill devicelist with valid network interfaces
 * Currently lists modem, isdn, ethernet & bridge devices
 */
static void
fill_devicelist (void)
{
	if (devicelist != NULL)
		return;

	devicelist = device_exists ("ippp0");
	devicelist = device_exists ("ippp1");
	devicelist = device_exists ("ippp2");
	devicelist = device_exists ("ippp3");
	devicelist = device_exists ("ppp0");
	devicelist = device_exists ("ppp1");
	devicelist = device_exists ("ppp2");
	devicelist = device_exists ("ppp3");
	devicelist = device_exists ("eth0");
	devicelist = device_exists ("eth1");
	devicelist = device_exists ("eth2");
	devicelist = device_exists ("eth3");
	devicelist = device_exists ("brg0");
	devicelist = device_exists ("brg1");
	devicelist = device_exists ("brg2");
	devicelist = device_exists ("brg3");
	devicelist = device_exists ("ipsec0");
	devicelist = device_exists ("ipsec1");
	devicelist = device_exists ("ipsec2");
	devicelist = device_exists ("ipsec3");
}

/* [ jump_to ]
 * Jump to a given page in a druid
 */
static gint
jump_to (GnomeDruidPage *currentpage, gpointer druid, GnomeDruidPage *page)
{
		gnome_druid_set_page (GNOME_DRUID (druid), page);
		return TRUE;
}

/* [ branch_next ]
 * Special flow case: From branch we either go to the advanced device page
 * or the simple device page
 */

static gint
set_page (GnomeDruidPage *currentpage, gpointer druid,
	     GnomeDruidPage *nextpage)
{
	if (advanced)
		return FALSE;
	else {
		gnome_druid_set_page (GNOME_DRUID (druid), nextpage);
		return TRUE;
	}
}


/* [ services_back ]
 * Special flow case: From the services page we either go back to the simple
 * devices page or the previous default advanced screen.
 */
static gint
services_back (GnomeDruidPage *currentpage, gpointer druid,
	       GnomeDruidPage *devicepage)
{
	if (advanced)
		return FALSE;
	else {
		gnome_druid_set_page (GNOME_DRUID (druid), devicepage);
		return TRUE;
	}
}

/* [ toggle_ppp ]
 * Toggles the sensitivity on the pppcheck widget, based on external device
 */
static void
toggle_ppp (GtkList *list, GtkWidget *check)
{
	GtkWidget *entry;

	if (!GTK_IS_OBJECT (check))
		return;

	entry = gtk_object_get_data (GTK_OBJECT (check), "entry");

	if (g_strcasecmp (gtk_entry_get_text (GTK_ENTRY (entry)), "ppp0") == 0) {
		gtk_widget_set_sensitive (check, TRUE);
		return;
	}
	if (g_strcasecmp (gtk_entry_get_text (GTK_ENTRY (entry)), "ppp1") == 0) {
		gtk_widget_set_sensitive (check, TRUE);
		return;
	}

	gtk_widget_set_sensitive (check, FALSE);
}

/* [ turn_white ]
 * Change the background of the druid pages to white
 * Shamelessly ripped from gnome-lokkit
 */
static void
turn_white (GtkWidget *page)
{
	GtkStyle *ns;

	ns = gtk_style_copy (page->style);
	gtk_style_ref (ns);
	ns->bg[GTK_STATE_NORMAL] = ns->white;
	ns->fg[GTK_STATE_NORMAL] = ns->black;
	gtk_widget_set_style (page, ns);
	gtk_style_unref (ns);

	gnome_druid_page_standard_set_title_color (GNOME_DRUID_PAGE_STANDARD (page), &black);
}

static void
set_skill (GtkToggleButton *button)
{
	advanced = gtk_toggle_button_get_active (button);
}

/* [ create_branch_page ]
 * Create the contents of the skill level branch page
 */
static GtkWidget*
create_branch_page (Druid *data)
{
	GtkWidget *page;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *vbox;
	GtkWidget *radio1;

	page = gnome_druid_page_standard_new_with_vals (_("Choose your skill level"), NULL);
	turn_white (page);

	table = gtk_table_new (1, 2, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);

	label = gtk_label_new (_(
		"Please choose the skill level best suited to you.\n\n"
		"Simple is recommended for most workstation users with a single computer.\n"
		"Advanced presents you with more options and is meant for experienced users\n"
		"with machines acting as gateways."));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD);

	vbox = gtk_vbox_new (FALSE, 1);
	gtk_table_attach (GTK_TABLE (table), vbox, 0, 1, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 2);

	radio1 = gtk_radio_button_new_with_label (NULL,
		_("Simple firewall setup"));
	gtk_table_attach (GTK_TABLE (table), radio1, 0, 1, 2, 3,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
//	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1),
//		!gnome_config_get_bool ("/firestarter/Druid/advanced=FALSE"));

	data->advanced = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
		_("Advanced firewall setup"));
	gtk_table_attach (GTK_TABLE (table), data->advanced, 0, 1, 3, 4,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD_SMALL);
	gtk_signal_connect (GTK_OBJECT (data->advanced), "toggled",
		GTK_SIGNAL_FUNC (set_skill), NULL);
//	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->advanced),
//		gnome_config_get_bool ("/firestarter/Druid/advanced=FALSE"));

	gtk_widget_show_all (table);

	gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox),
		table, TRUE, TRUE, 0);

	gnome_druid_page_standard_set_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);

	return (page);
}

/* [ create_device_page ]
 * Create the contents of the simple device selection page
 */
static GtkWidget*
create_device_page (Druid *data)
{
	GtkWidget *page;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *hbox;
	GtkWidget *combo;

	GdkImlibImage *logo;

	logo = gdk_imlib_load_image ("/usr/share/pixmaps/firestarter/card.png");
	page = gnome_druid_page_standard_new_with_vals (_("Network Device Configuration"), logo);
	turn_white (page);

	table = gtk_table_new (1, 2, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);

	label = gtk_label_new (_(
		"Please select your Internet connected network device from the\n"
		"drop-down list of detected devices.\n\n"
		"If you use a modem your device name is likely ppp0. If you have a\n"
		"cable modem or a DSL connection, choose eth0."));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD);

	hbox = gtk_hbox_new (FALSE, 1);
	gtk_table_attach (GTK_TABLE (table), hbox, 0, 1, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 2);

 	label = gtk_label_new (_("Detected device(s):"));
	gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 5);

	combo = gtk_combo_new();
	gtk_tooltips_set_tip (ttips, GTK_COMBO (combo)->entry, _(
		"Select your network device from the dropdown list. "
		"Go with the default if unsure."), "");
	fill_devicelist ();
	gtk_combo_set_popdown_strings (GTK_COMBO (combo), devicelist);
	gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 5);

	data->extdevice = (GTK_COMBO (combo)->entry);

	data->pppcheck = gtk_check_button_new_with_label (_(
		"Start the firewall on dial-out"));
	gtk_tooltips_set_tip (ttips, data->pppcheck, _(
		"Check this option and the firewall will start when "
		"you dial your Internet Service Provider. "
		"Only available when using a modem."), "");
	gtk_object_set_data (GTK_OBJECT (data->pppcheck), "entry",
			     GTK_COMBO (combo)->entry);
	gtk_signal_connect (GTK_OBJECT (GTK_COMBO (combo)->list), "selection-changed",
			    GTK_SIGNAL_FUNC (toggle_ppp), data->pppcheck);
	gtk_table_attach (GTK_TABLE (table), data->pppcheck, 0, 2, 2, 3,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	gtk_signal_emit_by_name (GTK_OBJECT (GTK_COMBO (combo)->list),
				 "selection-changed", data->pppcheck);

	data->dhcpcheck = gtk_check_button_new_with_label (_(
		"IP address is assigned via DHCP"));
	gtk_tooltips_set_tip (ttips, data->dhcpcheck, _(
		"Check this option if you need to connect to a DHCP server. "
		"Cable modem users should check this."), "");
	gtk_object_set_data (GTK_OBJECT (data->dhcpcheck), "entry",
			     GTK_COMBO (combo)->entry);
	gtk_table_attach (GTK_TABLE (table), data->dhcpcheck, 0, 2, 3, 4,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	gtk_widget_show_all (table);

	gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox),
			    table, TRUE, TRUE, 0);

	gnome_druid_page_standard_set_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);
	gnome_druid_page_standard_set_logo_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);

	return (page);
}

/* [ create_masq_page ]
 * Create the contents of the ipmasq setup page
 */
static GtkWidget*
create_masq_page (Druid *data)
{
	GtkWidget *page;
	GtkWidget *table;
	GtkWidget *table2;
	GtkWidget *label;
	GtkWidget *radio1;
	GtkWidget *radio2;
	GtkWidget *radio3;
	GtkWidget *entry;
	GtkWidget *combo;
	GtkWidget *align;
	GtkWidget *button;
	GdkImlibImage *logo;

	logo = gdk_imlib_load_image("/usr/share/pixmaps/firestarter/masq.png");

	page = gnome_druid_page_standard_new_with_vals (_(
		"IP Masquerade Configuration"), logo);

	turn_white (page);

	table = gtk_table_new (2, 2, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE (table), GNOME_PAD_SMALL);

	label = gtk_label_new (_(
		"Do you use IP Masquerading on your LAN, allowing all the machines on your network\n"
		"to communicate with the Internet via a single IP address?"));

	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 2, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD_SMALL);

	radio1 = gtk_radio_button_new_with_label (NULL,
		_("Disable masquerading"));
	gtk_table_attach (GTK_TABLE (table), radio1, 0, 2, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1),
		!gnome_config_get_bool ("/firestarter/Druid/masq"));

	radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
		_("Enable masquerading"));
	gtk_table_attach (GTK_TABLE (table), radio2, 0, 2, 2, 3,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD_SMALL);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio2),
		gnome_config_get_bool ("/firestarter/Druid/masq"));


	data->masq = gtk_hbox_new (FALSE, 10);
	gtk_widget_set_sensitive (data->masq, 0);
	gtk_table_attach (GTK_TABLE (table), data->masq, 0, 2, 3, 4,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	gtk_signal_connect_object (GTK_OBJECT (radio2), "toggled",
		GTK_SIGNAL_FUNC (sensitivity_flip), GTK_OBJECT (data->masq));

	table2 = gtk_table_new (2, 5, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE(table2), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE(table2), GNOME_PAD_SMALL);
	gtk_box_pack_start (GTK_BOX (data->masq), table2, FALSE, FALSE, 0);

 	label = gtk_label_new (_("Select your internal network interface:"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table2), label, 0, 1, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	combo = gtk_combo_new();
	gtk_tooltips_set_tip (ttips, GTK_COMBO (combo)->entry, _(
		"This is the device that connects to your LAN. "
		"Go with the default if unsure."), "");
	gtk_combo_set_popdown_strings (GTK_COMBO (combo), devicelist);
	gtk_list_select_item (GTK_LIST (GTK_COMBO (combo)->list), 1);
	gtk_table_attach (GTK_TABLE (table2), combo, 1, 2, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	radio1 = gtk_radio_button_new_with_label (NULL,
		_("Autodetect internal network IP range"));
	gtk_tooltips_set_tip (ttips, radio1, _(
		"Select this and the IP range of your LAN is autodetected."), "");
	gtk_table_attach (GTK_TABLE (table2), radio1, 0, 2, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1),
		!gnome_config_get_bool ("/firestarter/Druid/auto_int_ip"));

	radio3 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
		_("Specify internal network IP range manually (Not recommended)"));
	gtk_tooltips_set_tip (ttips, radio3, _(
		"Select this only if the automatic detection fails."), "");
	gtk_table_attach (GTK_TABLE (table2), radio3, 0, 2, 2, 3,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio3),
		gnome_config_get_bool ("/firestarter/Druid/auto_int_ip"));

	data->auto_int_ip = gtk_table_new (2, 2, FALSE);
	gtk_widget_set_sensitive (data->auto_int_ip, 0);
	gtk_table_attach (GTK_TABLE (table2), data->auto_int_ip, 0, 2, 3, 4,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	gtk_signal_connect_object (GTK_OBJECT (radio3), "toggled",
		GTK_SIGNAL_FUNC (sensitivity_flip), GTK_OBJECT (data->auto_int_ip));
 	label = gtk_label_new (_("Enter the internal network address range:"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (data->auto_int_ip), label, 0, 1, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	entry = gtk_entry_new ();
	gtk_entry_set_text (GTK_ENTRY (entry),
		gnome_config_get_string ("/firestarter/Druid/intrange"));

	gtk_table_attach (GTK_TABLE (data->auto_int_ip), entry, 1, 2, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

 	label = gtk_label_new (_(
		"The network range is given in the form of address/mask. 192.168.0.0/24 is the most\n"
		"common IP range reserved for internal networks."));
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (data->auto_int_ip), label, 0, 2, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	data->intdevice = (GTK_COMBO (combo)->entry);
	data->intrange = entry;


	align = gtk_alignment_new (0.0, 0.0, 0.0, 0.0);
//	gtk_table_attach (GTK_TABLE (table2), align, 0, 1, 4, 5,
//		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	button = gtk_button_new_with_label (_("Port Forwarding"));
	gtk_signal_connect (GTK_OBJECT (button), "clicked",
			    GTK_SIGNAL_FUNC (show_portfw_window), NULL);
	gtk_container_add (GTK_CONTAINER (align), button);


	gtk_widget_show_all (table);

	gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox),
			    table, TRUE, TRUE, 0);

	gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox),
			    align, TRUE, TRUE, 5);


	gnome_druid_page_standard_set_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);
	gnome_druid_page_standard_set_logo_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);

	return (page);
}

/* [ create_services_page ]
 * Create the contents of the service selection page
 */
static GtkWidget*
create_services_page (Druid *data)
{
	GtkWidget *page;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *vbox;
	GtkWidget *radio1, *radio2;

	page = gnome_druid_page_standard_new_with_vals (_(
		"Services Configuration"), NULL);

	turn_white (page);

	table = gtk_table_new (5, 1, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);

	label = gtk_label_new (_(
		"Do you run server software on your machine and want other people to have access\n"
		"to the network services you provide?"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD_SMALL);

	radio1 = gtk_radio_button_new_with_label (NULL,
		_("No, I do not run any public network services on my machine"));
	gtk_table_attach (GTK_TABLE (table), radio1, 0, 1, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1),
		!gnome_config_get_bool ("/firestarter/Druid/services"));

	radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
		_("Yes, I run the following services on my machine:"));
	gtk_table_attach (GTK_TABLE (table), radio2, 0, 1, 2, 3,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio2),
		gnome_config_get_bool ("/firestarter/Druid/services"));


	data->services = gtk_hbox_new (FALSE, 10);
	gtk_table_attach (GTK_TABLE (table), data->services, 0, 1, 3, 4,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	gtk_signal_connect_object (GTK_OBJECT (radio2), "toggled",
		GTK_SIGNAL_FUNC (sensitivity_flip), GTK_OBJECT (data->services));

	/* Column 1 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->ftp = gtk_check_button_new_with_label ("FTP");
	gtk_box_pack_start (GTK_BOX (vbox), data->ftp, FALSE, FALSE, 0);

	data->ssh = gtk_check_button_new_with_label ("SSH");
	gtk_box_pack_start (GTK_BOX (vbox), data->ssh, FALSE, FALSE, 0);

	data->telnet = gtk_check_button_new_with_label ("Telnet");
	gtk_box_pack_start (GTK_BOX (vbox), data->telnet, FALSE, FALSE, 0);

	data->smtp = gtk_check_button_new_with_label ("SMTP");
	gtk_box_pack_start (GTK_BOX (vbox), data->smtp, FALSE, FALSE, 0);

	data->dns = gtk_check_button_new_with_label ("DNS");
	gtk_box_pack_start (GTK_BOX (vbox), data->dns, FALSE, FALSE, 0);

	data->finger = gtk_check_button_new_with_label ("Finger");
	gtk_box_pack_start (GTK_BOX (vbox), data->finger, FALSE, FALSE, 0);

	gtk_box_pack_start (GTK_BOX (data->services), vbox, FALSE, FALSE, 0);

	/* Column 2 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->www = gtk_check_button_new_with_label ("WWW");
	gtk_box_pack_start (GTK_BOX (vbox), data->www, FALSE, FALSE, 0);

	data->sslweb = gtk_check_button_new_with_label ("SSL web");
	gtk_box_pack_start (GTK_BOX (vbox), data->sslweb, FALSE, FALSE, 0);

	data->pop = gtk_check_button_new_with_label ("POP");
	gtk_box_pack_start (GTK_BOX (vbox), data->pop, FALSE, FALSE, 0);

	data->imap = gtk_check_button_new_with_label ("IMAP");
	gtk_box_pack_start (GTK_BOX (vbox), data->imap, FALSE, FALSE, 0);

	data->ident = gtk_check_button_new_with_label ("IDENT");
	gtk_box_pack_start (GTK_BOX (vbox), data->ident, FALSE, FALSE, 0);

	data->nntp = gtk_check_button_new_with_label ("NNTP");
	gtk_box_pack_start (GTK_BOX (vbox), data->nntp, FALSE, FALSE, 0);

	gtk_box_pack_start (GTK_BOX (data->services), vbox, FALSE, FALSE, 0);

	/* Column 3 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->ntp = gtk_check_button_new_with_label ("NTP");
	gtk_box_pack_start (GTK_BOX (vbox), data->ntp, FALSE, FALSE, 0);

	data->samba = gtk_check_button_new_with_label ("SAMBA/NetBios");
	gtk_box_pack_start (GTK_BOX (vbox), data->samba, FALSE, FALSE, 0);

	data->routed = gtk_check_button_new_with_label ("Routed");
	gtk_box_pack_start (GTK_BOX (vbox), data->routed, FALSE, FALSE, 0);

	data->nfs = gtk_check_button_new_with_label ("NFS");
	gtk_box_pack_start (GTK_BOX (vbox), data->nfs, FALSE, FALSE, 0);

	data->x = gtk_check_button_new_with_label ("Xwindows");
	gtk_box_pack_start (GTK_BOX (vbox), data->x, FALSE, FALSE, 0);

	data->dhcp = gtk_check_button_new_with_label ("DHCP");
	gtk_box_pack_start (GTK_BOX (vbox), data->dhcp, FALSE, FALSE, 0);

	gtk_box_pack_start (GTK_BOX (data->services), vbox, FALSE, FALSE, 0);
	
	/* Column 4 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->ipsec = gtk_check_button_new_with_label ("IPSEC");
	gtk_box_pack_start (GTK_BOX (vbox), data->ipsec, FALSE, FALSE, 0);

	data->upnp = gtk_check_button_new_with_label ("uPNP");
	gtk_box_pack_start (GTK_BOX (vbox), data->upnp, FALSE, FALSE, 0);

	gtk_box_pack_start (GTK_BOX (data->services), vbox, FALSE, FALSE, 0);

	gtk_widget_show_all (table);

	gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox),
			    table, TRUE, TRUE, 0);

	gnome_druid_page_standard_set_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);
	gnome_druid_page_standard_set_logo_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);

	return (page);
}

/* [ create_icmp_page ]
 * Create the contents of the ICMP filtering page - fnk 10/2000
 */
static GtkWidget*
create_icmp_page (Druid *data)
{
	GtkWidget *page;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *vbox;
	GtkWidget *radio1, *radio2;

	page = gnome_druid_page_standard_new_with_vals (_(
		"ICMP Configuration"), NULL);

	turn_white (page);

	table = gtk_table_new (4, 1, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);

	label = gtk_label_new (_(
		"ICMP Packet Filtering can be useful to prevent some common\n"
		"Denial of Service (DoS) attacks on your network.\n\n"
		"Would you like to enable ICMP Filtering?"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD_SMALL);

	radio1 = gtk_radio_button_new_with_label (NULL,
		_("Disable ICMP Filtering"));
	gtk_table_attach (GTK_TABLE (table), radio1, 0, 1, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1),
		!gnome_config_get_bool ("/firestarter/Druid/icmp"));

	radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
		_("Enable ICMP Filtering related to the following packets:"));
	gtk_table_attach (GTK_TABLE (table), radio2, 0, 1, 2, 3,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio2),
		gnome_config_get_bool ("/firestarter/Druid/icmp"));


	data->icmp = gtk_hbox_new (FALSE, 10);
	gtk_table_attach (GTK_TABLE (table), data->icmp, 0, 1, 3, 4,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	gtk_signal_connect_object (GTK_OBJECT (radio2), "toggled",
		GTK_SIGNAL_FUNC (sensitivity_flip), GTK_OBJECT (data->icmp));

	/* Column 1 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->icmp_echo = gtk_check_button_new_with_label ("Echo");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_echo, FALSE, FALSE, 0);

	data->icmp_traceroute = gtk_check_button_new_with_label ("Traceroute");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_traceroute, FALSE, FALSE, 0);

	data->icmp_tracert = gtk_check_button_new_with_label ("MS Traceroute");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_tracert, FALSE, FALSE, 0);

	data->icmp_unreach = gtk_check_button_new_with_label ("Unreachable");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_unreach, FALSE, FALSE, 0);

	gtk_box_pack_start (GTK_BOX (data->icmp), vbox, FALSE, FALSE, 0);

	/* Column 2 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->icmp_timestamp = gtk_check_button_new_with_label ("Timestamping");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_timestamp, FALSE, FALSE, 0);

	data->icmp_masking = gtk_check_button_new_with_label ("Address Masking");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_masking, FALSE, FALSE, 0);

	data->icmp_redir = gtk_check_button_new_with_label ("Redirection");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_redir, FALSE, FALSE, 0);

	data->icmp_quench = gtk_check_button_new_with_label ("Source Quenches");
	gtk_box_pack_start (GTK_BOX (vbox), data->icmp_quench, FALSE, FALSE, 0);

	gtk_box_pack_start (GTK_BOX (data->icmp), vbox, FALSE, FALSE, 0);

	gtk_widget_show_all (table);

	gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox),
			    table, TRUE, TRUE, 0);

	gnome_druid_page_standard_set_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);
	gnome_druid_page_standard_set_logo_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);

	return (page);
}

/* [ create_tos_page ]
 * Create the contents of the Type of Service filtering page - fnk 12/2000
 */
static GtkWidget*
create_tos_page (Druid *data)
{
	GtkWidget *page;
	GtkWidget *table;
	GtkWidget *label;
	GtkWidget *vbox;
	GtkWidget *radio1, *radio2;

	page = gnome_druid_page_standard_new_with_vals (_(
		"Type of Service (ToS) Configuration"), NULL);

	turn_white (page);

	table = gtk_table_new (4, 1, FALSE);
	gtk_table_set_row_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);
	gtk_table_set_col_spacings (GTK_TABLE(table), GNOME_PAD_SMALL);

	label = gtk_label_new (_(
		"Type of Service filtering allows you to re-prioritize network\n"
		"services to allow higher throughput rates for commonly used services.\n\n"
		"Would you like to enable ToS Filtering?\n"));
	gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.0);
	gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT);
	gtk_table_attach (GTK_TABLE (table), label, 0, 1, 0, 1,
		GTK_FILL, GTK_FILL, GNOME_PAD, GNOME_PAD_SMALL);

	radio1 = gtk_radio_button_new_with_label (NULL,
		_("Disable ToS Filtering"));
	gtk_table_attach (GTK_TABLE (table), radio1, 0, 1, 1, 2,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio1),
		!gnome_config_get_bool ("/firestarter/Druid/tos"));

	radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1),
		_("Enable ToS Filtering related to the following packets:"));
	gtk_table_attach (GTK_TABLE (table), radio2, 0, 1, 2, 3,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);
	gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (radio2),
		gnome_config_get_bool ("/firestarter/Druid/tos"));

	data->tos = gtk_hbox_new (FALSE, 10);
	gtk_widget_set_sensitive (data->tos, 0);
	gtk_table_attach (GTK_TABLE (table), data->tos, 0, 1, 3, 4,
		GTK_FILL, GTK_FILL, GNOME_PAD, 0);

	gtk_signal_connect_object (GTK_OBJECT (radio2), "toggled",
		GTK_SIGNAL_FUNC (sensitivity_flip), GTK_OBJECT (data->tos));

	/* Column 1 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->tos_client = gtk_check_button_new_with_label ("Client Applications");
	gtk_box_pack_start (GTK_BOX (vbox), data->tos_client, FALSE, FALSE, 0);

	gtk_tooltips_set_tip (ttips, data->tos_client, _(
		"Check this option to enable Type of Service flags for common "
		"client applications, such as WWW, FTP, SSH & E-Mail."), "");

	data->tos_server = gtk_check_button_new_with_label ("Server Applications");
	gtk_box_pack_start (GTK_BOX (vbox), data->tos_server, FALSE, FALSE, 0);

	gtk_tooltips_set_tip (ttips, data->tos_server, _(
		"Check this option to enable Type of Service flags for common "
		"server applications, such as SQUID, FTPd, SSHd, SMTP & POP Daemons."), "");

	data->tos_X = gtk_check_button_new_with_label ("The X Window System");
	gtk_box_pack_start (GTK_BOX (vbox), data->tos_X, FALSE, FALSE, 0);

	gtk_tooltips_set_tip (ttips, data->tos_X, _(
		"Selecting this option will automatically configure Type of Service "
		"for `Throughput' for both X and SSHd."
		"You should select this ONLY if you need to run X over your link"), "");

	gtk_box_pack_start (GTK_BOX (data->tos), vbox, FALSE, FALSE, 0);

	/* Column 2 */
	vbox = gtk_vbox_new (FALSE, 1);

	data->tos_option_throughput = gtk_radio_button_new_with_label (NULL, "Throughput");
	gtk_box_pack_start (GTK_BOX (vbox), data->tos_option_throughput, FALSE, FALSE, 0);

	gtk_tooltips_set_tip (ttips, data->tos_option_throughput, _(
		"Selecting this option will configure Type of Service flags for "
		"Maximum Throughput for the options you have selected."), "");

	data->tos_option_reliability = gtk_radio_button_new_with_label_from_widget (
		GTK_RADIO_BUTTON (data->tos_option_throughput), _("Reliability"));
	gtk_box_pack_start (GTK_BOX (vbox), data->tos_option_reliability, FALSE, FALSE, 0);

	gtk_tooltips_set_tip (ttips, data->tos_option_reliability, _(
		"Selecting this option will configure Type of Service flags for "
		"Maximum Reliability for the options you have selected."), "");

	data->tos_option_delay = gtk_radio_button_new_with_label_from_widget (
		GTK_RADIO_BUTTON (data->tos_option_throughput), _("Delay"));
	gtk_box_pack_start (GTK_BOX (vbox), data->tos_option_delay, FALSE, FALSE, 0);

	gtk_tooltips_set_tip (ttips, data->tos_option_delay, _(
		"Selecting this option will configure Type of Service flags for "
		"Minimum Delay for the options you have selected."), "");

	gtk_box_pack_start (GTK_BOX (data->tos), vbox, FALSE, FALSE, 0);
     
	gtk_widget_show_all (table);

	gtk_box_pack_start (GTK_BOX (GNOME_DRUID_PAGE_STANDARD (page)->vbox),
			    table, TRUE, TRUE, 0);

	gnome_druid_page_standard_set_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);
	gnome_druid_page_standard_set_logo_bg_color (GNOME_DRUID_PAGE_STANDARD (page), &white);

	return (page);
}

/* [ create_start_page ]
 * Create the contents of the druid splash screen
 */

static GtkWidget*
create_start_page (void)
{
	GtkWidget *page;
        GnomeCanvasItem *item;

	page = gnome_druid_page_start_new_with_vals ("",
		_("Welcome to Firestarter!\n\n\n"
		"This wizard will now help you to set up a firewall for your\n"
		"Linux machine. You will be asked some questions about\n"
		"your network setup.\n\n"
		"Press the next button to continue.\n\n\n"),
		NULL, watermark);

	item = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (
		GNOME_DRUID_PAGE_START (page)->canvas)),
		gnome_canvas_image_get_type (),
		"image", image,
		"x", 0.0,
		"y", 0.0,
		"anchor", GTK_ANCHOR_NORTH_WEST,
		"width", (gfloat) 174,
		"height", (gfloat) 66,
		NULL);

	gnome_canvas_item_raise_to_top (item);
	gnome_canvas_item_raise_to_top (GNOME_DRUID_PAGE_START (page)->title_item);

	gnome_druid_page_start_set_bg_color (GNOME_DRUID_PAGE_START (page), &white);
	gnome_druid_page_start_set_logo_bg_color (GNOME_DRUID_PAGE_START (page), &white);

	return (page);
}

/* [ create_finish_page ]
 * Create the contents of the druid finish screen
 */
static GtkWidget*
create_finish_page (void)
{
	GtkWidget *page;
        GnomeCanvasItem *item;

	page = gnome_druid_page_finish_new_with_vals ("",
		_("The wizard is now ready to generate your firewall.\n\n"
		  "Press the finish button to continue, or the back button\n"
		  "to review your choices.\n\n"),
		NULL, watermark);

	item = gnome_canvas_item_new (gnome_canvas_root (GNOME_CANVAS (
		GNOME_DRUID_PAGE_FINISH (page)->canvas)),
		gnome_canvas_image_get_type (),
		"image", image,
		"x", 0.0,
		"y", 0.0,
		"anchor", GTK_ANCHOR_NORTH_WEST,
		"width", (gfloat) 174,
		"height", (gfloat) 66,
		NULL);

	gnome_canvas_item_raise_to_top (item);
	gnome_canvas_item_raise_to_top (GNOME_DRUID_PAGE_FINISH (page)->title_item);

	gnome_druid_page_finish_set_bg_color (GNOME_DRUID_PAGE_FINISH (page), &white);
	gnome_druid_page_finish_set_logo_bg_color (GNOME_DRUID_PAGE_FINISH (page), &white);

	return (page);
}


/* [ rundruid ]
 * The main druid function. The druid is essentially a stand alone program
 * (and actually was until 0.2.0)
 */
void
rundruid (void)
{
	GtkWidget *app = NULL;
	GtkWidget *druid;
	GtkWidget *startpage;
	GtkWidget *branchpage;
	GtkWidget *devicepage;
	GtkWidget *masqpage;
	GtkWidget *tospage;
	GtkWidget *servicespage;
	GtkWidget *icmppage;
	GtkWidget *finishpage;
	Druid *data;

	/* Check that the window is not already created */
	if (app != NULL) {
		g_assert (GTK_WIDGET_REALIZED (app));
		gdk_window_show (app->window);
		gdk_window_raise (app->window);
		return;
	}

	/* Check that the user is a superuser */
	if (geteuid ()) {
		GtkWidget *dialog=gnome_error_dialog (_(
			"You must be root to use the Firestarter wizard."));
		gnome_dialog_run_and_close (GNOME_DIALOG (dialog));
		return;
	}

	image = gdk_imlib_load_image("/usr/share/pixmaps/firestarter/top.png");
	watermark = gdk_imlib_load_image("/usr/share/pixmaps/firestarter/left.png");

	/* Init colors*/
	white.red = 255*255;
	white.green = 255*255;
	white.blue = 255*255;

	black.red = 0*255;
	black.green = 0*255;
	black.blue = 0*255;

	app = gnome_app_new ("firestarter", _("Firestarter Firewall Wizard"));
	gtk_window_set_position (GTK_WINDOW (app), GTK_WIN_POS_CENTER_ALWAYS);
	gtk_signal_connect_object (GTK_OBJECT (app), "destroy",
		GTK_SIGNAL_FUNC (quit_druid), GTK_OBJECT (app));

	gnome_window_icon_set_from_file (GTK_WINDOW (app),
		"/usr/share/pixmaps/firestarter_druid.xpm");

	data = g_new (Druid, 1);

	druid = gnome_druid_new ();
	gtk_signal_connect_object (GTK_OBJECT (druid), "cancel",
		GTK_SIGNAL_FUNC (quit_druid), GTK_OBJECT (app));
	gnome_app_set_contents (GNOME_APP (app), druid);

	/* Create the basic druid pages */
	startpage = create_start_page ();
	branchpage = create_branch_page (data);
	devicepage = create_device_page (data);
	masqpage = create_masq_page (data);
	tospage = create_tos_page (data);
	servicespage = create_services_page (data);
	icmppage = create_icmp_page (data);
	finishpage = create_finish_page ();


	/* Signals to save choices and terminate druid */
	gtk_signal_connect (GTK_OBJECT (finishpage), "finish",
		GTK_SIGNAL_FUNC (write_script), data);

	gtk_signal_connect_object (GTK_OBJECT (finishpage), "finish",
		GTK_SIGNAL_FUNC (quit_druid), GTK_OBJECT (app));

	/* Signal logic to alter the druid event flow*/

	/* 
	Simple:   Start, Branch, Network, ICMP, Services
	Advanced: Start, Branch, Network, ICMP, Services, (Sysctl), ToS, Masquerading, (PortfwScript)
	*/

	/* Services -> Finish */
	gtk_signal_connect (GTK_OBJECT (servicespage), "next",
		GTK_SIGNAL_FUNC (set_page), finishpage);

	/* Services <- Finish */
	gtk_signal_connect (GTK_OBJECT (finishpage), "back",
		GTK_SIGNAL_FUNC (set_page), servicespage);

	/* Add the pages to the druid */
	/* common pages to both branches */
	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (startpage));
	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (branchpage));
	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (devicepage));
	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (icmppage));
	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (servicespage));

	/* Pages only in the advanced branch */
	/* SYSCTL PAGE GOES HERE */
	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (tospage));
	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (masqpage));
	/* PORTFWSCRIPT PAGE GOES HERE*/

	gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (finishpage));

	/* Set page to start from */
	gnome_druid_set_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (startpage));

	load_choices (data);

	gtk_widget_show_all (app);

	/* Mark that the druid has been used at least once */
	gnome_config_set_bool ("/firestarter/Druid/firsttime", FALSE);
	gnome_config_sync ();
}
