Home Home > GIT Browse
summaryrefslogtreecommitdiff
blob: 816e3c501d6437b72c821a632624d8676b3204a3 (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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#! /bin/bash

LC_ALL=POSIX

usage() {
    cat <<EOF
Usage: ${0##*/} [-i module] [-x module] [-Nv] {module|rpm} ...

-i	Include the specified modules (glob expression).

-x	Exclude the specified modules (glob expression).

-N	Don't try to combine modalias tags that only differ in one character.

-v	Verbose: report which modules define which aliases.
EOF
    exit $1
}

ARGS=("$@")

options=`getopt -o i:x:vNh -- "$@"`

if [ $? -ne 0 ]
then
    usage 2
fi

eval set -- "$options"

opt_combine=1
while :; do
    case "$1" in
    -i)
	include="$include ${2%.ko}"
	shift 2
	;;
    -x)
	exclude="$exclude ${2%.ko}"
	shift 2
	;;
    -v)
	opt_verbose=1
	shift ;;
    -N)
	opt_combine=
	shift ;;
    -h)
	usage 0
	;;
    --)
	shift
	break
	;;
    esac
done

process_module() {
    declare module=$1 base=${1##*/} aliases

    if [ -n "$include" ]; then
	included=
	for x in $include; do
	    eval "case \"\${base%.ko}\" in (${x%.ko}) included=1;; esac"
	done
    else
	included=1
    fi
    for x in $exclude; do
	eval "case \"\${base%.ko}\" in (${x%.ko}) included=;; esac"
    done
    [ -n "$included" ] || return

    aliases="$(/sbin/modinfo -F alias "$module" \
	       | sed -nre 's@^.+:.+$@Supplements: modalias(&)@p')"
    if [ -n "$aliases" ]; then
	eval "processed_module_${base//[^a-zA-Z0-9_]/_}=$base"
	echo "$aliases" \
	| if [ -n "$opt_verbose" ]; then
	    sed -e "s@\$@ # $base@"
	else
	    cat
	fi
    fi
}

print_modaliases() {
    declare class=$1 variants=$2 pos=$3
    if [ -n "$variants" ]; then
	echo "${class:0:pos}[$variants]${class:pos+1}"
    else
	[ -z "$class" ] || echo "$class"
    fi
}

combine_modaliases() {
    declare tag class variants pos n
    read class
    while read tag; do
	for ((n=0; n<${#class}; n++)); do
	    if [ "*" != "${class:n:1}" -a \
		 "${class:0:n}" = "${tag:0:n}" -a \
		 "${class:n+1}" = "${tag:n+1}" ] &&
	       ( [ -z "$pos" ] || [ $n = $pos ] ); then
		variants="${variants:-${class:n:1}}${tag:n:1}"
		pos=$n
		break
	    fi
	done
	if [ $n -eq ${#class} ]; then
	    print_modaliases "$class" "$variants" "$pos"
	    variants=
	    pos=
	    class=$tag
	fi
    done
    print_modaliases "$class" "$variants" "$pos"
}

tmp=$(mktemp -t ${0##*/}.XXXXXX)
trap "rm -f $tmp" EXIT

for file in "$@"; do
    case "$(file -b "$file")" in
    RPM*)
	tmpdir=$(mktemp -td ${0##*/}.XXXXXX)
	rpm2cpio "$file" | ( cd $tmpdir && cpio -dim --quiet )
	for module in $(find $tmpdir -type f -name '*.ko'); do
	    process_module "$module" >> $tmp
	done
	rm -rf $tmpdir
	;;
    ELF*)
	process_module "$file" >> $tmp
	;;
    *)
	if [ -e "$file" ]; then
	    echo "File type of $file not supported" >&2
	    exit 1
	fi
	file2=$(/sbin/modinfo -F filename "${file%.ko}")
	if ! [ -e "$file2" ]; then
	    echo "No module $file found" >&2
	    exit 1
	fi
	process_module "$file2" >> $tmp
	;;
    esac
done

if [ -n "${!processed_module_*}" ]; then
    echo "# Modules:" $(for m in ${!processed_module_*}; do echo ${!m}; done \
			| sort -u)

    sort -u $tmp \
    | if [ -n "$opt_combine" ]; then
	combine_modaliases
    else
	cat
    fi

    echo "# Generated with: ${0##*/} ${ARGS[*]}"
fi

# vim:softtabstop=4 shiftwidth=4