ead5308818e609b23055a3b04016f38a9b08ffa9
[framework/appfw/aul-1.git] / src / miregex.c
1 /*
2  *  aul
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>, Jaeho Lee <jaeho81.lee@samsung.com>
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  *
20  */
21
22
23 #include "miregex.h"
24 #include "simple_util.h"
25 #include <sys/types.h>
26 #include <sys/stat.h>
27 #include <fcntl.h>
28 #include <dirent.h>
29 #include <stdlib.h>
30 #include <stdio.h>
31 #include <string.h>
32
33 #define MIREGEX_DIR RW_DATA_PREFIX"/miregex"
34 #define ONELINE_BUF 1024
35
36 typedef struct miregex_file_info_t {
37         char *regex;
38         char *desc;
39 } miregex_file_info;
40
41 regex_tbl *miregex_tbl = NULL;
42 static time_t miregex_mtime = 0;
43
44 static void __free_miregex_file_info(miregex_file_info *info);
45 static miregex_file_info *__get_miregex_file_info(const char *path);
46 static int __add_miregex(const char *name, const char *regex, const char *desc);
47 static int __need_update_miregex_tbl();
48 static void __miregex_free_regex_table();
49
50
51
52 static void __free_miregex_file_info(miregex_file_info *info)
53 {
54         if (info == NULL)
55                 return;
56
57         if (info->regex != NULL)
58                 free(info->regex);
59         if (info->desc != NULL)
60                 free(info->desc);
61
62         free(info);
63 }
64
65 static miregex_file_info *__get_miregex_file_info(const char *path)
66 {
67         FILE *f;
68         char oneline[ONELINE_BUF];
69         miregex_file_info *info;
70
71         f = fopen(path, "r");
72         if (f == NULL) {
73                 _E("miregex file %s is cannot open", path);
74                 return NULL;
75         }
76
77         info = (miregex_file_info *) malloc(sizeof(miregex_file_info));
78         if(info == NULL) {
79                 fclose(f);
80                 return NULL;
81         }
82                 
83         info->regex = NULL;
84         info->desc = NULL;
85
86         while ((info->regex == NULL) || (info->desc == NULL)) {
87                 memset(oneline, 0, ONELINE_BUF);
88                 if (fgets(oneline, ONELINE_BUF, f) == NULL)
89                         break;
90
91                 oneline[strlen(oneline) - 1] = 0;
92
93                 if (info->regex == NULL)
94                         info->regex = strdup(oneline);
95                 else
96                         info->desc = strdup(oneline);
97         }
98
99         /*_D("conf file process done : info->regex = %s, 
100                 info->desc = %s",info->regex, info->desc);*/
101         fclose(f);
102
103         return info;
104 }
105
106 static int __add_miregex(const char *name, const char *regex, const char *desc)
107 {
108         regex_tbl *tbl = NULL;
109         int error;
110         int ret;
111         char *msg = NULL;
112
113         if (regex == NULL)
114                 return -1;
115
116         tbl = (regex_tbl *) malloc(sizeof(regex_tbl));
117         if (NULL == tbl) {
118                 _E("Malloc failed!");
119                 return -1;
120         }
121
122         if ((error = regcomp(&(tbl->regex_preg), regex,
123                              REG_EXTENDED | REG_NOSUB)) != 0) {
124                 ret = regerror(error, &(tbl->regex_preg), NULL, 0);
125                 msg = (char *)malloc(sizeof(char) * ret);
126                 if (NULL == msg) {
127                         _E("Malloc failed!");
128                         if (tbl) {
129                                 free(tbl);
130                                 tbl = NULL;
131                         }
132                         return -1;
133                 }
134                 regerror(error, &(tbl->regex_preg), msg, ret);
135                 _E("regex compile error - %s\n", msg);
136                 if (msg) {
137                         free(msg);
138                         msg = NULL;
139                 }
140                 if (tbl) {
141                         free(tbl);
142                         tbl = NULL;
143                 }
144                 return -1;
145         }
146
147         tbl->mimetype = strdup(name);
148         tbl->regex = strdup(regex);
149         if (desc != NULL)
150                 tbl->desc = strdup(desc);
151         tbl->next = miregex_tbl;
152         miregex_tbl = tbl;
153
154         /*_D("added regex - %d %s %s##",getpid(),tbl->mimetype,tbl->regex);*/
155
156         return 0;
157 }
158
159 static int __need_update_miregex_tbl()
160 {
161         struct stat st;
162
163         if (stat(MIREGEX_DIR, &st) < 0) {
164                 _E("stat error - check miregex dir - %s", MIREGEX_DIR);
165                 return 1;
166         }
167
168         if (st.st_mtime != miregex_mtime) {
169                 miregex_mtime = st.st_mtime;
170                 return 1;
171         }
172
173         if (miregex_tbl == NULL) {
174                 miregex_mtime = st.st_mtime;
175                 return 1;
176         }
177
178         return 0;
179 }
180
181 static void __miregex_free_regex_table()
182 {
183         regex_tbl *tbl;
184
185         while (miregex_tbl) {
186                 if (miregex_tbl->mimetype != NULL)
187                         free(miregex_tbl->mimetype);
188                 if (miregex_tbl->regex != NULL)
189                         free(miregex_tbl->regex);
190                 if (miregex_tbl->desc != NULL)
191                         free(miregex_tbl->desc);
192                 regfree(&(miregex_tbl->regex_preg));
193
194                 tbl = miregex_tbl;
195                 miregex_tbl = miregex_tbl->next;
196                 free(tbl);
197         }
198
199         miregex_tbl = NULL;
200 }
201
202 regex_tbl *miregex_get_regex_table()
203 {
204         DIR *dp;
205         struct dirent *dentry;
206         char buf[MAX_LOCAL_BUFSZ];
207         miregex_file_info *info;
208
209         if (!__need_update_miregex_tbl())
210                 return miregex_tbl;
211
212         _D("*** reload miregex tbl ***");
213
214         if (miregex_tbl != NULL)
215                 __miregex_free_regex_table();
216
217         dp = opendir(MIREGEX_DIR);
218         if (dp == NULL)
219                 return NULL;
220
221         while ((dentry = readdir(dp)) != NULL) {
222                 if (dentry->d_name[0] == '.')
223                         continue;
224
225                 snprintf(buf, sizeof(buf), "%s/%s", MIREGEX_DIR,
226                          dentry->d_name);
227                 info = __get_miregex_file_info(buf);
228                 if (info == NULL)
229                         continue;
230
231                 if (__add_miregex(dentry->d_name, 
232                         info->regex, info->desc) < 0) {
233                         /* TODO : invalid regular expression - will be removed*/
234                 }
235
236                 __free_miregex_file_info(info);
237         }
238
239         closedir(dp);
240
241         return miregex_tbl;
242 }
243