summaryrefslogtreecommitdiffstats
path: root/source
diff options
context:
space:
mode:
authorDave Davenport <DaveDavenport@users.noreply.github.com>2016-06-05 19:01:38 +0200
committerDave Davenport <DaveDavenport@users.noreply.github.com>2016-06-05 19:01:38 +0200
commit3f31620a3ee8e6d04a71400b2abff8db66a0d4fb (patch)
treef5a56201e7f27f3ed3eac8fcf8892b98ea6e3850 /source
parent9149e35248716db522929795b3b905883eb5f86a (diff)
Wip/drun subdirs (#416)
* drun: Walk subdirectories too Signed-off-by: Quentin Glidic <sardemff7+git@sardemff7.net> * Remove goto, make it work for Filesystems that do not support reporting file type. * Fix using filename before creating it. * Run indenter over drun file. * Fix stupid typo
Diffstat (limited to 'source')
-rw-r--r--source/dialogs/drun.c106
1 files changed, 64 insertions, 42 deletions
diff --git a/source/dialogs/drun.c b/source/dialogs/drun.c
index a11f7137..8e004075 100644
--- a/source/dialogs/drun.c
+++ b/source/dialogs/drun.c
@@ -32,6 +32,7 @@
#include <limits.h>
#include <signal.h>
#include <sys/types.h>
+#include <sys/stat.h>
#include <dirent.h>
#include <strings.h>
#include <string.h>
@@ -197,27 +198,64 @@ static void read_desktop_file ( DRunModePrivateData *pd, char *path, const char
/**
* Internal spider used to get list of executables.
*/
-static void get_apps_dir ( DRunModePrivateData *pd, const char *bp )
+static void walk_dir ( DRunModePrivateData *pd, const char *dirname )
{
- DIR *dir = opendir ( bp );
+ DIR *dir;
- if ( dir != NULL ) {
- struct dirent *dent;
+ dir = opendir ( dirname );
+ if ( dir == NULL ) {
+ return;
+ }
- while ( ( dent = readdir ( dir ) ) != NULL ) {
- if ( dent->d_type != DT_REG && dent->d_type != DT_LNK && dent->d_type != DT_UNKNOWN ) {
- continue;
- }
- // Skip dot files.
- if ( dent->d_name[0] == '.' ) {
- continue;
+ struct dirent *file;
+ gchar *filename = NULL;
+ struct stat st;
+ while ( ( file = readdir ( dir ) ) != NULL ) {
+ if ( file->d_name[0] == '.' ) {
+ continue;
+ }
+
+ switch ( file->d_type )
+ {
+ case DT_LNK:
+ case DT_REG:
+ case DT_DIR:
+ case DT_UNKNOWN:
+ filename = g_build_filename ( dirname, file->d_name, NULL );
+ break;
+ default:
+ continue;
+ }
+
+ // On a link, or if FS does not support providing this information
+ // Fallback to stat method.
+ if ( file->d_type == DT_LNK || file->d_type == DT_UNKNOWN ) {
+ file->d_type = DT_UNKNOWN;
+ if ( stat ( filename, &st ) == 0 ) {
+ if ( S_ISDIR ( st.st_mode ) ) {
+ file->d_type = DT_DIR;
+ }
+ else if ( S_ISREG ( st.st_mode ) ) {
+ file->d_type = DT_REG;
+ }
}
- gchar *path = g_build_filename ( bp, dent->d_name, NULL );
- read_desktop_file ( pd, path, dent->d_name );
}
- closedir ( dir );
+ switch ( file->d_type )
+ {
+ case DT_REG:
+ read_desktop_file ( pd, filename, file->d_name );
+ filename = NULL;
+ break;
+ case DT_DIR:
+ walk_dir ( pd, filename );
+ break;
+ default:
+ break;
+ }
+ g_free ( filename );
}
+ closedir ( dir );
}
/**
* @param entry The command entry to remove from history
@@ -232,6 +270,7 @@ static void delete_entry_history ( const DRunModeEntry *entry )
g_free ( path );
}
+
static void get_apps_history ( DRunModePrivateData *pd )
{
unsigned int length = 0;
@@ -246,38 +285,21 @@ static void get_apps_history ( DRunModePrivateData *pd )
g_free ( retv );
pd->history_length = pd->cmd_list_length;
}
+
static void get_apps ( DRunModePrivateData *pd )
{
get_apps_history ( pd );
- const char * const * dr = g_get_system_data_dirs ();
- const char * const * iter = dr;
- while ( iter != NULL && *iter != NULL && **iter != '\0' ) {
- gboolean skip = FALSE;
- for ( size_t i = 0; !skip && dr[i] != ( *iter ); i++ ) {
- skip = ( g_strcmp0 ( *iter, dr[i] ) == 0 );
- }
- if ( skip ) {
- iter++;
- continue;
- }
- gchar *bp = g_build_filename ( *iter, "applications", NULL );
- get_apps_dir ( pd, bp );
- g_free ( bp );
- iter++;
- }
- const char *d = g_get_user_data_dir ();
- for ( size_t i = 0; dr && dr[i] != NULL; i++ ) {
- if ( g_strcmp0 ( d, dr[i] ) == 0 ) {
- // Done this already, no need to repeat.
- return;
- }
- }
- if ( d ) {
- gchar *bp = g_build_filename ( d, "applications", NULL );
- get_apps_dir ( pd, bp );
- g_free ( bp );
- }
+ gchar *dir;
+ const gchar * const * sys = g_get_system_data_dirs ();
+ for (; *sys != NULL; ++sys ) {
+ dir = g_build_filename ( *sys, "applications", NULL );
+ walk_dir ( pd, dir );
+ g_free ( dir );
+ }
+ dir = g_build_filename ( g_get_user_data_dir (), "applications", NULL );
+ walk_dir ( pd, dir );
+ g_free ( dir );
}
static int drun_mode_init ( Mode *sw )