GPL license address update (mentioned by Guillermo Gomez)
[fwsnort.git] / packaging / cd_rpmbuilder
1 #!/usr/bin/perl -w
2 #
3 #############################################################################
4 #
5 # File: cd_rpmbuilder "CipherDyne Rpm Builder"
6 #
7 # Purpose: Provides a consistent way to build RPMs of CipherDyne open source
8 #          projects (psad, fwsnort, fwsknop, and gpgdir).
9 #
10 # Author: Michael Rash
11 #
12 # Copyright (C) 2006-2008 Michael Rash (mbr@cipherdyne.org)
13 #
14 # License (GNU Public License - GPLv2):
15 #
16 #    This program is distributed in the hope that it will be useful,
17 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
18 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 #    GNU General Public License for more details.
20 #
21 #    You should have received a copy of the GNU General Public License
22 #    along with this program; if not, write to the Free Software
23 #    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
24 #    USA
25 #
26 #############################################################################
27 #
28
29 use File::Find;
30 use File::Copy;
31 use Getopt::Long 'GetOptions';
32 use strict;
33
34 #============================ config =============================
35 my $rpm_root_dir   = '/usr/src/redhat';
36 my $build_url_base = 'http://www.cipherdyne.org';
37
38 ### commands
39 my $rpmbuildCmd = '/usr/bin/rpmbuild';
40 my $wgetCmd     = '/usr/bin/wget';
41 #========================== end config ===========================
42
43 my $version = '0.9';
44
45 my $project = '';
46 my $build_version = '';
47 my $print_version = 0;
48 my $nodeps = 0;
49 my $verbose = 0;
50 my $help = 0;
51
52 my @rpm_paths = ();
53
54 my $RM    = 1;
55 my $PRINT = 2;
56
57 my %projects = (
58     'psad'    => '',
59     'fwknop'  => '',
60     'fwsnort' => '',
61     'gpgdir'  => ''
62 );
63
64 Getopt::Long::Configure('no_ignore_case');
65 &usage() unless (GetOptions(
66     'project=s' => \$project,
67     'build-version=s' => \$build_version,
68     'rpm-build-dir=s' => \$rpm_root_dir,
69     'no-deps' => \$nodeps,
70     'verbose' => \$verbose,
71     'Version' => \$print_version,
72     'help'    => \$help
73 ));
74 &usage() if $help;
75
76 if ($print_version) {
77     print "[+] cd_rpmbuilder by Michael Rash <mbr\@cipherdyne.org>\n";
78     exit 0;
79 }
80
81 if ($project) {
82     unless (defined $projects{$project}) {
83         print "[*] Unrecognized project: $project; must be one of:\n";
84         print $_, "\n" for keys %projects;
85         exit 1;
86     }
87 } else {
88     die "[*] Must specify a project with -p <project>\n";
89 }
90
91 die "[*] $wgetCmd is not a valid path to wget, update the config section."
92     unless -x $wgetCmd;
93 die "[*] $rpmbuildCmd is not a valid path to rpmbuild, update the config " .
94     "section." unless -x $rpmbuildCmd;
95
96 chdir "$rpm_root_dir/SPECS" or die "[*] Could not chdir $rpm_root_dir/SPECS";
97
98 unless ($build_version) {
99     ### we need to get the latest version from cipherdyne.org
100     &get_latest_version();
101 }
102
103 my $spec_file = "$project-$build_version.spec";
104 my $tar_file  = "$project-$build_version.tar.gz";
105
106 if ($nodeps) {
107     $spec_file = "$project-nodeps-$build_version.spec";
108     $tar_file  = "$project-nodeps-$build_version.tar.gz";
109 }
110
111 ### remove old RPMS
112 &find_rpms($RM);
113
114 ### get the remote spec file
115 &download_file($spec_file);
116 &md5_check($spec_file);
117
118 ### get the remote source tarball and md5 sum file
119 &download_file($tar_file);
120 &md5_check($tar_file);
121
122 if ($nodeps) {
123     move $tar_file, "../SOURCES/$project-$build_version.tar.gz" or die $!;
124 } else {
125     move $tar_file, '../SOURCES' or die $!;
126 }
127
128 ### build the rpm
129 &build_rpm();
130
131 ### print the paths to the new RPMS
132 &find_rpms($PRINT);
133
134 exit 0;
135 #======================= end main ========================
136
137 sub find_rpms() {
138     my $action = shift;
139     @rpm_paths = ();
140     find(\&get_rpms, "$rpm_root_dir/SRPMS");
141     find(\&get_rpms, "$rpm_root_dir/RPMS");
142     if ($action == $PRINT) {
143         if (@rpm_paths) {
144             print "[+] The following RPMS were successfully built:\n\n";
145         } else {
146             print "[-] No RPMS were successfully built; try running ",
147                 "with --verbose\n";
148         }
149     }
150     for my $rpm_file (@rpm_paths) {
151         if ($action == $RM) {
152             unlink $rpm_file or die "[*] Could not unlink $rpm_file: $!";
153         } elsif ($action == $PRINT) {
154             if ($rpm_file =~ /\.src\.rpm/) {
155                 print "      $rpm_file (source RPM)\n";
156             } else {
157                 print "      $rpm_file\n";
158             }
159         }
160     }
161     print "\n" if $action == $PRINT;
162     return;
163 }
164
165 sub get_rpms() {
166     my $file = $File::Find::name;
167     if ($file =~ /$project-$build_version-.*\.rpm$/) {
168         push @rpm_paths, $file;
169     }
170     return;
171 }
172
173 sub download_file() {
174     my $file = shift;
175     unlink $file if -e $file;
176     print "[+] Downloading file:\n",
177         "      $build_url_base/$project/download/$file\n";
178     my $cmd = "$wgetCmd $build_url_base/$project/download/$file";
179     unless ($verbose) {
180         $cmd .= ' > /dev/null 2>&1';
181     }
182     system $cmd;
183     die "[*] Could not download $file, try running with -v"
184         unless -e $file;
185     return;
186
187 }
188
189 sub md5_check() {
190     my $file = shift;
191     &download_file("$file.md5");
192     ### check MD5 sum
193     open MD5, "md5sum -c $file.md5 |"
194         or die $!;
195     my $sum_line = <MD5>;
196     close MD5;
197     unless ($sum_line =~ m/$file:\s+OK/) {
198         die "[*] MD5 sum check failed for $file, ",
199             "exiting.";
200     }
201     print "[+] Valid md5 sum check for $file\n";
202     unlink "$file.md5";
203     return;
204 }
205
206 sub build_rpm() {
207     print
208 "[+] Building RPM, this may take a little while (try -v if you want\n",
209 "    to see all of the steps)...\n\n";
210     my $cmd = "$rpmbuildCmd -ba $spec_file";
211     unless ($verbose) {
212         $cmd .= ' > /dev/null 2>&1';
213     }
214     system $cmd;
215     return;
216 }
217
218 sub get_latest_version() {
219     unlink "$project-latest" if -e "$project-latest";
220     print "[+] Getting latest version file:\n",
221         "      $build_url_base/$project/$project-latest\n";
222     my $cmd = "$wgetCmd $build_url_base/$project/$project-latest";
223     unless ($verbose) {
224         $cmd .= ' > /dev/null 2>&1';
225     }
226     system $cmd;
227     open F, "< $project-latest" or
228             die "[*] Could not open $project-latest: $!";
229     my $line = <F>;
230     close F;
231     chomp $line;
232     $build_version = $line;
233     die "[*] Could not get build version" unless $build_version;
234     unlink "$project-latest" if -e "$project-latest";
235     return;
236 }
237
238 sub usage() {
239     print <<_HELP_;
240
241 cd_rpmbuilder; the CipherDyne RPM builder
242 [+] Version: $version
243 [+] By Michael Rash (mbr\@cipherdyne.org, http://www.cipherdyne.org)
244
245 Usage: cd_rpmbuilder -p <project> [options]
246
247 Options:
248     -p, --project <name>       - This can be one of "psad", "fwknop",
249                                  "gpgdir", or "fwsnort".
250     -b, --build-version <ver>  - Build a specific project version.
251     -r, --rpm-build-dir <dir>  - Change the RPM build directory from the
252                                  default of $rpm_root_dir.
253     -n, --no-deps              - Build the specified project without any
254                                  dependencies (such as perl modules).
255     -v, --verbose              - Run in verbose mode.
256     -V, --Version              - Print version and exit.
257     -h, --help                 - Display usage information.
258 _HELP_
259     exit 0;
260 }