X-Git-Url: http://git.openpandora.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fpnd_discovery.c;h=b29f7333754d47a651b4765b7818870e36461b42;hb=a2e1c684f4754cce44d52f1572d8aaade9ff7434;hp=caf3ccb2c2513d811e401904bcdd550165fc5ba3;hpb=527d94fc765c2a180006c5f38450751f0f5c8058;p=pandora-libraries.git diff --git a/lib/pnd_discovery.c b/lib/pnd_discovery.c index caf3ccb..b29f733 100644 --- a/lib/pnd_discovery.c +++ b/lib/pnd_discovery.c @@ -1,6 +1,7 @@ #include /* for FILE etc */ #include /* for malloc */ +#include /* for unlink */ #define __USE_GNU /* for strcasestr */ #include /* for making ftw.h happy */ @@ -22,29 +23,19 @@ static char *disco_overrides = NULL; void pnd_disco_destroy ( pnd_disco_t *p ) { - if ( p -> title_en ) { - free ( p -> title_en ); - } - - if ( p -> icon ) { - free ( p -> icon ); - } - - if ( p -> exec ) { - free ( p -> exec ); - } - - if ( p -> unique_id ) { - free ( p -> unique_id ); - } - - if ( p -> main_category ) { - free ( p -> main_category ); - } - - if ( p -> clockspeed ) { - free ( p -> clockspeed ); - } + if ( p -> title_en ) { free ( p -> title_en ); } + if ( p -> unique_id ) { free ( p -> unique_id ); } + if ( p -> icon ) { free ( p -> icon ); } + if ( p -> exec ) { free ( p -> exec ); } + if ( p -> clockspeed ) { free ( p -> clockspeed ); } + if ( p -> startdir ) { free ( p -> startdir ); } + if ( p -> option_no_x11 ) { free ( p -> option_no_x11 ); } + if ( p -> main_category ) { free ( p -> main_category ); } + if ( p -> main_category1 ) { free ( p -> main_category1 ); } + if ( p -> main_category2 ) { free ( p -> main_category2 ); } + if ( p -> alt_category ) { free ( p -> alt_category ); } + if ( p -> alt_category1 ) { free ( p -> alt_category1 ); } + if ( p -> alt_category2 ) { free ( p -> alt_category2 ); } return; } @@ -52,8 +43,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 +58,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 +70,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 +106,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? @@ -128,34 +138,81 @@ 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; + char *z; p = pnd_box_allocinsert ( disco_box, (char*) fpath, sizeof(pnd_disco_t) ); - // base path - p -> path_to_object = strdup ( fpath ); + // base paths + p -> object_path = strdup ( fpath ); + + if ( ( fixpxml = strcasestr ( p -> object_path, PXML_FILENAME ) ) ) { + *fixpxml = '\0'; // if this is not a .pnd, lop off the PXML.xml at the end + } else if ( ( fixpxml = strrchr ( p -> object_path, '/' ) ) ) { + *(fixpxml+1) = '\0'; // for pnd, lop off to last / + } + + if ( ( fixpxml = strrchr ( fpath, '/' ) ) ) { + p -> object_filename = strdup ( fixpxml + 1 ); + } + + // 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 ) ); } + if ( pnd_pxml_get_description_en ( pxmlh ) ) { + p -> desc_en = strdup ( pnd_pxml_get_description_en ( pxmlh ) ); + } if ( pnd_pxml_get_icon ( pxmlh ) ) { p -> icon = strdup ( pnd_pxml_get_icon ( pxmlh ) ); } 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 ) ); } - if ( pnd_pxml_get_main_category ( pxmlh ) ) { - p -> main_category = strdup ( pnd_pxml_get_main_category ( pxmlh ) ); - } if ( pnd_pxml_get_clockspeed ( pxmlh ) ) { p -> clockspeed = strdup ( pnd_pxml_get_clockspeed ( pxmlh ) ); } if ( pnd_pxml_get_startdir ( pxmlh ) ) { p -> startdir = strdup ( pnd_pxml_get_startdir ( pxmlh ) ); } + // category kruft + if ( pnd_pxml_get_main_category ( pxmlh ) ) { + p -> main_category = strdup ( pnd_pxml_get_main_category ( pxmlh ) ); + } + if ( pnd_pxml_get_subcategory1 ( pxmlh ) ) { + p -> main_category1 = strdup ( pnd_pxml_get_subcategory1 ( pxmlh ) ); + } + if ( pnd_pxml_get_subcategory2 ( pxmlh ) ) { + p -> main_category2 = strdup ( pnd_pxml_get_subcategory2 ( pxmlh ) ); + } + if ( pnd_pxml_get_altcategory ( pxmlh ) ) { + p -> alt_category = strdup ( pnd_pxml_get_altcategory ( pxmlh ) ); + } + if ( pnd_pxml_get_altsubcategory1 ( pxmlh ) ) { + p -> alt_category1 = strdup ( pnd_pxml_get_altsubcategory1 ( pxmlh ) ); + } + if ( pnd_pxml_get_altsubcategory2 ( pxmlh ) ) { + p -> alt_category2 = strdup ( pnd_pxml_get_altsubcategory2 ( pxmlh ) ); + } + // preview pics + if ( ( z = pnd_pxml_get_previewpic1 ( pxmlh ) ) ) { + p -> preview_pic1 = strdup ( z ); + } + if ( ( z = pnd_pxml_get_previewpic2 ( pxmlh ) ) ) { + p -> preview_pic2 = strdup ( z ); + } } else { //printf ( "Invalid PXML; skipping.\n" ); @@ -200,76 +257,3 @@ pnd_box_handle pnd_disco_search ( char *searchpath, char *overridespath ) { return ( disco_box ); } - -unsigned char pnd_emit_dotdesktop ( char *targetpath, pnd_disco_t *p ) { - char filename [ FILENAME_MAX ]; - char buffer [ 1024 ]; - FILE *f; - - // specification - // http://standards.freedesktop.org/desktop-entry-spec - - // validation - - if ( ! p -> unique_id ) { - return ( 0 ); - } - - if ( ! p -> exec ) { - return ( 0 ); - } - - // set up - - sprintf ( filename, "%s/%s.desktop", targetpath, p -> unique_id ); - - // emit - - //printf ( "EMIT DOTDESKTOP '%s'\n", filename ); - - f = fopen ( filename, "w" ); - - if ( ! f ) { - return ( 0 ); - } - - if ( p -> title_en ) { - snprintf ( buffer, 1020, "Name=%s\n", p -> title_en ); - fprintf ( f, "%s", buffer ); - } - - fprintf ( f, "Type=Application\n" ); - fprintf ( f, "Version=1.0\n" ); - - if ( p -> icon ) { - snprintf ( buffer, 1020, "Icon=%s\n", p -> icon ); - fprintf ( f, "%s", buffer ); - } - -#if 0 - if ( p -> description_en ) { - snprintf ( buffer, 1020, "Comment=%s\n", p -> description_en ); - fprintf ( f, "%s", buffer ); - } -#endif - -#if 0 - if ( p -> startdir ) { - snprintf ( buffer, 1020, "Path=%s\n", p -> startdir ); - fprintf ( f, "%s", buffer ); - } else { - fprintf ( f, "Path=%s\n", PND_DEFAULT_WORKDIR ); - } -#endif - - if ( p -> exec ) { - snprintf ( buffer, 1020, "Exec=%s\n", p -> exec ); - fprintf ( f, "%s", buffer ); - } - - fprintf ( f, "_Source=libpnd\n" ); // should we need to know 'who' created the file during trimming - - fclose ( f ); - - return ( 1 ); -}