summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drakpxelinux.pl638
1 files changed, 638 insertions, 0 deletions
diff --git a/drakpxelinux.pl b/drakpxelinux.pl
new file mode 100644
index 0000000..8bdd24d
--- /dev/null
+++ b/drakpxelinux.pl
@@ -0,0 +1,638 @@
+#!/usr/bin/perl
+#
+# Copyright (C) 2004 by Mandrakesoft aginies _ateuh_ mandrakesoft.com
+#
+# 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, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+# 02111-1307, USA.
+
+# Quick configuration of PXE menu parameters
+# release 0.5
+# use with care developement release....
+# thx R1 for test and some debug
+
+use lib qw(/usr/lib/libDrakX);
+use standalone;
+use strict;
+use common;
+use MDK::Common;
+use ugtk2 qw(:ask :helpers :wrappers :create :dialogs);
+
+
+use constant FALSE => 0;
+use constant TRUE => 1;
+
+# ie of entry menu in PXE:
+#label linux
+# KERNEL images/vmlinuz
+# APPEND initrd=images/all.rdz automatic=method:http,interface:eth0,network:dhcp,server:10.0.1.33,directory:/install/ ramdisk_size=64000 root=/dev/ram3 rw vga=788 display=:0
+
+my $conf = "/var/lib/tftpboot/X86PC/linux/pxelinux.cfg/default";
+#my $conf = "/tmp/tr";
+
+my $help = "
+PXE Label: the name displayed in PXE menu (a word/number)
+Server: IP address of server, which contains installation directory
+Kernel: memdisk or vmlinuz
+Initrd: network boot image (network.img ) or all.rdz
+Interface: network interface used for the installation process
+Network: DHCP or an IP address
+Directory: full path to MDK install server directory
+Method: installation method: choose NFS or HTTP
+Ramsize: ramsize parameter on boot disk
+Display: export display on another computer (ie: 10.0.1.33:0)
+VGA: if you encounter any problem with VGA, please adjust
+";
+
+my $date = chomp_(`date +%d-%m-20%y`);
+
+if (!-f $conf) {
+ err_dialog("Error !", "missing $conf\n\nPlease install pxe package.") and die;
+} else {
+ cp_af($conf, "$conf-$date");
+}
+
+my @listpxe;
+my @list_method = qw(nfs http);
+my @list_ram = qw(48000 32000 64000 1280000);
+my @list_vga = qw(788 normal 785 791 792 text);
+my @list_eth = qw(eth0 eth1 eth2);
+
+use constant COLUMN_LABEL => 0;
+use constant COLUMN_INFO => 1;
+use constant COLUMN_KERNEL => 2;
+use constant COLUMN_INITRD => 3;
+use constant COLUMN_AUTOMATIC => 4;
+use constant COLUMN_INTERFACE => 5;
+use constant COLUMN_NETWORK => 6;
+use constant COLUMN_SERVER => 7;
+use constant COLUMN_DIRECTORY => 8;
+use constant COLUMN_RAMDISK => 9;
+use constant COLUMN_VGA => 10;
+use constant COLUMN_DISPLAY => 11;
+use constant COLUMN_OPTION => 12;
+use constant NUM_COLUMNS => 13;
+
+
+sub get_items() {
+ my $info; my $label; my $kernel; my $initrd;
+ foreach (cat_($conf)) {
+ if (any { /^label/ } cat_($conf)) {
+ if (/^label/) { ($label) = /^label\s(.*)/ }
+ if (/KERNEL/) { ($kernel) = /KERNEL\s(.*)/ }
+ my ($initrd, $automatic, $interface, $network, $server, $directory, $ramdisk, $vga, $display) = m!\s*APPEND\sinitrd=(.*?rdz)\s\bautomatic=method\b:(nfs|http),interface:(eth0|eth1|eth2),network:(dhcp|10.0.1.33),server:(.*?),directory:(.*?)\s\bramdisk_size\b=(.*?)\sroot=/dev/ram3\srw\svga=(.*?)\sdisplay=(.*?)\s!;
+ # in case of parameter not on this order (previous pxe default file)
+ $initrd or my ($init) = m!\s*APPEND\s\binitrd\b=(.*?)\s!;
+ $ramdisk or my ($ramdis) = m!\bramdisk_size\b=(\d+)\s!;
+ $automatic or my ($automati) = m!\bautomatic\b=method:(nfs|http)!;
+ $vga or my ($vg) = m!\bvga\b=(.*?)\s!;
+ $display or my ($displa) = m!\bdisplay\b=(.*?)\s!;
+ $interface or my ($interfac) = m!\binterface\b:(eth0|eth1|eth2)!;
+ $network or my ($networ) = m!\bnetwork\b:(dhcp|10.0.1.33)!;
+ $server or my ($serve) = m!\bserver\b:(.*?),!;
+ $directory or my ($director) = m!\bdirectory\b:(.*?)\s!;
+ my $information = "$label $automati";
+ my $initall; my $ramdiskall; my $autoall; my $vgaall; my $displayall; my $interfaceall; my $networkall; my $serverall; my $directoryall;
+ if ($initrd) { $initall = $initrd } else { $initall = $init }
+ if ($ramdisk) { $ramdiskall = $ramdisk } else { $ramdiskall = $ramdis }
+ if ($automatic) { $autoall = $automatic } else { $autoall = $automati }
+ if ($vga) { $vgaall = $vga } else { $vgaall = $vg }
+ if ($display) { $displayall = $display } else { $displayall = $displa }
+ if ($interface) { $interfaceall = $interface } else { $interfaceall = $interfac }
+ if ($network) { $networkall = $network } else { $networkall = $networ }
+ if ($server) { $serverall = $server } else { $serverall = $serve }
+ if ($directory) { $directoryall = $directory } else { $directoryall = $director }
+ my ($allopt) = m!\s*APPEND\s(.*)!;
+ my ($autocomp) = m!\bautomatic\b=(.*?)\s!;
+ my ($devram) = m!root=/dev/ram3\srw!;
+ my $optionsall = join(' ', grep { ! /$devram/ and ! /initrd=$initall/ and ! /display=$displayall/ and ! /ramdisk_size=$ramdiskall/ and ! /automatic=$autocomp/ and ! /vga=$vgaall/ } split(' ', $allopt));
+
+ if ($label and $kernel and $initall) {
+ push @listpxe, {
+ label => $label,
+ info => $information,
+ kernel => $kernel,
+ initrd => $initall,
+ automatic => $autoall,
+ interface => $interfaceall,
+ network => $networkall,
+ server => $serverall,
+ directory => $directoryall,
+ ramdisk => $ramdiskall,
+ vga => $vgaall,
+ display => $displayall,
+ option => $optionsall,
+ },;
+ }
+ }
+ }
+}
+
+sub list_label_pxe() {
+ my @labels;
+ foreach (cat_($conf)) {
+ my ($label) = /label\s(.*)/;
+ $label and push @labels, $label;
+ }
+ @labels;
+}
+
+sub set_new_default {
+ my ($default) = @_;
+ substInFile {
+ s/^DEFAULT.*/DEFAULT $default/;
+ } $conf;
+}
+
+sub get_default_pxe {
+ my ($defaultpxe) = cat_($conf) =~ /DEFAULT\s+(\S+)/;
+ return $defaultpxe;
+}
+
+sub get_default_prompt() {
+ my ($prompt) = cat_($conf) =~ /^PROMPT\s(\d+)/;
+ return $prompt;
+}
+
+sub get_default_timeout() {
+ my ($time) = cat_($conf) =~ /^TIMEOUT\s(\d+)/;
+ return $time;
+}
+
+sub write_conf_pxe {
+ my $default = get_default_pxe;
+ my $prompt = get_default_prompt;
+ my $time = get_default_timeout;
+ output($conf, <<EOF);
+# DO NOT EDIT auto_generated by drakpxe2.pl
+PROMPT $prompt
+DEFAULT $default
+DISPLAY messages
+TIMEOUT 50
+
+label local
+ LOCALBOOT 0
+EOF
+
+ foreach my $a (@listpxe) {
+ if ($a->{interface}) {
+ append_to_file($conf, "
+label $a->{label}
+ KERNEL $a->{kernel}
+ APPEND initrd=$a->{initrd} automatic=method:$a->{automatic},interface:$a->{interface},network:$a->{network},server:$a->{server},directory:$a->{directory} ramdisk_size=$a->{ramdisk} root=/dev/ram3 rw vga=$a->{vga} display=$a->{display}
+");
+ } else {
+ append_to_file($conf, "
+label $a->{label}
+ KERNEL $a->{kernel}
+ APPEND initrd=$a->{initrd}
+");
+ }
+ }
+}
+
+sub create_model {
+ get_items();
+ my $model = Gtk2::ListStore->new(("Glib::String") x13);
+ foreach my $a (@listpxe) {
+ my $iter = $model->append;
+ $model->set($iter,
+ COLUMN_LABEL, $a->{label},
+ COLUMN_INFO, $a->{info},
+ COLUMN_KERNEL, $a->{kernel},
+ COLUMN_INITRD, $a->{initrd},
+ COLUMN_AUTOMATIC, $a->{automatic},
+ COLUMN_INTERFACE, $a->{interface},
+ COLUMN_NETWORK, $a->{network},
+ COLUMN_SERVER, $a->{server},
+ COLUMN_DIRECTORY, $a->{directory},
+ COLUMN_RAMDISK, $a->{ramdisk},
+ COLUMN_VGA, $a->{vga},
+ COLUMN_DISPLAY, $a->{display},
+ COLUMN_OPTION, $a->{option},
+ ),
+ }
+ return $model;
+}
+
+sub add_item {
+ my ($button, $model) = @_;
+ my @a;
+ push @a, {
+ label => "cooker",
+ info => "install cooker",
+ kernel => "/images/cooker",
+ initrd => "cooker.rdz",
+ automatic => "http",
+ interface => "eth0",
+ network => "dhcp",
+ server => "10.0.1.33",
+ directory => "/install/cooker",
+ ramdisk => "64000",
+ vga => "788",
+ display => ":0",
+ option => "acpi=ht",
+ };
+
+ my $iter = $model->append;
+ $model->set($iter,
+ COLUMN_LABEL, $a[-1]{label},
+ COLUMN_INFO, $a[-1]{info},
+ COLUMN_KERNEL, $a[-1]{kernel},
+ COLUMN_INITRD, $a[-1]{initrd},
+ COLUMN_AUTOMATIC, $a[-1]{automatic},
+ COLUMN_INTERFACE, $a[-1]{interface},
+ COLUMN_NETWORK, $a[-1]{network},
+ COLUMN_SERVER, $a[-1]{server},
+ COLUMN_DIRECTORY, $a[-1]{directory},
+ COLUMN_RAMDISK, $a[-1]{ramdisk},
+ COLUMN_VGA, $a[-1]{vga},
+ COLUMN_DISPLAY, $a[-1]{display},
+ COLUMN_OPTION, $a[-1]{option},
+ );
+# write_conf_pxe;
+}
+
+sub remove_item {
+ my ($widget, $treeview) = @_;
+ my $model = $treeview->get_model;
+ my $selection = $treeview->get_selection;
+ my $iter = $selection->get_selected;
+ if ($iter) {
+ my $path = $model->get_path($iter);
+ my $i = ($path->get_indices)[0];
+ ask_okcancel("Remove $listpxe[$i]{label} PXE entry ?") or return;
+ $model->remove($iter);
+ splice @listpxe, $i, 1;
+ }
+ write_conf_pxe;
+}
+
+sub edit_box_item {
+ my ($widget, $treeview) = @_;
+ my $model = $treeview->get_model;
+ my $selection = $treeview->get_selection;
+
+ my $iter = $selection->get_selected;
+ if ($iter) {
+ my $path = $model->get_path($iter);
+ my $i = ($path->get_indices)[0];
+
+ my $dialog = new Gtk2::Dialog();
+ $dialog->set_modal(0);
+
+ my $label = Gtk2::Entry->new;
+ $label->set_text($listpxe[$i]{label});
+
+ my $info = Gtk2::Entry->new;
+ $info->set_text($listpxe[$i]{info});
+
+ my $kernel = Gtk2::Entry->new;
+ $kernel->set_text($listpxe[$i]{kernel});
+ # file selection for kernel
+ my $file_dialogk = new Gtk2::FileSelection("File Selection");
+ $file_dialogk->set_modal(TRUE);
+ $file_dialogk->signal_connect("destroy", sub { Gtk2->exit });
+ $file_dialogk->ok_button->signal_connect(clicked => sub {
+ my $file = $file_dialogk->get_filename;
+ $kernel->set_text($file);
+ $file_dialogk->hide;
+ }, $file_dialogk);
+ $file_dialogk->cancel_button->signal_connect(clicked => sub { $file_dialogk->hide });
+ # button kernel
+ my $buttonkernel = Gtk2::Button->new("Select kernel");
+ $buttonkernel->signal_connect(clicked => sub { $file_dialogk->show });
+
+ my $initrd = Gtk2::Entry->new;
+ $initrd->set_text($listpxe[$i]{initrd});
+ # file selection for initrd
+ my $file_dialog = new Gtk2::FileSelection("File Selection");
+ $file_dialog->set_modal(TRUE);
+ $file_dialog->signal_connect("destroy", sub { Gtk2->exit });
+ $file_dialog->ok_button->signal_connect(clicked => sub {
+ my $filei = $file_dialog->get_filename;
+ $initrd->set_text($filei);
+ $file_dialog->hide;
+ }, $file_dialog);
+ my $buttoninitrd = Gtk2::Button->new("Select initrd");
+ $buttoninitrd->signal_connect(clicked => sub { $file_dialog->show });
+
+ # combo box to pop down automatic installation
+ my $automatic = Gtk2::Combo->new;
+ $automatic->set_popdown_strings(@list_method);
+ $automatic->entry->set_text($listpxe[$i]{automatic});
+
+ # combo box to pop down list of network interface
+ my $interface = new Gtk2::Combo();
+ $interface->set_popdown_strings(@list_eth);
+ $interface->entry->set_text($listpxe[$i]{interface});
+
+ my $network = Gtk2::Entry->new;
+ $network->set_text($listpxe[$i]{network});
+
+ my $server = Gtk2::Entry->new;
+ $server->set_text($listpxe[$i]{server});
+
+ my $directory = Gtk2::Entry->new;
+ $directory->set_text($listpxe[$i]{directory});
+
+ my $ramdisk = new Gtk2::Combo();
+ $ramdisk->set_popdown_strings(@list_ram);
+ $ramdisk->entry->set_text($listpxe[$i]{ramdisk});
+
+ my $vga = new Gtk2::Combo();
+ $vga->set_popdown_strings(@list_vga);
+ $vga->entry->set_text($listpxe[$i]{vga});
+
+ my $display = Gtk2::Entry->new;
+ $display->set_text($listpxe[$i]{display});
+
+ my $option = Gtk2::Entry->new;
+ $option->set_text($listpxe[$i]{option});
+
+ gtkpack_($dialog->vbox,
+ 0, gtkadd(Gtk2::Frame->new(("Description")),
+ gtkpack(gtkset_border_width(Gtk2::VBox->new, 2),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Label"),
+ $label,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Info"),
+ $info,
+ ),
+ ),
+ ),
+ 0, gtkadd(Gtk2::Frame->new(("Boot image")),
+ gtkadd(gtkset_border_width(Gtk2::VBox->new, 2),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Kernel"),
+ $kernel,
+ $buttonkernel,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Initrd"),
+ $initrd,
+ $buttoninitrd,
+ ),
+ ),
+ ),
+ 0, gtkadd(Gtk2::Frame->new(("Automatic Options")),
+ gtkadd(gtkset_border_width(Gtk2::VBox->new, 2),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Automatic"),
+ $automatic,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Interface"),
+ $interface,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Network"),
+ $network,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Server"),
+ $server,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Directory"),
+ $directory),
+ ),
+ ),
+ 0, gtkadd(Gtk2::Frame->new(("Display")),
+ gtkadd(gtkset_border_width(Gtk2::VBox->new, 2),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Vga"),
+ $vga,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Display"),
+ $display,
+ ),
+ ),
+ ),
+ 0, gtkadd(Gtk2::Frame->new(("Other options")),
+ gtkadd(gtkset_border_width(Gtk2::VBox->new, 2),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Ramdisk"),
+ $ramdisk,
+ ),
+ gtkadd(Gtk2::HBox->new,
+ Gtk2::Label->new("Option"),
+ $option,
+ ),
+ ),
+ ),
+ 0, create_okcancel({
+ cancel_clicked => sub { $dialog->destroy },
+ ok_clicked => sub {
+ #ask_okcancel("are you sure you want to update all those values ?");
+ $listpxe[$i]{label} = $label->get_text;
+ $listpxe[$i]{info} = $info->get_text;
+ $listpxe[$i]{kernel} = $kernel->get_text;
+ $listpxe[$i]{initrd} = $initrd->get_text;
+ $listpxe[$i]{automatic} = $automatic->entry->get_text;
+ $listpxe[$i]{interface} = $interface->entry->get_text;
+ $listpxe[$i]{network} = $network->get_text;
+ $listpxe[$i]{server} = $server->get_text;
+ $listpxe[$i]{directory} = $directory->get_text;
+ $listpxe[$i]{ramdisk} = $ramdisk->entry->get_text;
+ $listpxe[$i]{vga} = $vga->entry->get_text;
+ $listpxe[$i]{display} = $display->get_text;
+ $listpxe[$i]{option} = $option->get_text;
+
+ # update value in cells
+ $model->set($iter,
+ COLUMN_LABEL, $listpxe[$i]{label},
+ COLUMN_INFO, $listpxe[$i]{info},
+ COLUMN_KERNEL, $listpxe[$i]{kernel},
+ COLUMN_INITRD, $listpxe[$i]{initrd},
+ COLUMN_AUTOMATIC, $listpxe[$i]{automatic},
+ COLUMN_INTERFACE, $listpxe[$i]{interface},
+ COLUMN_NETWORK, $listpxe[$i]{network},
+ COLUMN_SERVER, $listpxe[$i]{server},
+ COLUMN_DIRECTORY, $listpxe[$i]{directory},
+ COLUMN_RAMDISK, $listpxe[$i]{ramdisk},
+ COLUMN_VGA, $listpxe[$i]{vga},
+ COLUMN_DISPLAY, $listpxe[$i]{display},
+ COLUMN_OPTION, $listpxe[$i]{option},
+ );
+ $dialog->destroy;
+ write_conf_pxe;
+ },
+ },
+ ),
+ );
+ $dialog->show_all;
+ }
+}
+
+sub cell_edited {
+ my ($cell, $path_string, $new_text, $model) = @_;
+ my $path = Gtk2::TreePath->new_from_string($path_string);
+ my $column = $cell->get_data("column");
+ my $iter = $model->get_iter($path);
+
+ if ($column == COLUMN_LABEL) {
+ my $i = ($path->get_indices)[0];
+ $listpxe[$i]{label} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{label});
+ } elsif ($column == COLUMN_INFO) {
+ my $i = ($path->get_indices)[0];
+ $listpxe[$i]{info} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{info});
+ } elsif ($column == COLUMN_KERNEL) {
+ my $i = ($path->get_indices)[0];
+ if (-f $new_text) {
+ $listpxe[$i]{kernel} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{kernel});
+ }
+ } elsif ($column == COLUMN_INITRD) {
+ my $i = ($path->get_indices)[0];
+ if (-f $new_text) {
+ $listpxe[$i]{initrd} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{initrd});
+ }
+ } elsif ($column == COLUMN_AUTOMATIC) {
+ my $i = ($path->get_indices)[0];
+ if (!member($new_text, @list_method) or ($listpxe[$i]{kernel} =~ /memdisk/)) {
+ return;
+ } else {
+ $listpxe[$i]{automatic} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{automatic});
+ }
+ } elsif ($column == COLUMN_INTERFACE) {
+ my $i = ($path->get_indices)[0];
+ if (member($new_text, @list_eth) or ($listpxe[$i]{kernel} != /memdisk/)) {
+ $listpxe[$i]{interface} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{interface});
+ }
+ } elsif ($column == COLUMN_NETWORK) {
+ my $i = ($path->get_indices)[0];
+ if ($listpxe[$i]{kernel} != /memdisk/) {
+ $listpxe[$i]{network} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{network});
+ }
+ } elsif ($column == COLUMN_SERVER) {
+ my $i = ($path->get_indices)[0];
+ if ($listpxe[$i]{kernel} != /memdisk/) {
+ $listpxe[$i]{server} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{server});
+ }
+ } elsif ($column == COLUMN_DIRECTORY) {
+ my $i = ($path->get_indices)[0];
+ if (-d $new_text || ($listpxe[$i]{kernel} != /memdisk/)) {
+ $listpxe[$i]{directory} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{directory});
+ }
+ } elsif ($column == COLUMN_RAMDISK) {
+ my $i = ($path->get_indices)[0];
+ if (member($new_text, @list_ram) || ($listpxe[$i]{kernel} != /memdisk/)) {
+ $listpxe[$i]{ramdisk} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{ramdisk});
+ }
+ } elsif ($column == COLUMN_VGA) {
+ my $i = ($path->get_indices)[0];
+ if (member($new_text, @list_vga) || ($listpxe[$i]{kernel} != /memdisk/)) {
+ $listpxe[$i]{vga} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{vga});
+ }
+ } elsif ($column == COLUMN_DISPLAY) {
+ my $i = ($path->get_indices)[0];
+ if ($listpxe[$i]{kernel} != /memdisk/) {
+ $listpxe[$i]{display} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{display});
+ }
+ } elsif ($column == COLUMN_OPTION) {
+ my $i = ($path->get_indices)[0];
+ $listpxe[$i]{option} = $new_text;
+ $model->set($iter, $column, $listpxe[$i]{option});
+ }
+ write_conf_pxe;
+}
+
+sub show_help { info_dialog("Help", $help) }
+
+sub add_columns {
+ my $treeview = shift;
+ my $model = $treeview->get_model;
+ # horrible hack to avoid: GLib-GObject-CRITICAL **: file gobject.c: line 1019 (g_object_set_property): assertion `G_IS_VALUE (value)' failed at drakpxe2.pl line 640.
+ my $t = "0";
+ my @j = qw/Label Info Kernel Initrd Method Interface Network Server Directory Ramdisk vga Display Extra Options/;
+ each_index {
+ my $renderer = Gtk2::CellRendererText->new;
+ $renderer->set(editable => 1);
+ $renderer->signal_connect(edited => \&cell_edited, $model);
+ $renderer->set_data(column => $::i);
+ $treeview->insert_column_with_attributes(-1, $j[$t], $renderer, 'text' => $::i);
+ $t++;
+ } (qw/x x x x x x x x x x x x x/);
+#(("Label"), ("Info"), ("Kernel"), ("Initrd"), ("Method"), ("Interface"), ("Network"), ("Server"), ("Directory"), ("Ramdisk"), ("vga"), ("Display"), ("Extra"), ("Options"));
+}
+
+#
+# Main
+
+# create model
+my $model = create_model();
+
+my $window = ugtk2->new('Drakpxe2');
+$window->{rwindow}->set_size_request(800, 400) unless $::isEmbedded;
+my $W = $window->{window};
+$W->signal_connect(delete_event => sub { ugtk2->exit });
+
+my $treeview = Gtk2::TreeView->new_with_model($model);
+$treeview->set_rules_hint(TRUE);
+$treeview->get_selection->set_mode('single');
+add_columns($treeview);
+
+my $labels = new Gtk2::Combo();
+my @labels = list_label_pxe;
+my $defaultlabel = get_default_pxe;
+$labels->entry->set_text("$defaultlabel");
+$labels->entry->signal_connect("changed", sub { list_label_pxe; my $new_default = $labels->entry->get_text;
+ set_new_default($new_default);
+ }
+ );
+
+$labels->set_popdown_strings(@labels);
+$labels->entry->set_text("$defaultlabel");
+
+$W->add(gtkpack_(Gtk2::VBox->new(0,0),
+ 0, Gtk2::Banner->new('wiz_default_up', ("DrakPXE default configuration file")),
+ 1, create_scrolled_window($treeview),
+ 0, gtkadd(gtkset_border_width(Gtk2::VBox->new, 0,0),
+ gtkadd(Gtk2::HBox->new(0,0),
+ $labels,
+ gtkpack(gtkset_layout(new Gtk2::HButtonBox, 'spread'),
+ 0, (map {
+ my ($label, $sub, $widg) = @$_;
+ gtksignal_connect(Gtk2::Button->new($label), clicked => sub {
+ $sub->($model, $widg); })
+ } ([ ("Help"), \&show_help ],
+ [ ("Add a PXE entry"), \&add_item, $model ],
+ [ ("Remove PXE entry"), \&remove_item, $treeview ],
+ [ ("Edit a PXE entry"), \&edit_box_item, $treeview ],
+ )
+ ),
+ ),
+
+ ),
+ ),
+ ),
+ );
+
+$W->show_all;
+Gtk2->main;