static int rotateSingleLog(const struct logInfo *log, unsigned logNum,
                           struct logState *state, struct logNames *rotNames)
{
    int hasErrors = 0;
    struct stat sb;
    char *savedContext = NULL;

    if (!state->doRotate)
        return 0;

    if (!hasErrors) {

        if (!(log->flags & (LOG_FLAG_COPYTRUNCATE | LOG_FLAG_COPY))) {
            if (setSecCtxByName(log->files[logNum], &savedContext) != 0) {
                /* error msg already printed */
                return 1;
            }
#ifdef WITH_ACL
            if ((prev_acl = acl_get_file(log->files[logNum], ACL_TYPE_ACCESS)) == NULL) {
                if (is_acl_well_supported(errno)) {
                    message(MESS_ERROR, "getting file ACL %s: %s\n",
                            log->files[logNum], strerror(errno));
                    hasErrors = 1;
                }
            }
#endif /* WITH_ACL */
            if (log->flags & LOG_FLAG_TMPFILENAME) {
                char *tmpFilename;

                if (asprintf(&tmpFilename, "%s%s", log->files[logNum], ".tmp") < 0) {
                    message_OOM();
                    restoreSecCtx(&savedContext);
                    return 1;
                }

                message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
                        tmpFilename);
                if (!debug && !hasErrors && rename(log->files[logNum], tmpFilename)) {
                    message(MESS_ERROR, "failed to rename %s to %s: %s\n",
                            log->files[logNum], tmpFilename,
                            strerror(errno));
                    hasErrors = 1;
                }

                free(tmpFilename);
            }
            else {
                message(MESS_DEBUG, "renaming %s to %s\n", log->files[logNum],
                        rotNames->finalName);
                if (!debug && !hasErrors &&
                        rename(log->files[logNum], rotNames->finalName)) {
                    message(MESS_ERROR, "failed to rename %s to %s: %s\n",
                            log->files[logNum], rotNames->finalName,
                            strerror(errno));
                    hasErrors = 1;
                }
            }

            if (!log->rotateCount) {
                const char *ext = "";
                if (log->compress_ext && (log->flags & LOG_FLAG_COMPRESS))
                    ext = log->compress_ext;

                free(rotNames->disposeName);
                if (asprintf(&rotNames->disposeName, "%s%s", rotNames->finalName, ext) < 0) {
                    message_OOM();
                    return 1;
                }

                message(MESS_DEBUG, "disposeName will be %s\n", rotNames->disposeName);
            }
        }

        if (!hasErrors && (log->flags & LOG_FLAG_CREATE) &&
                !(log->flags & (LOG_FLAG_COPYTRUNCATE | LOG_FLAG_COPY))) {
            int have_create_mode = 0;

            if (log->createUid == NO_UID)
                sb.st_uid = state->sb.st_uid;
            else
                sb.st_uid = log->createUid;

            if (log->createGid == NO_GID)
                sb.st_gid = state->sb.st_gid;
            else
                sb.st_gid = log->createGid;
            if (log->createMode == NO_MODE)
                sb.st_mode = state->sb.st_mode & 0777;
            else {
                sb.st_mode = log->createMode;
                have_create_mode = 1;
            }

            message(MESS_DEBUG, "creating new %s mode = 0%o uid = %d "
                    "gid = %d\n", log->files[logNum], (unsigned int) sb.st_mode,
                    (int) sb.st_uid, (int) sb.st_gid);

            if (!debug) {
                if (!hasErrors) {
                    int fd = createOutputFile(log->files[logNum], O_CREAT | O_RDWR,
                            &sb, prev_acl, have_create_mode);
#ifdef WITH_ACL
                    if (prev_acl) {
                        acl_free(prev_acl);
                        prev_acl = NULL;
                    }
#endif
                    if (fd < 0)
                        hasErrors = 1;
                    else {
                        close(fd);
                    }
                }
            }
        }

        restoreSecCtx(&savedContext);

        if (!hasErrors
                && (log->flags & (LOG_FLAG_COPYTRUNCATE | LOG_FLAG_COPY))
                && !(log->flags & LOG_FLAG_TMPFILENAME)) {
            hasErrors = copyTruncate(log->files[logNum], rotNames->finalName,
                                     &state->sb, log->flags, !log->rotateCount);
        }

#ifdef WITH_ACL
        if (prev_acl) {
            acl_free(prev_acl);
            prev_acl = NULL;
        }
#endif /* WITH_ACL */

    }
    return hasErrors;
}