34 #define G_LOG_DOMAIN "Dialogs.Run" 43 #include <sys/types.h> 61 #define RUN_CACHE_FILE "rofi-3.runcache" 80 static void exec_cmd (
const char *cmd,
int run_in_term )
83 if ( !cmd || !cmd[0] ) {
86 gsize lf_cmd_size = 0;
87 gchar *lf_cmd = g_locale_from_utf8 ( cmd, -1, NULL, &lf_cmd_size, &error );
88 if ( error != NULL ) {
89 g_warning (
"Failed to convert command to locale encoding: %s", error->message );
90 g_error_free ( error );
135 static int sort_func (
const void *a,
const void *b, G_GNUC_UNUSED
void *data )
137 const char *astr = *(
const char *
const * ) a;
138 const char *bstr = *(
const char *
const * ) b;
140 if ( astr == NULL && bstr == NULL ) {
143 else if ( astr == NULL ) {
146 else if ( bstr == NULL ) {
149 return g_strcmp0 ( astr, bstr );
155 static char **
get_apps_external (
char **retv,
unsigned int *length,
unsigned int num_favorites )
159 FILE *inp = fdopen ( fd,
"r" );
162 size_t buffer_length = 0;
164 while ( getline ( &buffer, &buffer_length, inp ) > 0 ) {
167 if ( buffer[strlen ( buffer ) - 1] ==
'\n' ) {
168 buffer[strlen ( buffer ) - 1] =
'\0';
173 for (
unsigned int j = 0; found == 0 && j < num_favorites; j++ ) {
174 if ( strcasecmp ( buffer, retv[j] ) == 0 ) {
184 retv = g_realloc ( retv, ( ( *length ) + 2 ) *
sizeof (
char* ) );
185 retv[( *length )] = g_strdup ( buffer );
189 if ( buffer != NULL ) {
192 if ( fclose ( inp ) != 0 ) {
193 g_warning (
"Failed to close stdout off executor script: '%s'",
194 g_strerror ( errno ) );
198 retv[( *length ) ] = NULL;
207 GError *error = NULL;
209 unsigned int num_favorites = 0;
212 if ( g_getenv (
"PATH" ) == NULL ) {
220 num_favorites = ( *length );
222 path = g_strdup ( g_getenv (
"PATH" ) );
225 gchar *homedir = g_locale_to_utf8 ( g_get_home_dir (), -1, NULL, &l, &error );
226 if ( error != NULL ) {
227 g_debug (
"Failed to convert homedir to UTF-8: %s", error->message );
228 g_clear_error ( &error );
233 const char *
const sep =
":";
234 char *strtok_savepointer = NULL;
235 for (
const char *dirname = strtok_r ( path, sep, &strtok_savepointer ); dirname != NULL; dirname = strtok_r ( NULL, sep, &strtok_savepointer ) ) {
237 DIR *dir = opendir ( fpath );
238 g_debug (
"Checking path %s for executable.", fpath );
244 gchar *dirn = g_locale_to_utf8 ( dirname, -1, NULL, &dirn_len, &error );
245 if ( error != NULL ) {
246 g_debug (
"Failed to convert directory name to UTF-8: %s", error->message );
247 g_clear_error ( &error );
251 gboolean is_homedir = g_str_has_prefix ( dirn, homedir );
254 while ( ( dent = readdir ( dir ) ) != NULL ) {
255 if ( dent->d_type != DT_REG && dent->d_type != DT_LNK && dent->d_type != DT_UNKNOWN ) {
259 if ( dent->d_name[0] ==
'.' ) {
263 gchar *fpath = g_build_filename ( dirname, dent->d_name, NULL );
264 gboolean b = g_file_test ( fpath, G_FILE_TEST_IS_EXECUTABLE );
272 gchar *name = g_filename_to_utf8 ( dent->d_name, -1, NULL, &name_len, &error );
273 if ( error != NULL ) {
274 g_debug (
"Failed to convert filename to UTF-8: %s", error->message );
275 g_clear_error ( &error );
282 for (
unsigned int j = 0; found == 0 && j < num_favorites; j++ ) {
283 if ( g_strcmp0 ( name, retv[j] ) == 0 ) {
293 retv = g_realloc ( retv, ( ( *length ) + 2 ) *
sizeof (
char* ) );
294 retv[( *length )] = name;
295 retv[( *length ) + 1] = NULL;
309 if ( ( *length ) == 0 ) {
313 if ( ( *length ) > num_favorites ) {
314 g_qsort_with_data ( &retv[num_favorites], ( *length ) - num_favorites,
sizeof (
char* ),
sort_func, NULL );
318 unsigned int removed = 0;
319 for (
unsigned int index = num_favorites; index < ( ( *length ) - 1 ); index++ ) {
320 if ( g_strcmp0 ( retv[index], retv[index + 1] ) == 0 ) {
321 g_free ( retv[index] );
327 if ( ( *length ) > num_favorites ) {
328 g_qsort_with_data ( &retv[num_favorites], ( *length ) - num_favorites,
sizeof (
char* ),
333 ( *length ) -= removed;
352 if ( rmpd != NULL ) {
381 else if ( ( mretv &
MENU_OK ) && rmpd->
cmd_list[selected_line] != NULL ) {
384 else if ( ( mretv &
MENU_CUSTOM_INPUT ) && *input != NULL && *input[0] !=
'\0' ) {
398 static char *
_get_display_value (
const Mode *sw,
unsigned int selected_line, G_GNUC_UNUSED
int *state, G_GNUC_UNUSED GList **list,
int get_entry )
401 return get_entry ? g_strdup ( rmpd->
cmd_list[selected_line] ) : NULL;
413 .cfg_name_key =
"display-run",
420 ._get_completion = NULL,
421 ._preprocess_input = NULL,
422 .private_data = NULL,
static char * _get_display_value(const Mode *sw, unsigned int selected_line, G_GNUC_UNUSED int *state, G_GNUC_UNUSED GList **list, int get_entry)
static ModeMode run_mode_result(Mode *sw, int mretv, char **input, unsigned int selected_line)
void history_set(const char *filename, const char *entry)
char ** history_get_list(const char *filename, unsigned int *length)
gboolean helper_execute_command(const char *wd, const char *cmd, gboolean run_in_term, RofiHelperExecuteContext *context)
static int run_token_match(const Mode *sw, rofi_int_matcher **tokens, unsigned int index)
static char ** get_apps_external(char **retv, unsigned int *length, unsigned int num_favorites)
static void delete_entry(const char *cmd)
unsigned int cmd_list_length
void history_remove(const char *filename, const char *entry)
static int sort_func(const void *a, const void *b, G_GNUC_UNUSED void *data)
static int run_mode_init(Mode *sw)
int helper_token_match(rofi_int_matcher *const *tokens, const char *input)
static unsigned int run_mode_get_num_entries(const Mode *sw)
static char ** get_apps(unsigned int *length)
char * rofi_expand_path(const char *input)
int execute_generator(const char *cmd)
static void exec_cmd(const char *cmd, int run_in_term)
static void run_mode_destroy(Mode *sw)