Bump up efl module version.
[platform/core/appfw/launchpad.git] / src / debugger_info.c
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #define _GNU_SOURCE
17
18 #include <stdio.h>
19 #include <malloc.h>
20 #include <stdlib.h>
21 #include <dirent.h>
22 #include <string.h>
23 #include <unistd.h>
24
25 #include "launchpad_common.h"
26 #include "debugger_info.h"
27
28 #define TAG_DEBUGGER            "[DEBUGGER]"
29 #define TAG_NAME                "NAME"
30 #define TAG_EXE                 "EXE"
31 #define TAG_APP_TYPE            "APP_TYPE"
32 #define TAG_EXTRA_KEY           "EXTRA_KEY"
33 #define TAG_EXTRA_ENV           "EXTRA_ENV"
34 #define TAG_UNLINK              "UNLINK"
35 #define TAG_ATTACH              "ATTACH"
36 #define TAG_LAST_EXTRA_KEY      "LAST_EXTRA_KEY"
37 #define TAG_DEFAULT_OPT         "DEFAULT_OPT"
38
39 struct debugger_info_s {
40         char *name;
41         char *exe;
42         GList *app_types;
43         GList *extra_key_list;
44         GList *extra_env_list;
45         GList *unlink_list;
46         char *attach;
47         GList *last_extra_key_list;
48         GList *default_opt_list;
49 };
50
51 static struct debugger_info_s *__create_debugger_info(void)
52 {
53         struct debugger_info_s *info;
54
55         info = calloc(1, sizeof(struct debugger_info_s));
56         if (info == NULL) {
57                 _E("out of memory");
58                 return NULL;
59         }
60
61         return info;
62 }
63
64 static void __destroy_debugger_info(gpointer data)
65 {
66         struct debugger_info_s *info = (struct debugger_info_s *)data;
67
68         if (info == NULL)
69                 return;
70
71         if (info->default_opt_list)
72                 g_list_free_full(info->default_opt_list, free);
73         if (info->last_extra_key_list)
74                 g_list_free_full(info->last_extra_key_list, free);
75         if (info->attach)
76                 free(info->attach);
77         if (info->unlink_list)
78                 g_list_free_full(info->unlink_list, free);
79         if (info->extra_env_list)
80                 g_list_free_full(info->extra_env_list, free);
81         if (info->extra_key_list)
82                 g_list_free_full(info->extra_key_list, free);
83         if (info->app_types)
84                 g_list_free_full(info->app_types, free);
85         if (info->exe)
86                 free(info->exe);
87         if (info->name)
88                 free(info->name);
89         free(info);
90 }
91
92 static void __parse_app_types(struct debugger_info_s *info, char *line)
93 {
94         char *token;
95         char *saveptr = NULL;
96
97         token = strtok_r(line, " |\t\r\n", &saveptr);
98         while (token) {
99                 info->app_types = g_list_append(info->app_types, strdup(token));
100                 token = strtok_r(NULL, " |\t\r\n", &saveptr);
101         }
102 }
103
104 static GList *__parse_file(GList *list, const char *path)
105 {
106         FILE *fp;
107         char buf[LINE_MAX];
108         char *tok1 = NULL;
109         char *tok2 = NULL;
110         struct debugger_info_s *info = NULL;
111
112         fp = fopen(path, "rt");
113         if (fp == NULL)
114                 return list;
115
116         while (fgets(buf, sizeof(buf), fp) != NULL) {
117                 FREE_AND_NULL(tok1);
118                 FREE_AND_NULL(tok2);
119                 sscanf(buf, "%ms %ms", &tok1, &tok2);
120                 if (tok1 && strcasecmp(TAG_DEBUGGER, tok1) == 0) {
121                         if (info) {
122                                 _D("name: %s, exe: %s", info->name, info->exe);
123                                 list = g_list_append(list, info);
124                         }
125
126                         info = __create_debugger_info();
127                         if (info == NULL)
128                                 break;
129
130                         continue;
131                 }
132
133                 if (!tok1 || !tok2)
134                         continue;
135                 if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
136                         continue;
137                 if (info == NULL)
138                         continue;
139
140                 if (strcasecmp(TAG_NAME, tok1) == 0) {
141                         info->name = strdup(tok2);
142                         if (info->name == NULL) {
143                                 _E("out of memory");
144                                 __destroy_debugger_info(info);
145                                 info = NULL;
146                                 break;
147                         }
148                 } else if (strcasecmp(TAG_EXE, tok1) == 0) {
149                         info->exe = strdup(tok2);
150                         if (info->exe == NULL) {
151                                 _E("out of memory");
152                                 __destroy_debugger_info(info);
153                                 info = NULL;
154                                 break;
155                         }
156                 } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
157                         __parse_app_types(info, &buf[strlen(tok1)]);
158                         if (info->app_types == NULL) {
159                                 _E("app_types is NULL");
160                                 __destroy_debugger_info(info);
161                                 info = NULL;
162                                 break;
163                         }
164                 } else if (strcasecmp(TAG_EXTRA_KEY, tok1) == 0) {
165                         info->extra_key_list = g_list_append(
166                                         info->extra_key_list, strdup(tok2));
167                 } else if (strcasecmp(TAG_EXTRA_ENV, tok1) == 0) {
168                         info->extra_env_list = g_list_append(
169                                         info->extra_env_list, strdup(tok2));
170                 } else if (strcasecmp(TAG_UNLINK, tok1) == 0) {
171                         info->unlink_list = g_list_append(info->unlink_list,
172                                         strdup(tok2));
173                 } else if (strcasecmp(TAG_ATTACH, tok1) == 0) {
174                         info->attach = strdup(tok2);
175                         if (info->attach == NULL) {
176                                 _E("attach is NULL");
177                                 __destroy_debugger_info(info);
178                                 info = NULL;
179                                 break;
180                         }
181                 } else if (strcasecmp(TAG_LAST_EXTRA_KEY, tok1) == 0) {
182                         info->last_extra_key_list = g_list_append(
183                                         info->last_extra_key_list,
184                                         strdup(tok2));
185                 } else if (strcasecmp(TAG_DEFAULT_OPT, tok1) == 0) {
186                         info->default_opt_list = g_list_append(
187                                         info->default_opt_list,
188                                         strdup(tok2));
189                 }
190         }
191         fclose(fp);
192
193         if (info) {
194                 _D("name: %s, exe: %s", info->name, info->exe);
195                 list = g_list_append(list, info);
196         }
197
198         if (tok1)
199                 free(tok1);
200         if (tok2)
201                 free(tok2);
202
203         return list;
204 }
205
206 GList *_debugger_info_load(const char *path)
207 {
208         DIR *dp;
209         struct dirent *dentry = NULL;
210         GList *list = NULL;
211         char buf[PATH_MAX];
212         char *ext;
213
214         if (path == NULL)
215                 return NULL;
216
217         dp = opendir(path);
218         if (dp == NULL)
219                 return NULL;
220
221         while ((dentry = readdir(dp)) != NULL) {
222                 if (dentry->d_name[0] == '.')
223                         continue;
224
225                 ext = strrchr(dentry->d_name, '.');
226                 if (ext && strcmp(ext, ".debugger") == 0) {
227                         snprintf(buf, sizeof(buf), "%s/%s",
228                                         path, dentry->d_name);
229                         list = __parse_file(list, buf);
230                 }
231         }
232         closedir(dp);
233
234         return list;
235 }
236
237 void _debugger_info_unload(GList *info)
238 {
239         if (info == NULL)
240                 return;
241
242         g_list_free_full(info, __destroy_debugger_info);
243 }
244
245 static int __comp_name(gconstpointer a, gconstpointer b)
246 {
247         struct debugger_info_s *info = (struct debugger_info_s *)a;
248
249         if (info == NULL || info->name == NULL || b == NULL)
250                 return -1;
251
252         if (strcasecmp(info->name, b) == 0)
253                 return 0;
254
255         return -1;
256 }
257
258 debugger_info_h _debugger_info_find(GList *info_list, const char *name)
259 {
260         GList *list;
261
262         if (info_list == NULL || name == NULL)
263                 return NULL;
264
265         list = g_list_find_custom(info_list, name, __comp_name);
266         if (list == NULL)
267                 return NULL;
268
269         return (debugger_info_h)list->data;
270 }
271
272 const char *_debugger_info_get_exe(debugger_info_h info)
273 {
274         if (info == NULL)
275                 return NULL;
276
277         return info->exe;
278 }
279
280 GList *_debugger_info_get_extra_key_list(debugger_info_h info)
281 {
282         if (info == NULL)
283                 return NULL;
284
285         return info->extra_key_list;
286 }
287
288 GList *_debugger_info_get_extra_env_list(debugger_info_h info)
289 {
290         if (info == NULL)
291                 return NULL;
292
293         return info->extra_env_list;
294 }
295
296 GList *_debugger_info_get_unlink_list(debugger_info_h info)
297 {
298         if (info == NULL)
299                 return NULL;
300
301         return info->unlink_list;
302 }
303
304 const char *_debugger_info_get_attach(debugger_info_h info)
305 {
306         if (info == NULL)
307                 return NULL;
308
309         return info->attach;
310 }
311
312 GList *_debugger_info_get_last_extra_key_list(debugger_info_h info)
313 {
314         if (info == NULL)
315                 return NULL;
316
317         return info->last_extra_key_list;
318 }
319
320 GList *_debugger_info_get_default_opt_list(debugger_info_h info)
321 {
322         if (info == NULL)
323                 return NULL;
324
325         return info->default_opt_list;
326 }