summaryrefslogtreecommitdiffstats
path: root/portdep.sh
blob: cef8c6cf4a35d69c7f97273c912daf6ca806910c (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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
#!/bin/bash
#
#       For each package in a list, run a set of one or more scanners
#       over the source files looking for potential machine dependent
#       code (i.e., portability dependencies).
#

#-- functions
usage () {
        name=$(basename $0)
        echo "$name: scan source files for portability issues"
        echo
        echo "$name --pkglist <filename> --distro <distroname>"
        echo "      [--keep] [--output <filename>] [--workdir <dirname>]"
        echo
        echo "where:"
        echo "    --keep                => if given, do not remove any of"
        echo "                             the downloaded sources (WARNING!"
        echo "                             this is a LOT of GiBs)"
        echo "    --pkglist <filename>  => list of packages to scan,"
        echo "                             one package name per line"
        echo "    --distro <filename>   => one of: fedora, debian"
        echo "    --output <filename>   => where to report results"
        echo "                             (default: scan.results)"
        echo "    --workdir <dirname>   => temporary working directory"
        echo "                             for source trees and other"
        echo "                             stuff (default: ./work)"
}

run_scanners () {
        #-- run all scanners listed in ./scanners
        #   Each file is an independent executable, and will be passed
        #   be passed the working directory, package name, and the full
        #   path to the source tree.  In turn, whatever is executed needs
        #   to return a single output line that has this form:
        #
        #       <scanner-name>: <value>
        #
        #   For example:
        #       Dot-S-Files: 3
        #
        #   The name may not have white space in it, and a value of 0
        #   means the scan worked but found nothing, a value > 0 means
        #   something possibly problematic was found (larger implies more
        #   problematic), and a value of -1 means an error occurred.
        #   
        workdir="$1"
        pkg=$2
        src=$3
        echo >> $output
        echo "Package: $pkg" >> $output
        echo "Source: $(basename $src)" >> $output
        for ii in $(ls scanners)
        do
                result=$(scanners/$ii $workdir $src 2>&1)
                echo "$result" >> $output
        done
}

#-- input argument handling
distro=""
keep="no"
output="scan.results"
pkglist=""
workdir="$(pwd)/work"

while [ $# -gt 0 ]
do
        arg="$1"
        shift
        case $arg in
        --distro)               # which unpacking scheme is needed for source
                if [ $# -gt 0 ]
                then
                        dname=$1
                        shift
                        case $dname in
                        fedora|debian)
                                distro=$dname
                                ;;
                        *)
                                echo "? no such distro: $dname"
                                exit 1
                        esac
                else
                        echo "? must supply distro name"
                        exit 1
                fi
                ;;
        --keep)
                keep="yes"
                ;;
        --output)               # where to store the scan results
                if [ $# -gt 0 ]
                then
                        output=$1
                else
                        echo "? must supply output file name"
                        exit 1
                fi
                ;;
        --pkglist)              # which packages to scan
                if [ $# -gt 0 ]
                then
                        plist=$1
                        shift
                        if [ -f $plist ]
                        then
                                pkglist=$plist
                        else
                                echo "? no such file: $plist"
                                exit 1
                        fi
                else
                        echo "? must supply package list file name"
                        exit 1
                fi
                ;;
        --workdir)              # temporary working dir for source trees
                if [ $# -gt 0 ]
                then
                        workdir=$1
                else
                        echo "? must supply work directory name"
                        exit 1
                fi
                ;;
        *)
                echo "? unknown parameter: $arg"
                usage
                exit 1
        esac
done

if [ -z $distro ]
then
        echo "? --distro is a required parameter"
        exit 1
fi

if [ -z $pkglist ]
then
        echo "? --pkglist is a required parameter"
        exit 1
fi

#-- make sure we know how to handle the distro
#   Each file needs to define a function called get_source that will
#   be passed the working directory and a package name, and that must
#   return the full absolute path to the source tree.
#
#   There must also be a similar remove_source (same parameters) that
#   cleans up and removes all sources for a package.
if [ ! -f packages/$distro ]
then
        echo "? internal error: no script for distro $distro"
        exit 2
fi
source packages/$distro

#-- for each package in the list, scan it and report results
[ ! -d "$workdir" ] && mkdir -p "$workdir"
rm -f $output
cat $pkglist | (
        read line
        while [ "$line" ]
        do
                echo "scanning => $line"
                res=$(get_source "$workdir" $line)
                if [ ! -z "$res" ]
                then
                        run_scanners "$workdir" $line $res
                fi
                if [ $keep == "no" ]
                then
                        remove_source "$workdir" $line
                fi
                read line
        done
)