summaryrefslogtreecommitdiff
path: root/src/lib/ecore_file/ecore_file_path.c
blob: a368cf35fb04737654f6296444e3e63133cccaf4 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif

#ifdef STDC_HEADERS
# include <stdlib.h>
# include <stddef.h>
#else
# ifdef HAVE_STDLIB_H
#  include <stdlib.h>
# endif
#endif

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "ecore_file_private.h"

static Eina_List *__ecore_file_path_bin = NULL;

static Eina_List *_ecore_file_path_from_env(const char *env);

void
ecore_file_path_init(void)
{
   __ecore_file_path_bin = _ecore_file_path_from_env("PATH");
}

void
ecore_file_path_shutdown(void)
{
   char *dir;

   EINA_LIST_FREE(__ecore_file_path_bin, dir)
     eina_stringshare_del(dir);
}

Eina_List *
_ecore_file_path_from_env(const char *env)
{
   Eina_List *path = NULL;
   char *env_tmp, *env_path, *p, *last;

   env_tmp = getenv(env);
   if (!env_tmp)
     return path;

   env_path = alloca(sizeof(char) * strlen(env_tmp) + 1);
   memset(env_path, 0, strlen(env_tmp));
   strcpy(env_path, env_tmp);
   last = env_path;
   for (p = env_path; *p; p++)
     {
        if (*p == ':')
          *p = '\0';

        if (!*p)
          {
             if (!ecore_file_path_dir_exists(last))
               path = eina_list_append(path, eina_stringshare_add(last));
             last = p + 1;
          }
     }
   if (p > last)
     path = eina_list_append(path, eina_stringshare_add(last));

   return path;
}

/**
 * @addtogroup Ecore_File_Group Ecore_File - Files and directories convenience functions
 *
 * @{
 */

/**
 * @brief Check if the given directory is in PATH.
 *
 * @param in_dir The name of the directory to search in PATH.
 * @return @c EINA_TRUE if the directory exist in PATH, @c EINA_FALSE otherwise.
 *
 * This function checks if @p in_dir is in the environment variable
 * PATH. If @p in_dir is @c NULL, or if PATH is empty, or @p in_dir is
 * not in PATH, the function returns @c EINA_FALSE, otherwise it returns
 * @c EINA_TRUE.
 */
EAPI Eina_Bool
ecore_file_path_dir_exists(const char *in_dir)
{
   Eina_List *l;
   char *dir;

   if (!in_dir)
     return EINA_FALSE;

   if (!__ecore_file_path_bin) return EINA_FALSE;
   EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
     {
        if (strcmp(dir, in_dir))
          return EINA_TRUE;
     }

   return EINA_FALSE;
}

/**
 * @brief Check if the given application is installed.
 *
 * @param  exe The name of the application
 * @return @c EINA_TRUE if the @p exe is in PATH and is executable,
 * @c EINA_FALSE otherwise.
 *
 * This function checks if @p exe exists in PATH and is executable. If
 * @p exe is @c NULL or is not executable, the function returns
 * @c EINA_FALSE, otherwise it returns @c EINA_TRUE.
 */
EAPI Eina_Bool
ecore_file_app_installed(const char *exe)
{
   Eina_List *l;
   char *dir;
   char  buf[PATH_MAX];

   if (!exe) return EINA_FALSE;
   if (ecore_file_can_exec(exe)) return EINA_TRUE;

   EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
     {
        snprintf(buf, sizeof(buf), "%s/%s", dir, exe);
        if (ecore_file_can_exec(buf))
          return EINA_TRUE;
     }

   return EINA_FALSE;
}

/**
 * @brief Get a list of all the applications installed on the system.
 *
 * @return An Eina_List containing all the executable files in the
 * system.
 *
 * This function returns a list of allocated strings of all the
 * executable files. If no files are found, the function returns
 * @c NULL. When not needed anymore, the element of the list must be
 * freed.
 */
EAPI Eina_List *
ecore_file_app_list(void)
{
   Eina_List *list = NULL;
   Eina_List *files;
   Eina_List *l;
   char  buf[PATH_MAX], *dir, *exe;

   EINA_LIST_FOREACH(__ecore_file_path_bin, l, dir)
     {
        files = ecore_file_ls(dir);
        EINA_LIST_FREE(files, exe)
               {
                  snprintf(buf, sizeof(buf), "%s/%s", dir, exe);
                  if ((ecore_file_can_exec(buf)) &&
                      (!ecore_file_is_dir(buf)))
               list = eina_list_append(list, strdup(buf));
             free(exe);
          }
     }

   return list;
}

/**
 * @}
 */