aboutsummaryrefslogtreecommitdiffstats
path: root/magic.req
blob: e32532881225a2bd9e140d8db674fae3fb1eb81a (plain)
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
#!/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 ; 
}