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