Fix issues :
[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 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=$(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=$(losetup -a | grep "$(basename $PND)" | tail -n1 | awk -F: '{print $1}')
447                 /sbin/losetup -d $LOOP
448                 #rm $LOOP
449         fi
450         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         if is_pnd_mounted;then
462                 PND_WaitFor noMoreProcessPnd "Waiting the PND mount dir to be free"
463                 umount "$PND_MOUNT_DIR/$PND_NAME"
464         fi
465         if is_pnd_mounted; then
466                 echo WARNING umount PND failed, didnt clean up. Process still using this FS :
467                 list_using_fs "$PND_MOUNT_DIR/$PND_NAME"
468                 show_mounted_info
469         else
470                 # removing the now useless mountpoint
471                 if [ -d $PND_MOUNT_DIR/$PND_NAME ];then
472                         rmdir "$PND_MOUNT_DIR/$PND_NAME"
473                 fi
474
475                 # All went well, cleaning
476                 cleanups
477         fi
478 }
479
480 umountUnion() {
481         # Are we root yet ?
482         if [ $(id -u) -ne 0 ];then
483                 sudo /usr/pandora/scripts/pnd_run.sh -u -p "$PND" -b "$PND_NAME"
484                 return $?
485         fi
486
487         # Make sure the Union FS is unmounted
488         #PND_INTERACTIVE=2
489         if is_union_mounted;then
490                 PND_WaitFor noMoreProcessUnion "Waiting the Union to be available"
491                 umount "$UNION_MOUNT_DIR/$PND_NAME" #umount union
492         fi
493         if is_union_mounted; then
494                 echo "WARNING umount UNION failed, didnt clean up. Process still using this FS :"
495                 list_using_fs "$UNION_MOUNT_DIR/$PND_NAME"
496                 show_mounted_info
497         else
498                 # the Union is umounted, removing the now empty mountpoint
499                 if [[ "$PND_MOUNT_DIR" != "$UNION_MOUNT_DIR" ]];then
500                         if [ -d "$UNION_MOUNT_DIR/$PND_NAME" ];then
501                                 rmdir "$UNION_MOUNT_DIR/$PND_NAME"
502                         elif [ -e "$UNION_MOUNT_DIR/$PND_NAME" ];then
503                                 rm "$UNION_MOUNT_DIR/$PND_NAME" >/dev/null 2>&1 # as it might be a symlink
504                         fi
505                 fi
506                 # Try umounting the PND
507                 umountPnd
508         fi
509 }
510
511
512
513 #=============================================================================
514 # Create the condition to run an app, run it and wait for it's end
515 runApp() {
516         cd "$UNION_MOUNT_DIR/$PND_NAME"         # cd to union mount
517         if [ "$STARTDIR" ] && [ -d "$STARTDIR" ]; then
518                 cd "$STARTDIR";                 # cd to folder specified by the optional arg -s
519         fi
520
521         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/lib" ];then
522                 export LD_LIBRARY_PATH="$UNION_MOUNT_DIR/$PND_NAME/lib:${LD_LIBRARY_PATH:-"/usr/lib:/lib"}"
523         else
524                 export LD_LIBRARY_PATH="$UNION_MOUNT_DIR/$PND_NAME:${LD_LIBRARY_PATH:-"/usr/lib:/lib"}"
525         fi
526
527         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/bin" ];then
528                 export PATH="$UNION_MOUNT_DIR/$PND_NAME/bin:${PATH:-"/usr/bin:/bin:/usr/local/bin"}"
529         fi
530
531         if [ -d "$UNION_MOUNT_DIR/$PND_NAME/share" ];then
532                 export XDG_DATA_DIRS="$UNION_MOUNT_DIR/$PND_NAME/share:$XDG_DATA_DIRS:/usr/share"
533         fi
534
535         export XDG_CONFIG_HOME="$UNION_MOUNT_DIR/$PND_NAME"
536
537         if echo "$EXENAME"|grep -q ^\.\/;then
538                 "$EXENAME" $ARGUMENTS
539         else
540                 "./$EXENAME" $ARGUMENTS
541         RC=$?
542
543         #the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!
544         PID=$(pidof -o %PPID -x \"$EXENAME\")   # get pid of app
545         while [ "$PID" ];do                     # wait till we get no pid back for tha app, again a bit ugly, but it works
546                 sleep 10s
547                 PID=`pidof -o %PPID -x \"$EXENAME\"`
548         done
549         return $RC
550 }
551
552
553 main() {
554         case $ACTION in
555         mount)  
556                 mountUnion
557                 ;;
558         umount)
559                 umountUnion
560                 ;;
561         run)
562                 PND_BeginTask "Mount the PND"
563                 mountUnion
564                 PND_EndTask
565                 if [ $? -ne 0 ];then
566                         zenity --warning --title="Mounting the PND failed" --text="Mounting the PND failed. The application wont start. Please have a look at $PND_LOG"
567                         return 3
568                 fi
569                 if [ -e /proc/pandora/cpu_mhz_max ] && [ ! -z "$PND_CPUSPEED" ];then
570                         PND_BeginTask "Set CPU speed"
571                         PND_setCPUSpeed
572                         PND_EndTask
573                 fi
574                 if [ $CLOSE_X ]; then
575                         PND_BeginTask "Closing X"
576                         PND_CloseX
577                         PND_EndTask
578                 fi
579                 oPWD=$(pwd)
580                 if [ -e "${APPDATADIR}/PND_pre_script.sh" ]; then
581                         PND_BeginTask "Starting user configured pre-script"
582                         . ${APPDATADIR}/PND_pre_script.sh # Sourcing so it can shared vars with post-script ;)
583                         PND_EndTask
584                 fi
585                 PND_BeginTask "Starting the application ($EXENAME $ARGUMENTS)"
586                 runApp
587                 PND_EndTask
588                 if [ -e "${APPDATADIR}/PND_post_script.sh" ]; then
589                         PND_BeginTask "Starting user configured post-script"
590                         . ${APPDATADIR}/PND_post_script.sh
591                         PND_EndTask
592                 fi
593                 cd $oPWD
594                 if [ $CLOSE_X ]; then
595                         PND_BeginTask "Restarting X"
596                         PND_RestartX
597                         PND_EndTask
598                 fi
599                 if [ ! -z "$CURRENTSPEED" ]; then
600                         PND_BeginTask "Reset CPU speed to $CURRENTSPEED"
601                         PND_resetCPUSpeed
602                         PND_EndTask
603                 fi
604                 PND_BeginTask "uMount the PND"
605                 umountUnion
606                 PND_EndTask
607                 ;;
608         esac
609 }
610
611 ######################################################################################
612 ####    Parsing the arguments :
613 ##
614 ACTION=run
615 while [ "$#" -gt 0 ];do
616         if [ "$#" -gt 1 ] && ( [[ "$(echo $2|cut -c 1)" != "-" ]] || [[ "$1" = "-a" ]] );then
617                 case "$1" in
618                 -p) PND="$2";;
619                 -e) EXENAME="$2";;
620                 -b) PND_NAME="$2";;
621                 -s) STARTDIR="$2";;
622                 -j) append="$2";;
623                 -c) PND_CPUSPEED="$2";;
624                 -d) APPDATASET=1;APPDATADIR="$2";;
625                 -a) ARGUMENTS="$2";;
626                 *)      echo "ERROR while parsing arguments: \"$1 $2\" is not a valid argument"; 
627                         echo "Arguments were : $PND_ARGS"
628                         showHelp;
629                         exit 1 ;;
630                 esac
631                 shift 2
632         else # there's no $2 or it's an argument
633                 case "$1" in
634                 -m) ACTION=mount;;
635                 -u) ACTION=umount;;
636                 -x) CLOSE_X=1;;
637                 -d) APPDATASET=1;;
638                 *)      echo "ERROR while parsing arguments: \"$1\" is not a valid argument"; 
639                         echo "Arguments were : $PND_ARGS"
640                         showHelp;
641                         exit 1 ;;
642                 esac
643                 shift
644
645         fi
646 done
647
648 # getting the real full path to the file
649 PND="$(readlink -f $PND)"
650
651 #PND_NAME really should be something sensible and somewhat unique
652 #if -b is set use that as pnd_name, else generate it from PND
653 #get basename (strip extension if file) for union mountpoints etc, maybe  this should be changed to something specified inside the xml
654 #this should probably be changed to .... something more sensible
655 #currently only everything up to the first '.' inside the filenames is used.
656 PND_NAME="${PND_NAME:-"$(basename $PND | cut -d'.' -f1)"}"
657
658 PND_LOG="/tmp/pndrun_${PND_NAME}.out"
659 PND_HEADER="PND PND_FSTYPE APPDATADIR APPDD_FSTYPE PND_CPUSPEED EXENAME ARGUMENTS"
660
661 if [ ! -e "$PND" ]; then #check if theres a pnd suplied, need to clean that up a bit more
662         echo "ERROR: selected PND($PND) file does not exist!"
663         showHelp
664         exit 1
665 fi
666
667 if [ ! "$EXENAME" ] && [[ "$ACTION" = "run" ]]; then
668         echo "ERROR: no executable name provided!"
669         showHelp
670         exit 1
671 fi
672
673 PND_FSTYPE=$(file -b "$PND" | awk '{ print $1 }')       # is -p a zip/iso or folder?
674 MOUNTPOINT=$(df "$PND" | tail -1|awk '{print $6}')      # find out on which mountpoint the pnd is
675 if [ $(df "$PND"|wc -l) -eq 1 ];then                    # this is actually a bug in busybox
676         MOUNTPOINT="/";
677 elif [ ! -d "$MOUNTPOINT" ]; then 
678         MOUNTPOINT="";
679 fi
680 [ ! -z $APPDATASET ] || [ -z ${MOUNTPOINT} ] && APPDATADIR=${APPDATADIR:-$(dirname $PND)/$PND_NAME}
681 APPDATADIR=${APPDATADIR:-${MOUNTPOINT}/pandora/appdata/${PND_NAME}}
682 APPDD_FSTYPE=$(mount|awk '$3=="'${MOUNTPOINT}'"{print $5}')
683 CPUSPEED_FILE=${MOUNTPOINT}/pandora/appdata/${PND_NAME}/cpuspeed
684 if [ -f "$CPUSPEED_FILE" ]; then
685         PND_CPUSPEED=$(cat "$CPUSPEED_FILE")
686 fi
687 export APPDATADIR PND PND_NAME
688
689 #Only logging when running
690 if [[ "$ACTION" == "run" ]];then
691         PND_Start
692         {
693         if [ $CLOSE_X ]; then
694                 main 2>&1 & 
695                 disown
696         else
697                 main 2>&1
698         fi
699         }>>"$PND_LOG"
700         PND_Stop
701 else
702         main
703 fi