1#!/bin/bash 2 3############################################################################### 4# Verify preload file meets the necessary requirements for preloading an app 5# 6# Copyright 2012 Nintendo. All rights reserved. 7# 8# These coded instructions, statements, and computer programs contain 9# proprietary information of Nintendo of America Inc. and/or Nintendo 10# Company Ltd., and are protected by Federal copyright law. They may 11# not be disclosed to third parties or copied or duplicated in any form, 12# in whole or in part, without the prior written consent of Nintendo. 13############################################################################### 14 15############################################################################### 16# Defines 17############################################################################### 18 19# 20 megabyte cap 20MEMORY_CAP=$((20*1024*1024)) 21 22PRELOAD_FILE="preload.txt" 23 24############################################################################### 25# Functions 26############################################################################### 27 28function display_help { 29 echo -e "Preload File Verification\n" 30 echo -e "This script verifies that the $PRELOAD_FILE file meets"\ 31 "all necessary requirements for preloading an application.\n" 32 echo -e "Usage: preloadcheck.sh [options] [optional path to code folder]\n " 33 echo -e "Options:\n"\ 34 " -h : (help) display options\n"\ 35 " -g : generate preload file" 36} 37 38function check_file_exists_silent { 39 if [ ! -f $working_dir$1 ] 40 then 41 return 1 42 fi 43 return 0 44} 45 46function check_file_exists { 47 if ! check_file_exists_silent $1 48 then 49 echo "Error: Unable to locate the file '$1'" 50 let error_count++ 51 return 1 52 fi 53 return 0 54} 55 56function check_text { 57 local text=(`cat $working_dir$2 | tr -cs '[:upper:][:lower:][:punct:][:digit:]' '[\n*]' | grep $1`) 58 59 if [ ${#text[@]} -eq 1 ]; then return 0; fi 60 61 if [ ${#text[@]} -eq 0 ] 62 then 63 echo "Error: '$1' not found in the file '$2'" 64 else 65 echo "Error: Multiple instances of '$1' found in the file '$2'" 66 fi 67 68 let error_count++ 69 return 1 70} 71 72function get_filesize { 73 if ! check_file_exists_silent $1 74 then 75 echo 0 76 else 77 echo `stat -c %s $working_dir$1` 78 fi 79} 80 81function get_content_size { 82 local size=0 83 preload_contents=($(cat $working_dir$PRELOAD_FILE | tr '\r' ' ')) 84 for i in "${preload_contents[@]}" 85 do 86 let size+=$(get_filesize $i) 87 done 88 echo $size 89} 90 91function append_text { 92 echo -n $1' ' >> $working_dir$2 93} 94 95############################################################################### 96# Main 97############################################################################### 98 99relative_dir="" 100working_dir=$PWD 101generate_file=0 102 103# Process command line arguments 104for var in "$@" 105do 106 case "$var" in 107 -h) display_help 108 exit 109 ;; 110 -g) generate_file=1 111 ;; 112 *) 113 # Relative dir must not start with forward slash, but must 114 # end with one 115 relative_dir=$var 116 [[ $relative_dir = /* ]] && relative_dir=`echo $relative_dir | sed 's/^.//'` 117 [[ $relative_dir != */ ]] && relative_dir="$relative_dir"/ 118 working_dir=$working_dir/$relative_dir 119 break 120 ;; 121 esac 122done 123 124# Ensure working_dir ends with forward slash 125[[ $working_dir != */ ]] && working_dir="$working_dir"/ 126 127if [ $generate_file -eq 1 ] 128then 129 if check_file_exists_silent $PRELOAD_FILE 130 then 131 echo "Error: '$PRELOAD_FILE' already exists in the directory" 132 exit 133 fi 134 # Create the preload file 135 touch $working_dir$PRELOAD_FILE 136else 137 if ! check_file_exists $PRELOAD_FILE 138 then 139 exit 140 fi 141fi 142 143error_count=0 144 145# Check that the cos/app xml files exist and are listed in preload 146if check_file_exists "cos.xml" 147then 148 if [ $generate_file -eq 0 ] 149 then 150 check_text "cos.xml" $PRELOAD_FILE 151 else 152 append_text "cos.xml" $PRELOAD_FILE 153 fi 154fi 155 156if check_file_exists "app.xml" 157then 158 if [ $generate_file -eq 0 ] 159 then 160 check_text "app.xml" $PRELOAD_FILE 161 else 162 append_text "app.xml" $PRELOAD_FILE 163 fi 164fi 165 166# If the preload file was generated, get the name of the rpx and add it 167if [ $generate_file -eq 1 ] 168then 169 rpx_file=(`find $working_dir -maxdepth 1 -name '*.rpx'`) 170 if [ ${#rpx_file[@]} -eq 1 ] 171 then 172 rpx_file=`basename $rpx_file` 173 file_size=$(get_filesize $rpx_file) 174 if [ $file_size -gt $MEMORY_CAP ] 175 then 176 echo "Warning: '$rpx_file' exceeds the maximum memory size of"\ 177 "$MEMORY_CAP bytes, and will not be added to '$PRELOAD_FILE'" 178 else 179 append_text $rpx_file $PRELOAD_FILE 180 fi 181 else 182 if [ ${#rpx_file[@]} -eq 0 ] 183 then 184 echo "Error: No rpx file exists in the directory" 185 else 186 echo "Error: Multiple rpx files exist in the directory."\ 187 "Unabled to determine which one to add to '$PRELOAD_FILE'" 188 fi 189 let error_count++ 190 unset rpx_file 191 fi 192else 193 # Retieve the name of the rpx from the preload file 194 rpx_file=(`cat $working_dir$PRELOAD_FILE | tr -cs '[:upper:][:lower:][:punct:][:digit:]' '[\n*]' | grep '\.rpx'`) 195 if [ ${#rpx_file[@]} -eq 1 ] 196 then 197 if ! check_file_exists $rpx_file 198 then 199 unset rpx_file 200 fi 201 else 202 if [ ${#rpx_file[@]} -eq 0 ] 203 then 204 echo "Warning: No rpx file specified in '$PRELOAD_FILE'" 205 # Attempt to retrieve the rpx name from the directory 206 rpx_file=(`find $working_dir -maxdepth 1 -name '*.rpx'`) 207 if [ ${#rpx_file[@]} -eq 1 ] 208 then 209 rpx_file=`basename $rpx_file` 210 fi 211 else 212 echo "Error: Multiple rpx files specified in '$PRELOAD_FILE'" 213 let error_count++ 214 unset rpx_file 215 fi 216 fi 217fi 218 219if [ $generate_file -eq 1 ] 220then 221 content_size=$(get_content_size) 222else 223 # Verify that all listed rpls exist in the directory 224 rpl_file=(`cat $working_dir$PRELOAD_FILE | tr -cs '[:upper:][:lower:][:punct:][:digit:]' '[\n*]' | grep '\.rpl'`) 225 for i in "${rpl_file[@]}" 226 do 227 check_file_exists $i 228 done 229fi 230 231# Use dumprpl to return all statically bound rpls and verify that they 232# exist in the directory and are listed in the preload file. This is a 233# recurssive process as each rpl may have others statically bound to it 234rpl_search=($rpx_file) 235while [ ${#rpl_search[@]} -ne 0 ] 236do 237 for i in $rpl_search 238 do 239 rpl_temp=("${rpl_temp[@]}" `dumprpl -imports $relative_dir$i | grep 'Imports' |\ 240 tr -cs '[:upper:][:lower:][:punct:][:digit:]' '[\n*]' |\ 241 grep -E 'fimport_\w*|dimport_\w*' | cut -c10- | cut -f1 -d "," | sort -u`) 242 done 243 244 unset rpl_search 245 246 for i in "${rpl_temp[@]}" 247 do 248 i=$i".rpl" 249 250 # Only concerned with rpls that exist in the directory 251 if ! check_file_exists_silent $i; then continue; fi 252 253 # Check that the rpl is listed in the preload file 254 if [ $generate_file -eq 0 ] 255 then 256 check_text $i $PRELOAD_FILE 257 else 258 file_size=$(get_filesize $i) 259 if [ $(($content_size+$file_size)) -gt $MEMORY_CAP ] 260 then 261 echo "Warning: Unable to add $i to '$PRELOAD_FILE';"\ 262 " maximum content size exceeded" 263 else 264 append_text $i $PRELOAD_FILE 265 content_size=$(($content_size+$file_size)) 266 fi 267 fi 268 269 # Add any rpls that have not already been dumped to the search list 270 match=$(echo "$rpl_files:0}" | grep -o $i) 271 [[ -z $match ]] && rpl_files=("${rpl_files[@]}" $i) \ 272 && rpl_search=("${rpl_search[@]}" $i) 273 done 274 275 unset rpl_temp 276done 277 278# Check that total size of all files in the preload file does not exceed max 279content_size=$(get_content_size) 280if [ $content_size -gt $MEMORY_CAP ] 281then 282 echo "Error: The contents of '$PRELOAD_FILE' is $content_size bytes which"\ 283 "exceeds the maximum allowed size of $MEMORY_CAP bytes" 284 let error_count++ 285fi 286 287if [ $error_count -eq 0 ] 288then 289 echo -e "No errors detected." 290else 291 echo -e "\nErrors were encountered. Pleae check that $PRELOAD_FILE meets"\ 292 "all necessary\nrequirements." 293fi