pnd_run.sh was old version - updated to conform with the HotFix.
[pandora-libraries.git] / testdata / scripts / pnd_run.sh
1 #!/bin/bash
2  
3 #Usage: pnd_run.sh -p your.pnd -e executeable [-a "(arguments)"] [ -s "cd to folder inside pnd"] [-b UID (name of mountpoint/pandora/appdata)] [-x close x before launching(script needs to be started with nohup for this to work]
4 # -s startdir
5 # arguments can be inside -e, -a is optional
6  
7 #/etc/sudoers needs to be adjusted if you touch any of the sudo lines
8  
9 # look at the comments in the nox part, adjust 
10 #use "lsof /usr/lib/libX11.so.6 | awk '{print $1}'| sort | uniq > whitelist" with nothing running to generate the whitelist
11  
12 #todo - no proper order
13 #validate params better
14 #make uid/basename mandatory (and rename var, its confusing!)
15 #find a clean way of shutting down x without a fixed dm, mabye avoid nohup usage somehow
16 #add options to just mount iso without union and to mount the union later
17 #cleanup
18 #Rewrite! - this sucks
19  
20 # parse arguments
21 TEMP=`getopt -o p:e:a:b:s:m::u::n::x::j:c: -- "$@"`
22  
23 if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
24  
25 # Note the quotes around `$TEMP': they are essential!
26 eval set -- "$TEMP"
27  
28 while true ; do
29         case "$1" in
30                 -p) echo "pnd set to \`$2'" ;PND=$2;shift 2;;
31                 -e) echo "exec set to \`$2'" ;EXENAME=$2;shift 2 ;;
32 #               -n) echo "n set, no union pls!";NOUNION=1;shift 2;; # we will reuse -n soon,stop using it if you still did!
33                 -b) echo "BASENAME set to $2";BASENAME=$2;shift 2;;
34                 -s) echo "startdir set to $2";STARTDIR=$2;shift 2;;
35                 -m) echo "mount";mount=1;shift 2;;
36                 -u) echo "umount";umount=1;shift 2;;
37                 -x) echo "no x";nox=1;shift 2;;
38                 -j) echo "join/ also mount those folders";append=$2;shift 2;;
39                 -c) echo "set cpu speed to";cpuspeed=$2;shift 2;;
40                 -a) 
41                         case "$2" in
42                                 "") echo "no arguments"; shift 2 ;;
43                                 *)  echo "args set to \`$2'" ;ARGUMENTS=$2;shift 2 ;;
44                         esac ;;
45                 --) shift ; break ;;
46                 *) echo "Error while parsing arguments!" ; exit 1 ;;
47         esac
48 done
49
50 if [ ! -e "$PND" ]; then #check if theres a pnd suplied, need to clean that up a bit more
51         echo "ERROR: selected PND file does not exist!"
52         echo "Usage: pnd_run.sh -p your.pnd -e executeable [-a \"(arguments)\"] [ -s \"cd to folder inside pnd\"] [-b UID (name of mountpoint/pandora/appdata)] [-x close x before launching(script needs to be started with nohup for this to work]"
53         exit 1
54 fi
55 if [ ! "$EXENAME" ]; then
56         if [ ! $mount ] && [ ! $umount ]; then
57                 echo "ERROR: no executable name provided!"
58                 echo "Usage: pnd_run.sh -p your.pnd -e executeable [-a \"(arguments)\"] [ -s \"cd to folder inside pnd\"] [-b UID (name of mountpoint/pandora/appdata)] [-x close x before launching(script needs to be started with nohup for this to work]"
59                 echo "Usage for mounting/umounting pnd_run.sh -p your.pnd -b uid -m or -u"
60                 exit 1
61         fi
62 fi
63
64 fork () {
65 echo in fork!
66 if [ $nox ]; then #the app doesnt want x to run, so we kill it and restart it once the app quits
67         if [ ! $(pidof X) ]; then 
68                 unset $nox
69         else
70                 applist=$(lsof /usr/lib/libX11.so.6 | awk '{print $1}'| sort | uniq)
71                 whitelist=$(cat ~/pndtest/whitelist) #adjust this to a fixed whitelist, maybe in the config dir
72                 filteredlist=$(echo -e "$applist\n\n$whitelist\n\n$whitelist" | sort | uniq -u) #whitelist appended two times so those items are always removed
73                 if [ ${#filteredlist} -ge 1 ]; then
74                         message=$(echo -e "The following applications are still running, are you sure you want to close x? \n$filteredlist")
75                         echo -e ?ae[34me[30m?
76                         xmessage -center "$message", -buttons yes,no
77                         if [ $? = 102 ]; then
78                         exit 1
79                         fi
80                         sudo /etc/init.d/slim-init stop
81                         sleep 5s
82                 else
83                         echo -e ?ae[34me[30m?
84                         xmessage -center "killing x, nothing of value will be lost", -buttons ok,cancel
85                         if [ $? = 102 ]; then
86                         exit 1
87                         fi
88                         # close x now, do we want to use slim stop or just kill x?
89                         sudo /etc/init.d/slim-init stop
90                         sleep 5s
91                 fi
92         fi
93 fi
94  
95 #vars
96 echo "PND ++ $PND"
97 DFS=$(file -b "$PND" | awk '{ print $1 }') #is -p a zip/iso or folder?
98 MOUNTPOINT=$(df "$PND" | sed -ne 's/.*\% \(\S*\)/\1/p' | tail -n1) #find out on which mountpoint the pnd is
99 if [ ! -d "$MOUNTPOINT" ]; then MOUNTPOINT="/"; fi #make sure folder exists, if it doesnt assume rootfs
100
101 #if the pnd is on / set mountpoint to "" so we dont and up with // at the start,
102 #this is to make sure sudo doesnt get confused
103 if [ $MOUNTPOINT = "/" ]; then MOUNTPOINT=""; fi
104 echo "mountpoint: $MOUNTPOINT"
105  
106 #BASENAME really should be something sensible and somewhat unique
107 #if -b is set use that as basename, else generate it from PND
108 #get basename (strip extension if file) for union mountpoints etc, maybe  this should be changed to something specified inside the xml
109 #this should probably be changed to .... something more sensible
110 #currently only everything up to the first '.' inside the filenames is used.
111 if [ ! "$BASENAME" ]; then BASENAME=$(basename $PND | cut -d'.' -f1) ; fi
112  
113 echo "Basename: $BASENAME"
114  
115 if [ ! $umount ]; then 
116
117         oCWD=$(pwd)
118         #create mountpoints, check if they exist already first to avoid annoying error messages
119         if [ ! -d "/mnt/pnd/${BASENAME}" ]; then sudo mkdir -p "/mnt/pnd/${BASENAME}" ; echo "mkdir -p /mnt/pnd/${BASENAME}"; fi #mountpoint for iso, ro
120         #writeable dir for union
121         if [ ! -d "${MOUNTPOINT}/pandora/appdata/${BASENAME}" ]; then sudo mkdir -p "${MOUNTPOINT}/pandora/appdata/${BASENAME}"; echo "mkdir -p ${MOUNTPOINT}/pandora/appdata/${BASENAME}"; sudo chmod -R a+xrw "${MOUNTPOINT}/pandora/appdata/${BASENAME}"; fi
122         if [ ! -d "/mnt/utmp/${BASENAME}" ]; then sudo mkdir -p "/mnt/utmp/${BASENAME}"; echo "/mnt/utmp/${BASENAME}"; fi #union over the two
123
124         if [ ! $cpuspeed -eq $(cat /proc/pandora/cpu_mhz_max) ]; then 
125           gksu --message "$BASENAME wants to set the cpu speed to $cpuspeed, enter root password to allow" echo $cpuspeed > /proc/pandora/cpu_mhz_max
126         fi
127         #is the union already mounted? if not mount evrything, else launch the stuff
128         mount | grep "on /mnt/utmp/${BASENAME} type" # > /dev/null
129         if [ ! $? -eq 0 ]; then 
130
131                 echo not mounted on loop yet, doing so
132                 #check if pnd is already attached to loop 
133                 LOOP=$(sudo losetup -a | grep "$PND" | tail -n1 | awk -F: '{print $1}')
134                 #check if the loop device is already mounted
135                 loopmountedon=$( mount | grep $(mount | grep $LOOP | awk '{print $3}') | grep utmp | awk '{print $3}' )
136                 echo "LoopMountedon: $loopmountedon"
137                 if [ ! "$loopmountedon" ]; then #check if the pnd is already attached to some loop device but not used
138                         FREELOOP=$LOOP 
139                         #reuse existing loop
140                         if [ ! "$LOOP" ]; then
141                                 FREELOOP=$(sudo /sbin/losetup -f) #get first free loop device
142                                 echo $FREELOOP
143                                 if [ ! "$FREELOOP" ]; then  # no free loop device, create a new one
144                                             #find a free loop device and use it 
145                                             usedminor=$(sudo /sbin/losetup -a | tail -n1)
146                                             usedminor=${usedminor:9:1}
147                                             echo usedminor $usedminor
148                                             freeminor=$(($usedminor+1))
149                                             echo freeminor $freeminor
150                                             sudo mknod -m777 /dev/loop$freeminor b 7 $freeminor
151                                             FREELOOP=/dev/loop$freeminor
152                                 fi
153                         fi
154                           #detect fs
155                         
156                         if [ $DFS = ISO ]; then
157                                 sudo /sbin/losetup $FREELOOP "$PND" #attach the pnd to the loop device
158                                 mntline="sudo mount ${FREELOOP}" #setup the mountline for later
159                                 #mntline="sudo mount -o loop,mode=777 $PND /mnt/pnd/$BASENAME"
160                                 echo "Filetype is $DFS"
161                         elif [ $DFS = directory ]; then
162                                   mntline="sudo mount --bind -o ro \"${PND}\" "
163                           #we bind the folder, now it can be treated in a unified way ATENTION: -o ro doesnt work for --bind at least on 25, on 26 its possible using remount, may have changed on 27
164                                   echo "Filetype is $DFS"
165                         elif [ $DFS = Squashfs ]; then
166                                   sudo /sbin/losetup $FREELOOP "$PND" #attach the pnd to the loop device
167                                   mntline="sudo mount -t squashfs  ${FREELOOP}"
168                                   echo "Filetype is $DFS"
169                         else
170                                   echo "error determining fs, output was $DFS"
171                                   exit 1;
172                         fi
173
174                         echo "$mntline"
175                         $mntline "/mnt/pnd/${BASENAME}" #mount the pnd/folder
176                         echo "mounting union!"
177                         FILESYSTEM=$(mount | grep "on $MOUNTPOINT " | grep -v rootfs | awk '{print $5}' | tail -n1) #get filesystem appdata is on to determine aufs options
178                         echo "Filesystem is $FILESYSTEM"
179                         if [ $FILESYSTEM = vfat ]; then # use noplink on fat, dont on other fs's 
180                                 #append is fucking dirty, need to clean that up
181                                 sudo mount -t aufs -o exec,noplink,dirs="$MOUNTPOINT/pandora/appdata/$BASENAME=rw+nolwh":"/mnt/pnd/$BASENAME=rr$append" none "/mnt/utmp/$BASENAME" # put union on top
182                                 else
183                                 sudo mount -t aufs -o exec,dirs="$MOUNTPOINT/pandora/appdata/$BASENAME=rw+nolwh":"/mnt/pnd/$BASENAME=rr$append" none "/mnt/utmp/$BASENAME" # put union on top
184                         fi
185                 else #the pnd is already mounted but a mount was requested with a different basename/uid, just link it there
186                               echo $LOOP already mounted on $loopmountedon skipping losetup - putting link to old mount
187                               #this is bullshit
188                               sudo rmdir "/mnt/utmp/$BASENAME"
189                               sudo ln -s $loopmountedon "/mnt/utmp/$BASENAME" 
190                 fi
191         
192         else
193                 echo "Union already mounted"
194         fi
195  
196         if [ $mount ]; then echo "mounted /mnt/utmp/$BASENAME"; exit 1; fi; #mount only, die here
197         
198         cd "/mnt/utmp/$BASENAME" # cd to union mount
199         if [ "$STARTDIR" ]; then cd "$STARTDIR"; fi #cd to folder specified by the optional arg -s
200         LD_LIBRARY_PATH="/mnt/utmp/$BASENAME" "./$EXENAME" $ARGUMENTS # execute app with ld_lib_path set to the union mount, a bit evil but i think its a good solution
201         #the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!
202         PID=`pidof -o %PPID -x \"$EXENAME\"` #get pid of app
203         while [ "$PID" ] #wait till we get no pid back for tha app, again a bit ugly, but it works
204         do
205                 sleep 10s
206                 PID=`pidof -o %PPID -x \"$EXENAME\"`
207         done
208         echo app exited
209  
210         #app exited
211         cd $oCWD #cd out of the mountpoint so we can umount, doesnt really matter to where...
212 else
213 echo "-u set, nothing to do here"
214 fi
215  
216  
217 #clean up
218 sudo rmdir "/mnt/utmp/$BASENAME"
219 sudo rm "/mnt/utmp/$BASENAME"
220 sudo umount "/mnt/utmp/$BASENAME" #umount union
221 if [ $? -eq 0 ]; then # check if the umount was successfull, if it wasnt it would mean that theres still something running so we skip this stuff, this WILL lead to clutter if it happens, so we should make damn sure it never happens
222         #umount the actual pnd
223         sudo umount "/mnt/pnd/$BASENAME"
224         #delete folders created by aufs if empty
225         sudo rmdir "$MOUNTPOINT/pandora/appdata/$BASENAME/.wh..wh.plnk"
226         sudo rmdir "$MOUNTPOINT/pandora/appdata/$BASENAME/.wh..wh..tmp"
227         #delete appdata folder and ancestors if empty
228         sudo rmdir -p "$MOUNTPOINT/pandora/appdata/$BASENAME/"
229         #delete tmp mountpoint
230         sudo rmdir "/mnt/utmp/$BASENAME"
231         if [ $DFS = ISO ] || [ $DFS = Squashfs ]; then # check if we where running an iso, clean up loop device if we did
232                 LOOP=$(sudo losetup -a | grep $(basename $PND) | tail -n1 | awk -F: '{print $1}')
233                 sudo /sbin/losetup -d $LOOP
234                 sudo rm $LOOP
235         fi
236         sudo rmdir "/mnt/pnd/$BASENAME" #delete pnd mountpoint
237         echo cleanup done
238 else
239         echo umount failed, didnt clean up
240 fi
241
242 if [ $nox ]; then #restart x if it was killed
243         echo "starting x in 5s"
244         sleep 5
245         sudo /etc/init.d/slim-init start
246 fi
247
248 } #function end!
249
250 if [ $nox ]; then
251         echo forking now!
252         fork &> "/tmp/pndrun$BASENAME$mount.out" & 
253         disown
254 else
255         echo Running with x, not disowning!
256         fork &> "/tmp/pndrun$BASENAME$mount.out"
257 fi