0xV3NOMx
Linux ip-172-26-7-228 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64



Your IP : 3.145.83.96


Current Path : /usr/bin/
Upload File :
Current File : //usr/bin/lintian-info

#!/usr/bin/perl -w
#
# dplint -- General purpose frontend for Debian package checker
#
# Copyright (C) 2013 Niels Thykier
# - Based on lintian, which is/was:
#   Copyright (C) 1998 Christian Schwarz, Richard Braakman (and others)
#
# This program is free software.  It is distributed 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, you can find it on the World Wide
# Web at http://www.gnu.org/copyleft/gpl.html, or write to the Free
# Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston,
# MA 02110-1301, USA.

no lib '.';

# In main scope, need an unnamed sub to avoid tainting the "main" namespace
# in case we need to run a ".pm" tool.
use strict;
use warnings;

my $TOOL_RUNNER = sub {
    my ($tool_pm_path) = @_;
    my $main;
    eval {require $tool_pm_path;};
    if (my $err = $@) {
        dplint::error("Could not load ${tool_pm_path}: $err");
    }
    {
        no strict 'refs';
        $main = \&{'::main'};
    }
    if (not defined($main)) {
        dplint::error("${tool_pm_path} does not define a main sub");
    }
    eval {$main->();};
    if (my $err = "$@") {
        # main threw an exception
        $err .= "\n" if ($err !~ m/\n\Z/);
        print STDERR $err;
        exit(255);
    }
    exit(0);
};

package dplint;
use strict;
use warnings;

use Cwd qw(getcwd realpath);
use File::Basename qw(dirname basename);
use Getopt::Long();

# The $INIT_ROOT line below is (to be) replaced at install time to the
# actual root (i.e. '/usr/share/lintian').  The find_source_root call
# is simply a placeholder to make the command work out of the box in
# the source tree.
my $INIT_ROOT = q{/usr/share/lintian};
# NB: @INCLUDE_DIRS + @RESTRICTED_INCLUDE_DIRS should /only/ have
# absolute paths.  Various bit of lintian code implicitly rely on
# this.
my (@INCLUDE_DIRS, @RESTRICTED_INCLUDE_DIRS);
my $LINTIAN_VERSION = q{2.5.81ubuntu1}; # Substituted during build/install

my %BUILTINS = (
    'help' => \&builtin_help,
    'version' => \&builtin_version,
    'print-version' => \&builtin_version,
);

sub error {
    my (@lines) = @_;
    print STDERR join("\n", @lines), "\n";
    exit(1);
}

sub run_tool {
    my ($truename, $tool) = @_;
    for my $include_dir (@INCLUDE_DIRS) {
        my $tool_path = "$include_dir/commands/${tool}";
        my $tool_pm_path = "${tool_path}.pm";
        if (-f $tool_path) {
            if (!-x $tool_path) {
                error("$tool ($tool_path) is present but not executable!");
            }
            {
                # Scope here it to avoid a warning about exec not returning.
                exec {$tool_path} $truename, @ARGV;
            }
            local $" = ' ';
            error(
                "Running $tool failed!",
                "  Command: $tool_path @ARGV",
                "  Error from exec: $!"
            );
        }
        if (-f $tool_pm_path) {
            # Re-configure Getopt::Long - to avoid surprises in the tool
            Getopt::Long::config('default');
            # Update @INC before running the tool
            require lib;
            lib->import(grep { -d } map { "$_/lib" } @INCLUDE_DIRS);
            $0 = $tool;
            $TOOL_RUNNER->($tool_pm_path);
            error('TOOL_RUNNER returned unexpectedly!?');
        }
    }
    error("$tool is not available");
}

sub setup_env {
    my ($user_dirs) = @_;

    if ($user_dirs) {
        my ($data_home, $legacy_user_data);

        load_file_basedir();

        if (exists($ENV{'HOME'}) or exists($ENV{'XDG_CONFIG_HOME'})) {
            $data_home = data_home('lintian');
        }
        if (exists($ENV{'HOME'})) {
            $legacy_user_data = "$ENV{HOME}/.lintian";
        }
        if (defined($data_home) and $data_home !~ m@^/@) {
            # Turn the path into an absolute one.  Just in case
            # someone sets a relative HOME dir.
            my $cwd = getcwd();
            $data_home = "${cwd}/${data_home}";
        }
        push(@RESTRICTED_INCLUDE_DIRS, $data_home)
          if defined($data_home) && -d $data_home;
        push(@RESTRICTED_INCLUDE_DIRS, $legacy_user_data)
          if defined($legacy_user_data) && -d $legacy_user_data;
        push(@RESTRICTED_INCLUDE_DIRS, '/etc/lintian')
          if -d '/etc/lintian';
    }

    push(@INCLUDE_DIRS, $INIT_ROOT);

    $ENV{'LINTIAN_ROOT'} = $INIT_ROOT;
    $ENV{'LINTIAN_INCLUDE_DIRS'} = join(':', grep { -d } @INCLUDE_DIRS);
    $ENV{'LINTIAN_RESTRICTED_INCLUDE_DIRS'}
      = join(':', grep { -d } @RESTRICTED_INCLUDE_DIRS);
    $ENV{'LINTIAN_ENABLE_USER_DIRS'} = $user_dirs ? 1 : 0;
    $ENV{'LINTIAN_HELPER_DIRS'} = join(
        ':',  grep { -d }
          map { "$_/helpers" } @INCLUDE_DIRS
    );
    $ENV{'LINTIAN_DPLINT_CALLED_AS'} = $0;
    $ENV{'LINTIAN_DPLINT_FRONTEND'} = realpath($0)
      // error("Cannot resolve $0: $!");

    if (my $coverage_arg = $ENV{'LINTIAN_COVERAGE'}) {
        my $p5opt = $ENV{'PERL5OPT'}//q{};
        $p5opt .= ' ' if $p5opt ne q{};
        $ENV{'PERL5OPT'} = "${p5opt} ${coverage_arg}";
    }
    return;
}

sub load_file_basedir {
    # File::BaseDir spews warnings if $ENV{'HOME'} is undef, so
    # make sure it is defined when we load the module.  Though,
    # we need to scope this, so $ENV{HOME} becomes undef again
    # when we check for it later.
    local $ENV{'HOME'} = $ENV{'HOME'} // '/nonexistent';
    require File::BaseDir;
    File::BaseDir->import(qw(config_home config_files data_home));
    return;
}

sub cmd_add_include_dir {
    my (undef, $dir) = @_;
    my $abs_dir;
    error("$dir is not a directory") unless -d $dir;
    $abs_dir = realpath($dir) // error("Cannot resolve $dir: $!");
    push(@INCLUDE_DIRS, $abs_dir);
    return;
}

sub find_source_root {
    # Determine the $INIT_ROOT in case we are run from the source tree
    my $path = realpath(__FILE__) // error("realpath($0) failed: $!\n");
    # .../lintian.git/frontend/dplint  => .../lintian.git
    return dirname(dirname($path));
}

sub include_dirs {
    return @INCLUDE_DIRS;
}

sub restricted_include_dirs {
    return @RESTRICTED_INCLUDE_DIRS;
}

sub load_profile {
    my ($profile_name, $options) = @_;
    my %opt = (
        'restricted-search-dirs' => \@RESTRICTED_INCLUDE_DIRS,
        %{$options // {}},
    );
    require Lintian::Profile;

    return Lintian::Profile->new($profile_name, \@INCLUDE_DIRS, \%opt);
}

sub main {
    my $user_dirs = 1;
    my %opthash = (
        'include-dir=s' => \&cmd_add_include_dir,
        'user-dirs!' => $user_dirs,
    );

    binmode(STDOUT, ':utf8');

    # init commandline parser
    Getopt::Long::config(
        'bundling', 'no_getopt_compat',
        'no_auto_abbrev', 'require_order',
        'pass_through'
    );

    # process commandline options
    Getopt::Long::GetOptions(%opthash)
      or error("error parsing options\n");

    setup_env($user_dirs);

    my $called_as = basename($0);
    my $truename;
    my $cmd;

    if ($called_as ne 'dplint') {
        $truename = $0;
        if ($called_as eq 'lintian-ng') {
            $cmd = 'check';
        } elsif ($called_as eq 'lintian') {
            $cmd = 'lintian';
        } elsif ($called_as eq 'harness') {
            $cmd = 'reporting-harness';
        } elsif ($called_as =~ m{\A (?:(?:lintian|dplint)-)? (.+) \Z}xsm) {
            $cmd = $1;
        } else {
            error("Not sure what command $called_as was intended to be");
        }
    } else {
        if (!defined($cmd)) {
            $cmd = shift(@ARGV);
        }

        if (!defined($cmd)) {
            $cmd = 'help';
        }
        if ($cmd =~ m/^-/) {
            if ($cmd eq '--help' or $cmd eq '-h') {
                $cmd = 'help';
            } elsif ($cmd eq '--version' or $cmd eq '--print-version') {
                $cmd = substr($cmd, 2);
            } else {
                error("Unknown option $cmd");
            }
            $truename //= 'dplint';
        }
    }
    if (exists($BUILTINS{$cmd})) {
        my $handler = $BUILTINS{$cmd};
        error("Unimplemented built-in $cmd")
          unless $handler;
        # Re-configure Getopt::Long - builtins do not care about ordering
        Getopt::Long::config(
            'default', 'permute',
            'bundling','no_getopt_compat',
            'no_auto_abbrev'
        );
        $handler->($truename, $cmd);
        error("Built-in $cmd returned unexpectedly");
    }
    $truename //= $cmd;
    run_tool($truename, $cmd);
    error('run_tool returned unexpectedly');
}

sub lintian_version {
    $LINTIAN_VERSION = guess_version(__FILE__)
      if not defined($LINTIAN_VERSION);
    return $LINTIAN_VERSION;
}

sub builtin_version {
    my ($truename, $cmd) = @_;
    my $version = lintian_version();
    if ($cmd eq 'print-version') {
        print "${version}\n";
    } else {
        print "Lintian v${version}\n";
    }
    exit(0);
}

sub builtin_help {
    my ($truename, $cmd) = @_;
    my $me = basename($0);
    my $version = lintian_version();
    print <<"EOT";
Lintian v${version}
Usage: $me [General options] <command> [options/arguments...]
General options:
  --include-dir DIR     include checks, libraries (etc.) from DIR
  --[no-]user-dirs      whether to use files from user directories

EOT

    exit 0;
}

sub guess_version {
    my $rootdir = find_source_root();
    my $guess;

    if (-d "$rootdir/.git") {
        # Lets try git
        eval {
            # Disabling IPC::Run::Debug saves tons of useless calls.
            $ENV{'IPCRUNDEBUG'} = 'none'
              unless exists $ENV{'IPCRUNDEBUG'};
            require IPC::Run;
            IPC::Run::run(['git', "--git-dir=$rootdir/.git", 'describe'],
                \undef, \$guess, '2>/dev/null');
            chomp($guess);
        };
        return $guess if $guess;
    }
    # git was not possible - maybe the changelog is available
    if (-f "$rootdir/debian/changelog") {
        require Parse::DebianChangelog;
        eval {
            my $changelog
              = Parse::DebianChangelog->init(
                { infile => "$rootdir/debian/changelog" });
            $guess = $changelog->dpkg->{'Version'} if $changelog;
        };
        return $guess if $guess;
    }
    # Out of guesses ...
    error('Unable to determine the version automatically!?');
}

main();

# Local Variables:
# indent-tabs-mode: nil
# cperl-indent-level: 4
# End:
# vim: syntax=perl sw=4 sts=4 sr et