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.
23 /******************************************************************************
24 * File : email-core-mm_callbacks.c
25 * Desc : mm_callbacks for IMAP-2004g
30 * 2006.08.22 : created
31 *****************************************************************************/
35 #include "email-internal-types.h"
37 #include "email-core-global.h"
38 #include "email-core-utils.h"
39 #include "email-debug-log.h"
40 #include "email-core-mailbox.h"
41 #include "email-core-account.h"
43 static void mm_get_error(char *string, int *err_code);
47 * get subscribed mailbox list
49 INTERNAL_FUNC void mm_lsub(MAILSTREAM *stream, int delimiter, char *mailbox, long attributes)
51 EM_DEBUG_FUNC_BEGIN();
52 email_callback_holder_t *p_holder = (email_callback_holder_t *)stream->sparep;
53 email_mailbox_t *p, *p_old = p_holder->data;
54 int count = p_holder->num;
57 /* memory allocation */
58 p = realloc(p_old, sizeof(email_mailbox_t) * (count + 1));
61 /* uw-imap mailbox name format (ex : "{mail.test.com...}inbox" or "{mail.test.com...}anybox/anysubbox") */
62 enc_path = strchr(mailbox, '}');
66 emcore_free_mailbox_list(&p, count+1);
70 /* Convert UTF7 mailbox name to UTF8 mailbox name */
72 /* convert directory delimiter to '/' */
73 for (s = enc_path; *s; s++) {
74 if (*s == (char)delimiter)
79 p[count].mailbox_name = cpystr(enc_path);
80 p[count].alias = cpystr(enc_path);
82 p[count].account_id = stream->spare8;
88 /* ignore attributes */
89 /* if (attributes & latt_noinferiors) fputs (", no inferiors", fp_log); */
90 /* if (attributes & latt_noselect) fputs (", no select", fp_log); */
91 /* if (attributes & latt_marked) fputs (", marked", fp_log); */
92 /* if (attributes & latt_unmarked) fputs (", unmarked", fp_log); */
101 INTERNAL_FUNC void mm_list(MAILSTREAM *stream, int delimiter, char *mailbox, long attributes)
103 EM_DEBUG_FUNC_BEGIN();
104 email_callback_holder_t *p_holder = (email_callback_holder_t *)stream->sparep;
105 email_internal_mailbox_t *p, *p_old = p_holder->data;
106 int count = p_holder->num;
109 /* memory allocation */
110 p = realloc(p_old, sizeof(email_internal_mailbox_t) * (count + 1));
113 /* uw-imap mailbox name format (ex : "{mail.test.com...}inbox" or "{mail.test.com...}anybox/anysubbox") */
114 enc_path = strchr(mailbox, '}');
118 emcore_free_internal_mailbox(&p, count+1, NULL);
122 /* convert directory delimiter to '/' */
123 for (s = enc_path; *s; s++)
124 if (*s == (char)delimiter)
128 memset(p + count, 0x00, sizeof(email_internal_mailbox_t));
130 #ifdef __FEATURE_XLIST_SUPPORT__
131 if (attributes & LATT_XLIST_INBOX)
132 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_INBOX;
133 else if (attributes & LATT_XLIST_ALL)
134 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_ALL_EMAILS;
135 else if (attributes & LATT_XLIST_DRAFTS)
136 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_DRAFT;
137 else if (attributes & LATT_XLIST_SENT)
138 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_SENTBOX;
139 else if (attributes & LATT_XLIST_JUNK)
140 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_SPAMBOX;
141 else if (attributes & LATT_XLIST_FLAGGED)
142 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_USER_DEFINED; //EMAIL_MAILBOX_TYPE_FLAGGED; P141122-00523 sync starred folder as Inbox sync
143 else if (attributes & LATT_XLIST_TRASH)
144 p[count].mailbox_type = EMAIL_MAILBOX_TYPE_TRASH;
145 #endif /* __FEATURE_XLIST_SUPPORT__ */
147 if (attributes & LATT_NOSELECT)
148 p[count].no_select = true;
150 if (p[count].mailbox_type == EMAIL_MAILBOX_TYPE_INBOX) /* For exception handling of Gmail inbox*/
151 p[count].mailbox_name = cpystr("INBOX");
153 p[count].mailbox_name = cpystr(enc_path);
155 EM_DEBUG_LOG_SEC("mailbox name [%s] mailbox_type [%d] no_select [%d]", p[count].mailbox_name, p[count].mailbox_type, p[count].no_select);
157 p[count].alias = emcore_get_alias_of_mailbox((const char *)enc_path);
160 EM_DEBUG_LOG("mm_list account_id %d", stream->spare8);
163 /* in mailbox name parse n get user = %d - which is account_id */
164 tmp = strstr(mailbox, "user=");
167 for (s = tmp; *s != '/' && *s != '}' && *s != '\0'; s++);
170 p[count].account_id = atoi(tmp);
172 EM_DEBUG_LOG("mm_list account_id %d ", p[count].account_id);
177 /* ignore attributes */
186 INTERNAL_FUNC void mm_status(MAILSTREAM *stream, char *mailbox, MAILSTATUS* status)
188 EM_DEBUG_FUNC_BEGIN();
189 email_callback_holder_t *p = stream->sparep;
191 EM_DEBUG_FUNC_BEGIN();
192 if (status->flags & SA_MESSAGES)
193 p->num = status->messages;
194 if (status->flags & SA_UNSEEN)
195 p->data = (void *)status->unseen;
200 * get user_name and password
203 INTERNAL_FUNC void mm_login(NETMBX *mb, char *user, char *pwd, long trial)
205 EM_DEBUG_FUNC_BEGIN();
207 email_account_t *ref_account = NULL;
208 char *username = NULL;
209 char *password = NULL;
211 char *save_ptr = NULL;
212 char *user_info = NULL;
214 char *multi_user_name = NULL;
217 EM_DEBUG_EXCEPTION("invalid account_id...");
221 user_info = EM_SAFE_STRDUP(mb->user);
223 token = strtok_r(user_info, TOKEN_FOR_MULTI_USER, &temp);
224 EM_DEBUG_LOG_SEC("Token : [%s], multi_user_name:[%s][%zu]", token, temp, EM_SAFE_STRLEN(temp));
225 account_id = atoi(token);
228 if (temp != NULL && EM_SAFE_STRLEN(temp) > 0)
229 multi_user_name = EM_SAFE_STRDUP(temp);
231 ref_account = emcore_get_account_reference(multi_user_name, account_id, true);
233 EM_DEBUG_EXCEPTION("emcore_get_account_reference failed");
237 if (ref_account->incoming_server_user_name == NULL) {
238 EM_DEBUG_EXCEPTION("invalid incoming_server_user_name...");
241 username = EM_SAFE_STRDUP(ref_account->incoming_server_user_name);
243 if (ref_account->incoming_server_password == NULL) {
244 EM_SAFE_FREE(username);
245 EM_DEBUG_EXCEPTION("Empty password");
249 EM_DEBUG_LOG("incoming_server_authentication_method [%d]", ref_account->incoming_server_authentication_method);
251 if (ref_account->incoming_server_authentication_method == EMAIL_AUTHENTICATION_METHOD_XOAUTH2) {
252 token = strtok_r(ref_account->incoming_server_password, "\001", &save_ptr);
253 EM_DEBUG_LOG_SEC("token [%s]", token);
254 password = EM_SAFE_STRDUP(token);
256 password = EM_SAFE_STRDUP(ref_account->incoming_server_password);
259 if (EM_SAFE_STRLEN(username) > 0 && EM_SAFE_STRLEN(password) > 0) {
260 EM_SAFE_STRNCPY(user, username, NETMAXUSER - EM_SAFE_STRLEN(user) - 1);
261 EM_SAFE_STRNCPY(pwd, password, MAILTMPLEN - EM_SAFE_STRLEN(pwd) - 1);
263 EM_DEBUG_EXCEPTION("User Information is NULL || EM_SAFE_STRLEN is 0 ");
268 emcore_free_account(ref_account);
269 EM_SAFE_FREE(ref_account);
272 EM_SAFE_FREE(user_info);
273 EM_SAFE_FREE(username);
274 EM_SAFE_FREE(password);
275 EM_SAFE_FREE(multi_user_name);
281 INTERNAL_FUNC void mm_dlog(char *string)
283 #ifdef FEATURE_CORE_DEBUG
284 EM_DEBUG_LOG("IMAP_TOOLKIT_DLOG [%s]", string);
288 INTERNAL_FUNC void mm_log(char *string, long errflg)
293 EM_DEBUG_LOG_SEC("IMAP_TOOLKIT_LOG [%s]", string);
297 EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG WARN [%s]", string);
301 EM_DEBUG_LOG("IMAP_TOOLKIT_LOG PARSE [%s]", string);
305 EM_DEBUG_LOG("IMAP_TOOLKIT_LOG BYE [%s]", string);
309 EM_DEBUG_LOG_SEC("IMAP_TOOLKIT_LOG TCPDEBUG [%s]", string);
313 email_session_t *session = NULL;
315 EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG ERROR [%s]", string);
317 emcore_get_current_session(&session);
320 mm_get_error(string, &session->error);
321 EM_DEBUG_EXCEPTION("IMAP_TOOLKIT_LOG ERROR [%d]", session->error);
322 if (session->error == EMAIL_ERROR_XOAUTH_BAD_REQUEST ||
323 session->error == EMAIL_ERROR_XOAUTH_INVALID_UNAUTHORIZED) {
324 session->network = session->error;
333 INTERNAL_FUNC void mm_searched(MAILSTREAM *stream, unsigned long number)
335 EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
339 INTERNAL_FUNC void mm_exists(MAILSTREAM *stream, unsigned long number)
341 EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
345 INTERNAL_FUNC void mm_expunged(MAILSTREAM *stream, unsigned long number)
347 EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
351 INTERNAL_FUNC void mm_flags(MAILSTREAM *stream, unsigned long number)
353 EM_DEBUG_FUNC_BEGIN("stream [%p], number [%d]", stream, number);
357 INTERNAL_FUNC void mm_notify(MAILSTREAM *stream, char *string, long errflg)
359 EM_DEBUG_FUNC_BEGIN();
360 #ifdef FEATURE_CORE_DEBUG
361 mm_log(string, errflg);
362 #endif /* FEATURE_CORE_DEBUG */
366 INTERNAL_FUNC void mm_critical(MAILSTREAM *stream)
368 EM_DEBUG_FUNC_BEGIN("stream [%p]", stream);
372 INTERNAL_FUNC void mm_nocritical(MAILSTREAM *stream)
374 EM_DEBUG_FUNC_BEGIN("stream [%p]", stream);
378 INTERNAL_FUNC long mm_diskerror(MAILSTREAM *stream, long errcode, long serious)
380 EM_DEBUG_FUNC_BEGIN("stream [%p] errcode[%d] serious[%d]", stream, errcode, serious);
382 kill(getpid(), SIGSTOP);
390 INTERNAL_FUNC void mm_fatal(char *string)
392 EM_DEBUG_EXCEPTION("%s", string);
395 INTERNAL_FUNC void mm_get_error(char *string, int *err_code)
397 if (!string || !err_code)
400 EM_DEBUG_LOG("string [%s]", string);
402 if (strstr(string, "login failure") || strstr(string, "Login aborted") || strstr(string, "Can't login"))
403 *err_code = EMAIL_ERROR_LOGIN_FAILURE;
404 else if (strstr(string, "Scan not valid"))
405 *err_code = EMAIL_ERROR_SCAN_NOT_SUPPORTED;
406 else if (strstr(string, "Authentication cancelled"))
407 *err_code = EMAIL_ERROR_AUTHENTICATE;
408 else if (strstr(string, "authuser"))
409 *err_code = EMAIL_ERROR_AUTH_NOT_SUPPORTED;
410 else if (strstr(string, "negotiate TLS"))
411 *err_code = EMAIL_ERROR_CANNOT_NEGOTIATE_TLS;
412 else if (strstr(string, "TLS/SSL failure"))
413 *err_code = EMAIL_ERROR_TLS_SSL_FAILURE;
414 else if (strstr(string, "STARTLS"))
415 *err_code = EMAIL_ERROR_STARTLS;
416 else if (strstr(string, "TLS unavailable"))
417 *err_code = EMAIL_ERROR_TLS_NOT_SUPPORTED;
418 else if (strstr(string, "Can't access"))
419 *err_code = EMAIL_ERROR_IMAP4_APPEND_FAILURE;
420 else if (strstr(string, "Can not authenticate"))
421 *err_code = EMAIL_ERROR_AUTHENTICATE;
422 else if (strstr(string, "Unexpected IMAP response") || strstr(string, "hello"))
423 *err_code = EMAIL_ERROR_INVALID_RESPONSE;
424 else if (strstr(string, "NOTIMAP4REV1"))
425 *err_code = EMAIL_ERROR_COMMAND_NOT_SUPPORTED;
426 else if (strstr(string, "Anonymous"))
427 *err_code = EMAIL_ERROR_ANNONYM_NOT_SUPPORTED;
428 else if (strstr(string, "connection broken"))
429 *err_code = EMAIL_ERROR_CONNECTION_BROKEN;
430 else if (strstr(string, "SMTP greeting"))
431 *err_code = EMAIL_ERROR_NO_RESPONSE;
432 else if (strstr(string, "ESMTP failure"))
433 *err_code = EMAIL_ERROR_SMTP_SEND_FAILURE;
434 else if (strstr(string, "socket") || strstr(string, "Socket"))
435 *err_code = EMAIL_ERROR_SOCKET_FAILURE;
436 else if (strstr(string, "connect to") || strstr(string, "Connection failed"))
437 *err_code = EMAIL_ERROR_CONNECTION_FAILURE;
438 else if (strstr(string, "Certificate failure"))
439 *err_code = EMAIL_ERROR_CERTIFICATE_FAILURE;
440 else if (strstr(string, "No such host"))
441 *err_code = EMAIL_ERROR_NO_SUCH_HOST;
442 else if (strstr(string, "host") || strstr(string, "Host"))
443 *err_code = EMAIL_ERROR_INVALID_SERVER;
444 else if (strstr(string, "SELECT failed"))
445 *err_code = EMAIL_ERROR_MAILBOX_NOT_FOUND;
446 else if (strstr(string, "15 minute"))
447 *err_code = EMAIL_ERROR_LOGIN_ALLOWED_EVERY_15_MINS;
448 else if (strstr(string, "\"status\":\"400"))
449 *err_code = EMAIL_ERROR_XOAUTH_BAD_REQUEST;
450 else if (strstr(string, "\"status\":\"401"))
451 *err_code = EMAIL_ERROR_XOAUTH_INVALID_UNAUTHORIZED;
452 else if (strstr(string, "ALREADYEXISTS"))
453 *err_code = EMAIL_ERROR_ALREADY_EXISTS;
455 *err_code = EMAIL_ERROR_UNKNOWN;
458 #ifdef __FEATURE_SUPPORT_IMAP_ID__
459 INTERNAL_FUNC void mm_imap_id(char **id_string)
461 EM_DEBUG_FUNC_BEGIN("id_string [%p]", id_string);
464 char *result_string = NULL;
465 char *tag_string = "ID (\"os\" \"" IMAP_ID_OS "\" \"os-version\" \"" IMAP_ID_OS_VERSION "\" \"vendor\" \"" IMAP_ID_VENDOR "\" \"device\" \"" IMAP_ID_DEVICE_NAME "\" \"AGUID\" \"" IMAP_ID_AGUID "\" \"ACLID\" \"" IMAP_ID_ACLID "\"";
469 if (id_string == NULL) {
470 EM_DEBUG_EXCEPTION("EMAIL_ERROR_INVALID_PARAM");
477 tag_length = EM_SAFE_STRLEN(tag_string);
478 result_string = EM_SAFE_STRDUP(tag_string);
480 if (result_string == NULL) {
481 EM_DEBUG_EXCEPTION("malloc failed");
485 *id_string = result_string;
490 #endif /* __FEATURE_SUPPORT_IMAP_ID__ */