From fca7283580cb7bf5ce79310757239e630ab7624a Mon Sep 17 00:00:00 2001 From: skeezix Date: Mon, 23 Feb 2009 21:25:52 -0500 Subject: [PATCH] Added basic icon support discotest has it, not yet pndnotifyd discotest can extract icon from pnd to /tmp Almost there! --- Makefile | 1 + include/pnd_discovery.h | 15 +++- lib/pnd_discovery.c | 112 +++++++++++++++++++++++++++-- test/discotest.c | 120 +++++++++++++++++++++----------- testdata/pndsample/x86_echo.pnd | Bin 387551 -> 387551 bytes testdata/pndsample/x86_ls.pnd | Bin 489775 -> 489775 bytes 6 files changed, 201 insertions(+), 47 deletions(-) diff --git a/Makefile b/Makefile index f1b169e..e883136 100644 --- a/Makefile +++ b/Makefile @@ -65,6 +65,7 @@ deploy: cp bin/pndnotifyd deployment/usr/bin cp testdata/scripts/* deployment/usr/pandora/scripts # copy in freebee .pnd apps to /usr/pandora/apps + # add pndnotify to etc/rc/startup-whatever # test tool targets # diff --git a/include/pnd_discovery.h b/include/pnd_discovery.h index 59029dd..b92215e 100644 --- a/include/pnd_discovery.h +++ b/include/pnd_discovery.h @@ -31,12 +31,21 @@ pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath ); * confusion.. it is not displayed. So no big deal. */ +typedef enum { + pnd_object_type_unknown = 0, + pnd_object_type_directory, + pnd_object_type_pnd, + pnd_object_type_max +} pnd_object_type_t; + // another struct? Have always intended discovery_t to have minimal members.. just enough to lead to an // application (PXML, xecutable, name); if the apps want more details, they can use the pnd_pxml code to // fetch the full PXML and get all the details. But I think we got out of control here :) typedef struct { // base - char *path_to_object; // full path to the PXML.xml or awesomeapp.pnd file + unsigned char object_type; // see enum above + char *path_to_object; // full path to the PXML.xml or awesomeapp.pnd file + unsigned int pnd_icon_pos; // offset to the byte after end of PXML in a pnd file (should be icon if present) // strdup'd from PXML char *title_en; char *unique_id; @@ -53,6 +62,10 @@ void pnd_disco_destroy ( pnd_disco_t *p ); // a function name that simply could // 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, char *pndrun, pnd_disco_t *p ); +// emit_icon() will attempt to copy the icon from a PXML directory, or from a pnd file if appended, +// to the given directory; returns 1 on sucess, otherwise is a fail. +unsigned char pnd_emit_icon ( char *targetpath, pnd_disco_t *p ); + // TODO: A way to release the disco-lists and reclaim RAM :) #ifdef __cplusplus diff --git a/lib/pnd_discovery.c b/lib/pnd_discovery.c index 84de948..3ddecb4 100644 --- a/lib/pnd_discovery.c +++ b/lib/pnd_discovery.c @@ -52,8 +52,9 @@ void pnd_disco_destroy ( pnd_disco_t *p ) { static int pnd_disco_callback ( const char *fpath, const struct stat *sb, int typeflag, struct FTW *ftwbuf ) { - unsigned char valid = 0; // 1 for plaintext PXML, 2 for PND... + unsigned char valid = pnd_object_type_unknown; pnd_pxml_handle pxmlh = 0; + unsigned int pxml_close_pos = 0; //printf ( "disco root callback encountered '%s'\n", fpath ); @@ -66,9 +67,9 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, // PND/PNZ file and others may be valid as well .. but lets leave that for now // printf ( "%s %s\n", fpath + ftwbuf -> base, PND_PACKAGE_FILEEXT ); if ( strcasecmp ( fpath + ftwbuf -> base, PXML_FILENAME ) == 0 ) { - valid = 1; + valid = pnd_object_type_directory; } else if ( strcasestr ( fpath + ftwbuf -> base, PND_PACKAGE_FILEEXT "\0" ) ) { - valid = 2; + valid = pnd_object_type_pnd; } // if not a file of interest, just keep looking until we run out @@ -78,14 +79,14 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, } // potentially a valid application - if ( valid == 1 ) { + if ( valid == pnd_object_type_directory ) { // Plaintext PXML file //printf ( "PXML: disco callback encountered '%s'\n", fpath ); // pick up the PXML if we can pxmlh = pnd_pxml_fetch ( (char*) fpath ); - } else if ( valid == 2 ) { + } else if ( valid == pnd_object_type_pnd ) { // PND ... ?? FILE *f; char pxmlbuf [ 32 * 1024 ]; // TBD: assuming 32k pxml accrual buffer is a little lame @@ -114,9 +115,27 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, //printf ( "buffer is %s\n", pxmlbuf ); //fflush ( stdout ); +#if 1 // icon + // for convenience, lets skip along past trailing newlines/CR's in hopes of finding icon data? + { + unsigned int pos = ftell ( f ); + char pngbuffer [ 16 ]; // \211 P N G \r \n \032 \n + pngbuffer [ 0 ] = 137; pngbuffer [ 1 ] = 80; pngbuffer [ 2 ] = 78; pngbuffer [ 3 ] = 71; + pngbuffer [ 4 ] = 13; pngbuffer [ 5 ] = 10; pngbuffer [ 6 ] = 26; pngbuffer [ 7 ] = 10; + if ( fread ( pngbuffer + 8, 8, 1, f ) == 1 ) { + if ( memcmp ( pngbuffer, pngbuffer + 8, 8 ) == 0 ) { + pxml_close_pos = pos; + } + } + } // icon +#endif + // by now, we have .. , try to parse.. pxmlh = pnd_pxml_fetch_buffer ( (char*) fpath, pxmlbuf ); + // done with file + fclose ( f ); + } // pxmlh is useful? @@ -134,11 +153,16 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb, // 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 } + // png icon path + p -> pnd_icon_pos = pxml_close_pos; + + // type + p -> object_type = valid; + // PXML fields if ( pnd_pxml_get_app_name_en ( pxmlh ) ) { p -> title_en = strdup ( pnd_pxml_get_app_name_en ( pxmlh ) ); @@ -278,3 +302,79 @@ unsigned char pnd_emit_dotdesktop ( char *targetpath, char *pndrun, pnd_disco_t return ( 1 ); } + +unsigned char pnd_emit_icon ( char *targetpath, pnd_disco_t *p ) { + char buffer [ FILENAME_MAX ]; + char bits [ 8 * 1024 ]; + unsigned int bitlen; + + // filename + sprintf ( buffer, "%s/%u.png", targetpath, p -> unique_id ); + + // first.. are we looking through a pnd file or a dir? + if ( p -> object_type == pnd_object_type_directory ) { + // if we can find icon, copy it in from directory to destination + + } else if ( p -> object_type == pnd_object_type_pnd ) { + // if we can get it from pnd file, copy it into destination + + if ( ! p -> pnd_icon_pos ) { + return ( 0 ); // discover code didn't find it, so FAIL + } + + FILE *pnd, *target; + unsigned int len; + + pnd = fopen ( p -> path_to_object, "r" ); + + if ( ! pnd ) { + return ( 0 ); + } + + target = fopen ( buffer, "wb" ); + + if ( ! target ) { + fclose ( pnd ); + return ( 0 ); + } + + fseek ( pnd, 0, SEEK_END ); + len = ftell ( pnd ); + //fseek ( pnd, 0, SEEK_SET ); + + fseek ( pnd, p -> pnd_icon_pos, SEEK_SET ); + + len -= p -> pnd_icon_pos; + + while ( len ) { + + if ( len > (8*1024) ) { + bitlen = (8*1024); + } else { + bitlen = len; + } + + if ( fread ( bits, bitlen, 1, pnd ) != 1 ) { + fclose ( pnd ); + fclose ( target ); + unlink ( buffer ); + return ( 0 ); + } + + if ( fwrite ( bits, bitlen, 1, target ) != 1 ) { + fclose ( pnd ); + fclose ( target ); + unlink ( buffer ); + return ( 0 ); + } + + len -= bitlen; + } // while + + fclose ( pnd ); + fclose ( target ); + + } + + return ( 1 ); +} diff --git a/test/discotest.c b/test/discotest.c index a299e7d..b374f36 100644 --- a/test/discotest.c +++ b/test/discotest.c @@ -9,10 +9,35 @@ #include "pnd_discovery.h" #include "pnd_locate.h" -int main ( void) { +int main ( int argc, char *argv[] ) { char *configpath; char *appspath; char *overridespath; + unsigned char i; + unsigned char do_exec = 0; + unsigned char do_icon = 0; + unsigned char do_dotdesktop = 0; + + for ( i = 1; i < argc; i++ ) { + + if ( argv [ i ][ 0 ] == '-' && argv [ i ][ 1 ] == 'e' ) { + printf ( "Will attempt a random exec.\n" ); + do_exec = 1; + } else if ( argv [ i ][ 0 ] == '-' && argv [ i ][ 1 ] == 'i' ) { + printf ( "Will attempt to extract icons.\n" ); + do_icon = 1; + } else if ( argv [ i ][ 0 ] == '-' && argv [ i ][ 1 ] == 'd' ) { + printf ( "Will attempt to extract dotdesktop.\n" ); + do_dotdesktop = 1; + } else { + printf ( "%s [-e] [-i] [-d]\n", argv [ 0 ] ); + printf ( "-e\tOptional. Attempt to exec a random app.\n" ); + printf ( "-i\tOptional. Attempt to dump icon files from the end of pnd's to /tmp.\n" ); + printf ( "-d\tOptional. Attempt to dump dotdesktop files from the end of pnd's to /tmp.\n" ); + exit ( 0 ); + } + + } /* attempt to sort out the config file madness */ @@ -47,6 +72,36 @@ int main ( void) { printf ( "Apps searchpath is '%s'\n", appspath ); printf ( "Apps overrides searchpath is '%s'\n", overridespath ); + /* find pnd runscript + */ + 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 ); + /* attempt to discover apps in the path */ pnd_box_handle applist; @@ -62,7 +117,7 @@ int main ( void) { // display the app 'as is' - printf ( "App: %s\n", pnd_box_get_key ( d ) ); + printf ( "App: %s (type %u)\n", pnd_box_get_key ( d ), d -> object_type ); printf ( " Base path: %s\n", d -> path_to_object ); @@ -72,6 +127,9 @@ int main ( void) { if ( d -> icon ) { printf ( " Icon: %s\n", d -> icon ); } + if ( d -> pnd_icon_pos ) { + printf ( " Icon in pnd might be at: %u\n", d -> pnd_icon_pos ); + } if ( d -> unique_id ) { printf ( " Unique ID: %s\n", d -> unique_id ); } @@ -88,7 +146,13 @@ int main ( void) { printf ( " Clockspeed: %s\n", d -> clockspeed ); } - //pnd_emit_dotdesktop ( "/tmp", d ); + if ( do_dotdesktop ) { + pnd_emit_dotdesktop ( "/tmp", pndrun, d ); + } + + if ( do_icon ) { + pnd_emit_icon ( "/tmp", d ); + } // next! d = pnd_box_get_next ( d ); @@ -100,49 +164,25 @@ int main ( void) { } // 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; - } + if ( do_exec ) { - } 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 ( ! 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 ) { - pnd_apps_exec ( pndrun, d -> path_to_object, d -> unique_id, d -> exec, d -> startdir, atoi ( d -> clockspeed ) ); + 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 ) ); + } } + } - } + } // do_exec? // exeunt with alarums free ( configpath ); diff --git a/testdata/pndsample/x86_echo.pnd b/testdata/pndsample/x86_echo.pnd index a5ff2dbd42e6322e016fb831551ec0f31ef95b25..00d9ead41529e50ef09ef8018787edc14e7f46e1 100644 GIT binary patch delta 98 zcmcbAS^WNG@eO9pVwQ%M28IR(Z;T8KEDel|j19p8lYN?HS;4H$dCmH!%)-KqlNao; j76j67a+$;tRP&o1?QeE40x=U1GXpWp_BT6NKN|o59_%91 delta 98 zcmcbAS^WNG@eO9pViv}hhUNwaZ;T8KEDel|j19p8lYN?HS;4H$dCmH!%tGpdlNao; j76j67a+$;tRP&o1?QeE40x=U1GXpWp_BT6NKN|o5Io2b0 diff --git a/testdata/pndsample/x86_ls.pnd b/testdata/pndsample/x86_ls.pnd index dfea9e6b66559ad39cc3845a0a72561370f35f41..9e36a1df64c4287129267693ff57bbec46ecfa9d 100644 GIT binary patch delta 102 zcmZ4gNp}4w*$rmRVwQ%M28IR(Z;T8KEDel|j19p8lYN?HS;4H$dCmH!%)-KqlNao; l76j67a+$;tRP&o1?QeE40x=U1GXpUT5VLN7vxCj~005=iB+dW; delta 102 zcmZ4gNp}4w*$rmRViv}hhUNwaZ;T8KEDel|j19p8lYN?HS;4H$dCmH!%tGpdlNao; l76j67a+$;tRP&o1?QeE40x=U1GXpUT5VLN7vxCj~006^PC2{}& -- 2.39.2