pndnotifyd: fix some crashes
[pandora-libraries.git] / lib / pnd_discovery.c
index 7d89475..1e465ff 100644 (file)
@@ -30,6 +30,7 @@ static char *disco_overrides = NULL;
 void pnd_disco_destroy ( pnd_disco_t *p ) {
   if ( p -> package_id ) {     free ( p -> package_id);   }
   if ( p -> title_en ) {       free ( p -> title_en );    }
+  if ( p -> desc_en ) {        free ( p -> desc_en );    }
   if ( p -> unique_id ) {      free ( p -> unique_id );   }
   if ( p -> appdata_dirname ) { free ( p -> appdata_dirname );   }
   if ( p -> icon )     {       free ( p -> icon );        }
@@ -44,10 +45,25 @@ void pnd_disco_destroy ( pnd_disco_t *p ) {
   if ( p -> alt_category ) {   free ( p -> alt_category );   }
   if ( p -> alt_category1 ) {  free ( p -> alt_category1 );  }
   if ( p -> alt_category2 ) {  free ( p -> alt_category2 );  }
+  if ( p -> object_filename ) { free ( p -> object_filename ); }
+  if ( p -> object_path )     { free ( p -> object_path ); }
   if ( p -> mkdir_sp )      {  free ( p -> mkdir_sp );       }
   if ( p -> info_name )     {  free ( p -> info_name );       }
   if ( p -> info_type )     {  free ( p -> info_type );       }
   if ( p -> info_filename ) {  free ( p -> info_filename );       }
+  if ( p -> preview_pic1 )  {  free ( p -> preview_pic1 );     }
+  if ( p -> preview_pic2 )  {  free ( p -> preview_pic2 );     }
+  if ( p -> version_major ) {  free ( p -> version_major );    }
+  if ( p -> version_minor ) {  free ( p -> version_minor );    }
+  if ( p -> version_release ) {free ( p -> version_release );  }
+  if ( p -> version_build ) {  free ( p -> version_build );    }
+  if ( p -> package_version_major ) { free ( p -> package_version_major ); }
+  if ( p -> package_version_minor ) { free ( p -> package_version_minor ); }
+  if ( p -> package_version_release ) { free ( p -> package_version_release ); }
+  if ( p -> package_version_build ) { free ( p -> package_version_build ); }
+  if ( p -> associationitem1_name ) { free ( p -> associationitem1_name ); }
+  if ( p -> associationitem1_filetype ) { free ( p -> associationitem1_filetype ); }
+  if ( p -> exec_dashdash_args ) { free ( p -> exec_dashdash_args ); }
 
   return;
 }
@@ -59,7 +75,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
   pnd_pxml_handle pxmlh = 0;
   pnd_pxml_handle *pxmlapps = NULL;
   pnd_pxml_handle *pxmlappiter;
-  unsigned int pxml_close_pos = 0;
+  off_t pxml_close_pos = 0;
   unsigned char logit = pnd_log_do_buried_logging();
 
   if ( logit ) {
@@ -138,7 +154,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       pngbuffer [ 4 ] = 13;       pngbuffer [ 5 ] = 10;       pngbuffer [ 6 ] = 26;      pngbuffer [ 7 ] = 10;
 
       unsigned char padtests = 20;
-      unsigned int padstart = ftell ( f );
+      off_t padstart = ftello ( f );
 
       // seek back 10 (should be back into the /PXML> part) to catch any appending-icon-no-line-endings funny business
       fseek ( f, -10, SEEK_CUR );
@@ -147,7 +163,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
 
        if ( fread ( pngbuffer + 8, 8, 1, f ) == 1 ) {
          if ( memcmp ( pngbuffer, pngbuffer + 8, 8 ) == 0 ) {
-           pxml_close_pos = ftell ( f ) - 8;
+           pxml_close_pos = ftello ( f ) - 8;
            break;
          } // if
          fseek ( f, -7, SEEK_CUR ); // seek back 7 (so we're 1 further than we started, since PNG header is 8b)
@@ -158,7 +174,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
 
       if ( ! padtests ) {
        // no icon found, so back to where we started looking
-       fseek ( f, padstart, SEEK_SET );
+       fseeko ( f, padstart, SEEK_SET );
       }
 
     } // icon
@@ -218,7 +234,12 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       p -> subapp_number = ((pnd_pxml_t*) pxmlh) -> subapp_number;
 
       // png icon path
+      p -> pnd_icon_pos64 = pxml_close_pos;
       p -> pnd_icon_pos = pxml_close_pos;
+      if ( (off_t) p -> pnd_icon_pos != pxml_close_pos ) {
+        // pnd_icon_pos is an int and the offset doesn't fit, bad luck...
+        p -> pnd_icon_pos = 0;
+      }
 
       // type
       p -> object_type = valid;
@@ -227,11 +248,13 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       if ( pnd_pxml_get_package_id ( pxmlh ) ) {
        p -> package_id = strdup ( pnd_pxml_get_package_id ( pxmlh ) );
       }
-      if ( pnd_pxml_get_app_name_en ( pxmlh ) ) {
-       p -> title_en = strdup ( pnd_pxml_get_app_name_en ( pxmlh ) );
+      char *name_en = pnd_pxml_get_app_name_en ( pxmlh );
+      if (name_en) {
+       p -> title_en = name_en; /* already strdupped */
       }
-      if ( pnd_pxml_get_description_en ( pxmlh ) ) {
-       p -> desc_en = strdup ( pnd_pxml_get_description_en ( pxmlh ) );
+      char *desc_en = pnd_pxml_get_description_en ( pxmlh );
+      if ( desc_en ) {
+       p -> desc_en = desc_en; /* already strdupped */
       }
       if ( pnd_pxml_get_icon ( pxmlh ) ) {
        p -> icon = strdup ( pnd_pxml_get_icon ( pxmlh ) );
@@ -252,10 +275,10 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
        p -> appdata_dirname = strdup ( pnd_pxml_get_appdata_dirname ( pxmlh ) );
       }
       if ( pnd_pxml_get_clockspeed ( pxmlh ) ) {
-       p -> clockspeed = strdup ( 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 ) ); 
+       p -> startdir = strdup ( pnd_pxml_get_startdir ( pxmlh ) );
       }
       // category kruft
       if ( pnd_pxml_get_main_category ( pxmlh ) ) {
@@ -297,6 +320,41 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
       if ( pnd_pxml_get_info_type ( pxmlh ) ) {
        p -> info_type = strdup ( pnd_pxml_get_info_type ( pxmlh ) );
       }
+      if ( pnd_pxml_get_version_major ( pxmlh ) ) {
+   p -> version_major = strdup ( pnd_pxml_get_version_major ( pxmlh ) );
+      }
+      if ( pnd_pxml_get_version_minor ( pxmlh ) ) {
+   p -> version_minor = strdup ( pnd_pxml_get_version_minor ( pxmlh ) );
+      }
+      if ( pnd_pxml_get_version_release ( pxmlh ) ) {
+   p -> version_release = strdup ( pnd_pxml_get_version_release ( pxmlh ) );
+      }
+      if ( pnd_pxml_get_version_build ( pxmlh ) ) {
+   p -> version_build = strdup ( pnd_pxml_get_version_build ( pxmlh ) );
+      }
+      if ( pnd_pxml_get_package_version_major ( pxmlh ) ) {
+       p -> package_version_major = strdup ( pnd_pxml_get_package_version_major ( pxmlh ) );
+      }
+      if ( pnd_pxml_get_package_version_minor ( pxmlh ) ) {
+   p -> package_version_minor = strdup ( pnd_pxml_get_package_version_minor ( pxmlh ) );
+      }
+      if ( pnd_pxml_get_package_version_release ( pxmlh ) ) {
+   p -> package_version_release = strdup ( pnd_pxml_get_package_version_release ( pxmlh ) );
+      }
+      if ( pnd_pxml_get_package_version_build ( pxmlh ) ) {
+   p -> package_version_build = strdup ( pnd_pxml_get_package_version_build ( pxmlh ) );
+      }
+#if 1
+      // file associations
+      if ( pnd_pxml_get_associationitem1_name ( pxmlh ) ) {
+       p -> associationitem1_name = strdup ( pnd_pxml_get_associationitem1_name ( pxmlh ) );
+       p -> associationitem1_filetype = strdup ( pnd_pxml_get_associationitem1_filetype ( pxmlh ) );
+       //pnd_log ( PND_LOG_DEFAULT, "  Disco: Found file association request in PXML (%s)\n", p -> title_en );
+      }
+#endif
+      if ( pnd_pxml_get_execdashdashargs ( pxmlh ) ) {
+       p -> exec_dashdash_args = strdup ( pnd_pxml_get_execdashdashargs ( pxmlh ) );
+      }
 
       // look for any PXML overrides, if requested
       if ( disco_overrides ) {
@@ -367,6 +425,7 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
          if ( p -> main_category ) {
            free ( p -> main_category );
          }
+         // the override file cannot suppress the main category
          p -> main_category = strdup ( v );
        }
        snprintf ( key, 100, "Application-%u.maincategorysub1", p -> subapp_number );
@@ -379,6 +438,48 @@ static int pnd_disco_callback ( const char *fpath, const struct stat *sb,
            p -> main_category1 = strdup ( v );
          }
        }
+       snprintf ( key, 100, "Application-%u.maincategorysub2", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> main_category2 ) {
+           free ( p -> main_category2 );
+           p -> main_category2 = NULL;
+         }
+         if ( strcasecmp ( v, "NoSubcategory" ) != 0 ) {
+           p -> main_category2 = strdup ( v );
+         }
+       }
+       // alt categories
+       snprintf ( key, 100, "Application-%u.altcategory", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> alt_category ) {
+           free ( p -> alt_category );
+           p -> alt_category = NULL;
+         }
+         // but it makes sense to allow full suppression of the alternate category
+         if ( strcasecmp ( v, "NoCategory" ) != 0 ) {
+           p -> alt_category = strdup ( v );
+          }
+       }
+       snprintf ( key, 100, "Application-%u.altcategorysub1", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> alt_category1 ) {
+           free ( p -> alt_category1 );
+           p -> alt_category1 = NULL;
+         }
+         if ( strcasecmp ( v, "NoSubcategory" ) != 0 ) {
+           p -> alt_category1 = strdup ( v );
+         }
+       }
+       snprintf ( key, 100, "Application-%u.altcategorysub2", p -> subapp_number );
+       if ( ( v = pnd_conf_get_as_char ( ovrh, key ) ) ) {
+         if ( p -> alt_category2 ) {
+           free ( p -> alt_category2 );
+           p -> alt_category2 = NULL;
+         }
+         if ( strcasecmp ( v, "NoSubcategory" ) != 0 ) {
+           p -> alt_category2 = strdup ( v );
+         }
+       }
 
       } // got ovr conf loaded?