static int
_removeIncompleteCaches(const char *path) {
    DIR *dir = opendir(path);
    char filepath[MAX_NAME_LEN];
    struct dirent *entry;
    struct stat statbuf;
    int filenameLen;
    int extLen;
    int status;
    int statusFailed = 0;

    if (dir != NULL) {
        while ((entry = readdir(dir)) != NULL) {
            if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..")) {
                continue;
            }

            snprintf(filepath, MAX_NAME_LEN, "%s/%s", path, entry->d_name);

            if (!stat(filepath, &statbuf)) {
                // has entry
                if (S_ISDIR(statbuf.st_mode)) {
                    // directory
                    status = _removeIncompleteCaches(filepath);
                    if (status < 0) {
                        statusFailed = status;
                    }

                    if (isEmptyDir(filepath) == 0) {
                        rodsLog (LOG_DEBUG, "_removeIncompleteCaches: removing empty dir : %s", filepath);
                        status = rmdir(filepath);
                        if (status < 0) {
                            statusFailed = status;
                        }
                    }
                } else {
                    // file
                    filenameLen = strlen(entry->d_name);
                    extLen = strlen(PRELOAD_FILES_IN_DOWNLOADING_EXT);

                    if (filenameLen > extLen && !strcmp(entry->d_name + filenameLen - extLen, PRELOAD_FILES_IN_DOWNLOADING_EXT)) {
                        // found incomplete cache
                        rodsLog (LOG_DEBUG, "_removeIncompleteCaches: removing incomplete cache : %s", filepath);

                        status = unlink(filepath);
                        if (status < 0) {
                            statusFailed = status;
                        }
                    }
                }
            }
        }
        closedir(dir);
    }

    return statusFailed;
}
int my_rmdir(int argc, char* argv[])
{
    result_t result = NONE;
    const int uid = running->uid;
    const int device = running->cwd->device;

    if(argc < 2)
    {
        fprintf(stderr, "rmdir: missing operand\n");
        return MISSING_OPERAND;
    }

    // rmdir each path given by user
    int i = 1;
    while(i < argc)
    {
        char* path  = argv[i];
        int ino     = getino(device, path);
        MINODE* mip = iget(device, ino);

        // Verify file exists
        if(!mip)
        {
            result = DOES_NOT_EXIST;
            fprintf(stderr, "rmdir: failed to remove '%s':"
                    " No such file or directory\n", path);
            goto clean_up;
        }
        // Verify user has permission to remove the directory
        else if(uid != SUPER_USER && uid != mip->inode.i_uid)
        {
            result = PERM_DENIED;
            fprintf(stderr, "rmdir: failed to remove '%s':"
                    " Permission denied\n", path);
            goto clean_up;
        }
        // Verify that it is a directory
        else if(!S_ISDIR(mip->inode.i_mode))
        {
            result = NOT_DIR;
            fprintf(stderr, "rmdir: failed to remove '%s':"
                    " Not a directory\n", path);
            goto clean_up;
        }
        // Verify that it is not busy
        else if(mip->refCount > 1)
        {
            result = BUSY;
            fprintf(stderr, "rmdir: failed to remove directory '%s':"
                    " Directory busy\n", path);
            goto clean_up;
        }
        // Verify that it is empty
        else if(!isEmptyDir(mip))
        {
            result = NOT_EMPTY;
            fprintf(stderr, "rmdir: failed to remove directory '%s':"
                    " Directory not empty\n", path);
            goto clean_up;
        }

        // If removing multiple directories, display
        if(argc > 2)
            printf("rmdir: removing directory '%s'\n", path);

        INODE* ip = &mip->inode;

        // Get parent DIR's ino and Minode
        int parent_ino = 0;
        findino(mip, &ino, &parent_ino);
        MINODE* parent_mip = iget(device, parent_ino); 
        INODE*   parent_ip = &parent_mip->inode;

        // Deallocate its blocks
        for(int b = 0; b < NUM_DIRECT_BLOCKS && ip->i_block[b] != 0; b++)
            bfree(device, ip->i_block[b]);

        // Deallocate its inode
        ifree(device, ino);

        // Remove entry from parent directory
        rm_child(parent_mip, ino); 

        // Update parent's info
        parent_ip->i_links_count--;
        parent_ip->i_atime = time(0L);
        parent_ip->i_mtime = time(0L);
        parent_mip->dirty = true;

        // Write parent changes to disk
        iput(parent_mip);

clean_up:
        // Write changes to deleted directory to disk and clear refCount
        iput(mip); 

        if(result != NONE)
            return result;

        i++;
    }

    return SUCCESS;
}