bool imap_arg_get_list(const struct imap_arg *arg, const struct imap_arg **list_r) { unsigned int count; return imap_arg_get_list_full(arg, list_r, &count); }
bool imap_fetch_binary_init(struct imap_fetch_init_context *ctx) { struct imap_fetch_body_data *body; const struct imap_arg *list_args; unsigned int list_count; const char *str, *p, *error; i_assert(strncmp(ctx->name, "BINARY", 6) == 0); p = ctx->name + 6; body = p_new(ctx->pool, struct imap_fetch_body_data, 1); body->binary = TRUE; if (strncmp(p, ".SIZE", 5) == 0) { /* fetch decoded size of the section */ p += 5; body->binary_size = TRUE; } else if (strncmp(p, ".PEEK", 5) == 0) { p += 5; } else { ctx->fetch_ctx->flags_update_seen = TRUE; } if (*p != '[') { ctx->error = "Invalid BINARY[..] parameter: Missing '['"; return FALSE; } if (imap_arg_get_list_full(&ctx->args[0], &list_args, &list_count)) { /* BINARY[HEADER.FIELDS.. (headers list)] */ if (!imap_arg_get_atom(&ctx->args[1], &str) || str[0] != ']') { ctx->error = "Invalid BINARY[..] parameter: Missing ']'"; return FALSE; } if (body_header_fields_parse(ctx, body, p+1, list_args, list_count) < 0) return FALSE; p = str+1; ctx->args += 2; } else { /* no headers list */ body->section = p+1; p = strchr(body->section, ']'); if (p == NULL) { ctx->error = "Invalid BINARY[..] parameter: Missing ']'"; return FALSE; } body->section = p_strdup_until(ctx->pool, body->section, p); p++; } if (imap_msgpart_parse(body->section, &body->msgpart) < 0) { ctx->error = "Invalid BINARY[..] section"; return FALSE; } imap_msgpart_set_decode_to_binary(body->msgpart); ctx->fetch_ctx->fetch_data |= imap_msgpart_get_fetch_data(body->msgpart); if (!body->binary_size) { if (body_parse_partial(body, p, &error) < 0) { ctx->error = p_strdup_printf(ctx->pool, "Invalid BINARY[..] parameter: %s", error); return FALSE; } } /* update the section name for the imap_fetch_add_handler() */ ctx->name = p_strdup(ctx->pool, get_body_name(body)); if (body->binary_size) { imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT, "0", fetch_binary_size, body); } else { imap_fetch_add_handler(ctx, IMAP_FETCH_HANDLER_FLAG_WANT_DEINIT, "NIL", fetch_body_msgpart, body); } return TRUE; }
static bool cmd_x_apple_push_service(struct client_command_context *cmd) { const struct imap_arg *args; struct mail_user *user = cmd->client->user; const char *aps_topic = mail_user_plugin_getenv(user, "push_notify_aps_topic"); if (!client_read_args(cmd, 0, 0, &args)) return FALSE; const char *aps_ver=NULL; const char *aps_acct_id=NULL; const char *aps_dev_token=NULL; const char *aps_sub_topic=NULL; const struct imap_arg *mailbox_list=NULL; unsigned int mailbox_count=NULL; bool mailbox_subscriptions=FALSE; const char *key, *value; /* must have a topic */ if (aps_topic == NULL || *aps_topic == '\0') return FALSE; /* scarf off the aps keys/values */ while (imap_arg_get_astring(&args[0], &key)) { if (imap_arg_get_astring(&args[1], &value)) { if (strcasecmp(key, "aps-version") == 0) aps_ver = t_strdup(value); else if (strcasecmp(key, "aps-account-id") == 0) aps_acct_id = t_strdup(value); else if (strcasecmp(key, "aps-device-token") == 0) aps_dev_token = t_strdup(value); else if (strcasecmp(key, "aps-subtopic") == 0) aps_sub_topic = t_strdup(value); else return FALSE; } else if (strcasecmp(key, "mailboxes") == 0) { mailbox_subscriptions = imap_arg_get_list_full(&args[1], &mailbox_list, &mailbox_count); } args += 2; } /* save notification settings */ if ( aps_ver && aps_acct_id && aps_dev_token && aps_sub_topic ) { msg_data_t msg_data; /* subscribe to notification node */ memset(&msg_data, 0, sizeof(struct msg_data_s)); msg_data.msg = 2; i_strocpy(msg_data.d1, user->username, sizeof(msg_data.d1)); i_strocpy(msg_data.d2, aps_acct_id, sizeof(msg_data.d2)); i_strocpy(msg_data.d3, aps_dev_token, sizeof(msg_data.d3)); i_strocpy(msg_data.d4, aps_sub_topic, sizeof(msg_data.d4)); send_msg_data(&msg_data); if(mailbox_subscriptions) { const char *mailbox; while (imap_arg_get_astring(&mailbox_list[0], &mailbox)) { T_BEGIN; string_t *mailbox_str = t_str_new(256); imap_append_quoted( mailbox_str, "mailbox"); str_append_c( mailbox_str, ' '); imap_append_quoted( mailbox_str, mailbox); send_response(cmd->client, mailbox_str); msg_data.msg = 4; i_strocpy(msg_data.d4, mailbox, sizeof(msg_data.d4)); send_msg_data(&msg_data); T_END; mailbox_list += 1; } } /* generate aps response */ string_t *str = t_str_new(256); imap_append_quoted( str, "aps-version" ); str_append_c(str, ' '); imap_append_quoted( str, APS_VERSION ); str_append_c(str, ' '); imap_append_quoted( str, "aps-topic" ); str_append_c(str, ' '); imap_append_quoted( str, aps_topic ); send_response(cmd->client, str); } client_send_tagline(cmd, "OK Provisioned"); return TRUE; }