+
+// This very recently was inline code; just slight refactor to functionize it so that it can be
+// reused in a couple of places. Simple code with simple design quickly became too large for
+// its simple design; should revisit a lot of these little things..
+void process_discoveries ( pnd_box_handle applist, char *emitdesktoppath, char *emiticonpath ) {
+ pnd_disco_t *d = pnd_box_get_head ( applist );
+
+ while ( d ) {
+
+ pnd_log ( pndn_rem, "Found app: %s\n", pnd_box_get_key ( d ) );
+
+ // check if icon already exists (from a previous extraction say); if so, we needn't
+ // do it again
+ char existingpath [ FILENAME_MAX ];
+ sprintf ( existingpath, "%s/%s.png", emiticonpath, d -> unique_id );
+
+ struct stat dirs;
+ if ( stat ( existingpath, &dirs ) == 0 ) {
+ // icon seems to exist, so just crib the location into the .desktop
+
+ pnd_log ( pndn_rem, " Found icon already existed, so reusing it! %s\n", existingpath );
+
+ if ( d -> icon ) {
+ free ( d -> icon );
+ }
+ d -> icon = strdup ( existingpath );
+
+ } else {
+ // icon seems unreadable or does not exist; lets try to create it..
+
+ pnd_log ( pndn_debug, " Icon not already present, so trying to write it! %s\n", existingpath );
+
+ // attempt to create icon files; if successful, alter the disco struct to contain new
+ // path, otherwise leave it alone (since it could be a generic icon reference..)
+ if ( pnd_emit_icon ( emiticonpath, d ) ) {
+ // success; fix up icon path to new one..
+ if ( d -> icon ) {
+ free ( d -> icon );
+ }
+ d -> icon = strdup ( existingpath );
+ } else {
+ pnd_log ( pndn_debug, " WARN: Couldn't write out icon %s\n", existingpath );
+ }
+
+ } // icon already exists?
+
+ // create the .desktop file
+ if ( pnd_emit_dotdesktop ( emitdesktoppath, pndrun, d ) ) {
+ // add a watch onto the newly created .desktop?
+#if 0
+ char buffer [ FILENAME_MAX ];
+ sprintf ( buffer, "%s/%s", emitdesktoppath, d -> unique_id );
+ pnd_notify_watch_path ( nh, buffer, PND_NOTIFY_RECURSE );
+#endif
+ } else {
+ pnd_log ( pndn_rem, "ERROR: Error creating .desktop file for app: %s\n", pnd_box_get_key ( d ) );
+ }
+
+ // next!
+ d = pnd_box_get_next ( d );
+
+ } // while applist
+
+ return;
+}
+
+// returns true if any applications were found
+unsigned char perform_discoveries ( char *appspath, char *overridespath, // args to do discovery
+ char *emitdesktoppath, char *emiticonpath ) // args to do emitting
+{
+ pnd_box_handle applist;
+
+ // attempt to auto-discover applications in the given path
+ applist = pnd_disco_search ( appspath, overridespath );
+
+ if ( ! applist ) {
+ return ( 0 );
+ }
+
+ process_discoveries ( applist, emitdesktoppath, emiticonpath );
+
+ // run a clean up, to remove any dotdesktop files that we didn't
+ // just now create (that seem to have been created by pndnotifyd
+ // previously.) This allows SD eject (or .pnd remove) to remove
+ // an app from the launcher
+ // NOTE: Could opendir and iterate across all .desktop files,
+ // removing any that have Source= something else, and that the
+ // app name is not in the list found in applist box above. But
+ // a cheesy simple way right now is to just remove .desktop files
+ // that have a last mod time prior to the time we stored above.
+ {
+ DIR *dir;
+
+ if ( ( dir = opendir ( emitdesktoppath ) ) ) {
+ struct dirent *dirent;
+ struct stat dirs;
+ char buffer [ FILENAME_MAX ];
+
+ while ( ( dirent = readdir ( dir ) ) ) {
+
+ // file is a .desktop?
+ if ( strstr ( dirent -> d_name, ".desktop" ) == NULL ) {
+ continue;
+ }
+
+ // figure out full path
+ sprintf ( buffer, "%s/%s", emitdesktoppath, dirent -> d_name );
+
+ // file was previously created by libpnd; check Source= line
+ // logic: default to 'yes' (in case we can't open the file for some reason)
+ // if we can open the file, default to no and look for the source flag we added; if
+ // that matches then we know its libpnd created, otherwise assume not.
+ unsigned char source_libpnd = 1;
+ {
+ char line [ 256 ];
+ FILE *grep = fopen ( buffer, "r" );
+ if ( grep ) {
+ source_libpnd = 0;
+ while ( fgets ( line, 255, grep ) ) {
+ if ( strcasestr ( line, PND_DOTDESKTOP_SOURCE ) ) {
+ source_libpnd = 2;
+ }
+ } // while
+ fclose ( grep );
+ }
+ }
+ if ( source_libpnd ) {
+#if 0
+ pnd_log ( pndn_rem,
+ "File '%s' appears to have been created by libpnd so candidate for delete: %u\n", buffer, source_libpnd );
+#endif
+ } else {
+#if 0
+ pnd_log ( pndn_rem, "File '%s' appears NOT to have been created by libpnd, so leave it alone\n", buffer );
+#endif
+ continue; // skip deleting it
+ }
+
+ // file is 'new'?
+ if ( stat ( buffer, &dirs ) == 0 ) {
+ if ( dirs.st_mtime >= createtime ) {
+#if 0
+ pnd_log ( pndn_rem, "File '%s' seems 'new', so leave it alone.\n", buffer );
+#endif
+ continue; // skip deleting it
+ }
+ }
+
+ // by this point, the .desktop file must be 'old' and created by pndnotifyd
+ // previously, so can remove it
+ pnd_log ( pndn_rem, "File '%s' seems nolonger relevent; removing it.\n", dirent -> d_name );
+ unlink ( buffer );
+
+ } // while getting filenames from dir
+
+ closedir ( dir );
+ }
+
+ } // purge old .desktop files
+
+ //WARN: MEMORY LEAK HERE
+ pnd_log ( pndn_debug, "pndnotifyd - memory leak here - perform_discoveries()\n" );
+ pnd_box_delete ( applist ); // does not free the disco_t contents!
+
+ return ( 1 );
+}