static int mailimap_qresync_extension_parse(int calling_parser, mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { size_t cur_token; int r; cur_token = * indx; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_RESP_TEXT_CODE: { struct mailimap_qresync_resptextcode * resptextcode; struct mailimap_extension_data * ext_data; r = resp_text_code_parse(fd, buffer, parser_ctx, &cur_token, &resptextcode); if (r != MAILIMAP_NO_ERROR) return r; ext_data = mailimap_extension_data_new(&mailimap_extension_qresync, MAILIMAP_QRESYNC_TYPE_RESP_TEXT_CODE, resptextcode); if (ext_data == NULL) { mailimap_qresync_resptextcode_free(resptextcode); return MAILIMAP_ERROR_MEMORY; } * indx = cur_token; * result = ext_data; return MAILIMAP_NO_ERROR; } case MAILIMAP_EXTENDED_PARSER_RESPONSE_DATA: { struct mailimap_qresync_vanished * vanished; struct mailimap_extension_data * ext_data; r = vanished_parse(fd, buffer, parser_ctx, &cur_token, &vanished); if (r != MAILIMAP_NO_ERROR) return r; ext_data = mailimap_extension_data_new(&mailimap_extension_qresync, MAILIMAP_QRESYNC_TYPE_VANISHED, vanished); if (ext_data == NULL) { mailimap_qresync_vanished_free(vanished); return MAILIMAP_ERROR_MEMORY; } * indx = cur_token; * result = ext_data; return MAILIMAP_NO_ERROR; } } return MAILIMAP_ERROR_PARSE; }
/* this is the extension's initial parser. it switches on calling_parser and calls the corresponding actual parser. quota extends imap as follows: mailbox-data /= "*" SP quota_response CRLF / "*" SP quotaroot_response CRLF quota_response ::= "QUOTA" SP astring SP quota_list quotaroot_response ::= "QUOTAROOT" SP astring *(SP astring) quota_list ::= "(" #quota_resource ")" note that RFC2087 doesn't actually specify whether the responses augment mailbox-data or augment the cases in response-data; I have chosen to place them in mailbox-data (the difference is academic as the byte stream is identical in either case) */ int mailimap_quota_parse(int calling_parser, mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { int r; struct mailimap_quota_quota_data * quota_data = 0; struct mailimap_quota_quotaroot_data * quotaroot_data = 0; void * data; int type; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_MAILBOX_DATA: r = mailimap_quota_quota_response_parse(fd, buffer, indx, "a_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_QUOTA_TYPE_QUOTA_DATA; data = quota_data; } if (r == MAILIMAP_ERROR_PARSE) { r = mailimap_quota_quotaroot_response_parse(fd, buffer, indx, "aroot_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_QUOTA_TYPE_QUOTAROOT_DATA; data = quotaroot_data; } } if (r != MAILIMAP_NO_ERROR) { return r; } * result = mailimap_extension_data_new(&mailimap_extension_quota, type, data); if (*result == NULL) { if (quota_data) mailimap_quota_quota_data_free(quota_data); if (quotaroot_data) mailimap_quota_quotaroot_data_free(quotaroot_data); return MAILIMAP_ERROR_MEMORY; } break; default: /* return a MAILIMAP_ERROR_PARSE if the extension doesn't extend calling_parser. */ return MAILIMAP_ERROR_PARSE; break; } return MAILIMAP_NO_ERROR; }
static int mailimap_enable_extension_parse(int calling_parser, mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { int r; struct mailimap_capability_data * capabilities = NULL; struct mailimap_extension_data * ext_data; void * data; int type; size_t cur_token; cur_token = * indx; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_RESPONSE_DATA: r = mailimap_enable_parse(fd, buffer, &cur_token, &capabilities, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_ENABLE_TYPE_ENABLE; data = capabilities; } if (r != MAILIMAP_NO_ERROR) { return r; } ext_data = mailimap_extension_data_new(&mailimap_extension_enable, type, data); if (ext_data == NULL) { if (capabilities != NULL) mailimap_capability_data_free(capabilities); return MAILIMAP_ERROR_MEMORY; } * result = ext_data; * indx = cur_token; return MAILIMAP_NO_ERROR; default: /* return a MAILIMAP_ERROR_PARSE if the extension doesn't extend calling_parser. */ return MAILIMAP_ERROR_PARSE; } }
static int mailimap_xlist_extension_parse(int calling_parser, mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { int r; struct mailimap_mailbox_list * xlist_data = NULL; struct mailimap_extension_data * ext_data; void * data; int type; size_t cur_token; cur_token = * indx; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_RESPONSE_DATA: r = mailimap_mailbox_data_xlist_parse(fd, buffer, &cur_token, &xlist_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_XLIST_TYPE_XLIST; data = xlist_data; } if (r != MAILIMAP_NO_ERROR) { return r; } ext_data = mailimap_extension_data_new(&mailimap_extension_xlist, type, data); if (ext_data == NULL) { if (xlist_data != NULL) mailimap_mailbox_list_free(xlist_data); return MAILIMAP_ERROR_MEMORY; } * result = ext_data; * indx = cur_token; return MAILIMAP_NO_ERROR; default: /* return a MAILIMAP_ERROR_PARSE if the extension doesn't extend calling_parser. */ return MAILIMAP_ERROR_PARSE; } }
static int mailimap_sort_extension_parse(int calling_parser, mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { int r; clist * number_list = NULL; struct mailimap_extension_data * ext_data; void * data = NULL; size_t cur_token; cur_token = * indx; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_RESPONSE_DATA: case MAILIMAP_EXTENDED_PARSER_MAILBOX_DATA: r = mailimap_number_list_data_sort_parse(fd, buffer, &cur_token, &number_list, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { data = number_list; } if (r != MAILIMAP_NO_ERROR) { return r; } ext_data = mailimap_extension_data_new(&mailimap_extension_sort, MAILIMAP_SORT_TYPE_SORT, data); if (ext_data == NULL) { if (number_list != NULL) mailimap_mailbox_data_search_free(number_list); return MAILIMAP_ERROR_MEMORY; } * result = ext_data; * indx = cur_token; return MAILIMAP_NO_ERROR; default: /* return a MAILIMAP_ERROR_PARSE if the extension doesn't extend calling_parser. */ return MAILIMAP_ERROR_PARSE; } }
static int mailimap_xgmthrid_extension_parse(int calling_parser, mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { size_t cur_token; uint64_t thrid; uint64_t * data_thrid; struct mailimap_extension_data * ext_data; int r; cur_token = * indx; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_FETCH_DATA: r = fetch_data_xgmthrid_parse(fd, buffer, &cur_token, &thrid, progr_rate, progr_fun); if (r != MAILIMAP_NO_ERROR) return r; data_thrid = malloc(sizeof(* data_thrid)); if (data_thrid == NULL) { return MAILIMAP_ERROR_MEMORY; } * data_thrid = thrid; ext_data = mailimap_extension_data_new(&mailimap_extension_xgmthrid, MAILIMAP_XGMTHRID_TYPE_THRID, data_thrid); if (ext_data == NULL) { free(data_thrid); return MAILIMAP_ERROR_MEMORY; } * result = ext_data; * indx = cur_token; return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_PARSE; } }
static int mailimap_xgmlabels_extension_parse(int calling_parser, mailstream * fd, MMAPString * buffer, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { size_t cur_token; int type; struct mailimap_msg_att_xgmlabels * att; void * data; struct mailimap_extension_data * ext_data; int r; cur_token = * indx; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_FETCH_DATA: att = NULL; r = fetch_data_xgmlabels_parse(fd, buffer, &cur_token, &att); if (r != MAILIMAP_NO_ERROR) return r; type = MAILIMAP_XGMLABELS_TYPE_XGMLABELS; data = att; ext_data = mailimap_extension_data_new(&mailimap_extension_xgmlabels, type, data); if (ext_data == NULL) { if (att != NULL) mailimap_msg_att_xgmlabels_free(att); return MAILIMAP_ERROR_MEMORY; } * result = ext_data; * indx = cur_token; return MAILIMAP_NO_ERROR; default: return MAILIMAP_ERROR_PARSE; } }
static int mailimap_condstore_extension_parse(int calling_parser, mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { size_t cur_token; int r; cur_token = * indx; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_FETCH_DATA: { struct mailimap_condstore_fetch_mod_resp * fetch_data; struct mailimap_extension_data * ext_data; r = fetch_data_parse(fd, buffer, parser_ctx, &cur_token, &fetch_data); if (r != MAILIMAP_NO_ERROR) return r; ext_data = mailimap_extension_data_new(&mailimap_extension_condstore, MAILIMAP_CONDSTORE_TYPE_FETCH_DATA, fetch_data); if (ext_data == NULL) { mailimap_condstore_fetch_mod_resp_free(fetch_data); return MAILIMAP_ERROR_MEMORY; } * indx = cur_token; * result = ext_data; return MAILIMAP_NO_ERROR; } case MAILIMAP_EXTENDED_PARSER_RESP_TEXT_CODE: { struct mailimap_condstore_resptextcode * resptextcode; struct mailimap_extension_data * ext_data; r = resp_text_code_parse(fd, buffer, parser_ctx, &cur_token, &resptextcode); if (r != MAILIMAP_NO_ERROR) return r; ext_data = mailimap_extension_data_new(&mailimap_extension_condstore, MAILIMAP_CONDSTORE_TYPE_RESP_TEXT_CODE, resptextcode); if (ext_data == NULL) { mailimap_condstore_resptextcode_free(resptextcode); return MAILIMAP_ERROR_MEMORY; } * indx = cur_token; * result = ext_data; return MAILIMAP_NO_ERROR; } case MAILIMAP_EXTENDED_PARSER_MAILBOX_DATA: { struct mailimap_condstore_search * search_data; struct mailimap_extension_data * ext_data; search_data = NULL; r = search_data_parse(fd, buffer, parser_ctx, &cur_token, &search_data); if (r != MAILIMAP_NO_ERROR) return r; ext_data = mailimap_extension_data_new(&mailimap_extension_condstore, MAILIMAP_CONDSTORE_TYPE_SEARCH_DATA, search_data); if (ext_data == NULL) { mailimap_condstore_search_free(search_data); return MAILIMAP_ERROR_MEMORY; } * indx = cur_token; * result = ext_data; return MAILIMAP_NO_ERROR; } case MAILIMAP_EXTENDED_PARSER_STATUS_ATT: { struct mailimap_condstore_status_info * status_info; struct mailimap_extension_data * ext_data; r = status_info_parse(fd, buffer, parser_ctx, &cur_token, &status_info); if (r != MAILIMAP_NO_ERROR) return r; ext_data = mailimap_extension_data_new(&mailimap_extension_condstore, MAILIMAP_CONDSTORE_TYPE_STATUS_INFO, status_info); if (ext_data == NULL) { mailimap_condstore_status_info_free(status_info); return MAILIMAP_ERROR_MEMORY; } * indx = cur_token; * result = ext_data; return MAILIMAP_NO_ERROR; } } return MAILIMAP_ERROR_PARSE; }
int mailimap_acl_parse(int calling_parser, mailstream * fd, MMAPString * buffer, struct mailimap_parser_context * parser_ctx, size_t * indx, struct mailimap_extension_data ** result, size_t progr_rate, progress_function * progr_fun) { int r; int res; struct mailimap_acl_acl_data * acl_data; struct mailimap_acl_listrights_data * lr_data; struct mailimap_acl_myrights_data * mr_data; void * data; int type; acl_data = NULL; lr_data = NULL; mr_data = NULL; switch (calling_parser) { case MAILIMAP_EXTENDED_PARSER_MAILBOX_DATA: r = mailimap_acl_acl_data_parse(fd, buffer, parser_ctx, indx, &acl_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_ACL_TYPE_ACL_DATA; data = acl_data; } if (r == MAILIMAP_ERROR_PARSE) { r = mailimap_acl_listrights_data_parse(fd, buffer, parser_ctx, indx, &lr_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_ACL_TYPE_LISTRIGHTS_DATA; data = lr_data; } } if (r == MAILIMAP_ERROR_PARSE) { r = mailimap_acl_myrights_data_parse(fd, buffer, parser_ctx, indx, &mr_data, progr_rate, progr_fun); if (r == MAILIMAP_NO_ERROR) { type = MAILIMAP_ACL_TYPE_MYRIGHTS_DATA; data = mr_data; } } if (r != MAILIMAP_NO_ERROR) { res = r; goto err; } * result = mailimap_extension_data_new(&mailimap_extension_acl, type, data); if (*result == NULL) { res = MAILIMAP_ERROR_MEMORY; goto data_free; } break; default: /* return a MAILIMAP_ERROR_PARSE if the extension doesn't extend calling_parser. */ return MAILIMAP_ERROR_PARSE; break; } return MAILIMAP_NO_ERROR; data_free: if (acl_data != NULL) mailimap_acl_acl_data_free(acl_data); if (lr_data != NULL) mailimap_acl_listrights_data_free(lr_data); if (mr_data != NULL) mailimap_acl_myrights_data_free(mr_data); err: return res; }