void parse_primary_expression(void) { Token t = get_token(); if (t.type == T_OPEN_BRACKET) { parse_expression(); t = get_token(); if (t.type != T_CLOSE_BRACKET) { fprintf(stderr, "Syntax Error: Mismatch Bracket\n"); exit(-1); } } else { unget_token(); parse_split(); } }
static gint sieve_session_recv_msg(Session *session, const gchar *msg) { SieveSession *sieve_session = SIEVE_SESSION(session); SieveResult result; gint ret = SE_OK; log_print(LOG_PROTOCOL, "Sieve< %s\n", msg); if (response_is_bye(msg)) { gchar *status; parse_response((gchar *)msg, &result); if (!result.description) status = g_strdup(_("Disconnected")); else if (g_str_has_prefix(result.description, "Disconnected")) status = g_strdup(result.description); else status = g_strdup_printf(_("Disconnected: %s"), result.description); sieve_session->error = SE_ERROR; sieve_error(sieve_session, status); sieve_session->state = SIEVE_DISCONNECTED; g_free(status); return -1; } switch (sieve_session->state) { case SIEVE_CAPABILITIES: if (response_is_ok(msg)) { /* capabilities list done */ #ifdef USE_GNUTLS if (sieve_session->tls_init_done == FALSE && sieve_session->config->tls_type != SIEVE_TLS_NO) { if (sieve_session->capability.starttls) { log_print(LOG_PROTOCOL, "Sieve> STARTTLS\n"); session_send_msg(session, SESSION_SEND, "STARTTLS"); sieve_session->state = SIEVE_STARTTLS; } else if (sieve_session->config->tls_type == SIEVE_TLS_YES) { log_warning(LOG_PROTOCOL, "Sieve: does not support STARTTLS\n"); sieve_session->state = SIEVE_ERROR; } else { log_warning(LOG_PROTOCOL, "Sieve: continuing without TLS\n"); sieve_session->state = SIEVE_READY; } break; } #endif /* authenticate after getting capabilities */ if (!sieve_session->authenticated) { ret = sieve_auth(sieve_session); } else { sieve_session->state = SIEVE_READY; sieve_connected(sieve_session, TRUE); } } else { /* got a capability */ gchar *cap_name, *cap_value; parse_split((gchar *)msg, &cap_name, &cap_value); sieve_got_capability(sieve_session, cap_name, cap_value); } break; case SIEVE_READY: if (!msg[0]) break; log_warning(LOG_PROTOCOL, _("unhandled message on Sieve session: %s\n"), msg); break; case SIEVE_STARTTLS: #ifdef USE_GNUTLS if (session_start_tls(session) < 0) { sieve_session->state = SIEVE_ERROR; sieve_session->error = SE_ERROR; sieve_error(sieve_session, _("TLS failed")); return -1; } sieve_session->tls_init_done = TRUE; sieve_session->state = SIEVE_CAPABILITIES; #endif break; case SIEVE_AUTH: ret = sieve_auth_recv(sieve_session, msg); break; case SIEVE_AUTH_LOGIN_USER: ret = sieve_auth_login_user_recv(sieve_session, msg); break; case SIEVE_AUTH_PLAIN: case SIEVE_AUTH_LOGIN_PASS: case SIEVE_AUTH_CRAM_MD5: if (response_is_no(msg)) { log_print(LOG_PROTOCOL, "Sieve auth failed\n"); session->state = SIEVE_RETRY_AUTH; ret = SE_AUTHFAIL; } else if (response_is_ok(msg)) { log_print(LOG_PROTOCOL, "Sieve auth completed\n"); sieve_error(sieve_session, ""); sieve_session->authenticated = TRUE; sieve_session->state = SIEVE_READY; sieve_connected(sieve_session, TRUE); } break; case SIEVE_NOOP: if (!response_is_ok(msg)) { sieve_session->state = SIEVE_ERROR; } sieve_session->state = SIEVE_READY; break; case SIEVE_LISTSCRIPTS: if (response_is_no(msg)) { /* got an error. probably not authenticated. */ command_cb(sieve_session->current_cmd, NULL); sieve_session->state = SIEVE_READY; } else if (response_is_ok(msg)) { /* end of list */ sieve_session->state = SIEVE_READY; sieve_session->error = SE_OK; command_cb(sieve_session->current_cmd, (gpointer)&(SieveScript){0}); } else { /* got a script name */ SieveScript script; gchar *script_status; parse_split((gchar *)msg, &script.name, &script_status); script.active = (script_status && strcasecmp(script_status, "active") == 0); command_cb(sieve_session->current_cmd, (gpointer)&script); } break; case SIEVE_RENAMESCRIPT: if (response_is_no(msg)) { /* error */ command_cb(sieve_session->current_cmd, NULL); } else if (response_is_ok(msg)) { command_cb(sieve_session->current_cmd, (void*)TRUE); } else { log_warning(LOG_PROTOCOL, _("error occurred on SIEVE session\n")); } sieve_session->state = SIEVE_READY; break; case SIEVE_SETACTIVE: parse_response((gchar *)msg, &result); if (result.success) { /* clear status possibly set when setting another * script active. TODO: give textual feedback */ sieve_error(sieve_session, ""); command_cb(sieve_session->current_cmd, NULL); } else if (result.description) { command_cb(sieve_session->current_cmd, result.description); } else { log_warning(LOG_PROTOCOL, _("error occurred on SIEVE session\n")); } if (result.has_octets) { return sieve_session_recv_chunk(sieve_session, result.octets); } else { sieve_session->state = SIEVE_READY; } break; case SIEVE_GETSCRIPT: if (response_is_no(msg)) { command_cb(sieve_session->current_cmd, (void *)-1); sieve_session->state = SIEVE_READY; } else { parse_response((gchar *)msg, &result); sieve_session->state = SIEVE_GETSCRIPT_DATA; return sieve_session_recv_chunk(sieve_session, result.octets); } break; case SIEVE_GETSCRIPT_DATA: if (!msg[0]) break; sieve_session->state = SIEVE_READY; if (response_is_ok(msg)) { command_cb(sieve_session->current_cmd, NULL); } else if (msg[0]) { log_warning(LOG_PROTOCOL, _("error occurred on SIEVE session\n")); } break; case SIEVE_PUTSCRIPT: if (!msg[0]) break; parse_response((gchar *)msg, &result); sieve_session_putscript_cb(sieve_session, &result); if (result.has_octets) { return sieve_session_recv_chunk(sieve_session, result.octets); } else { sieve_session->state = SIEVE_READY; } break; case SIEVE_DELETESCRIPT: parse_response((gchar *)msg, &result); if (!result.success) { command_cb(sieve_session->current_cmd, result.description); } else { command_cb(sieve_session->current_cmd, NULL); } sieve_session->state = SIEVE_READY; break; case SIEVE_ERROR: log_warning(LOG_PROTOCOL, _("error occurred on Sieve session. data: %s\n"), msg); sieve_session->error = SE_ERROR; break; case SIEVE_RETRY_AUTH: log_warning(LOG_PROTOCOL, _("unhandled message on Sieve session: %s\n"), msg); ret = sieve_auth(sieve_session); break; default: log_warning(LOG_PROTOCOL, _("unhandled message on Sieve session: %d\n"), sieve_session->state); sieve_session->error = SE_ERROR; return -1; } if (ret == SE_OK && sieve_session->state == SIEVE_READY) ret = sieve_pop_send_queue(sieve_session); if (ret == SE_OK) { return session_recv_msg(session); } else if (ret == SE_AUTHFAIL) { sieve_error(sieve_session, _("Auth failed")); sieve_session->state = SIEVE_ERROR; sieve_session->error = SE_ERROR; } return 0; }