HIDDEN int mailbox_delete_cleanup(struct mailbox *mailbox, const char *part, const char *name, const char *uniqueid)
{
    strarray_t paths = STRARRAY_INITIALIZER;
    int i;
    mbentry_t *mbentry;
    struct meta_file *mf;
    int r;
    char nbuf[MAX_MAILBOX_NAME];
    char *ntail;
    char *p;

    int object_storage_enabled = 0 ;
#if defined ENABLE_OBJECTSTORE
    object_storage_enabled = config_getswitch(IMAPOPT_OBJECT_STORAGE_ENABLED);
#endif

    xstrncpy(nbuf, name, sizeof(nbuf));
    ntail = nbuf + strlen(nbuf);

    if (mailbox && object_storage_enabled){
        mailbox_remove_files_from_object_storage (mailbox, 0) ;
    }

    /* XXX - double XXX - this is a really ugly function.  It should be
     * using mboxname_parts and walking back up the 'boxes' list */

    strarray_add(&paths, mboxname_datapath(part, name, uniqueid, 0));

    /* find the directory for every one of the meta files */
    for (mf = meta_files; mf->metaflag; mf++) {
        char *fname = xstrdup(mboxname_metapath(part, name, uniqueid, mf->metaflag, 0));
        p = strrchr(fname, '/');
        if (p) *p = '\0';
        strarray_add(&paths, fname);
        free(fname);
    }

    for (i = 0; i < paths.count; i++) {
        const char *path = strarray_nth(&paths, i);
        mailbox_delete_files(path);
    }

    do {
        if (!uniqueid) {
            /* paths by mboxname - Check if the mailbox has children */
            r = mboxlist_mboxtree(nbuf, chkchildren, (void *)part, MBOXTREE_SKIP_ROOT);
            if (r != 0) break; /* We short-circuit with CYRUSDB_DONE */
        }

        /* no children, remove the directories */
        for (i = 0; i < paths.count; i++) {
            char *path = paths.data[i]; /* need direct reference, because we're fiddling */
            r = rmdir(path);
            if (r && errno != ENOENT)
                syslog(LOG_NOTICE,
                       "Remove of supposedly empty directory %s failed: %m",
                       path);
            p = strrchr(path, '/');
            if (p) *p = '\0';
        }

        /* Check if parent mailbox exists */
        ntail = strrchr(nbuf, '.');
        if (!ntail || strchr(ntail, '!')) {
            /* Hit top of hierarchy or domain separator */
            break;
        }
        *ntail = '\0';
        if (!strcmp(nbuf, "user") ||
            ((ntail - nbuf > 5) && !strcmp(ntail-5, "!user"))) {
            /* Hit top of 'user' hierarchy */
            break;
        }

        r = mboxlist_lookup(nbuf, &mbentry, NULL);
        /* if it's not being moved, and not the same partition, then it's safe to
         * clean up the parent directory too */
        if (!r) {
            if (!(mbentry->mbtype & MBTYPE_MOVING) && strcmp(mbentry->partition, part))
                r = IMAP_MAILBOX_NONEXISTENT;
            mboxlist_entry_free(&mbentry);
        }
    } while (r == IMAP_MAILBOX_NONEXISTENT);

    strarray_fini(&paths);

    return 0;
}
HIDDEN int mailbox_delete_cleanup(struct mailbox *mailbox, const char *part, const char *name, const char *uniqueid)
{
    strarray_t paths = STRARRAY_INITIALIZER;
    int i;
    mbentry_t *mbentry;
    struct meta_file *mf;
    int r;
    char nbuf[MAX_MAILBOX_NAME];
    char *ntail;
    char *p;

    int object_storage_enabled = 0 ;
#if defined ENABLE_OBJECTSTORE
    object_storage_enabled = config_getswitch(IMAPOPT_OBJECT_STORAGE_ENABLED);
#endif

    xstrncpy(nbuf, name, sizeof(nbuf));
    ntail = nbuf + strlen(nbuf);

    if (mailbox && object_storage_enabled){
        mailbox_remove_files_from_object_storage (mailbox, 0) ;
    }

     

    strarray_add(&paths, mboxname_datapath(part, name, uniqueid, 0));

     
    for (mf = meta_files; mf->metaflag; mf++) {
        char *fname = xstrdup(mboxname_metapath(part, name, uniqueid, mf->metaflag, 0));
        p = strrchr(fname, '/');
        if (p) *p = '\0';
        strarray_add(&paths, fname);
        free(fname);
    }

    for (i = 0; i < paths.count; i++) {
        const char *path = strarray_nth(&paths, i);
        mailbox_delete_files(path);
    }

    do {
        if (!uniqueid) {
             
            r = mboxlist_mboxtree(nbuf, chkchildren, (void *)part, MBOXTREE_SKIP_ROOT);
            if (r != 0) break;  
        }

         
        for (i = 0; i < paths.count; i++) {
            char *path = paths.data[i];  
            r = rmdir(path);
            if (r && errno != ENOENT)
                syslog(LOG_NOTICE,
                       "Remove of supposedly empty directory %s failed: %m",
                       path);
            p = strrchr(path, '/');
            if (p) *p = '\0';
        }

         
        ntail = strrchr(nbuf, '.');
        if (!ntail || strchr(ntail, '!')) {
             
            break;
        }
        *ntail = '\0';
        if (!strcmp(nbuf, "user") ||
            ((ntail - nbuf > 5) && !strcmp(ntail-5, "!user"))) {
             
            break;
        }

        r = mboxlist_lookup(nbuf, &mbentry, NULL);
         
        if (!r) {
            if (!(mbentry->mbtype & MBTYPE_MOVING) && strcmp(mbentry->partition, part))
                r = IMAP_MAILBOX_NONEXISTENT;
            mboxlist_entry_free(&mbentry);
        }
    } while (r == IMAP_MAILBOX_NONEXISTENT);

    strarray_fini(&paths);

    return 0;
}