r79: update changeloga za 2.4.3.
[carnet-tools-cn.git] / cp-update.old
1 #! /usr/bin/perl -w
2
3 ## Copyright (C) 1998 Hrvoje Niksic
4 ## Modification by Zeljko Boros (block entries, removing old entries)
5 ## More options and use strict by Zoran Dzelajlija on 2004-02-24
6 ##
7 ## This program is free software; you can redistribute it and/or modify
8 ## it under the terms of the GNU General Public License as published by
9 ## the Free Software Foundation; either version 2 of the License, or
10 ## (at your option) any later version.
11 ##
12 ## This program is distributed in the hope that it will be useful,
13 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
14 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 ## GNU General Public License for more details.
16 ##
17 ## You should have received a copy of the GNU General Public License
18 ## along with this program; if not, write to the Free Software
19 ## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21 ## $Id: cp-update,v 2.2 2004/02/24 jelly Exp $
22
23 use strict;
24
25 my ($name, $usage);
26
27 ($name = $0) =~ s%.*/%%;   # Looks nicer without the slashes
28 $usage =  "Usage:\n";
29 $usage .= "$name [-r] [-m] [-i AFTER|-t] [-b START -e STOP] [-c CHAR] PACKAGE FILE\n";
30 $usage .= "                 -r   Remove entry PACKAGE from FILE\n";
31 $usage .= "                      Default is to add lines from stdin.\n";
32 $usage .= "                 -m   Allow multiple blocks of the same type\n";
33 $usage .= "                      By default, old blocks are replaced with the new one.\n";
34 $usage .= "\n";
35 $usage .= "                      Special placement of config blocks:\n";
36 $usage .= "                 -i   Insert after this line\n";
37 $usage .= "                 -t   Insert on top\n";
38 $usage .= "                      The default is to append at the bottom.\n";
39 $usage .= "\n";
40 $usage .= "                      Manipulating block marks:\n";
41 $usage .= "                 -c   Use alternative comment character (default: #)\n";
42 $usage .= "                      Alternative block marks:\n";
43 $usage .= "                 -b   Start mark (ie 'service ftp')\n";
44 $usage .= "                 -e   Stop mark (ie. '}')\n";
45 $usage .= "                      These will delete to the end of the file if no end mark\n";
46 $usage .= "                      is found.  The deletion is otherwise not greedy and\n";
47 $usage .= "                      stops at the first end mark found.  You can use\n";
48 $usage .= "                      %P to insert the PACKAGE argument, and\n";
49 $usage .= "                      %% to insert a literal % sign into the mark.\n";
50
51
52
53
54 my ($begin, $end, $trailer);
55 my ($parambegin, $paramend, $insert);
56 my ($pkg, $file);
57 my ($block, $multi, $addafter, $addontop);
58
59 my $add = 1;
60 my $comment = "#";
61 my $SEEK_END = 2;
62
63 while (@ARGV)
64 {
65     $_ = shift;
66     if (/^-c$/ || /^--comment$/)
67     {
68         defined ($comment = shift)
69             || die "$name: `-c' must be followed by an argument\n";
70     }
71     elsif (/^-r$/ || /^--remove$/)
72     {
73         $add = 0;
74     }
75     elsif (/^-m$/ || /^--allow-multiple$/)
76     {
77         $multi = 1;
78     }
79     elsif (/^-b$/ || /^--begin$/)
80     {
81         defined ($parambegin = shift)
82             || die "$name: '-b' must be followed by an argument\n";
83         $block = 1;
84     }
85     elsif (/^-e$/ || /^--end$/)
86     {
87         defined ($paramend = shift)
88         || die "$name: '-e' must be followed by an argument\n";
89         $block = 1;
90     }
91     elsif (/^-i$/ || /^--insert-after$/)
92     {
93         defined($insert = shift)
94         || die "$name: '-i' must be followed by an anrgument\n";
95         #$multi = 1;  # uncomment for -i backward compatibility
96         $addafter = 1;
97     }
98     elsif (/^-t$/ || /^--insert-on-top$/)
99     {
100         $insert = "";
101         $addafter = 1;
102     }
103     elsif (/^-/)
104     {
105         die "$name: Unrecognized option \`$_'\n";
106     }
107     else
108     {
109         unshift(@ARGV, $_);
110         last;
111     }
112 }
113
114 ($pkg = shift)  || die $usage;
115 ($file = shift) || die $usage;
116 (! $block || ($parambegin && $paramend))
117     || die ("$name: must provide both begin and end marks.\n");
118
119 if ($block)
120 {
121     $parambegin =~ s,%P,$pkg,g;
122     $parambegin =~ s,%%,%,g;
123     $paramend =~ s,%P,$pkg,g;
124     $paramend =~ s,%%,%,g;
125     $begin = $parambegin;
126     $end = $paramend;
127     $trailer = "";
128 }
129 else
130 {
131     $begin   = "$comment Begin update by CARNet package $pkg";
132     $end     = "$comment End update by CARNet package $pkg";
133     $trailer = " -- DO NOT DELETE THIS LINE!";
134 }
135
136 if ($add)
137 {
138     if (! $multi)
139     {
140         &del;
141     }
142     &add;
143 }
144 else
145 {
146     &del;
147 }
148
149 sub add() {
150     $trailer .= "\n";
151     $begin   .= $trailer;
152     $end     .= $trailer;
153     my $byte = "";         # @#$@#$@#$$@#$@#$#@$! -w
154     my $prefix = "";
155
156     open (HANDLE, "<$file") || die "$file: $!\n";
157
158     # Need to load it all into memory if we want to write it
159     # out to the same file.
160     my @lines = <HANDLE> if ($addafter);
161
162     # If FILE does not have a trailing newline, be suire to add it
163     # before appending anything else.
164
165     # Unless it is size 0!
166     if ((-s $file))
167     {
168         seek HANDLE, -1, $SEEK_END;
169         defined (read HANDLE, $byte, 1) && ($byte ne "\n") && ($prefix = "\n");
170         close HANDLE;
171     }
172
173     if(!$addafter)
174     {
175         # The actual work is in the following three lines:
176         open (HANDLE, ">>$file") || die "$file: $!\n";
177         print HANDLE $prefix . $begin . join('', <STDIN>) . $end;
178         close HANDLE;
179     }
180     else
181     {
182         # Overwrite it
183         open (HANDLE, ">$file") || die "$file: $!\n";
184         my $added = 0;
185         foreach (@lines)
186         {
187             if (! $added && /^$insert/o)
188             {
189                 print HANDLE if ($insert ne ""); 
190                 print HANDLE $begin . join('', <STDIN>) . $end;
191                 print HANDLE if ($insert eq "");
192                 $added = 1;
193             }
194             else
195             {
196                 print HANDLE;
197             }
198         }
199         if(! $added)
200         {
201             print HANDLE $prefix . $begin . join('', <STDIN>) . $end;
202         }
203         close HANDLE;
204     }
205 }
206
207 sub del() {
208     # saving vars for &add function...
209     my ($mybegin, $myend, $mytrailer);
210
211     $mybegin = $begin;
212     $myend = $end;
213     $mytrailer = $trailer;
214
215     # Make the strings regexp-friendly by quoting non-word chars.
216     $mybegin   =~ s/\W/\\$&/g;
217     $myend     =~ s/\W/\\$&/g;
218     $mytrailer =~ s/\W/\\$&/g;
219     open (HANDLE, "<$file") || die "$file: $!\n";
220     # Need to load it all into memory, because we'll want to write it
221     # out to the same file.
222     my @lines = <HANDLE>;
223     close HANDLE;
224     open (HANDLE, ">$file") || die "$file: $!\n";
225     foreach (@lines)
226     {
227         print HANDLE unless (/^$mybegin(?:$mytrailer)?$/o
228                           .. /^$myend(?:$mytrailer)?$/o);
229     }
230     close HANDLE;
231 }