Move function definition to aul header
[platform/core/appfw/aul-1.git] / src / miregex.c
1 /*
2  * Copyright (c) 2000 - 2015 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
17 #define _GNU_SOURCE
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <fcntl.h>
21 #include <dirent.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <linux/limits.h>
26
27 #include "miregex.h"
28 #include "aul_util.h"
29
30 #define MIREGEX_DIR SHARE_PREFIX"/miregex"
31 #define ONELINE_BUF 1024
32
33 typedef struct miregex_file_info_t {
34         char *regex;
35         char *desc;
36 } miregex_file_info;
37
38 regex_tbl *miregex_tbl = NULL;
39 static time_t miregex_mtime = 0;
40
41 static void __free_miregex_file_info(miregex_file_info *info);
42 static miregex_file_info *__get_miregex_file_info(const char *path);
43 static int __add_miregex(const char *name, const char *regex, const char *desc);
44 static int __need_update_miregex_tbl();
45 static void __miregex_free_regex_table();
46
47
48
49 static void __free_miregex_file_info(miregex_file_info *info)
50 {
51         if (info == NULL)
52                 return;
53
54         if (info->regex != NULL)
55                 free(info->regex);
56
57         if (info->desc != NULL)
58                 free(info->desc);
59
60         free(info);
61 }
62
63 static miregex_file_info *__get_miregex_file_info(const char *path)
64 {
65         FILE *f;
66         char oneline[ONELINE_BUF];
67         miregex_file_info *info;
68
69         f = fopen(path, "r");
70         if (f == NULL) {
71                 _E("miregex file %s is cannot open", path);
72                 return NULL;
73         }
74
75         info = (miregex_file_info *)malloc(sizeof(miregex_file_info));
76         if (info == NULL) {
77                 fclose(f);
78                 return NULL;
79         }
80
81         info->regex = NULL;
82         info->desc = NULL;
83
84         while ((info->regex == NULL) || (info->desc == NULL)) {
85                 memset(oneline, 0, ONELINE_BUF);
86                 if (fgets(oneline, ONELINE_BUF, f) == NULL)
87                         break;
88
89                 oneline[strlen(oneline) - 1] = 0;
90
91                 if (info->regex == NULL)
92                         info->regex = strdup(oneline);
93                 else
94                         info->desc = strdup(oneline);
95         }
96
97         fclose(f);
98
99         return info;
100 }
101
102 static int __add_miregex(const char *name, const char *regex, const char *desc)
103 {
104         regex_tbl *tbl = NULL;
105         int error;
106         int ret;
107         char *msg = NULL;
108
109         if (regex == NULL)
110                 return -1;
111
112         tbl = (regex_tbl *)malloc(sizeof(regex_tbl));
113         if (NULL == tbl) {
114                 _E("Malloc failed!");
115                 return -1;
116         }
117
118         if ((error = regcomp(&(tbl->regex_preg), regex,
119                              REG_EXTENDED | REG_NOSUB)) != 0) {
120                 ret = regerror(error, &(tbl->regex_preg), NULL, 0);
121                 msg = (char *)malloc(sizeof(char) * ret);
122                 if (NULL == msg) {
123                         _E("Malloc failed!");
124                         if (tbl) {
125                                 free(tbl);
126                                 tbl = NULL;
127                         }
128
129                         return -1;
130                 }
131                 regerror(error, &(tbl->regex_preg), msg, ret);
132                 _E("regex compile error - %s", msg);
133                 if (msg) {
134                         free(msg);
135                         msg = NULL;
136                 }
137
138                 if (tbl) {
139                         free(tbl);
140                         tbl = NULL;
141                 }
142
143                 return -1;
144         }
145
146         tbl->mimetype = strdup(name);
147         tbl->regex = strdup(regex);
148         if (desc != NULL)
149                 tbl->desc = strdup(desc);
150         tbl->next = miregex_tbl;
151         miregex_tbl = tbl;
152
153         return 0;
154 }
155
156 static int __need_update_miregex_tbl()
157 {
158         struct stat st;
159
160         if (stat(MIREGEX_DIR, &st) < 0) {
161                 _E("stat error - check miregex dir - %s", MIREGEX_DIR);
162                 return 1;
163         }
164
165         if (st.st_mtime != miregex_mtime) {
166                 miregex_mtime = st.st_mtime;
167                 return 1;
168         }
169
170         if (miregex_tbl == NULL) {
171                 miregex_mtime = st.st_mtime;
172                 return 1;
173         }
174
175         return 0;
176 }
177
178 static void __miregex_free_regex_table()
179 {
180         regex_tbl *tbl;
181
182         while (miregex_tbl) {
183                 if (miregex_tbl->mimetype != NULL)
184                         free(miregex_tbl->mimetype);
185                 if (miregex_tbl->regex != NULL)
186                         free(miregex_tbl->regex);
187                 if (miregex_tbl->desc != NULL)
188                         free(miregex_tbl->desc);
189                 regfree(&(miregex_tbl->regex_preg));
190
191                 tbl = miregex_tbl;
192                 miregex_tbl = miregex_tbl->next;
193                 free(tbl);
194         }
195
196         miregex_tbl = NULL;
197 }
198
199 regex_tbl *miregex_get_regex_table()
200 {
201         DIR *dp;
202         struct dirent *dentry = NULL;
203         char buf[PATH_MAX];
204         miregex_file_info *info;
205
206         if (!__need_update_miregex_tbl())
207                 return miregex_tbl;
208
209         _D("*** reload miregex tbl ***");
210
211         if (miregex_tbl != NULL)
212                 __miregex_free_regex_table();
213
214         dp = opendir(MIREGEX_DIR);
215         if (dp == NULL)
216                 return NULL;
217
218         while ((dentry = readdir(dp)) != NULL) {
219                 if (dentry->d_name[0] == '.')
220                         continue;
221
222                 snprintf(buf, sizeof(buf), "%s/%s", MIREGEX_DIR,
223                          dentry->d_name);
224
225                 info = __get_miregex_file_info(buf);
226                 if (info == NULL)
227                         continue;
228
229                 if (__add_miregex(dentry->d_name,
230                         info->regex, info->desc) < 0) {
231                         /* TODO : invalid regular expression - will be removed*/
232                 }
233
234                 __free_miregex_file_info(info);
235         }
236
237         closedir(dp);
238
239         return miregex_tbl;
240 }