#!/bin/bash # # Copyright (c) 2012, Al Stone # # This program is free software; you can redistribute it and/or # modify it under the terms of version 2 (only) of the GNU General # Public License as published by the Free Software Foundation. # # # 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 --distro " echo " [--keep] [--output ] [--workdir ]" 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 => list of packages to scan," echo " one package name per line" echo " --distro => one of: fedora, debian" echo " --output => where to report results" echo " (default: scan.results)" echo " --workdir => 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: # # : # # 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 )