File build.specials.obscpio of Package kernel-source

07070100000000000081a40000000000000000000000016932839200000005000000000000000000000000000000000000000b00000000.gitignore.osc
07070100000001000081ed000000000000000000000001693283920000044a000000000000000000000000000000000000000e00000000apply-patches#!/bin/sh
#
# Given a series.conf file and a directory with patches, applies them to the
# current directory.
# Used by kernel-source.spec.in and kernel-binary.spec.in

USAGE="$0 [--vanilla] <series.conf> <patchdir> [symbol ...]"

set -e
set -o pipefail
vanilla=false
if test "$1" == "--vanilla"; then
	vanilla=true
	shift
fi
if test $# -lt 2; then
	echo "$USAGE" >&2
	exit 1
fi
DIR="${0%/*}"
SERIES_CONF=$1
PATCH_DIR=$2
shift 2

trap 'rm -f "$series"' EXIT
series=$(mktemp)
# support for patches in patches.addon/series
cp "$SERIES_CONF" "$series"
if ! $vanilla && test -e "$PATCH_DIR/patches.addon/series"; then
	# make it user-friendly and automatically prepend "patches.addon/"
	# if there is no "/"
	sed -r 's|^([[:space:]]*)([^#[:space:]][^/]*)$|\1patches.addon/\2|' \
		"$PATCH_DIR/patches.addon/series" >>"$series"
fi

(
	echo "trap 'echo \"*** patch \$_ failed ***\"' ERR"
	echo "set -ex"
	"$DIR"/guards "$@" <"$series" | \
	if $vanilla; then
		sed -rn '/^patches\.(kernel\.org|rpmify)\//p'
	else
		cat
	fi |\
	sed "s|^|patch -s -F0 -E -p1 --no-backup-if-mismatch -i $PATCH_DIR/|"
) | sh

07070100000002000081ed00000000000000000000000169328392000005a1000000000000000000000000000000000000000d00000000arch-symbols#!/bin/bash

#############################################################################
# Copyright (c) 2003-2005,2009 Novell, Inc.
# Copyright (c) 2010-2022 SUSE LLC
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# 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, contact https://www.suse.com/source-code/
#
#############################################################################


# With --list, list all known architectures, otherwise print the generic
# name for this architecture (or the one specified on command line).

if [ "$1" = "--list" ]; then
    # List all known architectures
    echo i386 mips{,64} sparc{,64} ppc{,64,64le} s390{,x} ia64 x86_64 alpha parisc armv6hl armv7hl arm64 riscv64
    exit 0
fi

if [ -n "$1" ]; then
    ARCH="$1"
else
    ARCH="$(arch)"
fi
case "$ARCH" in
    # from rpm --eval '%ix86'
    i?86 | pentium3 | pentium4 | athlon | geode)
        echo i386
        ;;
    aarch64)
        echo arm64
        ;;
    *)
        echo "$ARCH"
        ;;
esac
07070100000003000081ed0000000000000000000000016932839200000668000000000000000000000000000000000000001900000000check-for-config-changes#! /bin/bash

# This is a list of toolchain-dependent configs. That is: only those which
# change .config when gcc, ld, or similar changes.
#
# please keep them sorted alphabetically
declare -a IGNORED_CONFIGS_RE=(
	'ARCH_USING_PATCHABLE_FUNCTION_ENTRY'
	'AS_IS_\(GNU\|LLVM\)'
	'AS_HAS_[A-Z0-9_]*'
	'AS_VERSION'
	'AS_WRUSS' # x86_32
	'BUILTIN_RETURN_ADDRESS_STRIPS_PAC'
	'CC_ASM_FLAG_OUTPUT_BROKEN'
	'CC_CAN_[A-Z_]*'
	'CC_IMPLICIT_FALLTHROUGH'
	'CC_IS_\(CLANG\|GCC\)'
	'CC_HAS_[A-Z_]*'
	'CC_HAVE_[A-Z_]*'
	'CC_VERSION_TEXT'
	'CLANG_VERSION'
	'DRM_MSM_VALIDATE_XML'
	'DYNAMIC_SIGFRAME'
	'FTRACE_MCOUNT_USE_[A-Z_]*'
	'GCC_ASM_FLAG_OUTPUT_BROKEN'
	'GCC_ASM_GOTO_OUTPUT_BROKEN'
	'GCC_ASM_GOTO_OUTPUT_WORKAROUND'
	'GCC_VERSION'
	'G*CC[0-9]*_NO_[A-Z_]*'
	'HAS_LTO_CLANG'
	'HAVE_[A-Z]*_COMPILER'
	'HAVE_RUST'
	'HAVE_SHADOW_CALL_STACK'
	'LD_CAN_[A-Z_]*'
	'LD_IS_\(BFD\|LLD\)'
	'LD_VERSION'
	'LLD_VERSION'
	'OBJTOOL'
	'PAHOLE_HAS_[A-Z0-9_]*'
	'PAHOLE_VERSION'
	'RISCV_ISA_[A-Z_]*'
	'RUSTC_SUPPORTS_[A-Z0-9_]*'
	'SCHED_PROXY_EXEC'
	'TOOLCHAIN_HAS_[A-Z_]*'
	'TOOLCHAIN_NEEDS_[A-Z_]*'
	'TOOLS_SUPPORT_[A-Z_]*'
	'USE_X86_SEG_SUPPORT'
)

declare -a SED_ARGS=()

for CONFIG in "${IGNORED_CONFIGS_RE[@]}"; do
	SED_ARGS+=(-e "/\\<CONFIG_$CONFIG\\>/ d")
done

SED_ARGS+=(
	-e '/^# .* is not set$/p'
	-e '/^$\|^#/d'
)

differences="$(
    diff -bU0 <(sed "${SED_ARGS[@]}" "$1" | sort) \
	      <(sed "${SED_ARGS[@]}" "$2" | sort) \
    | grep '^[-+][^-+]'
)" || true
if [ -n "$differences" ]; then
    echo
    echo "Changes after running \`make oldconfig':"
    echo "$differences"
    echo
    if echo "$differences" | grep -q '^+' ; then
	exit 1
    fi
fi
07070100000004000081ed0000000000000000000000016932839200000125000000000000000000000000000000000000001500000000check-module-license#!/bin/sh

rc=0
for file in $(find "$@" -name '*.ko' -o -name '*.ko.xz' \
	      -o -name '*.ko.gz' -o -name '*.ko.zst'); do
    l=$(/sbin/modinfo -F license "$file")
    if [ -z "$l" ]; then
	echo "ERROR: No license is included for module ${file##*/lib/modules/}"
	rc=1
    fi
done

exit $rc
07070100000005000081ed0000000000000000000000016932839200000b1a000000000000000000000000000000000000001600000000group-source-files.pl#!/usr/bin/perl

use File::Spec;
use Getopt::Long qw(:config no_ignore_case);
use strict;

&main();
sub main
{
	my($dev_output, $ndev_output, $loc) = ("-", "-", ".");
	&Getopt::Long::Configure(qw(bundling));
	&GetOptions(
		"D=s" => \$dev_output,
		"N=s" => \$ndev_output,
		"L=s" => \$loc,
	);

	my($dev, $ndev) = &scan($loc);
	&output($dev, $ndev, $dev_output, $ndev_output);
}

sub rpm_quote_filename
{
	# technically should also quote  % -> %%  " -> \"  \ -> \\
	return map { "\"$_\"" } @_;
}

sub scan
{
	# Normalize file path, mainly to strip away the ending forward slash,
	# or any double forward slashes.
	my $loc = File::Spec->canonpath(shift @_);
	# We cannot use an absolute path (e.g. /usr/src/linux-5.14.21-150500.41)
	# during find because it's under build root, but rpm wants one later.
	my $abs_loc = rpm_path($loc);
	my(@dev, @ndev);

	foreach $_ (`find "$loc"`)
	{
		chomp $_;
		if (-d $_ && !-l $_) {
			# Generate directory list later.
			next;
		}
		my $is_devel =
			m{^\Q$loc\E.*/Kconfig} ||
			m{^\Q$loc\E.*/Kbuild} ||
			m{^\Q$loc\E.*/Makefile} ||
			m{^\Q$loc\E/arch/[^/]+/boot/dts/include/dt-bindings\b} ||
			m{^\Q$loc\E/arch/[^/]+/include\b} ||
			m{^\Q$loc\E/arch/.*/module\.lds\b} ||
			m{^\Q$loc\E/arch/arm/[^/]+/include/mach\b} ||
			m{^\Q$loc\E/arch/arm/[^/]+/include/plat\b} ||
			m{^\Q$loc\E/arch/[^/]+/scripts\b} ||
			m{^\Q$loc\E/arch/[^/]+/tools\b} ||
			m{^\Q$loc\E/include/[^/]+\b} ||
			m{^\Q$loc\E/scripts\b};
		my $abs_path = rpm_path($_);
		$is_devel ? push(@dev, $abs_path) : push(@ndev, $abs_path);
	}

	my @dev_dirs = calc_dirs($abs_loc, \@dev);
	my @ndev_dirs = calc_dirs($abs_loc, \@ndev);
	@dev = rpm_quote_filename(@dev);
	@ndev = rpm_quote_filename(@ndev);
	@dev_dirs = map { "\%dir $_" } rpm_quote_filename(@dev_dirs);
	@ndev_dirs = map { "\%dir $_" } rpm_quote_filename(@ndev_dirs);
	push(@dev, @dev_dirs);
	push(@ndev, @ndev_dirs);
	return (\@dev, \@ndev);
}

sub calc_dirs
{
	my($base, $files) = @_;
	my %dirs;

	foreach my $file (@$files) {
		my ($volume,$path,$basename) = File::Spec->splitpath($file);
		my @dirs = File::Spec->splitdir($path);
		do {
			# Always create $path from catdir() to avoid ending forward slash
			$path = File::Spec->catdir(@dirs);
			$dirs{$path} = 1;
			pop @dirs;
		} while ($path ne $base);
		# This loop also makes sure that $base itself is included.
	}

	return keys %dirs;
}

sub output
{
	my($dev, $ndev, $dev_out, $ndev_out) = @_;
	local *FH;

	open(FH, "> $dev_out") || warn "Error writing to $dev_out: $!";
	print FH join("\n", @$dev), "\n";
	close FH;

	open(FH, "> $ndev_out") || warn "Error writing to $ndev_out: $!";
	print FH join("\n", @$ndev), "\n";
	close FH;
}

sub rpm_path
{
	my $path = shift @_;
	# Always prepend forward slash and let canonpath take care of
	# duplicate forward slashes.
	return File::Spec->canonpath("/$path");
}
07070100000006000081ed0000000000000000000000016932839200001ebd000000000000000000000000000000000000000700000000guards#!/usr/bin/perl -w
##############################################################################
# Copyright (c) 2003-2007,2009 Novell, Inc.
# Copyright (c) 2010-2022 SUSE LLC
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# 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, contact https://www.suse.com/source-code/
#
#############################################################################
#
# Guards:
#
# +xxx   include if xxx is defined
# -xxx   exclude if xxx is defined
# +!xxx  include if xxx is not defined
# -!xxx  exclude if xxx is not defined
#

use FileHandle;
use Getopt::Long qw(:config no_ignore_case);
use strict;

# Prototypes
sub files_in($$);
sub parse($$);
sub help();

sub slashme($) {
    my ($dir) = @_;
    $dir =~ s#([^/])$#$&/#; # append a slash if necessary
    if ($dir eq './') {
	return '';
    } else {
	return $dir;
    }
}

# Generate a list of files in a directory
#
sub files_in($$) {
    my ($dir, $path) = @_;
    my $dh = new FileHandle;
    my (@files, $file);

    # @<file> syntax
    if ($path =~ s/^@//) {
	my $fh;
	open($fh, '<', $path) or die "$path: $!\n";
	@files = <$fh>;
	close($fh);
	chomp(@files);
	s:^$dir:: for @files;
	return @files;
    }

    $path = slashme($path);
    opendir $dh, length("$dir$path") ? "$dir$path" : '.'
	or die "$dir$path: $!\n";
    while ($file = readdir($dh)) {
	next if $file =~ /^(\.|\.\.|\.#.*|CVS|.*~)$/;
	if (-d "$dir$path$file") {
		@files = (@files, files_in($dir, "$path$file/"));
	} else {
		#print "[$path$file]\n";
		push @files, "$path$file";
	}
    }
    closedir $dh;
    return @files;
}

# Parse a configuration file
# Callback called with ($patch, @guards) arguments
#
sub parse($$) {
    my ($fh, $callback) = @_;

    my $line = "";

    while (<$fh>) {
	chomp;
	s/(^|\s+)#.*//;
	if (s/\\$/ /) {
		$line .= $_;
		next;
	}
	$line .= $_;
	my @guards = ();
	foreach my $token (split /[\s\t\n]+/, $line) {
	    next if $token eq "";
	    if ($token =~ /^[-+]/) {
		push @guards, $token;
	    } else {
		#print "[" . join(",", @guards) . "] $token\n";
		&$callback($token, @guards);
	    }
	}
	$line = "";
    }
}

# Command line options
#
my ($dir, $config, $default, $check, $list, $invert_match, $with_guards) =
   (  '',     '-',        1,      0,     0,             0,            0);
my @path;

# Help text
#
sub help() {
    print "$0 - select from a list of files guarded by conditions\n";
    print "SYNOPSIS: $0 [--prefix=dir] [--path=dir1:dir2:...]\n" .
	"	[--default=0|1] [--check|--list] [--invert-match]\n" .
	"	[--with-guards] [--config=file] symbol ...\n\n" .
	"	Defaults: --default=$default\n" .
	"	Use --path=\@<file> to read the list of entries from <file>\n";
    exit 0;
}

# Parse command line options
#
Getopt::Long::Configure ("bundling");
eval {
    unless (GetOptions (
	'd|prefix=s' => \$dir,
	'c|config=s' => \$config,
	'C|check' => \$check,
	'l|list' => \$list,
	'w|with-guards' => \$with_guards,
	'p|path=s' => \@path,
	'D|default=i' => \$default,
	'v|invert-match' => \$invert_match,
	'h|help' => sub { help(); exit 0; })) {
	help();
	exit 1;
    }
};
if ($@) {
    print "$@";
    help();
    exit 1;
}

@path = ('.')
    unless (@path);
@path = split(/:/, join(':', @path));

my $fh = ($config eq '-') ? \*STDIN : new FileHandle($config)
    or die "$config: $!\n";

$dir = slashme($dir);

if ($check) {
    # Check for duplicate files, or for files that are not referenced by
    # the specification.

    my $problems = 0;
    my @files;

    foreach (@path) {
	@files = (@files, files_in($dir, $_));
    }
    my %files = map { $_ => 0 } @files;

    parse($fh, sub {
	my ($patch, @guards) = @_;
	if (exists $files{$patch}) {
	    $files{$patch}++;
	} else {
	    if ($config eq '-') {
		print "Not found: $dir$patch\n";
	    } else {
		print "In $config but not found: $dir$patch\n";
	    }
	    $problems++;
	}});

    $fh->close();

    my ($file, $ref);
    while (($file, $ref) = each %files) {
	next if $ref == 1;

	if ($ref == 0) {
	    if ($config eq '-') {
		print "Unused: $file\n";
	    } else {
		print "Not in $config: $file\n";
	    }
	    $problems++;
	}
	if ($ref > 1) {
	    print "Warning: multiple uses";
	    print " in $config" if $config ne '-';
	    print ": $file\n";
	    # This is not an error if the entries are mutually exclusive...
	}
    }
    exit ($problems ? 1 : 0);

} elsif ($list) {
    parse($fh, sub {
	my ($patch, @guards) = @_;
	print join(' ', @guards), ' '
		if (@guards && $with_guards);
	print "$dir$patch\n";
	});
} else {
    # Generate a list of patches to apply.

    my %symbols = map { $_ => 1 } @ARGV;

    parse($fh, sub {
	my ($patch, @guards) = @_;

	my $selected;
	if (@guards) {
	    # If the first guard is -xxx, the patch is included by default;
	    # if it is +xxx, the patch is excluded by default.
	    $selected = ($guards[0] =~ /^-/);

	    foreach (@guards) {
		/^([-+])(!?)(.*)?/
		    or die "Bad guard '$_'\n";

		# Check if the guard matches
		if (($2 eq '!' && !exists $symbols{$3}) ||
		    ($2 eq ''  && ( $3 eq '' || exists $symbols{$3}))) {
		    # Include or exclude
		    $selected = ($1 eq '+');
		}
	    }
	} else {
	    # If there are no guards, use the specified default result.
	    $selected = $default;
	}

	print "$dir$patch\n"
	    if $selected ^ $invert_match;
	});

    $fh->close();

    exit 0;
}

__END__

=head1 NAME

guards - select from a list of files guarded by conditions

=head1 SYNOPSIS

F<guards> [--prefix=F<dir>] [--path=F<dir1:dir2:...>] [--default=<0|1>]
[--check|--list] [--invert-match] [--with-guards] [--config=<file>]
I<symbol> ...

=head1 DESCRIPTION

The script reads a configuration file that may contain so-called guards, file
names, and comments, and writes those file names that satisfy all guards to
standard output. The script takes a list of symbols as its arguments. Each line
in the configuration file is processed separately. Lines may start with a
number of guards. The following guards are defined:

=over

+I<xxx> Include the file(s) on this line if the symbol I<xxx> is defined.

-I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is defined.

+!I<xxx> Include the file(s) on this line if the symbol I<xxx> is not defined.

-!I<xxx> Exclude the file(s) on this line if the symbol I<xxx> is not defined.

- Exclude this file. Used to avoid spurious I<--check> messages.

=back

The guards are processed left to right. The last guard that matches determines
if the file is included. If no guard is specified, the I<--default>
setting determines if the file is included.

If no configuration file is specified, the script reads from standard input.

The I<--check> option is used to compare the specification file against the
file system. If files are referenced in the specification that do not exist, or
if files are not enlisted in the specification file warnings are printed. The
I<--path> option can be used to specify which directory or directories to scan.
Multiple directories are separated by a colon (C<:>) character. The
I<--prefix> option specifies the location of the files. Alternatively, the
I<--path=@E<lt>fileE<gt>> syntax can be used to specify a file from which the
file names will be read.

Use I<--list> to list all files independent of any rules. Use I<--invert-match>
to list only the excluded patches. Use I<--with-guards> to also include all
inclusion and exclusion rules.

=head1 AUTHOR

Andreas Gruenbacher <agruen@suse.de>, SUSE Labs
07070100000007000081ed0000000000000000000000016932839200001287000000000000000000000000000000000000000800000000kabi.pl#!/usr/bin/perl
use strict;
use warnings;

use Getopt::Long qw(:config no_ignore_case);
use Data::Dumper;

# ( { sym => regexp, mod => regexp, fail => 0/1 }, ... )
my @rules;
my ($opt_verbose, $opt_rules);

# if Module.symvers also lists namespaces (>=5.4)
my $use_namespaces;

sub load_rules {
	my $file = shift;
	my $errors = 0;

	xopen(my $fh, '<', $file);
	while (<$fh>) {
		chomp;
		s/#.*//;
		next if /^\s*$/;
		my ($pattern, $verdict) = split(/\s+/);
		my $new = {};
		if (uc($verdict) eq "PASS") {
			$new->{fail} = 0;
		} elsif (uc($verdict) eq "FAIL") {
			$new->{fail} = 1;
		} else {
			print STDERR "$file:$.: invalid verdict \"$verdict\", must be either PASS or FAIL.\n";
			$errors++;
			next;
		}
		# simple glob -> regexp conversion
		$pattern =~ s/\*/.*/g;
		$pattern =~ s/\?/./g;
		$pattern =~ s/.*/^$&\$/;

		# If it matches a module path or vmlinux
		if ($pattern =~ /\/|^vmlinux$/) {
			$new->{mod} = $pattern;
		# If it's not a path and the string is all uppercase, assume it's a namespace
		} elsif ($use_namespaces &&
			$pattern !~ /\// && $pattern eq uc($pattern)) {
			$new->{namespace} = $pattern;
		} else {
			$new->{sym} = $pattern;
		}
		push(@rules, $new);
	}
	if ($errors && !@rules) {
		print STDERR "error: only garbage found in $file.\n";
		exit 1;
	}
	close($fh);
}

# Return 1 if using new (>=5.4) Module.symvers format with namespaces
sub symvers_uses_namespaces {
	my $file = shift;
	xopen(my $fh, '<', $file);
	my $line =  <$fh>;
	chomp $line;

	# The new (>=5.4) Module.symvers format has 4 tabs (5 fields):
	#
	#    crc\tsymbol\tmodule\texport_type\tnamespace
	#
	# The older Module.symvers format only has 3 tabs (4 fields):
	#
	#    crc\tsymbol\tmodule\texport_type

	my $num_tabs = $line =~ tr/\t//;
	if ($num_tabs > 3) {
		return 1;
	} else {
		return 0;
	}
}

sub load_symvers {
	my $file = shift;
	my %res;
	my $errors = 0;
	my $new;

	xopen(my $fh, '<', $file);
	while (<$fh>) {
		chomp;
		my @l = split(/\t/, $_, -1);
		if (@l < 4) {
			print STDERR "$file:$.: unknown line\n";
			$errors++;
			next;
		}
		if ($use_namespaces) {
			$new = { crc => $l[0], mod => $l[2], type => $l[3], namespace => $l[4] };
		} else {
			$new = { crc => $l[0], mod => $l[2], type => $l[3] };
		}
		$res{$l[1]} = $new;
	}
	if (!%res) {
		print STDERR "error: no symvers found in $file.\n";
		exit 1;
	}
	close($fh);
	return %res;
}

# Each bit represents a restriction of the export and adding a restriction
# fails the check
my $type_GPL    = 0x1;
my $type_NOW    = 0x2;
my $type_UNUSED = 0x4;
my %types = (
	EXPORT_SYMBOL            => 0x0,
	EXPORT_SYMBOL_GPL        => $type_GPL | $type_NOW,
	EXPORT_SYMBOL_GPL_FUTURE => $type_GPL,
	EXPORT_UNUSED_SYMBOL     => $type_UNUSED,
	EXPORT_UNUSED_SYMBOL_GPL => $type_UNUSED | $type_GPL | $type_NOW
);

sub type_compatible {
	my ($old, $new) = @_;

	for my $type ($old, $new) {
		if (!exists($types{$type})) {
			print STDERR "error: unrecognized export type $type.\n";
			exit 1;
		}
	}
	# if $new has a bit set that $old does not -> fail
	return !(~$types{$old} & $types{$new});
}

my $kabi_errors = 0;
sub kabi_change {
	my ($sym, $symvers, $message) = @_;
	my $fail = 1;

	for my $rule (@rules) {
		if ($rule->{mod} && $symvers->{mod} =~ $rule->{mod} ||
		    $rule->{sym} && $sym =~ $rule->{sym} ||
			($use_namespaces && $rule->{namespace} &&
				$symvers->{namespace} =~ $rule->{namespace})) {
			$fail = $rule->{fail};
			last;
		}
	}
	return unless $fail or $opt_verbose;

	print STDERR "KABI: symbol $sym(mod:$symvers->{mod}";
	if ($use_namespaces && $symvers->{namespace}) {
		print STDERR " ns:$symvers->{namespace}";
	}
	print STDERR ") $message";
	if ($fail) {
		$kabi_errors++;
		print STDERR "\n";
	} else {
		print STDERR " (tolerated)\n";
	}
}

sub xopen {
	open($_[0], $_[1], @_[2..$#_]) or die "$_[2]: $!\n";
}

my $res = GetOptions(
	'verbose|v' => \$opt_verbose,
	'rules|r=s' => \$opt_rules,
);
if (!$res || @ARGV != 2) {
	print STDERR "Usage: $0 [--rules <rules file>] Module.symvers.old Module.symvers\n";
	exit 1;
}

# Determine symvers format
$use_namespaces = symvers_uses_namespaces($ARGV[0]);

if (defined($opt_rules)) {
	load_rules($opt_rules);
}
my %old = load_symvers($ARGV[0]);
my %new = load_symvers($ARGV[1]);

for my $sym (sort keys(%old)) {
	if (!$new{$sym}) {
		kabi_change($sym, $old{$sym}, "lost");
	} elsif ($old{$sym}->{crc} ne $new{$sym}->{crc}) {
		kabi_change($sym, $old{$sym}, "changed crc from " .
			"$old{$sym}->{crc} to $new{$sym}->{crc}");
	} elsif (!type_compatible($old{$sym}->{type}, $new{$sym}->{type})) {
		kabi_change($sym, $old{$sym}, "changed type from " .
			"$old{$sym}->{type} to $new{$sym}->{type}");
	}
}
if ($kabi_errors) {
	print STDERR "KABI: aborting due to kabi changes.\n";
	exit 1;
}
exit 0;
07070100000008000081ed0000000000000000000000016932839300000260000000000000000000000000000000000000000900000000mergedep#!/bin/sh -e

KREL=$1

{ cat /lib/modules/$KREL/modules.dep ;
cat /lib/modules/$KREL/modules.softdep | grep : | sed -e 's/^softdep //' -e 's/ \(pre\|post\):/:/' ; } \
	    | \
while read l ; do
	MOD=$(echo "$l" | sed -e 's/:.*//')
	MOD=$(basename $MOD)
	case $MOD in
	    *.ko.xz|*.ko.gz|*.ko.zst)
		MOD=${MOD%.*};;
	esac
	MOD=${MOD%.ko}
	DEPS="$(echo "$l" | sed -e 's/.*://')"
	moddeps=""
	for dep in $DEPS ; do
		dep=$(basename $dep)
		case $dep in
		    *.ko.xz|*.ko.gz|*.ko.zst)
			dep=${dep%.*};;
		esac
		dep=${dep%.ko}
		moddeps="$moddeps $dep"
	done
	[ -n "$moddeps" ] && echo $MOD:$moddeps ||:
done
07070100000009000081ed0000000000000000000000016932839300000194000000000000000000000000000000000000000700000000moddep#!/bin/sh

dependencies=$1
modules=$2
result=$3

cat $modules | tr ' ' '\n' > $result
echo > $result~

while ! diff -q $result~ $result > /dev/null ; do
	cp $result $result~
	while read MOD ; do
		moddeps="$(grep ^$MOD: $dependencies | sed -e 's/.*://' ||:)"
		for DEP in $moddeps ; do
			if ! grep -q ^$DEP\$ $result ; then
				echo $DEP >> $result
				echo $MOD: $DEP
			fi
		done
	done < $result
done
0707010000000a000081ed0000000000000000000000016932839300000122000000000000000000000000000000000000000900000000modflist#!/bin/sh -e
flist=$1
modules=$2
output=$3
mod_builtin=$4

while read MOD ; do
	[ -n "$MOD" ] || continue
	cat $flist | grep -E "/$MOD[.]ko([.]xz|[.]gz|[.]zst)?\$" >> $output || { grep -q /$MOD[.]ko\$ $mod_builtin && echo Module $MOD built-in ;} || echo Module $MOD missing
done < $modules
0707010000000b000081ed0000000000000000000000016932839300000e07000000000000000000000000000000000000000c00000000modversions#! /usr/bin/perl -w

use File::Basename;
use File::Path;
use File::Find;
use Getopt::Long qw(:config no_ignore_case);
use strict;

my %symbol_type_name = (
    n => 'normal', t => 'typedef', e => 'enum', s => 'struct', u => 'union',
    E => 'enum constant'
);

my %definitions;
my %override;
my %override_locally;
my %locally_unknown;
my %locally_defined;

sub expand_types($);
sub expand_types($) {
    my ($definition) = @_;
    local ($_, $1, $2);

    my @defn = split ' ', $definition;
    for (@defn[1..$#defn]) {
	if (/^(.)#(.*)/) {
	    #print "<<$defn[0] : $_>>\n";
	    next if exists $locally_defined{$_};
	    $locally_defined{$_} = 1;

	    if ($locally_unknown{$_}) {
                print "override " if $override_locally{$_};
		print "$_ $symbol_type_name{$1} $2 { UNKNOWN } \n";
	    } else {
		if (!exists $definitions{$_}) {
		    die "Missing definition of $symbol_type_name{$1} $2\n";
		}
		expand_types("$_ $definitions{$_}");
	    }
	}
    }
    print "override " if $override_locally{$defn[0]};
    print "$definition\n";
}

sub pack_dump($$) {
    my ($dir, $ext) = @_;
    my @files;

    $ext = ".symtypes" unless defined $ext;
    $dir =~ s/\/+$//;

    find(sub ($) { /\Q$ext\E$/ && push @files, $File::Find::name}, $dir);
    map { s/^\Q$dir\E\/(.*)\Q$ext\E$/$1/ } @files;

    foreach my $file (sort @files) {
	print "/* $file.o */\n";

	local *FD;
	open FD, "< $dir/$file$ext"
	    or die "$dir/$file$ext: $!\n";
	while (<FD>) {
	    chomp;

	    my $override = "";
	    if (s/^override //) {
		$override = $&;
	    }

	    if (/^(\S)#(\S+)\s*(.*)/) {
		my $sym = "$1#$2";
		my $definition = $3;

		if (/^$sym\s+$symbol_type_name{$1}\s+$2\s+{\s+UNKNOWN\s+}\s*$/) {
		    $_ = $override . substr($sym, 0, 1) . "##" . substr($sym, 2);
		} else {
		    if (exists $definitions{$sym} && $definitions{$sym} eq $definition) {
			if (($override ne "") == (exists $override{$sym})) {
			    next;
			}
			$_ = "$override$sym";
		    } else {
			$definitions{$sym} = $definition;
			if ($override eq "") {
			    delete $override{$sym};
			} else {
			    $override{$sym} = 1;
			    $_ = "$override$_";
			}
		    }
		}
	    } elsif ($override) {
		    $_ = "$override$_";
	    }
	    print "$_\n";
	}
	close FD;
	print "\n";
    }
}

sub unpack_dump($$) {
    my ($dir, $ext) = @_;

    $ext = ".symref" unless defined $ext;

    while (<STDIN>) {
	next if /^$/;
	chomp;

	if (/^\/\* (.*)\.o \*\//) {
	    close STDOUT;
	    mkpath(dirname("$dir/$1$ext"));
	    open STDOUT, "> $dir/$1$ext"
		or die "$dir/$1$ext: $!\n";
	    %locally_defined = ();
	    %locally_unknown = ();
	    %override_locally = %override;
	    next;
	}

	my $override = /^override\s/;
	s/^override\s//;

	if (/^([^ ])#(#?)([^ ]+) *(.*)$/) {
	    my $sym = "$1#$3";

	    if ($4 ne "") {
		if (/\s+{\s+UNKNOWN\s+}\s*$/) {
		    $locally_unknown{$sym} = 1;
		    $override_locally{$sym} = $override;
		} else {
		    $definitions{$sym} = $4;
		    $locally_unknown{$sym} = 0;
		    $override{$sym} = $override;
		    $override_locally{$sym} = $override;
		}
	    } else {
		$locally_unknown{$sym} = ($2 ne "");
		$override_locally{$sym} = $override;
	    }
	    next;
	} elsif (/^([^# ]*)/) {
		$override_locally{$1} = $override;
	}
	expand_types($_);
    }
}

my ($pack, $unpack, $ext);
GetOptions("pack" => \$pack, "unpack" => \$unpack, "ext:s" => \$ext)
    && ($pack || $unpack) && @ARGV == 1
    or die "USAGE:\t$0 [--ext extension] --pack {dir} > file\n" .
		 "\t$0 [--ext extension] --unpack {dir} < file\n";

pack_dump($ARGV[0], $ext) if $pack;
unpack_dump($ARGV[0], $ext) if $unpack;
0707010000000c000081ed0000000000000000000000016932839300001656000000000000000000000000000000000000000e00000000split-modules#!/bin/bash
# 
# given a Module.base and modules.dep, generate list
# of base / supported / unsupported modules

set -e
export LC_COLLATE=C

usage()
{
	echo "Usage: ${0##*/} -b Module.base [-d dir] [-i] [-e] [-o outdir]"
	echo "  -i    Ignore supported.conf errors"
	echo "  -e    Create the -extra filelist (otherwise, treat all modules as supported)"
}

options=$(getopt -o b:d:o:ie -- "$@")
if test $? -ne 0; then
	usage >&2
	exit 1
fi
eval set -- "$options"
opt_builddir=
opt_out=.
opt_dir=.
opt_ignore_errors=false
opt_extra=false
while test $# -gt 0; do
	opt=$1
	shift
	case "$opt" in
	-b | -d | -o)
		arg=$1
		shift
	esac
	case "$opt" in
	-b)
		opt_builddir=$arg ;;
	-d)
		opt_dir=$arg ;;
	-o)
		opt_out=$arg ;;
	-i)
		opt_ignore_errors=true ;;
	-e)
		opt_extra=true ;;
	--)
		break ;;
	*)
		echo "Unknown option $opt" >&2
		exit 1
	esac
done
if test -z "$opt_builddir"; then
	usage >&2
	exit 1
fi

trap 'rm -rf "$tmp"' EXIT
tmp=$(mktemp -d)
mkdir "$tmp/empty"

find "$opt_dir" -type f \( -name '*.ko' -o -name '*.ko.xz' -o -name '*.ko.gz' -o -name '*.ko.zst' \) -printf '/%P\n' | \
	awk -F/ '{ n=$NF; gsub(/-/, "_", n); sub(/\.ko(\.xz|\.gz|\.zst)?$/, "", n); print n " " $0; }' | \
	sort >"$tmp/all"

err=false
while read mod path; do
	if $opt_extra; then
		support=$(/sbin/modinfo -F supported "$opt_dir/$path")
	else
		support=yes
	fi
	case "$support" in
	yes | external)
		echo "$mod"
		;;
	no)
		;;
	"")
		echo "warning: $mod not listed in supported.conf" >&2
		;;
	*)
		echo "error: invalid support flag for $mod: $support" >&2
		err=true
		;;
	esac
done <"$tmp/all" | sort -u >"$tmp/supp"
if $err; then
	exit 1
fi

modules_dep=$(find "$opt_dir" -type f -name modules.dep)
if test -z "$modules_dep"; then
	echo "Cannot find modules.dep in $opt_dir" >&2
	exit 1
fi
(
	echo '%:
	@echo $@
ifdef EXPLAIN
	@for dep in $^; do echo "$$dep needed by $@"; done >> $(EXPLAIN)
endif
'
	sed -r 's:[^ ]*/([^/]*)\.ko(\.xz|\.gz|\.zst)?\>:\1:g; y/-/_/' "$modules_dep"
) >"$tmp/dep"

add_dependent_modules()
{
	xargs -r make $MAKE_ARGS EXPLAIN=$1 -rRs -C "$tmp/empty" -f "$tmp/dep" | sort -u
}

# base
if test -f "$opt_builddir/Module.base"; then
    sed 'y/-/_/' <"$opt_builddir/Module.base" | add_dependent_modules >"$tmp/base"
else
    touch "$tmp/base"
fi
join -j 1 -o 2.2 "$tmp/base" "$tmp/all" >"$opt_out/base-modules"

# base firmware
kver=$(make $MAKE_ARGS -s -C "$opt_builddir" kernelrelease)
fw_dir=/lib/firmware/$kver
test -d $opt_dir/usr$fw_dir && fw_dir=/usr$fw_dir
if test -d "$opt_dir$fw_dir"; then
	join <(/sbin/modinfo -F firmware \
		$(sed "s:^:$opt_dir:" "$opt_out/base-modules") | sort) \
	     <(find "$opt_dir$fw_dir" -type f -printf '%P\n' | sort)
fi | sed "s:^:$fw_dir:" >"$opt_out/base-firmware"

# kmps
for f in "$opt_builddir"/Module.*-kmp; do
	test -f "$f" || continue
	kmp=${f##*/Module.}
	sed 'y/-/_/' <"$f" >"$tmp/$kmp"
	join -j 1 -o 2.2 "$tmp/$kmp" "$tmp/all" >"$opt_out/$kmp-modules"
	cat "$tmp/$kmp"
done | sort -u >"$tmp/kmp-all"
join -v1 "$tmp/supp" "$tmp/kmp-all" >"$tmp/supp-main"

# main
add_dependent_modules "$tmp/supp-explain" <"$tmp/supp-main" >"$tmp/supp-all"
if ! cmp -s "$tmp/supp-main" "$tmp/supp-all"; then
	# FIXME: Error message not accurate if a supported KMP module is
	# needed by a module in the main package
	echo "The following unsupported modules are used by supported modules:" >&2
	join -j1 -a2 <(sort "$tmp/supp-explain") \
		 <(join -v2 "$tmp/supp-main" "$tmp/supp-all") >&2
	echo "Please fix supported.conf." >&2
	if ! $opt_ignore_errors; then
		exit 1
	fi
fi
join -j 1 -o 2.2 "$tmp/supp-all" "$tmp/all" >"$opt_out/main-modules"

# unsupported
join -j 1 -v 2 -o 2.2 <(sort -u "$tmp/supp-all" "$tmp/kmp-all") "$tmp/all" | sort -u > "$opt_out/unsupported-modules"

# split again to extra and optional
if $opt_extra && test -f "$opt_builddir/Module.optional"; then

    declare -A modmarks wcmarks
    wcpaths=()
    while read mark path; do
	case $path in
	    *.ko.xz|*.ko.gz|*.ko.zst)
		path=${path%.*};;
	esac
	path=${path%.ko}
	mod=${path##*/}
	mod=$(echo "$mod" | sed 'y/-/_/')
	modmarks["$mod"]="$mark"
	# paths with wildcards need to be verified sequentially, so we keep
	# the paths in the array wcpaths and each mark in wcmarks[]
	case "$path" in
	    *[\*\?\[]*)
		wcpaths[${#wcpaths[@]}]="$path"
		wcmarks["$path"]="$mark";;
	esac
    done < "$opt_builddir/Module.optional"

    while read xpath; do
	path=$xpath
	case $path in
	    *.ko.xz|*.ko.gz|*.ko.zst)
		path=${path%.*};;
	esac
	path=${path%.ko}
	mod=${path##*/}
	mod=$(echo "$mod" | sed 'y/-/_/')
	x=${modmarks["$mod"]}
	if [ -n "$x" ]; then
	    test x"$x" = x"-" && echo "$xpath"
	    continue
	fi

	# unmatched modules must be handled via wildcard
	path=${path#/usr}
	path=${path#/lib/modules/*/kernel/}
	for m in "${wcpaths[@]}"; do
	    case "$path" in
		($m)
		    test x${wcmarks["$m"]} = x"-" && echo "$xpath"
		    break;;
	    esac
	done
    done < "$opt_out/unsupported-modules" | sort > "$tmp/unsupp-extra"

    cat "$tmp/supp-all" "$tmp/kmp-all" "$tmp/unsupp-extra" | \
	sed -r 's:[^ ]*/([^/]*)\.ko(\.xz|\.gz|\.zst)?\>:\1:g; y/-/_/' | sort -u > "$tmp/unsupp-extra-all"
    add_dependent_modules "$tmp/unsupp-explain" <"$tmp/unsupp-extra-all" >"$tmp/unsupp-extra-dep"
    if ! cmp -s "$tmp/unsupp-extra-all" "$tmp/unsupp-extra-dep"; then
	echo "The following optional modules are used by extra modules:" >&2
	join -j1 -a2 <(sort "$tmp/unsupp-explain") \
		 <(join -v2 "$tmp/unsupp-extra-all" "$tmp/unsupp-extra-dep") >&2
	echo "Please fix supported.conf." >&2
	if ! $opt_ignore_errors; then
		exit 1
	fi
    fi

    join -j 1 -v 2 "$tmp/unsupp-extra" "$opt_out/unsupported-modules" > "$opt_out/optional-modules"
    mv "$tmp/unsupp-extra" "$opt_out/unsupported-modules"
fi

exit 0
0707010000000d000081ed000000000000000000000001693283930000019b000000000000000000000000000000000000000b00000000splitflist#!/bin/bash -e

package="$1"
present="$2"
ghost="$3"

missing=""

rpm -ql --noghost "$package" | while read x ; do
	[ -e "$x" -o -L "$x" ] && echo "$x" >> "$present" || echo Missing file "$x"
done

rpm -q --qf '[%{FILEFLAGS} %{FILENAMES} 0%{FILEMODES:octal} %{FILESIZES} %{FILEMTIMES} %{FILELINKTOS}\n]' $package | while read -a line; do
	[ $[line[0]&64] = 64 ] || continue
	echo "${line[@]:1}"
done > "$ghost"
07070100000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000b00000000TRAILER!!!
openSUSE Build Service is sponsored by