1#!/usr/bin/bash
2
3###############################################################################
4#
5# Copyright (C) 2009-2013 Nintendo.  All rights reserved.
6#
7# These coded instructions, statements, and computer programs contain
8# proprietary information of Nintendo of America Inc. and/or Nintendo
9# Company Ltd., and are protected by Federal copyright law.  They may
10# not be disclosed to third parties or copied or duplicated in any form,
11# in whole or in part, without the prior written consent of Nintendo.
12#
13###############################################################################
14
15FLG=0
16#==============================
17#MAIN FRAMEWORK
18#This script contains functions
19#used globally between the
20#installation and debug scripts
21#
22#VERSION 1.9
23#==============================
24
25#==============================
26#        GLOBAL DEFINES
27#==============================
28_initFlags(){
29  TITLE_USB=2 #debug/install title on USB
30  TITLE_MLC=4 #debug/install title on NAND
31
32  #launch NOT PCFS
33  TITLE_HINT=$((TITLE_USB|TITLE_MLC))
34}
35initFlags(){
36  _initFlags
37  DBG_BUILD=8 #is debug build
38}
39
40#==============================
41#      GLOBAL FUNCTIONS
42#==============================
43
44#send message and exit with error
45die(){
46  echo "$@"
47  exit 1
48}
49
50#test if a value is numeric
51not_numeric(){
52  printf '%d' "0x$TID" &>/dev/null
53  if [ $? == 0 ];then
54	echo -ne false
55  else
56	echo -ne true
57  fi
58}
59
60#make sure that the user input for title ID is valid ($TID)
61verifyTID(){
62  if [ ${#TID} -gt 16 ] ||
63  `not_numeric "$TID"`;then
64	die Invalid Title ID
65  fi
66}
67
68#pad the title id ($TID)
69padTID(){
70  for((i=${#TID};i<16;++i));do
71	TID=0"$TID"
72  done
73}
74
75doSync(){
76  trap runTrap INT
77  if [ "$SESSION_MANAGER" == 1 ];then
78	syncsession
79	if [ $? != 0 ];then
80	  die Sync Failed
81	fi
82  fi
83}
84
85toLower(){
86  echo -ne "$@" | tr [:upper:] [:lower:]
87}
88
89nextFile(){
90  FIL="${tmp[i]}"
91  if [ -z "$FIL" ];then
92	x=0
93  else
94	x=1
95  fi
96}
97
98#gets the full filename for the RPX
99_getRPX(){
100  #empty?
101  if [ -z "$FIL" ];then
102	#current dir, find rpx
103	tmp=(./*)
104	i=0
105	nextFile
106	while [ $x != 0 ];do
107	  if [ $(toLower "${FIL:${#FIL}-4}") == .rpx ];then
108		tmp=
109		echo Working with RPX:"
110$FIL
111"
112		return
113	  fi
114	  let i=i+1
115	  nextFile
116	done
117	echo No RPX found in current working directory...'
118Please specify an RPX or CD to a directory with an RPX...
119'
120	displayHelp 1
121  fi
122  #append .rpx
123  FIL="$FIL".rpx
124
125  #check if the RPX exists
126  if [ ! -f "$FIL" ];then
127	FIL="${FIL/$CAFE_ROOT/\$CAFE_ROOT}"
128	FIL="${FIL/system\/bin\/$TOOLCHAIN\/$PLATFORM/system/bin/\$TOOLCHAIN/\$PLATFORM}"
129	die This file does not exist:"
130$FIL"
131  fi
132}
133getRPX(){
134  _getRPX
135  #get real path
136  FIL=$(realpath "$FIL")
137  #warn user about debug version
138  if [[ $((FLG&DBG_BUILD)) == 0 &&
139  $(awk -v a=$(toLower "$FIL") -v b=/debug 'BEGIN{printf index(a,b)}') != 0 ]];then
140	echo '
141=====================WARNING==========================
142     Found a directory that starts with "debug"!
143If running a DEBUG version, Please specify option "-b"
144======================================================
145
146Continuing execution in 3 seconds...'
147    sleep 3
148  fi
149}
150
151#main trap function
152_runTrap(){
153  unset FIL
154
155  #stop cafe
156  if [ $((FLG&1)) != 0 ];then
157	echo '
158'Stopping cafe...
159	cafestop >/dev/null
160	FLG=$((FLG&(~1)))
161  fi
162}
163#trap wrapper
164runTrap(){
165  _runTrap
166  exit 0
167}
168
169#==============================
170#        SCP SCRIPTING
171#==============================
172
173#script writer
174writeSCP(){
175  #append \r to the data
176  echo -e "$1\r" >> "$scp"
177
178  #check if write was successful
179  if [ $? != 0 ];then
180	die '
181'Failed to write custom script
182  fi
183}
184
185#write delay
186writeSCPDelay(){
187  writeSCP 'echo ===Bug Work-around===\r
188sleep 10'
189}
190
191#remove custom script
192_closeSCP(){
193  rm -f "$scp"
194}
195
196#close function wrapper
197closeSCP(){
198  if [ -e "$scp" ];then
199	_closeSCP
200  fi
201}
202
203#script trap wrapper
204scpTrap(){
205  _runTrap
206  closeSCP
207  exit 0
208}
209
210#open a new script session
211openSCP(){
212
213  #init file names
214  scp="$CAFE_MLC_DIR/xtr$$".scp
215
216  #trap scpTrap
217  trap scpTrap INT
218
219  #create the custom script
220  echo -ne '' > "$scp"
221  if [ $? != 0 ];then
222	die '
223'Failed to create the custom script
224  fi
225
226  #bug work-around
227  writeSCPDelay
228}
229
230#run custom script
231runSCP(){
232
233  #finish off custom script
234  writeSCP '\r
235exit'
236
237  #source the custom script
238  FLG=$((FLG|1))
239  cafeon -nobgd -nosync -c "source '-c' '-q' /vol/storage_hfiomlc01/xtr$$.scp" -c exit
240  FLG=$((FLG&(~1)))
241
242  #return to previous state
243  _closeSCP
244}
245
246#==============================
247#        RUN DEBUG
248#==============================
249
250#run an RPX for debugging
251runDBG(){
252  #where are we debugging from
253  i=$((FLG&TITLE_HINT))
254  if [ $i == $TITLE_HINT ];then
255	die Cannot specify '-u and -n'
256  elif [ $i != 0 ];then
257	if [ $i == $TITLE_USB ];then
258	  i=usb
259	else
260	  i=mlc
261	fi
262	i="-e mcp:launch_hint:$i"
263  else
264	i=
265  fi
266
267  #check if debug build
268  if [ $((FLG&DBG_BUILD)) != 0 ];then
269	i="-b $i"
270  fi
271
272  #run the RPX for debugging
273  FLG=$((FLG|1))
274  caferun -d multi -z $i "$FIL" $ARG
275  FLG=$((FLG&(~1)))
276}
277