xref: /freebsd/crypto/openssl/util/perl/OpenSSL/fallback.pm (revision e0c4386e7e71d93b0edc0c8fa156263fc4a8b0b6)
1*e0c4386eSCy Schubert# Copyright 2019-2021 The OpenSSL Project Authors. All Rights Reserved.
2*e0c4386eSCy Schubert#
3*e0c4386eSCy Schubert# Licensed under the Apache License 2.0 (the "License").  You may not use
4*e0c4386eSCy Schubert# this file except in compliance with the License.  You can obtain a copy
5*e0c4386eSCy Schubert# in the file LICENSE in the source distribution or at
6*e0c4386eSCy Schubert# https://www.openssl.org/source/license.html
7*e0c4386eSCy Schubert
8*e0c4386eSCy Schubert=head1 NAME
9*e0c4386eSCy Schubert
10*e0c4386eSCy SchubertOpenSSL::fallback - push directories to the end of @INC at compile time
11*e0c4386eSCy Schubert
12*e0c4386eSCy Schubert=cut
13*e0c4386eSCy Schubert
14*e0c4386eSCy Schubertpackage OpenSSL::fallback;
15*e0c4386eSCy Schubert
16*e0c4386eSCy Schubertuse strict;
17*e0c4386eSCy Schubertuse warnings;
18*e0c4386eSCy Schubertuse Carp;
19*e0c4386eSCy Schubert
20*e0c4386eSCy Schubertour $VERSION = '0.01';
21*e0c4386eSCy Schubert
22*e0c4386eSCy Schubert=head1 SYNOPSIS
23*e0c4386eSCy Schubert
24*e0c4386eSCy Schubert    use OpenSSL::fallback LIST;
25*e0c4386eSCy Schubert
26*e0c4386eSCy Schubert=head1 DESCRIPTION
27*e0c4386eSCy Schubert
28*e0c4386eSCy SchubertThis small simple module simplifies the addition of fallback directories
29*e0c4386eSCy Schubertin @INC at compile time.
30*e0c4386eSCy Schubert
31*e0c4386eSCy SchubertIt is used to add extra directories at the end of perl's search path so
32*e0c4386eSCy Schubertthat later "use" or "require" statements will find modules which are not
33*e0c4386eSCy Schubertlocated on perl's default search path.
34*e0c4386eSCy Schubert
35*e0c4386eSCy SchubertThis is similar to L<lib>, except the paths are I<appended> to @INC rather
36*e0c4386eSCy Schubertthan prepended, thus allowing the use of a newer module on perl's default
37*e0c4386eSCy Schubertsearch path if there is one.
38*e0c4386eSCy Schubert
39*e0c4386eSCy Schubert=head1 CAVEAT
40*e0c4386eSCy Schubert
41*e0c4386eSCy SchubertJust like with B<lib>, this only works with Unix filepaths.
42*e0c4386eSCy SchubertJust like with L<lib>, this doesn't mean that it only works on Unix, but that
43*e0c4386eSCy Schubertnon-Unix users must first translate their file paths to Unix conventions.
44*e0c4386eSCy Schubert
45*e0c4386eSCy Schubert    # VMS users wanting to put [.my.stuff] into their @INC should write:
46*e0c4386eSCy Schubert    use fallback 'my/stuff';
47*e0c4386eSCy Schubert
48*e0c4386eSCy Schubert=head1 NOTES
49*e0c4386eSCy Schubert
50*e0c4386eSCy SchubertIf you try to add a file to @INC as follows, you will be warned, and the file
51*e0c4386eSCy Schubertwill be ignored:
52*e0c4386eSCy Schubert
53*e0c4386eSCy Schubert    use fallback 'file.txt';
54*e0c4386eSCy Schubert
55*e0c4386eSCy SchubertThe sole exception is the file F<MODULES.txt>, which must contain a list of
56*e0c4386eSCy Schubertsub-directories relative to the location of that F<MODULES.txt> file.
57*e0c4386eSCy SchubertAll these sub-directories will be appended to @INC.
58*e0c4386eSCy Schubert
59*e0c4386eSCy Schubert=cut
60*e0c4386eSCy Schubert
61*e0c4386eSCy Schubert# Forward declare
62*e0c4386eSCy Schubertsub glob;
63*e0c4386eSCy Schubert
64*e0c4386eSCy Schubertuse constant DEBUG => 0;
65*e0c4386eSCy Schubert
66*e0c4386eSCy Schubertsub import {
67*e0c4386eSCy Schubert    shift;                      # Skip module name
68*e0c4386eSCy Schubert
69*e0c4386eSCy Schubert    foreach (@_) {
70*e0c4386eSCy Schubert        my $path = $_;
71*e0c4386eSCy Schubert
72*e0c4386eSCy Schubert        if ($path eq '') {
73*e0c4386eSCy Schubert            carp "Empty compile time value given to use fallback";
74*e0c4386eSCy Schubert            next;
75*e0c4386eSCy Schubert        }
76*e0c4386eSCy Schubert
77*e0c4386eSCy Schubert        print STDERR "DEBUG: $path\n" if DEBUG;
78*e0c4386eSCy Schubert
79*e0c4386eSCy Schubert        unless (-e $path
80*e0c4386eSCy Schubert                && ($path =~ m/(?:^|\/)MODULES.txt/ || -d $path)) {
81*e0c4386eSCy Schubert            croak "Parameter to use fallback must be a directory, not a file";
82*e0c4386eSCy Schubert            next;
83*e0c4386eSCy Schubert        }
84*e0c4386eSCy Schubert
85*e0c4386eSCy Schubert        my @dirs = ();
86*e0c4386eSCy Schubert        if (-f $path) {         # It's a MODULES.txt file
87*e0c4386eSCy Schubert            (my $dir = $path) =~ s|/[^/]*$||; # quick dirname
88*e0c4386eSCy Schubert            open my $fh, $path or die "Could not open $path: $!\n";
89*e0c4386eSCy Schubert            while (my $l = <$fh>) {
90*e0c4386eSCy Schubert                $l =~ s|\R$||;        # Better chomp
91*e0c4386eSCy Schubert                my $d = "$dir/$l";
92*e0c4386eSCy Schubert                my $checked = $d;
93*e0c4386eSCy Schubert
94*e0c4386eSCy Schubert                if ($^O eq 'VMS') {
95*e0c4386eSCy Schubert                    # Some VMS unpackers replace periods with underscores
96*e0c4386eSCy Schubert                    # We must be real careful not to convert the directories
97*e0c4386eSCy Schubert                    # '.' and '..', though.
98*e0c4386eSCy Schubert                    $checked =
99*e0c4386eSCy Schubert                        join('/',
100*e0c4386eSCy Schubert                             map { my $x = $_;
101*e0c4386eSCy Schubert                                   $x =~ s|\.|_|g
102*e0c4386eSCy Schubert                                       if ($x ne '..' && $x ne '.');
103*e0c4386eSCy Schubert                                   $x }
104*e0c4386eSCy Schubert                             split(m|/|, $checked))
105*e0c4386eSCy Schubert                        unless -e $checked && -d $checked;
106*e0c4386eSCy Schubert                }
107*e0c4386eSCy Schubert                croak "All lines in $path must be a directory, not a file: $l"
108*e0c4386eSCy Schubert                    unless -e $checked && -d $checked;
109*e0c4386eSCy Schubert                push @INC, $checked;
110*e0c4386eSCy Schubert            }
111*e0c4386eSCy Schubert        } else {                # It's a directory
112*e0c4386eSCy Schubert            push @INC, $path;
113*e0c4386eSCy Schubert        }
114*e0c4386eSCy Schubert    }
115*e0c4386eSCy Schubert}
116*e0c4386eSCy Schubert
117*e0c4386eSCy Schubert=head1 SEE ALSO
118*e0c4386eSCy Schubert
119*e0c4386eSCy SchubertL<FindBin> - optional module which deals with paths relative to the source
120*e0c4386eSCy Schubertfile.
121*e0c4386eSCy Schubert
122*e0c4386eSCy Schubert=head1 AUTHOR
123*e0c4386eSCy Schubert
124*e0c4386eSCy SchubertRichard Levitte, 2019
125*e0c4386eSCy Schubert
126*e0c4386eSCy Schubert=cut
127*e0c4386eSCy Schubert
128