This file is indexed.

/usr/bin/prxs is in proftpd-dev 1.3.5~rc3-2.1ubuntu2.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
#!/usr/bin/env perl

# ---------------------------------------------------------------------------
# Copyright (C) 2008-2012 TJ Saunders <tj@castaglia.org>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
#
#  $Id: prxs.in,v 1.10 2012/09/19 00:11:39 castaglia Exp $
# ---------------------------------------------------------------------------

use strict;

use File::Basename qw(basename);
use Getopt::Long;

Getopt::Long::Configure("no_ignorecase");

my $prog = basename($0);

my $compiler = q(gcc);
my $cflags = q( -DLINUX -g -O2 -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security -Wall -DPR_SHARED_MODULE);
my $cppflags = q(-D_FORTIFY_SOURCE=2);
my $ltdl_ldflags = q(-avoid-version -export-dynamic -module);
my $sbindir = q(/usr/sbin);
my $includedir = q(/usr/include);
my $installer = q(/usr/bin/install -c);
my $install_strip = q(-s);
my $libexecdir = q(/usr/lib/proftpd);
my $libtool = 'libtool';

if (!defined($ENV{LIBTOOL})) {
  if ($^O eq 'darwin') {
    $libtool = 'glibtool';
  }

} else {
  $libtool = $ENV{LIBTOOL};
}

my $opts = {};
GetOptions($opts, 'c|compile', 'i|install', 'd|clean', 'h|help', 'name=s',
  'D=s@', 'I=s@', 'L=s@', 'l=s@', 'W=s@');

if ($opts->{h}) {
  usage();
  exit 0;
}

# Make sure we can query proftpd to find out its list of installed modules.
# Unless we see mod_dso listed, there's no point in compiling a shared
# module for proftpd to use.

my $proftpd = "$sbindir/proftpd";
unless (-x $proftpd) {
  print STDERR "$proftpd not found or not executable\n";
  exit 1;
}

unless (grep /mod_dso/, `$proftpd -l`) {
  print STDERR "\nYour installed proftpd does not support shared modules/DSOs.\n";
  print STDERR "Make sure the --enable-dso configure option is used when\n";
  print STDERR "compiling proftpd.\n\n";
  exit 1;
}

# If the libtool-specific linker flags are empty, it means that the
# script was generated by a configure script lacking the --enable-dso option.
unless (length($ltdl_ldflags) > 0) {
  print STDERR "\nMissing the required libtool flags.\n";
  print STDERR "Make sure the --enable-dso configure option is used when\n";
  print STDERR "compiling proftpd.\n\n";
  exit 1;
}

# Now, depending on the requested mode (compile/install/clean), build up
# and execute the commands.

my $mod_name = get_module_name();

if (defined($opts->{c})) {
  my $srcs = [];
  my $objs = [];

  my $configure_script;

  foreach my $file (@ARGV) {
    if ($file =~ /\.c$/) {
      push(@$srcs, $file);

      if ($file =~ /\/?mod_[^\/]+\.c$/) {
        $configure_script = $file;
        $configure_script =~ s/\/?mod_[^\/]+\.c$/\/configure/;
      }

      my $obj = $file;
      $obj =~ s/\.c$/\.lo/;

      # Handle an argument such as 'contrib/mod_sql_sqlite.c' by keeping
      # just the name portion of the path.
      $obj =~ s/^(.*)\///g;

      push(@$objs, $obj);

    } else {
      print STDERR "Cannot compile non-.c file $file, aborting\n";
      exit 1;
    }
  }

  if (defined($configure_script)) {
    # Check for any configure script for this module.  If present, error out
    # for now.
    if (-f $configure_script) {
      print STDERR "Cannot compile $mod_name using prxs; use $configure_script instead\n";
      exit 1;
    }
  }

  foreach my $def (@{ $opts->{D} }) {
    if ($def =~ /^(\S+)=(\S+)$/) {
      $cflags .= " -D'$1=$2'";

    } else {
      $cflags .= " -D$def";
    }
  }

  $cflags .= " -I. -I$includedir/proftpd";

  foreach my $incdir (@{ $opts->{I} }) {
    $cflags .= " -I$incdir";
  }

  my $cmds = [];
  foreach my $src (@$srcs) {
    push(@$cmds, "$libtool --mode=compile $compiler $cflags -c $src");
  }

  run_cmds($cmds);

  my $objlist = '';
  foreach my $obj (@$objs) {
    $objlist .= " $obj";
  }

  my $ldflags .= " $ltdl_ldflags";

  foreach my $libdir (@{ $opts->{L} }) {
    $ldflags .= " -L$libdir";
  }

  # Scan through the .c files, looking for the $Libraries$ hint that
  # proftpd's build system uses.
  foreach my $src (@$srcs) {
    if (open(my $fh, "< $src")) {
      while (my $line = <$fh>) {
        chomp($line);

        if ($line =~ /\$Libraries:\s+(.*)?\$/) {
          my $hint = $1;

          # Assume that the library hint list is space-separated; add them
          # to the $opts hashref.  Don't forget to strip of the '-l' prefix;
          # that is added back later in the handling of $opts.
          my $libs = [split(/\s+/, $hint)];
          foreach my $lib (@$libs) {
            $lib =~ s/^\-l//;
            push(@{ $opts->{l} }, $lib);
          }

          last;
        }
      }

      close($fh);

    } else {
      print STDERR "Unable to scan $src for \$Libraries\$ hint: $!\n";
    }
  }

  my $libs = "";
  foreach my $lib (@{ $opts->{l} }) {
    $libs .= " -l$lib";
  }

  $cmds = [];
  push(@$cmds, "$libtool --mode=link $compiler -o $mod_name.la -rpath $libexecdir $ldflags $objlist $libs");

  run_cmds($cmds);
}

if (defined($opts->{i})) {
  my $cmds = [];
  push(@$cmds, "$libtool --mode=install $installer $install_strip $mod_name.la $ENV{DESTDIR}$libexecdir");

  run_cmds($cmds);

  # Don't forget to remind the user to manually edit their proftpd.conf
  # and add the LoadModule to load the just-installed module.

  my $load_mod_name = $mod_name;
  $load_mod_name =~ s/^(.*)\///;

  print STDOUT "\nTo load your newly installed module into proftpd, be sure\n";
  print STDOUT "to edit your proftpd.conf and add the following:\n\n";
  print STDOUT "  <IfModule mod_dso.c>\n";
  print STDOUT "    LoadModule $load_mod_name.c\n";
  print STDOUT "  </IfModule>\n\n";
  print STDOUT "and then restart your proftpd server, so that the config change\n";
  print STDOUT "becomes live.\n\n";
}

if (defined($opts->{d})) {
  my $cmds = [];
  push(@$cmds, "$libtool --mode=clean rm -f $mod_name.la *.lo");

  run_cmds($cmds);
}

if (!defined($opts->{c}) &&
    !defined($opts->{i}) &&
    !defined($opts->{d})) {
  print STDERR "No compile, install, or clean mode requested, exiting\n";
  exit 1;
}

exit 0;

sub get_module_name {
  # Determine the name of the module (e.g. "mod_foo") being operated upon.
  if (defined($opts->{n})) {
    return $opts->{n};
  }

  foreach my $file (@ARGV) {
    # Handle an argument such as 'contrib/mod_sql_sqlite.c' by keeping
    # just the name portion of the path.

    if ($file =~ /\/?mod_([^\/]+)\.(c|la)$/) {
      return "mod_$1";
    }
  }

  return "mod_unknown";
}

sub run_cmds {
  my $cmds = shift;

  foreach my $cmd (@$cmds) {
    print STDOUT "$cmd\n";

    my $res = system($cmd);
    if ($res) {
      print STDERR "$prog: error executing command (", $res >> 8, ")\n";
      exit 1;
    }
  }
}

sub usage {
  my $prog = basename($0);

  print STDOUT <<EOU;

usage: $prog <action> <opts> <source files>

Actions:

 -c, --compile          Compiles the listed .c source files into a proftpd
                        DSO module.

 -i, --install          Installs a compiled proftpd DSO module into the
                        directory where proftpd expects to find loadable
                        DSO modules.

 -d, --clean            Removes any generated files, returning the build
                        directory to a clean state.

Options:

 -h, --help             Displays this message.

 -n, --name             Tells prxs the name of the module being compiled.
                        By default, prxs determines the module name from
                        the list of .c files listed, expecting to see a
                        "mod_\$name.c" file.

 -D key                 Passes these macros through to the compilation step.
 -D key=value           Note that the space before the key is important.

 -I includedir          Specify additional include file search directories.
                        Note that the space before the directory is important.

 -L libdir              Specify additional library file search directories.
                        Note that the space before the directory is important.

 -l library             Specify additional libraries for linking.
                        Note that the space before the library name is important.

At least one of the above actions must be specified when using prxs.  More
than one action can be specified at the same time.

To use prxs all in one step, you could do:

  prxs -c -i -d mod_custom.c

EOU
}