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