X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fpnd_apps.c;h=92a4b7afec1805e64881cf4c6cc263f23ac1da67;hb=560741a4dde4b672b39b6b035e69ac19edb87d4e;hp=4a2cf94665239dae3e787c155439062d95e54a71;hpb=6e40531b7e674b6cf20ff9d43c3068071de6e0a8;p=pandora-libraries.git diff --git a/lib/pnd_apps.c b/lib/pnd_apps.c index 4a2cf94..92a4b7a 100644 --- a/lib/pnd_apps.c +++ b/lib/pnd_apps.c @@ -3,6 +3,7 @@ #include /* for malloc */ #include /* for memset */ #include /* for fork/exec */ +#include #include /* for wait */ #include /* for wait */ @@ -10,12 +11,19 @@ #include "pnd_container.h" #include "pnd_pxml.h" #include "pnd_apps.h" +#include "pnd_logger.h" -unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, - char *rel_exec, char *rel_startdir, - unsigned int clockspeed, unsigned int options ) +static char apps_exec_runline [ 1024 ]; + +char *pnd_apps_exec_runline ( void ) { + return ( apps_exec_runline ); +} + +unsigned char pnd_apps_exec_disco ( char *pndrun, pnd_disco_t *app, + unsigned int options, void *reserved ) { - char *argv [ 20 ]; + char *argv [ 60 ]; + char fullpath [ PATH_MAX ] = ""; int f; //printf ( "Entering pnd_apps_exec\n" ); @@ -24,27 +32,23 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, return ( 0 ); } - if ( ! fullpath ) { + if ( ! app -> unique_id ) { return ( 0 ); } - if ( ! unique_id ) { + if ( ! app -> exec ) { return ( 0 ); } - if ( ! rel_exec ) { + if ( options & PND_EXEC_OPTION_INFO && ! reserved ) { return ( 0 ); } -#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 + // determine path to pnd-file + sprintf ( fullpath, "%s/%s", app -> object_path, app -> object_filename ); + // nail down argv for the app + // memset ( argv, '\0', sizeof(char*) * 20 ); f = 0; @@ -52,23 +56,114 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, argv [ f++ ] = "-p"; argv [ f++ ] = fullpath; argv [ f++ ] = "-e"; - argv [ f++ ] = rel_exec; - if ( rel_startdir ) { + if ( options & PND_EXEC_OPTION_INFO ) { + argv [ f++ ] = ((pnd_apps_exec_info_t*)reserved) -> viewer; + } else { + argv [ f++ ] = app -> exec; + } + if ( app -> startdir ) { argv [ f++ ] = "-s"; - argv [ f++ ] = rel_startdir; + argv [ f++ ] = app -> startdir; + } + if ( options & PND_EXEC_OPTION_INFO ) { + if ( ((pnd_apps_exec_info_t*)reserved) -> args ) { + argv [ f++ ] = "-a"; + argv [ f++ ] = ((pnd_apps_exec_info_t*)reserved) -> args; + } + } else { + if ( app -> execargs ) { + argv [ f++ ] = "-a"; + argv [ f++ ] = app -> execargs; + } + } + if ( app -> appdata_dirname ) { + argv [ f++ ] = "-b"; + argv [ f++ ] = app -> appdata_dirname; + } else { + argv [ f++ ] = "-b"; + argv [ f++ ] = app -> unique_id; } - // skip -a (arguments) for now - //argv [ f++ ] = "-b"; - //argv [ f++ ] = baename; + if ( options & PND_EXEC_OPTION_INFO ) { + // we don't need to overclock for showing info :) do we? crazy active .js pages maybe? + } else { + if ( app -> clockspeed ) { + argv [ f++ ] = "-c"; + argv [ f++ ] = app -> clockspeed; + } + } + + // skip -a (arguments) for now if ( options & PND_EXEC_OPTION_NOUNION ) { argv [ f++ ] = "-n"; // no union for now } + if ( options & PND_EXEC_OPTION_NOX11 ) { + argv [ f++ ] = "-x"; // shut down X! + } + // finish argv [ f++ ] = NULL; // for execv + // stop here? + if ( options & PND_EXEC_OPTION_NORUN ) { + unsigned char i; + bzero ( apps_exec_runline, 1024 ); + //pnd_log ( PND_LOG_DEFAULT, "Norun %u\n", f ); + unsigned char quotenext = 0; + for ( i = 0; i < ( f - 1 ); i++ ) { + //pnd_log ( PND_LOG_DEFAULT, "Norun %u: %s\n", i, argv [ i ] ); + + // add spacing between args + if ( i > 0 ) { + strncat ( apps_exec_runline, " ", 1000 ); + } + + // quoting + if ( quotenext ) { + strncat ( apps_exec_runline, "\"", 1000 ); + } + + // arg + strncat ( apps_exec_runline, argv [ i ], 1000 ); + + // unquoting + if ( quotenext ) { + strncat ( apps_exec_runline, "\"", 1000 ); + } + + // clear quoting + if ( quotenext ) { + quotenext = 0; + } else { + // deprecated; need to handle spaces in some additional args + // if ( strcmp ( argv [ i ], "-a" ) == 0 ) { + // if this is for -a, we need to wrap with quotes + // ivanovic: + // to allow spaces in filenames we have to add quotes around most terms! + // terms with quotes: + // -a additional arguments + // -p fullpath to pnd + // -e name of execuatable inside the pnd + // -s startdir + // -b name for the appdir + + if ( ( strcmp ( argv [ i ], "-a" ) == 0 ) || + ( strcmp ( argv [ i ], "-p" ) == 0 ) || + ( strcmp ( argv [ i ], "-e" ) == 0 ) || + ( strcmp ( argv [ i ], "-s" ) == 0 ) || + ( strcmp ( argv [ i ], "-b" ) == 0 ) ) + { + quotenext = 1; + } + + } + + } // for + return ( 1 ); + } + // debug #if 0 int i; @@ -86,7 +181,7 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, } else { // child, do it execv ( pndrun, argv ); - } + } // by definition, either error occurred or we are the original application. @@ -94,11 +189,104 @@ unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, // care if it crashed, was killed, was suspended, whatever.) if ( options & PND_EXEC_OPTION_BLOCK ) { int status = 0; - //waitpid ( f, &status. 0 /* no options */ ); - wait ( &status ); + waitpid ( f, &status, 0 /* no options */ ); + //wait ( &status ); } // printf ( "Exiting pnd_apps_exec\n" ); return ( 1 ); } + +unsigned char pnd_apps_exec ( char *pndrun, char *fullpath, char *unique_id, + char *rel_exec, char *rel_startdir, + char *args, + unsigned int clockspeed, unsigned int options ) +{ + pnd_disco_t d; + bzero ( &d, sizeof(pnd_disco_t) ); + + char cpuspeed [ 10 ]; + sprintf ( cpuspeed, "%u", clockspeed ); + + char hackpath [ PATH_MAX ]; + strncpy ( hackpath, fullpath, PATH_MAX ); + char *c = strrchr ( hackpath, '/' ); + if ( c ) { + *c = '\0'; + d.object_path = hackpath; + d.object_filename = c + 1; + } else { + d.object_path = fullpath; + } + + d.unique_id = unique_id; + d.exec = rel_exec; + d.startdir = rel_startdir; + d.execargs = args; + if ( clockspeed ) { + d.clockspeed = cpuspeed; + } else { + d.clockspeed = NULL; + } + + return ( pnd_apps_exec_disco ( pndrun, &d, options, NULL ) ); +} + +void pnd_get_ro_mountpoint ( char *fullpath, 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; +} + +unsigned char pnd_get_appdata_path ( char *fullpath, char *unique_id, char *r_path, unsigned int path_len ) { + // you know, determining the 'mount point' used is sort of a pain in the rear + // use df , skip header line, grab first token. Cheap and should work. + // (Rather than just assume first two path chunks in path, say, which would be pretty darned + // accurate, but whose to say they're not using NFS or crazy mountpoints?) + FILE *df; + char cmdbuf [ 1024 ]; + + snprintf ( cmdbuf, 1023, "/bin/df %s", fullpath ); + + df = popen ( cmdbuf, "r" ); + + if ( ! df ) { + return ( 0 ); // tunefs: you can tune a filesystem but you can't tune a fish + } + + // fetch and discard header + if ( ! fgets ( cmdbuf, 1023, df ) ) { + pclose ( df ); + return ( 0 ); + } + + // grab df result line + if ( ! fgets ( cmdbuf, 1023, df ) ) { + pclose ( df ); + return ( 0 ); + } + + pclose ( df ); + + // parse + char *ws = strchr ( cmdbuf, ' ' ); + + if ( ! ws ) { + return ( 0 ); + } + + *ws = '\0'; + + if ( r_path && path_len ) { + snprintf ( r_path, path_len, "%s/pandora/appdata/%s/", cmdbuf, unique_id ); + } + + return ( 1 ); +} +