r1924: missed adding a few files
[jpeach/samba.git] / packaging / Mandrake / smb-migrate
1 #!/usr/bin/perl
2
3 # migrate old samba2 smb.conf settings to new samba3 setup
4 # as well as merge local configuration settings
5 # Dec 3 2003 Stew Benedict <sbenedict@mandrakesoft.com>
6 # revised Jan 6 2004 - dropping some parameters
7 # revised Feb 11 2004 - don't try to process a config a second time
8
9 # check command line arguments
10 my $numargs = @ARGV;
11 if ($numargs lt 1) {
12         print "useage: smb-migrate test|test-commit|commit\n";
13         exit(1);
14 }
15
16 # define some variables
17 my $user_parms = 0;
18 my $new_conf_file = "/etc/samba/smb.conf";
19 my @new_conf;
20 my $merged_conf_file = "/etc/samba/smb.conf";
21 my $merge_comment = "# *** merged from original smb.conf: ***\n";
22 my $uncomment_comment = "# *** uncommented from original smb.conf: ***\n";
23 my $unique_comment = "# *** unique added from original smb.conf: ***\n";
24 my @merge_log;
25 my $log_file = "/var/log/samba/smb-migrate.log";
26 my $to_merge = "/etc/samba/smb.conf.tomerge";
27
28 if ($ARGV[0] eq "test" || $ARGV[0] eq "test-commit") {
29         $to_merge = "smb.conf"; 
30         $log_file = "smb-migrate.log";
31         $merged_conf_file = "smb.conf.merged";
32 }
33
34 # if the file has already been processed, don't do it again
35 my $processed = `grep -c 'original smb.conf: ***' $to_merge`;
36 if ($processed > 0) {
37         `cp $to_merge $new_conf_file`;
38         print "Already processed, aborting.\n"; 
39         exit 0;
40 }
41         
42 # get the stripped, uncommented data from old smb.conf
43 my @old_conf = `grep -v "^#" $to_merge | grep -v "^;" | grep -v "^\$"` or die;
44
45 # use a clean config file as a starting point
46 `cp /usr/share/samba/smb.conf.clean $new_conf_file` if $ARGV[0] !~ /test/;
47
48 # and the whole new conf file we're going to merge with
49 my @new_conf_org = `cat $new_conf_file` or die;
50
51 mlog("Data to change/add in standard sections of smb.conf:\n\n");
52
53 sub mlog {
54         my (@dstring) = @_;
55         if ($ARGV[0] eq "test") {
56                 print "@dstring";
57         } else {
58                 push @merge_log, @dstring;
59         }
60 }
61
62 sub merge_conf {
63         my ($header, $new_value) = @_;
64         my @parmlist = split " = ", $new_value;
65         my $match = 0;
66         my $comment = '';
67         $comment = $unique_comment if $continuation = 0;
68         $continuation = 1;
69         
70         # find the header in question
71         $index = 0;
72         foreach (@new_conf_org) {
73                 if (/^\[$header\]|;\[$header\]|^; \[$header\]|^\[$header\$\]|;\[$header\$\]|^; \[$header\$\]/) {
74                         # restore print$
75                         $header = "print" . '$' if $header eq "print";
76                         # if the header is commented, remove the comment
77                         if (/^;\[|^#\[|^; \[/) {
78                                 my $entry = $_;
79                                 @new_conf_org[$index] =~ s/^;|^; |^#//g;
80                                 mlog("uncomment: $header line $index: $entry -> @new_conf_org[$index]");
81                                 splice(@new_conf_org, $index, 0, $uncomment_comment);
82                                 $index++
83                         }
84                         $start_loc = $index;
85 #                       print "[$header]: $start_loc\n";
86                         last;
87                 }
88                 $index++
89         }
90         
91         my $elements = @new_conf_org;
92
93         # walk through this header's entries, update as needed
94         for ($i = $start_loc + 1; $i < $elements; $i++) {
95                 # if we hit a new header, may be commented - bail out
96                 my $is_header = @new_conf_org[$i];
97                 $is_header =~ s/^ |\t|\n//;
98                 if ($is_header =~ /^\[|;\[|#\[/) { 
99 #                       print "new header: $is_header at $i\n";
100                         if ($match == 0) {
101                                 # it's possible the parameter is continued across multiple lines
102                                 $continuation = 0 if  $new_value !~ /\\$/;
103                                 # completely new entry, try to place it under the correct header
104 #                               print "new entry for [$header]: $new_value\n";
105                                 mlog("unique: $header line $last_index: $new_value");
106                                 splice(@new_conf_org, $last_index + 1, 0, $comment, $new_value);
107                                 $last_index++;$last_index++;
108                         }
109                         return;
110                 }
111
112                 # some syntax changes
113                 if ($new_value =~ /winbind/) {
114                         $old_value = $new_value; 
115                         $new_value =~ s/winbind/idmap/;
116                         mlog("syntax: $header: $old_value -> $new_value");
117                 }
118
119                 # partial match, decide whether to add or replace
120                 if (@new_conf_org[$i] =~ /@parmlist[0]/) {
121                         if (@new_conf_org[$i] !~ /^;|^#/) {
122                                 if (@new_conf_org[$i] ne $_) { 
123                                         mlog("update: $header line $i: @new_conf_org[$i] -> $new_value");
124                                         @new_conf_org[$i] = ";" . $new_conf_org[$i];
125                                         splice(@new_conf_org, $i + 1, 0, $merge_comment, $new_value);
126 #                                       $match = 1;
127                                 }
128                                 $match = 1;
129                         } else {
130                                 # is it really a definition or just a comment?
131                                 if (@new_conf_org[$i] =~ / = /) {
132                                         # commented in new config, add the old entry
133                                         mlog("add: $header line $i: @new_conf_org[$i] -> $new_value");
134                                         splice(@new_conf_org, $i + 1, 0, $merge_comment, $new_value);
135                                         $i++;$i++;
136                                         $match = 1;
137                                 }
138                         }
139 #                       $match = 1 if $new_value eq @new_conf_org[$i];
140                         $last_index = $i;
141                         return if ($match eq 1);
142                         $match = 0;
143                 }       
144         }
145         return;
146 }
147
148 foreach (@old_conf) {
149         # check for section headers
150         if (/^\[/) {
151                 # standard headers?
152                 if (!/^\[global\]|^\[homes\]|^\[netlogon\]|^\[Profiles\]|^\[printers\]|^\[print\$\]|^\[pdf-generator\]/) {
153                         # non-standard - add to new config
154                         $user_parms = 1;
155                         push (@new_conf, $_);
156                 } else {
157                         $user_parms = 0;
158                         chop;
159                         $header = $_;
160                         s/\[|\]|\$//g;
161                         $bare_header = $_;
162                 }
163         } else {
164                 # non-standard - add to new config
165                 if ($user_parms == 1) {
166                         push (@new_conf, $_);
167                 } else {
168                         # now we're working with standard settings
169                         # update new config with values if they differ or are commented out
170                         # translate any old nomenclature to the new style
171                         # may still be some commented lines buried
172                         # throw those out and try to merge into new config
173                         if (!/^[ ]+#|^[ ]+;|^#|^;/) {
174 #                               print "$header: $_\n";
175                                 merge_conf($bare_header, $_);
176                         }
177                 }
178         }
179 }
180
181 # write the user config data to new smb.conf
182
183 mlog("\nNew data for smb.conf:\n\n");
184 mlog("@new_conf");
185
186 if ($ARGV[0] eq "commit" || $ARGV[0] eq "test-commit") {
187         local *NEWCONF;
188         open(NEWCONF, "> $merged_conf_file");
189         print NEWCONF @new_conf_org;
190         print NEWCONF @new_conf;
191         close NEWCONF;
192         local *LOGFILE;
193         open(LOGFILE, "> $log_file");
194         print LOGFILE @merge_log;
195         close LOGFILE
196 }
197