Moving Files around (removing file endings, libraries to lib)
[darcs-mirror-metainit.git] / arrange-sysvinit
1 #!/usr/bin/perl
2
3 use strict;
4 use warnings;
5
6 use lib './lib';
7 use MetaInit::Parse;
8
9 my $metainit_path = "./examples";
10 my $etc = "./etc";
11
12 my @new_scripts = @ARGV;
13
14 my %facilities = (
15         '$local_fs'  => 0,
16         '$network'   => 0,
17         '$named'     => 15,
18         '$portmap'   => 18,
19         '$remote_fs' => 21,
20         '$syslog'    => 10,
21         '$time'      => 0,
22 );
23
24 # Read in all meta-init scripts
25 my @metainit_files = <$metainit_path/*.metainit>;
26
27 my %metainits;
28
29 for my $metainit_file (@metainit_files) {
30         my $data = MetaInit::Parse::parse($metainit_file);
31         $metainits{$data->{Name}} = $data;
32 }
33
34
35 # Locate existing scripts
36 # We check for existing scripts only in /etc/rc2.d
37
38 my %startscripts;
39 for my $rc_file (<$etc/rc2.d/S??*>) {
40         my ($num, $name) = $rc_file =~ m!S(\d\d)([^/]+)!;
41         $startscripts{$name} = $num;
42 }
43
44
45 # Sort the scripts to existing and non-existing scripts
46 my @existing;
47 my @new;
48
49 for my $metainit (keys %metainits) {
50         if (exists $startscripts{$metainit}) {
51                 push @existing, $metainit;
52         } else {
53                 push @new, $metainit;
54         }
55 }
56
57 # Actually, we only want to treat the passed scripts as new
58 @new = @new_scripts;
59
60         
61 # Check the dependencies for existing scripts
62
63 for my $existing (@existing) {
64         my @deps = @{$metainits{$existing}{"Required-Start"}};
65         for my $dep (@deps) {
66                 if (exists $startscripts{$dep}) {
67                         if ($startscripts{$dep} >= $startscripts{$existing}) {
68                                 warn "Late dependency $dep of $existing.\n"
69                         }
70                 } elsif (exists $facilities{$dep}) {
71                         if ($facilities{$dep} >= $startscripts{$existing}) {
72                                 warn "Late facility $dep of $existing.\n"
73                         }
74                 } elsif (not exists $startscripts{$dep}){
75                         # Nothing to do here
76                 } else {
77                         
78                         warn "Unkown dependency $dep of $existing.\n";
79                 }
80         }
81
82 }
83
84 my @processed = ();
85
86 while (@new > 0) {
87         # Check Bounds 
88
89         my %lower;
90         my %upper;
91
92         for my $existing (@existing) {
93                 my @deps = @{$metainits{$existing}{"Required-Start"}};
94                 for my $dep (@deps) {
95                         if (exists $startscripts{$dep}){
96                                 $upper{$dep} = min($startscripts{$existing}, $upper{$dep})
97                         }
98                 }
99         }
100
101         for my $new (@new) {
102                 my @deps = @{$metainits{$new}{"Required-Start"}};
103                 for my $dep (@deps) {
104                         if (not exists $startscripts{$dep}){
105                                 $lower{$new} = $startscripts{$dep};
106                                 $lower{$new} = max($startscripts{$dep}, $lower{$new})
107                         }
108                 }
109         }
110
111         # Put a new scripts at appropriate location
112         my $current = pop @new;
113
114         # Standard case:
115         if (($lower{$current}||0) > ($upper{$current}||99)) {
116                 warn "Could not correctly fit in $current, please reorder manually.\n";
117                 $startscripts{$current} = $lower{$current}||10 + 10;
118                 push @processed, $current;
119                 push @existing,  $current;
120         } elsif (($lower{$current}||0 < 20) and not defined $upper{$current}) {
121                 $startscripts{$current} = 20;
122                 push @processed, $current;
123                 push @existing,  $current;
124         } else {
125                 $startscripts{$current} = mid($lower{$current}, $upper{$current});
126         }
127
128 }
129
130 for my $done (@processed) {
131         printf "%s %02d\n", $done, $startscripts{$done}
132 }
133
134
135 sub max {
136         return $_[1] if (defined $_[1] and $_[0] < $_[1]);
137         return $_[0]
138 }
139 sub min {
140         return $_[1] if (defined $_[1] and $_[0] > $_[1]);
141         return $_[0]
142 }
143 sub mid {
144         my ($a,$b) = @_;
145         return int(($a+$b)/2);
146 }