Refreshed pnd_run and sudoers scripts from wiki
authorskeezix <skeezix@flotsam-vm.(none)>
Wed, 10 Jun 2009 05:44:42 +0000 (01:44 -0400)
committerskeezix <skeezix@flotsam-vm.(none)>
Wed, 10 Jun 2009 05:44:42 +0000 (01:44 -0400)
Added support for 'no_x11' option in PXML.xml (and subsequently in emit_dotdesktop and pnd_apps_exec)
-> untested
Added pnd_pnd_mount and pnd_pnd_unmount in pnd_pndfiles, so apps can mount and find screenshots and such
-> untested
Added basic validator app (doesn't do anything, we need to add some regexp's in there!)
Added some new element names in pnd_pxml_names etc for the tinyxml parser

15 files changed:
Makefile
apps/pndvalidator.c [new file with mode: 0644]
include/pnd_apps.h
include/pnd_discovery.h
include/pnd_pndfiles.h
include/pnd_pxml.h
include/pnd_pxml_names.h
lib/pnd_apps.c
lib/pnd_desktop.c
lib/pnd_discovery.c
lib/pnd_pndfiles.c
lib/pnd_pxml.c
lib/pnd_tinyxml.cpp
testdata/scripts/pnd_run.sh
testdata/sh/sudoers

index b3c4bb7..0669235 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -26,7 +26,7 @@ ALLOBJ = pnd_conf.o pnd_container.o pnd_discovery.o pnd_pxml.o pnd_notify.o pnd_
 all: ${SOLIB} ${LIB} conftest discotest notifytest pndnotifyd rawpxmltest pndvalidator
 
 clean:
-       ${RM} -f ${ALLOBJ} ${XMLOBJ} ${LIB} ${SOLIB1} locatetest.o bin/locatetest conftest.o bin/conftest discotest.o bin/discotest bin/notifytest notifytest.o bin/rawpxmltest rawpxmltest.o bin/pndnotifyd pndnotifyd.o ${SOLIB} testdata/dotdesktop/*.desktop testdata/apps/*.pnd testdata/dotdesktop/*.png deployment/usr/lib/libpnd* deployment/usr/bin/pndnotifyd deployment/usr/pandora/scripts/* deployment/etc/sudoers deployment/etc/init.d/pndnotifyd bin/pndvalidator
+       ${RM} -f ${ALLOBJ} ${XMLOBJ} ${LIB} ${SOLIB1} locatetest.o bin/locatetest conftest.o bin/conftest discotest.o bin/discotest bin/notifytest notifytest.o bin/rawpxmltest rawpxmltest.o bin/pndnotifyd pndnotifyd.o ${SOLIB} testdata/dotdesktop/*.desktop testdata/apps/*.pnd testdata/dotdesktop/*.png deployment/usr/lib/libpnd* deployment/usr/bin/pndnotifyd deployment/usr/pandora/scripts/* deployment/etc/sudoers deployment/etc/init.d/pndnotifyd bin/pndvalidator pndvalidator.o
        ${RM} -rf deployment/media
        find . -name "*~*" -exec rm {} \; -print
 
diff --git a/apps/pndvalidator.c b/apps/pndvalidator.c
new file mode 100644 (file)
index 0000000..4307b31
--- /dev/null
@@ -0,0 +1,100 @@
+
+/* pndvalidator - a really dumb little tool to check a given PXML-app or pnd-app for 'compliance'.
+ * The "PXML spec" is not hard-defined so hopefull yover time this tool will prove useful, if it is
+ * updated to be 'tough enough' on PXML/pnd's and people actually use it
+ */
+
+#include <stdio.h>     // for stdio
+#include <string.h>    // for strcmp
+#include "pnd_conf.h"
+#include "pnd_apps.h"
+#include "pnd_pxml.h"
+#include "pnd_utility.h"
+
+int main ( int argc, char *argv[] ) {
+  char *fullpath = NULL;
+  unsigned char do_override = 0;
+  unsigned char do_assets = 0;
+
+  if ( argc <= 1 ) {
+    printf ( "usage: %s [options] path-to-file\n", argv [ 0 ] );
+    printf ( "\n" );
+    printf ( "path-to-file\tCan refer to a PXML.xml in a subdir, or can refer to a .pnd-style application bundle\n" );
+    printf ( "\n" );
+    printf ( "Options:\n" );
+    printf ( "\t-a\tattempt to mount and verify assets (executable, icon, screenshots, etc) are present\n" );
+    printf ( "\t-m\tattempt to merge in PXML-overrides and validate against the result\n" );
+    printf ( "\n" );
+    printf ( "By default, the validator will only pick up the PXML and perform checks on field content.\n" );
+    return ( 0 );
+  }
+
+  unsigned char i = 1;
+
+  while ( i < argc ) {
+
+    if ( strncmp ( argv [ i ], "-m", 2 ) == 0 ) {
+      do_override = 1;
+    } else if ( strncmp ( argv [ i ], "-a", 2 ) == 0 ) {
+      do_assets = 1;
+    } else {
+      fullpath = argv [ i ];
+    }
+
+    i++;
+
+  } // while
+
+  // summarize
+
+  if ( do_assets ) {
+    printf ( "Note: Will attempt to examine application assets\n" );
+  }
+
+  if ( do_override ) {
+    printf ( "Note: Will merge PXML-overrides if found (not an error if not found.)\n" );
+  }
+
+  if ( ! fullpath ) {
+    printf ( "ERROR: No path provided.\n" );
+    return ( 0 );
+  }
+
+  printf ( "Path to examine: %s\n", fullpath );
+
+  printf ( "\n" );
+
+  //
+  // actually do useful work
+  //
+
+  pnd_pxml_handle pxmlh;
+
+  pxmlh = pnd_pxml_get_by_path ( fullpath );
+
+  if ( ! pxmlh ) {
+    printf ( "ERROR: PXML could not be extracted meaningfully.\n" );
+    return ( 0 );
+  }
+
+  printf ( "Got back a meaningful PXML structure.\n" );
+
+  /* check the content
+   */
+
+  // check for required fields
+
+  // exec-path?
+
+  // app name?
+
+  // unique ID
+
+  // package-name (shortname)
+
+  /* done!
+   */
+  pnd_pxml_delete ( pxmlh );
+
+  return ( 0 );
+}
index da192f2..12cfa6b 100644 (file)
@@ -22,7 +22,7 @@ extern "C" {
 #define PND_PXML_OVERRIDE_SEARCHPATH "~/pxml-overrides"
 #define PND_PXML_OVERRIDE_KEY "overrides.searchpath"
 
-#define PND_MOUNT_PATH "/mnt/apps/" /* all mounted PND images should be here.. /mnt/apps/myapp/... */
+#define PND_MOUNT_PATH "/mnt/pnd/" /* all mounted PND images should be here.. /mnt/apps/UNIQUE-ID/... */
 
 // .desktop support
 #define PND_DOTDESKTOP_KEY "dotfiles.dotdesktoppath"
@@ -48,7 +48,8 @@ extern "C" {
 #define PND_EXEC_OPTION_NIL        0
 #define PND_EXEC_OPTION_BLOCK      1 /* wait till children complete; note, children might fork on their own.. */
 #define PND_EXEC_OPTION_NOUNION    2 /* request pnd_run not use a union, just do the mount/run */
-#define PND_EXEC_OPTION_FUTURE2    4
+#define PND_EXEC_OPTION_NOX11      4 /* request pnd_run to kill x11 and restart it after */
+#define PND_EXEC_OPTION_FUTURE2    8
 
 unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
                              char *rel_exec, char *rel_startdir,
index dc9e382..17d10a7 100644 (file)
@@ -55,6 +55,7 @@ typedef struct {
   char *main_category;
   char *clockspeed;
   char *startdir;
+  char *option_no_x11;
 } pnd_disco_t;
 
 void pnd_disco_destroy ( pnd_disco_t *p ); // a function name that simply could not be avoided
index 2abefba..d804913 100644 (file)
@@ -34,6 +34,17 @@ unsigned char pnd_pnd_accrue_pxml ( FILE *f, char *target, unsigned int maxlen )
 // only work in a non-binary buffer.) Brute force zombies ahead!
 char *pnd_match_binbuf ( char *haystack, unsigned int maxlen, char *needle );
 
+// pnd_mount() is for mounting a .pnd or PXML-app into the filesystem without running the app; for
+// instance, should you want to browse screenshots (listed from PXML say?), you might want to
+// pnd_mount(), lurk around in the mount, and then pnd_unmount() to release it
+// On success, _mount and _unmount return >0
+unsigned char pnd_pnd_mount ( char *pndrun, char *fullpath, char *unique_id );
+unsigned char pnd_pnd_unmount ( char *pndrun, char *fullpath, char *unique_id );
+// should you wish to know where an app will get mounted, call this function to obtain a guess. The
+// logic is wrapped up in pnd_run.sh, but in theory should be easily determined.
+//   r_mountpoint (if !NULL) will be populated; mountpoint_len should specify the maxlen of the buffer
+void pnd_get_mountpoint ( char *unique_id, char *r_mountpoint, unsigned int mountpoint_len );
+
 #ifdef __cplusplus
 } /* "C" */
 #endif
index 693b26a..e8853c2 100644 (file)
@@ -60,6 +60,7 @@ char *pnd_pxml_get_version_minor ( pnd_pxml_handle h );
 char *pnd_pxml_get_version_release ( pnd_pxml_handle h );
 char *pnd_pxml_get_version_build ( pnd_pxml_handle h );
 char *pnd_pxml_get_exec ( pnd_pxml_handle h );
+char *pnd_pxml_get_exec_option_no_x11 ( pnd_pxml_handle h );
 char *pnd_pxml_get_main_category ( pnd_pxml_handle h );
 char *pnd_pxml_get_subcategory1 ( pnd_pxml_handle h );
 char *pnd_pxml_get_subcategory2 ( pnd_pxml_handle h );
@@ -138,6 +139,7 @@ typedef struct
        char *clockspeed;
        char *background;
        char *startdir;
+       char *exec_no_x11;
        char *package_name;
        char *package_release_date;
 
index 2aef7a4..15540eb 100644 (file)
@@ -22,6 +22,7 @@ extern "C" {
 #define PND_PXML_ATTRNAME_EXECSTAL "standalone"
 #define PND_PXML_ATTRNAME_EXECCMD "command"
 #define PND_PXML_ATTRNAME_EXECWD "startdir"
+#define PND_PXML_ATTRNAME_EXECNOX11 "no_x11"
 
 /* <icon src="..." /> */
 #define PND_PXML_ENAME_ICON "icon"
index d2d2ce6..c4a0ad0 100644 (file)
@@ -66,6 +66,10 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id,
     argv [ f++ ] = "-n"; // no union for now
   }
 
+  if ( options & PND_EXEC_OPTION_NOX11 ) {
+    argv [ f++ ] = "-x"; // no union for now
+  }
+
   // finish
   argv [ f++ ] = NULL; // for execv
 
index 58b1191..bac1634 100644 (file)
@@ -97,6 +97,11 @@ unsigned char pnd_emit_dotdesktop ( char *targetpath, char *pndrun, pnd_disco_t
       strncat ( buffer, p -> startdir, 1020 );
     }
 
+    // exec options
+    if ( p -> option_no_x11 ) {
+      strncat ( buffer, " -x ", 1020 );
+    }
+
     // newline
     strncat ( buffer, "\n", 1020 );
 
index b6d5860..df0aa7e 100644 (file)
@@ -181,6 +181,9 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       if ( pnd_pxml_get_exec ( pxmlh ) ) {
        p -> exec = strdup ( pnd_pxml_get_exec ( pxmlh ) );
       }
+      if ( pnd_pxml_get_exec_option_no_x11 ( pxmlh ) ) {
+       p -> option_no_x11 = strdup ( pnd_pxml_get_exec_option_no_x11 ( pxmlh ) );
+      }
       if ( pnd_pxml_get_unique_id ( pxmlh ) ) {
        p -> unique_id = strdup ( pnd_pxml_get_unique_id ( pxmlh ) );
       }
index b539401..d249636 100644 (file)
@@ -2,6 +2,7 @@
 #include <stdio.h> /* for FILE etc */
 #include <stdlib.h> /* for malloc */
 #include <ctype.h> /* for isprint */
+#include <unistd.h> /* for fork/exec */
 
 #define __USE_GNU
 #include <string.h> /* for making strcasestr happy */
@@ -131,3 +132,86 @@ char *pnd_match_binbuf ( char *haystack, unsigned int maxlen, char *needle ) {
 
   return ( NULL );
 }
+
+void pnd_get_mountpoint ( char *unique_id, char *r_mountpoint, unsigned int mountpoint_len ) {
+
+  if ( ! r_mountpoint ) {
+    return; // sillyness
+  }
+
+  snprintf ( r_mountpoint, mountpoint_len, "%s/%s", PND_MOUNT_PATH, unique_id );
+
+  return;
+}
+
+static unsigned char pnd_pnd_mountie ( char *pndrun, char *fullpath, char *unique_id, unsigned char do_mount ) {
+  char *argv [ 20 ];
+  int f;
+
+  if ( ! pndrun ) {
+    return ( 0 );
+  }
+
+  if ( ! fullpath ) {
+    return ( 0 );
+  }
+
+  if ( ! unique_id ) {
+    return ( 0 );
+  }
+
+#if 0
+  printf ( "  runscript: %s\n", pndrun );
+  printf ( "  path: %s\n", fullpath );
+  printf ( "  id: %s\n", unique_id );
+#endif
+
+  memset ( argv, '\0', sizeof(char*) * 20 );
+
+  // normal stuff
+  f = 0;
+  argv [ f++ ] = pndrun;
+  argv [ f++ ] = "-p";
+  argv [ f++ ] = fullpath;
+  argv [ f++ ] = "-b";
+  argv [ f++ ] = unique_id;
+
+  // mount-only
+  if ( do_mount ) {
+    argv [ f++ ] = "-m";
+  } else {
+    argv [ f++ ] = "-u";
+  }
+
+  // finish
+  argv [ f++ ] = NULL; // for execv
+
+  // debug
+#if 0
+  int i;
+  for ( i = 0; i < f; i++ ) {
+    printf ( "exec's argv %u [ %s ]\n", i, argv [ i ] );
+  }
+#endif
+
+  // invoke it!
+
+  if ( ( f = fork() ) < 0 ) {
+    // error forking
+  } else if ( f > 0 ) {
+    // parent
+  } else {
+    // child, do it
+    execv ( pndrun, argv );
+  } 
+
+  return ( 1 );
+}
+
+unsigned char pnd_pnd_mount ( char *pndrun, char *fullpath, char *unique_id ) {
+  return ( pnd_pnd_mountie ( pndrun, fullpath, unique_id, 1 ) );
+}
+
+unsigned char pnd_pnd_unmount ( char *pndrun, char *fullpath, char *unique_id ) {
+  return ( pnd_pnd_mountie ( pndrun, fullpath, unique_id, 0 ) );
+}
index 6b1c96e..6ad67c3 100644 (file)
@@ -383,6 +383,11 @@ char *pnd_pxml_get_exec ( pnd_pxml_handle h ) {
   return ( p -> exec );
 }
 
+char *pnd_pxml_get_exec_option_no_x11 ( pnd_pxml_handle h ) {
+  pnd_pxml_t *p = (pnd_pxml_t*) h;
+  return ( p -> exec_no_x11 );
+}
+
 char *pnd_pxml_get_main_category ( pnd_pxml_handle h ) {
   pnd_pxml_t *p = (pnd_pxml_t*) h;
   return ( p -> main_category );
index c8e42c9..bb3a7a3 100644 (file)
@@ -157,6 +157,7 @@ unsigned char pnd_pxml_parse ( const char *pFilename, char *buffer, unsigned int
                app->standalone = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECSTAL);
                app->exec       = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECCMD);
                app->startdir   = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECWD);
+               app->exec_no_x11     = pnd_pxml_get_attribute(pElem, PND_PXML_ATTRNAME_EXECNOX11);
        }
 
        //The app icon:
index 6ee7523..3e46858 100755 (executable)
-#!/bin/bash
-#Usage: pnd_run.sh -p your.pnd -e executeable [-a \"(arguments)\"] [ -s \"cd to folder inside pnd\"] [-u (skip union)] [-b override BASENAME (name of mountpoint/appdata)]
-# -n to skip union mount, should probably be removed before release
-# -s startdir
-# arguments can be inside -e, -a is optional
-#/etc/sudoers needs to be adjusted if you touch any of the sudo lines in the wrong place.
-# parse arguments
-TEMP=`getopt -o p:e:a:b:s:m::u::n:: -- "$@"`
-if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi
-# Note the quotes around `$TEMP': they are essential!
-eval set -- "$TEMP"
-while true ; do
-       case "$1" in
-               -p) echo "pnd set to \`$2'" ;PND=$2;shift 2;;
-               -e) echo "exec set to \`$2'" ;EXENAME=$2;shift 2 ;;
-               -n) echo "u set, no union pls!";NOUNION=1;shift 2;;
-               -b) echo "BASENAME set to $2";BASENAME=$2;shift 2;;
-               -s) echo "startdir set to $2";STARTDIR=$2;shift 2;;
-               -m) echo "mount";mount=1;shift 2;;
-               -u) echo "umount";umount=1;shift 2;;
-               -a) 
-                       case "$2" in
-                               "") echo "no arguments"; shift 2 ;;
-                               *)  echo "args set to \`$2'" ;ARGUMENTS=$2;shift 2 ;;
-                       esac ;;
-               --) shift ; break ;;
-               *) echo "Error while parsing arguments!" ; exit 1 ;;
-       esac
-done
-if [ ! $PND ] || [ ! $EXENAME ]; then
-       echo "Usage: pnd_run.sh -p your.pnd -e executeable [-a \"(arguments)\"] [ -s \"cd to folder inside pnd\"] [-u (skip union)] [-b override BASENAME (name of mountpoint/appdata)]"
-       exit 1
-fi
-#vars
-DFS=$(file -b $PND | awk '{ print $1 }') #is -p a zip/iso or folder?
-MOUNTPOINT=$(df $PND | grep -vE '^Filesystem' | awk '{ print $6  }') #find out which mountpoint the pnd/folder is on, there probably is a better way to do this
-#BASENAME really should be something sensible and somewhat unique
-#if -b is set use that as basename, else generate it from PND
-#get basename (strip extension if file) for union mountpoints etc, maybe  this should be changed to something specified inside the xml
-#this should probably be changed to .... something more sensible
-if [ ! $BASENAME ]; then BASENAME=$(basename "$PND" | cut -d'.' -f1) ; fi
-oCWD=$(pwd)
-#detect fs
-if [ $DFS = ISO ]; then
-       mntline="sudo mount -o loop,mode=777 $PND /mnt/pnd/$BASENAME"
-       echo "Filetype is $DFS"
-elif [ $DFS = Zip ]; then
-       mntline="fuse-zip $PND /mnt/pnd/$BASENAME -o ro,fmask=000" #TOTALLY untested right now
-       echo "Filetype is $DFS"
-elif [ $DFS = directory ]; then
-       mntline="sudo mount --bind -o ro $PND /mnt/pnd/$BASENAME"
-#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
-       echo "Filetype is $DFS"
-else
-       echo "error"
-       exit 1;
-fi
-#create mountpoints, check if they exist already first to avoid annoying error messages
-if [ ! -d /mnt/pnd/$BASENAME ]; then sudo mkdir -p /mnt/pnd/$BASENAME ; fi
-if [ ! -d $MOUNTPOINT/appdata/$BASENAME ]; then sudo mkdir -p $MOUNTPOINT/appdata/$BASENAME; fi
-if [ ! -d /mnt/utmp/$BASENAME ]; then sudo mkdir -p /mnt/utmp/$BASENAME; fi 
-#mount
-if [ ! $NOUNION ] && [ ! $umount ]; then
-       #is the union already mounted? if not mount evrything, else launch the stuff
-       mount | grep "on /mnt/utmp/$BASENAME type" # > /dev/null
-       if [ ! $? -eq 0 ]; then 
-               $mntline #mount the pnd/folder
-               echo "mounting union!"
-               sudo mount -t aufs -o exec,dirs\=$MOUNTPOINT/appdata/$BASENAME=rw+nolwh:/mnt/pnd/$BASENAME=rr none /mnt/utmp/$BASENAME # put union on top
-       else
-               echo "Union already mounted"
-       fi
-       if [ $mount ]; then echo "mounted /mnt/utmp/$BASENAME"; exit 1; fi;
-       #start app
-       cd /mnt/utmp/$BASENAME
-       if [ $STARTDIR ]; then cd $STARTDIR; fi #cd to folder specified by the optional arg -s
-       ./$EXENAME $ARGUMENTS
-#the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!
-       PID=`pidof -o %PPID -x $EXENAME`
-       while [ "$PID" -gt 0 ]
-       do
-       sleep 10s
-       PID=`pidof -o %PPID -x $EXENAME`
-       done
-       echo end
-       #app exited
-       cd $oCWD #cd out of the mountpoint so we can umount, doesnt really matter to where...
-elif [ ! $umount ]; then
-       $mntline
-       if [ $mount ]; then echo "mounted /mnt/pnd/$BASENAME"; exit 1; fi;
-       cd /mnt/pnd/$BASENAME
-       if [ $STARTDIR ]; then cd $STARTDIR; fi
-       echo $(pwd)
-       ./$EXENAME $ARGUMENTS 
-#the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!
-       PID=`pidof -o %PPID -x $EXENAME`
-       while [ "$PID" -gt 0 ]
-       do
-       sleep 10s
-       PID=`pidof -o %PPID -x $EXENAME`
-       done
-       echo end
-       cd $oCWD
-else
-echo "-u set, nothing to do here"
-fi
-#clean up
-if [ ! $NOUNION ] ; then sudo umount /mnt/utmp/$BASENAME; fi #umount union if -u wasnt set
-if [ $NOUNION ] ; then sudo umount /mnt/pnd/$BASENAME; fi #umount iso if -u WAS set
-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
-       if [ ! $NOUNION ] ; then
-               sudo umount /mnt/pnd/$BASENAME
-               sudo rmdir $MOUNTPOINT/appdata/$BASENAME/.wh..wh.plink 
-               sudo rmdir $MOUNTPOINT/appdata/$BASENAME/
-               sudo rmdir /mnt/utmp/$BASENAME;
-       fi
-       sudo rmdir /mnt/pnd/$BASENAME 
-fi
\ No newline at end of file
+#!/bin/bash\r
+ #needs some serious cleanup!\r
\r
+#Usage: pnd_run.sh -p your.pnd -e executeable [-a "(arguments)"] [ -s "cd to folder inside pnd"] [-u (skip union)] [-b override BASENAME (name of mountpoint/appdata)] [-x close x before launching(script needs to be started with nohup for this to work]\r
+# -n to skip union mount, should probably be removed before release\r
+# -s startdir\r
+# arguments can be inside -e, -a is optional\r
\r
+#/etc/sudoers needs to be adjusted if you touch any of the sudo lines in the wrong place.\r
\r
+# look at the comments in the nox part, adjust \r
\r
+#use "lsof /usr/lib/libX11.so.6 | awk '{print $1}'| sort | uniq > whitelist" with nothing running to generate the whitelist\r
\r
+#launch the script with nohup for -x to work!\r
\r
+#todo\r
+#make sure to only use free loop devices!\r
+#cleanup\r
\r
+# parse arguments\r
+TEMP=`getopt -o p:e:a:b:s:m::u::n::x:: -- "$@"`\r
\r
+if [ $? != 0 ] ; then echo "Terminating..." >&2 ; exit 1 ; fi\r
\r
+# Note the quotes around `$TEMP': they are essential!\r
+eval set -- "$TEMP"\r
\r
+while true ; do\r
+       case "$1" in\r
+               -p) echo "pnd set to \`$2'" ;PND=$2;shift 2;;\r
+               -e) echo "exec set to \`$2'" ;EXENAME=$2;shift 2 ;;\r
+               -n) echo "n set, no union pls!";NOUNION=1;shift 2;;\r
+               -b) echo "BASENAME set to $2";BASENAME=$2;shift 2;;\r
+               -s) echo "startdir set to $2";STARTDIR=$2;shift 2;;\r
+               -m) echo "mount";mount=1;shift 2;;\r
+               -u) echo "umount";umount=1;shift 2;;\r
+               -x) echo "no x";nox=1;shift 2;;\r
+               -a) \r
+                       case "$2" in\r
+                               "") echo "no arguments"; shift 2 ;;\r
+                               *)  echo "args set to \`$2'" ;ARGUMENTS=$2;shift 2 ;;\r
+                       esac ;;\r
+               --) shift ; break ;;\r
+               *) echo "Error while parsing arguments!" ; exit 1 ;;\r
+       esac\r
+done\r
\r
+if [ ! $PND ] || [ ! $EXENAME ]; then\r
+       echo "Usage: pnd_run.sh -p your.pnd -e executeable [-a \"(arguments)\"] [ -s \"cd to folder inside pnd\"] [-u (skip union)] [-b override BASENAME (name of mountpoint/appdata)] [-x close x before launching(script needs to be started with nohup for this to work]"\r
+       exit 1\r
+fi\r
+if [ $nox ]; then\r
+       applist=$(lsof /usr/lib/libX11.so.6 | awk '{print $1}'| sort | uniq)\r
+       whitelist=$(cat ~/pndtest/whitelist) #adjust this to a fixed whitelist, maybe in the config dir\r
+       filteredlist=$(echo -e "$applist\n\n$whitelist\n\n$whitelist" | sort | uniq -u) #whitelist appended two times so those items are always removed\r
+       if [ ${#filteredlist} -ge 1 ]; then\r
+               message=$(echo -e "The following applications are still running, are you sure you want to close x? \n$filteredlist")\r
+               echo -e \93ae[34me[30m\94\r
+               xmessage -center "$message", -buttons yes,no\r
+               if [ $? = 102 ]; then\r
+               exit 1\r
+               fi\r
+               sudo /etc/init.d/gdm stop\r
+               sleep 5s\r
+       else\r
+               echo -e \93ae[34me[30m\94\r
+               xmessage -center "killing x, nothing of value will be lost", -buttons ok,cancel\r
+               if [ $? = 102 ]; then\r
+               exit 1\r
+               fi\r
+               # close x now, do we want to use gdm stop or just kill x?\r
+               sudo /etc/init.d/gdm stop\r
+               sleep 5s\r
+       fi\r
+fi\r
\r
+#vars\r
+DFS=$(file -b $PND | awk '{ print $1 }') #is -p a zip/iso or folder?\r
+MOUNTPOINT=$(df $PND | sed -ne 's/.*\% \(\S*\)/\1/p' | tail -n1)\r
+echo "mountpoint: $MOUNTPOINT"\r
+#MOUNTPOINT=$(df -h $PND | grep -E '[1-9]%' | awk '{ print $6  }') #find out which mountpoint the pnd/folder is on, there probably is a better way to do this\r
\r
\r
+#BASENAME really should be something sensible and somewhat unique\r
+#if -b is set use that as basename, else generate it from PND\r
+#get basename (strip extension if file) for union mountpoints etc, maybe  this should be changed to something specified inside the xml\r
+#this should probably be changed to .... something more sensible\r
+if [ ! $BASENAME ]; then BASENAME=$(basename "$PND" | cut -d'.' -f1) ; fi\r
\r
\r
\r
+oCWD=$(pwd)\r
\r
+#detect fs\r
+if [ $DFS = ISO ]; then\r
\r
+       usedminor=$( ls -l /dev/loop* | awk '{print $6}')\r
+       freeminor=$( echo -e "$(seq 0 64)\n$usedminor" | sort -rn | uniq -u | tail -n1)\r
+       sudo mknod -m777 /dev/loop$freeminor b 7 $freeminor\r
+       sudo losetup /dev/loop$freeminor $PND\r
\r
+       mntline="sudo mount /dev/loop$freeminor /mnt/pnd/$BASENAME/"\r
+#      mntline="sudo mount -o loop,mode=777 $PND /mnt/pnd/$BASENAME"\r
+       echo "Filetype is $DFS"\r
+elif [ $DFS = Zip ]; then\r
+       mntline="fuse-zip $PND /mnt/pnd/$BASENAME -o ro,fmask=000" #TOTALLY untested right now\r
+       echo "Filetype is $DFS"\r
+elif [ $DFS = directory ]; then\r
+       mntline="sudo mount --bind -o ro $PND /mnt/pnd/$BASENAME"\r
+#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\r
+       echo "Filetype is $DFS"\r
+else\r
+       echo "error"\r
+       exit 1;\r
+fi\r
\r
+#create mountpoints, check if they exist already first to avoid annoying error messages\r
+if [ ! -d /mnt/pnd/$BASENAME ]; then sudo mkdir -p /mnt/pnd/$BASENAME ; fi\r
+if [ ! -d $MOUNTPOINT/appdata/$BASENAME ]; then sudo mkdir -p $MOUNTPOINT/appdata/$BASENAME; fi\r
+if [ ! -d /mnt/utmp/$BASENAME ]; then sudo mkdir -p /mnt/utmp/$BASENAME; fi \r
\r
+#mount\r
\r
+if [ ! $NOUNION ] && [ ! $umount ]; then\r
+       #is the union already mounted? if not mount evrything, else launch the stuff\r
+       mount | grep "on /mnt/utmp/$BASENAME type" # > /dev/null\r
+       if [ ! $? -eq 0 ]; then \r
+               echo "$mntline"\r
+               $mntline #mount the pnd/folder\r
+               echo "mounting union!"\r
+               sudo mount -t aufs -o exec,dirs\=$MOUNTPOINT/appdata/$BASENAME=rw+nolwh:/mnt/pnd/$BASENAME=rr none /mnt/utmp/$BASENAME # put union on top\r
\r
+       else\r
+               echo "Union already mounted"\r
+       fi\r
\r
+       if [ $mount ]; then echo "mounted /mnt/utmp/$BASENAME"; exit 1; fi;\r
\r
+       #start app\r
+       cd /mnt/utmp/$BASENAME\r
+       if [ $STARTDIR ]; then cd $STARTDIR; fi #cd to folder specified by the optional arg -s\r
+       #echo "/lib/ld-linux.so.2 --library-path /mnt/utmp/$BASENAME/ $EXENAME $ARGUMENTS"\r
+       #/lib/ld-linux.so.2 --library-path /mnt/utmp/$BASENAME/ $EXENAME $ARGUMENTS\r
+       LD_LIBRARY_PATH=/mnt/utmp/$BASENAME ./$EXENAME $ARGUMENTS\r
+       #the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!\r
+       PID=`pidof -o %PPID -x $EXENAME`\r
+       while [ "$PID" ]\r
+       do\r
+       sleep 10s\r
+       PID=`pidof -o %PPID -x $EXENAME`\r
+       done\r
+       echo end\r
\r
+       #app exited\r
+       cd $oCWD #cd out of the mountpoint so we can umount, doesnt really matter to where...\r
\r
+elif [ ! $umount ]; then\r
+       $mntline\r
+       if [ $mount ]; then echo "mounted /mnt/pnd/$BASENAME"; exit 1; fi;\r
+       cd /mnt/pnd/$BASENAME\r
+       if [ $STARTDIR ]; then cd $STARTDIR; fi\r
+       echo $(pwd)\r
+       #/lib/ld-linux.so.2 --library-path /mnt/pnd/$BASENAME/ $EXENAME $ARGUMENTS      \r
+       ./$EXENAME $ARGUMENTS \r
+       LD_LIBRARY_PATH=/mnt/pnd/$BASENAME ./$EXENAME $ARGUMENTS\r
+       #the app could have exited now, OR it went into bg, we still need to wait in that case till it really quits!\r
+       PID=`pidof -o %PPID -x $EXENAME`\r
+       while [ $PID ]\r
+       do\r
+       sleep 10s\r
+       PID=`pidof -o %PPID -x $EXENAME`\r
+       done\r
+       echo end\r
\r
+       cd $oCWD\r
+else\r
+echo "-u set, nothing to do here"\r
+fi\r
\r
\r
+#clean up\r
+if [ ! $NOUNION ] ; then sudo umount /mnt/utmp/$BASENAME; fi #umount union if -u wasnt set\r
+if [ $NOUNION ] ; then sudo umount /mnt/pnd/$BASENAME; fi #umount iso if -u WAS set\r
+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\r
+       if [ ! $NOUNION ] ; then\r
+               sudo umount /mnt/pnd/$BASENAME\r
+               sudo rmdir $MOUNTPOINT/appdata/$BASENAME/.wh..wh.plink \r
+               sudo rmdir $MOUNTPOINT/appdata/$BASENAME/\r
+               sudo rmdir /mnt/utmp/$BASENAME;\r
+       fi\r
+       if [ $DFS = ISO ]; then\r
+               sudo losetup -d /dev/loop$freeminor\r
+               sudo rm /dev/loop$freeminor\r
+       fi\r
+       sudo rmdir /mnt/pnd/$BASENAME \r
+fi\r
+if [ $nox ]; then\r
+echo "starting x in 5s"\r
+sleep 5\r
+sudo /etc/init.d/gdm start\r
+fi\r
+\r
index 3023434..e665243 100644 (file)
@@ -1,6 +1,7 @@
-ALL ALL=NOPASSWD:NOEXEC: /bin/mount -o loop\,mode=777 *pnd /mnt/pnd/* , \
-/bin/mount -t aufs -o exec\,dirs\=*/appdata/*\=rw+nolwh\:/mnt/pnd/*\=rr none /mnt/utmp/* , \
-/bin/mount --bind -o ro * /mnt/pnd/*, \
-/bin/umount /mnt/pnd/*, /bin/umount /mnt/utmp/*, \
-/bin/mkdir -p /mnt/pnd/* , /bin/mkdir -p /mnt/utmp/* , /bin/mkdir -p */appdata/* , \
-/bin/rmdir /mnt/pnd/*,/bin/rmdir /mnt/utmp/* ,/bin/rmdir */appdata/*/.wh..wh.plink ,/bin/rmdir */appdata/*/
+ALL ALL=NOPASSWD: /etc/init.d/gdm stop, /etc/init.d/gdm start, NOEXEC: /bin/mount -o loop\,mode=777 *pnd /mnt/pnd/* , \ \r
+/bin/mount -t aufs -o exec\,dirs\=*/appdata/*\=rw+nolwh\:/mnt/pnd/*\=rr none /mnt/utmp/* , \\r
+/bin/mount --bind -o ro * /mnt/pnd/*, \\r
+/bin/umount /mnt/pnd/*, /bin/umount /mnt/utmp/*, \\r
+/bin/mkdir -p /mnt/pnd/* , /bin/mkdir -p /mnt/utmp/* , /bin/mkdir -p */appdata/* , \\r
+/bin/rmdir /mnt/pnd/*,/bin/rmdir /mnt/utmp/* ,/bin/rmdir */appdata/*/.wh..wh.plink ,/bin/rmdir */appdata/*/, \\r
+/sbin/losetup /dev/loop*, /sin/mknod -m777 /dev/loop*, /sbin/losetup -d /dev/loop*, /bin/rm /dev/loop*\r