gBootRoot pronounced "bOOtrOOt"
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

5415 lines
161 KiB

#!/usr/bin/perl -w
##############################################################################
##
## BootRoot.pm
## Copyright (C) 2000, 2001, 2002, 2003 by Jonathan Rosenbaum
## <freesource@users.sourceforge.net>
##
## This program is free software; you may 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.
##
## 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., 675 Mass Ave, Cambridge, MA 02139, USA.
##
##############################################################################
package BootRoot::BootRoot;
use vars qw(@ISA @EXPORT %EXPORT_TAGS);
use Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(start skas_or_tt);
use strict;
use POSIX;
use BootRoot::Yard;
use BootRoot::YardBox;
use BootRoot::Error;
use File::Basename;
use File::Find;
use File::Path;
use BootRoot::Options;
$SIG{__WARN__} =
sub { warn @_ unless $_[0] =~ /Subroutine [\w:]+ redefined/io
|| $_[0] =~ /Use of uninitialized value in concatenation/};
# Important option setting up
option();
$::commandline = \%option if %option;
$::commandline = $ARGV[0] if $ARGV[0];
if ( $option{home} && !$option{template} ) {
undef $::commandline;
$option{gui_mode} = $option{home};
undef $option{home};
}
# If you want gBootRoot to do it's stuff somewhere else, change the
# value for $tmp1.
my $tmp1 = "/tmp"; # tmp should be default - Cristian
my $lilo_conf = "/etc/lilo.conf";
my $pwd = `pwd`; chomp $pwd;
my $home;
$option{home} = $option{gui_mode} if $option{gui_mode};
$option{home} ? ($home = $pwd) : ($home = "$ENV{HOME}/.gbootroot");
my $uml_xterm = "xterm -e";
# Don't edit from here, but you can if you want to change the HERE docs
# and/or the contents of initrd (in which case you need to make sure the
# right libraries are copied over to initrd and the size is checked).
# I need to remember to edit this
# and to update scripts/Debian.yard if
# make_debian has been changed,
# and to install -s linux.
# and to make sure modules are correct in Initrd.gz
# apply special patches
my $version = "1.5.0";
my $date = "02.15.2003";
my $gtk_perl_version = "0.7002";
my $home_rootfs = "$home/root_filesystem/";
# here's where the value of linux can be set
my $home_uml_kernel;
$option{gui_mode} ? ($home_uml_kernel = "$home/user-mode-linux/usr/bin/")
: ($home_uml_kernel = "$home/uml_kernel/");
sub uml_kernel {
my $home_umlk = $home_uml_kernel;
$home_umlk = $home_umlk . "linuxbr" if !$option{"uml-kernel"};
return $home_umlk;
}
my $modules_directory = "/lib/modules";
my $Initrd;
$option{gui_mode} ?
($Initrd = $home_rootfs . "Initrd.gz")
: ($Initrd = "/usr/lib/bootroot/root_filesystem/Initrd.gz");
# This is for experimental stuff .. basically so I can test
# the boot fs as a normal user, since it's hard to create a boot disk
# with enough room using genext2fs.
my $busybox;
# Yard Stuff
my $home_yard = "$home/yard";
my $template_dir = "$home_yard/templates/";
my $home_yard_replacements = "$home_yard/Replacements";
$main::global_yard = $home_yard;
$main::oldroot = "/OLDROOT";
my $global_yard_replacements_arch_indep =
"/usr/share/gbootroot/yard/Replacements";
my $global_yard_replacements_arch_dep = "/usr/lib/bootroot/yard/Replacements";
my $global_yard_templates = "/usr/share/gbootroot/yard/templates";
$ENV{'PATH'} = "$home_yard:" . $ENV{'PATH'};
my $initrd;
my $compress;
my $false = 0;
my $true = 1;
# Helps determine what procedure to follow for the Boot Disk
my $ok;
my $box2;
my $label;
my $label_advanced;
my $separator;
my $order;
my $text_window;
my $verbosity_window;
#my $colormap;
#my $window;
# Make @container verbose, also look in generate()
my @container;
use constant METHOD => 0 ;
use constant KERNEL => 1 ;
use constant ROOT_FS => 2 ;
use constant BOOT_DEVICE => 3 ;
use constant SIZE => 4 ;
use constant COMPRESS => 5 ;
use constant LIB_STRIP => 6 ;
use constant BIN_STRIP => 7 ;
use constant OBJCOPY_BOOL => 8 ;
use constant ABS_DEVICE => 9 ;
use constant ABS_OPT_DEVICE => 10 ;
use constant ABS_APPEND => 11 ;
# The Selection values are used for button_fileselect_advanced
# since it shares fileselect and file_ok_sel with button.
#
# ABS: 12=Root_Device_Selection 13=UML_Kernel_Selection
# UML BOX: 14=Root_Fs_Selection
#
use constant MOD_STRIP => 15 ;
#
# ABS: 16=System.map_Selection
my @original_container;
my $file_dialog;
my $mtab;
# $old_mount is used for a little swapping magic when a normal user
# is using genext2fs and lilo.
my ($tmp, $mnt, $old_mount);
my $norm_root_device;
my ($hbox_advanced);
my $separator_advanced;
my @entry_advanced;
my ($ea1,$ea2,$ea3,$ea4,$ea5,$ea6); # entry advanced boot
my ($ear1,$ear2,$ear2_save,$ear3,$ear4); # entry advanced root
my ($eab1,$eab2,$eab3,$eab4); # entry advanced uml
my ($mtd_radio, $mtd_fs_type, $mtd_fs_type_combo, @fs_types,
$mtd_radio_mtdram, $mtd_radio_blkmtd, $mtd_check, $mtd_size,
$mtd_total_size); # mtd uml box
my $uml_window;
my $table_advanced;
my $table_advanced_root;
my ($spinner_advanced,$spinner_size);
my $button_count = 0;
my $button_count_root = 0;
my $obj_count = 0;
my $obj_count_root = 0;
my ($lib_strip_check,$bin_strip_check,$mod_strip_check);
my ($bz2_toggle,$gz_toggle);
my ($bz2_toggle_root,$gz_toggle_root,$compression_off);
#my ($main::combo); made this totally global
my ($adj2,$adj3);
my @strings;
#######
#######
# Since the restructuring
#######
my $tooltips;
my $vbox_advanced;
my $vbox_advanced_root;
my $entry3;
my $box1;
my $entry5;
my $pbar;
my $rbutton;
my $verbosefn;
my $umid;
# Value set by kernel_modules
my $kernel_version;
# $entry_advanced[3] is the Root Device
# $filesystem_size and root_device_size are important globals for ARS,
# there weren't put into entry_advanced because they are spin buttons.
# $entry_advanced[4] is the Root Filename
#
my ($filesystem_size, $root_device_size);
#
# Carrries ARS values to other modules via ars(), another program just has to
# export ars and it can capture these values
my $ars = {}; # anonymous hash
# My own creation - the roots touch the ground if three lines are added.
my @xpm_data = (
"32 45 3 1",
" c None",
". c SaddleBrown",
"X c black",
" ... ... ",
" ... ... ",
" ... ... ",
" ... ... ",
" ... ... ",
" ... ... ",
" ... ... ",
" ... ... ",
" ... ... ",
" ... .. ",
" ... ... ",
" ... ... ",
" .... ... ",
" .... ... ",
" .... ... ",
" .... ............. ",
" ..... ............. ",
" ...... ............. ",
" ....... ...",
"......... ..",
"................................",
"................................",
"............................... ",
"......... XXXXX ............ ",
"........ XXX .......... ",
"........ XXX ........ ",
" XXXXXX ",
" XXX XXX X XX XX ",
" X XXXXX X X X ",
" XX XXX X XX ",
" X XX X X ",
" X XX X XX X ",
" XX XX X XXXXX ",
" X XXXX XXX XXXXX X ",
" XX XX XX X XX ",
" X X X X X ",
" X XX X XX X ",
" X XX XX X ",
" X XX XXXXXXX XXX ",
" XX XX XXX ",
" XX XX XXXX XX XX ",
" XX XXX X XXXXXXX X ",
" X XXX X XX ",
" XX XXXXXXX XXX ",
" X XX X ",
" X X "
);
sub start {
if ( ($> != 0 && -e "/usr/lib/bootroot/genext2fs") ||
($> != 0 && ( $option{gui_mode} || $option{template}) ) ||
($> != 0 && ( $option{help} || $option{h} ) ) ) {
$main::makefs = "genext2fs -z -r0"; # -i8192 not a good idea
}
$SIG{INT} = \&signal;
$SIG{ABRT} = \&signal;
$SIG{TERM} = \&signal;
$SIG{QUIT} = \&signal;
$SIG{KILL} = \&signal;
(undef,$container[KERNEL],$container[ABS_APPEND]) = gdkbirdaao();
my ($sec,$min,$hour,$day,$month,$year) = (localtime)[0,1,2,3,4,5];
my $time = sprintf("%02d:%02d:%02d-%02d-%02d-%04d",
$hour, $min, $sec, $month+1, $day, $year+1900);
# Here's where stuff gets intersting, non-root users can create root_fs,
# which is great for UML, and a boot disk.
# The Administrator just needs to add a line like the one below to the
# fstab for each non-root user who wants to be able to create root_fs.
# In this example, `id -u` has to be the actual effective numeric user
# id, and the root_fs has to always be named root_fs when it is being
# made, but it can be renamed afterwards.
#
# /tmp/gboot_non_root_`id -u`/root_fs \
# /tmp/gboot_non_root_`id -u`/loopback \
# auto defaults,noauto,user,loop 0 0
#
# For the boot/root disks the administrator will have to give the user
# special su privileges (mknod) to make special devices. The $sudo
# variable can be set to sudo or super, fakeroot won't work.
# These include: /dev/{console,null,ram0,ram1,tty0}
# These two lines need to be added to create the boot_fs and the boot/root
# disk. In this example the user is locked into using one type of device
# for the boot/root
#
# /tmp/gboot_non_root_`id -u`/initrd_image \
# /tmp/gboot_non_root_'id -u1`/initrd_mnt \
# auto defaults,noauto,user,loop 0 0
#
#
# For genext2fs this is the only line required, this is so that lilo can
# run.
#
# /dev/fd0 /tmp/gboot_not_root_mnt_`id -u` auto defaults,noauto,user 0 0
# We call root, non-root, too, that's an in-joke. Root should stay
# out the picture anyways.
my $user = $>;
if (!-d "$tmp1/gboot_non_root_$user") {
$tmp = "$tmp1/gboot_non_root_$user" if err_custom_perl(
"mkdir $tmp1/gboot_non_root_$user",
"gBootRoot: ERROR: Could not make temporary directory") != 2;
}
$tmp = "$tmp1/gboot_non_root_$user";
if (!-d "$tmp1/gboot_non_root_mnt_$user") {
$mnt = "$tmp1/gboot_non_root_mnt_$user" if err_custom_perl(
"mkdir $tmp1/gboot_non_root_mnt_$user",
"gBootRoot: ERROR: Could not make mount directory") != 2;
}
$mnt = "$tmp1/gboot_non_root_mnt_$user";
# Verbosity is universal for all methods, and controlled by a scale slider.
# Yard
# 0 --> only the important messages.
# 1 --> all messages.
my $verbosity = 1; # info & sys use this as Global
## One hard copy log file is saved for the session, and the user can also
## save from the verbosity box including saving a selection.
$verbosefn = "$tmp/verbose"; # All verbosity
#my $verbosefn = "/tmp/verbose"; # Yard - always logged, but 0&1 = STDOUT
if ( !%option || $option{gui_mode} ) {
if ( !$::commandline ) {
# Need this before everything.
Gtk::Rc->parse("/etc/gbootroot/gbootrootrc");
verbosity_box();
start_logging_output($verbosefn,$verbosity); # Yard "tmp dir name"
# "verbosity level"
}
}
#-------------------------------
# USER DIRECTORIES
# /tmp
home_builder($tmp1);
if ( $home_uml_kernel =~ /user-mode-linux/ &&
$option{home} ) {
if (!-e "$home_uml_kernel/.options") {
open(OPTIONS,">$home_uml_kernel/.options")
or die "Couldn't write $home_uml_kernel/.options at $?\n";
# I removed mem=16M to make sure the optimal mem size was being
# chosen for the MTD Emulator
# in case the user didn't know any better.
print OPTIONS "umid=bootroot root=/dev/ubd0\n";
close(OPTIONS);
}
}
if ( !( $option{help} || $option{h} ) &&
$home_uml_kernel !~ /user-mode-linux/ &&
!$option{home} ) {
# $HOME/.gbootroot/root_filesystem
home_builder($home_rootfs);
# $HOME/.gbootroot/uml_kernel
home_builder($home_uml_kernel);
symlink_builder("/usr/bin/linuxbr","$home_uml_kernel/linuxbr");
if (!-e "$home_uml_kernel/.options") {
open(OPTIONS,">$home_uml_kernel/.options")
or die "Couldn't write $home_uml_kernel/.options at $?\n";
# I removed mem=16M to make sure the optimal mem size was being
# chosen for the MTD Emulator
# in case the user didn't know any better.
print OPTIONS "umid=bootroot root=/dev/ubd0\n";
close(OPTIONS);
}
# $HOME/.gbootroot/yard/templates
home_builder($template_dir);
if ( -d $global_yard_templates ) {
opendir(DIR,$global_yard_templates) if -d $template_dir;
# I decided this may be too restrictive, besides, everything
# is kept in its own directory.
#my @templates = grep { m,\.yard$, } readdir(DIR);
my @templates = grep { m,^\w+, } readdir(DIR);
closedir(DIR);
foreach ( @templates ) {
if (!-e "$template_dir/$_" && !-l "$template_dir/$_") {
symlink_builder("$global_yard_templates/$_","$template_dir/$_");
}
}
}
# Arch indep replacements repository
# $HOME/.gbootroot/yard/Replacements
home_builder($home_yard_replacements);
if ( -d $global_yard_replacements_arch_indep ) {
if (-d $home_yard_replacements) {
find sub { ( my $replacement =
$File::Find::name ) =~ s/$global_yard_replacements_arch_indep\///;
if (!-e "$home_yard_replacements/$replacement") {
#system "cp -a $File::Find::name $home_yard_replacements/$replacement > /dev/null 2>&1";
system "mkdir $home_yard_replacements/$replacement > /dev/null 2>&1" if -d $File::Find::name;
symlink_builder( $File::Find::name,"$home_yard_replacements/$replacement") if !-d $File::Find::name;
}
}, $global_yard_replacements_arch_indep;
}
}
# Arch dep replacements repository
if ( -d $global_yard_replacements_arch_dep ) {
if (-d $home_yard_replacements) {
find sub { ( my $replacement =
$File::Find::name ) =~ s/$global_yard_replacements_arch_dep\///;
if (!-e "$home_yard_replacements/$replacement") {
#system "cp -a $File::Find::name $home_yard_replacements/$replacement > /dev/null 2>&1";
system "mkdir $home_yard_replacements/$replacement > /dev/null 2>&1" if -d $File::Find::name;
symlink_builder( $File::Find::name,"$home_yard_replacements/$replacement") if !-d $File::Find::name;
}
}, $global_yard_replacements_arch_dep;
}
}
} # !%options
#-------------------------------
if ( !%option || $option{gui_mode} ) {
if ( !$::commandline ) {
# Gtk::check_version expects different arguments than .7004 so will have
# to check for the version instead.
# Right now >= 0.7002 is o.k.
#if (Gtk::check_version(undef,"1","0","7") =~ /too old/) {
if (Gtk->major_version < 1) {
et();
}
elsif (Gtk->micro_version < 7) {
et();
}
elsif (Gtk->minor_version < 2) {
et();
}
}
}
my $window;
if ( !%option || $option{gui_mode} ) {
if ( !$::commandline ) {
$window = Gtk::Window->new("toplevel");
# special policy
$window->set_policy( $false, $true, $true );
$window->set_title("gBootRoot");
$window->set_position('none');
$window->signal_connect("destroy",
sub {
unlink "$verbosefn", "$tmp/initrd_image.gz";
rmdir "$tmp/initrd_mnt";
rmdir "$tmp";
rmdir "$mnt";
Gtk->exit(0);
});
$window->border_width(1);
$window->realize;
# Do the iconizing thing
# "xpm/circles.xpm" can be @pixmap within file if not create_from_xpm.
my ($circles,$mask) = Gtk::Gdk::Pixmap->create_from_xpm_d($window->window,
$window->style->white,
@xpm_data);
$window->window->set_icon(undef, $circles, $mask);
$window->window->set_icon_name("gBootRoot");
# Zas - bug in gtk-perl < .7002
$window->window->set_decorations(['all', 'menu']);
$window->window->set_functions(['all', 'resize']);
$tooltips = Gtk::Tooltips->new();
$box1 = Gtk::VBox->new($false,0);
$window->add($box1);
$box1->show();
# First row
hbox();
my $entry = entry($false,0);
# Menu - later this may be improved if new methods are added.
my $opt = Gtk::OptionMenu->new();
$tooltips->set_tip( $opt, "Choose the Boot method.", "" );
my $menu = Gtk::Menu->new();
my $item = Gtk::MenuItem->new("2 disk compression" );
$item->show();
# Eventually get_menu, or something totally different will be used.
$item->signal_connect( 'activate',
sub { $entry->set_text("2 disk compression");
$container[METHOD] = "2 disk compression";
two_disk_compression_check();
kernel_modules(); });
$menu->append( $item );
$opt->set_menu( $menu );
$box2->pack_start( $opt, $true, $true, 0 );
$opt->show();
$box2->show();
# Second row
# Get to look three places for kernel value
# default ( null|gdkkbirdaao) && entry() && fileselect->file_ok_sel
hbox();
my $entry2 = entry($true,1);
$entry2->set_text($container[KERNEL]);
if ($container[KERNEL]) {
$ars->{kernel} = $container[KERNEL];
ars($ars);
ars2($ars);
}
button("Kernel Selection",$entry2,"Kernel Selection",1);
# Third row
hbox();
$entry3 = entry($true,2);
button("Root Filesystem",$entry3,"Root Filesystem",2,$home_rootfs);
# In the future, if experimenters send in data, there will be two
# different devices.
# Fourth row
hbox();
my $entry4 = entry($true,3);
$container[BOOT_DEVICE] = "/dev/fd0";
$entry4->set_text($container[BOOT_DEVICE]);
button("Device Selection",$entry4,"Device Selection",3,"/dev/fd0");
# Fifth row
hbox("what");
my $adj = Gtk::Adjustment->new( 1440.0, 0.0, 360000000.0, 282.0, 360.0, 0.0 );
my $spinner = Gtk::SpinButton->new( $adj, 0, 0 );
$tooltips->set_tip( $spinner, "Choose the Device Size.\n" .
"Hint: Many 1440 floppy drives support 1722.\n", "" );
$spinner->set_wrap( $true );
$spinner->set_numeric( $true );
$spinner->set_shadow_type( 'in' );
$spinner->show();
$container[SIZE] = 1440; # A better value - a rtbt trick.
$adj->signal_connect( "value_changed", sub {
$container[SIZE] = $spinner->get_value_as_int();
$adj2->set_value($container[SIZE]) if defined $adj2;});
$box2->pack_start( $spinner, $true, $true, 0 );
#label("Device Size");
# gz and bz2 radio buttons
$rbutton = Gtk::RadioButton->new( "gz" );
$tooltips->set_tip( $rbutton, "Choose Compression used on the Filesystem.", "" );
$gz_toggle = $rbutton;
$rbutton->set_active( $true );
$box2->pack_start( $rbutton, $false, $false, 0 );
$rbutton->show();
$rbutton = Gtk::RadioButton->new( "bz2", $rbutton );
$rbutton->set_usize(1,1);
$tooltips->set_tip( $rbutton, "Choose Compression used on the Filesystem.", "" );
$bz2_toggle = $rbutton;
$box2->pack_start( $rbutton, $true, $true, 0);
$rbutton->show();
# Verbosity adjustment
my $adj1 = Gtk::Adjustment->new( 2.0, 0.0, 2.0, 0.0, 1.0, 0.0 );
my $verbosity_scale = Gtk::HScale->new($adj1);
$verbosity_scale->set_value_pos("right");
$verbosity_scale->set_digits(0);
$tooltips->set_tip( $verbosity_scale, "Adjust the Verbosity Level.", "" );
$verbosity_scale->show();
# Verbosity Box can be turned on/off here
$adj1->signal_connect( "value_changed", sub {
$verbosity = $verbosity_scale->get_adjustment->value - 1;
verbosity($verbosity);
if ($verbosity == -1) {
if ($verbosity_window) {
destroy $verbosity_window if visible $verbosity_window;
}
}
elsif (!$verbosity_window) {
close(LOGFILE);
verbosity_box();
start_logging_output($verbosefn,$verbosity);
}
} );
$box2->pack_start( $verbosity_scale, $false, $false, 0);
#start_logging_output($yard_temp,$verbosity);
# Size status entry
$entry5 = Gtk::Entry->new();
$entry5->set_editable( $false );
$tooltips->set_tip( $entry5, "This shows room remaining on the Device.", "" );
$entry5->set_usize(20,20);
$box2->pack_start( $entry5, $true, $true, 0 );
$entry5->show();
my $button_advanced;
###########################
# The ADVANCED BOOT SECTION
###########################
# Separator
$separator = Gtk::HSeparator->new();
$box1->pack_start( $separator, $false, $true, 0 );
$separator->show();
# This is cool how this works.
$vbox_advanced = Gtk::VBox->new($false,0);
$box1->add($vbox_advanced);
$vbox_advanced->show();
# The Advanced Boot Section button
hbox_advanced($vbox_advanced);
$button_advanced = Gtk::Button->new("Advanced Boot Section");
$tooltips->set_tip( $button_advanced,
"Change settings for the Boot Disk Image.", "" );
$button_advanced->signal_connect("clicked",\&advanced_boot_section );
$hbox_advanced->pack_start( $button_advanced, $true, $true, 0 );
$button_advanced->show();
###########################
# The ADVANCED ROOT SECTION
###########################
$vbox_advanced_root = Gtk::VBox->new($false,0);
$box1->add($vbox_advanced_root);
$vbox_advanced_root->show();
hbox_advanced($vbox_advanced_root);
$button_advanced = Gtk::Button->new("Advanced Root Section");
$tooltips->set_tip( $button_advanced,
"Generate a Root Filesystem and/or use a different Root Device.", "" );
$button_advanced->signal_connect("clicked",\&advanced_root_section );
$hbox_advanced->pack_start( $button_advanced, $true, $true, 0 );
$button_advanced->show();
###########################
#############################
# The ADVANCED KERNEL SECTION
#############################
my $vbox_advanced_kernel = Gtk::VBox->new($false,0);
$box1->add($vbox_advanced_kernel);
$vbox_advanced_kernel->show();
hbox_advanced($vbox_advanced_kernel);
$button_advanced = Gtk::Button->new("Advanced Kernel Section");
$tooltips->set_tip( $button_advanced,
"Retrieve/Make Kernel Sources.", "" );
#$button_advanced->signal_connect("clicked",\&advanced_root_section );
$hbox_advanced->pack_start( $button_advanced, $true, $true, 0 );
$button_advanced->show();
#############################
# Separator
$separator = Gtk::HSeparator->new();
$box1->pack_start( $separator, $false, $true, 0 );
$separator->show();
# Status bar
my $align = Gtk::Alignment->new( 0.5, 0.5, 0, 0 );
$box1->pack_start( $align, $false, $false, 5);
$align->show();
$pbar = Gtk::ProgressBar->new();
$pbar->set_usize(321,10); # 321 10
$align->add($pbar);
$pbar->show();
# Separator
$separator = Gtk::HSeparator->new();
$box1->pack_start( $separator, $false, $true, 0 );
$separator->show();
# Submit button
hbox();
my $sbutton = Gtk::Button->new("Submit");
$sbutton->signal_connect( "clicked", \&submit);
$tooltips->set_tip( $sbutton, "Generate the Boot/Root set.", "" );
$sbutton->show();
$box2->pack_start( $sbutton, $true, $true, 0 );
$box2->show();
# Close button
my $cbutton = Gtk::Button->new("Close");
$cbutton->signal_connect("clicked",
sub {
unlink "$verbosefn", "$tmp/initrd_image",
"$tmp/initrd_image.gz";
system "umount $tmp/initrd_mnt > /dev/null 2>&1";
rmdir "$tmp/initrd_mnt";
rmdir "$tmp";
rmdir "$mnt";
Gtk->exit(0);
});
$tooltips->set_tip( $cbutton, "Exit gBootRoot.", "" );
$cbutton->show();
$box2->pack_start( $cbutton, $true, $true, 0 );
$box2->show();
# Help button
my $hbutton = Gtk::Button->new("Help");
$hbutton->signal_connect( "clicked", sub { create_text("help") });
$tooltips->set_tip( $hbutton, "Help about gBootRoot.", "" );
$hbutton->show();
$box2->pack_start( $hbutton, $true, $true, 0 );
$box2->show();
$window->show();
}
}
# Here we put the logic if the program is going to be run from the commandline.
# The logic is linear and the only feature planned to be included from the
# commandline is root_fs prototyping via the yard method. This logic could
# easily have been run from somewhere else, but for convenience it is here
# for now.
#
# here we avoid Generate() -> yard() -> yard_box() to avoid the GUI
else {
# VARIABLES
# # @entry_advanced
# UD or Default 4 = Root Filename
# UD or Default 5 = UML Kernel
# UD or Default 6 = Method -> my $method = $entry_advanced[6];
# UD 7 = Template
# UD or Default $filesystem_size;
# UD or Default fs_type & $uml_exclusively & preserve_ownership
# ?# 11 = Kernel Modules .. from the Boot Method
# UD or Default 12 = Kernel Version .. from the Boot Method ($RELASE)
# Default $ars->{tmp} = $tmp;
# Default $ars->{mnt} = $mnt;
# Default $ars->{template_dir} = $template_dir; #static right now.
# ars($ars);
# see prev. my $template = $ars->{template};
# my $root_filename = $ars->{filename};
# DON'T forget variables for Filesystem Box. fs_type & uml_exclusively &
# preserve_ownership
# sub ars2 { $ars = $_[0];
# $kernel = $ars->{kernel};
# $kernel_version_choice = $ars->{kernel_version_choice};
# $uml_exclusively = $ars->{uml_exclusively};
# $preserve_ownership = $ars->{preserve_ownership};
# }
# Commands will either be genext2fs -z -r0 or helper_fs .. root is allowable
# like normal
# For package making:
# Will always be genxt2fs (made first) for making the first helper fs ..
# then this helper fs will be used to make the one with cramfs .. although
# this could have been done with cramfs itself .. this avoids root automation
# and is a cool demonstration and testing mechanism.
# STAGE LOGIC - skip space_left and test
# Stages all have my $error return if $error && $error eq "ERROR";
# kernel_version_check() -- automatically
#
# check() read_contents_file( "$template_dir$template", $tmp,
# $filesystem_size, \%uml_expect );
#
# links_deps() extra_links($changed_text, \%nss_pam); hard_links
# library_dependencies
#
# create() - term depends on whether root or normal user (really copy)
# $lib_bool = "" if $lib_bool eq 0;
# $bin_bool = "" if $bin_bool eq 0;
# $mod_bool = "" if $mod_bool eq 0;
#
# my $error = create_filesystem($filename,$filesystem_size,$tmp,$lib_bool,
# $bin_bool,$mod_bool,$strip_bool, \%uml_expect);
# return if $error && $error eq "ERROR";
#
# create_uml() create_expect_uml($filesystem_size, $tmp, $filename);
#
# something like this does the trick: ./gbootroot --home . --template Example-Mini.yard --uml-exclusively on --expect-program ./expect_uml --uml-kernel user-mode-linux/usr/bin/linux --root-fs-helper root_filesystem/root_fs_helper
########################################################
# What to do if somebody specifies help
if ( $option{help} || $option{h} ) {
print "Usage: gbootroot [OPTION]...\n";
print " --help -h help\n";
print " --template=name required option - template " .
"in default template dir\n";
print " $template_dir" . "[name]\n\n";
print " (defaults)\n";
print " --method=name yard\n";
print " --root-filename=name root_fs\n";
print " --filesystem-size=size 8192\n";
print " --filesystem-command=c \"$::makefs\"\n";
print " --uml-exclusively=on|off off\n";
print " --uml-kernel=path $ENV{HOME}/.gbootroot/" .
"uml_kernel/linuxbr\n";
print " --uml-options=\"list\" \"\"\n";
print " --preserve-ownership=y|n n\n";
print " --genext2fs-dir=dir /usr/lib/bootroot/\n";
print " --expect-program=path /usr/lib/bootroot/expect_uml\n";
print " --root-fs-helper=path /usr/lib/bootroot/root_filesystem/root_fs_helper\n";
print " --home=dir gui mode = without other options\n";
print " cl mode = with other options\n";
print " min: --template\n\n";
print " (system kernel options)\n";
print " --kernel=path specify different system kernel\n";
print " --kernel-version=version specify alternative version\n\n";
print " (print options)\n";
print " --no-stdout don't print to console\n\n";
print "filesytem-commands supported by root_fs_helper:\n";
print "mke2fs mkcramfs genromfs mkfs.minix mkminix mkreiserfs " .
"mkfs.jffs mkfs.jffs2\n";
print "\nReport bugs to <freesource\@users.sourceforge.net>\n";
exit;
}
# Let's read in the ARGV
die "specify a template found in $template_dir\nuse --template\n"
if !$option{template};
start_logging_output($verbosefn,$verbosity); # Yard "tmp dir name"
$ars->{kernel} = $option{kernel};
ars2($ars);
$ars->{kernel_version_choice} = $option{"kernel-version"};
ars2($ars);
my $template = $option{template};
$option{"filesystem-size"}
? ($filesystem_size = $option{"filesystem-size"})
: ($filesystem_size = 8192);
my $uml_exclusively = 0; # assume genext2fs
if ( $option{"uml-exclusively"} ) {
$option{"uml-exclusively"} eq "on"
? ($uml_exclusively = 1)
: ($uml_exclusively = 0);
}
my $preserve_ownership = 0; # assume no
if ( $option{"preserve-ownership"} ) {
$option{"preserve-ownership"} eq "y"
? ($preserve_ownership = 1)
: ($preserve_ownership = 0);
}
$ars->{uml_exclusively} = $uml_exclusively;
ars2($ars); #not used in function below
$ars->{preserve_ownership} = $preserve_ownership;
ars2($ars);
# links_deps()
# Good defaults
my %nss_pam = (
60 => {
conf_nss => 1,
},
61 => {
conf_pam => 1,
},
);
# create()
my $lib_bool = 1;
my $bin_bool = 1;
my $mod_bool = 1;
my $strip_bool = 1;
my $filename;
$option{"root-filename"}
? ($filename = $option{"root-filename"})
: ($filename = "root_fs");
# The filesystem-type
$::makefs = $option{"filesystem-command"} if $option{"filesystem-command"};
# The Action - yard is the default method
my $method;
$option{method}
? ($method = $option{method})
: ($method = "yard");
if ( $method eq "yard" ) {
my $error = read_contents_file( "$template_dir$template", $tmp,
$filesystem_size);
return if $error && $error eq "ERROR";
$error = extra_links("$template_dir$template", \%nss_pam);
return if $error && $error eq "ERROR";
$error = hard_links();
return if $error && $error eq "ERROR";
$error = library_dependencies("$template_dir$template");
return if $error && $error eq "ERROR";
$error = create_filesystem($filename,$filesystem_size,$tmp,$lib_bool,
$bin_bool,$mod_bool,$strip_bool);
return if $error && $error eq "ERROR";
# create_uml()
create_expect_uml($filesystem_size, $tmp, $filename);
}
######################################################
} # end if !$::commandline || $option{gui_mode}
} # end start
#----------------------------
sub et {
error_window("gBootRoot is presently being developed with gtk-perl" .
" version $gtk_perl_version.\nYou are using a" .
" version of gtk-perl < $gtk_perl_version." .
" You may still be able\n" .
" to use this program, but you may encounter problems." .
" See the FAQ\nfor places to get a newer gtk-perl version." .
" \n\nThe most common error reported:\n\"Can't locate" .
" object method\"");
#,"center");
print "Using a version of gtk-perl < $gtk_perl_version\n";
}
# Basically so different users get the same things in
# their personal directories.
sub symlink_builder {
my ($oldfile,$newfile) = @_;
if (!-e $newfile && !-l $newfile) {
my $error;
symlink($oldfile,$newfile) or
($error = error("Can not make symlink to $oldfile
from $newfile.\n"));
}
}
sub home_builder {
my ($home_builder) = @_;
if (!-d $home_builder) {
if (-e $home_builder) {
error_window(
"gBootRoot: ERROR: A file exists where $home_builder should be");
}
else {
my @directory_parts = split(m,/,,$home_builder);
my $placement = "/";
for (1 .. $#directory_parts) {
$_ == 1 ? ($placement = "/$directory_parts[$_]")
: ($placement = $placement . "/" . $directory_parts[$_]);
-d $placement or err_custom_perl(
"mkdir $placement","gBootRoot: ERROR: Could not make $home_builder");
}
}
}
} # end home_builder
# This works on GNU/Linux
sub signal {
unlink "$verbosefn", "$tmp/initrd_image.gz";
system "umount $tmp/initrd_mnt > /dev/null 2>&1";
rmdir "$tmp/initrd_mnt";
rmdir "$tmp";
rmdir "$mnt";
$SIG{INT} = \&signal;
$SIG{ABRT} = \&signal;
$SIG{TERM} = \&signal;
$SIG{QUIT} = \&signal;
$SIG{KILL} = \&signal;
Gtk->exit(0);
}
sub hbox_advanced {
$hbox_advanced = Gtk::HBox->new(1,1 );
$hbox_advanced->border_width( 2 ); # was 10
$hbox_advanced->set_usize(321, 20);
$_[0]->pack_start( $hbox_advanced, $false, $false, 0 );
show $hbox_advanced;
}
sub objcopy_right_click_advanced {
my ( @data ) = @_;
my $event = pop( @data );
if ( ( defined( $event->{'type'} ) )
and ( $event->{'type'} eq 'button_press' ) ) {
if ( $event->{'button'} == 3 ) {
if (defined $lib_strip_check) {
if ($obj_count == 0) {
$tooltips->set_tip( $lib_strip_check,
"This is generally a good idea." .
" Press the right mouse button to" .
" change from [objcopy --strip-all]" .
" to [objcopy --strip-debug].", "" );
$obj_count++;
}
else {
$tooltips->set_tip( $lib_strip_check,
"This is generally a good idea." .
" Press the right mouse button to" .
" change from [objcopy --strip-debug]".
" to [objcopy --strip-all].", "" );
$obj_count--;
}
}
}
}
} # end obj_right_click_advanced
sub advanced_boot_section {
if ($button_count == 0) {
#$vbox_advanced->set_usize(321,300);
my $boolean;
# The table section
$table_advanced = Gtk::Table->new( 7, 3, $true );
$vbox_advanced->pack_start( $table_advanced, $true, $true, 0 );
$table_advanced->show();
#_______________________________________
# lib_strip_check
#label_advanced("Stripping:",0,1,0,1,$table_advanced);
!defined $lib_strip_check ? ($boolean = 1)
: ($boolean = $lib_strip_check->get_active());
$lib_strip_check = Gtk::CheckButton->new("Libraries");
$lib_strip_check->set_active($boolean);
$lib_strip_check->signal_connect( "button_press_event",
\&objcopy_right_click_advanced);
$tooltips->set_tip( $lib_strip_check,
"This is generally a good idea. Press the" .
" right mouse button to change from" .
" [objcopy --strip-debug] to" .
" [objcopy --strip-all].", "" );
$table_advanced->attach($lib_strip_check,0,1,0,1,
['expand'],['fill','shrink'],0,0);
show $lib_strip_check;
# bin_strip_check
!defined $bin_strip_check ? ($boolean = 1)
: ($boolean = $bin_strip_check->get_active());
$bin_strip_check = Gtk::CheckButton->new("Binaries");
$bin_strip_check->set_active($boolean);
$tooltips->set_tip( $bin_strip_check,
"This is generally a good idea." .
" [objcopy --strip-all]", "" );
$table_advanced->attach($bin_strip_check,1,2,0,1,
['expand'],['fill','shrink'],0,0);
show $bin_strip_check;
# mod_strip_check
!defined $mod_strip_check ? ($boolean = 1)
: ($boolean = $mod_strip_check->get_active());
$mod_strip_check = Gtk::CheckButton->new("Modules");
$mod_strip_check->set_active($boolean);
$tooltips->set_tip( $mod_strip_check,
"This is generally a good idea." .
" [objcopy --strip-debug]", "" );
$table_advanced->attach($mod_strip_check,2,3,0,1,
['expand'],['fill','shrink'],0,0);
show $mod_strip_check;
#_______________________________________
# Development Drive
label_advanced("Devel Device:",0,1,1,2,$table_advanced);
$ea1 = entry_advanced(1,2,1,2,0,$table_advanced);
$tooltips->set_tip( $ea1, "If the device used for development" .
" is different than the actual boot" .
" device, use this field" .
" to indicate that device." .
" You will have to run" .
" lilo -v -C brlilo.conf -r" .
" \"device mount point\" manually at a" .
" later time on the actual" .
" boot device.",
"" );
$ea1->set_text($container[BOOT_DEVICE]) if defined $container[BOOT_DEVICE];
#_______________________________________
# Optional Device(s)
label_advanced("Opt. Device(s)",0,1,2,3,$table_advanced);
$ea2 = entry_advanced(1,3,2,3,1,$table_advanced);
$tooltips->set_tip( $ea2, "Add devices to the boot disk which are" .
" necessary for the kernel to function" .
" properly. Put a space between each" .
" device. For instance, /dev/fb0 for" .
" frame buffer devices.",
"");
$ea2->set_text($entry_advanced[1]) if defined $entry_advanced[1];
#_______________________________________
# Kernel Module(s)
label_advanced("Kernel Module(s)",0,1,4,5,$table_advanced);
$ea3 = entry_advanced(1,3,4,5,11,$table_advanced);
$tooltips->set_tip( $ea3, "Add the modules found in" .
" /lib/modules/kernel-version which are" .
" necessary for the Boot Method to work" .
" properly. Kmod inserts the modules," .
" and kmod needs to be built into the" .
" kernel along with initrd and ramdisk." ,
"");
$ea3->set_text($entry_advanced[11]) if defined $entry_advanced[11];
#_______________________________________
# Append Options
label_advanced("append =",0,1,3,4,$table_advanced);
$ea4 = entry_advanced(1,3,3,4,2,$table_advanced);
my $append; (undef,undef,$append) = gdkbirdaao();
$tooltips->set_tip( $ea4, "Add append options to brlilo.conf.", "");
# this will only show append if real
if (!defined $entry_advanced[2]) {
$ea4->set_text($append) if $append;
}
else {
$ea4->set_text($entry_advanced[2]) if $entry_advanced[2];
}
#_______________________________________
# Kernel Version
label_advanced("Kernel Version:",0,1,5,6,$table_advanced);
$ea5 = entry_advanced(1,2,5,6,12,$table_advanced);
$tooltips->set_tip( $ea5, "Override the kernel version number found" .
" in the kernel header. This will change" .
" the /lib/modules/kernel-version directory",
"");
$ea5->set_text($entry_advanced[12]) if defined $entry_advanced[12];
#_______________________________________
# System.map
label_advanced("System.map:",0,1,6,7,$table_advanced);
$ea6 = entry_advanced(1,2,6,7,13,$table_advanced);
$tooltips->set_tip( $ea6, "When a non-running kernel is chosen it is " .
" important to include a copy of that" .
" kernel's System.map file so that depmod" .
" can use the correct set of kernel symbols" .
" to resolve kernel references in each" .
" module. This can be found in the" .
" kernel's source code after compilation.",
"");
$ea6->set_text($entry_advanced[13]) if defined $entry_advanced[13];
button_fileselect_advanced(2,3,6,7,"Selection",$ea6,"Selection",16,
$table_advanced,"/lib/modules/");
$button_count++;
}
else {
destroy $table_advanced;
$button_count--;
}
} # end sub advanced_boot_section
sub advanced_root_section {
if ($button_count_root == 0) {
my $boolean;
$table_advanced_root = Gtk::Table->new( 9, 3, $true );
# temp solution?
#$table_advanced_root->set_row_spacings( 3 );
$vbox_advanced_root->pack_start( $table_advanced_root, $true,
$true, 0 );
#_______________________________________
# Root Device selection
# $::device $device already exist
label_advanced("Root Device:",0,1,0,1,$table_advanced_root);
# $_[4] shares with advanced_boot_sections @entry_advanced
$ear1 = entry_advanced(1,2,0,1,3,$table_advanced_root);
if ($entry_advanced[3]) {
$ear1->set_text($entry_advanced[3]);
}
else {
$ear1->set_text($container[BOOT_DEVICE]);
}
$tooltips->set_tip( $ear1,
"Type in the location of the Root Device to use.",
"" );
# $order is important because it is put in $container[$order]
button_fileselect_advanced(2,3,0,1,"Selection",$ear1,"Selection",12,
$table_advanced_root,"/dev/fd0");
#_______________________________________
# Root Device Size
# gBootRoot methods
label_advanced("Root Device Size:",0,1,1,2,$table_advanced_root);
$adj2 = Gtk::Adjustment->new( 1440.0, 0.0, 360000000.0, 282.0,
360.0, 0.0 );
$spinner_advanced = Gtk::SpinButton->new( $adj2, 0, 0 );
$table_advanced_root->attach($spinner_advanced,1,2,1,2,
['shrink','fill','expand'],['fill','shrink'],
0,0);
$tooltips->set_tip( $spinner_advanced,
"Choose the Root Device Size.",
"" );
$spinner_advanced->set_wrap( $true );
$spinner_advanced->set_numeric( $true );
$spinner_advanced->set_shadow_type( 'in' );
$spinner_advanced->show();
$root_device_size = 1440 if !$root_device_size;
$adj2->signal_connect( "value_changed", sub {
$root_device_size = $spinner_advanced->get_value_as_int();});
# For some reason $container[SIZE] is tranforming into [3] when
# device selection is changed. & in ABS devel device doesn't keep
# state.
if ($root_device_size) {
$spinner_advanced->set_value($root_device_size);
}
else {
$adj2->set_value($container[SIZE]) if defined $adj2;
}
#_______________________________________
# Root File Name
# gBootRoot methods
label_advanced("Root Filename:",0,1,2,3,$table_advanced_root);
$ear2 = entry_advanced(1,2,2,3,4,$table_advanced_root);
$ear2->set_text("root_fs") if !$entry_advanced[4];
$ars->{filename} = "root_fs" if !$entry_advanced[4];
$ear2->set_text($entry_advanced[4]) if $entry_advanced[4];
root_filename($ear2);
$ars->{filename} = $entry_advanced[4] if $entry_advanced[4];
ars($ars);
$tooltips->set_tip( $ear2, "Give the Root Filesystem file a name.",
"" );
!defined $ear2_save ? ($boolean = 1)
: ($boolean = $ear2_save->get_active());
$ear2_save = Gtk::CheckButton->new("save");
$ear2_save->set_active($boolean);
# "Save Root File. Press right button to change" .
# " the Directory the file is saved in.",
$tooltips->set_tip( $ear2_save,
"Saves the Root Filesystem in your" .
" $ENV{HOME}/.gbootroot/root_filesystem" .
" directory.",
"" );
$table_advanced_root->attach($ear2_save,2,3,2,3,
['expand'],['fill','shrink'],0,0);
show $ear2_save;
#_______________________________________
# Filesystem Size
# $::fs_device
label_advanced("Filesystem Size:",0,1,3,4,$table_advanced_root);
$adj3 = Gtk::Adjustment->new( 8192.0, 0.0, 1000000000.0, 128.0,
1024.0, 0.0 );
$spinner_size = Gtk::SpinButton->new( $adj3, 0, 0 );
$table_advanced_root->attach($spinner_size,1,2,3,4,
['shrink','fill','expand'],['fill','shrink'],
0,0);
$tooltips->set_tip( $spinner_size,
"Choose the Filesystem Size.",
"" );
$spinner_size->set_wrap( $true );
$spinner_size->set_numeric( $true );
$spinner_size->set_shadow_type( 'in' );
$spinner_size->show();
$filesystem_size = 8192 if !$filesystem_size;
$ars->{filesystem_size} = $filesystem_size;
ars($ars);
filesystem_size();
$adj3->signal_connect( "value_changed", sub {
$filesystem_size = $spinner_size->get_value_as_int();
$ars->{filesystem_size} = $filesystem_size;
ars($ars);
filesystem_size();
});
$spinner_size->set_value($filesystem_size) if $filesystem_size;
my $filesystem_box_b = button_advanced(2,3,3,4,"Filesystem Box",$table_advanced_root);
$filesystem_box_b->signal_connect("clicked",\&file_system);
$tooltips->set_tip( $filesystem_box_b, "Open Filesystem Box.", "" );
#_______________________________________
# Compression
# gBootRoot methods
my $hbox_between = Gtk::HBox->new(0,1);
$table_advanced_root->attach($hbox_between,0,3,4,5,
['fill'],
['fill','shrink'],15,0 );
$hbox_between->show;
# label
my $label_compression = Gtk::Label->new( "Compression:" );
$label_compression->set_justify( "right" );
$hbox_between->pack_start( $label_compression, $false, $false, 0 );
$label_compression->show();
# gz
$rbutton = Gtk::RadioButton->new( "gz" );
$tooltips->set_tip( $rbutton,
"Choose Compression used on the Filesystem.", "" );
$gz_toggle_root = $rbutton;
$rbutton->set_active( $true );
$hbox_between->pack_start( $rbutton, $true, $false, 0 );
$rbutton->show();
# bz2
$rbutton = Gtk::RadioButton->new( "bz2", $rbutton );
$tooltips->set_tip( $rbutton,
"Choose Compression used on the Filesystem.", "" );
$bz2_toggle_root = $rbutton;
$hbox_between->pack_start( $rbutton, $true, $false, 0 );
$rbutton->show();
# compression off
!defined $compression_off ? ($boolean = 1)
: ($boolean = $compression_off->get_active());
$compression_off = Gtk::CheckButton->new( "off");
$tooltips->set_tip( $compression_off,
"Turn Compression off.", "" );
$hbox_between->pack_start( $compression_off, $true, $false, 0 );
$compression_off->set_active($boolean);
$compression_off->show();
#_______________________________________
# UML Kernel
label_advanced("UML Kernel:",0,1,5,6,$table_advanced_root);
# $_[4] shares with advanced_boot_sections @entry_advanced
$ear3 = entry_advanced(1,2,5,6,5,$table_advanced_root);
!$entry_advanced[5] ? $ear3->set_text("$home_uml_kernel" . "linuxbr") :
$ear3->set_text($entry_advanced[5]);
$tooltips->set_tip( $ear3,
"If you have a User Mode Linux Kernel, type in" .
" the Kernel's location," .
" and any Kernel options desired afterwards.",
"" );
button_fileselect_advanced(2,3,5,6,"Selection",$ear3,"Selection",13,
$table_advanced_root, $home_uml_kernel);
#_______________________________________
# Method
label_advanced("Method:",0,1,6,7,$table_advanced_root);
$ear4 = entry_advanced(1,2,6,7,6,$table_advanced_root);
$ear4->set_editable($false);
$tooltips->set_tip( $ear4,
"Choose the Root Filesystem Generation Method.",
"" );
my $opt_root = Gtk::OptionMenu->new();
$tooltips->set_tip( $opt_root,
"Choose the Root Filesystem Generation Method.",
"" );
my $menu_root = Gtk::Menu->new();
my $yard = Gtk::MenuItem->new("Yard" );
$menu_root->append( $yard );
$yard->signal_connect( 'activate', sub {
$ear4->set_text("yard");
$entry_advanced[6] = $ear4->get_text();
opendir(DIR,$template_dir) if -d $template_dir;
#@strings = grep { m,\.yard$, } readdir(DIR);
@strings = grep { m,^\w+, } readdir(DIR);
closedir(DIR);
$main::combo->set_popdown_strings( @strings ) if @strings;
} );
$ear4->set_text($entry_advanced[6]) if $entry_advanced[6];
if ($yard) {
opendir(DIR,$template_dir) if -d $template_dir;
#@strings = grep { m,\.yard$, } readdir(DIR) if $yard;
@strings = grep { m,^\w+, } readdir(DIR) if $yard;
closedir(DIR)
}
$yard->show();
$opt_root->set_menu( $menu_root );
$table_advanced_root->attach($opt_root,2,3,6,7,
['expand','fill'],['fill','shrink'],0,0);
$opt_root->show();
#_______________________________________
# Template
# $::contents_file
label_advanced("Template:",0,1,7,8,$table_advanced_root);
$main::combo = Gtk::Combo->new();
$main::combo->entry->set_text($entry_advanced[7]) if $entry_advanced[7];
#$button_count_root_open = 1 + $button_count_root_open;
#print $button_count_root_open;
#if ($button_count_root_open > 1) {
# $main::combo->set_popdown_strings( @strings )
# if $entry_advanced[7] ne "";
#}
$tooltips->set_tip( Gtk::Combo::entry($main::combo),
"Choose a Template for the Method.",
"" );
$entry_advanced[7] = $main::combo->entry->get_text(); # nothing selected
$main::combo->entry->signal_connect("changed", sub {
$entry_advanced[7] = $main::combo->entry->get_text();
$ars->{template} = $entry_advanced[7];
ars($ars);
} );
$table_advanced_root->attach($main::combo,1,3,7,8,
['expand','fill'],['fill','shrink'],0,0);
show $main::combo;
#_______________________________________
# Generate - UML - Accept buttons
$table_advanced_root->set_row_spacing( 7, 9);
# The Generation process is determined by the method chosen. Yard -
# asks the user if they want to modify the template, and/or save a
# new template with modifications (to be added to Template menu).
my $generate_b = button_advanced(0,1,8,9,"Generate",$table_advanced_root);
$generate_b->signal_connect("clicked",\&Generate);
$tooltips->set_tip( $generate_b, "Generate Root Filesystem.", "" );
my $UML_b = button_advanced(1,2,8,9,"UML",$table_advanced_root);
$UML_b->signal_connect("clicked", \&uml_box);
$tooltips->set_tip( $UML_b, "Test Filesystem with User Mode Linux.",
"" );
# UML kernel doesn't look like a normal kernel
##if (!-d $entry_advanced[5] && -f $entry_advanced[5]) {
##$k_error = kernel_version_check($entry_advanced[5]);
##return if $k_error && $k_error eq "ERROR";}
## else {
##error_window("Kernel Selection required");
##return; }
# Will check to make sure that Filesystem fits device.
# Method determines whether or not compression is used.
my $accept_b = button_advanced(2,3,8,9,"Accept",$table_advanced_root);
$accept_b->signal_connect("clicked", \&accept_button, $ear2_save);
$tooltips->set_tip( $accept_b, "Accept Filesystem.", "" );
$table_advanced_root->show();
$button_count_root++;
}
else {
destroy $table_advanced_root;
$button_count_root--;
}
} # end sub advanced_root_section
sub uml_box {
if (not defined $uml_window) {
$uml_window = Gtk::Window->new("toplevel");
$uml_window->signal_connect("destroy", \&destroy_window,
\$uml_window);
$uml_window->signal_connect("delete_event", \&destroy_window,
\$uml_window);
##$uml_window->set_usize( 500, 95 ); # 450 175 || 500 600
$uml_window->set_default_size( 525, 165 ); # 525 95 || 450 175
# 525 135 || 500 600
$uml_window->set_policy( $true, $true, $false );
$uml_window->set_title( "UML Box" );
$uml_window->border_width(1);
my $main_vbox = Gtk::VBox->new( $false, 0 );
$uml_window->add( $main_vbox );
$main_vbox->show();
##my $table_uml = Gtk::Table->new( 4, 3, $true );
my $table_uml = Gtk::Table->new( 5, 8, $false );
##$main_vbox->pack_start( $table_uml, $true, $true, 0 );
$main_vbox->pack_start( $table_uml, $true, $false, 0 );
$table_uml->show();
#_______________________________________
# Xterm and execute options
label_advanced("Xterm:",0,1,0,1,$table_uml);
$eab1 = entry_advanced(1,2,0,1,8,$table_uml); # 1,2
$eab1->set_text($uml_xterm);
$tooltips->set_tip( $eab1,
"Choose an xterm with " .
"its executable option switch.",
"" );
#_______________________________________
# UML options
label_advanced("Options:",0,1,1,2,$table_uml);
$eab2 = Gtk::Combo->new();
$table_uml->attach($eab2,1,5,1,2,
['expand','fill'],['fill','shrink'],0,0); # 1,3
my $error;
open(OPTIONS,"$home_uml_kernel/.options") or
($error = error("$home_uml_kernel/.options: $!\n"));
return "ERROR"if $error && $error eq "ERROR";
my @initial_options = <OPTIONS>;
close(OPTIONS); chomp @initial_options;
$eab2->entry->set_text($initial_options[0]);
$entry_advanced[9] = $eab2->entry->get_text();
$eab2->set_popdown_strings( @initial_options ) ;
$eab2->entry->signal_connect("changed", sub {
$entry_advanced[9] = $eab2->entry->get_text();
open(OPTIONS,">$home_uml_kernel/.options");
$entry_advanced[9] =~ s/\n//g;
$entry_advanced[9] =~ s/\s+$//g;
print OPTIONS "$entry_advanced[9]\n";
foreach (@initial_options) {
if ($_ ne "$entry_advanced[9]") {
print OPTIONS "$_\n";
}
}
close(OPTIONS);
} );
$tooltips->set_tip( Gtk::Combo::entry($eab2),
"Enter uml command-line options.\n" .
"The umid value is used by mconsole to " .
"recognize which machine is running. " .
"Alter value for each Linux virtual " .
"machine invocation, and use the " .
"mconsole's switch options to gain " .
"control of the new machine.\n" .
"mtd_init is a special option that " .
"allows a MTD root_fs to start with an " .
"alternative init like /bin/bash.",
"" );
$eab2->show();
#_______________________________________
# mconsole
label_advanced("mconsole:",2,3,0,1,$table_uml);
$eab4 = entry_advanced(3,5,0,1,14,$table_uml);
$tooltips->set_tip( $eab4,
"Pass commands to the mconsole.\n" .
"1. sysrq [0-9|b|e|i|l|m|p|r|s|t|u] \n" .
"2. cad reboot halt stop go \n" .
"3. config <dev>=<config>\n4. remove <dev>\n" .
"5. switch <umid>\n6. version help",
"" );
$eab4->signal_connect("activate",
sub {
if ( $entry_advanced[9] ) {
$entry_advanced[9] =~
m,\s*umid=([\w\d-]+)\s*,;
$umid = $1 if !$umid;
my @command_parts = split(" ",
$entry_advanced
[14]);
# cad
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,cad, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"cad"
)
{
sys(
"uml_mconsole " .
$umid .
" cad");
}
}
}
# stop
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,stop, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"stop"
)
{
sys(
"uml_mconsole " .
$umid .
" stop");
}
}
}
# go
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,go, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"go"
)
{
sys(
"uml_mconsole " .
$umid .
" go");
}
}
}
# help
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,help, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"help"
)
{
sys(
"uml_mconsole " .
$umid .
" help");
}
}
}
# version
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,version, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"version"
)
{
sys(
"uml_mconsole " .
$umid .
" version");
}
}
}
# reboot
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,reboot, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"reboot"
)
{
system
"uml_mconsole " .
$umid .
" reboot&";
}
}
}
# halt
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,halt, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"halt"
)
{
system
"uml_mconsole " .
$umid .
" halt&";
}
}
}
# sysrq
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,sysrq, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"sysrq"
)
{
if ( !$command_parts[$co + 1] ||
$command_parts[$co + 1] =~
m,^[0-9]{1}$ | ^b$ | ^e$ | ^i$ | ^l$ |
^m$ | ^p$ | ^r$ | ^s$ | ^t$ | ^u$,x ) {
system
"uml_mconsole " .
$umid .
" sysrq $command_parts[$co + 1]&";
}
else {
system
"uml_mconsole " .
$umid .
" sysrq&";
}
}
}
}
# switch
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,switch, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"switch"
)
{
sys(
"uml_mconsole " .
$umid .
" switch $command_parts[$co + 1]");
$umid = $command_parts[$co + 1];
#$eab4->changed();
}
}
}
# config
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,config, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"config"
)
{
system
"uml_mconsole " .
$umid .
" config " .
"$command_parts[$co + 1]&";
}
}
}
# remove
if ( $entry_advanced[14] &&
$entry_advanced[14] =~ m,remove, ) {
for my $co (0 .. $#command_parts ) {
if ( $command_parts[$co] eq
"remove"
)
{
system
"uml_mconsole " .
$umid .
" remove " .
"$command_parts[$co + 1]&";
}
}
}
}
} );
#_______________________________________
# Root Filesystem defaults to generated one if found.
label_advanced("Root_Fs:",0,1,2,3,$table_uml);
$eab3 = entry_advanced(1,4,2,3,10,$table_uml); # 1,2 & 2,3
button_fileselect_advanced(4,5,2,3,"Selection",$eab3,"Selection",14,
$table_uml,$home_rootfs);
$eab3->set_text("ubd0=$tmp/$entry_advanced[4]")
if -e "$tmp/$entry_advanced[4]";
$tooltips->set_tip( $eab3,
"Choose an uncompressed root filesystem." .
"Append with ubd?=.",
"" );
#_______________________________________
# MTD device emulation - mtdram or blkmtd
# Which?
my $mtd_label = label_advanced("MTD",0,1,4,5,$table_uml);
$mtd_label->set_pattern("___");
my $mtd_check_on;
if ( $mtd_check ) {
if ( $mtd_check->get_active() ) {
$mtd_check_on = 1;
}
}
$mtd_check = Gtk::CheckButton->new("On or Off");
$tooltips->set_tip( $mtd_check,
"Turn MTD emulation on or off.",
"" );
$mtd_check->set_active( $true ) if $mtd_check_on;
$table_uml->attach($mtd_check,1,2,4,5,
['expand','shrink'],['fill','shrink'],0,0);
$mtd_check->show();
my ($mtdram_on, $blkmtd_on);
if ( $mtd_radio_mtdram ) {
if ( $mtd_radio_mtdram->get_active() ) {
$mtdram_on = 1;
}
else {
$blkmtd_on = 1;
}
}
# mtdram
$mtd_radio = Gtk::RadioButton->new("mtdram");
$mtd_radio_mtdram = $mtd_radio;
$mtd_radio->set_active( $true ) if $mtdram_on;
$tooltips->set_tip( $mtd_radio,
"Use memory to emulate test mtd device.",
"" );
$table_uml->attach($mtd_radio,2,3,4,5,
['shrink','expand'],['fill','shrink'],0,0);
$mtd_radio->show();
# blkmtd
$mtd_radio = Gtk::RadioButton->new("blkmtd", $mtd_radio);
$mtd_radio_blkmtd = $mtd_radio;
$mtd_radio->set_active( $true ) if $blkmtd_on;
$tooltips->set_tip( $mtd_radio,
"Use block device to emulate test mtd device.",
"" );
$table_uml->attach($mtd_radio,3,4,4,5,
['shrink','expand'],['fill','shrink'],0,0);
$mtd_radio->show();
# fs_type - users can define their own, but this won't be remembered.
$mtd_fs_type_combo = Gtk::Combo->new();
$tooltips->set_tip( Gtk::Combo::entry($mtd_fs_type_combo),
"Choose filesystem type used by root filesystem.",
"" );
$table_uml->attach($mtd_fs_type_combo,4,5,4,5,
['shrink','expand','fill'],['fill','shrink'],20,0);
if ( !$mtd_fs_type ) {
@fs_types = qw(jffs2 jffs ext2 ext3 minix cramfs romfs reiserfs);
$mtd_fs_type_combo->entry->set_text( $fs_types[0] );
$mtd_fs_type_combo->set_popdown_strings( @fs_types );
}
else {
$mtd_fs_type_combo->entry->set_text( $mtd_fs_type );
$mtd_fs_type_combo->set_popdown_strings( @fs_types );
}
$mtd_fs_type_combo->entry->signal_connect("changed", sub {
$mtd_fs_type = $mtd_fs_type_combo->entry->get_text();
if ( $mtd_fs_type =~ /$fs_types[0]/ ||
$fs_types[0] =~ /$mtd_fs_type/ ) {
shift(@fs_types);
}
unshift(@fs_types,$mtd_fs_type);
} );
$mtd_fs_type_combo->set_usize(20,0);
$mtd_fs_type_combo->show();
my $mtd_emul = label_advanced("Emulator",0,1,5,6,$table_uml);
$mtd_emul->set_pattern("________");
# total size
label_advanced("total size:",1,2,5,6,$table_uml);
my $mtd_adj = Gtk::Adjustment->new( 8192.0, 0.0, 1000000000.0, 1024.0,
8192.0, 0.0 );
$mtd_size = Gtk::SpinButton->new( $mtd_adj, 0, 0 );
$table_uml->attach($mtd_size,2,3,5,6,
['shrink','fill','expand'],['fill','shrink'],
0,0);
$tooltips->set_tip( $mtd_size,
"Choose the total size for the mtd device.",
"" );
$mtd_size->set_wrap( $true );
$mtd_size->set_numeric( $true );
$mtd_size->set_shadow_type( 'in' );
$mtd_size->show();
# Watch size if an actual file on open
my $stat_size;
if ( -f "$tmp/$entry_advanced[4]" ) {
$stat_size = (stat("$tmp/$entry_advanced[4]"))[12]/2;
my $blocks = ($stat_size + ( $stat_size * 0.30 ))/1024;
$blocks = sprintf("%.f",ceil($blocks));
$mtd_total_size = $blocks * 1024;
}
$eab3->signal_connect( "changed", sub {
my $root_fs = (split(/ubd\d{1}\w?=/,$entry_advanced[10]))[1];
if ( -f $root_fs ) {
$stat_size = (stat("$root_fs"))[12]/2;
my $blocks = ($stat_size + ( $stat_size * 0.30 ))/1024;
$blocks = sprintf("%.f",ceil($blocks));
$mtd_total_size = $blocks * 1024;
}
if ( $mtd_size ) {
$mtd_size->set_value($mtd_total_size) if $mtd_total_size;
}
});
$mtd_adj->signal_connect( "value_changed", sub {
$mtd_total_size = $mtd_size->get_value_as_int();
});
$mtd_size->set_value($mtd_total_size) if $mtd_total_size;
# erasure size $entry_advanced[15]
label_advanced("erasure size:",3,4,5,6,$table_uml);
my $mtd_erasure = entry_advanced(4,5,5,6,15,$table_uml);
$mtd_erasure->set_text( $entry_advanced[15] ) if $entry_advanced[15];
$tooltips->set_tip( $mtd_erasure,
"Choose the erasure size for the mtd device.",
"" );
#----------------------------------
# Separators
my $mtd_separator1 = Gtk::HSeparator->new();
$table_uml->attach($mtd_separator1,0,5,3,4,
['shrink','fill','expand'],['fill','shrink'],
0,5);
$mtd_separator1->show();
my $mtd_separator2 = Gtk::HSeparator->new();
$table_uml->attach($mtd_separator2,0,5,6,7,
['shrink','fill','expand'],['fill','shrink'],
0,5);
$mtd_separator2->show();
$table_uml->set_row_spacing( 6, 8);
#_______________________________________
# Submit Button
my $submit_b = button_advanced(0,1,7,8,"Submit",$table_uml);
$tooltips->set_tip( $submit_b,
"Start uml kernel processes.",
"" );
$submit_b->signal_connect("clicked",
sub {
# UML kernel = $entry_advanced[5]
# xterm -e linux ubd#=root_fs
# root=/dev/ubd#
open(OPTIONS,"$home_uml_kernel/.options");
@initial_options = <OPTIONS>;
close(OPTIONS); chomp @initial_options;
$eab2->set_popdown_strings( @initial_options ) ;
my $pid;
if ($entry_advanced[8] &&
$entry_advanced[10]) {
# Check to see if it actually exists
my $executable =
(split(/\s+/,$entry_advanced[8]))[0];
if (!find_file_in_path(basename($executable))) {
error_window("gBootRoot Error: " .
"Enter a valid xterm, and " .
"executable option.");
return;
}
if ($executable =~ m,/,) {
if (! -e $executable) {
error_window("gBootRoot Error: " .
"Enter a valid path for the xterm.");
return;
}
}
# MTD?
#########
if ( $mtd_check->get_active() ) {
# Everything becomes an option for Initrd to parse
# and is put on the options[9] line
my ($initrd, $ram, $mem, $root, $ramdisk_size, $ubd0, $init);
for ( $entry_advanced[10],$entry_advanced[9] ) {
# Check for the existence of root=/dev/ram0
if ( m,root=/dev/ram, ) {
$ram = 1;
}
# Check for the existence of root=/dev/ram0
if ( m,ramdisk_size=, ) {
$ramdisk_size = 1;
}
# Check for the existence of root=
if ( m,root=, ) {
$root = 1;
}
# Check for the existence of initrd=
if ( m,initrd=, ) {
m,(initrd=[/\d\w-]+),;
$initrd = $1;
}
# Find which runlevel or whether mtd_init is being used
if ( m,(mtd_init=[/\d\w\'\"-]+\s?\d?)[\"\']?, ) {
$init = (split(/=/,$1))[1];
chomp $init;
$init =~ s/\"//g;
$init =~ s/\'//g;
$init =~ s/\///;
}
elsif ( m,\s+([0-9A-CS]{1})|\s+(single), ) {
$init = $1 if $1;
$init = $2 if $2;
chomp $init;
$init = "sbin/init " . $init;
}
if ( $mtd_radio_mtdram->get_active() ) {
# Check for the existence mem=
if ( m,mem=, ) {
$mem = 1;
}
}
}
for ( $entry_advanced[10] ) {
# Grab the file being used
if ( $mtd_radio_blkmtd->get_active() ) {
if ( m,(ubd\d{1}\w?=[/\d\.\+\w-]+), ) {
if ( $1 !~ /_dd/ ) {
my $ubd0_replacement = $1;
$ubd0 = (split(/=/,$1))[1];
chomp $ubd0;
$ubd0 = $ubd0 . "_dd";
my $ubd0_replacement_dd = $ubd0_replacement . "_dd";
s/$ubd0_replacement/$ubd0_replacement_dd/;
}
else {
m,(ubd\d{1}\w?=[/\d\w-]+),;
$ubd0 = (split(/=/,$1))[1];
chomp $ubd0;
}
}
}
}
my ($total_size, $fs_type, $erasure_size);
# total size
$total_size = $mtd_size->get_value_as_int();
# what type of fs.
$fs_type = $mtd_fs_type_combo->entry->get_text();
# Pass on erasure size if it exists
if ( $entry_advanced[15] ) {
$erasure_size = $entry_advanced[15]
}
# Set a ram block if necessary
if ( !$ram ) {
for ( $entry_advanced[10],$entry_advanced[9] ) {
if ( m,root=, ) {
s,(root=[/\d\w-]+),root=/dev/ram0,;
}
}
}
if ( !$root ) {
$entry_advanced[9] = "root=/dev/ram0 " . $entry_advanced[9];
}
# Decide what to do with initrd
if ( !$initrd ) {
$initrd = "initrd=" . $Initrd;
}
else {
undef $initrd;
}
# Memory needs to be figured out in 16384K blocks
# otherwise it fails, and it needs to be at least 16384
# for uml.
# mem
my $mem_size;
if ( $mtd_radio_mtdram->get_active() ) {
if ( $total_size < 16384 ) {
$mem_size = 16384;
}
else {
$mem_size = 16384 * ceil($mtd_total_size / 16384);
if ( $total_size == $mem_size ) {
$mem_size = $mem_size + 16384;
}
}
}
elsif ( $mtd_radio_blkmtd->get_active() ) {
if ( $total_size < 16384 ) {
$mem_size = 16384;
}
else {
# This seems to be the way things are with blkmtd.
my $stat_size2 = $stat_size * 2;
my $stat_constant = 16384;
while ( $stat_size2 > $stat_constant ) {
$mem_size = $stat_constant * 2;
$stat_constant = $stat_constant * 2;
}
if ( $total_size >= $mem_size ) {
while ( $total_size >= $mem_size ) {
$mem_size = $mem_size * 2;
}
}
}
}
if ( !$mem ) {
$mem = "mem=$mem_size" . "K";
}
else {
undef $mem;
}
# Will use this format
# initrd=Initrd mem=? mtd=type,fs_type,size,erasure
# Tell initrd whether it is mtdram or blkmtd, and
if ( $mtd_radio_mtdram->get_active() ) {
# blkmtd uses the _dd images, mtdram uses the real image
for ( $entry_advanced[10],$entry_advanced[9] ) {
if ( m,(ubd\d{1}\w?=[/\d\w-]+), ) {
if ( $1 =~ /_dd/ ) {
s/_dd//g;
}
}
}
# ramdisk_size
if ( !$ramdisk_size ) {
#$ramdisk_size = "ramdisk_size=$total_size";
$ramdisk_size = "ramdisk_size=4096";
}
else {
undef $ramdisk_size;
}
# Order does matter because it's used by linuxrc
$entry_advanced[9] =
"mtd=mtdram,$fs_type,$total_size,$erasure_size,$init, " .
"$mem $ramdisk_size $initrd " . $entry_advanced[9];
}
# blkmtd
else {
# Make backing file
info(0,"Making $ubd0 backing file\n");
sys("dd if=/dev/zero of=$ubd0 bs=1k count=1 seek=$total_size");
# Order does matter because it's used by linuxrc
$entry_advanced[9] =
"mtd=blkmtd,$fs_type,$total_size,$erasure_size,$init, " .
"$mem $initrd " . $entry_advanced[9];
}
#info(0,"$entry_advanced[9]\n$entry_advanced[10]\n");
} # mtd preparations
#############
# The first argument is important
# to linuxrc, so just append new
# arguments.
if ( $entry_advanced[9] !~ m,mode=, ) {
$entry_advanced[9] = $entry_advanced[9] . " mode=" . skas_or_tt();
}
unless ($pid = fork) {
unless (fork) {
if ($pid == 0) {
sys("$entry_advanced[8] $entry_advanced[5] $entry_advanced[9] $entry_advanced[10]");
Gtk->_exit($pid);
}
}
}
waitpid($pid,0);
# Reset $entry_advanced[9] && $entry_advanced[10]
if ( $mtd_check->get_active() ) {
$entry_advanced[9] = $eab2->entry->get_text();
$entry_advanced[10] = $eab3->get_text();
}
}
else {
# MTD .. testing location
if (!$entry_advanced[8]) {
error_window("gBootRoot Error: " .
"Enter an xterm, and executable " .
"option.");
return;
}
if (!$entry_advanced[10]) {
error_window("gBootRoot Error: " .
"Enter the ubd?=Root_Filesystem " .
"and its location.");
return;
}
}
} );
#_______________________________________
# Abort Button
# This is the hard kill when all else fails, it also cleans up
# lingering processess, but is considered a last resort, and
# can be dangerous, it has even taken down a WM.
my $abort_b = button_advanced(3,4,7,8,"Abort",$table_uml);
$tooltips->set_tip( $abort_b,
"Abort uml kernel processes." .
"This serves three purposes:\n" .
"1. Your creation doesn't boot.\n" .
"2. Your creation does work and" .
" you use something like" .
" `shutdown -h now`. When you are all done use" .
" Abort because it provides an excellent" .
" way to kill any ghost processes.\n" .
"3. Your creation gets weird, and you need to " .
"Abort its processes to shut it down. ",
"" );
$abort_b->signal_connect("clicked",
sub {
if ($entry_advanced[10]) {
# Most stuff
remove_matching_process($entry_advanced[10]);
# Debian
remove_matching_process("Virtual Console");
# Good to remove uml_\w*
remove_matching_process('uml_\w*');
# Again for good measure :)
remove_matching_process($entry_advanced[10]);
}
} );
#_______________________________________
# Reboot Button - mconsole
my $reboot_b = button_advanced(1,2,7,8,"Reboot",$table_uml);
$tooltips->set_tip( $reboot_b,
"Passes the reboot command to the mconsole.",
"" );
$reboot_b->signal_connect("clicked",
sub {
# use first one found
$entry_advanced[9] =~
m,\s*umid=([\w\d-]+)\s*,;
$umid = $1 if !$umid;
system
"uml_mconsole $umid" .
" reboot&";
} );
#_______________________________________
# Halt Button - mconsole
my $halt_b = button_advanced(2,3,7,8,"Halt",$table_uml);
$tooltips->set_tip( $halt_b,
"Passes the halt command to the mconsole. " .
"If this fails use the Abort button.",
"" );
$halt_b->signal_connect("clicked",
sub {
# use first one found
$entry_advanced[9] =~
m,\s*umid=([\w\d-]+)\s*,;
$umid = $1 if !$umid;
system
"uml_mconsole $umid" .
" halt&";
} );
#_______________________________________
# Cancel button also kills UML kernel if still open
my $cancel_b = button_advanced(4,5,7,8,"Close",$table_uml);
$tooltips->set_tip( $cancel_b,
"Close uml box.",
"" );
$cancel_b->signal_connect("clicked",
sub {
$uml_window->destroy() if $uml_window;
} );
}
if (!visible $uml_window) {
$uml_window->show();
} else {
$uml_window->destroy;
}
} # sub uml_box
# Someday .. like today .. this will be switched to using mconsole as the
# first means of cleaning processes:
# uml_mconsole /tmp/uml/debian/mconsole (reboot|halt)
sub remove_matching_process {
my ($match_word) = @_;
# Just an overkill
if ($match_word =~ m,/,) {
$match_word =~ s,/,\\/,g;
}
my $ps = "ps auxw|";
open(P,"$ps");
while(<P>) {
# friendly approach
if (m,$match_word,) {
my $process = (split(/\s+/,$_,))[1];
system "kill $process";
# not so friendly approach
system "kill -9 $process";
}
}
close(P);
} # end remove_matching_process
sub accept_button {
my ($widget,$ear2_save) = @_;
my($tool,$value);
if (-e "$tmp/$entry_advanced[4]" ) {
if (!$compression_off->active) {
if ($gz_toggle_root->active) {
$compress = "gzip";
open(F,"file $tmp/$entry_advanced[4] |");
while (<F>) {
if (/gzip/) {
info(0, "Already gzip compressed.\n");
}
elsif (/bzip2/) {
info(0, "Already bzip2 compressed.\n");
}
else {
info(0,"Compressing $entry_advanced[4] with $compress\n");
system "$compress -c9 $tmp/$entry_advanced[4] > $tmp/$entry_advanced[4].gz&";
$, = "";
my @ps_check = `ps w -C $compress 2> /dev/null`;
$, = "\n";
my @pids;
foreach my $line ( @ps_check ) {
if ( $line =~
m,$compress -c $tmp/$entry_advanced[4]$, ) {
my $pid = (split(" ",$line))[0];
push(@pids,$pid);
}
}
foreach my $pid ( @pids ) {
do {
while (Gtk->events_pending)
{ Gtk->main_iteration; }
} while -d "/proc/$pid";
}
info(0,"Done compressing $entry_advanced[4] with $compress\n");
# Actually, keeping the original value is much nicer.
#$entry_advanced[4] = "$entry_advanced[4].gz";
$entry3->set_text("$tmp/$entry_advanced[4].gz");
}
}
close(F);
if ($ear2_save->active) {
if (-f "$home_rootfs/$entry_advanced[4]") {
save_as($entry_advanced[4]);
}
else {
return if errcp(sys("cp -a $tmp/$entry_advanced[4] $home_rootfs")) == 2;
}
}
else {
$ear2->set_text("$entry_advanced[4]");
}
}
elsif ($bz2_toggle_root->active) {
$compress = "bzip2";
open(F,"file $tmp/$entry_advanced[4] |");
while (<F>) {
if (/gzip/) {
info(0, "Already gzip compressed.\n");
}
elsif (/bzip2/) {
info(0, "Already bzip2 compressed.\n");
}
else {
info(0,"Compressing $entry_advanced[4] with $compress\n");
system "$compress -c $tmp/$entry_advanced[4] > $tmp/$entry_advanced[4].bz2&";
$, = "";
my @ps_check = `ps w -C $compress 2> /dev/null`;
$, = "\n";
my @pids;
foreach my $line ( @ps_check ) {
if ( $line =~
m,$compress -c $tmp/$entry_advanced[4]$, ) {
my $pid = (split(" ",$line))[0];
push(@pids,$pid);
}
}
foreach my $pid ( @pids ) {
do {
while (Gtk->events_pending)
{ Gtk->main_iteration; }
} while -d "/proc/$pid";
}
info(0,"Done compressing $entry_advanced[4] with $compress\n");
# Actually, keeping the original value is much nicer.
#$entry_advanced[4] = "$entry_advanced[4].bz2";
$entry3->set_text("$tmp/$entry_advanced[4].bz2");
}
}
close(F);
if ($ear2_save->active) {
if (-f "$home_rootfs/$entry_advanced[4]") {
save_as($entry_advanced[4]);
}
else {