Release version 0.15.20
[platform/core/appfw/launchpad.git] / src / launchpad / src / launcher_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 "launcher_info.h"
26 #include "launchpad_common.h"
27
28 #define TAG_LAUNCHER    "[LAUNCHER]"
29 #define TAG_NAME        "NAME"
30 #define TAG_EXE         "EXE"
31 #define TAG_APP_TYPE    "APP_TYPE"
32 #define TAG_EXTRA_ARG   "EXTRA_ARG"
33
34 struct launcher_info_s {
35         char *name;
36         char *exe;
37         GList *app_types;
38         GList *extra_args;
39 };
40
41 static struct launcher_info_s *__create_launcher_info(void)
42 {
43         struct launcher_info_s *info;
44
45         info = calloc(1, sizeof(struct launcher_info_s));
46         if (info == NULL) {
47                 _E("out of memory");
48                 return NULL;
49         }
50
51         return info;
52 }
53
54 static void __destroy_launcher_info(gpointer data)
55 {
56         struct launcher_info_s *info = (struct launcher_info_s *)data;
57
58         if (info == NULL)
59                 return;
60
61         if (info->extra_args)
62                 g_list_free_full(info->extra_args, free);
63         if (info->app_types)
64                 g_list_free_full(info->app_types, free);
65         if (info->exe)
66                 free(info->exe);
67         if (info->name)
68                 free(info->name);
69         free(info);
70 }
71
72 static void __parse_app_types(struct launcher_info_s *info, char *line)
73 {
74         char *token;
75         char *saveptr = NULL;
76
77         token = strtok_r(line, " |\t\r\n", &saveptr);
78         while (token) {
79                 info->app_types = g_list_append(info->app_types, strdup(token));
80                 token = strtok_r(NULL, " |\t\r\n", &saveptr);
81         }
82 }
83
84 static GList *__parse_file(GList *list, const char *path)
85 {
86         FILE *fp;
87         char buf[LINE_MAX];
88         char *tok1 = NULL;
89         char *tok2 = NULL;
90         struct launcher_info_s *info = NULL;
91
92         fp = fopen(path, "rt");
93         if (fp == NULL)
94                 return list;
95
96         while (fgets(buf, sizeof(buf), fp) != NULL) {
97                 FREE_AND_NULL(tok1);
98                 FREE_AND_NULL(tok2);
99                 sscanf(buf, "%ms %ms", &tok1, &tok2);
100                 if (tok1 && strcasecmp(TAG_LAUNCHER, tok1) == 0) {
101                         if (info) {
102                                 _D("name: %s, exe: %s", info->name, info->exe);
103                                 list = g_list_append(list, info);
104                         }
105
106                         info = __create_launcher_info();
107                         if (info == NULL)
108                                 break;
109
110                         continue;
111                 }
112
113                 if (!tok1 || !tok2)
114                         continue;
115                 if (tok1[0] == '\0' || tok2[0] == '\0' || tok1[0] == '#')
116                         continue;
117                 if (info == NULL)
118                         continue;
119
120                 if (strcasecmp(TAG_NAME, tok1) == 0) {
121                         info->name = strdup(tok2);
122                         if (info->name == NULL) {
123                                 _E("out of memory");
124                                 __destroy_launcher_info(info);
125                                 info = NULL;
126                                 break;
127                         }
128                 } else if (strcasecmp(TAG_EXE, tok1) == 0) {
129                         info->exe = strdup(tok2);
130                         if (info->exe == NULL) {
131                                 _E("out of memory");
132                                 __destroy_launcher_info(info);
133                                 info = NULL;
134                                 break;
135                         }
136                         if (access(info->exe, F_OK | X_OK) != 0) {
137                                 _E("Failed to access %s", info->exe);
138                                 __destroy_launcher_info(info);
139                                 info = NULL;
140                         }
141                 } else if (strcasecmp(TAG_APP_TYPE, tok1) == 0) {
142                         __parse_app_types(info, &buf[strlen(tok1)]);
143                         if (info->app_types == NULL) {
144                                 _E("app_types is NULL");
145                                 __destroy_launcher_info(info);
146                                 info = NULL;
147                                 break;
148                         }
149                 } else if (strcasecmp(TAG_EXTRA_ARG, tok1) == 0) {
150                         info->extra_args = g_list_append(info->extra_args,
151                                         strdup(tok2));
152                 }
153         }
154         fclose(fp);
155
156         if (info) {
157                 _D("name: %s, exe: %s", info->name, info->exe);
158                 list = g_list_append(list, info);
159         }
160
161         if (tok1)
162                 free(tok1);
163         if (tok2)
164                 free(tok2);
165
166         return list;
167 }
168
169 GList *_launcher_info_load(const char *path)
170 {
171         DIR *dp;
172         struct dirent *dentry = NULL;
173         GList *list = NULL;
174         char buf[PATH_MAX];
175         char *ext;
176
177         if (path == NULL)
178                 return NULL;
179
180         dp = opendir(path);
181         if (dp == NULL)
182                 return NULL;
183
184         while ((dentry = readdir(dp)) != NULL) {
185                 if (dentry->d_name[0] == '.')
186                         continue;
187
188                 ext = strrchr(dentry->d_name, '.');
189                 if (ext && strcmp(ext, ".launcher") == 0) {
190                         snprintf(buf, sizeof(buf), "%s/%s",
191                                         path, dentry->d_name);
192                         list = __parse_file(list, buf);
193                 }
194         }
195         closedir(dp);
196
197         return list;
198 }
199
200 void _launcher_info_unload(GList *info)
201 {
202         if (info == NULL)
203                 return;
204
205         g_list_free_full(info, __destroy_launcher_info);
206 }
207
208 static int __comp_str(gconstpointer a, gconstpointer b)
209 {
210         if (a == NULL || b == NULL)
211                 return -1;
212
213         return strcmp(a, b);
214 }
215
216 static int __comp_app_type(gconstpointer a, gconstpointer b)
217 {
218         struct launcher_info_s *info = (struct launcher_info_s *)a;
219
220         if (info == NULL || info->app_types == NULL || b == NULL)
221                 return -1;
222
223         if (g_list_find_custom(info->app_types, b, __comp_str))
224                 return 0;
225
226         return -1;
227 }
228
229 launcher_info_h _launcher_info_find(GList *info_list, const char *app_type)
230 {
231         GList *list;
232
233         if (info_list == NULL || app_type == NULL)
234                 return NULL;
235
236         list = g_list_find_custom(info_list, app_type, __comp_app_type);
237         if (list == NULL)
238                 return NULL;
239
240         return (launcher_info_h)list->data;
241 }
242
243 const char *_launcher_info_get_exe(launcher_info_h info)
244 {
245         if (info == NULL)
246                 return NULL;
247
248         return info->exe;
249 }
250
251 GList *_launcher_info_get_extra_args(launcher_info_h info)
252 {
253         if (info == NULL)
254                 return NULL;
255
256         return info->extra_args;
257 }