4 * Copyright (c) 2012 - 2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Kyuho Jo <kyuho.jo@samsung.com>, Sunghyun Kwon <sh0701.kwon@samsung.com>
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
12 * http://www.apache.org/licenses/LICENSE-2.0
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.
24 * This file contains functionality related to IMAP IDLE.
25 * to interact with email-service.
26 * @file em_core-imap-idle.c
29 * @brief This file contains functionality to provide IMAP IDLE support in email-service.
32 #include <email-internal-types.h>
34 #ifdef __FEATURE_IMAP_IDLE__
36 #include <openssl/ssl.h>
38 #include <sys/epoll.h>
40 #include "email-core-imap-idle.h"
41 #include "email-debug-log.h"
42 #include "email-storage.h"
43 #include "email-network.h"
44 #include "email-core-utils.h"
45 #include "email-core-mailbox.h"
46 #include "email-core-event.h"
47 #include "email-core-account.h"
48 #include "email-core-alarm.h"
49 #include "email-utilities.h"
50 #include "email-core-container.h"
52 /*Definitions copied temporarily from ssl_unix.c */
53 #define SSLBUFLEN 8192
54 #define MAX_EPOLL_EVENT 100
56 typedef struct ssl_stream {
57 TCPSTREAM *tcpstream; /* TCP stream */
58 SSL_CTX *context; /* SSL context */
59 SSL *con; /* SSL connection */
60 int ictr; /* input counter */
61 char *iptr; /* input pointer */
62 char ibuf[SSLBUFLEN]; /* input buffer */
64 /*Definitions copied temporarily from ssl_unix.c - end*/
66 typedef struct _email_imap_idle_connection_info_t {
69 MAILSTREAM *mail_stream;
71 char *multi_user_name;
72 } email_imap_idle_connection_info_t;
74 int imap_idle_pipe_fd[2];
75 thread_t imap_idle_thread_id;
77 static int emcore_get_connection_info_by_socket_fd(GList *input_imap_idle_task_list,
79 email_imap_idle_connection_info_t **output_connection_info)
81 EM_DEBUG_FUNC_BEGIN("input_imap_idle_task_list[%p] input_socket_fd[%d] output_connection_info[%p]",
82 input_imap_idle_task_list, input_socket_fd, output_connection_info);
83 int err = EMAIL_ERROR_NONE;
84 email_imap_idle_connection_info_t *connection_info = NULL;
87 if (input_imap_idle_task_list == NULL || output_connection_info == NULL) {
88 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
89 err = EMAIL_ERROR_INVALID_PARAM;
93 index = g_list_first(input_imap_idle_task_list);
96 connection_info = index->data;
97 if (connection_info && connection_info->socket_fd == input_socket_fd) {
100 index = g_list_next(index);
104 *output_connection_info = connection_info;
106 err = EMAIL_ERROR_DATA_NOT_FOUND;
110 EM_DEBUG_FUNC_END("err [%d]", err);
114 static int emcore_clear_old_connections(int input_epoll_fd, GList **input_imap_idle_task_list)
116 EM_DEBUG_FUNC_BEGIN("input_epoll_fd[%d] input_imap_idle_task_list[%p]", input_epoll_fd, input_imap_idle_task_list);
118 int err = EMAIL_ERROR_NONE;
119 email_imap_idle_connection_info_t *connection_info = NULL;
120 struct epoll_event ev = {0};
122 char errno_buf[ERRNO_BUF_SIZE] = {0};
124 if (input_imap_idle_task_list == NULL) {
125 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
126 err = EMAIL_ERROR_INVALID_PARAM;
130 index = *input_imap_idle_task_list;
133 connection_info = index->data;
134 if (connection_info) {
135 /* Removes all fd from epoll_fd */
137 ev.data.fd = connection_info->socket_fd;
139 if (epoll_ctl(input_epoll_fd, EPOLL_CTL_DEL, connection_info->socket_fd, &ev) == -1) {
140 EM_DEBUG_LOG("epoll_ctl failed: %s[%d]", EM_STRERROR(errno_buf), errno);
143 /* Close connection */
144 if (connection_info->mail_stream)
145 connection_info->mail_stream = mail_close(connection_info->mail_stream);
147 g_free(connection_info->multi_user_name);
148 g_free(connection_info);
151 EM_DEBUG_LOG("Delete the index list");
152 *input_imap_idle_task_list = g_list_delete_link(*input_imap_idle_task_list, index);
153 index = *input_imap_idle_task_list;
156 *input_imap_idle_task_list = NULL;
160 EM_DEBUG_FUNC_END("err [%d]", err);
164 static int emcore_imap_idle_insert_sync_event(char *multi_user_name,
165 int input_account_id,
166 int input_mailbox_id,
169 EM_DEBUG_FUNC_BEGIN();
172 int err = EMAIL_ERROR_NONE;
174 email_event_t *event_data = NULL;
176 if (input_account_id <= 0) {
177 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
178 err = EMAIL_ERROR_INVALID_PARAM;
182 event_data = em_malloc(sizeof(email_event_t));
183 if (event_data == NULL) {
184 EM_DEBUG_EXCEPTION("em_mallocfailed");
185 err = EMAIL_ERROR_OUT_OF_MEMORY;
189 event_data->type = EMAIL_EVENT_SYNC_HEADER;
190 event_data->event_param_data_5 = input_mailbox_id;
191 event_data->account_id = input_account_id;
192 event_data->multi_user_name = EM_SAFE_STRDUP(multi_user_name);
194 if (!emcore_insert_event(event_data, &handle, &err)) {
195 EM_DEBUG_EXCEPTION("emcore_insert_event failed [%d]", err);
203 if (ret == false && event_data) {
204 emcore_free_event(event_data);
205 EM_SAFE_FREE(event_data);
211 EM_DEBUG_FUNC_END("ret [%d]", ret);
215 static int emcore_parse_imap_idle_response(char *multi_user_name,
216 int input_account_id,
217 int input_mailbox_id,
218 MAILSTREAM *input_mailstream,
221 EM_DEBUG_FUNC_BEGIN("input_account_id[%d] input_mailbox_id [%d] input_mailstream[%p] input_socket_fd[%d]",
222 input_account_id, input_mailbox_id, input_mailstream, input_socket_fd);
224 int err = EMAIL_ERROR_NONE;
226 IMAPLOCAL *imap_local = NULL;
228 if (!input_mailstream) {
229 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
230 err = EMAIL_ERROR_INVALID_PARAM;
234 imap_local = input_mailstream->local;
237 EM_DEBUG_EXCEPTION("imap_local is NULL");
238 err = EMAIL_ERROR_INVALID_PARAM;
242 while (imap_local->netstream) {
243 p = net_getline(imap_local->netstream);
244 if (p && !strncmp(p, "*", 1)) {
245 EM_DEBUG_LOG("p is [%s]", p);
246 if (p+1 && p+2 && p+3 && p+4 && !strncmp(p+2, "BYE", 3)) {
247 EM_DEBUG_LOG("BYE connection from server");
249 err = EMAIL_ERROR_IMAP4_IDLE_FAILURE;
252 if (strstr(p, "EXIST") != NULL) {
253 if (!emcore_imap_idle_insert_sync_event(multi_user_name, input_account_id, input_mailbox_id, &err))
254 EM_DEBUG_EXCEPTION_SEC("Syncing mailbox[%d] failed with err_code [%d]", input_mailbox_id, err);
259 EM_DEBUG_LOG("Skipped this message");
264 } else if (p && (!strncmp(p, "+", 1))) {
265 /* Bad response from server */
266 EM_DEBUG_LOG("p is [%s]", p);
270 EM_DEBUG_LOG("In else part");
277 EM_DEBUG_FUNC_END("err [%d]", err);
281 /* connects to given mailbox. send idle and returns socket id */
282 static int emcore_connect_and_idle_on_mailbox(char *multi_user_name,
283 GList **input_connection_list,
284 email_account_t *input_account,
285 email_mailbox_t *input_mailbox,
286 MAILSTREAM **output_mailstream,
287 int *output_socket_fd)
289 EM_DEBUG_FUNC_BEGIN("input_connection_list [%p] input_account [%p] input_mailbox[%p] "
290 "output_mailstream [%p] output_socket_fd [%p]",
291 input_connection_list, input_account, input_mailbox, output_mailstream, output_socket_fd);
293 void *mail_stream = NULL;
294 char cmd[128] = { 0, };
295 char tag[32] = { 0, };
298 int err = EMAIL_ERROR_NONE;
299 email_session_t *session = NULL;
300 IMAPLOCAL *imap_local = NULL;
301 NETSTREAM *net_stream = NULL;
302 TCPSTREAM *tcp_stream = NULL;
303 GList *imap_idle_connection_list = NULL;
304 email_imap_idle_connection_info_t *connection_info = NULL;
306 if (input_connection_list == NULL || input_account == NULL || input_mailbox == NULL ||
307 output_mailstream == NULL || output_socket_fd == NULL) {
308 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
309 err = EMAIL_ERROR_INVALID_PARAM;
313 imap_idle_connection_list = *input_connection_list;
315 if (!emcore_get_empty_session(&session))
316 EM_DEBUG_EXCEPTION("emcore_get_empty_session failed...");
318 /* Open connection to mailbox */
319 if (!emcore_connect_to_remote_mailbox(multi_user_name,
320 input_mailbox->account_id,
321 input_mailbox->mailbox_id,
323 (void **)&mail_stream,
324 &err) || !mail_stream) {
325 EM_DEBUG_EXCEPTION("emcore_connect_to_remote_mailbox failed [%d]", err);
329 imap_local = ((MAILSTREAM *)mail_stream)->local;
330 net_stream = imap_local->netstream;
332 /* check if ssl option is enabled on this account - shasikala.p */
333 if (input_account->incoming_server_secure_connection) {
334 SSLSTREAM *ssl_stream = net_stream->stream;
335 tcp_stream = ssl_stream->tcpstream;
337 tcp_stream = net_stream->stream;
340 socket_fd = ((TCPSTREAM *)tcp_stream)->tcpsi;
342 snprintf(tag, sizeof(tag), "%08lx", 0xffffffff & (((MAILSTREAM *)mail_stream)->gensym++));
343 snprintf(cmd, sizeof(cmd), "%s IDLE\015\012", tag);
345 /* Send IDLE command */
346 if (!imap_local->netstream || !net_sout(imap_local->netstream, cmd, (int)EM_SAFE_STRLEN(cmd))) {
347 EM_DEBUG_EXCEPTION("network error - failed to IDLE on Mailbox - [%d]", input_mailbox->mailbox_id);
348 err = EMAIL_ERROR_IMAP4_IDLE_FAILURE;
352 /* Get the response for IDLE command */
353 while (imap_local->netstream) {
354 p = net_getline(imap_local->netstream);
356 EM_DEBUG_LOG("IDLE command response: [%s]", p);
358 if (p && '+' == *p) {
359 EM_DEBUG_LOG("OK. Go.");
361 } else if (p && '*' == *p) {
365 EM_DEBUG_EXCEPTION("Unsuspected response: [%s]", p);
366 err = EMAIL_ERROR_IMAP4_IDLE_FAILURE;
373 if (err == EMAIL_ERROR_NONE) {
374 connection_info = em_malloc(sizeof(email_imap_idle_connection_info_t));
375 if (connection_info == NULL) {
376 EM_DEBUG_EXCEPTION("EMAIL_ERROR_OUT_OF_MEMORY");
377 err = EMAIL_ERROR_OUT_OF_MEMORY;
381 connection_info->account_id = input_account->account_id;
382 connection_info->mailbox_id = input_mailbox->mailbox_id;
383 connection_info->mail_stream = mail_stream;
384 connection_info->socket_fd = socket_fd;
385 connection_info->multi_user_name = EM_SAFE_STRDUP(multi_user_name);
387 imap_idle_connection_list = g_list_append(imap_idle_connection_list, (gpointer)connection_info);
392 if (err == EMAIL_ERROR_NONE) {
393 /* IMAP IDLE - SUCCESS */
394 // *output_mailstream = mail_stream;
395 *output_socket_fd = socket_fd;
396 *input_connection_list = imap_idle_connection_list;
397 } else if (mail_stream)
398 mail_stream = mail_close(mail_stream);
400 emcore_clear_session(session);
402 EM_DEBUG_FUNC_END("err [%d]", err);
406 static int emcore_imap_idle_cb(email_alarm_data_t *alarm_data, void *user_parameter)
408 EM_DEBUG_FUNC_BEGIN("alarm_data [%p] user_parameter [%p]", alarm_data, user_parameter);
409 int err = EMAIL_ERROR_NONE;
411 emcore_refresh_imap_idle_thread();
413 EM_DEBUG_FUNC_END("err [%d]", err);
417 static int emcore_refresh_alarm_for_imap_idle(char *multi_user_name)
419 EM_DEBUG_FUNC_BEGIN();
420 int err = EMAIL_ERROR_NONE;
422 int account_count = 0;
423 int auto_sync_account_count = 0;
425 time_t trigger_at_time;
426 email_account_t *account_ref_list = NULL;
428 /* Check whether the alarm is already existing */
429 if (emcore_check_alarm_by_class_id(EMAIL_ALARM_CLASS_IMAP_IDLE) == EMAIL_ERROR_NONE) {
430 EM_DEBUG_LOG("Already exist. Remove old one.");
431 emcore_delete_alram_data_by_reference_id(EMAIL_ALARM_CLASS_IMAP_IDLE, 0);
434 if ((err = emcore_get_account_reference_list(multi_user_name,
436 &account_count)) != EMAIL_ERROR_NONE) {
437 EM_DEBUG_LOG("emcore_get_account_reference_list failed [%d]", err);
441 for (i = 0; i < account_count; i++) {
442 if (account_ref_list[i].incoming_server_type == EMAIL_SERVER_TYPE_IMAP4 &&
443 (account_ref_list[i].check_interval == 0 || account_ref_list[i].peak_interval == 0)) {
444 auto_sync_account_count++;
448 if (account_ref_list)
449 emcore_free_account_list(&account_ref_list, account_count, NULL);
451 if (auto_sync_account_count) {
453 trigger_at_time = current_time + (29 * 60);
455 if ((err = emcore_add_alarm(multi_user_name,
457 EMAIL_ALARM_CLASS_IMAP_IDLE,
460 NULL)) != EMAIL_ERROR_NONE) {
461 EM_DEBUG_EXCEPTION("emcore_add_alarm failed [%d]", err);
467 EM_DEBUG_FUNC_END("err [%d]", err);
471 void* emcore_imap_idle_worker(void* thread_user_data)
473 EM_DEBUG_FUNC_BEGIN();
474 int err = EMAIL_ERROR_NONE;
479 int signal_from_pipe = 0;
480 int refresh_connection_flag = 1;
481 int account_count = 0;
482 char errno_buf[ERRNO_BUF_SIZE] = {0};
483 struct epoll_event ev = {0};
484 struct epoll_event events[MAX_EPOLL_EVENT] = {{0}, };
485 MAILSTREAM *mail_stream = NULL;
486 email_mailbox_t inbox_mailbox = {0};
487 email_account_t *account_ref_list = NULL;
488 GList *imap_idle_connection_list = NULL;
489 GList *zone_name_list = NULL;
491 email_imap_idle_connection_info_t *connection_info = NULL;
493 EM_DEBUG_LOG("emcore_imap_idle_worker start ");
495 if (pipe(imap_idle_pipe_fd) == -1) {
496 EM_DEBUG_EXCEPTION("pipe failed");
497 err = EMAIL_ERROR_UNKNOWN;
501 epoll_fd = epoll_create(MAX_EPOLL_EVENT);
504 EM_DEBUG_CRITICAL_EXCEPTION("epoll_create failed: [%d]", errno);
505 err = EMAIL_ERROR_IMAP4_IDLE_FAILURE;
510 ev.data.fd = imap_idle_pipe_fd[0];
512 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, imap_idle_pipe_fd[0], &ev) == -1) {
513 EM_DEBUG_EXCEPTION("epoll_ctl failed: %s[%d]", EM_STRERROR(errno_buf), errno);
516 EM_DEBUG_LOG("Enter imap idle loop");
518 if (refresh_connection_flag) {
520 EM_DEBUG_LOG("Clear old connections");
521 emcore_clear_old_connections(epoll_fd, &imap_idle_connection_list);
523 EM_DEBUG_LOG("Getting account list");
524 if ((err = emcore_get_zone_name_list(&zone_name_list)) != EMAIL_ERROR_NONE) {
525 EM_DEBUG_EXCEPTION("emcore_get_zone_name_list failed : err[%d]", err);
526 if (zone_name_list) g_list_free(zone_name_list);
530 if (g_list_length(zone_name_list) <= 1) {
531 if ((err = emcore_get_account_reference_list(NULL,
533 &account_count)) != EMAIL_ERROR_NONE)
534 EM_DEBUG_LOG("emcore_get_account_reference_list failed [%d]", err);
536 for (i = 0; i < account_count; i++) {
537 if (account_ref_list[i].incoming_server_type != EMAIL_SERVER_TYPE_IMAP4 ||
538 (account_ref_list[i].check_interval != 0 && account_ref_list[i].peak_interval != 0)) {
539 EM_DEBUG_LOG("account_id[%d] is not for auto sync", account_ref_list[i].account_id);
543 /* TODO: peak schedule handling */
545 memset(&inbox_mailbox, 0, sizeof(email_mailbox_t));
547 if (!emcore_get_mailbox_by_type(NULL,
548 account_ref_list[i].account_id,
549 EMAIL_MAILBOX_TYPE_INBOX,
552 EM_DEBUG_EXCEPTION("emcore_get_mailbox_by_type failed [%d]", err);
556 EM_DEBUG_LOG("Connect to IMAP server");
557 err = emcore_connect_and_idle_on_mailbox(NULL,
558 &imap_idle_connection_list,
559 &(account_ref_list[i]),
564 emcore_free_mailbox(&inbox_mailbox);
566 if (err != EMAIL_ERROR_NONE) {
567 EM_DEBUG_EXCEPTION("emcore_connect_and_idle_on_mailbox failed [%d]", err);
572 ev.data.fd = socket_fd;
574 EM_DEBUG_LOG("Add listener for socket buffer");
575 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &ev) == -1) {
576 EM_DEBUG_EXCEPTION("epoll_ctl failed: %s[%d]", EM_STRERROR(errno_buf), errno);
580 if (account_ref_list)
581 emcore_free_account_list(&account_ref_list, account_count, NULL);
583 EM_DEBUG_LOG(" Delete old an alarm and add an alarm to refresh connections every 29min");
584 emcore_refresh_alarm_for_imap_idle(NULL);
586 refresh_connection_flag = 0;
588 node = g_list_first(zone_name_list);
590 while (node != NULL) {
592 node = g_list_next(node);
594 EM_DEBUG_LOG("Data name of node : [%p]", node->data);
596 if ((err = emcore_get_account_reference_list(node->data,
598 &account_count)) != EMAIL_ERROR_NONE) {
599 EM_DEBUG_LOG("emcore_get_account_reference_list failed [%d]", err);
602 for (i = 0; i < account_count; i++) {
603 if (account_ref_list[i].incoming_server_type != EMAIL_SERVER_TYPE_IMAP4 ||
604 (account_ref_list[i].check_interval != 0 && account_ref_list[i].peak_interval != 0)) {
605 EM_DEBUG_LOG("account_id[%d] is not for auto sync", account_ref_list[i].account_id);
609 /* TODO: peak schedule handling */
611 memset(&inbox_mailbox, 0, sizeof(email_mailbox_t));
613 if (!emcore_get_mailbox_by_type(node->data,
614 account_ref_list[i].account_id,
615 EMAIL_MAILBOX_TYPE_INBOX,
618 EM_DEBUG_EXCEPTION("emcore_get_mailbox_by_type failed [%d]", err);
622 EM_DEBUG_LOG("Connect to IMAP server");
623 err = emcore_connect_and_idle_on_mailbox(node->data,
624 &imap_idle_connection_list,
625 &(account_ref_list[i]),
630 emcore_free_mailbox(&inbox_mailbox);
632 if (err != EMAIL_ERROR_NONE) {
633 EM_DEBUG_EXCEPTION("emcore_connect_and_idle_on_mailbox failed [%d]", err);
638 ev.data.fd = socket_fd;
640 EM_DEBUG_LOG("Add listener for socket buffer");
641 if (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, socket_fd, &ev) == -1) {
642 EM_DEBUG_EXCEPTION("epoll_ctl failed: %s[%d]", EM_STRERROR(errno_buf), errno);
646 if (account_ref_list)
647 emcore_free_account_list(&account_ref_list, account_count, NULL);
649 EM_DEBUG_LOG(" Delete old an alarm and add an alarm to refresh connections every 29min");
650 emcore_refresh_alarm_for_imap_idle(node->data);
652 EM_SAFE_FREE(node->data);
653 node = g_list_next(node);
656 refresh_connection_flag = 0;
660 g_list_free(zone_name_list);
663 EM_DEBUG_LOG("Waiting.......");
664 event_num = epoll_wait(epoll_fd, events, MAX_EPOLL_EVENT, -1);
665 EM_DEBUG_LOG("epoll_wait returns [%d]", event_num);
668 EM_DEBUG_LOG(">>>> Data coming from socket or pipe ");
669 for (j = 0; j < event_num; j++) {
670 int event_fd = events[j].data.fd;
672 EM_DEBUG_LOG("event_fd [%d]", event_fd);
674 if (event_fd == imap_idle_pipe_fd[0]) {
675 EM_DEBUG_LOG(">>>> Data coming from pipe ");
676 if (read(imap_idle_pipe_fd[0], (void*)&signal_from_pipe, sizeof(signal_from_pipe)) != -1) {
677 EM_DEBUG_LOG("Refresh IMAP connections");
678 refresh_connection_flag = 1;
682 if ((err = emcore_get_connection_info_by_socket_fd(imap_idle_connection_list,
684 &connection_info)) != EMAIL_ERROR_NONE) {
685 EM_DEBUG_LOG("emcore_get_connection_info_by_socket_fd "
686 "couldn't find proper connection info. [%d]", err);
690 if ((err = emcore_parse_imap_idle_response(connection_info->multi_user_name,
691 connection_info->account_id,
692 connection_info->mailbox_id,
693 connection_info->mail_stream,
694 connection_info->socket_fd)) != EMAIL_ERROR_NONE) {
695 EM_DEBUG_EXCEPTION("emcore_parse_imap_idle_response failed. [%d] ", err);
696 refresh_connection_flag = 1;
697 // mail_stream = mail_close(mail_stream);
705 EM_DEBUG_LOG("Exit imap idle loop");
708 emcore_free_mailbox(&inbox_mailbox);
710 EM_DEBUG_LOG("Close pipes");
712 close(imap_idle_pipe_fd[0]);
713 close(imap_idle_pipe_fd[1]);
715 imap_idle_thread_id = 0;
717 EM_DEBUG_FUNC_END("err [%d]", err);
722 INTERNAL_FUNC int emcore_create_imap_idle_thread()
724 EM_DEBUG_FUNC_BEGIN();
725 int err = EMAIL_ERROR_NONE;
728 if (imap_idle_thread_id) {
729 EM_DEBUG_EXCEPTION("IMAP IDLE thread already exists.");
730 err = EMAIL_ERROR_ALREADY_EXISTS;
735 THREAD_CREATE(imap_idle_thread_id, emcore_imap_idle_worker, NULL, thread_error);
737 if (thread_error != 0) {
738 EM_DEBUG_EXCEPTION("cannot make IMAP IDLE thread...");
739 err = EMAIL_ERROR_UNKNOWN;
745 EM_DEBUG_FUNC_END("err [%d]", err);
749 INTERNAL_FUNC int emcore_refresh_imap_idle_thread()
751 EM_DEBUG_FUNC_BEGIN();
752 int err = EMAIL_ERROR_NONE;
755 write(imap_idle_pipe_fd[1], (char *)&signal, sizeof(signal));
757 EM_DEBUG_FUNC_END("err [%d]", err);
760 #endif /* __FEATURE_IMAP_IDLE__ */