3 # Main -- an exercise in initrd building
4 # Copyright (C) 2005 Erik van Konijnenburg
6 # This program is free software; you can redistribute it and/or modify
7 # it under the terms of the GNU General Public License as published by
8 # the Free Software Foundation; either version 2 of the License, or
9 # (at your option) any later version.
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write to the Free Software
18 # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 use lib '/usr/local/lib/yaird/perl';
31 my $appName = "yaird";
32 my $appVersion = "0.0.5";
37 # write an image to destination in specified format.
38 # destination must not exist yet.
39 # root is the blockdev to use as root after reboot, or undef for default.
42 my ($format, $destination, $root) = @_;
43 my $masterPlan = Plan::makePlan ($root);
44 my $image = $masterPlan->expand ();
45 Pack::package ($image, $format, $destination);
50 # paranoia -- Random bits of -
56 # Perlsec(1) identifies the following as risky:
58 # delete @ENV{qw(IFS CDPATH ENV BASH_ENV)};
60 # but just scrapping the complete environment
61 # seems to work nicely.
63 delete @ENV{keys %ENV};
64 $ENV{'PATH'} = '/bin:/sbin:/usr/bin:/usr/sbin';
69 # usage -- print invocation patterns of the application
74 $appName generates initrd images.
76 $appName --test [ version ]
77 print an overview of system data, without writing anything to disk.
79 $appName --output dest --format format [ version ]
80 generate an initrd image in 'dest', in the format 'format'.
83 -h, -?, --help print this help text and exit
84 -V, --version print version and exit (don't bother: $appVersion)
85 -v, --verbose print progress messages
86 -d, --debug detailed output
87 -q, --quiet don't print warning messages
88 -o, --output dest place result here
89 -f, --format form produce the image in this format,
90 valid values: directory, cramfs, cpio
91 -r, --root blockdev let initrd boot another block device as root
92 the blockdev must occur in fstab somewhere.
93 -t, --test print overview of system data,
94 used as basis for debugging.
101 # main -- main program, argument processing
104 my ($opt_help, $opt_version,
105 $opt_verbose, $opt_quiet, $opt_debug,
106 $opt_format, $opt_output, $opt_root, $opt_test);
109 Base::setProgName ($appName);
114 # catch warnings during getopt, but not elsewhere.
115 # The idea is to let -? produce help without complaint,
116 # even if other args are broken.
118 local $SIG{__WARN__} = sub { push @warnings, $_[0]; };
120 Getopt::Long::Configure ("bundling");
121 my $result = GetOptions (
122 "h|help|?" => \$opt_help,
123 "V|version" => \$opt_version,
124 "v|verbose" => \$opt_verbose,
125 "q|quiet" => \$opt_quiet,
126 "d|debug" => \$opt_debug,
127 "f|format=s" => \$opt_format,
128 "o|output=s" => \$opt_output,
129 "r|root=s" => \$opt_root,
130 "t|test" => \$opt_test,
135 # --help and --version processed without regard to other options,
136 # exit without side effect.
138 if (defined ($opt_help)) {
142 if (defined ($opt_version)) {
143 Base::setVerbose (1);
144 Base::info ("version $appVersion");
149 # Argument validation
151 for my $w (@warnings) {
152 # lazy: perhaps we could provide more info here?
155 if (defined ($opt_output) && defined ($opt_test)) {
156 Base::fatal "conflicting options --output and --test";
158 if (! defined ($opt_output) && ! defined ($opt_test)) {
159 Base::fatal "one of --output and --test must be given";
161 if (defined ($opt_output)) {
162 if (-e $opt_output) {
163 Base::fatal "destination $opt_output already exists";
165 if (! defined ($opt_format)) {
166 Base::fatal "option --output requires --format option";
168 if (! Pack::knownFormat ($opt_format)) {
169 Base::fatal "unknown --format argument: $opt_format";
173 # Untaint -- is there a need for 'output' with an umlaut?
175 if ($opt_output !~ m!^([-_./[a-zA-Z0-9]+)$!) {
176 Base::fatal ("illegal character in output file name");
180 if (defined ($opt_root)) {
182 if ($opt_root !~ m!^([-_./[a-zA-Z0-9]+)$!) {
183 Base::fatal ("illegal character in root device name");
188 if (defined ($opt_test)) {
189 if (defined ($opt_format)) {
190 Base::fatal "conflicting options --test and --format";
192 if (defined ($opt_root)) {
193 Base::fatal "conflicting options --test and --root";
197 my $valid = $ARGV[0];
198 Base::fatal "extra arguments after $valid";
202 # All arguments validated; start processing.
205 Conf::set ("version", $ARGV[0]);
208 Base::setVerbose (1);
217 # avoid silly messages with an early test
218 my $v = Conf::get("version");
219 my $mdir = Conf::get("libModules") . "/$v";
221 Base::fatal ("unknown kernel version: $v");
225 if (defined ($opt_test)) {
228 elsif (defined ($opt_output)) {
229 go ($opt_format, $opt_output, $opt_root);