aboutsummaryrefslogtreecommitdiffstats
path: root/magic.req
diff options
context:
space:
mode:
Diffstat (limited to 'magic.req')
-rwxr-xr-xmagic.req143
1 files changed, 143 insertions, 0 deletions
diff --git a/magic.req b/magic.req
new file mode 100755
index 0000000..e325328
--- /dev/null
+++ b/magic.req
@@ -0,0 +1,143 @@
+#!/usr/bin/perl
+
+# Given a list of filenames on the command line or on stdin this
+# script returns the interpreter that is required to run the
+# filenames. Usually this is extracted from the #! line of the file
+# but we also handle the various 'exec' tricks that people use to
+# start the interpreter via an intermediate shell.
+
+# Also we want to convert:
+# /usr/local/bin/perl5.00404
+# /usr/local/bin/tclsh8.0
+# into dependencies with RPM version numbers.
+
+
+
+
+
+# These have all been seen on our system or are "recommended" in
+# various man pages.
+
+# Examples:
+
+# #!/bin/sh
+# # the next line restarts using wish \
+# exec wish "$0" "$@"
+
+
+# #!/bin/sh -- # -*- perl -*- -p
+# eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
+# if $running_under_some_shell;
+
+
+# #!/bin/sh -- # -*- perl -*- -p
+# eval '(exit $?0)' && eval 'exec /usr/bin/perl -wS $0 ${1+"$@"}'
+
+
+# #!/bin/sh -- # -*- perl -*- -p
+# & eval 'exec /usr/bin/perl -wS $0 $argv:q'
+# if $running_under_some_shell;
+
+
+# #! /usr/bin/env python
+
+
+use File::Basename;
+
+if ("@ARGV") {
+ foreach (@ARGV) {
+ process_file($_);
+ }
+} else {
+
+ # notice we are passed a list of filenames NOT as common in unix the
+ # contents of the file.
+
+ foreach (<>) {
+ process_file($_);
+ }
+}
+
+
+foreach $prog (sort keys %require) {
+
+
+ # ignore variable interpolation and any program whose name is made
+ # up only of non word characters ('<', '&&', etc).
+
+ ( ( $prog != /\$/ ) || ( $prog =~ /^\W+$/ ) ) &&
+ next;
+
+ # filenames of the form './miniperl' will be reported in canonical
+ # manner 'miniperl'
+
+ $prog =~ s!^\./!!;
+
+ if ( $prog !~ /\$/ ) {
+ print "exectuable($prog)\n";
+ }
+
+ $prog=basename($prog);
+
+ if ( $prog !~ /\$/ ) {
+ print "exectuable($prog)\n";
+
+ # get the correct version dependencies for magic numbers like:
+ # /usr/local/bin/perl5.00404
+ # /usr/local/bin/tclsh8.0
+ # these are always PACKAGE versions since typical executables do not
+ # have versions
+
+ my $version = "";
+ if ($module =~ s/([.0-9]+)$//) {
+ $version = "$1";
+ print "$prog>=$version\n";
+ }
+
+ }
+
+}
+
+exit 0;
+
+
+sub process_file {
+
+ my ($file) = @_;
+ chomp $file;
+
+ my ($version, $magic) = ();
+
+ (-f $file) || return ;
+
+ open(FILE, "<$file")||
+ die("$0: Could not open file: '$file' : $!\n");
+
+ my $rc = sysread(FILE,$line,1000);
+
+ $rc =~ s/\#.*\n//g;
+
+ # Ignore all parameter substitution.
+ # I have no hope of parsing something like:
+ # exec ${SHELL:-/bin/sh}
+ $rc =~ s/\$\{.*\}//g;
+ $rc =~ s/echo\s+.*[\n;]//g;
+
+ if ( ($rc > 1) && ($line =~ m/^\#\!\s*/) ) {
+
+ if ($line =~ m/\b(exec|env)\s+([\'\"\`\\]+)?([^ \t\n\r]+)/) {
+ $require{$3} = 1;
+ }
+
+ # strip off extra lines and any arguments
+ if ($line =~ m/^\#\!\s*([^ \t\n\r]+)/) {
+ $require{$1} = 1;
+ }
+
+ }
+
+ close(FILE) ||
+ die("$0: Could not close file: '$file' : $!\n");
+
+ return ;
+}