restore the framebuffer status on PND exit
[pandora-libraries.git] / testdata / scripts / pnd_run.sh
1 #!/bin/bash
2  
3 #/etc/sudoers needs to be adjusted if you touch any of the sudo lines
4  
5 # look at the comments in the CLOSE_X part, adjust 
6 #use "lsof /usr/lib/libX11.so.6 | awk '{print $1}'| sort | uniq > whitelist" with nothing running to generate the whitelist
7  
8 #todo - no proper order
9 #validate params better
10 #make uid/pnd_name mandatory (and rename var, its confusing!)
11 #find a clean way of shutting down x without a fixed dm, mabye avoid nohup usage somehow
12 #add options to just mount iso without union and to mount the union later
13
14 #SCRIPT_DIR=$(echo $(dirname $(which $0))|sed 's#^\.#'"$(pwd)"'#')
15 #. $SCRIPT_DIR/pnd_loging
16 #PND_LogDateFormat=PND_Time
17
18 PND_MOUNT_DIR="/mnt/pnd"
19 UNION_MOUNT_DIR="/mnt/utmp"
20 CPUSPEEDSCRIPT=/usr/pandora/scripts/op_cpuspeed.sh
21
22 #=============================================================================
23 # Log functions
24
25 PND_isInteractive=0
26 PND_Start() {
27         if [ $(ps -o tty,pid 2>/dev/null|grep $$|awk 'BEGIN{R=0}/pts/{R=1}END{print R}') -eq 1 ];then
28                 PND_isInteractive=1
29                 exec 3>&1       # duplicate stdout so we can still write to screen after the log redirect
30         fi
31         {
32         echo "======================================================================================="
33         for v in $PND_HEADER;do
34                 printf "%-15s : %s\n" "$v"  "$(eval "echo \${$v:-'<unset>'}")"
35         done
36         echo "======================================================================================="
37         }>"$PND_LOG"
38 }
39
40 PND_checkLog() {
41 awk 'BEGIN{R=0}END{exit R}
42 /cannot open display/||/unary operator expected/||/No such file or directory/||/command not found/{R=R+1}
43 {IGNORECASE=1}
44 !/gpg-error/&&/ERROR/||/FAILED/{R=R+1}
45 {IGNORECASE=0}' < "$PND_LOG"
46 }
47
48 PND_Stop() {
49         local RC=$?
50         PND_checkLog
51         RC=$(( $RC + $? ))      # trying to find error in the logs
52         {
53         echo "======================================================================================="
54         echo "Return code is : $RC"
55         }>>"$PND_LOG"
56         return $RC
57 }
58
59 PND_BeginTask() {
60         export PND_TASK_NAME="$*"
61         echo "[ START ]--- $PND_TASK_NAME ----------"
62         if [ $PND_isInteractive -eq 1 ];then
63                 printf "$PND_TASK_NAME"  >&3
64         fi
65 }
66
67 PND_EndTask() {
68         local RC="$?"
69         local STATUS=""
70         local COLOR=""
71         local X=""
72         if [ $RC -eq 0 ];then 
73                 STATUS=SUCCESS
74                 COLOR="\\033[32m"
75         else
76                 STATUS=FAILED
77                 COLOR="\\033[31m"
78         fi
79         
80         printf "[%7s]--- $PND_TASK_NAME ----------\n" "$STATUS"
81         if [ $PND_isInteractive -eq 1 ];then
82                 printf "\r%s\033[70G[$COLOR%7s\033[m]\n" "$PND_TASK_NAME" "$STATUS" >&3
83         fi
84         unset PND_TASK_NAME
85         return $RC
86 }
87
88 PND_WaitFor() {
89         [ $# -gt 0 ]||return 1
90         local l_test="$1"
91         local l_name=${2:-"Wait succes of $1"}
92         local l_cnt=${3:-12}
93         local l_sleep=${4:-10}
94         local C=0
95         PND_BeginTask $l_name
96         while [ $C -lt $l_cnt ] && ! eval $l_test;do
97                 sleep $l_sleep;C=$(($C + 1));
98         done
99         [ $C -lt $l_cnt ]
100         PND_EndTask
101 }
102
103 PND_Exec() {
104         local CMD="$*"
105         {
106         if [ $PND_ISEXEC -eq 0 ];then
107                 PND_ISEXEC=1
108                 exec 3>&1               # 
109         fi
110         export PND_INTERACTIVE=2
111         $* 2>&1
112         RES=$(( $? + $PND_ERRORS ))
113         echo "<result>$RES</result>"
114         PND_ISEXEC=0
115         exec 3>&-
116         }|{
117         while read line;do
118                 if echo "$line"|grep -q "<result>.*</result>";then
119                         return $(( $(echo $line|sed 's/<[^>]*>//g') + $PND_ERRORS ))
120                 elif ! echo "$line"| $(eval $PND_OUT_CHECK); then
121                         PND_Error "$line";
122                 else
123                         PND_Print "$line";
124                 fi
125         done
126         return $PND_ERRORS
127         }
128 }
129
130
131
132 #=============================================================================
133 # Utility functions
134
135 showHelp() {
136         cat <<endHELP
137 Usage:
138   pnd_run.sh -p file.pnd -e cmd [-a args] [-b pndid] [-s path] [-c speed] [-d [path]] [-x] [-m] [-u]
139     -p file.pnd : Specify the pnd file to execute
140     -e cmd      : Command to run
141     -a args     : Arguments to the command
142     -b pndid    : name of the directory mount-point ($UNION_MOUNT_DIR/pndid) (Default: name of the pnd file)
143     -s path     : Directory in the union to start the command from
144     -o speed    : Set the CPU speed
145     -d [path]   : Use path as source of the overlay. (Default: pandora/appdata/pndid)
146     -x          : Stop X before starting the apps
147     -m          : Only mount the pnd, dont run it (-e become optional)
148     -u          : Only umount the pnd, dont run it (-e become optional)
149 endHELP
150 }
151
152 list_using_fs() {
153         for p in $(fuser -m $1 2>/dev/null);do ps hf $p;done
154 }
155
156
157 #=============================================================================
158 # CPU speed functions
159 PND_getCPUSpeed() {
160         cat /proc/pandora/cpu_mhz_max
161 }
162
163 PND_setCPUSpeed() {
164         unset CURRENTSPEED
165         if ! [ -f "$CPUSPEED_FILE" ] && [ ! -z "$PND_CPUSPEED" ]; then
166                 if [ ${PND_CPUSPEED} -gt $(PND_getCPUSpeed) ]; then 
167                    CURRENTSPEED=$(PND_getCPUSpeed)
168                    case "$(zenity --title="set cpu speed" --height=350 --list --column "id" --column "Please select" --hide-column=1 \
169                                   --text="$PND_NAME suggests to set the cpu speed to $PND_CPUSPEED MHz to make it run properly.\n\n Do you want to change the cpu speed? (current speed: $(PND_getCPUSpeed) MHz)\n\nWarning: Setting the clock speed above 600MHz can be unstable and it NOT recommended!" \
170                                   "yes" "Yes, set it to $PND_CPUSPEED MHz" \
171                                   "custom" "Yes, select custom value" \
172                                   "yessave" "Yes, set it to $PND_CPUSPEED MHz and don't ask again" \
173                                   "customsave" "Yes, set it to custom speed and don't ask again" \
174                                   "no" "No, don't change the speed" \
175                                   "nosave" "No, don't chage the speed and don't ask again")" in
176                         "yes")
177                                 sudo $CPUSPEEDSCRIPT $PND_CPUSPEED
178                                 ;;
179                         "custom")
180                                 sudo $CPUSPEEDSCRIPT
181                                 ;;
182                         "customsave")
183                                 sudo $CPUSPEEDSCRIPT
184                                 zenity --info --title="Note" --text="Speed saved.\n\nTo re-enable this dialogue, please delete the file\n$CPUSPEED_FILE"
185                                 PND_getCPUSpeed > $CPUSPEED_FILE
186                                 ;;
187                         "yessave")
188                                 zenity --info --title="Note" --text="Speed saved.\n\nTo re-enable this dialogue, please delete the file\n$CPUSPEED_FILE"
189                                 sudo $CPUSPEEDSCRIPT $PND_CPUSPEED
190                                 PND_getCPUSpeed > $CPUSPEED_FILE
191                                 ;;
192                         "nosave")
193                                 unset CURRENTSPEED
194                                 zenity --info --title="Note" --text="Speed will not be changed.\n\nTo re-enable this dialogue, please delete the file\n$CPUSPEED_FILE"
195                                 echo 9999 > $CPUSPEED_FILE
196                                 ;;
197                         *)      unset CURRENTSPEED;;
198                   esac
199                fi
200         elif [ "$PND_CPUSPEED" -lt "1500" ]; then
201                 CURRENTSPEED=$(PND_getCPUSpeed)
202                 echo Setting to CPU-Speed $PND_CPUSPEED MHz
203                 sudo $CPUSPEEDSCRIPT $PND_CPUSPEED
204         fi
205 }
206
207 PND_resetCPUSpeed() {
208         if [ ! -z "$CURRENTSPEED" ]; then
209                 sudo $CPUSPEEDSCRIPT $CURRENTSPEED
210         fi
211 }
212
213 #=============================================================================
214 # X management functions
215
216 PND_CloseX(){
217         if [ $CLOSE_X ]; then #the app doesnt want x to run, so we kill it and restart it once the app quits
218                 if [ ! $(pidof X) ]; then 
219                         unset $CLOSE_X
220                 else
221                         applist=$(lsof /usr/lib/libX11.so.6 | awk '{print $1}'| sort | uniq)
222                         whitelist=$(cat ~/pndtest/whitelist) #adjust this to a fixed whitelist, maybe in the config dir
223                         filteredlist=$(echo -e "$applist\n\n$whitelist\n\n$whitelist" | sort | uniq -u) #whitelist appended two times so those items are always removed
224                         if [ ${#filteredlist} -ge 1 ]; then
225                                 message=$(echo -e "The following applications are still running, are you sure you want to close x? \n$filteredlist")
226                                 echo -e "?ae[34me[30m?"
227                                 xmessage -center "$message", -buttons yes,no
228                                 if [ $? = 102 ]; then
229                                         exit 1
230                                 fi
231                                 sudo /etc/init.d/slim-init stop
232                                 sleep 5s
233                         else
234                                 echo -e "?ae[34me[30m?"
235                                 xmessage -center "killing x, nothing of value will be lost", -buttons ok,cancel
236                                 if [ $? = 102 ]; then
237                                         exit 1
238                                 fi
239                                 # close x now, do we want to use slim stop or just kill x?
240                                 sudo /etc/init.d/slim-init stop
241                                 sleep 5s
242                         fi
243                 fi
244         fi
245 }
246
247 PND_RestartX(){
248         if [ $CLOSE_X ]; then #restart x if it was killed
249                 # We need to wait a bit, doing it nicely ;)
250                 sleep 5
251                 sudo /etc/init.d/slim-init start
252         fi
253 }
254
255
256 #=============================================================================
257 # (u)Mounting functions
258
259 show_mounted_info(){
260         echo "+++++++"
261         echo "Loopback devices :"
262         sudo /sbin/losetup -a
263         echo "Are mounted on :"
264         mount|grep loop
265         echo "For these Union :"
266         mount|grep aufs
267 }
268
269 is_union_mounted() {
270         mount | grep -q "on $UNION_MOUNT_DIR/${PND_NAME} type aufs"
271 }
272
273 is_pnd_mounted() {
274         mount |grep -v aufs | grep -q "on $PND_MOUNT_DIR/${PND_NAME} type" || \
275         mount |grep -v aufs | grep -q "on $UNION_MOUNT_DIR/${PND_NAME} type"
276 }
277
278 noMoreProcessPnd() {
279         [ -z "$(list_using_fs "$PND_MOUNT_DIR/$PND_NAME")" ]
280 }
281
282 noMoreProcessUnion() {
283         [ -z "$(list_using_fs "$UNION_MOUNT_DIR/$PND_NAME")" ]
284 }
285
286 mountPnd() {
287         MOUNT_TARGET="${1:-$PND_MOUNT_DIR}"
288         if ! is_pnd_mounted;then
289                 #check if pnd is already attached to loop 
290                 LOOP=$(/sbin/losetup -a | grep "$PND" | tail -n1 | awk -F: '{print $1}')
291                 #check if the loop device is already mounted
292                 if ! [ -z "$LOOP" ];then
293                         echo "Found a loop ($LOOP), using it"
294                         loopmountedon=$( mount | grep "$(mount | grep "$LOOP" | awk '{print $3}')" | grep utmp | awk '{print $3}' )
295                 else
296                         loopmountedon=""
297                 fi
298                 if [ ! "$loopmountedon" ]; then #check if the pnd is already attached to some loop device but not used
299                         FREELOOP=$LOOP 
300                         #reuse existing loop
301                         if [ ! "$LOOP" ]; then
302                                 FREELOOP=$(/sbin/losetup -f) #get first free loop device
303                                 if [ ! "$FREELOOP" ]; then  # no free loop device, create a new one
304                                         #find a free loop device and use it 
305                                         usedminor=$(/sbin/losetup -a | tail -n1|sed 's/.*loop\(.*\)\: .*/\1/')
306                                         #usedminor=${usedminor:9:1}
307                                         freeminor=$(($usedminor+1))
308                                         echo "Creating a new device : mknod -m777 /dev/loop$freeminor b 7 $freeminor"
309                                         mknod -m777 /dev/loop$freeminor b 7 $freeminor
310                                         FREELOOP=/dev/loop$freeminor
311                                 fi
312                         fi
313
314                         #detect fs
315                         case $PND_FSTYPE in
316                         ISO)
317                                 /sbin/losetup $FREELOOP "$PND" #attach the pnd to the loop device
318                                 mntline="mount" #setup the mountline for later
319                                 mntdev="${FREELOOP}"
320                                 ;;
321                         directory)
322                                 #we bind the folder, now it can be treated in a unified way 
323                                 #ATENTION: -o ro doesnt work for --bind at least on 25, on 26 its possible using remount, may have changed on 27
324                                 mntline="mount --bind -o ro"
325                                 mntdev="${PND}"
326                                 ;;
327                         Squashfs)
328                                 /sbin/losetup $FREELOOP "$PND" #attach the pnd to the loop device
329                                 mntline="mount -t squashfs"
330                                 mntdev="${FREELOOP}"
331                                 ;;
332                         *)
333                                 echo "ERROR Unknown filesystem type : $PND_FSTYPE"
334                                 exit 1;;
335                         esac
336                         echo "Mounting : $mntline \"$mntdev\" \"$MOUNT_TARGET/${PND_NAME}\""
337                         $mntline "$mntdev" "$MOUNT_TARGET/${PND_NAME}" #mount the pnd/folder
338
339                         if ! is_pnd_mounted ;then
340                                 sleep 1
341                                 echo "WARNING : mount faild, re-tring"
342                                 sleep 1
343                                 $mntline "$mntdev" "$MOUNT_TARGET/${PND_NAME}" #mount the pnd/folder
344                                 if ! is_pnd_mounted ;then
345                                         echo "ERROR The PND File-system is not mounted !"
346                                         show_mounted_info
347                                         return 2
348                                 fi
349                         fi
350                 else #the pnd is already mounted but a mount was requested with a different basename/uid, just link it there
351                       echo WARNING $LOOP already mounted on $loopmountedon skipping losetup - putting link to old mount
352                       #this is bullshit
353                       rmdir "$UNION_MOUNT_DIR/$PND_NAME"
354                       ln -s $loopmountedon "$UNION_MOUNT_DIR/$PND_NAME" 
355                 fi
356         fi
357
358         # For backward compatibility
359         if [[ "$MOUNT_TARGET" != "$PND_MOUNT_DIR" ]];then
360                 if [ -d "$PND_MOUNT_DIR/$PND_NAME" ];then
361                         rmdir "$PND_MOUNT_DIR/$PND_NAME"
362                 else
363                         rm "$PND_MOUNT_DIR/$PND_NAME"
364                 fi
365                 if [ ! -e "$PND_MOUNT_DIR/$PND_NAME" ];then
366                         ln -s "$MOUNT_TARGET/$PND_NAME" "$PND_MOUNT_DIR/$PND_NAME"
367                 fi
368         fi
369 }
370
371 mountUnion() {
372         if [ $(id -u) -ne 0 ];then
373                 sudo /usr/pandora/scripts/pnd_run.sh -m -p "$PND" -b "$PND_NAME"
374                 if ! is_union_mounted;then
375                         echo "ERROR: The Union File-system is not mounted !"
376                         show_mounted_info
377                         return 1
378                 fi
379                 return $RC
380         fi
381         #create mountpoints, check if they exist already first to avoid annoying error messages
382         if ! [ -d "$PND_MOUNT_DIR/${PND_NAME}" ]; then 
383                 mkdir -p "$PND_MOUNT_DIR/${PND_NAME}"           #mountpoint for iso, ro
384         fi 
385         #writeable dir for union
386         if ! [ -d "${APPDATADIR}" ]; then 
387                 mkdir -p "${APPDATADIR}"
388                 chmod -R a+xrw "${APPDATADIR}" 2>/dev/null
389         fi
390         # create the union mountpoint
391         if ! [ -d "$UNION_MOUNT_DIR/${PND_NAME}" ]; then
392                 mkdir -p "$UNION_MOUNT_DIR/${PND_NAME}"         # union over the two
393         fi
394         #is the union already mounted? if not mount evrything, else launch the stuff
395         if ! is_union_mounted;then
396                 if ! is_pnd_mounted;then
397                         mountPnd "$UNION_MOUNT_DIR"|| return 2; # quit mounting the union if the PND first didnt mount
398                 else
399                         echo "WARNING The PND is already mounted, using it"
400                         show_mounted_info
401                 fi
402                 RO=0;for o in $(mount|awk '$3=="'$MOUNTPOINT'"{print $6}'|sed 's/.*(//;s/)$//;s/,/ /g');do [[ $o = "ro" ]]&& RO=1;done
403                 if [ $RO -eq 1 ];then
404                         echo "WARNING SD-Card is mounted Read-only !! Trying to remount RW"
405                         mount -oremount,rw $MOUNTPOINT
406                 fi
407
408                 if [[ "$APPDD_FSTYPE" = "vfat" ]]; then # use noplink on fat, dont on other fs's 
409                         #append is fucking dirty, need to clean that up
410                         MOUNT_CMD="mount -t aufs -o exec,noplink,dirs=\"${APPDATADIR}=rw+nolwh\":\"$PND_MOUNT_DIR/$PND_NAME=rr$append\" none \"$UNION_MOUNT_DIR/$PND_NAME\""
411                 else
412                         MOUNT_CMD="mount -t aufs -o exec,dirs=\"${APPDATADIR}=rw+nolwh\":\"$PND_MOUNT_DIR/$PND_NAME=rr$append\" none \"$UNION_MOUNT_DIR/$PND_NAME\""
413                 fi
414                 echo "Mounting the Union FS : $MOUNT_CMD"
415                 eval $MOUNT_CMD
416
417                 if ! is_union_mounted;then
418                         sleep 1
419                         echo "WARNING : mount faild, re-tring"
420                         sleep 1
421                         eval $MOUNT_CMD
422                         if ! is_union_mounted;then
423                                 echo "ERROR: The Union File-system is not mounted !"
424                                 show_mounted_info
425                                 return 1
426                         fi
427                 fi
428         else
429                 echo "WARNING Union already mounted, using it"
430                 show_mounted_info
431         fi
432 }
433
434 cleanups() {
435         #delete folders created by aufs if empty
436         rmdir -rf "${APPDATADIR}/.wh..wh.plnk" 2>/dev/null
437         rmdir -rf "${APPDATADIR}/.wh..wh..tmp" 2>/dev/null
438         rmdir "${APPDATADIR}/.wh..wh.orph" 2>/dev/null
439         rm "${APPDATADIR}/.aufs.xino" 2>/dev/null
440
441         #delete appdata folder and ancestors if _empty_
442         rmdir -p "${APPDATADIR}" 2>/dev/null
443
444         # Clean the loopback device
445         if [ $PND_FSTYPE = ISO ] || [ $PND_FSTYPE = Squashfs ]; then # check if we where running an iso, clean up loop device if we did
446                 LOOP=$(/sbin/losetup -a | grep "$(basename $PND)" | tail -n1 | awk -F: '{print $1}')
447                 /sbin/losetup -d $LOOP
448                 #rm $LOOP
449         fi
450         /sbin/losetup -a|cut -d':' -f 1|while read l;do
451                 if ! mount|grep -q $l;then
452                         echo "WARNING Found $l loop as unused. flushing"
453                         /sbin/losetup -d $l
454                 fi
455         done
456
457         echo cleanup done
458 }
459
460 umountPnd() {
461         MOUNT_TARGET="${1:-$PND_MOUNT_DIR}"
462         if is_pnd_mounted;then
463                 PND_WaitFor noMoreProcessPnd "Waiting the PND mount dir to be free"
464                 umount "$MOUNT_TARGET/$PND_NAME"
465         fi
466         if is_pnd_mounted; then
467                 echo WARNING umount PND failed, didnt clean up. Process still using this FS :
468                 list_using_fs "$MOUNT_TARGET/$PND_NAME"
469                 show_mounted_info
470         else
471                 # removing the now useless mountpoint
472                 if [ -d "$MOUNT_TARGET/$PND_NAME" ];then
473                         rmdir "$MOUNT_TARGET/$PND_NAME"
474                 fi
475                 if [ -h "$PND_MOUNT_DIR/$PND_NAME" ];then
476                         rm "$PND_MOUNT_DIR/$PND_NAME"
477                 fi
478
479                 # All went well, cleaning
480                 cleanups
481         fi
482 }
483
484 umountUnion() {
485         # Are we root yet ?
486         if [ $(id -u) -ne 0 ];then
487                 sudo /usr/pandora/scripts/pnd_run.sh -u -p "$PND" -b "$PND_NAME"
488                 return $?
489         fi
490
491         # Make sure the Union FS is unmounted
492         #PND_INTERACTIVE=2
493         if is_union_mounted;then
494                 PND_WaitFor noMoreProcessUnion "Waiting the Union to be available"
495                 umount "$UNION_MOUNT_DIR/$PND_NAME" #umount union
496         fi
497         if is_union_mounted; then
498                 echo "WARNING umount UNION failed, didnt clean up. Process still using this FS :"
499                 list_using_fs "$UNION_MOUNT_DIR/$PND_NAME"
500                 show_mounted_info
501         else
502                 # the Union is umounted, removing the now empty mountpoint
503                 if [[ "$PND_MOUNT_DIR" != "$UNION_MOUNT_DIR" ]];then
504                         if [ -d "$UNION_MOUNT_DIR/$PND_NAME" ];then
505                                 rmdir "$UNION_MOUNT_DIR/$PND_NAME"
506                         elif [ -e "$UNION_MOUNT_DIR/$PND_NAME" ];then
507                                 rm "$UNION_MOUNT_DIR/$PND_NAME" >/dev/null 2>&1 # as it might be a symlink
508                         fi
509                 fi
510                 # Try umounting the PND
511                 umountPnd $UNION_MOUNT_DIR
512         fi
513 }
514
515
516
517 #=============================================================================
518 # Create the condition to run an app, run it and wait for it's end
519 runApp() {
520         cd "$UNION_MOUNT_DIR/$PND_NAME"         # cd to union mount
521         if [ "$STARTDIR" ] && [ -d "$STARTDIR" ]; then
522                 cd "$STARTDIR";                 # cd to folder specified by the optional arg -s
523         fi
524
525         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/lib" ];then
526                 export LD_LIBRARY_PATH="$UNION_MOUNT_DIR/$PND_NAME/lib:${LD_LIBRARY_PATH:-"/usr/lib:/lib"}"
527         else
528                 export LD_LIBRARY_PATH="$UNION_MOUNT_DIR/$PND_NAME:${LD_LIBRARY_PATH:-"/usr/lib:/lib"}"
529         fi
530
531         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/bin" ];then
532                 export PATH="$UNION_MOUNT_DIR/$PND_NAME/bin:${PATH:-"/usr/bin:/bin:/usr/local/bin"}"
533         fi
534
535         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/share" ];then
536                 export XDG_DATA_DIRS="$UNION_MOUNT_DIR/$PND_NAME/share:$XDG_DATA_DIRS:/usr/share"
537         fi
538
539         export XDG_CONFIG_HOME="$UNION_MOUNT_DIR/$PND_NAME"
540         export REAL_HOME="$HOME"
541         export HOME="$UNION_MOUNT_DIR/$PND_NAME"
542
543         if echo "$EXENAME"|grep -q ^\.\/;then
544                 "$EXENAME" $ARGUMENTS
545         else
546                 "./$EXENAME" $ARGUMENTS
547         fi
548         RC=$?
549
550         #the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!
551         PID=$(pidof -o %PPID -x \"$EXENAME\")   # get pid of app
552         while [ "$PID" ];do                     # wait till we get no pid back for tha app, again a bit ugly, but it works
553                 sleep 10s
554                 PID=`pidof -o %PPID -x \"$EXENAME\"`
555         done
556         export HOME="$REAL_HOME"
557         return $RC
558 }
559
560
561 main() {
562         case $ACTION in
563         mount)  
564                 mountUnion
565                 ;;
566         umount)
567                 umountUnion
568                 ;;
569         run)
570                 PND_BeginTask "Mount the PND"
571                 mountUnion
572                 PND_EndTask
573                 if [ $? -ne 0 ];then
574                         zenity --warning --title="Mounting the PND failed" --text="Mounting the PND failed. The application wont start. Please have a look at $PND_LOG"
575                         return 3
576                 fi
577                 if [ -e /proc/pandora/cpu_mhz_max ] && [ ! -z "$PND_CPUSPEED" ];then
578                         PND_BeginTask "Set CPU speed"
579                         PND_setCPUSpeed
580                         PND_EndTask
581                 fi
582                 if [ $CLOSE_X ]; then
583                         PND_BeginTask "Closing X"
584                         PND_CloseX
585                         PND_EndTask
586                 fi
587                 oPWD=$(pwd)
588                 if [ -e "${APPDATADIR}/PND_pre_script.sh" ]; then
589                         PND_BeginTask "Starting user configured pre-script"
590                         . ${APPDATADIR}/PND_pre_script.sh # Sourcing so it can shared vars with post-script ;)
591                         PND_EndTask
592                 fi
593                 PND_BeginTask "Starting the application ($EXENAME $ARGUMENTS)"
594                 runApp
595                 PND_EndTask
596                 if [ -e "${APPDATADIR}/PND_post_script.sh" ]; then
597                         PND_BeginTask "Starting user configured post-script"
598                         . ${APPDATADIR}/PND_post_script.sh
599                         PND_EndTask
600                 fi
601                 cd $oPWD
602                 if [ $CLOSE_X ]; then
603                         PND_BeginTask "Restarting X"
604                         PND_RestartX
605                         PND_EndTask
606                 fi
607                 if [ ! -z "$CURRENTSPEED" ]; then
608                         PND_BeginTask "Reset CPU speed to $CURRENTSPEED"
609                         PND_resetCPUSpeed
610                         PND_EndTask
611                 fi
612                 if ! lsof /dev/fb1 > /dev/null; then
613                         PND_BeginTask "Restoring the frame buffer status"
614                         ofbset -fb /dev/fb1 -mem 0 -size 0 0 -en 0
615                         PND_EndTask
616                 fi
617                 PND_BeginTask "uMount the PND"
618                 umountUnion
619                 PND_EndTask
620                 ;;
621         esac
622 }
623
624 ######################################################################################
625 ####    Parsing the arguments :
626 ##
627 ACTION=run
628 while [ "$#" -gt 0 ];do
629         if [ "$#" -gt 1 ] && ( [[ "$(echo $2|cut -c 1)" != "-" ]] || [[ "$1" = "-a" ]] );then
630                 case "$1" in
631                 -p) PND="$2";;
632                 -e) EXENAME="$2";;
633                 -b) PND_NAME="$2";;
634                 -s) STARTDIR="$2";;
635                 -j) append="$2";;
636                 -c) PND_CPUSPEED="$2";;
637                 -d) APPDATASET=1;APPDATADIR="$2";;
638                 -a) ARGUMENTS="$2";;
639                 *)      echo "ERROR while parsing arguments: \"$1 $2\" is not a valid argument"; 
640                         echo "Arguments were : $PND_ARGS"
641                         showHelp;
642                         exit 1 ;;
643                 esac
644                 shift 2
645         else # there's no $2 or it's an argument
646                 case "$1" in
647                 -m) ACTION=mount;;
648                 -u) ACTION=umount;;
649                 -x) CLOSE_X=1;;
650                 -d) APPDATASET=1;;
651                 *)      echo "ERROR while parsing arguments: \"$1\" is not a valid argument"; 
652                         echo "Arguments were : $PND_ARGS"
653                         showHelp;
654                         exit 1 ;;
655                 esac
656                 shift
657
658         fi
659 done
660
661 # getting the real full path to the file
662 PND="$(readlink -f $PND)"
663
664 #PND_NAME really should be something sensible and somewhat unique
665 #if -b is set use that as pnd_name, else generate it from PND
666 #get basename (strip extension if file) for union mountpoints etc, maybe  this should be changed to something specified inside the xml
667 #this should probably be changed to .... something more sensible
668 #currently only everything up to the first '.' inside the filenames is used.
669 PND_NAME="${PND_NAME:-"$(basename $PND | cut -d'.' -f1)"}"
670
671 PND_LOG="/tmp/pndrun_${PND_NAME}.out"
672 PND_HEADER="PND PND_FSTYPE APPDATADIR APPDD_FSTYPE PND_CPUSPEED EXENAME ARGUMENTS"
673
674 if [ ! -e "$PND" ]; then #check if theres a pnd suplied, need to clean that up a bit more
675         echo "ERROR: selected PND($PND) file does not exist!"
676         showHelp
677         exit 1
678 fi
679
680 if [ ! "$EXENAME" ] && [[ "$ACTION" = "run" ]]; then
681         echo "ERROR: no executable name provided!"
682         showHelp
683         exit 1
684 fi
685
686 PND_FSTYPE=$(file -b "$PND" | awk '{ print $1 }')       # is -p a zip/iso or folder?
687 MOUNTPOINT=$(df "$PND" | tail -1|awk '{print $6}')      # find out on which mountpoint the pnd is
688 if [ $(df "$PND"|wc -l) -eq 1 ];then                    # this is actually a bug in busybox
689         MOUNTPOINT="/";
690 elif [ ! -d "$MOUNTPOINT" ]; then 
691         MOUNTPOINT="";
692 fi
693 [ ! -z $APPDATASET ] || [ -z ${MOUNTPOINT} ] && APPDATADIR=${APPDATADIR:-$(dirname $PND)/$PND_NAME}
694 APPDATADIR=${APPDATADIR:-${MOUNTPOINT}/pandora/appdata/${PND_NAME}}
695 APPDD_FSTYPE=$(mount|awk '$3=="'${MOUNTPOINT}'"{print $5}')
696 CPUSPEED_FILE=${MOUNTPOINT}/pandora/appdata/${PND_NAME}/cpuspeed
697 if [ -f "$CPUSPEED_FILE" ]; then
698         PND_CPUSPEED=$(cat "$CPUSPEED_FILE")
699 fi
700 export APPDATADIR PND PND_NAME
701
702 #Only logging when running
703 if [[ "$ACTION" == "run" ]];then
704         PND_Start
705         {
706         if [ $CLOSE_X ]; then
707                 main 2>&1 & 
708                 disown
709         else
710                 main 2>&1
711         fi
712         }>>"$PND_LOG"
713         PND_Stop
714 else
715         main
716 fi