0ea23e84aaebebb8fbafa73f455cc41b1fe57417
[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_WaitForExit() {
104         # this used to wait for $1 ($EXENAME), but that doesn't work well
105         # when multiple PNDs run as too many PNDs have run.sh as $EXENAME
106         wait
107 }
108
109 PND_Exec() {
110         local CMD="$*"
111         {
112         if [ $PND_ISEXEC -eq 0 ];then
113                 PND_ISEXEC=1
114                 exec 3>&1               # 
115         fi
116         export PND_INTERACTIVE=2
117         $* 2>&1
118         RES=$(( $? + $PND_ERRORS ))
119         echo "<result>$RES</result>"
120         PND_ISEXEC=0
121         exec 3>&-
122         }|{
123         while read line;do
124                 if echo "$line"|grep -q "<result>.*</result>";then
125                         return $(( $(echo $line|sed 's/<[^>]*>//g') + $PND_ERRORS ))
126                 elif ! echo "$line"| $(eval $PND_OUT_CHECK); then
127                         PND_Error "$line";
128                 else
129                         PND_Print "$line";
130                 fi
131         done
132         return $PND_ERRORS
133         }
134 }
135
136
137
138 #=============================================================================
139 # Utility functions
140
141 showHelp() {
142         cat <<endHELP
143 Usage:
144   pnd_run.sh -p file.pnd -e cmd [-a args] [-b pndid] [-s path] [-c speed] [-d [path]] [-x] [-m] [-u] [-- more_args]
145     -p file.pnd : Specify the pnd file to execute
146     -e cmd      : Command to run
147     -a args     : Arguments to the command
148     -b pndid    : name of the directory mount-point ($UNION_MOUNT_DIR/pndid) (Default: name of the pnd file)
149     -s path     : Directory in the union to start the command from
150     -o speed    : Set the CPU speed
151     -d [path]   : Use path as source of the overlay. (Default: pandora/appdata/pndid)
152     -x          : Stop X before starting the apps
153     -m          : Only mount the pnd, dont run it (-e become optional)
154     -u          : Only umount the pnd, dont run it (-e become optional)
155
156   If '--' is specified, all subsequent arguments are passed through to the command
157   (useful if you want to pass quotes and weird chars to the command)
158 endHELP
159 }
160
161 list_using_fs() {
162         for p in $(fuser -m $1 2>/dev/null);do ps hf $p;done
163 }
164
165
166 #=============================================================================
167 # CPU speed functions
168 PND_getCPUSpeed() {
169         cat /proc/pandora/cpu_mhz_max
170 }
171
172 PND_setCPUSpeed() {
173         unset CURRENTSPEED
174         if ! [ -f "$CPUSPEED_FILE" ] && [ ! -z "$PND_CPUSPEED" ]; then
175                 if [ ${PND_CPUSPEED} -gt $(PND_getCPUSpeed) ]; then 
176                    CURRENTSPEED=$(PND_getCPUSpeed)
177                    case "$(zenity --title="set cpu speed" --height=350 --list --column "id" --column "Please select" --hide-column=1 \
178                                   --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!" \
179                                   "yes" "Yes, set it to $PND_CPUSPEED MHz" \
180                                   "custom" "Yes, select custom value" \
181                                   "yessave" "Yes, set it to $PND_CPUSPEED MHz and don't ask again" \
182                                   "customsave" "Yes, set it to custom speed and don't ask again" \
183                                   "no" "No, don't change the speed" \
184                                   "nosave" "No, don't chage the speed and don't ask again")" in
185                         "yes")
186                                 sudo $CPUSPEEDSCRIPT $PND_CPUSPEED
187                                 ;;
188                         "custom")
189                                 sudo $CPUSPEEDSCRIPT
190                                 ;;
191                         "customsave")
192                                 sudo $CPUSPEEDSCRIPT
193                                 zenity --info --title="Note" --text="Speed saved.\n\nTo re-enable this dialogue, please delete the file\n$CPUSPEED_FILE"
194                                 PND_getCPUSpeed > $CPUSPEED_FILE
195                                 ;;
196                         "yessave")
197                                 zenity --info --title="Note" --text="Speed saved.\n\nTo re-enable this dialogue, please delete the file\n$CPUSPEED_FILE"
198                                 sudo $CPUSPEEDSCRIPT $PND_CPUSPEED
199                                 PND_getCPUSpeed > $CPUSPEED_FILE
200                                 ;;
201                         "nosave")
202                                 unset CURRENTSPEED
203                                 zenity --info --title="Note" --text="Speed will not be changed.\n\nTo re-enable this dialogue, please delete the file\n$CPUSPEED_FILE"
204                                 echo 9999 > $CPUSPEED_FILE
205                                 ;;
206                         *)      unset CURRENTSPEED;;
207                   esac
208                fi
209         elif [ "$PND_CPUSPEED" -lt "1500" ]; then
210                 CURRENTSPEED=$(PND_getCPUSpeed)
211                 echo Setting to CPU-Speed $PND_CPUSPEED MHz
212                 sudo $CPUSPEEDSCRIPT $PND_CPUSPEED
213         fi
214 }
215
216 PND_resetCPUSpeed() {
217         if [ ! -z "$CURRENTSPEED" ]; then
218                 sudo $CPUSPEEDSCRIPT $CURRENTSPEED
219         fi
220 }
221
222 #=============================================================================
223 # X management functions
224
225 PND_CloseX(){
226         if [ $CLOSE_X ]; then #the app doesnt want x to run, so we kill it and restart it once the app quits
227                 if [ ! $(pidof X) ]; then 
228                         unset $CLOSE_X
229                 else
230                         applist=$(lsof /usr/lib/libX11.so.6 | awk '{print $1}'| sort | uniq)
231                         whitelist=$(cat ~/pndtest/whitelist) #adjust this to a fixed whitelist, maybe in the config dir
232                         filteredlist=$(echo -e "$applist\n\n$whitelist\n\n$whitelist" | sort | uniq -u) #whitelist appended two times so those items are always removed
233                         if [ ${#filteredlist} -ge 1 ]; then
234                                 message=$(echo -e "The following applications are still running, are you sure you want to close x? \n$filteredlist")
235                                 echo -e "?ae[34me[30m?"
236                                 xmessage -center "$message", -buttons yes,no
237                                 if [ $? = 102 ]; then
238                                         exit 1
239                                 fi
240                                 sudo /etc/init.d/slim-init stop
241                                 sleep 5s
242                         else
243                                 echo -e "?ae[34me[30m?"
244                                 xmessage -center "killing x, nothing of value will be lost", -buttons ok,cancel
245                                 if [ $? = 102 ]; then
246                                         exit 1
247                                 fi
248                                 # close x now, do we want to use slim stop or just kill x?
249                                 sudo /etc/init.d/slim-init stop
250                                 sleep 5s
251                         fi
252                 fi
253         fi
254 }
255
256 PND_RestartX(){
257         if [ $CLOSE_X ]; then #restart x if it was killed
258                 # We need to wait a bit, doing it nicely ;)
259                 sleep 5
260                 sudo /etc/init.d/slim-init start
261         fi
262 }
263
264
265 #=============================================================================
266 # (u)Mounting functions
267
268 show_mounted_info(){
269         echo "+++++++"
270         echo "Loopback devices :"
271         sudo /sbin/losetup -a
272         echo "Are mounted on :"
273         mount|grep loop
274         echo "For these Union :"
275         mount|grep aufs
276 }
277
278 is_union_mounted() {
279         mount | grep -q "on $UNION_MOUNT_DIR/${PND_NAME} type aufs"
280 }
281
282 is_pnd_mounted() {
283         mount |grep -v aufs | grep -q "on $PND_MOUNT_DIR/${PND_NAME} type" || \
284         mount |grep -v aufs | grep -q "on $UNION_MOUNT_DIR/${PND_NAME} type"
285 }
286
287 noMoreProcessPnd() {
288         [ -z "$(list_using_fs "$PND_MOUNT_DIR/$PND_NAME")" ]
289 }
290
291 noMoreProcessUnion() {
292         [ -z "$(list_using_fs "$UNION_MOUNT_DIR/$PND_NAME")" ]
293 }
294
295 mountPnd() {
296         MOUNT_TARGET="${1:-$PND_MOUNT_DIR}"
297         if ! is_pnd_mounted;then
298                 #check if pnd is already attached to loop 
299                 LOOP=$(/sbin/losetup -a | grep "$PND" | tail -n1 | awk -F: '{print $1}')
300                 #check if the loop device is already mounted
301                 if ! [ -z "$LOOP" ];then
302                         echo "Found a loop ($LOOP), using it"
303                         loopmountedon=$( mount | grep "$(mount | grep "$LOOP" | awk '{print $3}')" | grep utmp | awk '{print $3}' )
304                 else
305                         loopmountedon=""
306                 fi
307                 if [ ! "$loopmountedon" ]; then #check if the pnd is already attached to some loop device but not used
308                         FREELOOP=$LOOP 
309                         #reuse existing loop
310                         if [ ! "$LOOP" ]; then
311                                 FREELOOP=$(/sbin/losetup -f) #get first free loop device
312                                 if [ ! "$FREELOOP" ]; then  # no free loop device, create a new one
313                                         #find a free loop device and use it 
314                                         usedminor=$(/sbin/losetup -a | tail -n1|sed 's/.*loop\(.*\)\: .*/\1/')
315                                         #usedminor=${usedminor:9:1}
316                                         freeminor=$(($usedminor+1))
317                                         echo "Creating a new device : mknod -m777 /dev/loop$freeminor b 7 $freeminor"
318                                         mknod -m777 /dev/loop$freeminor b 7 $freeminor
319                                         FREELOOP=/dev/loop$freeminor
320                                 fi
321                         fi
322
323                         #detect fs
324                         case $PND_FSTYPE in
325                         ISO)
326                                 /sbin/losetup -r $FREELOOP "$PND" #attach the pnd to the loop device
327                                 mntline="mount -o ro" #setup the mountline for later
328                                 mntdev="${FREELOOP}"
329                                 ;;
330                         directory)
331                                 #we bind the folder, now it can be treated in a unified way 
332                                 #ATENTION: -o ro doesnt work for --bind at least on 25, on 26 its possible using remount, may have changed on 27
333                                 mntline="mount --bind -o ro"
334                                 mntdev="${PND}"
335                                 ;;
336                         Squashfs)
337                                 /sbin/losetup -r $FREELOOP "$PND" #attach the pnd to the loop device
338                                 mntline="mount -t squashfs -o ro"
339                                 mntdev="${FREELOOP}"
340                                 ;;
341                         *)
342                                 echo "ERROR Unknown filesystem type : $PND_FSTYPE"
343                                 exit 1;;
344                         esac
345                         echo "Mounting : $mntline \"$mntdev\" \"$MOUNT_TARGET/${PND_NAME}\""
346                         $mntline "$mntdev" "$MOUNT_TARGET/${PND_NAME}" #mount the pnd/folder
347
348                         if ! is_pnd_mounted ;then
349                                 sleep 1
350                                 echo "WARNING : mount faild, re-tring"
351                                 sleep 1
352                                 $mntline "$mntdev" "$MOUNT_TARGET/${PND_NAME}" #mount the pnd/folder
353                                 if ! is_pnd_mounted ;then
354                                         echo "ERROR The PND File-system is not mounted !"
355                                         show_mounted_info
356                                         return 2
357                                 fi
358                         fi
359                 else #the pnd is already mounted but a mount was requested with a different basename/uid, just link it there
360                       echo WARNING $LOOP already mounted on $loopmountedon skipping losetup - putting link to old mount
361                       #this is bullshit
362                       rmdir "$UNION_MOUNT_DIR/$PND_NAME"
363                       ln -s $loopmountedon "$UNION_MOUNT_DIR/$PND_NAME" 
364                 fi
365         fi
366
367         # For backward compatibility
368         if [[ "$MOUNT_TARGET" != "$PND_MOUNT_DIR" ]];then
369                 if [ -h "$PND_MOUNT_DIR/$PND_NAME" ];then
370                         rm "$PND_MOUNT_DIR/$PND_NAME"
371                 else
372                         rmdir "$PND_MOUNT_DIR/$PND_NAME"
373                 fi
374                 if [ ! -e "$PND_MOUNT_DIR/$PND_NAME" ];then
375                         ln -s "$MOUNT_TARGET/$PND_NAME" "$PND_MOUNT_DIR/$PND_NAME"
376                 fi
377         fi
378 }
379
380 mountUnion() {
381         if [ $(id -u) -ne 0 ];then
382                 sudo /usr/pandora/scripts/pnd_run.sh -m -p "$PND" -b "$PND_NAME"
383                 if ! is_union_mounted;then
384                         echo "ERROR: The Union File-system is not mounted !"
385                         show_mounted_info
386                         return 1
387                 fi
388                 return $RC
389         fi
390         #create mountpoints, check if they exist already first to avoid annoying error messages
391         if ! [ -d "$PND_MOUNT_DIR/${PND_NAME}" ]; then 
392                 mkdir -p "$PND_MOUNT_DIR/${PND_NAME}"           #mountpoint for iso, ro
393         fi 
394         #writeable dir for union
395         if ! [ -d "${APPDATADIR}" ]; then 
396                 mkdir -p "${APPDATADIR}"
397                 chmod -R a+xrw "${APPDATADIR}" 2>/dev/null
398         fi
399         # create the union mountpoint
400         if ! [ -d "$UNION_MOUNT_DIR/${PND_NAME}" ]; then
401                 mkdir -p "$UNION_MOUNT_DIR/${PND_NAME}"         # union over the two
402         fi
403         #is the union already mounted? if not mount evrything, else launch the stuff
404         if ! is_union_mounted;then
405                 if ! is_pnd_mounted;then
406                         mountPnd "$UNION_MOUNT_DIR"|| return 2; # quit mounting the union if the PND first didnt mount
407                 else
408                         echo "WARNING The PND is already mounted, using it"
409                         show_mounted_info
410                 fi
411                 RO=0;for o in $(mount|awk '$3=="'$MOUNTPOINT'"{print $6}'|sed 's/.*(//;s/)$//;s/,/ /g');do [[ $o = "ro" ]]&& RO=1;done
412                 if [ $RO -eq 1 ];then
413                         echo "WARNING SD-Card is mounted Read-only !! Trying to remount RW"
414                         mount -oremount,rw $MOUNTPOINT
415                 fi
416
417                 if [[ "$APPDD_FSTYPE" = "vfat" ]]; then # use noplink on fat, dont on other fs's 
418                         #append is fucking dirty, need to clean that up
419                         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\""
420                 else
421                         MOUNT_CMD="mount -t aufs -o exec,dirs=\"${APPDATADIR}=rw+nolwh\":\"$PND_MOUNT_DIR/$PND_NAME=rr$append\" none \"$UNION_MOUNT_DIR/$PND_NAME\""
422                 fi
423                 echo "Mounting the Union FS : $MOUNT_CMD"
424                 eval $MOUNT_CMD
425
426                 if ! is_union_mounted;then
427                         sleep 1
428                         echo "WARNING : mount faild, re-tring"
429                         sleep 1
430                         eval $MOUNT_CMD
431                         if ! is_union_mounted;then
432                                 echo "ERROR: The Union File-system is not mounted !"
433                                 show_mounted_info
434                                 return 1
435                         fi
436                 fi
437         else
438                 echo "WARNING Union already mounted, using it"
439                 show_mounted_info
440         fi
441 }
442
443 cleanups() {
444         #delete folders created by aufs if empty
445         rmdir -rf "${APPDATADIR}/.wh..wh.plnk" 2>/dev/null
446         rmdir -rf "${APPDATADIR}/.wh..wh..tmp" 2>/dev/null
447         rmdir "${APPDATADIR}/.wh..wh.orph" 2>/dev/null
448         rm "${APPDATADIR}/.aufs.xino" 2>/dev/null
449
450         #delete appdata folder and ancestors if _empty_
451         rmdir -p "${APPDATADIR}" 2>/dev/null
452
453         # Clean the loopback device
454         if [ $PND_FSTYPE = ISO ] || [ $PND_FSTYPE = Squashfs ]; then # check if we where running an iso, clean up loop device if we did
455                 LOOP=$(/sbin/losetup -a | grep "$(basename $PND)" | tail -n1 | awk -F: '{print $1}')
456                 /sbin/losetup -d $LOOP
457                 #rm $LOOP
458         fi
459         /sbin/losetup -a|cut -d':' -f 1|while read l;do
460                 if ! mount|grep -q $l;then
461                         echo "WARNING Found $l loop as unused. flushing"
462                         /sbin/losetup -d $l
463                 fi
464         done
465
466         echo cleanup done
467 }
468
469 umountPnd() {
470         MOUNT_TARGET="${1:-$PND_MOUNT_DIR}"
471         if is_pnd_mounted;then
472                 PND_WaitFor noMoreProcessPnd "Waiting the PND mount dir to be free"
473                 umount "$MOUNT_TARGET/$PND_NAME"
474         fi
475         if is_pnd_mounted; then
476                 echo WARNING umount PND failed, didnt clean up. Process still using this FS :
477                 list_using_fs "$MOUNT_TARGET/$PND_NAME"
478                 show_mounted_info
479         else
480                 # removing the now useless mountpoint
481                 if [ -d "$MOUNT_TARGET/$PND_NAME" ];then
482                         rmdir "$MOUNT_TARGET/$PND_NAME"
483                 fi
484                 if [ -h "$PND_MOUNT_DIR/$PND_NAME" ];then
485                         rm "$PND_MOUNT_DIR/$PND_NAME"
486                 fi
487
488                 # All went well, cleaning
489                 cleanups
490         fi
491 }
492
493 umountUnion() {
494         # Are we root yet ?
495         if [ $(id -u) -ne 0 ];then
496                 sudo /usr/pandora/scripts/pnd_run.sh -u -p "$PND" -b "$PND_NAME"
497                 return $?
498         fi
499
500         # Make sure the Union FS is unmounted
501         #PND_INTERACTIVE=2
502         if is_union_mounted;then
503                 PND_WaitFor noMoreProcessUnion "Waiting the Union to be available"
504                 umount "$UNION_MOUNT_DIR/$PND_NAME" #umount union
505         fi
506         if is_union_mounted; then
507                 echo "WARNING umount UNION failed, didnt clean up. Process still using this FS :"
508                 list_using_fs "$UNION_MOUNT_DIR/$PND_NAME"
509                 show_mounted_info
510         else
511                 # the Union is umounted, removing the now empty mountpoint
512                 if [[ "$PND_MOUNT_DIR" != "$UNION_MOUNT_DIR" ]];then
513                         if [ -d "$UNION_MOUNT_DIR/$PND_NAME" ];then
514                                 rmdir "$UNION_MOUNT_DIR/$PND_NAME"
515                         elif [ -e "$UNION_MOUNT_DIR/$PND_NAME" ];then
516                                 rm "$UNION_MOUNT_DIR/$PND_NAME" >/dev/null 2>&1 # as it might be a symlink
517                         fi
518                 fi
519                 # Try umounting the PND
520                 umountPnd $UNION_MOUNT_DIR
521         fi
522 }
523
524
525
526 #=============================================================================
527 # Create the condition to run an app, run it and wait for it's end
528 runApp() {
529         cd "$UNION_MOUNT_DIR/$PND_NAME"         # cd to union mount
530         if [ "$STARTDIR" ] && [ -d "$STARTDIR" ]; then
531                 cd "$STARTDIR";                 # cd to folder specified by the optional arg -s
532         fi
533
534         echo "$EXENAME" | grep -q "^\.\/" && DOTSLASH="true"
535
536         # now set up the env for the PND, don't run any tools after this point
537         # because PATH and LD_LIBRARY_PATH may be different and incompatible
538
539         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/lib" ];then
540                 export LD_LIBRARY_PATH="$UNION_MOUNT_DIR/$PND_NAME/lib:${LD_LIBRARY_PATH:-"/usr/lib:/lib"}"
541         else
542                 export LD_LIBRARY_PATH="$UNION_MOUNT_DIR/$PND_NAME:${LD_LIBRARY_PATH:-"/usr/lib:/lib"}"
543         fi
544
545         REAL_PATH="$PATH"
546         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/bin" ];then
547                 export PATH="$UNION_MOUNT_DIR/$PND_NAME/bin:${PATH:-"/usr/bin:/bin:/usr/local/bin"}"
548         fi
549
550         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/share" ];then
551                 export XDG_DATA_DIRS="$UNION_MOUNT_DIR/$PND_NAME/share:$XDG_DATA_DIRS:/usr/share"
552         fi
553
554         export REAL_HOME="$HOME"
555         export HOME="$UNION_MOUNT_DIR/$PND_NAME"
556         export XDG_CONFIG_HOME="$HOME"
557         export XDG_DATA_HOME="$HOME"
558         export XDG_CACHE_HOME="$HOME"
559
560         if [ -e "${APPDATADIR}/PND_pre_script.sh" ]; then
561                 echo "Starting user configured pre-script ${APPDATADIR}/PND_pre_script.sh"
562                 . ${APPDATADIR}/PND_pre_script.sh # Sourcing so it can shared vars with post-script ;)
563                 echo "${APPDATADIR}/PND_pre_script.sh is done"
564         fi
565
566         if [ "$DOTSLASH" = "true" ]; then
567                 "$EXENAME" $ARGUMENTS "$@"
568         else
569                 "./$EXENAME" $ARGUMENTS "$@"
570         fi
571         RC=$?
572
573         #the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!
574         LD_LIBRARY_PATH= PATH="$REAL_PATH" PND_WaitForExit "$EXENAME"
575
576         if [ -e "${APPDATADIR}/PND_post_script.sh" ]; then
577                 echo "Starting user configured post-script ${APPDATADIR}/PND_post_script.sh"
578                 . ${APPDATADIR}/PND_post_script.sh
579                 echo "${APPDATADIR}/PND_post_script.sh is done"
580         fi
581
582         # clean up to avoid any effects of the .pnd on the remaining parts of this script
583         unset LD_LIBRARY_PATH
584         export HOME="$REAL_HOME"
585         unset REAL_HOME
586         export PATH="$REAL_PATH"
587         unset REAL_PATH
588         # ... the rest should not matter
589
590         return $RC
591 }
592
593
594 main() {
595         case $ACTION in
596         mount)  
597                 mountUnion
598                 ;;
599         umount)
600                 umountUnion
601                 ;;
602         run)
603                 PND_BeginTask "Mount the PND"
604                 mountUnion
605                 PND_EndTask
606                 if [ $? -ne 0 ];then
607                         zenity --warning --title="Mounting the PND failed" --text="Mounting the PND failed. The application wont start. Please have a look at $PND_LOG"
608                         return 3
609                 fi
610                 if [ -e /proc/pandora/cpu_mhz_max ] && [ ! -z "$PND_CPUSPEED" ];then
611                         PND_BeginTask "Set CPU speed"
612                         PND_setCPUSpeed
613                         PND_EndTask
614                 fi
615                 if [ $CLOSE_X ]; then
616                         PND_BeginTask "Closing X"
617                         PND_CloseX
618                         PND_EndTask
619                 fi
620                 oPWD=$(pwd)
621                 old_fb0_geometry=$(fbset -fb /dev/fb0 -s | grep geometry | awk '{print $2, $3, $4, $5, $6}')
622
623                 PND_BeginTask "Starting the application ( $EXENAME $ARGUMENTS "$@")"
624                 runApp "$@"
625                 PND_EndTask
626
627                 cd $oPWD
628                 if [ $CLOSE_X ]; then
629                         PND_BeginTask "Restarting X"
630                         PND_RestartX
631                         PND_EndTask
632                 fi
633                 if [ ! -z "$CURRENTSPEED" ]; then
634                         PND_BeginTask "Reset CPU speed to $CURRENTSPEED"
635                         PND_resetCPUSpeed
636                         PND_EndTask
637                 fi
638                 PND_BeginTask "Restoring the frame buffer status"
639                 ofbset -fb /dev/fb0 -pos 0 0
640                 fbset -fb /dev/fb0 -g $old_fb0_geometry
641                 old_res=$(echo $old_fb0_geometry | awk '{print $1, $2}')
642                 ofbset -fb /dev/fb0 -size $old_res -en 1
643                 if ! lsof /dev/fb1 > /dev/null; then
644                         ofbset -fb /dev/fb1 -mem 0 -size 0 0 -en 0
645                 fi
646                 PND_EndTask
647
648                 running_pnd_count=$(ps ax | grep "pnd_run.s[h]" | wc -l)
649                 # restore settings if we are the last exiting pnd
650                 # compare with 2 because one is used by subshell where "ps ax | ..." runs
651                 if [ "$running_pnd_count" -eq "2" ]; then
652                         PND_BeginTask "Restoring nub mode"
653                         sed -n '1p' /etc/pandora/conf/nubs.state > /proc/pandora/nub0/mode
654                         sed -n '7p' /etc/pandora/conf/nubs.state > /proc/pandora/nub1/mode
655                         PND_EndTask
656                 fi
657
658                 PND_BeginTask "uMount the PND"
659                 umountUnion
660                 PND_EndTask
661                 ;;
662         esac
663 }
664
665 ######################################################################################
666 ####    Parsing the arguments :
667 ##
668 if [ "$#" -lt 1 ]; then
669         showHelp
670         exit 1
671 fi
672
673 ACTION=run
674 while [ "$#" -gt 0 ];do
675         if [ "$1" == "--" ]; then
676                 shift
677                 break
678         fi
679
680         if [ "$#" -gt 1 ] && ( [[ "$(echo $2|cut -c 1)" != "-" ]] || [[ "$1" = "-a" ]] );then
681                 case "$1" in
682                 -p) PND="$2";;
683                 -e) EXENAME="$2";;
684                 -b) PND_NAME="$2";;
685                 -s) STARTDIR="$2";;
686                 -j) append="$2";;
687                 -c) PND_CPUSPEED="$2";;
688                 -d) APPDATASET=1;APPDATADIR="$2";;
689                 -a) ARGUMENTS="$2";;
690                 *)      echo "ERROR while parsing arguments: \"$1 $2\" is not a valid argument"; 
691                         showHelp;
692                         exit 1 ;;
693                 esac
694                 shift 2
695         else # there's no $2 or it's an argument
696                 case "$1" in
697                 -m) ACTION=mount;;
698                 -u) ACTION=umount;;
699                 -x) CLOSE_X=1;;
700                 -d) APPDATASET=1;;
701                 *)      echo "ERROR while parsing arguments: \"$1\" is not a valid argument"; 
702                         showHelp;
703                         exit 1 ;;
704                 esac
705                 shift
706
707         fi
708 done
709
710 if test -z "$PND"; then
711         echo "ERROR: pnd file provided (-p)"
712         showHelp
713         exit 1
714 fi
715
716 # getting the real full path to the file
717 PND="$(readlink -f $PND)"
718
719 #PND_NAME really should be something sensible and somewhat unique
720 #if -b is set use that as pnd_name, else generate it from PND
721 #get basename (strip extension if file) for union mountpoints etc, maybe  this should be changed to something specified inside the xml
722 #this should probably be changed to .... something more sensible
723 #currently only everything up to the first '.' inside the filenames is used.
724 PND_NAME="${PND_NAME:-"$(basename $PND | cut -d'.' -f1)"}"
725
726 PND_LOG="/tmp/pndrun_${PND_NAME}.out"
727 PND_HEADER="PND PND_FSTYPE APPDATADIR APPDD_FSTYPE PND_CPUSPEED EXENAME ARGUMENTS"
728
729 if [ ! -e "$PND" ]; then #check if theres a pnd suplied, need to clean that up a bit more
730         echo "ERROR: selected PND($PND) file does not exist!"
731         showHelp
732         exit 1
733 fi
734
735 if [ ! "$EXENAME" ] && [[ "$ACTION" = "run" ]]; then
736         echo "ERROR: no executable name provided! (-e)"
737         showHelp
738         exit 1
739 fi
740
741 PND_FSTYPE=$(file -b "$PND" | awk '{ print $1 }')       # is -p a zip/iso or folder?
742 MOUNTPOINT=$(df "$PND" | tail -1|awk '{print $6}')      # find out on which mountpoint the pnd is
743 if [ $(df "$PND"|wc -l) -eq 1 ];then                    # this is actually a bug in busybox
744         MOUNTPOINT="/";
745 elif [ ! -d "$MOUNTPOINT" ]; then 
746         MOUNTPOINT="";
747 fi
748 [ ! -z $APPDATASET ] || [ -z ${MOUNTPOINT} ] && APPDATADIR=${APPDATADIR:-$(dirname $PND)/$PND_NAME}
749 APPDATADIR=${APPDATADIR:-${MOUNTPOINT}/pandora/appdata/${PND_NAME}}
750 APPDD_FSTYPE=$(cat /proc/mounts | awk '$2=="'${MOUNTPOINT}'"{print $3}' | head -1)
751 CPUSPEED_FILE=${MOUNTPOINT}/pandora/appdata/${PND_NAME}/cpuspeed
752 if [ -f "$CPUSPEED_FILE" ]; then
753         PND_CPUSPEED=$(cat "$CPUSPEED_FILE")
754 fi
755 export APPDATADIR PND PND_NAME
756
757 #Only logging when running
758 if [[ "$ACTION" == "run" ]];then
759         PND_Start
760         {
761         if [ $CLOSE_X ]; then
762                 main "$@" 2>&1 & 
763                 disown
764         else
765                 main "$@" 2>&1
766         fi
767         }>>"$PND_LOG"
768         PND_Stop
769 else
770         main
771 fi