static int createOutputFile(const char *fileName, int flags, const struct stat *sb,
                            acl_type acl, int force_mode)
{
    int fd = -1;
    struct stat sb_create;
    int acl_set = 0;
    int i;

    for (i = 0; i < 2; ++i) {
        struct tm now;
        size_t fileName_size, buf_size;
        char *backupName, *ptr;

        fd = open(fileName, (flags | O_CREAT | O_EXCL | O_NOFOLLOW),
                (S_IRUSR | S_IWUSR) & sb->st_mode);

        if ((fd >= 0) || (errno != EEXIST))
            break;

        /* the destination file already exists, while it should not */
        localtime_r(&nowSecs, &now);
        fileName_size = strlen(fileName);
        buf_size = fileName_size + sizeof("-YYYYMMDDHH.backup");
        backupName = malloc(buf_size);
        if (!backupName) {
            message_OOM();
            return -1;
        }
        ptr = backupName;

        /* construct backupName starting with fileName */
        strcpy(ptr, fileName);
        ptr += fileName_size;
        buf_size -= fileName_size;

        /* append the -YYYYMMDDHH time stamp and the .backup suffix */
        ptr += strftime(ptr, buf_size, "-%Y%m%d%H", &now);
        strcpy(ptr, ".backup");

        message(MESS_ERROR, "destination %s already exists, renaming to %s\n",
                fileName, backupName);
        if (rename(fileName, backupName) != 0) {
            message(MESS_ERROR, "error renaming already existing output file"
                    " %s to %s: %s\n", fileName, backupName, strerror(errno));
            free(backupName);
            return -1;
        }

        free(backupName);

        /* existing file renamed, try it once again */
    }

    if (fd < 0) {
        message(MESS_ERROR, "error creating output file %s: %s\n",
                fileName, strerror(errno));
        return -1;
    }
    if (fchmod(fd, (S_IRUSR | S_IWUSR) & sb->st_mode)) {
        message(MESS_ERROR, "error setting mode of %s: %s\n",
                fileName, strerror(errno));
        close(fd);
        return -1;
    }

    if (fstat(fd, &sb_create)) {
        message(MESS_ERROR, "fstat of %s failed: %s\n", fileName,
                strerror(errno));
        close(fd);
        return -1;
    }

    /* Only attempt to set user/group if running as root */
    if (
        ROOT_UID == geteuid() &&
        (sb_create.st_uid != sb->st_uid || sb_create.st_gid != sb->st_gid) &&
        fchown(fd, sb->st_uid, sb->st_gid)
    ) {
        message(MESS_ERROR, "error setting owner of %s to uid %u and gid %u: %s\n",
                fileName, (unsigned) sb->st_uid, (unsigned) sb->st_gid, strerror(errno));
        close(fd);
        return -1;
    }

#ifdef WITH_ACL
    if (!force_mode && acl) {
        if (acl_set_fd(fd, acl) == -1) {
            if (is_acl_well_supported(errno)) {
                message(MESS_ERROR, "setting ACL for %s: %s\n",
                        fileName, strerror(errno));
                close(fd);
                return -1;
            }
            acl_set = 0;
        }
        else {
            acl_set = 1;
        }
    }
#else
    (void) acl;
#endif

    if (!acl_set || force_mode) {
        if (fchmod(fd, sb->st_mode)) {
            message(MESS_ERROR, "error setting mode of %s: %s\n",
                    fileName, strerror(errno));
            close(fd);
            return -1;
        }
    }

    return fd;
}