• Patch: Elm ME+ 2.5 PLalpha50 -> Elm ME+ 2.5 PLalpha51 [2/6] (4/4)

    From Kari Hurtta@21:1/5 to All on Tue Feb 11 20:03:57 2020
    [continued from previous message]

    + if (ison(ret, QUOTA_ITEM_have_limit)) {
    + DPRINT(Debug,15,(&Debug, " QUOTA_ITEM_have_limit"));
    + }
    + if (usage_r) {
    + DPRINT(Debug,15,(&Debug, " *usage_r=%lu",
    + (unsigned long)*usage_r));
    + }
    + if (limit_r) {
    + DPRINT(Debug,15,(&Debug, " *limit_r=%lu",
    + (unsigned long)*limit_r));
    + }
    + DPRINT(Debug,15,(&Debug, "\n"));
    +
    + return ret;
    + }
    +
    + S_(mq_unlink_con mq_unlink_con_imap)
    + static void mq_unlink_con_imap P_((struct mail_quota *mq,
    + struct connection_cache *con));
    + static void mq_unlink_con_imap(mq,con)
    + struct mail_quota *mq;
    + struct connection_cache *con;
    + {
    + DPRINT(Debug,15,(&Debug,
    + "mq_unlink_con_imap: mq=%p\n",
    + mq));
    +
    + if (MQUOTA_IMAP_magic != mq->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"mq_unlink_con",
    + "Bad magic number (mquota_imap)",0);
    +
    + if (mq->p.imap->con != con)
    + panic("MBX PANIC",__FILE__,__LINE__,"mq_unlink_con",
    + "mq->p.imap->con have wrong value", 0);
    +
    + mq->p.imap->con = NULL;
    + }
    +
    +
    + struct mail_quota_type imap_quota = {
    + MAIL_QUOTA_TYPE_magic ,
    +
    + /* struct mail_quota */
    +
    + mq_init_imap,
    + mq_dest_imap,
    +
    + /* struct mail_quotaroot_list */
    +
    + mq_init_mqrl_imap,
    + mq_disc_mqrl_imap,
    + mq_dest_mqrl_imap,
    +
    + mq_listlen_mqrl_imap,
    + mq_listitem_mqrl_imap,
    +
    + /* struct mail_quotaroot */
    +
    + mq_init_mqr_imap,
    + mq_disc_mqr_imap,
    + mq_dest_mqr_imap,
    +
    + mq_itemcount_mqr_imap,
    + mq_item_mqr_imap,
    + mq_status_mqr_imap,
    +
    + /* struct mail_quota_item */
    + mq_init_mqi_imap,
    + mq_disc_mqi_imap,
    + mq_dest_mqi_imap,
    + mq_values_mqi_imap,
    +
    + /* struct connection_cache */
    +
    + mq_unlink_con_imap
    + };
    +
    + /* given_name may be NULL */
    + static struct mail_quotaroot *ref_mail_quotaroot(mq,given_name)
    + struct mail_quota * mq;
    + const char * given_name;
    + {
    + if (MAIL_QUOTA_magic != mq->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_mail_quotaroot",
    + "Bad magic number (mail_quota)",0);
    +
    + if (mq->quotaroot_list) {
    + size_t i;
    +
    + for (i = 0; i < mq->quotaroot_count; i++) {
    + if (mq->quotaroot_list[i]) {
    + if (MAIL_QUOTAROOT_magic != mq->quotaroot_list[i]->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_mail_quotaroot",
    + "Bad magic number (mail_quotaroot)",0);
    +
    + if (&imap_quota == mq->quotaroot_list[i]->quota_type) {
    +
    + if (MQR_IMAP_magic != mq->quotaroot_list[i]->p.imap->magic) + panic("MBX PANIC",__FILE__,__LINE__,
    + "ref_mail_quotaroot",
    + "Bad magic number (mqr_imap)",0);
    +
    + if (!given_name &&
    + !mq->quotaroot_list[i]->p.imap->given_name) {
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_mail_quotaroot=%p; idx #%zu, name not set\n",
    + mq->quotaroot_list[i],i));
    +
    + return mq->quotaroot_list[i];
    +
    + } else if (given_name &&
    + mq->quotaroot_list[i]->p.imap->given_name &&
    + 0 == strcmp(mq->quotaroot_list[i]->p.imap->given_name, + given_name)) {
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_mail_quotaroot=%p; idx #%zu, name=%s\n",
    + mq->quotaroot_list[i],i,
    + mq->quotaroot_list[i]->p.imap->given_name));
    +
    + return mq->quotaroot_list[i];
    + }
    + }
    + }
    + }
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_mail_quotaroot=NULL; quotaroot_count=%zu",
    + mq->quotaroot_count));
    + if (given_name) {
    + DPRINT(Debug,20,(&Debug,"; given_name=%s",given_name));
    + }
    + DPRINT(Debug,20,(&Debug,"\n"));
    +
    + return NULL;
    + }
    +
    +
    + void init_imap_quota_mbx(con)
    + struct connection_cache * con;
    + {
    + if (con->type != &IMAP_connection) {
    + panic("MBX PANIC",__FILE__,__LINE__,"init_imap_quota_mbx",
    + "Wrong type connection ",0);
    + }
    +
    + if (con->f->folder_type != &imap_mbx)
    + panic("MBX PANIC",__FILE__,__LINE__,"init_imap_quota_mbx",
    + "Bad folder type attached to connection",0);
    +
    + if (PRIVATE_DATA_magic != con->f->p->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"init_imap_quota_mbx",
    + "Bad magic number (private_data)",0);
    +
    +
    + if (con->quota) {
    + DPRINT(Debug,11,(&Debug,
    + "init_imap_quota_mbx: Connection have already quota set\n"));
    +
    + } else {
    + struct mail_quota * X = malloc_mail_quota(&imap_quota);
    +
    + connection_set_reset_quota(con,X);
    + X->p.imap->con = con; /* Not refcounted */
    +
    + con->f->p->quota = X;
    + }
    + }
    +
    + /* Increments refcount */
    + static struct mail_quotaroot_list *give_quotaroot_list P_((struct mail_quota *mq,
    + struct imap_token names[],
    + size_t names_count)); + static struct mail_quotaroot_list *give_quotaroot_list(mq,names,names_count) + struct mail_quota *mq;
    + struct imap_token names[];
    + size_t names_count;
    + {
    + struct mail_quotaroot_list *ret = NULL;
    +
    + if (MAIL_QUOTA_magic != mq->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_quotaroot_list",
    + "Bad magic number (mail_quota)",0);
    +
    + if (mq->quotarootl_list) {
    + size_t idx;
    +
    + for (idx = 0; idx < mq->quotarootl_count; idx++) {
    + if (mq->quotarootl_list[idx]) {
    + if (MAIL_QUOTAROOT_LIST_magic != mq->quotarootl_list[idx]->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_quotaroot_list", + "Bad magic number (mail_quotaroot_list)",0);
    +
    + if (&imap_quota == mq->quotarootl_list[idx]->quota_type) {
    +
    + if (MQRL_IMAP_magic != mq->quotarootl_list[idx]->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_quotaroot_list",
    + "Bad magic number (mqrl_imap)",0);
    +
    + if (names_count ==
    + mq->quotarootl_list[idx]->p.imap->quotaroot_name_count) {
    +
    + size_t t;
    +
    + for (t = 0; t < names_count; t++) {
    +
    + if ( ! names[t].str &&
    + ! mq->quotarootl_list[idx]->p.imap->
    + quotaroot_name_list[t].given_name) {
    +
    + DPRINT(Debug,20,(&Debug,
    + "give_quotaroot_list: pos #%zu, name #%zu not set\n",
    + idx,t));
    +
    + } else if (! names[t].str ||
    + ! mq->quotarootl_list[idx]->p.imap->
    + quotaroot_name_list[t].given_name ||
    + 0 != strcmp(names[t].str,
    + mq->quotarootl_list[idx]->p.imap-> + quotaroot_name_list[t].given_name)) + goto fail_match;
    +
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "give_quotaroot_list: Found pos #%zu\n",
    + idx));
    +
    + ret = mq->quotarootl_list[idx];
    + inc_mail_quotaroot_list_refcount(ret);
    + goto found;
    + }
    +
    +
    + }
    + }
    +
    + fail_match:;
    +
    + }
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "give_quotaroot_list: Adding new quotaroot_list, current count %zu\n",
    + mq->quotarootl_count));
    +
    + ret = malloc_mail_quotaroot_list(mq);
    +
    + if (MQRL_IMAP_magic != ret->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_quotaroot_list",
    + "Bad magic number (mqrl_imap)",0);
    +
    + if (ret->p.imap->quotaroot_name_count ||
    + ret->p.imap->quotaroot_name_list)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_quotaroot_list",
    + "Not empty quotaroot_name_list",0);
    +
    +
    + if (names_count > 0) {
    + size_t t;
    +
    + ret->p.imap->quotaroot_name_list =
    + safe_calloc(names_count,
    + sizeof (ret->p.imap->quotaroot_name_list[0]));
    +
    + for (t = 0; t < names_count; t++) {
    +
    + if (names[t].str) {
    + ret->p.imap->quotaroot_name_list[t].
    + name = new_string2(imap_charset,s2us(names[t].str));
    + ret->p.imap->quotaroot_name_list[t].
    + given_name = safe_strdup(names[t].str);
    + } else {
    + DPRINT(Debug,20,(&Debug,
    + "give_quotaroot_list: name #%zu not set\n",
    + t));
    +
    + ret->p.imap->quotaroot_name_list[t].name = NULL;
    + ret->p.imap->quotaroot_name_list[t].given_name = NULL;
    + }
    + }
    + ret->p.imap->quotaroot_name_count = t;
    + }
    +
    + found:
    + DPRINT(Debug,20,(&Debug,
    + "give_quotaroot_list=%p\n",
    + ret));
    +
    + return ret;
    + }
    +
    + static struct folder_quotaroot * ref_folder_quotaroot P_((struct mquota_imap *mquota,
    + struct imap_token * name));
    + static struct folder_quotaroot * ref_folder_quotaroot(mquota,name)
    + struct mquota_imap *mquota;
    + struct imap_token * name;
    + {
    + struct folder_quotaroot * ret = NULL;
    + size_t found_idx,new_count;
    +
    + if (MQUOTA_IMAP_magic != mquota->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_folder_quotaroot",
    + "Bad magic number (mail_quota)",0);
    +
    + if (mquota->folder_quotaroot_list) {
    + size_t idx;
    +
    + for (idx = 0; idx < mquota->folder_quotaroot_count; idx++) {
    +
    + if (! name->str &&
    + ! mquota->folder_quotaroot_list[idx].given_name) {
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_folder_quotaroot: pos #%zu - name not set\n",
    + idx));
    +
    + found_idx = idx;
    + goto found;
    + } else if (name->str &&
    + mquota->folder_quotaroot_list[idx].given_name &&
    + 0 == strcmp(name->str,mquota->folder_quotaroot_list[idx].given_name)) {
    + DPRINT(Debug,20,(&Debug,
    + "ref_folder_quotaroot: pos #%zu - found %s\n", + idx,
    + name->str));
    + found_idx = idx;
    + goto found;
    + }
    + }
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_folder_quotaroot: Adding new item to folder_quotaroot_list, current count %zu\n",
    + mquota->folder_quotaroot_count));
    +
    + found_idx = mquota->folder_quotaroot_count;
    + new_count = mquota->folder_quotaroot_count+1;
    +
    + mquota->folder_quotaroot_list =
    + safe_array_realloc(mquota->folder_quotaroot_list,
    + new_count,
    + sizeof (mquota->folder_quotaroot_list[0]));
    +
    + if (name->str) {
    + mquota->folder_quotaroot_list[found_idx].mailbox_name
    + = conv_from_imap_name(name->str);
    + mquota->folder_quotaroot_list[found_idx].given_name
    + = safe_strdup(name->str);
    + } else {
    + DPRINT(Debug,20,(&Debug,
    + "ref_folder_quotaroot: Name not set\n"));
    + mquota->folder_quotaroot_list[found_idx].mailbox_name = NULL;
    + mquota->folder_quotaroot_list[found_idx].given_name = NULL;
    + }
    + mquota->folder_quotaroot_list[found_idx].quotaroot_list = NULL;
    +
    + mquota->folder_quotaroot_count = new_count;
    +
    + found:
    + if (found_idx >= mquota->folder_quotaroot_count)
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_folder_quotaroot",
    + "Bad found_idx",0);
    + ret = &(mquota->folder_quotaroot_list[found_idx]);
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_folder_quotaroot=%p, pos #%zu",
    + ret, found_idx));
    + if (ret->given_name) {
    + DPRINT(Debug,20,(&Debug,", given_name=%s",
    + ret->given_name));
    + }
    + if (ret->mailbox_name) {
    + DPRINT(Debug,20,(&Debug,", mailbox_name=%S",
    + ret->mailbox_name));
    + }
    + if (ret->quotaroot_list) {
    + DPRINT(Debug,20,(&Debug,", quotaroot_list=%p",
    + ret->quotaroot_list));
    + }
    + DPRINT(Debug,20,(&Debug,"\n"));
    +
    + return ret;
    + }
    +
    +
    + static struct mqr_imap * ref_mqr_imap P_((struct mail_quota * mq,
    + struct imap_token * name));
    + static struct mqr_imap * ref_mqr_imap(mq,name)
    + struct mail_quota * mq;
    + struct imap_token * name;
    + {
    + struct mail_quotaroot * quotaroot = NULL;
    + struct mqr_imap * ret = NULL;
    +
    + if (MAIL_QUOTA_magic != mq->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_mqr_imap",
    + "Bad magic number (mail_quota)",0);
    +
    + /* Allow NULL name->str */
    + quotaroot = ref_mail_quotaroot(mq,name->str);
    +
    + if (quotaroot) {
    +
    + if (MAIL_QUOTAROOT_magic != quotaroot->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_mqr_imap",
    + "Bad magic number (mail_quotaroot)",0);
    +
    + if (&imap_quota == quotaroot->quota_type) {
    +
    + if (MQR_IMAP_magic != quotaroot->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "ref_mqr_imap",
    + "Bad magic number (mqr_imap)",0);
    +
    + ret = quotaroot->p.imap;
    + } else
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_mqr_imap",
    + "Bad quotaroot type",0);
    +
    + } else {
    + struct string * name_s = NULL;
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_mqr_imap: Adding new item to quotaroot_list, current count #%zu\n",
    + mq->quotaroot_count));
    +
    + if (name->str)
    + name_s = new_string2(imap_charset,s2us(name->str));
    +
    + quotaroot = malloc_mail_quotaroot(mq,name_s,qr_root_none);
    +
    + if (MAIL_QUOTAROOT_magic != quotaroot->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_mqr_imap",
    + "Bad magic number (mail_quotaroot)",0);
    +
    + if (&imap_quota == quotaroot->quota_type) {
    +
    + if (MQR_IMAP_magic != quotaroot->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,
    + "ref_mqr_imap",
    + "Bad magic number (mqr_imap)",0);
    +
    + if (name->str)
    + quotaroot->p.imap->given_name =
    + strmcpy(quotaroot->p.imap->given_name,
    + name->str);
    +
    + ret = quotaroot->p.imap;
    + } else
    + panic("MBX PANIC",__FILE__,__LINE__,"ref_mqr_imap",
    + "Bad quotaroot type",0);
    +
    + if (name_s)
    + free_string(& name_s);
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "ref_mqr_imap=%p",
    + ret));
    +
    + if (ret->given_name)
    + DPRINT(Debug,20,(&Debug,"; given_name=%s",
    + ret->given_name));
    +
    + if (quotaroot) {
    + DPRINT(Debug,20,(&Debug,"; quotaroot=%p",quotaroot));
    +
    + if (quotaroot->name)
    + DPRINT(Debug,20,(&Debug,"; name=%S",
    + quotaroot->name));
    + }
    +
    + DPRINT(Debug,20,(&Debug,"\n"));
    +
    + return ret;
    + }
    +
    + static struct mail_quota_item * give_mail_quota_item
    + P_((struct mail_quota * mq,
    + struct imap_token * resource,
    + struct imap_token * usage,
    + struct imap_token * limit));
    + static struct mail_quota_item * give_mail_quota_item(mq,resource,usage,limit)
    + struct mail_quota * mq;
    + struct imap_token * resource;
    + struct imap_token * usage;
    + struct imap_token * limit;
    + {
    +
    + struct string * name = NULL;
    +
    +
    + struct mail_quota_item * ret = NULL;
    +
    + if (MAIL_QUOTA_magic != mq->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_mail_quota_item",
    + "Bad magic number (mail_quota)",0);
    +
    + if (resource->str) {
    + name = new_string2(imap_charset,s2us(resource->str));
    +
    + DPRINT(Debug,20,(&Debug,"give_mail_quota_item: name=%S\n",name));
    + }
    +
    + ret = malloc_mail_quota_item(mq,name,qr_res_none);
    +
    + if (&imap_quota != ret->quota_type)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_mail_quota_item",
    + "Bad quota type",0);
    +
    + if (MQI_IMAP_magic != ret->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"give_mail_quota_item",
    + "Bad magic number (mqi_imap)",0);
    +
    + if (imap_number == usage->imap_token) {
    + setit(ret->p.imap->quota_item_mask,QUOTA_ITEM_have_usage);
    + ret->p.imap->usage = usage->value;
    +
    + DPRINT(Debug,20,(&Debug,"give_mail_quota_item: usage=%lu\n",
    + (unsigned long)(ret->p.imap->usage)));
    + }
    +
    + if (imap_number == limit->imap_token) {
    + setit(ret->p.imap->quota_item_mask,QUOTA_ITEM_have_limit);
    + ret->p.imap->limit = limit->value;
    +
    + DPRINT(Debug,20,(&Debug,"give_mail_quota_item: limit=%lu\n",
    + (unsigned long)(ret->p.imap->limit)));
    + }
    +
    + if (name)
    + free_string(&name);
    +
    + DPRINT(Debug,20,(&Debug,"give_mail_quota_item=%p; quota_item_mask=%d",
    + ret,ret->p.imap->quota_item_mask));
    + if (ison(ret->p.imap->quota_item_mask,QUOTA_ITEM_have_usage)) {
    + DPRINT(Debug,20,(&Debug," QUOTA_ITEM_have_usage"));
    + }
    + if (ison(ret->p.imap->quota_item_mask,QUOTA_ITEM_have_limit)) {
    + DPRINT(Debug,20,(&Debug," QUOTA_ITEM_have_limit"));
    + }
    + DPRINT(Debug,20,(&Debug,"\n"));
    +
    + return ret;
    +
    + }
    +
    + void parse_imap_quotaroot(quota,quotaroot_params,quotaroot_param_count)
    + struct mail_quota * quota;
    + struct imap_token quotaroot_params[];
    + int quotaroot_param_count;
    + {
    + struct mail_quotaroot_list * qrlist = NULL;
    + struct folder_quotaroot * folqroot = NULL;
    +
    + struct mquota_imap * mquota;
    + size_t idx;
    +
    + if (MAIL_QUOTA_magic != quota->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quotaroot",
    + "Bad magic number (mail_quota)",0);
    +
    + if (&imap_quota != quota->quota_type)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quotaroot",
    + "Bad quota type attached to quota",0);
    +
    + /* quotaroot_params[0] == mailbox
    + quotaroot_params[1...n] quotaroot names
    + */
    +
    + if (quotaroot_param_count < 1)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quotaroot",
    + "Bad param count",0);
    +
    + if (MQUOTA_IMAP_magic != quota->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quotaroot",
    + "Bad magic number (mquota_imap)",0);
    +
    + mquota = quota->p.imap;
    +
    + switch (quotaroot_params[0].imap_token) {
    + case imap_atom:
    + case imap_string:
    +
    + if (quotaroot_params[0].str) {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quotaroot: mailbox name = %s\n",
    + quotaroot_params[0].str));
    + }
    +
    + break;
    +
    + default:
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quotaroot: atom or string expected for mailbox name\n"));
    +
    + goto cleanup;
    + }
    +
    +
    + for (idx = 1; idx < quotaroot_param_count; idx++) {
    + switch (quotaroot_params[idx].imap_token) {
    + case imap_atom:
    + case imap_string:
    +
    + if (quotaroot_params[idx].str) {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quotaroot: quota root name #%zu = %s\n",
    + idx,
    + quotaroot_params[idx].str));
    + }
    +
    + break;
    +
    + default:
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quotaroot: atom or string expected for quota root name #%zu\n",
    + idx
    + ));
    +
    + goto cleanup;
    + }
    + }
    +
    + qrlist = give_quotaroot_list(quota,&(quotaroot_params[1]),quotaroot_param_count-1);
    +
    + folqroot = ref_folder_quotaroot(mquota,&(quotaroot_params[0]));
    +
    + if (folqroot->quotaroot_list)
    + free_mail_quotaroot_list(& (folqroot->quotaroot_list));
    +
    + folqroot->quotaroot_list = qrlist;
    +
    + cleanup: ;
    + }
    +
    + void parse_imap_quota(quota,quota_params,quota_param_count)
    + struct mail_quota * quota;
    + struct imap_token quota_params[];
    + int quota_param_count;
    + {
    + size_t idx;
    + size_t resource_count = 0;
    +
    + struct mqr_imap * mqrimap;
    +
    + if (MAIL_QUOTA_magic != quota->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quota",
    + "Bad magic number (mail_quota)",0);
    +
    + if (&imap_quota != quota->quota_type)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quota",
    + "Bad quota type attached to quota",0);
    +
    + /* quota_params[0] == quotaroot name
    + quota_params[1...n] quota resource list with ( ) per resource
    + */
    +
    + switch (quota_params[0].imap_token) {
    + case imap_atom:
    + case imap_string:
    +
    + if (quota_params[0].str) {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: quotaroot name = %s\n",
    + quota_params[0].str));
    + }
    +
    + break;
    +
    + default:
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: atom or string expected for quotaroot name\n"));
    +
    + goto cleanup;
    + }
    +
    + for (idx = 1; idx < quota_param_count; idx++) {
    + switch (quota_params[idx].imap_token) {
    + case imap_atom:
    + if (quota_params[idx].str) {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu quota resource token = %s\n",
    + idx,
    + quota_params[idx].str));
    + }
    +
    + break;
    +
    + case imap_number:
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu quota resource value = %lu\n",
    + idx,
    + (unsigned long)quota_params[idx].value));
    + break;
    +
    + case imap_list_begin:
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu quota resource start (\n", + idx));
    +
    + resource_count++;
    +
    + break;
    +
    + case imap_list_end:
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu quota resource end )\n",
    + idx));
    + break;
    + default:
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu -- atom, number, list begin '(' or list end ')' expected for quota resource data\n",
    + idx));
    +
    + goto cleanup;
    + }
    + }
    +
    + mqrimap = ref_mqr_imap(quota,&(quota_params[0]));
    +
    + if (MQR_IMAP_magic != mqrimap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quota",
    + "Bad magic number (mqr_imap)",0);
    +
    +
    + /* Delete previous resource data */
    + free_quota_item_list(mqrimap);
    +
    + mqrimap->status = qr_stat_none;
    +
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: resource count %zu\n",
    + resource_count));
    +
    + if (mqrimap->quota_item_list ||
    + mqrimap->quota_item_count)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quota",
    + "Quota item list not empty",0);
    +
    + if (resource_count > 0) {
    + size_t i;
    +
    + mqrimap->quota_item_list =
    + safe_calloc(resource_count,
    + sizeof (mqrimap->quota_item_list[0]));
    +
    + for (i = 0; i < resource_count; i++)
    + mqrimap->quota_item_list[i] = NULL;
    +
    + } else
    + mqrimap->status = qr_stat_empty;
    +
    + for (idx = 1; idx < quota_param_count; ) {
    +
    + if (imap_list_begin == quota_params[idx].imap_token) {
    +
    + struct imap_token * resource = NULL;
    + struct imap_token * usage = NULL;
    + struct imap_token * limit = NULL;
    + /* expecting: ( atom number number ) */
    +
    + if (mqrimap->quota_item_count >= resource_count)
    + panic("MBX PANIC",__FILE__,__LINE__,"parse_imap_quota",
    + "quota_item_count overflow",0);
    +
    + idx++;
    + if (idx < quota_param_count &&
    + imap_atom == quota_params[idx].imap_token) {
    +
    + resource = &(quota_params[idx]);
    + } else {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu parse error -- expected atom\n",
    + idx));
    + mqrimap->status = qr_stat_failed;
    + break;
    + }
    +
    + idx++;
    + if (idx < quota_param_count &&
    + imap_number == quota_params[idx].imap_token) {
    +
    + usage = &(quota_params[idx]);
    + } else {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu parse error -- expected number\n",
    + idx));
    + mqrimap->status = qr_stat_failed;
    + break;
    + }
    +
    + idx++;
    + if (idx < quota_param_count &&
    + imap_number == quota_params[idx].imap_token) {
    +
    + limit = &(quota_params[idx]);
    + } else {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu parse error -- expected number\n",
    + idx));
    + mqrimap->status = qr_stat_failed;
    + break;
    + }
    +
    + idx++;
    +
    + if (idx < quota_param_count &&
    + imap_list_end == quota_params[idx].imap_token) {
    +
    + struct mail_quota_item * item =
    + give_mail_quota_item(quota,resource,usage,limit);
    +
    + mqrimap->quota_item_list[mqrimap->quota_item_count++] = item;
    +
    + mqrimap->status = qr_stat_normal;
    +
    + } else {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu parse error -- expected )\n",
    + idx));
    + mqrimap->status = qr_stat_failed;
    + break;
    + }
    +
    + idx++;
    +
    + } else {
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: #%zu parse error -- expected (\n",
    + idx));
    + mqrimap->status = qr_stat_failed;
    + break;
    + }
    +
    + }
    +
    + DPRINT(Debug,20,(&Debug,
    + "parse_imap_quota: %zu items parsed, status=%d",
    + mqrimap->quota_item_count,
    + mqrimap->status
    + ));
    + switch (mqrimap->status) {
    + case qr_stat_failed: DPRINT(Debug,20,(&Debug," qr_stat_failed")); break;
    + case qr_stat_none: DPRINT(Debug,20,(&Debug," qr_stat_none")); break;
    + case qr_stat_empty: DPRINT(Debug,20,(&Debug," qr_stat_empty")); break;
    + case qr_stat_normal: DPRINT(Debug,20,(&Debug," qr_stat_normal")); break;
    + }
    + DPRINT(Debug,20,(&Debug,"\n"));
    +
    + cleanup: ;
    + }
    +
    +
    +
    + E_(mbx_have_folder_quota mbx_have_imap_quota)
    + struct mail_quota * mbx_have_imap_quota(folder)
    + struct folder_info * folder;
    + {
    + struct mail_quota * ret = NULL;
    + struct connection_cache *con;
    +
    + DPRINT(Debug,11,(&Debug,
    + "mbx_have_imap_quota: folder=%p (%s)\n",
    + folder,folder->cur_folder_sys));
    +
    + if (PRIVATE_DATA_magic != folder->p->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_have_imap_quota",
    + "Bad magic number (private_data)",0);
    +
    + if (folder->p->quota) {
    + DPRINT(Debug,11,(&Debug,
    + "mbx_have_imap_quota: Freeing old quota data\n"));
    +
    + free_mail_quota(& (folder->p->quota));
    + }
    +
    + con = folder->p->a.imap_mbx.Ch;
    + if (con) {
    +
    + if (con->type != &IMAP_connection) {
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_have_imap_quota",
    + "Wrong type connection attached to folder",0);
    + }
    +
    + if (con->quota) {
    +
    + DPRINT(Debug,11,(&Debug,
    + "mbx_have_imap_quota: Connection have already quota set\n"));
    +
    + if (MAIL_QUOTA_magic != con->quota->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_have_imap_quota",
    + "Bad magic number (mail_quota)",0);
    + if (&imap_quota != con->quota->quota_type)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_have_imap_quota",
    + "Bad quota type",0);
    +
    + ret = con->quota;
    + inc_mail_quota_refcount(ret);
    +
    + if (ret->p.imap->con != con)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_have_imap_quota",
    + "Incorrect ret->p.imap->con",0);
    +
    + } else {
    + struct IMAP_CON * Ma = con->a.imap_con;
    +
    + if (!Ma)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_have_imap_quota",
    + "No imap connection",0);
    +
    + if ( 0 != (Ma->capability_bits & CAPA_QUOTA) ) {
    +
    + DPRINT(Debug,11,(&Debug,
    + "mbx_have_imap_quota: Connection supports QUOTA\n"));
    +
    + ret = malloc_mail_quota(&imap_quota);
    +
    + connection_set_reset_quota(con,ret);
    + ret->p.imap->con = con; /* Not refcounted */
    +
    + folder->p->quota = ret;
    + inc_mail_quota_refcount(folder->p->quota);
    +
    + } else {
    + DPRINT(Debug,11,(&Debug,
    + "mbx_have_imap_quota: Connection does not support QUOTA\n"));
    + }
    +
    + }
    + } else {
    + DPRINT(Debug,11,(&Debug,
    + "mbx_have_imap_quota: No connection\n"));
    + }
    +
    + DPRINT(Debug,11,(&Debug,"mbx_have_imap_quota="));
    + if (ret) {
    + DPRINT(Debug,11,(&Debug,"%p",ret));
    + } else {
    + DPRINT(Debug,11,(&Debug,"NULL"));
    + }
    + DPRINT(Debug,11,(&Debug,"\n"));
    +
    + return ret;
    + }
    +
    + static struct mail_quotaroot_list *
    + folder_name_to_quote_root_list P_((struct mquota_imap *mqimap,
    + struct string *folder_name));
    + static struct mail_quotaroot_list * folder_name_to_quote_root_list(mqimap,
    + folder_name) + struct mquota_imap *mqimap;
    + struct string *folder_name;
    + {
    + if (MQUOTA_IMAP_magic != mqimap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"folder_name_to_quote_root_list",
    + "Bad magic number (mquota_imap)",0);
    +
    + if (mqimap->folder_quotaroot_list) {
    + size_t i;
    +
    + for (i = 0; i < mqimap->folder_quotaroot_count; i++) {
    + if (mqimap->folder_quotaroot_list[i].mailbox_name &&
    + 0 == string_cmp(mqimap->folder_quotaroot_list[i].mailbox_name, + folder_name,
    + -999 /* Does not compare */)) {
    +
    + return mqimap->folder_quotaroot_list[i].quotaroot_list;
    + }
    + }
    + }
    +
    + return NULL;
    + }
    +
    +
    + E_(mbx_give_folder_quotar_list mbx_give_imap_quotar_list)
    + struct mail_quotaroot_list * mbx_give_imap_quotar_list(folder,mq,cd)
    + struct folder_info * folder;
    + struct mail_quota * mq;
    + struct cancel_data * cd /* Allow cancelation (Ctrl-C) on remote mailbox */;
    + {
    + struct mail_quotaroot_list * ret = NULL;
    + struct string * folder_name = NULL;
    +
    + DPRINT(Debug,11,(&Debug,
    + "mbx_give_imap_quotar_list: folder=%p (%s)\n",
    + folder,folder->cur_folder_sys));
    +
    + if (PRIVATE_DATA_magic != folder->p->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_give_imap_quotar_list",
    + "Bad magic number (private_data)",0);
    +
    + if (MAIL_QUOTA_magic != mq->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_give_imap_quotar_list",
    + "Bad magic number (mail_quota)",0);
    +
    + if (&imap_quota != mq->quota_type)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_give_imap_quotar_list",
    + "Bad quota type",0);
    +
    + if (MQUOTA_IMAP_magic != mq->p.imap->magic)
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_give_imap_quotar_list",
    + "Bad magic number (mquota_imap)",0);
    +
    + if (folder->p->a.imap_mbx.folder_name_cache &&
    + string_len(folder->p->a.imap_mbx.folder_name_cache) > 0) {
    +
    + DPRINT(Debug,11,(&Debug,
    + "mbx_give_imap_quotar_list: Folder name %S\n",
    + folder->p->a.imap_mbx.folder_name_cache));
    +
    + folder_name = dup_string(folder->p->a.imap_mbx.folder_name_cache);
    + } else {
    + DPRINT(Debug,11,(&Debug,
    + "mbx_give_imap_quotar_list: Raw folder name %s\n",
    + folder->p->a.imap_mbx.folder));
    +
    + folder_name = conv_from_imap_name(folder->p->a.imap_mbx.folder);
    + }
    +
    + ret = folder_name_to_quote_root_list( mq->p.imap,folder_name);
    + if (ret) {
    + inc_mail_quotaroot_list_refcount(ret);
    + } else {
    + struct connection_cache *con = folder->p->a.imap_mbx.Ch;
    +
    + if (con->type != &IMAP_connection) {
    + panic("MBX PANIC",__FILE__,__LINE__,"mbx_give_imap_quotar_list",
    + "Wrong type connection attached to folder",0);
    + }
    +
    + if (start_imap_command_c(con,"GETQUOTAROOT",cd)) {
    + imap_states res;
    +
    + imap_command_push_astring(con,folder->p->a.imap_mbx.folder);
    +
    + end_imap_command(con);
    + if (imap_command_ok_c(con,&res,NULL,cd)) {
    +
    + ret = folder_name_to_quote_root_list( mq->p.imap,folder_name); + if (ret) {
    + inc_mail_quotaroot_list_refcount(ret);
    + } else {
    + DPRINT(Debug,11,(&Debug,
    + "mbx_give_imap_quotar_list: GETQUOTAROOT did not returned quota root list?\n"));
    + }
    + } else {
    + DPRINT(Debug,11,(&Debug,
    + "mbx_give_imap_quotar_list: GETQUOTAROOT failed or canceled\n"));
    + }
    + }
    +
    + if (!imap_clear_command_c(con,cd)) {
    + DPRINT(Debug,11,(&Debug,
    + "mbx_give_imap_quotar_list: OOPS failure on clear command (canceled?)\n"));
    + }
    + }
    +
    + free_string(&folder_name);
    +
    + DPRINT(Debug,11,(&Debug,"mbx_give_imap_quotar_list="));
    + if (ret) {
    + DPRINT(Debug,11,(&Debug,"%p",ret));
    + } else {
    + DPRINT(Debug,11,(&Debug,"NULL"));
    + }
    + DPRINT(Debug,11,(&Debug,"\n"));
    +
    + return ret;
    + }
    +
    +
    +
    + #endif /* REMOTE_MBX */
    +
    +
    +
    + /*
    + * Local Variables:
    + * mode:c
    + * c-basic-offset:4
    + * buffer-file-coding-system: iso-8859-1
    + * End:
    + */

    --
    / Kari Hurtta

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)