From: skeezix Date: Mon, 23 Feb 2009 22:54:44 +0000 (-0500) Subject: Added first stab of pnd exec support X-Git-Tag: Release-2010-05/1~210 X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?p=pandora-libraries.git;a=commitdiff_plain;h=c2df73cf09db1c3a0315b6644d8cec64eeeffb35 Added first stab of pnd exec support Fixed base path in auto-disco to drop PXML.xml portion (but keep .pnd portion) Added pnd_apps.c/pnd_apps_exec() .desktop file should have a useful Exec line in it now --- diff --git a/Makefile b/Makefile index 90de4c4..14564da 100644 --- a/Makefile +++ b/Makefile @@ -20,12 +20,13 @@ LIB = libpnd.a SOLIB = libpnd.so.1 # canonicle name SOLIB1 = libpnd.so.1.0.1 # versioned name XMLOBJ = lib/tinyxml/tinystr.o lib/tinyxml/tinyxml.o lib/tinyxml/tinyxmlerror.o lib/tinyxml/tinyxmlparser.o -ALLOBJ = pnd_conf.o pnd_container.o pnd_discovery.o pnd_pxml.o pnd_notify.o pnd_locate.o pnd_tinyxml.o pnd_pndfiles.o +ALLOBJ = pnd_conf.o pnd_container.o pnd_discovery.o pnd_pxml.o pnd_notify.o pnd_locate.o pnd_tinyxml.o pnd_pndfiles.o pnd_apps.o all: ${SOLIB} ${LIB} conftest discotest notifytest locatetest pndnotifyd clean: ${RM} -f ${ALLOBJ} ${XMLOBJ} ${LIB} ${SOLIB1} locatetest.o bin/locatetest conftest.o bin/conftest discotest.o bin/discotest bin/notifytest notifytest.o bin/pndnotifyd pndnotifyd.o ${SOLIB} testdata/dotdesktop/*.desktop + find . -name "*~*" -exec rm {} \; -print libpnd.a: ${ALLOBJ} ${XMLOBJ} ${AR} r ${LIB} ${ALLOBJ} ${XMLOBJ} diff --git a/TODO.txt b/TODO.txt index 90e253e..97388cc 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,10 @@ Some things to be done.. +- put in code to fetch clock speed, and add clock speed handler to pnd_apps_exec + +- remove -u's from pnd_apps_exec and pnd_emit_dotdesktop + - replace brute force memcmp() in pnd pnd with a fancy pants CS alg - review pnd_tinyxml to ensure the PXML_FILENAME is csae insensitive as needed diff --git a/apps/pndnotifyd.c b/apps/pndnotifyd.c index b534153..3cc1686 100644 --- a/apps/pndnotifyd.c +++ b/apps/pndnotifyd.c @@ -25,6 +25,7 @@ #include "pnd_notify.h" #include "../lib/pnd_pathiter.h" #include "pnd_discovery.h" +#include "pnd_locate.h" static unsigned char g_daemon_mode = 0; @@ -40,6 +41,10 @@ int main ( int argc, char *argv[] ) { // behaviour unsigned char scanonlaunch = 1; unsigned int interval_secs = 20; + // pnd runscript + char *run_searchpath; + char *run_script; + char *pndrun; // misc int i; @@ -138,6 +143,39 @@ int main ( int argc, char *argv[] ) { dotdesktoppath = PND_DOTDESKTOP_DEFAULT; } + // try to locate a runscript + + if ( apph ) { + run_searchpath = pnd_conf_get_as_char ( apph, PND_PNDRUN_SEARCHPATH_KEY ); + run_script = pnd_conf_get_as_char ( apph, PND_PNDRUN_KEY ); + pndrun = NULL; + + if ( ! run_searchpath ) { + run_searchpath = PND_APPS_SEARCHPATH; + run_script = PND_PNDRUN_FILENAME; + } + + } else { + run_searchpath = NULL; + run_script = NULL; + pndrun = PND_PNDRUN_DEFAULT; + } + + if ( ! pndrun ) { + pndrun = pnd_locate_filename ( run_searchpath, run_script ); + + if ( ! pndrun ) { + pndrun = PND_PNDRUN_DEFAULT; + } + + } + + if ( ! g_daemon_mode ) { + if ( run_searchpath ) printf ( "Locating pnd run in %s\n", run_searchpath ); + if ( run_script ) printf ( "Locating pnd runscript as %s\n", run_script ); + if ( pndrun ) printf ( "Default pndrun is %s\n", pndrun ); + } + /* startup */ @@ -214,7 +252,7 @@ int main ( int argc, char *argv[] ) { } // create the .desktop file - if ( pnd_emit_dotdesktop ( dotdesktoppath, d ) ) { + if ( pnd_emit_dotdesktop ( dotdesktoppath, pndrun, d ) ) { // add a watch onto the newly created .desktop? #if 0 char buffer [ FILENAME_MAX ]; diff --git a/include/pnd_apps.h b/include/pnd_apps.h index 6cf16b4..3f2065a 100644 --- a/include/pnd_apps.h +++ b/include/pnd_apps.h @@ -9,8 +9,8 @@ extern "C" { #define PND_APPS_SEARCHPATH "/mnt/sd1/pandora/apps:/mnt/sd2/pandora/apps:./testdata/apps" #define PND_APPS_KEY "autodiscovery.searchpath" -#define PND_PNDRUN_SEARCHPATH "pnd.searchpath" -#define PND_PNDRUN_KEY "pnd.default" +#define PND_PNDRUN_SEARCHPATH_KEY "pnd.searchpath" +#define PND_PNDRUN_KEY "pnd.runscript" #define PND_PNDRUN_FILENAME "pnd_run.sh" #define PND_PNDRUN_DEFAULT "./testdata/scripts/pnd_run.sh" @@ -29,12 +29,12 @@ extern "C" { /* pnd_apps_exec() is used to blindly launch an app, be it a .pnd file bundle or a plain executable * (shell, bin, whatever.) pndrun specifies the full path to the pnd_run sh script, which should be * found using searchpaths and locates.. see locatetest.c for a sample - * if fullpath ends in PXML_FILENAME (PXML.xml) then pnd_run will be invoked (after extracting goodies - * from PXML file as appropriate) - * if fullpath ends in .pnd then pnd_run will be invoked (after inspecting embedded PXML or best-guess) - * otherwise the fullpath will be executed as-is + * NOTE: Use pnd_locate function to locate the pnd_run, for example + * NOTE: clock speed will be set prior to invoking the script, and set back on exit + * NOTE: No values can be except clockspeed; a 0 clockspeed means 'leave alone'. Set startdoir to "." instead of NULL. + * fork() is implied; calling this function does not kill this process :) */ -signed char pnd_apps_exec ( char *fullpath, char *pndrun ); +unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, char *rel_exec, char *rel_startdir, unsigned int clockspeed ); #ifdef __cplusplus } /* "C" */ diff --git a/include/pnd_discovery.h b/include/pnd_discovery.h index 19de2dc..59029dd 100644 --- a/include/pnd_discovery.h +++ b/include/pnd_discovery.h @@ -51,7 +51,7 @@ void pnd_disco_destroy ( pnd_disco_t *p ); // a function name that simply could // emit_dotdesktop() will determine a filename and create a FILENAME.desktop file in the targetpath // TODO: Copy the icon into this directory as well, if its source is a .pnd or info is in the dico struct -unsigned char pnd_emit_dotdesktop ( char *targetpath, pnd_disco_t *p ); +unsigned char pnd_emit_dotdesktop ( char *targetpath, char *pndrun, pnd_disco_t *p ); // TODO: A way to release the disco-lists and reclaim RAM :) diff --git a/lib/pnd_apps.c b/lib/pnd_apps.c new file mode 100644 index 0000000..daf3dda --- /dev/null +++ b/lib/pnd_apps.c @@ -0,0 +1,62 @@ + +#include /* for FILE etc */ +#include /* for malloc */ +#include /* for memset */ +#include /* for fork/exec */ + +#include "pnd_container.h" +#include "pnd_pxml.h" +#include "pnd_apps.h" + +unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, char *rel_exec, char *rel_startdir, unsigned int clockspeed ) { + char *argv [ 20 ]; + int f, i; + + printf ( "Entering pnd_apps_exec\n" ); +#if 0 + printf ( " runscript: %s\n", pndrun ); + printf ( " path: %s\n", fullpath ); + printf ( " id: %s\n", unique_id ); + printf ( " exec: %s\n", rel_exec ); + printf ( " cwd: %s\n", rel_startdir ); + printf ( " clock: %u\n", clockspeed ); +#endif + + memset ( argv, '\0', sizeof(char*) * 20 ); + + f = 0; + argv [ f++ ] = pndrun; + argv [ f++ ] = "-p"; + argv [ f++ ] = fullpath; + argv [ f++ ] = "-e"; + argv [ f++ ] = rel_exec; + // skip -a (arguments) for now + + //argv [ f++ ] = "-b"; + //argv [ f++ ] = baename; + + argv [ f++ ] = "-u"; // no union for now + argv [ f++ ] = NULL; // for execv + + // debug +#if 0 + 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 ); + } + + printf ( "Exiting pnd_apps_exec\n" ); + + return ( 1 ); +} diff --git a/lib/pnd_discovery.c b/lib/pnd_discovery.c index caf3ccb..84de948 100644 --- a/lib/pnd_discovery.c +++ b/lib/pnd_discovery.c @@ -128,12 +128,17 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, // check for validity and add to resultset if it looks executable if ( pnd_is_pxml_valid_app ( pxmlh ) ) { pnd_disco_t *p; + char *fixpxml; p = pnd_box_allocinsert ( disco_box, (char*) fpath, sizeof(pnd_disco_t) ); // base path p -> path_to_object = strdup ( fpath ); + if ( ( fixpxml = strcasestr ( p -> path_to_object, PXML_FILENAME ) ) ) { + *fixpxml = '\0'; // if this is not a .pnd, lop off the PXML.xml at the end + } + // PXML fields if ( pnd_pxml_get_app_name_en ( pxmlh ) ) { p -> title_en = strdup ( pnd_pxml_get_app_name_en ( pxmlh ) ); @@ -201,7 +206,7 @@ pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath ) { return ( disco_box ); } -unsigned char pnd_emit_dotdesktop ( char *targetpath, pnd_disco_t *p ) { +unsigned char pnd_emit_dotdesktop ( char *targetpath, char *pndrun, pnd_disco_t *p ) { char filename [ FILENAME_MAX ]; char buffer [ 1024 ]; FILE *f; @@ -263,7 +268,7 @@ unsigned char pnd_emit_dotdesktop ( char *targetpath, pnd_disco_t *p ) { #endif if ( p -> exec ) { - snprintf ( buffer, 1020, "Exec=%s\n", p -> exec ); + snprintf ( buffer, 1020, "Exec=%s -p %s -e %s -u\n", pndrun, p -> path_to_object, p -> exec ); fprintf ( f, "%s", buffer ); } diff --git a/lib/pnd_pndfiles.c b/lib/pnd_pndfiles.c index a8f564c..b539401 100644 --- a/lib/pnd_pndfiles.c +++ b/lib/pnd_pndfiles.c @@ -45,7 +45,7 @@ unsigned char pnd_pnd_seek_pxml ( FILE *f ) { while ( 1 ) { - printf ( "find pxml; pos %u readable %u\n", pos, readable ); + //printf ( "find pxml; pos %u readable %u\n", pos, readable ); // seek into this blocks position fseek ( f, pos, SEEK_SET ); @@ -58,7 +58,7 @@ unsigned char pnd_pnd_seek_pxml ( FILE *f ) { // performing brute force strategy here. if ( ( match = pnd_match_binbuf ( b, readable, PXML_TAGHEAD ) ) ) { fseek ( f, pos + ( match - b ), SEEK_SET ); - printf ( " match found at %u\n", pos + ( match - b ) ); + //printf ( " match found at %u\n", pos + ( match - b ) ); free ( b ); return ( 1 ); } diff --git a/test/discotest.c b/test/discotest.c index 7186ce6..a299e7d 100644 --- a/test/discotest.c +++ b/test/discotest.c @@ -7,6 +7,7 @@ #include "pnd_apps.h" #include "pnd_pxml.h" #include "pnd_discovery.h" +#include "pnd_locate.h" int main ( void) { char *configpath; @@ -98,6 +99,51 @@ int main ( void) { printf ( "No applications found in search path\n" ); } + // lets toy with executing an application + char *run_searchpath; + char *run_script; + char *pndrun; + + if ( apph ) { + run_searchpath = pnd_conf_get_as_char ( apph, PND_PNDRUN_SEARCHPATH_KEY ); + run_script = pnd_conf_get_as_char ( apph, PND_PNDRUN_KEY ); + pndrun = NULL; + + if ( ! run_searchpath ) { + run_searchpath = PND_APPS_SEARCHPATH; + run_script = PND_PNDRUN_FILENAME; + } + + } else { + run_searchpath = NULL; + run_script = NULL; + pndrun = PND_PNDRUN_DEFAULT; + } + + if ( ! pndrun ) { + pndrun = pnd_locate_filename ( run_searchpath, run_script ); + } + + if ( run_searchpath ) printf ( "Locating pnd run in %s\n", run_searchpath ); + if ( run_script ) printf ( "Locating pnd runscript as %s\n", run_script ); + if ( pndrun ) printf ( "Default pndrun is %s\n", pndrun ); + + if ( ! pndrun ) { + printf ( "*** Couldn't locate a pnd runscript.\n" ); + } else { + printf ( "Found a pnd runscript of %s\n", pndrun ); + + pnd_disco_t *d = pnd_box_get_head ( applist ); + if ( d ) { + d = pnd_box_get_next ( d ); + + if ( d ) { + pnd_apps_exec ( pndrun, d -> path_to_object, d -> unique_id, d -> exec, d -> startdir, atoi ( d -> clockspeed ) ); + } + } + + } + // exeunt with alarums free ( configpath ); if ( apph ) { diff --git a/test/locatetest.c b/test/locatetest.c index 59ad3b0..64b94ca 100644 --- a/test/locatetest.c +++ b/test/locatetest.c @@ -24,17 +24,17 @@ int main ( int argc, char *argv[] ) { apph = pnd_conf_fetch_by_id ( pnd_conf_apps, configpath ); if ( apph ) { - pndpath = pnd_conf_get_as_char ( apph, PND_PNDRUN_SEARCHPATH ); + pndpath = pnd_conf_get_as_char ( apph, PND_PNDRUN_SEARCHPATH_KEY ); printf ( "Found a path in apps config: '%s'\n", pndpath ); if ( ! pndpath ) { - pndpath = PND_PNDRUN_SEARCHPATH; + pndpath = PND_PNDRUN_SEARCHPATH_KEY; } } else { // couldn't find a useful app search path so use the default - pndpath = PND_PNDRUN_SEARCHPATH; + pndpath = PND_PNDRUN_SEARCHPATH_KEY; } // given a searchpath (Default or configured), try to find pnd_run.sh; if not diff --git a/testdata/conf/apps b/testdata/conf/apps index fe47925..ed63b52 100644 --- a/testdata/conf/apps +++ b/testdata/conf/apps @@ -12,4 +12,4 @@ searchpath ~/pxml-overrides:./testdata/apps-override # [pnd] defines where to locate the pnd support scripts, so the user may override pnd_run.sh without clobbering built in [pnd] searchpath /mnt/sd1/pandora/scripts:/mnt/sd2/pandora/scripts:./testdata/scripts -default pndrun.sh +runscript pnd_run.sh diff --git a/testdata/pndsample/x86_ls.pnd b/testdata/pndsample/x86_ls.pnd index a3f11b4..7ff984d 100644 Binary files a/testdata/pndsample/x86_ls.pnd and b/testdata/pndsample/x86_ls.pnd differ diff --git a/testdata/pndsample/x86_ls/PXML.xml b/testdata/pndsample/x86_ls/PXML.xml index 87f9873..7977b97 100644 --- a/testdata/pndsample/x86_ls/PXML.xml +++ b/testdata/pndsample/x86_ls/PXML.xml @@ -38,7 +38,7 @@ 2 -program.exe +./my_ls
Main category
diff --git a/testdata/pndsample/x86_ls/ls b/testdata/pndsample/x86_ls/my_ls similarity index 100% rename from testdata/pndsample/x86_ls/ls rename to testdata/pndsample/x86_ls/my_ls diff --git a/testdata/scripts/pnd_run.sh b/testdata/scripts/pnd_run.sh old mode 100644 new mode 100755 index eac2552..ce32ff3 --- a/testdata/scripts/pnd_run.sh +++ b/testdata/scripts/pnd_run.sh @@ -48,7 +48,7 @@ oCWD=$(pwd) #detect fs if [ $DFS = ISO ]; then - mntline="mount -o loop $PND /mnt/pnd/$BASENAME" + mntline="mount -o loop,exec,umask=777 $PND /mnt/pnd/$BASENAME" echo "Filetype is $DFS" elif [ $DFS = Zip ]; then mntline="fuse-zip $PND /mnt/pnd/$BASENAME -oro" #should be reight now @@ -85,7 +85,7 @@ if [ ! $UNION ] ; then $mntline #mount the pnd/folder #mount -t unionfs -o exec,dirs\=$MOUNTPOINT/appdata/$BASENAME=rw:/mnt/pnd/$BASENAME=ro unionfs /mnt/utmp/$BASENAME #union mount #aufs, one of those should work, bit unsure. - mount -t aufs -o exec,dirs\=$MOUNTPOINT/appdata/$BASENAME=rw:/mnt/pnd/$BASENAME=ro none /mnt/utmp/$BASENAME #aufs? + mount -t aufs -o exec,umask=777,dirs\=$MOUNTPOINT/appdata/$BASENAME=rw:/mnt/pnd/$BASENAME=ro none /mnt/utmp/$BASENAME #aufs? #mount -t aufs -o exec,dirs\=$MOUNTPOINT/appdata/$BASENAME=rw:/mnt/pnd/$BASENAME=ro aufs /mnt/utmp/$BASENAME #aufs? " else