4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
\r
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
\r
8 * Licensed under the Apache License, Version 2.0 (the "License");
\r
9 * you may not use this file except in compliance with the License.
\r
10 * You may obtain a copy of the License at
\r
12 * http://www.apache.org/licenses/LICENSE-2.0
\r
14 * Unless required by applicable law or agreed to in writing, software
\r
15 * distributed under the License is distributed on an "AS IS" BASIS,
\r
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
\r
17 * See the License for the specific language governing permissions and
\r
18 * limitations under the License.
\r
25 * Created on: 2012. 3. 6.
\r
26 * Author: kyuho.jo@samsung.com
\r
33 #include <sys/time.h>
\r
34 #include <sys/vfs.h>
\r
37 #include <pthread.h>
\r
40 #include "c-client.h"
\r
42 #include "email-types.h"
\r
43 #include "email-internal-types.h"
\r
44 #include "email-utilities.h"
\r
46 INTERNAL_FUNC void* em_malloc(unsigned len)
\r
48 /* EM_DEBUG_LOG("Memory allocation size[%d] bytes", len); */
\r
52 EM_DEBUG_EXCEPTION("len should be positive.[%d]", len);
\r
59 memset(p, 0x00, len);
\r
61 EM_DEBUG_EXCEPTION("malloc failed");
\r
65 /* remove left space, tab, CR, L */
\r
66 INTERNAL_FUNC char *em_trim_left(char *str)
\r
68 char *p, *temp_buffer = NULL;
\r
70 /* EM_DEBUG_FUNC_BEGIN() */
\r
71 if (!str) return NULL;
\r
74 while (*p && (*p == ' ' || *p == '\t' || *p == LF || *p == CR)) p++;
\r
76 if (!*p) return NULL;
\r
78 temp_buffer = EM_SAFE_STRDUP(p);
\r
80 strncpy(str, temp_buffer, strlen(str));
\r
81 str[strlen(temp_buffer)] = NULL_CHAR;
\r
83 EM_SAFE_FREE(temp_buffer);
\r
88 /* remove right space, tab, CR, L */
\r
89 INTERNAL_FUNC char *em_trim_right(char *str)
\r
93 /* EM_DEBUG_FUNC_BEGIN() */
\r
94 if (!str) return NULL;
\r
96 p = str+strlen(str)-1;
\r
97 while (((int)p >= (int)str) && (*p == ' ' || *p == '\t' || *p == LF || *p == CR))
\r
100 if ((int) p < (int)str)
\r
106 INTERNAL_FUNC char* em_upper_string(char *str)
\r
116 INTERNAL_FUNC char* em_lower_string(char *str)
\r
126 INTERNAL_FUNC int em_upper_path(char *path)
\r
128 int i = 0, is_utf7 = 0, len = path ? (int)strlen(path) : -1;
\r
129 for (; i < len; i++) {
\r
130 if (path[i] == '&' || path[i] == 5) {
\r
135 if (path[i] == '-') is_utf7 = 0;
\r
138 path[i] = toupper(path[i]);
\r
146 INTERNAL_FUNC void em_skip_whitespace(char *addr_str, char **pAddr)
\r
148 EM_DEBUG_FUNC_BEGIN("addr_str[%p]", addr_str);
\r
152 char *str = addr_str;
\r
153 char ptr[strlen(str)+1] ;
\r
157 for (i = 0; str[i] != NULL_CHAR ; i++) {
\r
158 if (str[i] != SPACE && str[i] != TAB && str[i] != CR && str[i] != LF)
\r
161 ptr[j] = NULL_CHAR;
\r
163 *pAddr = EM_SAFE_STRDUP(ptr);
\r
164 EM_DEBUG_FUNC_END("ptr[%s]", ptr);
\r
167 INTERNAL_FUNC char* em_skip_whitespace_without_strdup(char *source_string)
\r
169 EM_DEBUG_FUNC_BEGIN("source_string[%p]", source_string);
\r
171 if (!source_string)
\r
175 for (i = 0; source_string[i] != NULL_CHAR ; i++) {
\r
176 if (source_string[i] != SPACE) /* || source_string[i] != TAB || source_string[i] != CR || source_string[i] || LF) */
\r
180 EM_DEBUG_FUNC_END("i[%d]", i);
\r
181 return source_string + i;
\r
184 INTERNAL_FUNC char* em_replace_string(char *source_string, char *old_string, char *new_string)
\r
186 EM_DEBUG_FUNC_BEGIN();
\r
187 char *result_buffer = NULL;
\r
189 int buffer_length = 0;
\r
191 EM_IF_NULL_RETURN_VALUE(source_string, NULL);
\r
192 EM_IF_NULL_RETURN_VALUE(old_string, NULL);
\r
193 EM_IF_NULL_RETURN_VALUE(new_string, NULL);
\r
195 p = strstr(source_string, old_string);
\r
198 EM_DEBUG_EXCEPTION("old_string not found in source_string");
\r
199 EM_DEBUG_FUNC_END("return NULL");
\r
203 buffer_length = strlen(source_string) + 1024;
\r
204 result_buffer = (char *)em_malloc(buffer_length);
\r
206 if (!result_buffer) {
\r
207 EM_DEBUG_EXCEPTION("em_malloc failed");
\r
211 strncpy(result_buffer, source_string, p - source_string);
\r
212 snprintf(result_buffer + strlen(result_buffer), buffer_length - strlen(result_buffer), "%s%s", new_string, p + strlen(old_string));
\r
214 EM_DEBUG_FUNC_END("result_buffer[%s]", result_buffer);
\r
215 return result_buffer;
\r
218 /* Memory clean up */
\r
219 #include <sys/mman.h>
\r
221 /* #define GETSP() ({ unsigned int sp; asm volatile ("mov %0, sp " : "=r"(sp)); sp;}) */
\r
222 #define BUF_SIZE 256
\r
223 #define PAGE_SIZE (1 << 12)
\r
224 #define _ALIGN_UP(addr, size) (((addr)+((size)-1))&(~((size)-1)))
\r
225 #define _ALIGN_DOWN(addr, size) ((addr)&(~((size)-1)))
\r
226 #define PAGE_ALIGN(addr) _ALIGN_DOWN(addr, PAGE_SIZE)
\r
228 int stack_trim(void)
\r
231 char buf[BUF_SIZE];
\r
233 unsigned int stacktop;
\r
237 asm volatile ("mov %0, sp " : "=r"(sp));
\r
239 sprintf(buf, "/proc/%d/maps", getpid());
\r
240 file = fopen(buf, "r");
\r
241 while (fgets(buf, BUF_SIZE, file) != NULL) {
\r
242 if (strstr(buf, "[stack]")) {
\r
251 sscanf(buf, "%x-", &stacktop);
\r
252 if (madvise((void *)PAGE_ALIGN(stacktop), PAGE_ALIGN(sp)-stacktop, MADV_DONTNEED) < 0)
\r
253 perror("stack madvise fail");
\r
259 INTERNAL_FUNC void em_flush_memory()
\r
261 EM_DEBUG_FUNC_BEGIN();
\r
262 /* flush memory in heap */
\r
265 /* flush memory in stack */
\r
268 /* flush memory for sqlite */
\r
269 emstorage_flush_db_cache();
\r
270 EM_DEBUG_FUNC_END();
\r
273 #define DATE_TIME_STRING_LEGNTH 14
\r
275 INTERNAL_FUNC char *em_get_extension_from_file_path(char *source_file_path, int *err_code)
\r
277 EM_DEBUG_FUNC_BEGIN("source_file_path[%s]", source_file_path);
\r
278 int err = EMF_ERROR_NONE, pos_on_string = 0;
\r
279 char *extension = NULL;
\r
281 if (!source_file_path) {
\r
282 EM_DEBUG_EXCEPTION("Invalid Parameter");
\r
283 err = EMF_ERROR_INVALID_PARAM;
\r
287 pos_on_string = strlen(source_file_path) - 1;
\r
289 while(pos_on_string > 0 && source_file_path[pos_on_string--] != '.') ;
\r
291 if(pos_on_string > 0)
\r
292 extension = source_file_path + pos_on_string + 2;
\r
294 EM_DEBUG_LOG("*extension [%s] pos_on_string [%d]", extension, pos_on_string);
\r
299 EM_DEBUG_FUNC_END();
\r
303 INTERNAL_FUNC int em_get_encoding_type_from_file_path(const char *input_file_path, char **output_encoding_type)
\r
305 EM_DEBUG_FUNC_BEGIN("input_file_path[%d], output_encoding_type[%p]", input_file_path, output_encoding_type);
\r
306 int err = EMF_ERROR_NONE;
\r
307 int pos_of_filename = 0;
\r
308 int pos_of_dot = 0;
\r
309 int enf_of_string = 0;
\r
310 int result_string_length = 0;
\r
311 char *filename = NULL;
\r
312 char *result_encoding_type = NULL;
\r
314 if (!input_file_path || !output_encoding_type) {
\r
315 EM_DEBUG_EXCEPTION("Invalid Parameter");
\r
316 err = EMF_ERROR_INVALID_PARAM;
\r
320 enf_of_string = pos_of_filename = strlen(input_file_path) - 1;
\r
322 while(pos_of_filename >= 0 && input_file_path[pos_of_filename--] != '/') {
\r
323 if(input_file_path[pos_of_filename] == '.')
\r
324 pos_of_dot = pos_of_filename;
\r
327 if(pos_of_filename != 0)
\r
328 pos_of_filename += 2;
\r
330 filename = (char*)input_file_path + pos_of_filename;
\r
332 if(pos_of_dot != 0 && pos_of_dot > pos_of_filename)
\r
333 result_string_length = pos_of_dot - pos_of_filename;
\r
335 result_string_length = enf_of_string - pos_of_filename;
\r
337 EM_DEBUG_LOG("pos_of_dot [%d], pos_of_filename [%d], enf_of_string[%d],result_string_length [%d]", pos_of_dot, pos_of_filename, enf_of_string, result_string_length);
\r
339 if( !(result_encoding_type = em_malloc(sizeof(char) * (result_string_length + 1))) ) {
\r
340 EM_DEBUG_EXCEPTION("EMF_ERROR_OUT_OF_MEMORY");
\r
341 err = EMF_ERROR_OUT_OF_MEMORY;
\r
345 memcpy(result_encoding_type, input_file_path + pos_of_filename, result_string_length);
\r
347 EM_DEBUG_LOG("*result_encoding_type [%s]", result_encoding_type);
\r
349 *output_encoding_type = result_encoding_type;
\r
352 EM_DEBUG_FUNC_END("err [%d]", err);
\r
356 INTERNAL_FUNC int em_get_content_type_from_extension_string(const char *extension_string, int *err_code)
\r
358 EM_DEBUG_FUNC_BEGIN("extension_string[%s]", extension_string);
\r
359 int i = 0, err = EMF_ERROR_NONE, result_content_type = TYPEAPPLICATION;
\r
360 char *image_extension[] = { "jpeg", "jpg", "png", "gif", "bmp", "pic", "agif", "tif", "wbmp" , NULL};
\r
362 if (!extension_string) {
\r
363 EM_DEBUG_EXCEPTION("Invalid Parameter");
\r
364 err = EMF_ERROR_INVALID_PARAM;
\r
368 while(image_extension[i]) {
\r
369 EM_DEBUG_LOG("image_extension[%d] [%s]", i, image_extension[i]);
\r
370 if(strcasecmp(image_extension[i], extension_string) == 0) {
\r
371 result_content_type = TYPEIMAGE;
\r
380 EM_DEBUG_FUNC_END();
\r
381 return result_content_type;
\r
384 #define EMAIL_ACCOUNT_RGEX "([a-z0-9!#$%&'*+/=?^_`{|}~-]+.)*[a-z0-9!#$%&'*+/=?^_`{|}~-]+"
\r
385 #define EMAIL_DOMAIN_RGEX "([a-z0-9!#$%&'*+/=?^_`{|}~-]+.)+[a-z0-9!#$%&'*+/=?^_`{|}~-]+"
\r
387 #define EMAIL_ADDR_RGEX "[[:space:]]*<"EMAIL_ACCOUNT_RGEX"@"EMAIL_DOMAIN_RGEX">[[:space:]]*"
\r
388 #define EMAIL_ALIAS_RGEX "([[:space:]]*\"[^\"]*\")?"EMAIL_ADDR_RGEX
\r
389 #define EMAIL_ALIAS_LIST_RGEX "^("EMAIL_ALIAS_RGEX"[;,])*"EMAIL_ALIAS_RGEX"[;,]?[[:space:]]*$"
\r
391 #define EMAIL_ADDR_WITHOUT_BRACKET_RGEX "[[:space:]]*"EMAIL_ACCOUNT_RGEX"@"EMAIL_DOMAIN_RGEX"[[:space:]]*"
\r
392 #define EMAIL_ALIAS_WITHOUT_BRACKET_RGEX "([[:space:]]*\"[^\"]*\")?"EMAIL_ADDR_WITHOUT_BRACKET_RGEX
\r
393 #define EMAIL_ALIAS_LIST_WITHOUT_BRACKET_RGEX "("EMAIL_ALIAS_WITHOUT_BRACKET_RGEX"[;,])*"EMAIL_ADDR_WITHOUT_BRACKET_RGEX"[;,]?[[:space:]]*$"
\r
395 INTERNAL_FUNC int em_verify_email_address(char *address, int without_bracket, int *err_code)
\r
397 EM_DEBUG_FUNC_BEGIN("address[%s] without_bracket[%d]", address, without_bracket);
\r
399 /* this following code verfies the email alias string using reg. exp. */
\r
400 regex_t alias_list_regex = {0};
\r
401 int ret = false, error = EMF_ERROR_NONE;
\r
402 char *reg_rule = NULL;
\r
404 if(!address || strlen(address) == 0) {
\r
405 EM_DEBUG_EXCEPTION("EMF_ERROR_INVALID_PARAM");
\r
407 *err_code = EMF_ERROR_INVALID_PARAM;
\r
411 if(without_bracket)
\r
412 reg_rule = EMAIL_ALIAS_LIST_WITHOUT_BRACKET_RGEX;
\r
414 reg_rule = EMAIL_ALIAS_LIST_RGEX;
\r
416 if (regcomp(&alias_list_regex, reg_rule, REG_ICASE | REG_EXTENDED)) {
\r
417 EM_DEBUG_EXCEPTION("email alias regex unrecognized");
\r
419 *err_code = EMF_ERROR_UNKNOWN;
\r
423 int alias_len = strlen(address) + 1;
\r
424 regmatch_t pmatch[alias_len];
\r
426 bzero(pmatch, alias_len);
\r
428 if (regexec(&alias_list_regex, address, alias_len, pmatch, 0) == REG_NOMATCH)
\r
429 EM_DEBUG_LOG("failed :[%s]", address);
\r
431 EM_DEBUG_LOG("success :[%s]", address);
\r
435 regfree(&alias_list_regex);
\r
440 EM_DEBUG_FUNC_END("ret [%d]", ret);
\r
444 INTERNAL_FUNC int em_verify_email_address_of_mail_data(emf_mail_data_t *mail_data, int without_bracket, int *err_code)
\r
446 EM_DEBUG_FUNC_BEGIN("mail_data[%p] without_bracket[%d]", mail_data, without_bracket);
\r
447 char *address_array[4] = { mail_data->full_address_from, mail_data->full_address_to, mail_data->full_address_cc, mail_data->full_address_bcc};
\r
448 int ret = false, err = EMF_ERROR_NONE, i;
\r
450 /* check for email_address validation */
\r
451 for (i = 0; i < 4; i++) {
\r
452 if (address_array[i] && address_array[i][0] != 0) {
\r
453 if (!em_verify_email_address(address_array[i] , without_bracket, &err)) {
\r
454 err = EMF_ERROR_INVALID_ADDRESS;
\r
455 EM_DEBUG_EXCEPTION("Invalid Email Address [%d][%s]", i, address_array[i]);
\r
462 EM_DEBUG_FUNC_END("ret [%d]", ret);
\r
466 INTERNAL_FUNC int em_verify_email_address_of_mail_tbl(emstorage_mail_tbl_t *input_mail_tbl, int input_without_bracket)
\r
468 EM_DEBUG_FUNC_BEGIN("input_mail_tbl[%p] input_without_bracket[%d]", input_mail_tbl, input_without_bracket);
\r
469 char *address_array[4] = { input_mail_tbl->full_address_to, input_mail_tbl->full_address_cc, input_mail_tbl->full_address_bcc, input_mail_tbl->full_address_from};
\r
470 int err = EMF_ERROR_NONE, i;
\r
472 /* check for email_address validation */
\r
473 for (i = 0; i < 4; i++) {
\r
474 if (address_array[i] && address_array[i][0] != 0) {
\r
475 if (!em_verify_email_address(address_array[i] , input_without_bracket, &err)) {
\r
476 err = EMF_ERROR_INVALID_ADDRESS;
\r
477 EM_DEBUG_EXCEPTION("Invalid Email Address [%d][%s]", i, address_array[i]);
\r
484 EM_DEBUG_FUNC_END("err [%d]", err);
\r
488 INTERNAL_FUNC int em_find_tag_for_thread_view(char *subject, int *result)
\r
490 EM_DEBUG_FUNC_BEGIN();
\r
491 int error_code = EMF_ERROR_NONE;
\r
492 char *copy_of_subject = NULL;
\r
494 EM_IF_NULL_RETURN_VALUE(subject, EMF_ERROR_INVALID_PARAM);
\r
495 EM_IF_NULL_RETURN_VALUE(result, EMF_ERROR_INVALID_PARAM);
\r
499 copy_of_subject = EM_SAFE_STRDUP(subject);
\r
501 if (copy_of_subject == NULL) {
\r
502 EM_DEBUG_EXCEPTION("strdup is failed.");
\r
506 em_upper_string(copy_of_subject);
\r
507 EM_DEBUG_LOG("em_upper_string result : %s\n", copy_of_subject);
\r
509 if (strstr(copy_of_subject, "RE:") == NULL) {
\r
510 if (strstr(copy_of_subject, "FWD:") == NULL) {
\r
511 if (strstr(copy_of_subject, "FW:") != NULL)
\r
521 EM_SAFE_FREE(copy_of_subject);
\r
523 EM_DEBUG_FUNC_END("result : %d", *result);
\r
528 INTERNAL_FUNC int em_find_pos_stripped_subject_for_thread_view(char *subject, char *stripped_subject)
\r
530 EM_DEBUG_FUNC_BEGIN();
\r
531 int error_code = EMF_ERROR_NONE;
\r
533 char *copy_of_subject = NULL, *curpos = NULL, *result;
\r
535 EM_IF_NULL_RETURN_VALUE(subject, EMF_ERROR_INVALID_PARAM);
\r
536 EM_IF_NULL_RETURN_VALUE(stripped_subject, EMF_ERROR_INVALID_PARAM);
\r
538 copy_of_subject = EM_SAFE_STRDUP(subject);
\r
540 if (copy_of_subject == NULL) {
\r
541 EM_DEBUG_EXCEPTION("strdup is failed");
\r
545 em_upper_string(copy_of_subject);
\r
546 curpos = copy_of_subject;
\r
548 EM_DEBUG_LOG("em_upper_string result : %s", copy_of_subject);
\r
550 while ((result = strstr(curpos, "RE:")) != NULL) {
\r
551 curpos = result + 3;
\r
552 EM_DEBUG_LOG("RE result : %s", curpos);
\r
555 while ((result = strstr(curpos, "FWD:")) != NULL) {
\r
556 curpos = result + 4;
\r
557 EM_DEBUG_LOG("FWD result : %s", curpos);
\r
560 while ((result = strstr(curpos, "FW:")) != NULL) {
\r
561 curpos = result + 3;
\r
562 EM_DEBUG_LOG("FW result : %s", curpos);
\r
565 while (curpos != NULL && *curpos == ' ') {
\r
569 gap = curpos - copy_of_subject;
\r
571 strcpy(stripped_subject, subject + gap);
\r
574 EM_SAFE_FREE(copy_of_subject);
\r
576 if (error_code == EMF_ERROR_NONE && stripped_subject)
\r
577 EM_DEBUG_LOG("result[%s]", stripped_subject);
\r
579 EM_DEBUG_FUNC_END("error_code[%d]", error_code);
\r
587 INTERNAL_FUNC int em_encode_base64(char *src, unsigned long src_len, char **enc, unsigned long* enc_len, int *err_code)
\r
589 EM_DEBUG_FUNC_BEGIN();
\r
591 unsigned char *content;
\r
592 int ret = true, err = EMF_ERROR_NONE;
\r
594 if (err_code != NULL) {
\r
595 *err_code = EMF_ERROR_NONE;
\r
598 content = rfc822_binary(src, src_len, enc_len);
\r
601 *enc = (char *)content;
\r
603 err = EMF_ERROR_UNKNOWN;
\r
610 EM_DEBUG_FUNC_END();
\r
617 INTERNAL_FUNC int em_decode_base64(unsigned char *enc_text, unsigned long enc_len, char **dec_text, unsigned long* dec_len, int *err_code)
\r
619 unsigned char *text = enc_text;
\r
620 unsigned long size = enc_len;
\r
621 unsigned char *content;
\r
622 int ret = true, err = EMF_ERROR_NONE;
\r
624 if (err_code != NULL) {
\r
625 *err_code = EMF_ERROR_NONE;
\r
628 EM_DEBUG_FUNC_BEGIN();
\r
630 content = rfc822_base64(text, size, dec_len);
\r
632 *dec_text = (char *)content;
\r
635 err = EMF_ERROR_UNKNOWN;
\r