root/morphix/trunk/morph-scripts/minimod-gen.pl

Revision 2, 16.7 kB (checked in by nextime, 2 years ago)

Initial import, branching from morphix svn

  • Property svn:executable set to
Line 
1 #!/usr/bin/perl -w
2 #
3 # Licenced under the GNU GPL v2 (www.gnu.org)
4 #
5 # The MiniModule generator
6 #
7 # This script's purpose is to easily build a mini-module,
8 # in an interactive way. We'll start with only a few options,
9 # but this can gradually get more complex. It's only a test,
10 # but should ease the creation of building your own minimodule...
11 #
12 # This script has been made by Alex de Landgraaf, and it's
13 # built up in about the same way the morphix CD ISO creator
14 # was built (by Laurens Buhler). You can be sure i've 'borrowed'
15 # about 3/4 of his code, as i'm not a perl fanatic. Open Source is good :o)
16 #
17
18 use strict;
19 use Net::FTP;
20 use File::Spec;
21
22 our $moddir;
23
24 # option 1: copy
25 our %filelist;
26 # option 2: cmd
27 our @cmdlist;
28 # option 3: deb
29 our @deblist;
30 # option 4: deblist
31 our @deblist_list;
32 our @debfiles_list;
33 our @repolist;
34 our @rellist;
35 our @loclist;
36 our @localfilelist;
37 # option 5: homedir
38 our $homedir = "";
39
40 if ($> != 0) {
41     print "Sorry, you must be root to start the generator!\n";
42     exit 1;
43 }
44
45 main();
46
47 sub main {
48     our $type;
49     our $ret;
50    
51     print ("\n\tWelcome to the interactive Morphix minimodule generator\n\n");
52
53 # Check necessary programs (create_compressed_fs, mkisofs)
54
55     my $ccfs = qx|which create_compressed_fs 2>&1|;
56     my $mkisofs = qx|which mkisofs 2>&1|;
57
58     if (($ccfs =~ /no create_compressed_fs in/) || ($mkisofs =~ /no mkisofs in/)) {
59         die("Can't find create_compressed_fs and / or mkisofs, install these to run the minimodule generator\n");
60     }   
61
62     do {
63         $ret = setup_new_module();
64     } while $ret != 1;
65
66     do {
67         print("Please add an action to the minimodule:\n");
68         print("1) Copy a file/dir to the mainmod at boot, or overwrite one if it exists\n");
69         print("2) Enter a command to be executed at boot\n");
70         print("3) Enter one or more debian packages to be added (experimental, needs dpkg-deb)\n");
71         print("4) Enter a filename containing a list of debian packages to download and add\n");
72         print("5) Enter a directories name, all files in it will be available in morph's homedir\n");
73         print("9) Build the module and exit\n");
74         print("0) Abort without building the module\n\n");
75         print("> ");
76         chomp($type = <STDIN>);
77         print("\n");
78        
79         if ($type == 1) {
80             add_copy();
81         }
82         if ($type == 2) {
83             add_cmd();
84         }
85         if ($type == 3) {
86             add_deb();
87         }
88         if ($type == 4) {
89             add_deblist();
90         }
91         if ($type == 5) {
92             add_homedir();
93         }
94         if ($type == 9) {
95             generate_module();
96             print("The generator will now exit\n");
97             exit 1;
98         }
99         if ($type == 0) {
100             print "Aborted...";
101             exit 1;
102         }
103     }
104     while (1);
105     exit 0;
106 }
107
108 # done before the GUI is shown, used as work directory
109
110 sub setup_new_module {
111     our $i;
112     our $dir;
113     our $input;
114
115     print("Enter a directory to place the unpacked module\n");
116     for ($i = 0; $i <= 100; $i++) {
117         if (!(-e "minimod-$i")) {
118             last;
119         }
120     }
121     print("[minimod-$i] > ");
122     chomp($dir = <STDIN>);
123     if ($dir eq "") {
124         $dir = "minimod-$i";
125     }
126     if (-e "$dir") {
127         print "$dir exists, are you sure you want to overwrite it? ";
128         print "y/N > ";
129         chomp($input = <STDIN>);
130         print "\n";
131         if (!($input eq "y" || $input eq "Y")) {
132             return 0;
133         }
134         system("rm -r $dir");
135     }
136     mkdir ($dir,0755) || die "cannot mkdir $dir: $!";
137     $moddir = $dir;
138     return 1;
139 }  
140
141 ### start option section ###
142
143 # first option: copy a directory over at boottime
144
145 sub add_copy {
146     our $src;
147     our $dest;
148     our $input;
149
150     while(1) {
151         print "Enter a filename to be included (the new file), newline to stop\n";
152         print "> ";
153         chomp($src = <STDIN>);
154         print "\n";
155         if ($src eq "") {
156             last;
157         }
158         if (!(-e $src)) {
159             print "Can't find $src, lets try again\n";
160             redo;
161         }
162        
163         print "Enter in which dir it will be placed, or what file it will replace (with path!)\n";
164         print "> ";
165         chomp($dest = <STDIN>);
166         print "\n\n";
167        
168         $filelist{"$src"} = "$dest";
169
170         our $break = "";
171         while ($break eq "") {
172             print "Do you want to add another file? (or l for list)\n";
173             print "y/N/l > ";
174             chomp($input = <STDIN>);
175             if ($input eq "y" || $input eq "Y") {
176                 $break = "false";
177             }
178             if ($input eq "n" || $input eq "N" || $input eq "") {
179                 $break = "true";
180             }
181             if ($input eq "l" || $input eq "L") {
182                 while (($src,$dest) = each(%filelist)) {
183                     print("Source: $src Destination: $dest\n");
184                 }
185                 print "\n";
186             }
187         };
188         if ($break eq "true") {
189             last;
190         }
191     }
192
193     if (keys %filelist == 0) {
194         print "No files were entered...";
195     }
196 }
197
198 # second option: execute a command at boottime
199
200 sub add_cmd {
201     our $cmd;
202     our $input;
203
204     while(1) {
205         print "Enter a command to be executed on loading of the module, newline to stop\n";
206         print "> ";
207         chomp($cmd = <STDIN>);
208         print "\n";
209         if ($cmd eq "") {
210             last;
211         }
212        
213         @cmdlist = (@cmdlist,$cmd);
214         our $break = "";
215         while ($break eq "") {
216             print "Do you want to add another command? (or l for list)\n";
217             print "y/N/l > ";
218             chomp($input = <STDIN>);
219             if ($input eq "y" || $input eq "Y") {
220                 $break = "false";
221             }
222             if ($input eq "n" || $input eq "N" || $input eq "") {
223                 $break = "true";
224             }
225             if ($input eq "l" || $input eq "L") {
226                 foreach $cmd (@cmdlist) {
227                     print "Command: $cmd\n";
228                 }
229                 print "\n";
230             }
231         };
232         if ($break eq "true") {
233             last;
234         }
235     }
236
237     if (scalar @cmdlist == 0) {
238         print "No commands were entered...";
239     } 
240 }
241
242 # third option: extract a debian package and overlay it at boottime
243
244 sub add_deb {
245     our $src;
246     our $input;
247
248     while(1) {
249         print "Enter a package to be included, newline to stop\n";
250         print "Note that this won't change the debian package database,\n";
251         print "and this is still experimental and might not work...\n";
252         print "> ";
253         chomp($src = <STDIN>);
254         print "\n";
255         if ($src eq "") {
256             last;
257         }
258         if (!(-e $src)) {
259             print "Can't find $src, lets try again\n";
260             redo;
261         }
262
263         print "\n\n";
264         @deblist = (@deblist,$src);
265
266         our $break = "";
267         while ($break eq "") {
268             print "Do you want to add another package? (or l for list)\n";
269             print "y/N/l > ";
270             chomp($input = <STDIN>);
271             if ($input eq "y" || $input eq "Y") {
272                 $break = "false";
273             }
274             if ($input eq "n" || $input eq "N" || $input eq "") {
275                 $break = "true";
276             }
277             if ($input eq "l" || $input eq "L") {
278                 foreach $src (@deblist) {
279                     print "Package: $src\n";
280                 }
281                 print "\n";
282             }
283         };
284         if ($break eq "true") {
285             last;
286         }
287     }
288
289     if (scalar @deblist == 0) {
290         print "No files were entered...";
291     }
292 }
293
294 # forth option: overlay a set of debian packages, which are found & downloaded
295 # using the hosts source.list
296
297 sub add_deblist {
298     our $src;
299     our $input;
300     our $line;
301
302     while(1) {
303         print "Enter a filename containing a list of debian packages\n";
304         print "All packages in this list will be downloaded from your apt\n";
305         print "mirror in /etc/apt/sources.list and unpacked into a minimod\n";
306         print "Make sure you updated using dselect beforehand, please note only ftp repositories are used atm\n";
307         print "> ";
308         chomp($src = <STDIN>);
309         print "\n";
310         if ($src eq "") {
311             last;
312         }       
313         if (!(-e $src)) {
314             print "Can't find $src, lets try again\n";
315             redo;
316         }
317         else {
318             last;
319         }
320     }
321     open(SOURCE, "< $src")
322     or die "Couldn't open $src for reading: $!\n";
323
324     while(defined ($line = <SOURCE>)) {
325         chomp $line;
326         @deblist_list = (@deblist_list,$line);
327     }
328     close(SOURCE);
329 }    
330
331 # fifth option: use a directory as homedir
332
333 sub add_homedir {
334     our $src;
335     our $input;
336
337     while(1) {
338         print "Enter a dir to use as homedirectory, newline to stop\n";
339         print "> ";
340         chomp($src = <STDIN>);
341         print "\n";
342         if ($src eq "") {
343             last;
344         }
345         if (!(-e $src)) {
346             print "Can't find $src, lets try again\n";
347             redo;
348         }
349        
350         $homedir = $src;
351         last;
352     }
353 }
354
355 ### end option section ###
356
357 # gets the list of repositories in /etc/apt/sources.list
358
359 sub get_repos {
360     our @stuff;
361     our $line;
362     open(SOURCE, "< /etc/apt/sources.list")
363     or die "Couldn't open /etc/apt/sources.list for reading: $!\n";
364     print("in repos\n");
365     while(defined ($line = <SOURCE>)) {
366         print("line: $line");
367         chomp $line;
368         if ($line =~ /^\#/ || $line =~ /^deb-src/) {
369             next;
370         }
371         if ($line eq "") {
372             next;
373         }
374         @stuff = $line =~ /^deb ftp:\/\/(\S+) (\S+)/g;
375         if (@stuff ne "") {
376             print @stuff;
377             print ("\nin stuff\n");
378             if (($stuff[0] ne "") && ($stuff[1] ne "")) {
379                 @repolist = (@repolist,$stuff[0]);
380                 @rellist = (@rellist,$stuff[1]);
381             }
382         }
383     }
384     close(SOURCE);
385 }
386
387 # gets the list of packages to be downloaded
388
389 sub download_list {
390     our $package = $_[0];
391     our @filename;
392     our $fileloc = "";
393     our $line;
394     open(SOURCE, "< /var/lib/dpkg/available")
395         or die "Couldn't open /var/lib/dpkg/available for reading: $!\n";
396
397     while(defined ($line = <SOURCE>)) {
398         chomp $line;
399         $filename[0] = "";
400         if ($line eq "Package: $package") {
401             while(defined ($line = <SOURCE>)) {
402         #       print("line is $line\n");
403                 if (@filename = $line =~ /Filename: (\S+)/) {
404                     print("Found $package at $filename[0]!\n");
405                     last;
406                 }
407             }
408         }
409         if ($filename[0] ne "") {
410             last;
411         }   
412     }
413     if ($filename[0] eq "") {
414         print("Couldn't find $package in /var/lib/dpkg/available,\n");
415         print("Make sure you have entered the correct packagename\n");
416         print("in your list file!\n");
417     }
418     return $filename[0];
419 }
420
421 # actually download the debs necessary
422
423 sub download_debs {
424     our $item;
425     our @hostname;
426     our $ftp;
427     our @path;
428     our $foo;
429     our $bar;
430     our $file;
431     our $i;
432
433     foreach $item (@repolist) {
434         print("$item\n");
435         $hostname[0] = "";
436         @hostname = $item =~ /([A-Za-z0-9.]+)/;
437         @path = $item =~ /\/(\S+)/;
438         if ($hostname[0] ne "") {
439             print("Found hostname $hostname[0]");
440             last;
441         }
442     }
443     if ($hostname[0] eq "") {
444         print("Hostname not found!\n");
445         return;
446     }
447     $ftp = Net::FTP->new($hostname[0]) or die "Can't connect: $@\n";
448     $ftp->login("anonymous","anonymous\@abc.com") or die "Couldn't login\n";
449  
450     print("Logged in to $hostname[0]\n");
451     for ($i = 0; $i < scalar(@loclist); $i++) {
452         $ftp->cwd("/$path[0]") or die "Couldn't change directory to /$path[0]\n";
453         print("In /$path[0]\n");
454         print("Downloading $loclist[$i]\n");
455         ($foo,$bar,$file) = File::Spec->splitpath($loclist[$i]);
456         $ftp->binary();
457         $ftp->get($loclist[$i],"$file") or die "Couldn't get $loclist[$i]\n";
458         print("adding $file\n");
459         @localfilelist = (@localfilelist,$file);
460     }
461 }
462
463 sub add_overlay_output {
464     our $overlaytype = $_[0];
465
466         if ($overlaytype == 1) {
467             # symlink/overlay files
468             print OUT "cp -as \"\$1\"/morphix/deb/* /\n";
469         }
470         elsif ($overlaytype == 2) {
471             print OUT "CURR_TRANS=\"\$(cat /proc/sys/translucency/used)\"\n";
472             print OUT "echo \"/ -> \$1/morphix/deb/\" >> /proc/sys/translucency/\$CURR_TRANS\n";
473         }
474         elsif ($overlaytype == 3) {
475             print OUT "OVERLAY=`date +%s`\n";
476             print OUT "OVERLAY=\"/tmp/overlay/\$OVERLAY\"\n";
477             print OUT "mount -t mini_fo -o \"dir=/,dir2=\$OVERLAY\" / \$1/morphix/deb\n";
478         }
479 }
480        
481 sub generate_module {
482     our $minitag = "";
483     our $maintag = "";
484     our $overlaytype = "";
485     our $desc = "";
486     our $basename;
487     our $text;
488     our $input;
489     our $src;
490     our $dest;
491     our $cmd;
492     our $count;
493
494     print "\n";
495     while ($minitag eq "") {
496         print "Enter the /morphix/mini_module tag:\n";
497         print "> ";
498         chomp($minitag = <STDIN>);
499     };
500     $minitag = "$minitag\n";
501     print "\n";
502     print "Enter a description, end with an enter on a blank line:\n";
503     do {
504         $text = <STDIN>;
505         $desc = "$desc$text";
506     } while ($text ne "\n");
507
508     while ($maintag eq ""){
509         local $input;
510
511         print "Select the main module for which this mini module will be generated:\n";
512         print "1) LightGUI\n";
513         print "2) Gnome\n";
514         print "3) KDE\n";
515         print "4) Gamer\n";
516         print "5) Bare\n";
517         print "6) ALL (generic minimodule, works on everything :)\n";
518         print "7) Enter your own\n";
519         print "[1-5] > ";
520         chomp($input = <STDIN>);
521         if ($input == 1) {
522             $maintag = "LightGUI\n";
523         }
524         if ($input == 2) {
525             $maintag = "HeavyGUI\n";
526         }
527         if ($input == 3) {
528             $maintag = "KDE\n";
529         }
530         if ($input == 4) {
531             $maintag = "Gamer\n";
532         }
533         if ($input == 5) {
534             $maintag = "Bare\n";
535         }
536         if ($input == 6) {
537             $maintag = "ALL\n";
538         }
539         if ($input == 7) {
540             while ($maintag eq "") {
541                 print "Enter the /morphix/main_module tag, or ALL for all main modules\nMake sure the tag is exactly correct, otherwise the module won't load! ";
542                 print "> ";
543                 chomp($maintag = <STDIN>);
544             }
545             $maintag = "$maintag\n";
546         }
547     }
548
549     $maintag = "$maintag\n";
550
551    while ($overlaytype eq ""){
552         local $input;
553
554         print "Select the way to overlay files:\n";
555         print "1) Symlink (default, messy but more tested)\n";
556         print "2) Direct-overlay with translucency (for 0.4-versions)\n";
557         print "3) Direct-overlay with mini-fo (for 0.5-versions)\n";
558         print "[1-3] > ";
559         chomp($input = <STDIN>);
560         if ($input == 1) {
561             $overlaytype = 1;
562         }
563         if ($input == 2) {
564             $overlaytype = 2;
565         }
566         if ($input == 3) {
567             $overlaytype = 3;
568         }
569     }
570
571     # generate module
572
573     mkdir ("$moddir/morphix",0755);
574     mkdir ("$moddir/morphix/files",0755);
575     system ("dd if=/dev/urandom of=$moddir/morphix/files/minimum_minimod_size.junk bs=1k count=2");
576     while (($src,$dest) = each(%filelist)) {
577         $basename = (split/\//,$src)[-1];       
578         system("cp -a $src $moddir/morphix/files/$basename");
579     }
580     print "\n";
581     open (OUT, ">$moddir/morphix/loadmod.sh");
582    
583     print OUT "#!/bin/sh\n\#\n# This file has been generated by minimod-gen.pl\n\n";
584     ### the copy option
585
586     while (($src,$dest) = each(%filelist)) {
587         $basename = (split/\//,$src)[-1];
588         print OUT "cp -a \"\$1\"/morphix/files/$basename $dest\n";
589     }
590    
591     ### the cmd/execute option
592
593     foreach $cmd (@cmdlist) {
594         print OUT "$cmd\n";
595     }
596
597     ### the debianpackage list option