mirror of
https://github.com/fspc/gbootroot.git
synced 2025-02-23 09:03:23 -05:00
and only tests if root and using a method which has lilo .. default if method hasn't been chosen.
4431 lines
135 KiB
Perl
Executable File
4431 lines
135 KiB
Perl
Executable File
#!/usr/bin/perl -w
|
||
|
||
# gBootRoot Copyright (C) 2000, 2001
|
||
#
|
||
#
|
||
# AUTHOR
|
||
# ------
|
||
#
|
||
# [ Lead Developer and Project Coordinator ]
|
||
# Jonathan Rosenbaum <freesource@users.sourceforge.net>
|
||
#
|
||
#
|
||
#
|
||
# CONTRIBUTORS
|
||
# ------------
|
||
#
|
||
# [ Developers ]
|
||
# Cristian Ionescu-Idbohrn <cii@axis.com>
|
||
# - Submitted gdkbirdaao() "Guess Default Kernel Boot Image Root Device
|
||
# And Append Options", mount directory suggestion, bug reports, lots of
|
||
# good conversations.
|
||
#
|
||
# [ Testers ]
|
||
# Magnus Holmberg <pucko@lysator.liu.se>
|
||
# - Suggestions, BootRoot (predecessor of gBootRoot) FAQ question,
|
||
# discovered a sizing discrepancy in boot_root.
|
||
#
|
||
# Zas <zas@metaconcept.com>
|
||
# - Discovered a Gtk versioning problem, and unnecessary defined variable.
|
||
#
|
||
# Cameron Caffee <Cameron_C_Caffee@AtlanticMutual.com>
|
||
# - Bug reports and data submission which lead to important solutions for
|
||
# the Boot.
|
||
#
|
||
# [ Supporters and Users ]
|
||
# Ben Carrell <ben@xmission.com>
|
||
# - Great compliments.
|
||
#
|
||
# Wim Vinckier <WimPunk@linuxfan.com>
|
||
# - Sent alert about bad BootRoot site link.
|
||
#
|
||
# [ Helper ]
|
||
# Yahshua Mashiyach
|
||
#
|
||
# FREE SOFTWARE (partial list only)
|
||
# --------------------------------
|
||
#
|
||
# User-Mode-Linux
|
||
# Jeff Dike <jdike@karaya.com>
|
||
#
|
||
# Yard
|
||
# Tom Fawcett <fawcett@croftj.net>
|
||
#
|
||
# Genext2fs
|
||
# Xavier Bestel <xavier.bestel@free.fr>
|
||
# Erik Andersen <andersen@codepoet.org>
|
||
#
|
||
# Perl
|
||
# Larry Wall <larry@wall.org>
|
||
#
|
||
# Gtk-Perl
|
||
# Kenneth Albanowski <kjahds@kjahds.com>
|
||
# Paolo Molaro <lupus@debian.org>
|
||
#
|
||
# GNU/Linux
|
||
# Linus Torvalds <torvalds@transmeta.com>
|
||
#
|
||
# E2fsprogs
|
||
# Theodore Ts'o <tytso@mit.edu>
|
||
#
|
||
# lsMode
|
||
# M-J. Dominus <mjd-perl-lsmode-id-i0k+gzzokd+@plover.com>
|
||
#
|
||
# http://gbootroot.sourceforge.net
|
||
|
||
# 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.
|
||
|
||
# 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.
|
||
|
||
|
||
# For distributions that don't adhere to the most recent FHS.
|
||
BEGIN {
|
||
|
||
my $fhs = grep(/\/usr\/share\/perl5/,@INC);
|
||
|
||
if ($fhs == 0) {
|
||
unshift(@INC,"/usr/share/perl5");
|
||
}
|
||
|
||
|
||
my $sbin = grep(/\/sbin/,$ENV{'PATH'});
|
||
if ($sbin == 0) {
|
||
$ENV{'PATH'} = "/sbin:" . $ENV{'PATH'};
|
||
}
|
||
|
||
$sbin = grep(/\/usr\/sbin/,$ENV{'PATH'});
|
||
if ($sbin == 0) {
|
||
$ENV{'PATH'} = "/usr/sbin:" . $ENV{'PATH'};
|
||
}
|
||
|
||
}
|
||
|
||
use Gtk;
|
||
use strict;
|
||
use BootRoot::Yard;
|
||
use BootRoot::YardBox;
|
||
use BootRoot::Error;
|
||
use File::Basename;
|
||
use File::Find;
|
||
use File::Path;
|
||
init Gtk;
|
||
set_locale Gtk;
|
||
|
||
# Perhaps you are wondering where to learn how to program with Gtk-Perl?
|
||
# There is an excellent tutorial by Stephen Wilhelm at
|
||
# http://personal.riverusers.com/~swilhelm/perlgtk/. Please
|
||
# help support his development of this tutorial. Another good place
|
||
# to learn from is test.pl in the Gtk/samples directory included with
|
||
# Gtk-Perl. A good reference can be found at
|
||
# http://projects.prosa.it/gtkperl/reference.html
|
||
|
||
# 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 $home = "$ENV{HOME}/.gbootroot";
|
||
my $uml_xterm = "xterm -e";
|
||
$main::editor = "emacs --font 6x13";
|
||
$main::makefs = "mke2fs -F -m0 -i8192"; # Root Disk
|
||
$main::sudo = "sudo";
|
||
|
||
# CHANGES
|
||
# 1.3.0 - 12/07/2001
|
||
# * Moved Changes to a /usr/share/doc/gbootroot/Changes
|
||
# from this version onwards.
|
||
#
|
||
#######################################################################
|
||
# 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.
|
||
my $version = "1.3.0";
|
||
my $date = "12.12.2001";
|
||
my $gtk_perl_version = "0.7002";
|
||
my $pwd = `pwd`; chomp $pwd;
|
||
my $home_rootfs = "$home/root_filesystem/";
|
||
my $home_uml_kernel = "$home/uml_kernel/";
|
||
my $modules_directory = "/lib/modules";
|
||
if ( $> != 0 && -e "/usr/lib/bootroot/genext2fs" ) {
|
||
$main::makefs = "genext2fs -z -r0"; # -i8192 not a good idea
|
||
}
|
||
# 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;
|
||
|
||
# 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,$ear3,$ear4); # entry advanced root
|
||
my ($eab1,$eab2,$eab3); # entry advanced uml
|
||
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;
|
||
|
||
# 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
|
||
|
||
# How the Boot/Root set is constructed for the 2 disk compression method:
|
||
#
|
||
# 1. submit() start the process.
|
||
# 2. kernel_modules() sets the $kernel_version.
|
||
# 3. lilo() is called.
|
||
# 4. $ok determines what functions should be called for creating the
|
||
# Boot disk.
|
||
# 5. If initrd hasn't been created yet then initrd is called, and then
|
||
# mtab(0=Boot) .. otherwise only mtab is called. If initrd is called,
|
||
# then it in turn calls initrd_size to check the size of everything going
|
||
# into the initrd, so that the initrd can be made as small as possible.
|
||
# 6. mtab determines which dialog to present to the user and then calls
|
||
# mtab_window with the numeric value determing whether to make a Boot or
|
||
# Root disk. 0=Boot 1=Root
|
||
# 7. mtab_window (prompts the user) and then calls mtab_check.
|
||
# 8. mtab_check checks whether the device is already mounted or not, and will
|
||
# keep prompting the user until either the device is umounted or a disk is
|
||
# inserted. Then it will mke2fs the block device and then it will call
|
||
# lilo_put_it_together if 0, or device2() if 1.
|
||
# 9. lilo_put_it_together puts together the initrd and necessary things to get
|
||
# lilo to work properly, and then runs lilo if the device is bootable.
|
||
# If the devel device is not the same as the boot device lilo will be
|
||
# skipped. Then mtab(1) is called.
|
||
#10. The filesystem for the Root device is made, and then device2 is called
|
||
# to copy over the root filesystem.
|
||
|
||
# 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 "
|
||
);
|
||
|
||
$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.
|
||
|
||
if ( $> == 0 ) {
|
||
|
||
if (!-d "$tmp1/gbootroot_tmp$time") {
|
||
$tmp = "$tmp1/gbootroot_tmp$time" if err_custom_perl(
|
||
"mkdir $tmp1/gbootroot_tmp$time",
|
||
"gBootRoot: ERROR: Could not make temporary directory") != 2;
|
||
}
|
||
if (!-d "$tmp1/gbootroot_mnt$time") {
|
||
$mnt = "$tmp1/gbootroot_mnt$time" if err_custom_perl(
|
||
"mkdir $tmp1/gbootroot_mnt$time",
|
||
"gBootRoot: ERROR: Could not make mount directory") != 2;
|
||
}
|
||
|
||
# Why?
|
||
$tmp = "$tmp1/gbootroot_tmp$time";
|
||
|
||
}
|
||
else {
|
||
|
||
# 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 $main::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
|
||
|
||
|
||
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.
|
||
|
||
my $verbosefn = "$tmp/verbose"; # All verbosity
|
||
#my $verbosefn = "/tmp/verbose"; # Yard - always logged, but 0&1 = STDOUT
|
||
|
||
# Need this before everything.
|
||
Gtk::Rc->parse("/etc/gbootroot/gbootrootrc");
|
||
|
||
verbosity_box();
|
||
start_logging_output($verbosefn,$verbosity); # Yard "tmp dir name"
|
||
# "verbosity level"
|
||
|
||
# While on the subject of error output:
|
||
#
|
||
# info($verbosity setting can be {0=blue,1=red}, "text") writes to verbosity
|
||
# box and to the LOGFILE $tmp/verbosity. Realative to the slider 1 == 2 and
|
||
# 0 == 1.
|
||
#
|
||
# warning("text") produces 0=blue output with "Warning: " prepended and keeps
|
||
# count of warning via the $Warnings variable.
|
||
#
|
||
# warning_test("text") is like warning except that it doesnt prepend any
|
||
# text, and doesn't keep count of anything.
|
||
#
|
||
# error("text") returns ERROR, writes to verbosity box (Error: "text"), and
|
||
# produces "gBootRoot: ERROR: "text" in error_window(), and writes to the
|
||
# LOGFILE $tmp/verbosity .. used to report an error
|
||
#
|
||
# sys("command action",TESTING) is like system(), if the command fails to open
|
||
# it calls error() and returns ERROR, if the command succeeds it writes the
|
||
# output from the action to info(1,$) if $_[1] doesn't equal TESTING, otherwise
|
||
# info(3,$_) which is really info(0,"text"). If the command fails it returns
|
||
# the error code $? or 0 on success.
|
||
#
|
||
# error_window("text") pop-ups an error dialog box with the text, but doesn't
|
||
# write to the verbosity box.
|
||
#
|
||
# The next commands are wrapped around sys() and produce pre-defined text for
|
||
# the error_window if an error occurs which returns 2, ofcourse because sys
|
||
# is called the output is sent to the verbosity box if the command succeeds.
|
||
# function(sys())
|
||
#
|
||
# errmk() "gBootRoot: ERROR: Could not make important directories" if $? != 0;
|
||
#
|
||
# errcp() "gBootRoot: ERROR: Could not copy over important stuff" if $? != 0;
|
||
#
|
||
# errum() "gBootRoot: ERROR: Could not umount the device" if $? != 0;
|
||
#
|
||
# errm() "gBootRoot: ERROR: Could not mount device" if $? != 0;
|
||
#
|
||
# errrm() "gBootRoot: ERROR: Could not remove a directory or file" if $? != 0;
|
||
#
|
||
# err() "gBootRoot: ERROR: Not enough space after all" if $? > 0
|
||
#
|
||
# The next commands are both wrapped around sys() and are given customized
|
||
# text to write to the error_window if an error occurs which returns 2.
|
||
# Ofcourse because sys is called the output is sent to the verbosity box if
|
||
# the command succeeds.
|
||
#
|
||
# err_custom("command action","error text","value") A defined third value will
|
||
# cause a normal system("$_[0] > /dev/null 2>&1") othewise
|
||
# BootRoot::Yard::sys("$_[0]") Is used.
|
||
#
|
||
# err_custom_perl("command action", "error text") Right now this is just for
|
||
# the command "mkdir." If mkdir is the command mkdir("directory",0755) is
|
||
# called.
|
||
|
||
#-------------------------------
|
||
# USER DIRECTORIES
|
||
# /tmp
|
||
home_builder($tmp1);
|
||
|
||
# $HOME/.gbootroot/root_filesystem
|
||
home_builder($home_rootfs);
|
||
|
||
# $HOME/.gbootroot/uml_kernel
|
||
home_builder($home_uml_kernel);
|
||
symlink_builder("/usr/bin/linux","$home_uml_kernel/linux");
|
||
if (!-e "$home_uml_kernel/.options") {
|
||
open(OPTIONS,">$home_uml_kernel/.options")
|
||
or die "Couldn't write $home_uml_kernel/.options at $?\n";
|
||
print OPTIONS "root=/dev/ubd0 mem=16M\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;
|
||
|
||
|
||
}
|
||
}
|
||
|
||
|
||
# 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
|
||
#-------------------------------
|
||
|
||
# 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();
|
||
}
|
||
|
||
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";
|
||
}
|
||
|
||
my $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']);
|
||
|
||
my $tooltips = Gtk::Tooltips->new();
|
||
|
||
my $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();
|
||
my $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
|
||
my $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
|
||
my $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.
|
||
my $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
|
||
###########################
|
||
my $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();
|
||
my $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();
|
||
main Gtk;
|
||
exit( 0 );
|
||
|
||
#----------------------------
|
||
|
||
# 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];
|
||
$ars->{filename} = $entry_advanced[4] if $entry_advanced[4];
|
||
ars($ars);
|
||
$tooltips->set_tip( $ear2, "Give the Root Filesystem file a name.",
|
||
"" );
|
||
my $ear2_save = Gtk::CheckButton->new("save");
|
||
$ear2_save->set_active($true);
|
||
|
||
# "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( 4096.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 = 4096 if !$filesystem_size;
|
||
$ars->{filesystem_size} = $filesystem_size;
|
||
ars($ars);
|
||
$adj3->signal_connect( "value_changed", sub {
|
||
$filesystem_size = $spinner_size->get_value_as_int();
|
||
$ars->{filesystem_size} = $filesystem_size;
|
||
ars($ars);
|
||
});
|
||
$spinner_size->set_value($filesystem_size) if $filesystem_size;
|
||
|
||
#_______________________________________
|
||
# 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
|
||
$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($true);
|
||
$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);
|
||
$ear3->set_text("$home_uml_kernel" . "linux");
|
||
$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", \¨_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( 500, 95 ); # 450 175 || 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( 4, 3, $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);
|
||
$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,3,1,2,
|
||
['expand','fill'],['fill','shrink'],0,0);
|
||
open(OPTIONS,"$home_uml_kernel/.options");
|
||
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.",
|
||
"" );
|
||
$eab2->show();
|
||
|
||
|
||
#_______________________________________
|
||
# Root Filesystem defaults to generated one if found.
|
||
label_advanced("Root_Fs:",0,1,2,3,$table_uml);
|
||
$eab3 = entry_advanced(1,2,2,3,10,$table_uml);
|
||
button_fileselect_advanced(2,3,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?=.",
|
||
"" );
|
||
|
||
$table_uml->set_row_spacing( 2, 4);
|
||
|
||
#_______________________________________
|
||
# Submit Button
|
||
my $submit_b = button_advanced(0,1,3,4,"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;
|
||
}
|
||
}
|
||
|
||
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);
|
||
|
||
}
|
||
else {
|
||
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;
|
||
}
|
||
|
||
}
|
||
|
||
} );
|
||
|
||
|
||
#_______________________________________
|
||
# Cancel button also kills UML kernel if still open
|
||
my $abort_b = button_advanced(1,2,3,4,"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 shutdown it. ",
|
||
"" );
|
||
$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]);
|
||
}
|
||
} );
|
||
|
||
#_______________________________________
|
||
# Cancel button also kills UML kernel if still open
|
||
my $cancel_b = button_advanced(2,3,3,4,"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 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 {
|
||
system
|
||
"$compress -c9 $tmp/$entry_advanced[4] > $tmp/$entry_advanced[4].gz";
|
||
$entry_advanced[4] = "$entry_advanced[4].gz";
|
||
$entry3->set_text("$tmp/$entry_advanced[4]");
|
||
}
|
||
}
|
||
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 {
|
||
system
|
||
"$compress -c $tmp/$entry_advanced[4] > $tmp/$entry_advanced[4].bz2";
|
||
$entry_advanced[4] = "$entry_advanced[4].bz2";
|
||
$entry3->set_text("$tmp/$entry_advanced[4]");
|
||
}
|
||
}
|
||
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]");
|
||
}
|
||
}
|
||
}
|
||
else { # off
|
||
$entry3->set_text("$tmp/$entry_advanced[4]");
|
||
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 {
|
||
error("$entry_advanced[4] doesn't exist; create it first.\n");
|
||
}
|
||
|
||
} # end accept_button
|
||
|
||
my ($save_as);
|
||
sub save_as {
|
||
|
||
# Will just use a dialog box.
|
||
|
||
my ($template) = @_;
|
||
#my ($button);
|
||
|
||
if (not defined $save_as) {
|
||
$save_as = Gtk::Dialog->new();
|
||
$save_as->signal_connect("destroy", \&destroy_window, \$save_as);
|
||
$save_as->signal_connect("delete_event", \&destroy_window, \$save_as);
|
||
$save_as->signal_connect("key_press_event", sub {
|
||
my $event = pop @_;
|
||
if ($event->{'keyval'}) {
|
||
if ($event->{'keyval'} == 65307) {
|
||
$save_as->destroy;
|
||
}
|
||
}
|
||
},
|
||
);
|
||
$save_as->set_title("Save As");
|
||
$save_as->border_width(12);
|
||
$save_as->set_position('center');
|
||
|
||
my $new_template = $template;
|
||
my $entry = Gtk::Entry->new();
|
||
$entry->set_editable( $true );
|
||
$entry->set_text($template) if $template;
|
||
$entry->signal_connect( "changed", sub {
|
||
$new_template = $entry->get_text();
|
||
});
|
||
$save_as->vbox->pack_start( $entry, $false, $false, 0);
|
||
$entry->show();
|
||
|
||
my $label = Gtk::Label->new();
|
||
$label->set_justify( 'left' );
|
||
$label->set_text("$template already exists, " .
|
||
"do\nyou want to write over it, " .
|
||
"or\nsave $new_template with a different name?");
|
||
$save_as->vbox->pack_start( $label, $false, $false, 2 );
|
||
$label->show();
|
||
|
||
my $button = Gtk::Button->new("OK");
|
||
my $event_count = 0;
|
||
my $new_template_tmp = "nothing";
|
||
$button->signal_connect("clicked", sub {
|
||
|
||
$entry_advanced[4] = $new_template;
|
||
$ars->{filename} = $new_template;
|
||
ars($ars);
|
||
|
||
# This is a renaming deal and this time doesn't exist in the archive
|
||
# or $tmp.
|
||
if (!-f "$home_rootfs/$new_template") {
|
||
if ($template ne $new_template) {
|
||
return if err_custom("mv $tmp/$template $tmp/$new_template",
|
||
"gBootRoot: ERROR: Could not rename $template to " .
|
||
"$new_template") == 2;
|
||
}
|
||
|
||
return if errcp(sys("cp -a $tmp/$new_template $home_rootfs")) == 2;
|
||
$ear2->set_text($new_template);
|
||
$entry3->set_text("$tmp/$new_template");
|
||
$save_as->destroy;
|
||
}
|
||
|
||
# This is a write-over situation .. exists in $tmp and archive
|
||
elsif (-e "$tmp/$new_template" && -f "$tmp/$new_template"
|
||
&& -f "$home_rootfs/$new_template" ) {
|
||
return if errcp(sys("cp -a $tmp/$new_template $home_rootfs")) == 2;
|
||
$ear2->set_text($new_template);
|
||
$entry3->set_text("$tmp/$new_template");
|
||
$save_as->destroy;
|
||
}
|
||
|
||
# Here the file trying to be renamed already exists in the archive
|
||
# but doesn't exist in $tmp
|
||
else {
|
||
|
||
$label->set_text("$new_template already exists, " .
|
||
"do\nyou want to write over it, " .
|
||
"or\nsave $template with a different name?");
|
||
|
||
$event_count++;
|
||
my $event = pop(@_);
|
||
|
||
if ($new_template eq $new_template_tmp) {
|
||
if ($event_count >= 2 && $event && $event eq "clicked") {
|
||
if ("$tmp/$template" ne "$tmp/$new_template") {
|
||
return if err_custom("mv $tmp/$template $tmp/$new_template",
|
||
"gBootRoot: ERROR: Could not rename $template to " .
|
||
"$new_template") == 2;
|
||
}
|
||
|
||
return if errcp(sys("cp -a $tmp/$new_template $home_rootfs"))
|
||
== 2;
|
||
$event_count = 0;
|
||
$ear2->set_text($new_template);
|
||
$entry3->set_text("$tmp/$new_template");
|
||
$save_as->destroy;
|
||
}
|
||
}
|
||
$new_template_tmp = $new_template;
|
||
}
|
||
},"clicked");
|
||
$button->can_default(1);
|
||
$save_as->action_area->pack_start($button, $false, $false,0);
|
||
$button->grab_default;
|
||
$button->show;
|
||
|
||
$button = Gtk::Button->new("Cancel");
|
||
$button->signal_connect("clicked", sub { destroy $save_as} );
|
||
$save_as->action_area->pack_start($button, $false, $false,0);
|
||
$button->show;
|
||
|
||
}
|
||
if (!visible $save_as) {
|
||
show $save_as;
|
||
}
|
||
else {
|
||
destroy $save_as;
|
||
}
|
||
|
||
} # end sub save_as
|
||
|
||
# Coming - .config storage, auto-matic kernel locus, all stages
|
||
# /usr/src/linux* Possible integration with other Projects .. modules
|
||
# will be in the logical place. Before ABS.
|
||
sub advanced_kernel_section {
|
||
|
||
|
||
} # end sub advanced_kernel_section
|
||
|
||
# Stuff univeral for all root filesystem methods
|
||
# Compression, UML Kernel, and Method only need to be known by the Dock.
|
||
|
||
|
||
sub Generate {
|
||
|
||
# @entry_advanced
|
||
# 0 = Development Drive
|
||
# 1 = Optional Devices
|
||
# 2 = Append Options
|
||
#------------------
|
||
# 3 = Root Device
|
||
# 4 = Root Filename
|
||
# 5 = UML Kernel
|
||
my $method = $entry_advanced[6]; # 6 = Method
|
||
# 7 = Template
|
||
# 8 = UML xterm
|
||
# 9 = UML options
|
||
# 10 = UML root_fs
|
||
#------------------
|
||
# 11 = Kernel Modules .. from the Boot Method
|
||
# 12 = Kernel Version .. from the Boot Method
|
||
# 13 = System.map .. from the Boot Method
|
||
|
||
# $root_device_size;
|
||
# $filesystem_size;
|
||
|
||
# File select: function order: non-table = button->fileselect->file_ok_sel
|
||
# table = button_fileselect_advanced->fileselect->file_ok_sel
|
||
|
||
$ars->{device} = $entry_advanced[3];
|
||
$ars->{device_size} = $root_device_size;
|
||
$ars->{tmp} = $tmp;
|
||
$ars->{mnt} = $mnt;
|
||
$ars->{template_dir} = $template_dir; # static right now.
|
||
ars($ars);
|
||
|
||
|
||
my $template = $ars->{template};
|
||
my $root_device = $ars->{device};
|
||
my $root_filename = $ars->{filename};
|
||
|
||
if (!$root_device || $root_device eq "") {
|
||
error_window("gBootRoot: ERROR: Root Device not defined");
|
||
return;
|
||
}
|
||
# devfs may change this .. it did, this is silly.
|
||
## if (!-b $root_device) {
|
||
## error_window("gBootRoot: ERROR: Not a valid Block Device");
|
||
## return;
|
||
## }
|
||
|
||
if (!$root_filename || $root_filename eq "") {
|
||
error_window("gBootRoot: ERROR: Root Filename not given");
|
||
return;
|
||
}
|
||
if (!$method || $method eq "") {
|
||
error_window("gBootRoot: ERROR: Method must be supplied");
|
||
return;
|
||
}
|
||
if (!$template || $template eq "") {
|
||
error_window("gBootRoot: ERROR: Template name not given");
|
||
return;
|
||
}
|
||
|
||
|
||
if ($method eq "yard") {
|
||
if (!$main::yard_window) {
|
||
##$ars->{kernel} = "" if !$entry2->get_text();
|
||
##ars($ars);
|
||
yard();
|
||
}
|
||
}
|
||
|
||
|
||
} # end sub Generate
|
||
|
||
sub button_advanced {
|
||
|
||
# cretzu should like this
|
||
my ($left_attach,$right_attach,$top_attach,
|
||
$bottom_attach,$text,$widget) = @_;
|
||
my $button = Gtk::Button->new($text);
|
||
$widget->attach($button,$left_attach,$right_attach,
|
||
$top_attach,$bottom_attach,
|
||
['shrink','fill','expand'],['fill','shrink'],2,2);
|
||
show $button;
|
||
return $button;
|
||
|
||
}
|
||
|
||
sub button_fileselect_advanced {
|
||
|
||
# cretzu should like this
|
||
# $order does matter because it fills in $container[$order].
|
||
my ($left_attach,$right_attach,$top_attach,$bottom_attach,$text,$ent,
|
||
$name,$order,$widget,$device) = @_;
|
||
|
||
my $button = Gtk::Button->new($text);
|
||
$widget->attach($button,$left_attach,$right_attach,
|
||
$top_attach,$bottom_attach,
|
||
['shrink','fill','expand'],['fill','shrink'],2,2);
|
||
|
||
# example
|
||
if ($order == 12) {
|
||
$tooltips->set_tip( $button, "Select the Root Device.", "" );
|
||
}
|
||
elsif ($order == 13) {
|
||
$tooltips->set_tip( $button, "Select the UML Kernel.", "" );
|
||
}
|
||
elsif ($order == 14) {
|
||
$tooltips->set_tip( $button, "Select the Root Filesystem.", "" );
|
||
}
|
||
elsif ($order == 16) {
|
||
$tooltips->set_tip( $button, "Select the System.map.", "" );
|
||
}
|
||
|
||
|
||
$button->signal_connect( "clicked",\&fileselect,$ent,$name,$order,$device);
|
||
$button->show();
|
||
|
||
|
||
} # end sub button_fileselect_advanced
|
||
|
||
|
||
sub entry_advanced {
|
||
|
||
my $numa = $_[4];
|
||
my $entry_advanced = Gtk::Entry->new();
|
||
$entry_advanced->set_editable( $true );
|
||
$entry_advanced->signal_connect( "changed", sub {
|
||
$entry_advanced[$numa] = $entry_advanced->get_text();
|
||
if ($numa == 4) {
|
||
$ars->{filename} = $entry_advanced[$numa];
|
||
ars($ars);
|
||
}
|
||
if ( $numa == 12 ) {
|
||
$ars->{kernel_version_choice} = $entry_advanced[$numa];
|
||
ars($ars);
|
||
ars2($ars);
|
||
}
|
||
} );
|
||
$entry_advanced->set_usize(100,20);
|
||
$_[5]->attach($entry_advanced,$_[0],$_[1],$_[2],$_[3],
|
||
['shrink','fill','expand'],['fill','shrink'],0,0);
|
||
show $entry_advanced;
|
||
return $entry_advanced;
|
||
|
||
}
|
||
|
||
sub separator_advanced {
|
||
|
||
$separator_advanced = Gtk::HSeparator->new();
|
||
$_[0]->pack_start( $separator_advanced, $false, $true, 0 );
|
||
$separator_advanced->show();
|
||
|
||
}
|
||
|
||
sub label_advanced {
|
||
|
||
my($text) = @_;
|
||
|
||
$label_advanced = Gtk::Label->new( $text );
|
||
$label_advanced->set_justify( "fill" );
|
||
$_[5]->attach($label_advanced,$_[1],$_[2],$_[3],$_[4], ['expand'],['fill','shrink'],0,0);
|
||
$label_advanced->show();
|
||
|
||
}
|
||
|
||
# I created two of these, one for help (eventually there may be a different
|
||
# approach), and one for verbosity. I am sure there is a better OO way to
|
||
# do it, though.
|
||
sub create_text {
|
||
|
||
if (not defined $text_window) {
|
||
$text_window = Gtk::Window->new("toplevel");
|
||
$text_window->signal_connect("destroy", \&destroy_window,
|
||
\$text_window);
|
||
$text_window->signal_connect("delete_event", \&destroy_window,
|
||
\$text_window);
|
||
$text_window->set_title("Help");
|
||
$text_window->set_usize( 500, 600 );
|
||
$text_window->set_policy( $true, $true, $false );
|
||
$text_window->set_title( "gBootRoot Help" );
|
||
$text_window->border_width(0);
|
||
|
||
my $main_vbox = Gtk::VBox->new( $false, 0 );
|
||
$text_window->add( $main_vbox );
|
||
$main_vbox->show();
|
||
|
||
my $vbox = Gtk::VBox->new( $false, 10 );
|
||
$vbox->border_width( 10 );
|
||
$main_vbox->pack_start( $vbox, $true, $true, 0 );
|
||
$vbox->show();
|
||
|
||
my $table = Gtk::Table->new( 2, 2, $false );
|
||
$table->set_row_spacing( 0, 2 );
|
||
$table->set_col_spacing( 0, 2 );
|
||
$vbox->pack_start( $table, $true, $true, 0 );
|
||
$table->show( );
|
||
|
||
# Create the GtkText widget
|
||
my $text = Gtk::Text->new( undef, undef );
|
||
$text->set_editable($false);
|
||
$table->attach( $text, 0, 1, 0, 1,
|
||
[ 'expand', 'shrink', 'fill' ],
|
||
[ 'expand', 'shrink', 'fill' ],
|
||
0, 0 );
|
||
$text->grab_focus();
|
||
$text->show();
|
||
|
||
# Add a vertical scrollbar to the GtkText widget
|
||
my $vscrollbar = Gtk::VScrollbar->new( $text->vadj );
|
||
$table->attach( $vscrollbar, 1, 2, 0, 1, 'fill',
|
||
[ 'expand', 'shrink', 'fill' ], 0, 0 );
|
||
#my $logadj = $vscrollbar->get_adjustment();
|
||
#logadj($logadj);
|
||
#$vscrollbar->show();
|
||
|
||
$text->freeze();
|
||
$text->insert( undef, undef, undef, help() );
|
||
$text->thaw();
|
||
|
||
my $separator = Gtk::HSeparator->new();
|
||
$main_vbox->pack_start( $separator, $false, $true, 0 );
|
||
$separator->show();
|
||
|
||
$vbox = Gtk::VBox->new( $false, 10 );
|
||
$vbox->border_width( 10 );
|
||
$main_vbox->pack_start( $vbox, $false, $true, 0 );
|
||
$vbox->show();
|
||
|
||
my $button = Gtk::Button->new( "Close" );
|
||
$button->signal_connect( 'clicked', sub { destroy $text_window; } );
|
||
$vbox->pack_start( $button, $true, $true, 0 );
|
||
$button->can_default( $true );
|
||
$button->grab_default();
|
||
$button->show();
|
||
}
|
||
if (!visible $text_window) {
|
||
show $text_window;
|
||
} else {
|
||
destroy $text_window;
|
||
}
|
||
|
||
} # end sub create_text
|
||
|
||
# This monster needs different behavior than create_text.
|
||
sub verbosity_box {
|
||
|
||
|
||
$verbosity_window = Gtk::Window->new("toplevel");
|
||
$verbosity_window->signal_connect("destroy", \&destroy_window,
|
||
\$verbosity_window);
|
||
$verbosity_window->signal_connect("delete_event", \&destroy_window,
|
||
\$verbosity_window);
|
||
$verbosity_window->set_usize( 450, 175 ); # 500 600
|
||
$verbosity_window->set_policy( $true, $true, $false );
|
||
$verbosity_window->set_title( "Verbosity Box" );
|
||
$verbosity_window->border_width(0);
|
||
|
||
my $main_vbox = Gtk::VBox->new( $false, 0 );
|
||
$verbosity_window->add( $main_vbox );
|
||
$main_vbox->show();
|
||
|
||
my $vbox = Gtk::VBox->new( $false, 10 );
|
||
$vbox->border_width( 10 );
|
||
$main_vbox->pack_start( $vbox, $true, $true, 0 );
|
||
$vbox->show();
|
||
|
||
my $table = Gtk::Table->new( 2, 2, $false );
|
||
$table->set_row_spacing( 0, 2 );
|
||
$table->set_col_spacing( 0, 2 );
|
||
$vbox->pack_start( $table, $true, $true, 0 );
|
||
$table->show( );
|
||
|
||
# Create the GtkText widget
|
||
my $text = Gtk::Text->new( undef, undef );
|
||
$text->set_editable($false);
|
||
$table->attach( $text, 0, 1, 0, 1,
|
||
[ 'expand', 'shrink', 'fill' ],
|
||
[ 'expand', 'shrink', 'fill' ],
|
||
0, 0 );
|
||
$text->grab_focus();
|
||
$text->show();
|
||
my $red = Gtk::Gdk::Color->parse_color("red");
|
||
my $blue = Gtk::Gdk::Color->parse_color("blue");
|
||
text_insert($text,$red,$blue); # yard thing
|
||
|
||
# Add a vertical scrollbar to the GtkText widget
|
||
my $vscrollbar = Gtk::VScrollbar->new( $text->vadj );
|
||
$table->attach( $vscrollbar, 1, 2, 0, 1, 'fill',
|
||
[ 'expand', 'shrink', 'fill' ], 0, 0 );
|
||
my $logadj = $vscrollbar->get_adjustment();
|
||
logadj($logadj);
|
||
$vscrollbar->show();
|
||
|
||
my $separator = Gtk::HSeparator->new();
|
||
$main_vbox->pack_start( $separator, $false, $true, 0 );
|
||
$separator->show();
|
||
|
||
$vbox = Gtk::VBox->new( $false, 10 );
|
||
$vbox->border_width( 10 );
|
||
$main_vbox->pack_start( $vbox, $false, $true, 0 );
|
||
$vbox->show();
|
||
|
||
#my $button = Gtk::Button->new( "Close" );
|
||
#$button->signal_connect( 'clicked',
|
||
# sub { destroy $verbosity_window; } );
|
||
#$vbox->pack_start( $button, $true, $true, 0 );
|
||
#$button->can_default( $true );
|
||
#$button->grab_default();
|
||
#$button->show();
|
||
|
||
show $verbosity_window;
|
||
|
||
} # end sub verbosity_box
|
||
|
||
sub fileselect {
|
||
|
||
my ($widget,$ent,$name,$order,$device) = @_;
|
||
|
||
if (not defined $file_dialog) {
|
||
# Create a new file selection widget
|
||
$file_dialog = Gtk::FileSelection->new( "$name" );
|
||
$file_dialog->signal_connect( "destroy",
|
||
\&destroy_window, \$file_dialog);
|
||
$file_dialog->signal_connect( "delete_event",
|
||
\&destroy_window, \$file_dialog);
|
||
|
||
# Connect the ok_button to file_ok_sel function
|
||
$file_dialog->ok_button->signal_connect( "clicked",
|
||
\&file_ok_sel,
|
||
$file_dialog,$ent,$order);
|
||
|
||
# Connect the cancel_button to destroy the widget
|
||
$file_dialog->cancel_button->signal_connect( "clicked",
|
||
sub { destroy $file_dialog } );
|
||
$file_dialog->set_filename( $device ) if defined $device;
|
||
$file_dialog->set_position('mouse');
|
||
|
||
}
|
||
if (!visible $file_dialog) {
|
||
show $file_dialog;
|
||
}
|
||
else {
|
||
destroy $file_dialog;
|
||
}
|
||
|
||
} # end sub fileselect
|
||
|
||
|
||
# Get the selected filename and print it to the text widget
|
||
sub file_ok_sel {
|
||
|
||
my( $widget, $file_selection,$entry,$order) = @_;
|
||
my $file = $file_selection->get_filename();
|
||
if ($order != 14) {
|
||
$entry->set_text($file);
|
||
}
|
||
else {
|
||
$entry->set_text("ubd0=$file");
|
||
}
|
||
$container[$order] = $file;
|
||
if ($order == 1) {
|
||
$ars->{kernel} = $container[$order];
|
||
ars($ars);
|
||
ars2($ars);
|
||
}
|
||
|
||
# auto-detect compression if system has file
|
||
if ($container[ROOT_FS]) {
|
||
my $file = sys("which file > /dev/null 2>&1");
|
||
if ($file == 0) {
|
||
open(F,"file $container[ROOT_FS] |"); # no error check
|
||
# here
|
||
while (<F>) {
|
||
if (/gzip/) {
|
||
$gz_toggle->set_active( $true );
|
||
}
|
||
elsif (/bzip2/) {
|
||
$bz2_toggle->set_active( $true );
|
||
}
|
||
else {
|
||
info(0, "Neither gz or bz2 compression found\n");
|
||
}
|
||
}
|
||
close(F);
|
||
}
|
||
}
|
||
|
||
destroy $file_dialog;
|
||
|
||
}
|
||
|
||
sub hbox {
|
||
my $homogeneous;
|
||
defined $_[0] ? ($homogeneous = 0) : ($homogeneous = 1);
|
||
$box2 = Gtk::HBox->new( $homogeneous, 5 );
|
||
$box2->border_width( 2 ); # was 10
|
||
$box1->pack_start( $box2, $true, $true, 0 );
|
||
#$box1->pack_start( $box2, $false, $true, 0 );
|
||
$box2->show();
|
||
}
|
||
|
||
sub label {
|
||
|
||
my($text) = @_;
|
||
|
||
$label = Gtk::Label->new( $text );
|
||
$label->set_justify( "fill" );
|
||
$box2->pack_start( $label, $false, $false, 5 );
|
||
$label->show();
|
||
|
||
}
|
||
|
||
sub entry {
|
||
|
||
my($edit,$num) = @_;
|
||
|
||
my $entry = Gtk::Entry->new();
|
||
|
||
$entry->set_editable( $false ) if $edit == 0;
|
||
|
||
if ($num == 0) {
|
||
$entry->signal_connect( "activate", sub {
|
||
$container[$num] = $entry->get_text();});
|
||
}
|
||
else {
|
||
$entry->signal_connect( "changed", sub {
|
||
$container[$num] = $entry->get_text();
|
||
if ($num == 1) {
|
||
$ars->{kernel} = $container[$num];
|
||
ars($ars);
|
||
ars2($ars);
|
||
}
|
||
# here's where types in entry3, types other places
|
||
if (defined $ea1 and $num == 3) {
|
||
$ea1->set_text($container[$num]);
|
||
}
|
||
if (defined $ear1 and $num == 3) {
|
||
$ear1->set_text($container[$num]);
|
||
}
|
||
|
||
# auto-detect compression if system has file
|
||
if ($num == 2) {
|
||
my $file = sys("which file");
|
||
if ($file == 0) {
|
||
if ($container[ROOT_FS]) {
|
||
open(F,"file $container[ROOT_FS] |"); # no error check here
|
||
while (<F>) {
|
||
if (/gzip/) {
|
||
$gz_toggle->set_active( $true );
|
||
}
|
||
elsif (/bzip2/) {
|
||
$bz2_toggle->set_active( $true );
|
||
}
|
||
else {
|
||
info(0,
|
||
"Neither gz or bz2 compression found\n");
|
||
}
|
||
}
|
||
close(F);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
}
|
||
if (defined $num and $num != 0) {
|
||
my $todo;
|
||
if ($num == 1) {
|
||
$todo = "the Kernel";
|
||
}
|
||
elsif ($num == 2) {
|
||
$todo = "the Compressed Filesystem";
|
||
}
|
||
else {
|
||
$todo = "the Block Device to use";
|
||
}
|
||
$tooltips->set_tip( $entry,
|
||
"Type in the location of $todo.", "" );
|
||
}
|
||
$box2->pack_start( $entry, $true, $true, 0 );
|
||
$entry->show();
|
||
|
||
return $entry;
|
||
|
||
}
|
||
|
||
sub button {
|
||
|
||
my ($text,$ent,$name,$order,$device) = @_;
|
||
|
||
my $button = Gtk::Button->new($text);
|
||
if ($order == 1) {
|
||
$tooltips->set_tip( $button, "Select the Kernel.", "" );
|
||
}
|
||
elsif ($order == 2) {
|
||
$tooltips->set_tip( $button, "Select the Root Filesystem.", "" );
|
||
}
|
||
else {
|
||
$tooltips->set_tip( $button, "Select the Device.", "" );
|
||
}
|
||
$button->signal_connect( "clicked",\&fileselect,$ent,$name,$order,$device);
|
||
$button->show();
|
||
$box2->pack_start( $button, $true, $true, 0 );
|
||
$box2->show();
|
||
|
||
}
|
||
|
||
sub submit {
|
||
|
||
my($kernel, $root_image, $device, $size);
|
||
|
||
# comment this out for testing
|
||
# Since only one filehandle is now used, this won't work
|
||
# anymore.
|
||
#unlink("$verbosefn");
|
||
open (MTAB, "/etc/mtab") or die "no mtab!\n";
|
||
while (<MTAB>) {
|
||
if (m,$mnt,) {
|
||
sys("umount $mnt");
|
||
}
|
||
}
|
||
close(MTAB);
|
||
$entry5->set_text("");
|
||
pb("boot",0);
|
||
|
||
if ($gz_toggle->active) {
|
||
$compress = "gzip";
|
||
}
|
||
elsif ($bz2_toggle->active) {
|
||
$compress = "bzip2";
|
||
}
|
||
|
||
# Run some checks
|
||
if (!defined $container[METHOD]) {
|
||
error_window("gBootRoot: ERROR: No Method supplied");
|
||
return;
|
||
}
|
||
else {
|
||
if ( $container[METHOD] eq "2 disk compression" ) {
|
||
my $rt = two_disk_compression_check();
|
||
return if $rt;
|
||
}
|
||
}
|
||
|
||
|
||
if (defined $container[KERNEL] && -e $container[KERNEL] &&
|
||
!-d $container[KERNEL]) {
|
||
$kernel = $container[KERNEL];
|
||
# Better be sure it isn't in the mount directory
|
||
if ($kernel =~ m,^$mnt,) {
|
||
error_window("gBootRoot: ERROR: Kernel found below Device mount point: $mnt");
|
||
return;
|
||
}
|
||
|
||
}
|
||
elsif (defined $container[METHOD]) {
|
||
error_window("gBootRoot: ERROR: Kernel not found");
|
||
return;
|
||
}
|
||
if (defined $container[ROOT_FS] && -e $container[ROOT_FS] &&
|
||
!-d $container[ROOT_FS] ) {
|
||
$root_image = $container[ROOT_FS];
|
||
if ($root_image =~ m,^$mnt,) {
|
||
# Bug revealed by Cristian Ionescu-Idbohrn <cii@axis.com>
|
||
error_window(
|
||
"gBootRoot: ERROR: Rootimage found below Device mount point: $mnt");
|
||
return;
|
||
}
|
||
}
|
||
elsif (defined $container[METHOD] && defined $container[KERNEL]) {
|
||
error_window("gBootRoot: ERROR: Root Filesystem not found");
|
||
return;
|
||
}
|
||
# we need to check for this, too.
|
||
if (defined $container[BOOT_DEVICE] && -b $container[BOOT_DEVICE]) {
|
||
$device = $container[BOOT_DEVICE];
|
||
}
|
||
elsif (defined $container[METHOD] && defined $container[KERNEL]
|
||
&& defined $container[ROOT_FS]) {
|
||
error_window("gBootRoot: ERROR: Not a valid Block Device");
|
||
return;
|
||
}
|
||
if (defined $container[SIZE]) {
|
||
$size = $container[SIZE];
|
||
}
|
||
|
||
# pretty unlikely
|
||
elsif (defined $container[METHOD] && defined $container[KERNEL] &&
|
||
defined $container[ROOT_FS] && defined $container[BOOT_DEVICE]) {
|
||
error_window("gBootRoot: ERROR: No size specified");
|
||
return;
|
||
}
|
||
|
||
# kernel value can change without effecting initrd
|
||
# no sense doing this until important stuff is filled in
|
||
if (defined $kernel && defined $root_image &&
|
||
defined $device && defined $size) {
|
||
$container[COMPRESS] = $compress;
|
||
|
||
# 1 .. 4 - its a hash .. not too simple
|
||
!defined $lib_strip_check ? ($container[LIB_STRIP] = 1)
|
||
: ($container[LIB_STRIP] = $lib_strip_check->get_active());
|
||
!$container[LIB_STRIP] ? ($container[LIB_STRIP] = 2)
|
||
: ($container[LIB_STRIP] = 1);
|
||
|
||
!defined $bin_strip_check ? ($container[BIN_STRIP] = 3)
|
||
: ($container[BIN_STRIP] =
|
||
$bin_strip_check->get_active());
|
||
!$container[BIN_STRIP] ? ($container[BIN_STRIP] = 4)
|
||
: ($container[BIN_STRIP] = 3);
|
||
|
||
!defined $mod_strip_check ? ($container[MOD_STRIP] = 7)
|
||
: ($container[MOD_STRIP] =
|
||
$mod_strip_check->get_active());
|
||
!$container[MOD_STRIP] ? ($container[MOD_STRIP] = 8)
|
||
: ($container[MOD_STRIP] = 7);
|
||
|
||
|
||
if ($container[LIB_STRIP] == 1) {
|
||
$obj_count == 0 ? ($container[OBJCOPY_BOOL] = 5)
|
||
: ($container[OBJCOPY_BOOL] = 6);
|
||
}
|
||
|
||
|
||
if (!defined $entry_advanced[0]) {
|
||
$container[ABS_DEVICE] = $device . "ea1";
|
||
$entry_advanced[0] = $device;
|
||
}
|
||
else {
|
||
$container[ABS_DEVICE] = $entry_advanced[0] . "ea1";
|
||
}
|
||
|
||
# If ARS was never opened, root device defaults to boot device.
|
||
# This keeps the logic in the right place.
|
||
$entry_advanced[3] = $container[BOOT_DEVICE] if !$entry_advanced[3];
|
||
|
||
|
||
# Works now .. whoosh!
|
||
if ($container[ABS_OPT_DEVICE]) {
|
||
if ($container[ABS_OPT_DEVICE] ne "") {
|
||
$container[ABS_OPT_DEVICE] = $entry_advanced[1]
|
||
if $entry_advanced[1];
|
||
}
|
||
if (defined $entry_advanced[1] and $entry_advanced[1] eq "") {
|
||
$container[ABS_OPT_DEVICE] = "";
|
||
}
|
||
elsif ($container[ABS_OPT_DEVICE] eq "") {
|
||
push(@original_container,$entry_advanced[1]);
|
||
}
|
||
}
|
||
else {
|
||
push(@original_container,$entry_advanced[1])
|
||
if $entry_advanced[1];
|
||
}
|
||
|
||
# pretty complex and works properly even for !-e lilo.conf
|
||
if ($container[ABS_APPEND]) {
|
||
if ($container[ABS_APPEND] ne "") {
|
||
$container[ABS_APPEND] = $entry_advanced[2]
|
||
if $entry_advanced[2];
|
||
}
|
||
if (defined $entry_advanced[2] and $entry_advanced[2] eq "") {
|
||
$container[ABS_APPEND] = "";
|
||
}
|
||
elsif ($container[ABS_APPEND] eq "") {
|
||
push(@original_container,$entry_advanced[2]);
|
||
}
|
||
}
|
||
else {
|
||
push(@original_container,$entry_advanced[2])
|
||
if $entry_advanced[2];
|
||
}
|
||
|
||
if (@original_container) { # defined array deprecate Perl 5.6 - zas@metaconcept.com
|
||
# a hash check isn't perfect for two values which are the same
|
||
# no need to check all the values
|
||
|
||
my @temp_container = @container;
|
||
|
||
# Got it! - how to deal with fields with no init value
|
||
if (defined $container[ABS_OPT_DEVICE] and
|
||
$container[ABS_OPT_DEVICE] eq "") {
|
||
$container[ABS_OPT_DEVICE] = $entry_advanced[1];
|
||
}
|
||
if (!defined $container[ABS_OPT_DEVICE]) {
|
||
$container[ABS_OPT_DEVICE] = $entry_advanced[1];
|
||
}
|
||
if (defined $container[ABS_APPEND] and
|
||
$container[ABS_APPEND] eq "") {
|
||
$container[ABS_APPEND] = $entry_advanced[2];
|
||
}
|
||
if (!defined $container[ABS_APPEND]) {
|
||
$container[ABS_APPEND] = $entry_advanced[2];
|
||
}
|
||
|
||
# no sense looking at undef values
|
||
my (@temp_container2,@original_container2);
|
||
for (@temp_container) {
|
||
if ($_) {
|
||
push(@temp_container2,$_);
|
||
}
|
||
}
|
||
for (@original_container) {
|
||
if ($_) {
|
||
push(@original_container2,$_);
|
||
}
|
||
}
|
||
|
||
@temp_container = @temp_container2;
|
||
@original_container = @original_container2;
|
||
|
||
splice(@temp_container,1,1);
|
||
|
||
# A test which I've had to run too often
|
||
#print "BEFORE @temp_container\nAFTER @original_container\n";
|
||
|
||
my %diff;
|
||
grep($diff{$_}++,@temp_container);
|
||
my @diff = grep(!$diff{$_},@original_container);
|
||
|
||
if ($#diff >= 0) {
|
||
# unlink initrd_image.gz, do initrd_size()
|
||
$ok = 1;
|
||
$initrd = "initrd_image";
|
||
}
|
||
else {
|
||
$ok = 0;
|
||
}
|
||
}
|
||
else {
|
||
$ok = 2; # this is actually first (1 = diff, 0 = same)
|
||
$initrd = "initrd_image";
|
||
}
|
||
|
||
# reset
|
||
@original_container = ( $container[METHOD],
|
||
$root_image,
|
||
$device,
|
||
$size,
|
||
$compress,
|
||
$container[LIB_STRIP],
|
||
$container[BIN_STRIP],
|
||
$container[MOD_STRIP],
|
||
$container[OBJCOPY_BOOL],
|
||
$container[ABS_DEVICE],
|
||
$container[ABS_OPT_DEVICE],
|
||
$container[ABS_APPEND]
|
||
);
|
||
|
||
kernel_modules();
|
||
lilo(); # This is the default now, and the value for
|
||
# METHOD doesn't matter now.
|
||
}
|
||
|
||
} # end sub submit
|
||
|
||
sub lilo {
|
||
|
||
# Do a little cleanup just in case
|
||
sys("rm $tmp/initrd_image.gz") if $ok == 1;
|
||
sys("umount $tmp/initrd_mnt");
|
||
|
||
my $kernel = $container[KERNEL];
|
||
my $root_fs = $container[ROOT_FS];
|
||
my $device = $container[BOOT_DEVICE];
|
||
my $size = $container[SIZE];
|
||
|
||
if ($ok == 1 || $ok == 2) {
|
||
my $value = initrd($kernel,$root_fs,$device,$size);
|
||
mtab(0) if defined $value;
|
||
}
|
||
elsif ($ok == 0) {
|
||
mtab(0);
|
||
}
|
||
|
||
} # end sub lilo
|
||
|
||
sub lilo_put_it_together {
|
||
|
||
my $B = "boot";
|
||
my $fs_type = (split(/\s/,$main::makefs))[0];
|
||
|
||
# Time to do a little calculations
|
||
my $device_size;
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
$device_size = (split(/\s+/,`df $mnt`))[8];
|
||
}
|
||
else {
|
||
$device_size = $container[SIZE];
|
||
}
|
||
my $boot_size = (stat($container[KERNEL]))[12]/2 +
|
||
(stat("$tmp/$initrd"))[12]/2;
|
||
my $remain_boot = $device_size - $boot_size;
|
||
pb($B,1);
|
||
|
||
# A little output
|
||
if ($remain_boot =~ /^-+\d+$/) {
|
||
error_window("gBootRoot: ERROR: Not enough room: boot stuff = $boot_size k, device = $device_size k");
|
||
return;
|
||
}
|
||
else {
|
||
$entry5->set_text("$remain_boot k");
|
||
}
|
||
|
||
|
||
# If genext2fs is being used clean $tmp/bootdisk if any garbage is found,
|
||
# and temporarily rename $mnt to that directory.
|
||
#my $old_mount;
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
if (-d "$tmp/bootdisk") {
|
||
sys("rm -rf $tmp/bootdisk");
|
||
}
|
||
if (!-d "$tmp/bootdisk") {
|
||
return if errmk(sys("mkdir $tmp/bootdisk")) == 2;
|
||
}
|
||
$old_mount = $mnt;
|
||
$mnt = "$tmp/bootdisk/";
|
||
}
|
||
|
||
# Here everything is copied over either to the device or the the $mnt
|
||
# directory if genext2fs is used.
|
||
info(0, "Copy over initrd ramdisk\n");
|
||
info(0, "Copy over initrd ramdisk .. $tmp/$initrd $mnt/$initrd\n");
|
||
return if err_custom("cp $tmp/$initrd $mnt/$initrd",
|
||
"gBootRoot: ERROR: Could not copy over initrd") == 2;
|
||
pb($B,2);
|
||
|
||
info(0, "Copying over kernel\n");
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
return if
|
||
err_custom("rm -rf $mnt/lost+found; cp $container[KERNEL] $mnt/kernel", "gBootRoot: ERROR: Could not copy over the kernel") == 2;
|
||
}
|
||
else {
|
||
return if
|
||
err_custom("cp $container[KERNEL] $mnt/kernel", "gBootRoot: ERROR: Could not copy over the kernel") == 2;
|
||
}
|
||
pb($B,3);
|
||
|
||
info(0, "Making stuff for lilo\n");
|
||
# will be 0 if mkdir fails, but 0 if cp succeeds ?
|
||
return if err(sys("mkdir $mnt/{boot,dev}")) == 2;
|
||
|
||
# DEVICES SECTION
|
||
my @devices;
|
||
my $device_table = "$tmp/boot_device_table.txt";
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
|
||
info(0, "Making $device_table for genext2fs\n");
|
||
my $error;
|
||
unlink( $device_table ) if -e $device_table;
|
||
|
||
#<path> <type> <mode> <uid> <gid> <major> <minor> <start><inc><count>
|
||
# /dev is always needs to be made automatically
|
||
open(BootRoot::Yard::DEVICE_TABLE, ">$device_table") or
|
||
($error = error("$device_table: $!"));
|
||
return "ERROR"if $error && $error eq "ERROR";
|
||
|
||
print BootRoot::Yard::DEVICE_TABLE
|
||
"# <path>\t<type>\t<mode>\t<uid>\t<gid>\t<major>\t<minor>" .
|
||
"\t<start>\t<inc>\t<count>\n";
|
||
print BootRoot::Yard::DEVICE_TABLE "/dev\t\td\t0755\t-\t-\t-\t-\t-\t-\t-\n";
|
||
|
||
# Keep a record of the devices required
|
||
@devices = qw(/dev/null /dev/fd0 /dev/fd1 /dev/hda1);
|
||
for ( split(" ", $container[BOOT_DEVICE] ) ) {
|
||
my @existing_device_test = grep ( /$_/, @devices );
|
||
if ( !@existing_device_test ) {
|
||
push(@devices, $_ ) if $_;
|
||
}
|
||
}
|
||
|
||
# This adds that next device if found in lilo.conf
|
||
($norm_root_device) = gdkbirdaao();
|
||
if ( $norm_root_device ) {
|
||
my @existing_device_test =
|
||
grep ( /\/dev\/$norm_root_device/, @devices );
|
||
if ( !@existing_device_test ) {
|
||
push( @devices, "/dev/$norm_root_device" );
|
||
}
|
||
}
|
||
|
||
# For frame buffer devices and the like.
|
||
if ( $entry_advanced[1] ) {
|
||
for ( split(" ", $entry_advanced[1] ) ) {
|
||
my @existing_device_test = grep ( /$_/, @devices );
|
||
if ( !@existing_device_test ) {
|
||
push(@devices, $_ ) if $_;
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
device_table( @devices );
|
||
close(BootRoot::Yard::DEVICE_TABLE);
|
||
|
||
}
|
||
else {
|
||
|
||
info(0, "Copying over devices to $mnt/dev\n");
|
||
|
||
return if err(sys("cp -a /dev/{null,fd?,hda1} $mnt/dev")) == 2;
|
||
|
||
# Hopefully, this works, but have never tested it -- o.k I did
|
||
if ($container[BOOT_DEVICE] !~ m,/dev/fd\d{1}$,) {
|
||
return if err(sys("cp -a $container[BOOT_DEVICE] $mnt/dev")) == 2;
|
||
}
|
||
|
||
# This adds that next device if found in lilo.conf
|
||
($norm_root_device) = gdkbirdaao();
|
||
if (!-e "$mnt/dev/$norm_root_device") {
|
||
return if err(sys("cp -a /dev/$norm_root_device $mnt/dev")) == 2;
|
||
}
|
||
|
||
# For frame buffer devices and the like.
|
||
if ($entry_advanced[1]) {
|
||
return if errcp(sys("cp -a $entry_advanced[1] $mnt/dev")) == 2;
|
||
}
|
||
|
||
|
||
} # end DEVICES SECTION
|
||
|
||
info(0, "Copy over important lilo stuff\n");
|
||
return if
|
||
err_custom("cp /boot/boot.b $mnt/boot",
|
||
"gBootRoot: ERROR: Not enough space or can't find /boot/boot.b") == 2;
|
||
pb($B,4);
|
||
# 3k sort of accounts for dev & dirs assuming dev is reasonable
|
||
$remain_boot = $remain_boot - (stat("/boot/boot.b"))[12]/2 - 3;
|
||
$entry5->set_text("$remain_boot k");
|
||
|
||
# Write out the HEREDOCS
|
||
open(LC, ">$mnt/brlilo.conf") or die "Couldn't write $mnt/brlilo.conf\n";
|
||
if ( $> == 0 ) {
|
||
print LC brlilo($container[BOOT_DEVICE]); close(LC);
|
||
}
|
||
else {
|
||
print LC brlilo_non_root($container[BOOT_DEVICE]); close(LC);
|
||
}
|
||
|
||
open(M, ">$mnt/message") or die "Couldn't write $mnt/message\n";
|
||
print M message(); close(M);
|
||
pb($B,5);
|
||
$remain_boot = $remain_boot - ( (stat("$mnt/brlilo.conf"))[12]/2 +
|
||
(stat("$mnt/message"))[12]/2 );
|
||
$entry5->set_text("$remain_boot k");
|
||
|
||
# Got to umount,mount, and umount again to make sure everything is
|
||
# copied over before doing lilo unless genext2fs in being used.
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
return if errum(sys("umount $mnt")) == 2;
|
||
info(0, "Umount device\n");
|
||
info(0, "Remount device\n");
|
||
}
|
||
pb($B,6);
|
||
|
||
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
|
||
my $error;
|
||
|
||
# When creating a fs on floppy, specifying -i causes genext2fs to fail,
|
||
# its better to just let the program figure out the inode size for now.
|
||
if (
|
||
sys("/usr/lib/bootroot/$main::makefs -b $device_size -d $mnt -D $device_table $entry_advanced[0]") !~
|
||
/^0$/ ) {
|
||
$error = error("Cannot $fs_type filesystem.\n");
|
||
return "ERROR" if $error && $error eq "ERROR";
|
||
}
|
||
|
||
}
|
||
|
||
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
$mnt = $old_mount;
|
||
}
|
||
|
||
# Real device
|
||
if ( $> == 0 ) {
|
||
return if errm(sys("mount -t ext2 $entry_advanced[0] $mnt")) == 2;
|
||
}
|
||
else {
|
||
my $errm_value = errm(sys("mount $mnt"));
|
||
if ( $errm_value == 2 && $fs_type eq "genext2fs" ) {
|
||
info(0, "Ask your administrator to add this line to the" .
|
||
" fstab file:\n");
|
||
info(0, "\n$entry_advanced[0]\t$mnt\tauto\tdefaults,noauto," .
|
||
"user\t0\t0\n\n");
|
||
}
|
||
else {
|
||
return if $errm_value == 2;
|
||
}
|
||
}
|
||
|
||
|
||
info(0, "Configuring lilo\n");
|
||
pb($B,7);
|
||
chdir("$mnt"); #"boot_root: ERROR: Could not change directories\n";
|
||
|
||
# This enforces that lilo is only wil run on a bootable drive,
|
||
# otherwise the user has to do it manually.
|
||
if ($container[BOOT_DEVICE] eq $entry_advanced[0]) {
|
||
|
||
# root can happily chroot
|
||
if ( $> == 0 ) {
|
||
|
||
if ( err_custom("lilo -v -C brlilo.conf -r $mnt",
|
||
"gBootRoot: ERROR: lilo failed") == 2 ) {
|
||
chdir($pwd);
|
||
return;
|
||
}
|
||
|
||
}
|
||
|
||
# At this point the normal user needs to be asked first if they have
|
||
# root lilo power, before going on.
|
||
else {
|
||
|
||
# Ask the user if they have su lilo priviliges.
|
||
# Hopefully, password free, but that can be incorporated.
|
||
mtab(3);
|
||
do {
|
||
if ( $mtab == 2 ) {
|
||
undef $mtab;
|
||
chdir($pwd);
|
||
return if errum(sys("umount $mnt")) == 2;
|
||
return;
|
||
}
|
||
while (Gtk->events_pending) { Gtk->main_iteration; }
|
||
} while $mtab;
|
||
|
||
# It's o.k. if lilo fails.
|
||
if ( err_custom("$main::sudo lilo -v -C $mnt/brlilo.conf -b $entry_advanced[0]", "gBootRoot: ERROR: lilo failed") == 2 ) {
|
||
chdir($pwd);
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
$remain_boot = $remain_boot - (stat("$mnt/boot/map"))[12]/2;
|
||
$entry5->set_text("$remain_boot k");
|
||
pb($B,8);
|
||
|
||
chdir($pwd); # or die "boot_root: ERROR: Could not change directories\n";
|
||
|
||
info(0, "Umounting $mnt\n");
|
||
my $um = errum(sys("umount $mnt"));
|
||
pb($B,10);
|
||
|
||
if ($ok == 1 || $ok == 2) {
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
return if
|
||
errrm(sys("rmdir $tmp/initrd_mnt")) == 2;
|
||
}
|
||
}
|
||
|
||
# Here's where we copy over that compressed filesystem
|
||
# We could separate $container[BOOT_DEVICE] = boot,root allowing two
|
||
# different devices to be used. -- now there is $entry_advanced[3] which
|
||
# is the ROOT_DEVICE
|
||
if ($um == 0 ) {
|
||
mtab(1);
|
||
}
|
||
else {
|
||
error_window("gBootRoot: ERROR: Boot disk was never umounted");
|
||
} # copy over the compressed
|
||
|
||
} # end sub lilo_put_it_together
|
||
|
||
sub device2 {
|
||
|
||
my $fs_type = (split(/\s/,$main::makefs))[0];
|
||
|
||
# Time to do a little calculations
|
||
my $device_size;
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
$device_size = (split(/\s+/,`df $mnt`))[8];
|
||
}
|
||
else {
|
||
if ( !$root_device_size ) {
|
||
$device_size = $container[SIZE];
|
||
}
|
||
else {
|
||
$device_size = $root_device_size;
|
||
}
|
||
}
|
||
|
||
my $root_image_size = (stat($container[ROOT_FS]))[12]/2;
|
||
my $remain_root = $device_size - $root_image_size;
|
||
|
||
if ($remain_root =~ /^-+\d+$/) {
|
||
error_window("gBootRoot: ERROR: Not enough room: root stuff = $root_image_size k, device = $device_size k");
|
||
}
|
||
else {
|
||
$entry5->set_text("$remain_root k");
|
||
}
|
||
|
||
info(0, "Copy over the compressed filesystem\n");
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
return if errrm(sys("rmdir $mnt/lost+found")) == 2;
|
||
}
|
||
my $broot_image = basename($container[ROOT_FS]);
|
||
|
||
# Status output, use FH, or genext2fs to create disk.
|
||
#----------------------------------------------------
|
||
my $FS = "filesystem";
|
||
my $line_count = `wc -l < $container[ROOT_FS]`; chomp $line_count;
|
||
my $half_line_count = $line_count/2;
|
||
my $count = 1;
|
||
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
open(CF, ">$mnt/$broot_image") or error_window(
|
||
"gBootRoot: ERROR: Could not copy over the root filesystem") and return;
|
||
|
||
open(CR, "$container[ROOT_FS]") or error_window(
|
||
"gBootRoot: ERROR: Could not copy over the root filesystem") and return;
|
||
|
||
while (<CR>) {
|
||
print CF $_;
|
||
pb($FS,$count,$line_count) if $count < $half_line_count;
|
||
$count++;
|
||
}
|
||
close(CF);
|
||
close(CR);
|
||
}
|
||
|
||
# genext2fs
|
||
else {
|
||
|
||
my $error;
|
||
|
||
# If genext2fs is being used clean $tmp/rootdisk if any garbage is
|
||
# found.
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
if (-d "$tmp/rootdisk") {
|
||
sys("rm -rf $tmp/rootdisk");
|
||
}
|
||
if (!-d "$tmp/rootdisk") {
|
||
return if errmk(sys("mkdir $tmp/rootdisk")) == 2;
|
||
}
|
||
}
|
||
|
||
return if errcp( sys("cp -a $container[ROOT_FS] $tmp/rootdisk") ) == 2;
|
||
|
||
for ( $count .. $half_line_count ) {
|
||
pb($FS,$count,$line_count) if $count < $half_line_count;
|
||
$count++;
|
||
}
|
||
|
||
|
||
if (
|
||
sys("/usr/lib/bootroot/$main::makefs -b $device_size -d $mnt $entry_advanced[3]") !~
|
||
/^0$/ ) {
|
||
info( 0, "/usr/lib/bootroot/$main::makefs -b $device_size -d $tmp/rootdisk $entry_advanced[3]\n");
|
||
$error = error("Cannot $fs_type filesystem.\n");
|
||
return "ERROR" if $error && $error eq "ERROR";
|
||
}
|
||
|
||
|
||
}
|
||
#------------------------------------------------------
|
||
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
return if
|
||
err_custom("umount $mnt",
|
||
"gBootRoot: ERROR: Root disk did not properly umount") == 2;
|
||
}
|
||
|
||
pb($FS,$count,$line_count);
|
||
info(0, "Finished!\n");
|
||
|
||
} # end sub device 2
|
||
|
||
# Checks if lib or bin is stripped, if not proceeds to strip. Returns
|
||
# full file path and strip result. Right now this is specific to initrd.
|
||
sub stripper {
|
||
|
||
# stripper (program,bin|lib|mod);
|
||
if ((!defined $lib_strip_check && !defined $bin_strip_check
|
||
&& !defined $mod_strip_check) or
|
||
($lib_strip_check->active || $bin_strip_check->active
|
||
|| $mod_strip_check->active)) {
|
||
|
||
# DON'T DO THIS >/dev/null 2>&1`;
|
||
my $not_stripped = `file $_[0] 2> /dev/null`;
|
||
my $filename = basename($_[0]);
|
||
|
||
if ($not_stripped =~ m,not stripped,) {
|
||
if (($_[1] eq "lib" && !defined $lib_strip_check) or
|
||
($_[1] eq "lib" && $lib_strip_check->active)) {
|
||
# --strip-all works for initrd
|
||
if ($obj_count == 0) {
|
||
sys("objcopy --strip-debug -p $_[0] $tmp/$filename");
|
||
info(1,"--strip-debug $filename\n");
|
||
return ( "$tmp/$filename", 1 );
|
||
}
|
||
elsif ($obj_count == 1) {
|
||
sys("objcopy --strip-all -p $_[0] $tmp/$filename");
|
||
info(1,"--strip-all $filename\n");
|
||
return ( "$tmp/$filename", 1 );
|
||
}
|
||
}
|
||
elsif (($_[1] eq "bin" && !defined $bin_strip_check) or
|
||
($_[1] eq "bin" && $bin_strip_check->active)) {
|
||
sys("objcopy --strip-all -p $_[0] $tmp/$filename");
|
||
info(1,"--strip-all $filename\n");
|
||
return ( "$tmp/$filename", 1 );
|
||
}
|
||
elsif (($_[1] eq "mod" && !defined $mod_strip_check) or
|
||
($_[1] eq "mod" && $mod_strip_check->active)) {
|
||
sys("objcopy --strip-debug -p $_[0] $tmp/$filename");
|
||
info(1,"--strip-debug $filename\n");
|
||
return ( "$tmp/$filename", 1 );
|
||
}
|
||
}
|
||
else {
|
||
return ( $_[0], 0 );
|
||
}
|
||
}
|
||
return ( $_[0], 0);
|
||
|
||
} # end sub stripper
|
||
|
||
sub two_disk_compression_check {
|
||
|
||
my ($ash,$lilo,$bzip2,$file);
|
||
|
||
if ( !find_file_in_path("ash") ) {
|
||
$ash = "ash";
|
||
}
|
||
|
||
if ( !find_file_in_path("lilo") ) {
|
||
$lilo = "lilo";
|
||
}
|
||
|
||
if ( !find_file_in_path("bzip2") ) {
|
||
$bzip2 = "bzip2";
|
||
}
|
||
|
||
if ( !find_file_in_path("file") ) {
|
||
$file = "file";
|
||
}
|
||
|
||
if ( $ash ||
|
||
|
||
$lilo ||
|
||
|
||
$bzip2 ||
|
||
|
||
$ash
|
||
|
||
) {
|
||
|
||
error_window(
|
||
"Program(s) required by this method: $lilo $ash $bzip2 $file"
|
||
);
|
||
|
||
return 1;
|
||
}
|
||
|
||
|
||
} # end sub two_disk_compression_check
|
||
|
||
sub kernel_modules {
|
||
|
||
my (@modules, @modules_found);
|
||
|
||
my $module_choices = $ea3->get_text() if $ea3;
|
||
my $kernel_version_choice = $ea5->get_text() if $ea5;
|
||
undef $kernel_version_choice if defined $kernel_version_choice eq "";
|
||
undef $kernel_version_choice if !$kernel_version_choice;
|
||
|
||
$kernel_version = kernel_version_check($container[KERNEL],
|
||
$kernel_version_choice);
|
||
#-----------------------------
|
||
# METHOD -> 2 DISK COMPRESSION
|
||
#-----------------------------
|
||
if ( $container[METHOD] eq "2 disk compression" ) {
|
||
|
||
$entry_advanced[11] = "floppy";
|
||
|
||
if ($ea3) {
|
||
if ($module_choices eq "") {
|
||
$ea3->set_text("floppy");
|
||
$module_choices = "floppy";
|
||
}
|
||
else {
|
||
$ea3->set_text($ea3->get_text() . " floppy")
|
||
if $ea3->get_text() !~ /\s*floppy\s*/;
|
||
$module_choices = $ea3->get_text();
|
||
}
|
||
}
|
||
else {
|
||
$module_choices = "floppy";
|
||
}
|
||
|
||
@modules = split(/\s+/, $module_choices);
|
||
|
||
}
|
||
|
||
info(1, "Modules: @modules\n");
|
||
|
||
|
||
# Figure out modules path.
|
||
if ( @modules ) {
|
||
foreach my $module (@modules) {
|
||
finddepth sub { if ( $File::Find::name =~ m,/$module\.o$, ) {
|
||
push(@modules_found,$File::Find::name);
|
||
} },
|
||
"$modules_directory/$kernel_version";
|
||
|
||
}
|
||
}
|
||
|
||
$, = " ";
|
||
info(1,"Modules found:\n@modules_found\n");
|
||
$, = "";
|
||
|
||
return @modules_found;
|
||
|
||
|
||
} # end sub kernel_modules
|
||
|
||
|
||
sub initrd_size {
|
||
|
||
info(0,"Boot Method: 2 disk\n",
|
||
"Type: initrd boot disk with LILO/root filesystem disk\n");
|
||
|
||
my ($linuxrc_size) = @_;
|
||
my ($what,$lib);
|
||
my ($path,$value);
|
||
info(0, "Checking size needed for initrd\n");
|
||
|
||
# the size of the loop device should be at least 1.63% larger than what
|
||
# it will contain (i.e. 8192 inode), but to keep on the safe size it will
|
||
# be 2.00% larger.
|
||
|
||
# Unforturnately, stat is being done on
|
||
# the actual live fs, whereas the loop filesystem may be different. In
|
||
# general the check is quite conservative and will always leave room.
|
||
# Stat seems to view things differently based on the situation, and
|
||
# -s file has another opinion, for now stat will be used and perhaps
|
||
# the actual filesystem in the future. Better extra room than too little.
|
||
|
||
# 9 dirs = 1024 each (increase if modified)
|
||
# {ash,gzip,mount,umount} (required executables)
|
||
# bzip2 if $compress eq bzip2 (optional)
|
||
# 1 for ld.so.cache
|
||
|
||
# change dir size if needed
|
||
my $dir_size = 9 + 1;
|
||
my $initrd_size = $dir_size + $linuxrc_size;
|
||
|
||
# clean initrd_mnt if any garbage is found.
|
||
if (-d "$tmp/initrd_mnt") {
|
||
sys("rm -rf $tmp/initrd_mnt");
|
||
}
|
||
if (!-d "$tmp/initrd_mnt") {
|
||
return if errmk(sys("mkdir $tmp/initrd_mnt")) == 2;
|
||
}
|
||
|
||
# modules - see CVS:1.65 for previous non-size check.
|
||
my @modules = kernel_modules();
|
||
if (@modules) {
|
||
|
||
my $tool;
|
||
|
||
# dirs sizes, just assuming 1024
|
||
my $ds = mkpath("$tmp/initrd_mnt/lib/modules/$kernel_version");
|
||
$initrd_size = $initrd_size + ($ds - 1);
|
||
|
||
# copy over the modules
|
||
foreach my $stuff (@modules) {
|
||
($path,$value) = stripper($stuff,"mod");
|
||
|
||
$value == 0 ? ($tool = "cp -a") : ($tool = "mv");
|
||
if (!$path) {
|
||
info(1,"gBootRoot Error: Couldn't find $stuff\n");
|
||
}
|
||
|
||
# copy stuff to proper directory and unlink size tester
|
||
return if
|
||
errcp(sys("$tool $path $tmp/initrd_mnt/lib/modules/$kernel_version")) == 2;
|
||
unlink($path) if $value == 1;
|
||
}
|
||
|
||
# Do the depmod operation
|
||
|
||
if ($entry_advanced[13] && $entry_advanced[13] ne "") {
|
||
|
||
if ( $> == 0 ) {
|
||
|
||
return if err_custom("depmod -ae -F $entry_advanced[13] -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
}
|
||
else {
|
||
|
||
return if err_custom("depmod -aer -F $entry_advanced[13] -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
|
||
}
|
||
|
||
} # $entry_advanced[13] defined
|
||
|
||
else {
|
||
|
||
if ( $> == 0 ) {
|
||
|
||
return if err_custom("depmod -ae -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
}
|
||
else {
|
||
|
||
return if err_custom("depmod -aer -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
# Check all the files in the dirctory for their size, and unlink them.
|
||
opendir(DIR,"$tmp/initrd_mnt/lib/modules/$kernel_version")
|
||
or info(1,"Failed to open $tmp/initrd_mnt/$kernel_version");
|
||
my @module_stuff = grep { /\w+/ } readdir(DIR);
|
||
close(DIR);
|
||
|
||
# Figure out the size for all the stuff created by depmod and the
|
||
# modules included.
|
||
foreach my $stuff (@module_stuff) {
|
||
$initrd_size = $initrd_size +
|
||
((stat("$tmp/initrd_mnt/lib/modules/$kernel_version/$stuff"))[12]/2);
|
||
unlink("$tmp/initrd_mnt/lib/modules/$kernel_version/$stuff");
|
||
}
|
||
|
||
|
||
# The modules directory has to be removed here.
|
||
return if
|
||
errrm(sys("rmdir $tmp/initrd_mnt/lib/modules/$kernel_version")) == 2;
|
||
return if
|
||
errrm(sys("rmdir $tmp/initrd_mnt/lib/modules")) == 2;
|
||
return if
|
||
errrm(sys("rmdir $tmp/initrd_mnt/lib/")) == 2;
|
||
|
||
|
||
} # end if (@modules)
|
||
|
||
|
||
# This and libs should be user accessible
|
||
# add other executables here
|
||
my @initrd_stuff;
|
||
if (@modules) {
|
||
@initrd_stuff = qw(ash gzip mount umount modprobe insmod);
|
||
}
|
||
else {
|
||
@initrd_stuff = qw(ash gzip mount umount);
|
||
}
|
||
|
||
foreach (@initrd_stuff) {
|
||
if ( !readlink($_) ) {
|
||
($path,$value) = stripper(find_file_in_path($_),"bin");
|
||
$initrd_size = $initrd_size + ((stat($path))[12]/2);
|
||
unlink($path) if $value == 1;
|
||
}
|
||
else {
|
||
$initrd_size = $initrd_size +
|
||
length(readlink(find_file_in_path($_)));
|
||
}
|
||
}
|
||
|
||
if ($compress eq "bzip2" && -e find_file_in_path($compress)) {
|
||
($path,$value) = stripper(find_file_in_path($compress),"bin");
|
||
$initrd_size = $initrd_size + ((stat($path))[12]/2);
|
||
unlink($path) if $value == 1;
|
||
}
|
||
|
||
my $lib_tester;
|
||
if ($bz2_toggle->active && -x find_file_in_path("bzip2") ) {
|
||
|
||
$lib_tester = find_file_in_path("bzip2");
|
||
|
||
}
|
||
else {
|
||
|
||
$lib_tester = find_file_in_path("init");
|
||
|
||
}
|
||
|
||
my $dir;
|
||
|
||
# lib sizes This is going to be improved later with library_dependencies
|
||
open(L,"ldd $lib_tester|") or die "Oops, no init could be found :)\n"; # safe to use ldd
|
||
while (<L>) {
|
||
my $place;
|
||
($lib,$place) = (split(/=>/,$_))[0,1];
|
||
$place = (split(" ",$place))[0];
|
||
$lib =~ s/\s+//;
|
||
$lib = basename($lib);
|
||
$lib =~ s/\s+$//;
|
||
$dir = dirname($place);
|
||
|
||
open (SL,"ls -l $dir/$lib|") or die "humm: $!\n";
|
||
while (<SL>) {
|
||
# symbolic link
|
||
if (-l "$dir/$lib") {
|
||
$what = (split(/\s+/,$_))[10];
|
||
$initrd_size = $initrd_size + 1;
|
||
($path,$value) = stripper("$dir/$lib","lib");
|
||
$initrd_size = $initrd_size + ((stat($path))[12]/2);
|
||
unlink($path) if $value == 1;
|
||
}
|
||
# no symbolic link
|
||
else {
|
||
($path,$value) = stripper("$dir/$lib","lib");
|
||
$initrd_size = $initrd_size + ((stat($path))[12]/2);
|
||
unlink($path) if $value == 1;
|
||
}
|
||
}
|
||
}
|
||
|
||
$initrd_size = $initrd_size + ($initrd_size * 0.02);
|
||
|
||
# For perfection 1 (rounded up) is o.k., but for safety 10 would be
|
||
# better
|
||
$initrd_size = sprintf("%.f",$initrd_size) + 10;
|
||
return $initrd_size;
|
||
|
||
} # end sub initrd_size
|
||
|
||
sub pb {
|
||
|
||
# Will have to count by hand
|
||
if ($_[0] eq "initrd") {
|
||
$pbar->configure( 10, 0, 10 );
|
||
}
|
||
elsif ($_[0] eq "boot") {
|
||
$pbar->configure( 10, 0, 10 );
|
||
}
|
||
elsif ($_[0] eq "filesystem") {
|
||
$pbar->configure($_[2], 0, $_[2]);
|
||
}
|
||
|
||
$pbar->set_value($_[1]);
|
||
# Found this at Gnome ..
|
||
# http://www.uk.gnome.org/mailing-lists/archives/gtk-list/
|
||
# 1999-October/0401.shtml
|
||
# Also, http://www.gtk.org/faq/ 5.14
|
||
while (Gtk->events_pending) { Gtk->main_iteration; }
|
||
|
||
}
|
||
|
||
sub initrd {
|
||
|
||
my($kernel,$root_image,$device,$size) = @_;
|
||
my($lib,$what,$path,$value,$tool);
|
||
my $I = "initrd";
|
||
|
||
# Basically this means the ARS was never opened or edited and the
|
||
# default behavior is to use the same device.
|
||
if ( !$entry_advanced[3] ) {
|
||
$device = $container[BOOT_DEVICE];
|
||
}
|
||
else {
|
||
$device = $entry_advanced[3];
|
||
}
|
||
|
||
|
||
my $fs_type = (split(/\s/,$main::makefs))[0];
|
||
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
# Assuming busybox is being used, so bzip2 should still be standard
|
||
# just another link .. just for testing.
|
||
if ( $compress eq "bzip2" ) {
|
||
$compress = "bunzip2";
|
||
}
|
||
}
|
||
|
||
my $broot_image = basename($root_image);
|
||
open(LC, ">$tmp/linuxrc") or die "Couldn't write linuxrc to loop device\n";
|
||
print LC initrd_heredoc($broot_image,$device); close(LC);
|
||
pb($I,1);
|
||
my $size_needed = initrd_size((stat("$tmp/linuxrc"))[12]/2);
|
||
unlink("$tmp/linuxrc");
|
||
|
||
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
|
||
info(0, "Using loop device to make initrd\n");
|
||
info(0, "Make sure you have loop device capability" .
|
||
" in your running kernel\n");
|
||
sys("dd if=/dev/zero of=$tmp/$initrd bs=1024 count=$size_needed");
|
||
pb($I,2);
|
||
# no need to enter y every time .. could use -F
|
||
my $error;
|
||
open(T,"|mke2fs -F -m0 -i8192 $tmp/$initrd >/dev/null 2>&1") or
|
||
($error = error("Can not make ext2 filesystem on initrd.\n"));
|
||
return "ERROR" if $error && $error eq "ERROR";
|
||
print T "y\n"; close(T);
|
||
pb($I,3);
|
||
info(0, "Mounting initrd in $tmp/initrd_mnt\n");
|
||
|
||
}
|
||
|
||
# clean initrd_mnt if any garbage is found.
|
||
if (-d "$tmp/initrd_mnt") {
|
||
sys("rm -rf $tmp/initrd_mnt");
|
||
}
|
||
if (!-d "$tmp/initrd_mnt") {
|
||
return if errmk(sys("mkdir $tmp/initrd_mnt")) == 2;
|
||
}
|
||
|
||
|
||
# Here the loop device is made on tmp, not mnt
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
info(0, "Using genext2fs to make initrd rather than a loop device\n");
|
||
}
|
||
|
||
else {
|
||
if ( $> == 0 ) {
|
||
return if errm(sys("mount -o loop -t ext2 $tmp/$initrd $tmp/initrd_mnt")) == 2;
|
||
}
|
||
else {
|
||
return if errm(sys("mount $tmp/initrd_mnt")) == 2;
|
||
}
|
||
}
|
||
pb($I,4);
|
||
|
||
info(0, "Putting everything together\n");
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
open(LC, ">$tmp/initrd_mnt/linuxrc") or die "Couldn't write linuxrc to $tmp/initrd_mnt\n";
|
||
}
|
||
else {
|
||
open(LC, ">$tmp/initrd_mnt/linuxrc") or die "Couldn't write linuxrc to loop device\n";
|
||
}
|
||
print LC initrd_heredoc($broot_image,$device); close(LC);
|
||
# I could test this but somebody's system may do permissions differently
|
||
sys("chmod 755 $tmp/initrd_mnt/linuxrc");
|
||
if ($fs_type ne "genext2fs" ) {
|
||
sys("rmdir $tmp/initrd_mnt/lost+found");
|
||
}
|
||
pb($I,5);
|
||
|
||
info(0, "... the dirs\n");
|
||
return if errmk(
|
||
sys("mkdir $tmp/initrd_mnt/{bin,dev,etc,lib,mnt,proc,sbin,usr}")) == 2;
|
||
return if errmk(sys("mkdir $tmp/initrd_mnt/usr/lib")) == 2;
|
||
pb($I,6);
|
||
|
||
# Hopefully, this works, but have never tested it - o.k I did
|
||
if ( $fs_type ne "genext2fs" ) {
|
||
if ($container[BOOT_DEVICE] !~ m,/dev/fd\d{1}$,) {
|
||
return if err(sys("cp -a $container[BOOT_DEVICE] $mnt/dev")) == 2;
|
||
}
|
||
}
|
||
|
||
# DEVICES SECTION
|
||
my @devices;
|
||
my $device_table = "$tmp/initrd_device_table.txt";
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
|
||
info(0, "Making $device_table for genext2fs\n");
|
||
my $error;
|
||
unlink( $device_table ) if -e $device_table;
|
||
|
||
#<path> <type> <mode> <uid> <gid> <major> <minor> <start><inc><count>
|
||
# /dev is always needs to be made automatically
|
||
open(BootRoot::Yard::DEVICE_TABLE, ">$device_table") or
|
||
($error = error("$device_table: $!"));
|
||
return "ERROR"if $error && $error eq "ERROR";
|
||
|
||
print BootRoot::Yard::DEVICE_TABLE
|
||
"# <path>\t<type>\t<mode>\t<uid>\t<gid>\t<major>\t<minor>" .
|
||
"\t<start>\t<inc>\t<count>\n";
|
||
print BootRoot::Yard::DEVICE_TABLE "/dev\t\td\t0755\t-\t-\t-\t-\t-\t-\t-\n";
|
||
|
||
# Keep a record of the devices required
|
||
@devices = qw(/dev/console dev/null /dev/ram0 /dev/ram1 /dev/tty0);
|
||
for ( split(" ", $container[BOOT_DEVICE] ) ) {
|
||
push(@devices, $_ ) if $_;
|
||
}
|
||
|
||
device_table( @devices );
|
||
close(BootRoot::Yard::DEVICE_TABLE);
|
||
|
||
}
|
||
|
||
else {
|
||
|
||
if ( $> == 0 ) {
|
||
info(0, "Copying over devices to $tmp/initrd_mnt/dev\n");
|
||
return if errcp(
|
||
sys("cp -a /dev/{console,null,ram0,ram1,tty0} $tmp/initrd_mnt/dev")
|
||
) == 2;
|
||
return if errcp(
|
||
sys("cp -a $container[BOOT_DEVICE] $tmp/initrd_mnt/dev")) == 2;
|
||
}
|
||
else {
|
||
info(0, "Mknod devices at $tmp/initrd_mnt/dev\n");
|
||
# This could be replaced by a devfs.
|
||
sys("$main::sudo mknod c 5 1 $tmp/initrd_mnt/dev/console");
|
||
sys("$main::sudo mknod c 1 3 $tmp/initrd_mnt/dev/null");
|
||
sys("$main::sudo mknod b 1 0 $tmp/initrd_mnt/dev/ram0");
|
||
sys("$main::sudo mknod b 1 1 $tmp/initrd_mnt/dev/ram1");
|
||
sys("$main::sudo mknod c 4 0 $tmp/initrd_mnt/dev/tty0");
|
||
sys("$main::sudo mknod b 2 0 $tmp/initrd_mnt/dev/fd0");
|
||
}
|
||
|
||
} # end DEVICES SECTION
|
||
|
||
pb($I,7);
|
||
|
||
# This and libs should be user accessible
|
||
info(0, ".. the modules\n");
|
||
my @modules = kernel_modules();
|
||
|
||
if (@modules) {
|
||
|
||
mkpath("$tmp/initrd_mnt/lib/modules/$kernel_version");
|
||
|
||
foreach my $stuff (@modules) {
|
||
($path,$value) = stripper($stuff,"mod");
|
||
$value == 0 ? ($tool = "cp -a") : ($tool = "mv");
|
||
if (!$path) {
|
||
info(1,"gBootRoot Error: Couldn't find $stuff\n");
|
||
}
|
||
return if
|
||
errcp(sys("$tool $path $tmp/initrd_mnt/lib/modules/$kernel_version")) == 2;
|
||
}
|
||
|
||
if ($entry_advanced[13] && $entry_advanced[13] ne "") {
|
||
|
||
if ( $> == 0 ) {
|
||
|
||
info(1, "depmod -ae -F $entry_advanced[13] -b $tmp/initrd_mnt/lib/modules/$kernel_version $kernel_version\n");
|
||
return if err_custom("depmod -ae -F $entry_advanced[13] -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
}
|
||
else {
|
||
|
||
info(1, "depmod -aer -F $entry_advanced[13] -b $tmp/initrd_mnt/lib/modules/$kernel_version $kernel_version\n");
|
||
return if err_custom("depmod -aer -F $entry_advanced[13] -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
}
|
||
|
||
} # $entry_advanced[13] defined
|
||
else {
|
||
|
||
if ( $> == 0 ) {
|
||
|
||
info(1, "depmod -ae -b $tmp/initrd_mnt/lib/modules/$kernel_version $kernel_version\n");
|
||
return if err_custom("depmod -ae -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
}
|
||
else {
|
||
|
||
info(1, "depmod -aer -b $tmp/initrd_mnt/lib/modules/$kernel_version $kernel_version\n");
|
||
return if err_custom("depmod -aer -b $tmp/initrd_mnt $kernel_version", "gBootRoot: ERROR: depmod failed") == 2;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
|
||
info(0, ".. the bins\n");
|
||
my @initrd_stuff;
|
||
if (@modules) {
|
||
@initrd_stuff = qw(ash gzip mount umount modprobe insmod);
|
||
}
|
||
else {
|
||
@initrd_stuff = qw(ash gzip mount umount);
|
||
}
|
||
|
||
# Will put the stuff in sbin because the is where the kernel looks for
|
||
# modprobe.
|
||
if ( ! $busybox ) {
|
||
|
||
foreach (@initrd_stuff) {
|
||
($path,$value) = stripper(find_file_in_path($_),"bin");
|
||
$value == 0 ? ($tool = "cp -a") : ($tool = "mv");
|
||
if (!$path) {
|
||
info(1,"gBootRoot Error: Couldn't find $_\n");
|
||
}
|
||
return if errcp(sys("$tool $path $tmp/initrd_mnt/sbin")) == 2;
|
||
}
|
||
|
||
if ($compress eq "bzip2" && -e find_file_in_path($compress)) {
|
||
($path,$value) = stripper(find_file_in_path($compress),"bin");
|
||
$value == 0 ? ($tool = "cp -a") : ($tool = "mv");
|
||
return if errcp(sys("$tool $path $tmp/initrd_mnt/sbin")) == 2;
|
||
}
|
||
|
||
# Testing if init is sufficient for grabbing the correct libraries for the
|
||
# executables immediately above. This could be modified to test a
|
||
# list of executables. Now bzip2 uses libbz2.so.1.0, so if bzip2 is
|
||
# present on the system this will be the tester instead, and size
|
||
# has to be figured out differently.
|
||
info(0, ".. the libs\n");
|
||
|
||
my $lib_tester;
|
||
if ($bz2_toggle->active && -x find_file_in_path("bzip2") ) {
|
||
|
||
$lib_tester = find_file_in_path("bzip2");
|
||
|
||
}
|
||
else {
|
||
|
||
$lib_tester = find_file_in_path("init");
|
||
|
||
}
|
||
|
||
my $dir;
|
||
|
||
open(L,"ldd $lib_tester|") or die "Oops, no $lib_tester could be found :)\n"; # safe to use ldd, this is going to be fixed later with library_dependencies
|
||
while (<L>) {
|
||
my $place;
|
||
($lib,$place) = (split(/=>/,$_))[0,1];
|
||
$place = (split(" ",$place))[0];
|
||
$lib =~ s/\s+//;
|
||
$lib = basename($lib);
|
||
$lib =~ s/\s+$//;
|
||
$dir = dirname($place);
|
||
info(0,"$dir/$lib\n");
|
||
open (SL,"ls -l $dir/$lib|") or die "humm: $!\n";
|
||
while (<SL>) {
|
||
# symbolic link
|
||
if (-l "$dir/$lib") {
|
||
$what = (split(/\s+/,$_))[10];
|
||
($path,$value) = stripper("$dir/$lib","lib");
|
||
$value == 0 ? ($tool = "cp -a") : ($tool = "mv");
|
||
return if errcp(sys("$tool $path $tmp/initrd_mnt$dir")) == 2;
|
||
($path,$value) = stripper("$dir/$what","lib");
|
||
$value == 0 ? ($tool = "cp -a") : ($tool = "mv");
|
||
return if errcp(sys("$tool $path $tmp/initrd_mnt$dir")) == 2;
|
||
}
|
||
# no symbolic link
|
||
else {
|
||
($path,$value) = stripper("$dir/$lib","lib");
|
||
return if errcp(sys("cp -a $path $tmp/initrd_mnt$dir")) == 2;
|
||
}
|
||
}
|
||
}
|
||
|
||
} # not busybox
|
||
|
||
else {
|
||
|
||
my $error;
|
||
|
||
# busybox binary
|
||
$tool = "cp -a";
|
||
$path = "/home/mttrader/busybox/busybox/busybox";
|
||
return if errcp(sys("$tool $path $tmp/initrd_mnt/sbin")) == 2;
|
||
|
||
#Currently defined functions:
|
||
# [, ash, bunzip2, busybox, echo, false, gzip, insmod, modprobe,
|
||
# mount, sh, test, true, umount
|
||
|
||
my $target = "$tmp/initrd_mnt/sbin/busybox";
|
||
my @busystuff = qw(ash sh bunzip2 echo gzip insmod modprobe mount
|
||
umount);
|
||
chdir("$tmp/initrd_mnt/sbin/");
|
||
foreach ( @busystuff ) {
|
||
|
||
symlink("busybox", "$tmp/initrd_mnt/sbin/$_" );
|
||
|
||
}
|
||
|
||
# uClibc
|
||
mkpath("$tmp/initrd_mnt/usr/i386-linux-uclibc/lib");
|
||
$path = "/usr/i386-linux-uclibc/lib/libuClibc-0.9.5.so";
|
||
return if errcp(sys("$tool $path $tmp/initrd_mnt/usr/i386-linux-uclibc/lib")) == 2;
|
||
sys("chmod 755 $tmp/initrd_mnt/usr/i386-linux-uclibc/lib/libuClibc-0.9.5.so");
|
||
chdir("$tmp/initrd_mnt/lib");
|
||
symlink("../usr/i386-linux-uclibc/lib/libuClibc-0.9.5.so", "$tmp/initrd_mnt/lib/libc.so.0" );
|
||
|
||
$path = "/usr/i386-linux-uclibc/lib/ld-uClibc-0.9.5.so";
|
||
return if errcp(sys("$tool $path $tmp/initrd_mnt/usr/i386-linux-uclibc/lib")) == 2;
|
||
sys("chmod 755 $tmp/initrd_mnt/usr/i386-linux-uclibc/lib/ld-uClibc-0.9.5.so");
|
||
chdir("$tmp/initrd_mnt/usr/i386-linux-uclibc/lib");
|
||
symlink("ld-uClibc-0.9.5.so", "$tmp/initrd_mnt/usr/i386-linux-uclibc/lib/ld-uClibc.so.0" );
|
||
|
||
}
|
||
|
||
|
||
info(0, "Determine run-time link bindings\n");
|
||
# Has a return code of 0 regardless
|
||
# Also, produces false alarms even when it is working.
|
||
info(1, "Ignore warnings about missing directories\n");
|
||
sys("ldconfig -v -r $tmp/initrd_mnt");
|
||
|
||
|
||
if ( $fs_type eq "genext2fs" ) {
|
||
info(0, "Using genext2fs to contruct the initrd\n");
|
||
# The -D option is unique to the newest unreleased version of
|
||
# genextfs modified by BusyBox maintainer Erick Andersen
|
||
# August 20, 2001.
|
||
|
||
my $error;
|
||
|
||
# genext2fs doesn't make accurate sized filesystems.
|
||
# this will be user adjustable in the future.
|
||
$size_needed = $size_needed + 1000;
|
||
|
||
if (
|
||
sys("/usr/lib/bootroot/$main::makefs -b $size_needed -d $tmp/initrd_mnt -D $device_table $tmp/$initrd") !~
|
||
/^0$/ ) {
|
||
$error = error("Cannot $fs_type filesystem.\n");
|
||
return "ERROR" if $error && $error eq "ERROR";
|
||
}
|
||
|
||
}
|
||
|
||
else {
|
||
chdir($pwd);
|
||
info(0, "Umounting loop device, and compressing initrd\n");
|
||
return if errum(sys("umount $tmp/initrd_mnt")) == 2;
|
||
}
|
||
|
||
info(0, "Compressing initrd\n");
|
||
sys("gzip -f9 $tmp/$initrd");
|
||
|
||
pb($I,10); # This takes the longest.
|
||
|
||
$initrd = $initrd . ".gz";
|
||
|
||
} # end sub initrd
|
||
|
||
# This was submitted by Cristian "cretzu."
|
||
sub gdkbirdaao {
|
||
|
||
# Guess Default Kernel Boot Image Root Device And Append Options
|
||
#(gdbirdaao)
|
||
#
|
||
# We return a list with 3 elements:
|
||
#
|
||
# root device, kernel boot image path and append options
|
||
#
|
||
# The last list element (append options) could be returned as a list
|
||
# of options, but it probably might be cleaner if the caller splitted it.
|
||
#
|
||
# this should cover the following cases:
|
||
#
|
||
# 1. we have a 'root=...' somewhere above the 'image=...' block(s), and
|
||
# the image block may or may not have a root specified
|
||
#
|
||
# 2. there is no default label, in which case, we take the first one
|
||
#
|
||
# 3. there is a default label, and that's what we pick up
|
||
#
|
||
|
||
my $ret_image_path = '';
|
||
my $ret_root_dev = '';
|
||
my $ret_append = '';
|
||
|
||
|
||
# enough of the annoying "perhaps you are not root"
|
||
# ofcourse this test is always ran assuming lilo is used.
|
||
if ( $> == 0 ) {
|
||
|
||
if ( !$container[METHOD] ||
|
||
$container[METHOD] eq "2 disk compression" ) {
|
||
|
||
if (-e $lilo_conf and !-d $lilo_conf) {
|
||
|
||
my @lilo_lines;
|
||
open(LIL, $lilo_conf) or
|
||
warn "*** $lilo_conf not found\n";
|
||
@lilo_lines = <LIL>;
|
||
close(LIL);
|
||
chomp(@lilo_lines);
|
||
|
||
my $default_label = '';
|
||
my %image_blocks;
|
||
my $image_block_name_prefix = 'ImageBlock';
|
||
my $image_block_no = 1;
|
||
my $image_block_name = '';
|
||
my $root_dev = '';
|
||
|
||
for (@lilo_lines) {
|
||
# ignore comment lines
|
||
next if m/^\s*[#]/;
|
||
|
||
# cleanup whitespace
|
||
s/\s*//;
|
||
s/\s*$//;
|
||
s/\s*=\s*/=/;
|
||
|
||
# 'default=whatever' returns just a label
|
||
if (m/default=(.+)\s*/) {
|
||
$default_label = $1;
|
||
}
|
||
# start of a new 'image=<kernel path>'
|
||
# image block or similar
|
||
elsif (m/(image|other)=(.+)\s*/) {
|
||
$image_block_name =
|
||
sprintf("%s%02d",
|
||
$image_block_name_prefix,
|
||
$image_block_no);
|
||
$image_blocks{$image_block_name}
|
||
{'kernel_image_path'} = $2;
|
||
$image_blocks{$image_block_name}
|
||
{'root_device'} = $root_dev;
|
||
$image_block_no += 1;
|
||
}
|
||
# image block label
|
||
elsif (m/label=(.+)\s*/) {
|
||
$image_blocks{$image_block_name}
|
||
{'block_label'} = $1;
|
||
}
|
||
# 'root=<root device>'
|
||
elsif (m#root=/dev/(.+)\s*#) {
|
||
# inside an image block
|
||
if ($image_block_name and
|
||
defined($image_blocks
|
||
{$image_block_name}
|
||
{'root_device'})) {
|
||
$image_blocks{$image_block_name}
|
||
{'root_device'} = $1;
|
||
}
|
||
# loose
|
||
else {
|
||
$root_dev = $1 if !$root_dev;
|
||
}
|
||
}
|
||
elsif (m#append=\"(.+)\"#) {
|
||
$image_blocks{$image_block_name}
|
||
{'append'} = $1;
|
||
}
|
||
else {
|
||
# Ignore everything else
|
||
}
|
||
}
|
||
|
||
# we'll now find the kernel image and root device
|
||
foreach $image_block_name (sort keys %image_blocks) {
|
||
# Assume there's no specified default label;
|
||
# take the first
|
||
$ret_root_dev =
|
||
$image_blocks{$image_block_name}{'root_device'}
|
||
if !$ret_root_dev;
|
||
$ret_image_path =
|
||
$image_blocks{$image_block_name}
|
||
{'kernel_image_path'}
|
||
if !$ret_image_path;
|
||
$ret_append =
|
||
$image_blocks{$image_block_name}{'append'}
|
||
if !$ret_append;
|
||
|
||
# do we have a default kernel?
|
||
if (defined $image_blocks{$image_block_name}
|
||
{'block_label'}) {
|
||
if ($image_blocks{$image_block_name}
|
||
{'block_label'} eq $default_label) {
|
||
# Found the block match for the default label
|
||
$ret_root_dev =
|
||
$image_blocks{$image_block_name}
|
||
{'root_device'};
|
||
$ret_image_path =
|
||
$image_blocks{$image_block_name}
|
||
{'kernel_image_path'};
|
||
$ret_append = $image_blocks
|
||
{$image_block_name}{'append'};
|
||
last;
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
|
||
} # if METHOD eq 2 disk compression
|
||
|
||
} # if not root
|
||
|
||
# and some a small portion of paranoia
|
||
$ret_root_dev = 'hda1' if !$ret_root_dev;
|
||
|
||
return ($ret_root_dev, $ret_image_path, $ret_append);
|
||
|
||
} # end sub gdkbirdaao
|
||
|
||
###########
|
||
# Mtab area
|
||
###########
|
||
|
||
sub mtab_window {
|
||
# Will just use a dialog box.
|
||
my ($dialog,$error,$count,$pattern) = @_;
|
||
|
||
if (not defined $mtab) {
|
||
$mtab = Gtk::Dialog->new();
|
||
$mtab->signal_connect("destroy", \&destroy_window, \$mtab);
|
||
$mtab->signal_connect("delete_event", \&destroy_window, \$mtab);
|
||
$mtab->set_title("gBootRoot: Device check");
|
||
$mtab->border_width(15);
|
||
$mtab->set_position('center');
|
||
my $label = Gtk::Label->new($dialog);
|
||
$label->set_justify( 'left' );
|
||
$label->set_pattern("_________") if $pattern == 9;
|
||
$label->set_pattern("_____") if $pattern == 5;
|
||
$mtab->vbox->pack_start( $label, $true, $true, 15 );
|
||
$label->show();
|
||
my $button = Gtk::Button->new("OK");
|
||
$button->signal_connect("clicked", \&mtab_check, $count);
|
||
$button->can_default(1);
|
||
$mtab->action_area->pack_start($button, $false, $false,0);
|
||
$button->grab_default;
|
||
$button->show;
|
||
$button = Gtk::Button->new("Cancel");
|
||
$button->signal_connect("clicked", sub { destroy $mtab;
|
||
$mtab = 2 if $count == 3; } );
|
||
$mtab->action_area->pack_start($button, $false, $false,0);
|
||
$button->show;
|
||
}
|
||
if (!visible $mtab) {
|
||
show $mtab;
|
||
}
|
||
else {
|
||
destroy $mtab;
|
||
mtab_window($dialog,$error,$count) if $error == 0;
|
||
}
|
||
|
||
} # end sub mtab_window
|
||
|
||
sub mtab{
|
||
|
||
# /proc/mount could be used, but maybe there is no /proc
|
||
# Press OK when drive and storage medium are ready. The drive should not
|
||
# be mounted.
|
||
|
||
if ($_[0] == 0) {
|
||
my $dialog = "BOOTDISK:\n"
|
||
."Press OK when the drive and its storage medium is ready.\n"
|
||
."The Boot Disk will now be made. All data already on\n"
|
||
."the storage medium will be erased.";
|
||
mtab_window($dialog,1,$_[0],9);
|
||
}
|
||
elsif ($_[0] == 1) {
|
||
my $dialog = "ROOTDISK:\n"
|
||
."Press OK when the drive and its storage medium is ready.\n"
|
||
."The Root Disk will now be made. All data already on\n"
|
||
."the storage medium will be erased.";
|
||
mtab_window($dialog,1,$_[0],9);
|
||
}
|
||
elsif ( $_[0] == 3 ) {
|
||
my $dialog = "LILO:\n"
|
||
."Lilo will now be executed. In order for the bootloader\n"
|
||
."to work properly you need superuser privileges to run lilo.\n"
|
||
."See FAQ for ways to accomplish this. Even if you don't have\n"
|
||
."privileges, the program will continue to make a boot disk.\n"
|
||
."Lilo may be ran as root at a later time on the boot disk.";
|
||
mtab_window($dialog,3,$_[0],5);
|
||
}
|
||
|
||
|
||
} # end sub mtab
|
||
|
||
|
||
sub mtab_check {
|
||
|
||
my($widget,$count) = @_;
|
||
|
||
my $dialog;
|
||
my $error = 1;
|
||
|
||
my $fs_type = (split(/\s/,$main::makefs))[0];
|
||
|
||
# Check to see if $device is mounted
|
||
|
||
if ( $count < 3 ) {
|
||
open (MTAB, "/etc/mtab") or die "no mtab!\n";
|
||
while (<MTAB>) {
|
||
|
||
if ($count == 1) {
|
||
|
||
# ROOT_DEVICE
|
||
if ( m,$entry_advanced[3], ) {
|
||
# Safety Check:
|
||
$dialog =
|
||
"Please umount the device first.\nPress OK when you are ready.";
|
||
$error = 0;
|
||
}
|
||
|
||
}
|
||
|
||
elsif ( $count == 0 ) {
|
||
|
||
# BOOT_DEVICE
|
||
if (m,$entry_advanced[0],) {
|
||
# Safety Check:
|
||
$dialog =
|
||
"Please umount the device first.\nPress OK when you are ready.";
|
||
$error = 0;
|
||
}
|
||
|
||
}
|
||
|
||
}
|
||
close(MTAB);
|
||
|
||
}
|
||
|
||
mtab_window($dialog,$error,$count) if $error == 0;
|
||
|
||
# Make sure the drive and storage medium are accessible
|
||
# Keep asking until they are.
|
||
if ( $error == 1 && $fs_type ne "genext2fs" ) {
|
||
destroy $mtab;
|
||
|
||
# $size has to be determined by boot disk or root disk
|
||
|
||
# ROOT_DEVICE - test with a loop device
|
||
if ($count == 1) {
|
||
sys("mke2fs -F -m0 -i8192 $entry_advanced[3] $root_device_size");
|
||
}
|
||
|
||
|
||
# BOOT_DEVICE
|
||
elsif ($count == 0) {
|
||
sys("mke2fs -F -m0 -i8192 $entry_advanced[0] $container[SIZE]");
|
||
}
|
||
|
||
if ($? != 0) {
|
||
$dialog = "gBootRoot: ERROR: You need to insert a disk\n";
|
||
mtab_window($dialog,$error,$count);
|
||
return;
|
||
}
|
||
|
||
# ROOT_DEVICE
|
||
if ($count == 1) {
|
||
if ( $> == 0 ) {
|
||
return if errm(sys("mount -t ext2 $entry_advanced[3] $mnt")) == 2;
|
||
}
|
||
else {
|
||
return if errm(sys("mount $mnt")) == 2;
|
||
}
|
||
}
|
||
|
||
# BOOT_DEVICE
|
||
elsif ($count == 0) {
|
||
if ( $> == 0 ) {
|
||
return if errm(sys("mount -t ext2 $entry_advanced[0] $mnt")) == 2;
|
||
}
|
||
else {
|
||
return if errm(sys("mount $mnt")) == 2;
|
||
}
|
||
}
|
||
|
||
|
||
lilo_put_it_together() if $count == 0; # mtab(1) runs from here
|
||
device2() if $count == 1;
|
||
|
||
} # if $error == 1
|
||
|
||
if ( $fs_type eq "genext2fs" && $error == 1 ) {
|
||
|
||
destroy $mtab;
|
||
lilo_put_it_together() if $count == 0; # mtab(1) runs from here
|
||
device2() if $count == 1;
|
||
|
||
}
|
||
|
||
# Warned the user about something
|
||
if ( $error == 3 ) {
|
||
$mtab->destroy;
|
||
}
|
||
|
||
|
||
} # end sub mtab_check
|
||
|
||
##################
|
||
# Here Doc Section
|
||
##################
|
||
|
||
# This should be user accessible
|
||
# This should be called linuxrc.
|
||
sub initrd_heredoc {
|
||
|
||
my($broot_image,$root_device) = @_;
|
||
|
||
# Here's where the initrd is put together using a loop device
|
||
# HEREDOC
|
||
my $initrd_exec = << "INITRD";
|
||
#!/sbin/ash
|
||
|
||
export PATH=/bin:/sbin:/usr/bin:
|
||
|
||
echo Preparing to setup ramdisk.
|
||
|
||
# Before busybox experimentation this was the state of things:
|
||
# mount -o remount,rw / 2>/dev/null
|
||
# echo Mounting proc...
|
||
# mount -t proc none /proc
|
||
|
||
echo Mounting proc...
|
||
mount -t proc none /proc
|
||
|
||
echo Mounting $root_device readable-writable
|
||
mount -o remount,rw $root_device /
|
||
|
||
echo -n 'Please insert the root floppy, and press [Enter]: '
|
||
read ENTER
|
||
|
||
echo Mounting $root_device readonly ...
|
||
|
||
# -t causes busybox to fail here, -o doesn't help much either.
|
||
#mount -o ro -t ext2 $root_device /mnt
|
||
mount $root_device /mnt
|
||
|
||
echo -n Copying new root to ramdisk .. please wait ...
|
||
$compress -cd /mnt/$broot_image > /dev/ram1
|
||
echo done.
|
||
|
||
echo -n Unmounting $root_device ...
|
||
umount /mnt
|
||
echo done.
|
||
|
||
# Using change_root, eventually may change to pivot_root or
|
||
# give the user the choice.
|
||
|
||
echo Changing to the new root.
|
||
echo 257 >/proc/sys/kernel/real-root-dev
|
||
|
||
echo -n Unmounting proc ...
|
||
umount /proc
|
||
echo done.
|
||
|
||
echo Continuing normal boot procedure from ramdisk.
|
||
INITRD
|
||
|
||
return $initrd_exec;
|
||
|
||
} # end sub initrd_heredoc
|
||
|
||
sub brlilo {
|
||
|
||
my ($device) = @_;
|
||
$entry_advanced[2] ? $entry_advanced[2] = $entry_advanced[2]
|
||
: $entry_advanced[2] = $container[ABS_APPEND];
|
||
|
||
# HEREDOC
|
||
my $brlilo = << "LILOCONF";
|
||
boot = $device
|
||
message = message
|
||
delay = 50
|
||
vga = normal
|
||
install = /boot/boot.b
|
||
map = /boot/map
|
||
backup = /dev/null
|
||
compact
|
||
|
||
# bootdisk
|
||
image = kernel
|
||
append = "load_ramdisk=1 debug $entry_advanced[2]"
|
||
initrd = $initrd
|
||
root = $device
|
||
label = bootdisk
|
||
read-write
|
||
|
||
# normalboot
|
||
image = kernel
|
||
append = "$entry_advanced[2]"
|
||
root = /dev/$norm_root_device
|
||
label = normalboot
|
||
read-only
|
||
LILOCONF
|
||
|
||
return $brlilo;
|
||
|
||
} # end sub brlilo
|
||
|
||
|
||
sub brlilo_non_root {
|
||
|
||
my ($device) = @_;
|
||
$entry_advanced[2] ? $entry_advanced[2] = $entry_advanced[2]
|
||
: $entry_advanced[2] = $container[ABS_APPEND];
|
||
|
||
# HEREDOC
|
||
my $brlilo = << "LILOCONF";
|
||
boot = $device
|
||
message = $old_mount/message
|
||
delay = 50
|
||
vga = normal
|
||
install = $old_mount/boot/boot.b
|
||
map = $old_mount/boot/map
|
||
backup = /dev/null
|
||
compact
|
||
|
||
# bootdisk
|
||
image = $old_mount/kernel
|
||
append = "load_ramdisk=1 debug $entry_advanced[2]"
|
||
initrd = $old_mount/$initrd
|
||
root = $device
|
||
label = bootdisk
|
||
read-write
|
||
|
||
# normalboot
|
||
#image = kernel
|
||
#append = "$entry_advanced[2]"
|
||
#root = /dev/$norm_root_device
|
||
#label = normalboot
|
||
#read-only
|
||
LILOCONF
|
||
|
||
return $brlilo;
|
||
|
||
} # end sub brlilo_non_root
|
||
|
||
|
||
sub message {
|
||
# HEREDOC
|
||
my $message = << "MESSAGE";
|
||
|
||
gBootRoot $version $date GNU GPL
|
||
mailto: Jonathan Rosenbaum <freesource\@users.sourceforge.net>
|
||
|
||
Press [Ctrl] to see the lilo prompt.
|
||
|
||
Press [Tab] to see a list of boot options.
|
||
|
||
bootdisk = This will boot a compressed root filesystem
|
||
on another floppy.
|
||
normalboot = This will boot up a specified filesystem.
|
||
default: /dev/$norm_root_device
|
||
Use root=/dev/(h or s)dXX
|
||
h = IDE Drive
|
||
s = SCSI Drive
|
||
|
||
Trouble: Do not forget boot: option single
|
||
Fix a filesystem: e2fsck /dev/(h or s)dXX
|
||
Bad superblock: e2fsck -b 8192 /dev/(h or s)dXX
|
||
|
||
MESSAGE
|
||
|
||
return $message;
|
||
|
||
} # end sub message
|
||
|
||
sub help {
|
||
|
||
<< "HELP";
|
||
|
||
gBootRoot $version $date GNU GPL
|
||
|
||
Email contact -> Jonathan Rosenbaum <freesource\@users.sourceforge.net>
|
||
|
||
Homepage -> http://gbootroot.sourceforge.net
|
||
Submit a Bug -> http://sourceforge.net/bugs/?group_id=9513
|
||
Devel. & Releases -> http://sourceforge.net/projects/gbootroot
|
||
|
||
Places to talk:
|
||
|
||
gbootroot-{devel,user} mailing lists -> http://sourceforge.net/mail/?group_id=9513
|
||
Help forum -> http://sourceforge.net/forum/forum.php?forum_id=29639
|
||
Open forum -> http://sourceforge.net/forum/forum.php?forum_id=29638
|
||
|
||
gbootroot documentation and FAQ:
|
||
|
||
/usr/share/doc/gbootroot/html/index.html
|
||
|
||
How to Use gBootRoot:
|
||
|
||
The most important button to familiarize yourself with is the Submit button
|
||
which starts the whole process; dialogs are presented as the process
|
||
continues asking you if you want to continue "OK" or stop "Cancel".
|
||
|
||
The first row presently has only one Boot Method choice: "2 disk compression."
|
||
Clicking on the menu on the right selects the Boot Method.
|
||
|
||
The second row allows you to select the kernel for the Boot/Root set. You
|
||
may either use the file selector button on the right hand side, or you may
|
||
type in the location on the left hand side.
|
||
|
||
The third row allows you to select the compressed filesystem you are
|
||
providing, using either of the two ways mentioned before. You may use a
|
||
pre-made root filesystem or you may create one using one of the Methods
|
||
provided in the Advanced Root Section.
|
||
|
||
The fourth row allows you to select the device you want to use. The default
|
||
device is the first floppy disk (/dev/fd0).
|
||
|
||
The fifth row allows you to choose the size of the device being used. The
|
||
default size of 1440 assumes you are using a floppy drive (Note: You may want
|
||
to experiment with 1722 which works fine with many floppy drives.), but can
|
||
be used with other sized devices like tape drives. Click on the
|
||
appropriate radio button to choose either gzip or bzip2 compression if the
|
||
program doesn't automatically detect it.
|
||
|
||
The slider bar on the right allows the output of the verbosity box to be
|
||
changed from the highest (2) to the lowest setting (1) or to be turned off (0)
|
||
or on again. At times it may be advantageous to turn off the verbosity box
|
||
since large quantities of output to this box may cause gbootroot to use too
|
||
much cpu power; however, output may still be found in the text file "verbose"
|
||
in /tmp/gbootroot_tmp'time-date'.
|
||
|
||
Advanced Boot Section:
|
||
|
||
Libraries & Binaries & Modules check boxes: Turn off and on the
|
||
stripping of symbols. The stripping behavior for libraries may be
|
||
changed by clicking on the right mouse button to change --strip-debug
|
||
to --strip-all. Binaries default to --strip-all and Modules default to
|
||
--strip-debug.
|
||
|
||
"Devel Device" 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.
|
||
|
||
"Opt. Device" 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.
|
||
|
||
"append =" Add append options to brlilo.conf. If you are using a frame
|
||
buffer device you could add something like video=matrox:vesa:402,depth:16.
|
||
|
||
"Kernel Module" Add the modules found in /lib/modules/kernel-version
|
||
which are necessary for the Boot Method to work properly. If these
|
||
modules aren't found in the modules directory it is assumed that they
|
||
either are in the kernel or they do not exist. In the case of 2 disk
|
||
compression, floppy needs to be included in the kernel or included as a
|
||
module. Kmod inserts the modules, and kmod needs to be built into the
|
||
kernel along with initrd and ramdisk."
|
||
|
||
"Kernel Version" Override the kernel version number found in the
|
||
kernel header. This will change the /lib/modules/kernel-version
|
||
directory.
|
||
|
||
System.map: 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.
|
||
|
||
Advanced Root Section:
|
||
|
||
"Root Device" This is the device used for the root filesystem when
|
||
constructing the Boot/Root set. You may choose a device which is different
|
||
than the Boot device, but presently only floppy devices are supported.
|
||
|
||
"Root Device Size" The size of the actual media used for the Root Device.
|
||
|
||
"Root Filename" The name give to the root filesystem when initially made
|
||
in the temporary creation location. The save button allows the creation to
|
||
be saved in the permanent default location when the Accept button is pressed.
|
||
|
||
"Filesystem Size" Root Methods make the filesystem the size which is
|
||
specified here.
|
||
|
||
"Compression" Off by default to allow user-mode-linux testing. Turn on
|
||
compression when you are ready to use a Boot Method which requires compression.
|
||
|
||
"Method" The root filesystem creation method.
|
||
|
||
"Template" The template associated with a Root Method. Not all Root Methods
|
||
have templates.
|
||
|
||
"Generate" This puts the chosen Root Method in action.
|
||
|
||
"UML" Abbreviation for user-mode-linux. This is a linux kernel which runs on
|
||
top of the host system's linux kernel and allows a you run a live root
|
||
filesystem.
|
||
|
||
"Accept" This accepts the created root filesystem if it is found in the
|
||
temporary creation directory. The UML box and the main section will now
|
||
reflect the path to this root filesystem. You can now test with the UML
|
||
button or a put together a complete Boot/Root set with the Submit button.
|
||
|
||
Advanced Kernel Section:
|
||
|
||
Still in development.
|
||
|
||
|
||
Little things you may want to know:
|
||
|
||
* gBootRoot requires ash for initrd. Ash is a feather weight version of Bash.
|
||
|
||
HELP
|
||
|
||
}
|