527fef7b840c21873777e25f31d7c834828dfbd6
[profile/ivi/murphy.git] / src / plugins / ivi-resource-manager / appid.c
1 /*
2  * Copyright (c) 2012, Intel Corporation
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *  * Redistributions of source code must retain the above copyright notice,
9  *    this list of conditions and the following disclaimer.
10  *  * Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *  * Neither the name of Intel Corporation nor the names of its contributors
14  *    may be used to endorse or promote products derived from this software
15  *    without specific prior written permission.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <dirent.h>
37 #include <limits.h>
38 #include <errno.h>
39
40 #ifdef TZCONFIG_ENABLED
41 #    include <tzplatform_config.h>
42 #endif
43
44 #include <murphy/common.h>
45
46 #include "appid.h"
47
48 #define APP_MAX   1024
49
50 typedef struct appid_map_s   appid_map_t;
51
52 struct appid_map_s {
53     const char *id;
54     const char *exe;
55 };
56
57 struct mrp_resmgr_appid_s {
58     mrp_resmgr_data_t *data;
59     mrp_htbl_t *map;
60 };
61
62 static void map_init(mrp_resmgr_appid_t *, const char *);
63 static void map_add_entry(mrp_resmgr_appid_t *, const char *, const char *);
64 static void map_free_entry(void *, void *);
65
66 static int pid2exe(const char *, char *, size_t);
67
68
69 mrp_resmgr_appid_t *mrp_resmgr_appid_create(mrp_resmgr_data_t *data)
70 {
71     mrp_resmgr_appid_t *appid;
72     mrp_htbl_config_t cfg;
73
74 #ifdef TZCONFIG_ENABLED
75     char *app_dir = tzplatform_getenv(TZ_USER_APP);
76 #else
77     char *app_dir = "/usr/app";
78 #endif
79
80     cfg.nentry = APP_MAX;
81     cfg.comp = mrp_string_comp;
82     cfg.hash =  mrp_string_hash;
83     cfg.free = map_free_entry;
84     cfg.nbucket = cfg.nentry / 8;
85
86     if ((appid = mrp_allocz(sizeof(*appid)))) {
87         appid->data = data;
88         appid->map = mrp_htbl_create(&cfg);
89
90         map_init(appid, app_dir);
91     }
92
93     return appid;
94 }
95
96
97 void mrp_resmgr_appid_destroy(mrp_resmgr_appid_t *appid)
98 {
99     if (appid) {
100         mrp_htbl_destroy(appid->map, TRUE);
101         mrp_free(appid);
102     }
103 }
104
105 const char *mrp_resmgr_appid_find_by_pid(mrp_resmgr_appid_t *appid,
106                                          const char *pid)
107 {
108     char exe[PATH_MAX];
109     appid_map_t *entry;
110
111     if (pid2exe(pid, exe, PATH_MAX) < 0)
112         goto failed;
113
114     if (!(entry = mrp_htbl_lookup(appid->map, exe)))
115         goto failed;
116
117
118     return entry->id;
119
120  failed:
121     return NULL;
122 }
123
124 static void map_init(mrp_resmgr_appid_t *appid, const char *dir_path)
125 {
126     DIR *dir, *bindir;
127     struct dirent *dirent, *binent;
128     struct stat stat;
129     const char *id;
130     char subdir_path[PATH_MAX];
131     char bindir_path[PATH_MAX];
132     char exe[PATH_MAX];
133
134     if (!(dir = opendir(dir_path))) {
135         mrp_log_error("ivi-resource-manager: can't open directory %s: %s",
136                       dir_path, strerror(errno));
137         return;
138     }
139
140     while ((dirent = readdir(dir))) {
141         id = dirent->d_name;
142
143         snprintf(subdir_path, sizeof(subdir_path), "%s/%s", dir_path, id);
144
145         if (lstat(subdir_path, &stat) < 0) {
146             mrp_log_error("ivi-resource-manager: can't stat %s: %s",
147                           subdir_path, strerror(errno));
148             continue;
149         }
150
151         if (!S_ISDIR(stat.st_mode) || id[0] == '.')
152             continue;
153
154         snprintf(bindir_path, sizeof(bindir_path), "%s/bin", subdir_path);
155
156         if (!(bindir = opendir(bindir_path))) {
157             mrp_log_error("ivi-resource-manager: can't open directory %s: %s",
158                           bindir_path, strerror(errno));
159             continue;
160         }
161
162         while ((binent = readdir(bindir))) {
163             snprintf(exe, sizeof(exe), "%s/%s", bindir_path, binent->d_name);
164
165             if (lstat(exe, &stat) < 0) {
166                 mrp_log_error("ivi-resource-manager: can't stat %s: %s",
167                               exe, strerror(errno));
168                 continue;
169             }
170
171             if (!S_ISREG(stat.st_mode) || !(stat.st_mode & 0111))
172                 continue;
173
174             map_add_entry(appid, id, exe);
175         }
176
177         closedir(bindir);
178
179     } /* while dirent */
180
181     closedir(dir);
182 }
183
184 static void map_add_entry(mrp_resmgr_appid_t *appid,
185                           const char *id,
186                           const char *exe)
187 {
188     appid_map_t *entry;
189
190     if (!(entry = mrp_allocz(sizeof(*entry))) ||
191         !(entry->id = mrp_strdup(id)) ||
192         !(entry->exe = mrp_strdup(exe)))
193     {
194         mrp_log_error("ivi-resource-manager: can't allocate memory");
195         return;
196     }
197
198     mrp_htbl_insert(appid->map, (void *)entry->exe, entry);
199
200     mrp_log_info("ivi-resource-manager: map exe %s => appid %s",
201                  entry->exe, entry->id);
202 }
203
204 static void map_free_entry(void *key, void *object)
205 {
206     appid_map_t *me = (appid_map_t *)object;
207
208     MRP_UNUSED(key);
209
210     free((void *)me->id);
211     free((void *)me->exe);
212     free((void *)me);
213 }
214
215 static int pid2exe(const char *pid, char *buf, size_t len)
216 {
217     FILE *f;
218     char path[PATH_MAX];
219     char *p;
220     int st = -1;
221
222     if (pid && buf && len > 0) {
223         snprintf(path, sizeof(path), "/proc/%s/cmdline", pid);
224
225         if ((f = fopen(path, "r"))) {
226             if (fgets(buf, len-1, f)) {
227                 if ((p = strchr(buf, ' ')))
228                     *p = '\0';
229                 else if ((p = strchr(buf, '\n')))
230                     *p = '\0';
231                 st = 0;
232             }
233             fclose(f);
234         }
235     }
236
237     if (st < 0)
238         mrp_log_info("ivi-resource-manager: pid2exe(%s) failed", pid);
239     else
240         mrp_log_info("ivi-resource-manager: pid %s => exe %s", pid, buf);
241
242     return st;
243 }
244
245
246 /*
247  * Local Variables:
248  * c-basic-offset: 4
249  * indent-tabs-mode: nil
250  * End:
251  *
252  */