source: src/router/proftpd/src/prxs @ 17876

Last change on this file since 17876 was 17876, checked in by BrainSlayer, 19 months ago

update proftp

File size: 7.6 KB
Line 
1#!/usr/bin/env perl
2
3# ---------------------------------------------------------------------------
4# Copyright (C) 2008-2011 TJ Saunders <tj@castaglia.org>
5#
6# This program is free software; you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation; either version 2 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program; if not, write to the Free Software
18# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
19#
20#  $Id: prxs.in,v 1.7 2011/05/23 21:25:44 castaglia Exp $
21# ---------------------------------------------------------------------------
22
23use strict;
24
25use File::Basename qw(basename);
26use Getopt::Long;
27
28Getopt::Long::Configure("no_ignorecase");
29
30my $prog = basename($0);
31
32my $compiler = q(arm-linux-uclibc-gcc);
33my $cflags = q( -DLINUX -Os -pipe -march=armv6k -mtune=mpcore -mfloat-abi=softfp -mfpu=vfp -fno-caller-saves -Wall -DPR_SHARED_MODULE);
34my $cppflags = q();
35my $ltdl_ldflags = q();
36my $sbindir = q(/tmp/proftpd/sbin);
37my $includedir = q(/tmp/proftpd/include);
38my $installer = q(/usr/bin/install -c);
39my $install_strip = q(-s);
40my $libexecdir = q(/tmp/proftpd/libexec);
41my $libtool = 'libtool';
42
43if (!defined($ENV{LIBTOOL})) {
44  if ($^O eq 'darwin') {
45    $libtool = 'glibtool';
46  }
47
48} else {
49  $libtool = $ENV{LIBTOOL};
50}
51
52my $opts = {};
53GetOptions($opts, 'c|compile', 'i|install', 'd|clean', 'h|help', 'name=s',
54  'D=s@', 'I=s@', 'L=s@', 'l=s@', 'W=s@');
55
56if ($opts->{h}) {
57  usage();
58  exit 0;
59}
60
61# Make sure we can query proftpd to find out its list of installed modules.
62# Unless we see mod_dso listed, there's no point in compiling a shared
63# module for proftpd to use.
64
65my $proftpd = "$sbindir/proftpd";
66unless (-x $proftpd) {
67  print STDERR "$proftpd not found or not executable\n";
68  exit 1;
69}
70
71unless (grep /mod_dso/, `$proftpd -l`) {
72  print STDERR "\nYour installed proftpd does not support shared modules/DSOs.\n";
73  print STDERR "Make sure the --enable-dso configure option is used when\n";
74  print STDERR "compiling proftpd.\n\n";
75  exit 1;
76}
77
78# Now, depending on the requested mode (compile/install/clean), build up
79# and execute the commands.
80
81my $mod_name = get_module_name();
82
83if (defined($opts->{c})) {
84  my $srcs = [];
85  my $objs = [];
86
87  foreach my $file (@ARGV) {
88    if ($file =~ /\.c$/) {
89      push(@$srcs, $file);
90
91      my $obj = $file;
92      $obj =~ s/\.c$/\.lo/;
93      push(@$objs, $obj);
94
95    } else {
96      print STDERR "Cannot compile non-.c file $file, aborting\n";
97      exit 1;
98    }
99  }
100
101  foreach my $def (@{ $opts->{D} }) {
102    if ($def =~ /^(\S+)=(\S+)$/) {
103      $cflags .= " -D'$1=$2'";
104
105    } else {
106      $cflags .= " -D$def";
107    }
108  }
109
110  $cflags .= " -I. -I$includedir/proftpd";
111
112  foreach my $incdir (@{ $opts->{I} }) {
113    $cflags .= " -I$incdir";
114  }
115
116  my $cmds = [];
117  foreach my $src (@$srcs) {
118    push(@$cmds, "$libtool --mode=compile $compiler $cflags -c $src");
119  }
120
121  run_cmds($cmds);
122
123  my $objlist = '';
124  foreach my $obj (@$objs) {
125    $objlist .= " $obj";
126  }
127
128  my $ldflags .= " $ltdl_ldflags";
129
130  foreach my $libdir (@{ $opts->{L} }) {
131    $ldflags .= " -L$libdir";
132  }
133
134  # Scan through the .c files, looking for the $Libraries$ hint that
135  # proftpd's build system uses.
136  foreach my $src (@$srcs) {
137    if (open(my $fh, "< $src")) {
138      while (my $line = <$fh>) {
139        chomp($line);
140
141        if ($line =~ /\$Libraries:\s+(.*)?\$/) {
142          my $hint = $1;
143
144          # Assume that the library hint list is space-separated; add them
145          # to the $opts hashref.  Don't forget to strip of the '-l' prefix;
146          # that is added back later in the handling of $opts.
147          my $libs = [split(/\s+/, $hint)];
148          foreach my $lib (@$libs) {
149            $lib =~ s/^\-l//;
150            push(@{ $opts->{l} }, $lib);
151          }
152
153          last;
154        }
155      }
156
157      close($fh);
158
159    } else {
160      print STDERR "Unable to scan $src for \$Libraries\$ hint: $!\n";
161    }
162  }
163
164  my $libs = "";
165  foreach my $lib (@{ $opts->{l} }) {
166    $libs .= " -l$lib";
167  }
168
169  $cmds = [];
170  push(@$cmds, "$libtool --mode=link $compiler -o $mod_name.la -rpath $libexecdir $ldflags $objlist $libs");
171
172  run_cmds($cmds);
173}
174
175if (defined($opts->{i})) {
176  my $cmds = [];
177  push(@$cmds, "$libtool --mode=install $installer $install_strip $mod_name.la $ENV{DESTDIR}$libexecdir");
178
179  run_cmds($cmds);
180
181  # Don't forget to remind the user to manually edit their proftpd.conf
182  # and add the LoadModule to load the just-installed module.
183
184  print STDOUT "\nTo load your newly installed module into proftpd, be sure\n";
185  print STDOUT "to edit your proftpd.conf and add the following:\n\n";
186  print STDOUT "  <IfModule mod_dso.c>\n";
187  print STDOUT "    LoadModule $mod_name.c\n";
188  print STDOUT "  </IfModule>\n\n";
189  print STDOUT "and then restart your proftpd server, so that the config change\n";
190  print STDOUT "becomes live.\n\n";
191}
192
193if (defined($opts->{d})) {
194  my $cmds = [];
195  push(@$cmds, "$libtool --mode=clean rm -f $mod_name.la *.lo");
196
197  run_cmds($cmds);
198}
199
200if (!defined($opts->{c}) &&
201    !defined($opts->{i}) &&
202    !defined($opts->{d})) {
203  print STDERR "No compile, install, or clean mode requested, exiting\n";
204  exit 1;
205}
206
207exit 0;
208
209sub get_module_name {
210  # Determine the name of the module (e.g. "mod_foo") being operated upon.
211  if (defined($opts->{n})) {
212    return $opts->{n};
213  }
214
215  foreach my $file (@ARGV) {
216    if ($file =~ /^mod_(\S+)\.(c|la)$/) {
217      return "mod_$1";
218    }
219  }
220
221  return "mod_unknown";
222}
223
224sub run_cmds {
225  my $cmds = shift;
226
227  foreach my $cmd (@$cmds) {
228    print STDOUT "$cmd\n";
229
230    my $res = system($cmd);
231    if ($res) {
232      print STDERR "$prog: error executing command (", $res >> 8, ")\n";
233      exit 1;
234    }
235  }
236}
237
238sub usage {
239  my $prog = basename($0);
240
241  print STDOUT <<EOU;
242
243usage: $prog <action> <opts> <source files>
244
245Actions:
246
247 -c, --compile          Compiles the listed .c source files into a proftpd
248                        DSO module.
249
250 -i, --install          Installs a compiled proftpd DSO module into the
251                        directory where proftpd expects to find loadable
252                        DSO modules.
253
254 -d, --clean            Removes any generated files, returning the build
255                        directory to a clean state.
256
257Options:
258
259 -h, --help             Displays this message.
260
261 -n, --name             Tells prxs the name of the module being compiled.
262                        By default, prxs determines the module name from
263                        the list of .c files listed, expecting to see a
264                        "mod_\$name.c" file.
265
266 -D key                 Passes these macros through to the compilation step.
267 -D key=value           Note that the space before the key is important.
268
269 -I includedir          Specify additional include file search directories.
270                        Note that the space before the directory is important.
271
272 -L libdir              Specify additional library file search directories.
273                        Note that the space before the directory is important.
274
275 -l library             Specify additional libraries for linking.
276                        Note that the space before the library name is important.
277
278At least one of the above actions must be specified when using prxs.  More
279than one action can be specified at the same time.
280
281To use prxs all in one step, you could do:
282
283  prxs -c -i -d mod_custom.c
284
285EOU
286}
Note: See TracBrowser for help on using the repository browser.