Пример #1
0
int lua_apr_time_format(lua_State *L)
{
  char formatted[1024];
  apr_status_t status;
  const char *format;

  luaL_checktype(L, 1, LUA_TSTRING);
  format = lua_tostring(L, 1);

  if (strcmp(format, "ctime") == 0) {
    status = apr_ctime(formatted, time_check(L, 2));
    if (status != APR_SUCCESS)
      return push_error_status(L, status);
    lua_pushlstring(L, formatted, APR_CTIME_LEN - 1);
    return 1;
  } else if (strcmp(format, "rfc822") == 0) {
    status = apr_rfc822_date(formatted, time_check(L, 2));
    if (status != APR_SUCCESS)
      return push_error_status(L, status);
    lua_pushlstring(L, formatted, APR_RFC822_DATE_LEN - 1);
    return 1;
  } else {
    apr_time_exp_t components = { 0 };
    apr_size_t length = count(formatted);
    time_check_exploded(L, 2, &components, 1);
    status = apr_strftime(formatted, &length, length, format, &components);
    if (status != APR_SUCCESS)
      return push_error_status(L, status);
    lua_pushlstring(L, formatted, length);
    return 1;
  }
}
Пример #2
0
int logging_rotateLogFile(mm_logger* log) {
    mm_logger* ltmp;
    apr_finfo_t finfo;
    apr_time_t tnow;
    apr_time_exp_t texp;
    apr_status_t st;
    apr_size_t tbuflen,tbufmax=64;
    char tbuf[64],*newPath;

    st=apr_stat(&finfo,log->filepath,APR_FINFO_SIZE,log->p);

    if(finfo.size > log->maxLogFileSizeMB*1024*1024) {
        apr_file_printf(log->file,"Monitor File Size [%dB], Max Value [%dB].\r\n",finfo.size,log->maxLogFileSizeMB*1024*1024);
        logging_closeLogger(log);
        log->file=NULL;

        tnow=apr_time_now();
        memset(tbuf,'\0',64);
        apr_time_exp_lt(&texp,tnow);
        apr_strftime(tbuf,&tbuflen,tbufmax,"%F-%H_%M_%S",&texp);
        newPath=apr_psprintf(log->p,"%s.%s.%d",log->filepath,tbuf,texp.tm_usec);
        apr_file_rename(log->filepath,newPath,log->p);
        ltmp=logging_getLogger(log->p,log->filepath,log->maxLogFileSizeMB);
        log->file=ltmp->file;

        return TRUE;
    }
    return FALSE;
}
Пример #3
0
int lc_rotateLogFile() {
    apr_status_t status=0;
    int cur_pid;
    cur_pid=getpid();
    if(refreshLogger.status!=APR_SUCCESS||cur_pid!=refreshLogger.pid) {
        //printf("\nLogfile has not been opened.\n");
        return FALSE;
    }

    lc_closeLogFile();

    apr_time_t tnow;
    apr_time_exp_t texp;
    apr_size_t tbuflen,tbufmax=64;
    char tbuf[64],*renamedPath;

    tnow=apr_time_now();
    memset(tbuf,'\0',64);
    apr_time_exp_lt(&texp,tnow);
    apr_strftime(tbuf,&tbuflen,tbufmax,"%F-%H_%M_%S",&texp);
    renamedPath=apr_psprintf(refreshLogger.logger.p,"%s.%s.%d",refreshLogger.logger.filepath,tbuf,texp.tm_usec);
    status = apr_file_rename(refreshLogger.logger.filepath,renamedPath,refreshLogger.logger.p);
    // open a new file
    status = lc_openLogFile(refreshLogger.logger.p, refreshLogger.logger.filepath);
    return status;
}
Пример #4
0
 static const LogString getTimeZoneName()
 {
   const int MAX_TZ_LENGTH = 255;
   char tzName[MAX_TZ_LENGTH];
   apr_size_t tzLength;
   apr_time_exp_t tm;
   apr_time_exp_lt(&tm, 0);
   apr_strftime(tzName, &tzLength, MAX_TZ_LENGTH, "%Z", &tm);
   if (tzLength == 0) {
     apr_strftime(tzName, &tzLength, MAX_TZ_LENGTH, "%z", &tm);
   }
   tzName[tzLength] = 0;
   LogString retval;
   log4cxx::helpers::Transcoder::decode(tzName, retval);
   return retval;
 }
Пример #5
0
static const char *log_request_time_custom(request_rec *r, char *a,
                                           apr_time_exp_t *xt)
{
    apr_size_t retcode;
    char tstr[MAX_STRING_LEN];
    apr_strftime(tstr, &retcode, sizeof(tstr), a, xt);
    return apr_pstrdup(r->pool, tstr);
}
Пример #6
0
static void jk2_logger_file_setTimeStr(jk_env_t *env, char *str, int len)
{
    apr_time_exp_t gmt;
    apr_size_t     l;

    apr_time_exp_gmt(&gmt, apr_time_now());
    apr_strftime(str, &l, len, jk2_logger_file_logFmt, &gmt);
}
Пример #7
0
static const char *ap_pstrftime(apr_pool_t *p, const char *format, apr_time_exp_t *tm) {
    size_t got, len = strlen(format) + 1;
    const char *fp = strchr(format, '%');
    char *buf = NULL;
    while (NULL != fp) {
        len += 10;   /* approx only, will fail if anything generates a huge expansion */
        fp = strchr(fp + 1, '%');
    }

    buf = apr_palloc(p, len);
    apr_strftime(buf, &got, len, format, tm);
    return buf;
}
Пример #8
0
SWITCH_DECLARE(switch_status_t) switch_strftime(char *s, switch_size_t *retsize, switch_size_t max, const char *format, switch_time_exp_t *tm)
{
	const char *p = format;

	if (!p)
		return SWITCH_STATUS_FALSE;

	while (*p) {
		if (*p == '%') {
			switch (*(++p)) {
			case 'C':
			case 'D':
			case 'r':
			case 'R':
			case 'T':
			case 'e':
			case 'a':
			case 'A':
			case 'b':
			case 'B':
			case 'c':
			case 'd':
			case 'H':
			case 'I':
			case 'j':
			case 'm':
			case 'M':
			case 'p':
			case 'S':
			case 'U':
			case 'w':
			case 'W':
			case 'x':
			case 'X':
			case 'y':
			case 'Y':
			case 'z':
			case 'Z':
			case '%':
				p++;
				continue;
			case '\0':
			default:
				return SWITCH_STATUS_FALSE;
			}
		}
		p++;
	}

	return apr_strftime(s, retsize, max, format, (apr_time_exp_t *) tm);
}
Пример #9
0
static void test_strftimesmall(CuTest *tc)
{
    apr_status_t rv;
    apr_time_exp_t xt;
    char str[STR_SIZE];
    apr_size_t sz;

    rv = apr_time_exp_gmt(&xt, now);
    rv = apr_strftime(str, &sz, STR_SIZE, "%T", &xt);
    if (rv == APR_ENOTIMPL) {
        CuNotImpl(tc, "apr_strftime");
    }
    CuAssertTrue(tc, rv == APR_SUCCESS);
    CuAssertStrEquals(tc, "19:05:36", str);
}
Пример #10
0
static void test_strftimeoffset(CuTest *tc)
{
    apr_status_t rv;
    apr_time_exp_t xt;
    char str[STR_SIZE];
    apr_size_t sz;
    apr_int32_t hr_off = -5 * 3600; /* 5 hours in seconds */

    apr_time_exp_tz(&xt, now, hr_off);
    rv = apr_strftime(str, &sz, STR_SIZE, "%T", &xt);
    if (rv == APR_ENOTIMPL) {
        CuNotImpl(tc, "apr_strftime");
    }
    CuAssertTrue(tc, rv == APR_SUCCESS);
}
Пример #11
0
static void test_strftime(CuTest *tc)
{
    apr_status_t rv;
    apr_time_exp_t xt;
    char *str = NULL;
    apr_size_t sz;

    rv = apr_time_exp_gmt(&xt, now);
    str = apr_palloc(p, STR_SIZE + 1);
    rv = apr_strftime(str, &sz, STR_SIZE, "%R %A %d %B %Y", &xt);
    if (rv == APR_ENOTIMPL) {
        CuNotImpl(tc, "apr_strftime");
    }
    CuAssertTrue(tc, rv == APR_SUCCESS);
    CuAssertStrEquals(tc, "19:05 Saturday 14 September 2002", str);
}
Пример #12
0
static void
badge_emit_timestamp(request_rec * r, const char * fromto, time_t value,
	int rdonly, badge_timestamp * ts, int errflags, int yearerr,
	int montherr, int dayerr, int hourerr, int minerr, int secerr)

{
	apr_time_exp_t exptime;
	apr_time_t aprtime;
	apr_size_t len;
	char buf[100];

	/**
	***	Emit a timestamp in an html table row, either as normal text
	***		from `value' or as input fields with values from `*ts'
	***		according to the `rdonly' flag.
	**/

	ap_rvputs(r, "<tr><td>Valid ", fromto, "</td><td>", NULL);

	if (rdonly) {
		apr_time_ansi_put(&aprtime, value);
		apr_time_exp_tz(&exptime, aprtime, 0);
		apr_strftime(buf, &len, sizeof buf - 1, "%c", &exptime);
		buf[len] = '\0';
		ap_rvputs(r, ap_escape_html(r->pool, buf), NULL);
		}
	else {
		ap_rvputs(r, "Y<input type=\"text\" name=\"", fromto,
		    "-year\" value=\"",
		    ts->year? ap_escape_html(r->pool, ts->year): "",
		    "\"", badge_arg_err(errflags & yearerr), " />", NULL);
		badge_emit_range_select(r, "M", fromto,
		    "month", 1, 12, ts->month, errflags & montherr);
		badge_emit_range_select(r, "D", fromto,
		    "day", 1, 31, ts->day, errflags & dayerr);
		badge_emit_range_select(r, "H", fromto,
		    "hour", 0, 23, ts->hour, errflags & hourerr);
		badge_emit_range_select(r, "M", fromto,
		    "min", 0, 59, ts->min, errflags & minerr);
		badge_emit_range_select(r, "S", fromto,
		    "sec", 0, 59, ts->sec, errflags & secerr);
		}

	ap_rvputs(r, "</td></tr>\n", NULL);
}
Пример #13
0
static char * add_auth_token(apr_pool_t *pool, saxctxt *ctx, apr_uri_t *u)
{
  apr_uri_t u2 = *u;
  const char *unparsed_uri, *auth_token, *ip;
  char *timestamp, *forwarded_list, *last;
  apr_status_t rv;
  apr_time_exp_t xt;
  apr_size_t sz;
  apr_table_t *params;

  unparsed_uri = apr_uri_unparse(pool, &u2, APR_URI_UNP_OMITQUERY);

  rv = apr_time_exp_lt(&xt, apr_time_now() + apr_time_from_sec(ctx->cfg->auth_exptime));
  timestamp = apr_palloc(pool, TIME_STR_SIZE + 1);
  rv = apr_strftime(timestamp, &sz, TIME_STR_SIZE, "%FT%T%z", &xt);

  if (u2.query)
    u2.query = apr_pstrcat(pool, u2.query, "&vox_timestamp=", timestamp, NULL);
  else
    u2.query = apr_pstrcat(pool, "vox_timestamp=", timestamp, NULL);

  /* Convert the query string to a table */
  params = apr_table_make(pool, 1);
  qs_to_table(u2.query, params, pool);

  /* Generate the auth token */
  forwarded_list = (char *)apr_table_get(ctx->f->r->headers_in, "X-Forwarded-For");
  /* If X-Forwarded-For header exists, use first IP in it */
  if (forwarded_list &&
      (forwarded_list = apr_pstrdup(pool, forwarded_list)) &&
      (ip = apr_strtok(forwarded_list, ", \t", &last)))
    auth_token = make_auth_token(ctx->f->r, ip, unparsed_uri, params,
                                 ctx->cfg->auth_key);
  else /* Otherwise, use the normal remote_ip */
    auth_token = make_auth_token(ctx->f->r, ctx->f->r->connection->remote_ip,
                                 unparsed_uri, params, ctx->cfg->auth_key);

  if (auth_token) {
    u2.query = apr_pstrcat(pool, u2.query, "&vox_sig=", auth_token, NULL);
    ap_log_error(APLOG_MARK, APLOG_INFO, APR_SUCCESS, ctx->f->r->server,
                 "add_auth_token: new query string is %s", u2.query);
  }

  return u2.query;
}
int slayer_server_log_request(slayer_server_log_manager_t *manager, apr_pool_t *mpool, apr_socket_t *conn,
                               const char *request_line, int response_code, int nbytes_sent, apr_int64_t time_toservice) {
	//generate data
	char dstring[1024];
	apr_int64_t current_time = apr_time_now();
	apr_size_t result_size;
	apr_time_exp_t ltime;
	apr_time_exp_lt(&ltime,current_time);
	apr_strftime (dstring, &result_size, sizeof(dstring), "%d/%b/%Y:%H:%M:%S %z", &ltime );

	apr_sockaddr_t *client_addr;
	char *client_ip;
	apr_socket_addr_get(&client_addr,0,conn);
	apr_sockaddr_ip_get(&client_ip,client_addr);
	if (manager->fhandle) {
		char *message = apr_pstrcat(mpool,client_ip," - - ","[",dstring,"] \"",request_line,"\" ",
		                            apr_itoa(mpool,response_code)," ",apr_itoa(mpool,nbytes_sent), " ",apr_ltoa(mpool,time_toservice), "\n",NULL);
		slayer_server_log_message(manager,message);
	}
	slayer_server_log_add_entry(manager,mpool,client_ip,current_time,request_line,response_code,nbytes_sent,time_toservice);
	return 0;
}
Пример #15
0
SWITCH_DECLARE(switch_status_t) switch_strftime_nocheck(char *s, switch_size_t *retsize, switch_size_t max, const char *format, switch_time_exp_t *tm)
{
	return apr_strftime(s, retsize, max, format, (apr_time_exp_t *) tm);
}
Пример #16
0
/* This implements the svn_client_list_func_t API, printing a single
   directory entry in text format. */
static svn_error_t *
print_dirent(void *baton,
             const char *path,
             const svn_dirent_t *dirent,
             const svn_lock_t *lock,
             const char *abs_path,
             apr_pool_t *pool)
{
  struct print_baton *pb = baton;
  const char *entryname;

  if (pb->ctx->cancel_func)
    SVN_ERR(pb->ctx->cancel_func(pb->ctx->cancel_baton));

  if (strcmp(path, "") == 0)
    {
      if (dirent->kind == svn_node_file)
        entryname = svn_dirent_basename(abs_path, pool);
      else if (pb->verbose)
        entryname = ".";
      else
        /* Don't bother to list if no useful information will be shown. */
        return SVN_NO_ERROR;
    }
  else
    entryname = path;

  if (pb->verbose)
    {
      apr_time_t now = apr_time_now();
      apr_time_exp_t exp_time;
      apr_status_t apr_err;
      apr_size_t size;
      char timestr[20];
      const char *sizestr, *utf8_timestr;

      /* svn_time_to_human_cstring gives us something *way* too long
         to use for this, so we have to roll our own.  We include
         the year if the entry's time is not within half a year. */
      apr_time_exp_lt(&exp_time, dirent->time);
      if (apr_time_sec(now - dirent->time) < (365 * 86400 / 2)
          && apr_time_sec(dirent->time - now) < (365 * 86400 / 2))
        {
          apr_err = apr_strftime(timestr, &size, sizeof(timestr),
                                 _("%b %d %H:%M"), &exp_time);
        }
      else
        {
          apr_err = apr_strftime(timestr, &size, sizeof(timestr),
                                 _("%b %d  %Y"), &exp_time);
        }

      /* if that failed, just zero out the string and print nothing */
      if (apr_err)
        timestr[0] = '\0';

      /* we need it in UTF-8. */
      SVN_ERR(svn_utf_cstring_to_utf8(&utf8_timestr, timestr, pool));

      sizestr = apr_psprintf(pool, "%" SVN_FILESIZE_T_FMT, dirent->size);

      return svn_cmdline_printf
              (pool, "%7ld %-8.8s %c %10s %12s %s%s\n",
               dirent->created_rev,
               dirent->last_author ? dirent->last_author : " ? ",
               lock ? 'O' : ' ',
               (dirent->kind == svn_node_file) ? sizestr : "",
               utf8_timestr,
               entryname,
               (dirent->kind == svn_node_dir) ? "/" : "");
    }
  else
    {
      return svn_cmdline_printf(pool, "%s%s\n", entryname,
                                (dirent->kind == svn_node_dir)
                                ? "/" : "");
    }
}
Пример #17
0
const char *
svn_time_to_human_cstring(apr_time_t when, apr_pool_t *pool)
{
    apr_time_exp_t exploded_time;
    apr_size_t len, retlen;
    apr_status_t ret;
    char *datestr, *curptr, human_datestr[SVN_TIME__MAX_LENGTH];

    /* Get the time into parts */
    ret = apr_time_exp_lt(&exploded_time, when);
    if (ret)
        return NULL;

    /* Make room for datestring */
    datestr = apr_palloc(pool, SVN_TIME__MAX_LENGTH);

    /* Put in machine parseable part */
    len = apr_snprintf(datestr,
                       SVN_TIME__MAX_LENGTH,
                       HUMAN_TIMESTAMP_FORMAT,
                       exploded_time.tm_year + 1900,
                       exploded_time.tm_mon + 1,
                       exploded_time.tm_mday,
                       exploded_time.tm_hour,
                       exploded_time.tm_min,
                       exploded_time.tm_sec,
                       exploded_time.tm_gmtoff / (60 * 60),
                       (abs(exploded_time.tm_gmtoff) / 60) % 60);

    /* If we overfilled the buffer, just return what we got. */
    if (len >= SVN_TIME__MAX_LENGTH)
        return datestr;

    /* Calculate offset to the end of the machine parseable part. */
    curptr = datestr + len;

    /* Put in human explanatory part */
    ret = apr_strftime(human_datestr,
                       &retlen,
                       SVN_TIME__MAX_LENGTH - len,
                       human_timestamp_format_suffix,
                       &exploded_time);

    /* If there was an error, ensure that the string is zero-terminated. */
    if (ret || retlen == 0)
        *curptr = '\0';
    else
    {
        const char *utf8_string;
        svn_error_t *err;

        err = svn_utf_cstring_to_utf8(&utf8_string, human_datestr, pool);
        if (err)
        {
            *curptr = '\0';
            svn_error_clear(err);
        }
        else
            apr_cpystrn(curptr, utf8_string, SVN_TIME__MAX_LENGTH - len);
    }

    return datestr;
}
Пример #18
0
/* Send the authentication to the log table */
int
pg_log_auth_user(request_rec * r, pg_auth_config_rec * sec, char *user,
				 char *sent_pw)
{
	char sql[MAX_STRING_LEN];
	char *s;
	int n;
	char fields[MAX_STRING_LEN];
	char values[MAX_STRING_LEN];
	char *safe_user;
	char *safe_pw;
	char *safe_req;
	char ts[MAX_STRING_LEN];	/* time in string format */
	apr_time_exp_t t;			/* time of request start */
	apr_size_t retsize;

	safe_user = apr_palloc(r->pool, 1 + 2 * strlen(user));
	safe_pw = apr_palloc(r->pool, 1 + 2 * strlen(sent_pw));
	safe_req = apr_palloc(r->pool, 1 + 2 * strlen(r->the_request));

	/* we do not want to process internal redirect  */
	if (!ap_is_initial_req(r))
		return DECLINED;
	if ((!sec->auth_pg_log_table) || (!sec->auth_pg_log_uname_field) || (!sec->auth_pg_log_date_field)) {	// At least table name, username and date field are specified
		// send error message and exit 
		return DECLINED;
	}

	/* AUD: MAX_STRING_LEN probably isn't always correct */
	pg_check_string(safe_user, user, strlen(user));
	pg_check_string(safe_pw, sent_pw, strlen(sent_pw));
	pg_check_string(safe_req, r->the_request, strlen(r->the_request));


	if (sec->auth_pg_lowercaseuid) {
		/* and force it to lowercase */
		n = 0;
		while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
			if (isupper(safe_user[n])) {
				safe_user[n] = tolower(safe_user[n]);
			}
			n++;
		}
	}

	if (sec->auth_pg_uppercaseuid) {
		/* and force it to uppercase */
		n = 0;
		while (safe_user[n] && n < (MAX_STRING_LEN - 1)) {
			if (islower(safe_user[n])) {
				safe_user[n] = toupper(safe_user[n]);
			}
			n++;
		}
	}


	/* time field format  */
	apr_time_exp_lt(&t, r->request_time);
	apr_strftime(ts, &retsize, 100, "%Y-%m-%d %H:%M:%S", &t);



	/* SQL Statement, required fields: Username, Date */
	apr_snprintf(fields, MAX_STRING_LEN, "%s,%s",
				 sec->auth_pg_log_uname_field,
				 sec->auth_pg_log_date_field);
	apr_snprintf(values, MAX_STRING_LEN, "'%s','%s'", safe_user, ts);

	/* Optional parameters */
	if (sec->auth_pg_log_addrs_field) {	/* IP Address field */
		apr_snprintf(sql, MAX_STRING_LEN, ", %s",
					 sec->auth_pg_log_addrs_field);
		strncat(fields, sql, MAX_STRING_LEN - strlen(fields) - 1);
		apr_snprintf(sql, MAX_STRING_LEN, ", '%s'",
					 r->connection->remote_ip);
		strncat(values, sql, MAX_STRING_LEN - strlen(values) - 1);
	}
	if (sec->auth_pg_log_pwd_field) {	/* Password field , clear WARNING */
		apr_snprintf(sql, MAX_STRING_LEN, ", %s",
					 sec->auth_pg_log_pwd_field);
		strncat(fields, sql, MAX_STRING_LEN - strlen(fields) - 1);
		apr_snprintf(sql, MAX_STRING_LEN, ", '%s'", safe_pw);
		strncat(values, sql, MAX_STRING_LEN - strlen(values) - 1);
	}
	if (sec->auth_pg_log_uri_field) {	/* request string */
		apr_snprintf(sql, MAX_STRING_LEN, ", %s",
					 sec->auth_pg_log_uri_field);
		strncat(fields, sql, MAX_STRING_LEN - strlen(fields) - 1);
		apr_snprintf(sql, MAX_STRING_LEN, ", '%s'", safe_req);
		strncat(values, sql, MAX_STRING_LEN - strlen(values) - 1);
	}

	apr_snprintf(sql, MAX_STRING_LEN, "insert into %s (%s) values(%s) ; ",
				 sec->auth_pg_log_table, fields, values);

	s = do_pg_query(r, sql, sec);
	return (0);
}
/*
 * Open a new log file, and if successful
 * also close the old one.
 *
 * The timestamp for the calculation of the file
 * name of the new log file will be the actual millisecond
 * timestamp, except when a regular rotation based on a time
 * interval is configured and the previous interval
 * is over. Then the timestamp is the starting time
 * of the actual interval.
 */
static void doRotate(rotate_config_t *config, rotate_status_t *status)
{

    int now = get_now(config);
    int tLogStart;
    apr_status_t rv;
    struct logfile newlog;
    int thisLogNum = -1;

    status->rotateReason = ROTATE_NONE;

    if (config->tRotation) {
        int tLogEnd;
        tLogStart = (now / config->tRotation) * config->tRotation;
        tLogEnd = tLogStart + config->tRotation;
        /*
         * Check if rotation was forced and the last rotation
         * interval is not yet over. Use the value of now instead
         * of the time interval boundary for the file name then.
         */
        if (tLogStart < status->tLogEnd) {
            tLogStart = now;
        }
        status->tLogEnd = tLogEnd;
    }
    else {
        tLogStart = now;
    }

    if (config->use_strftime) {
        apr_time_t tNow = apr_time_from_sec(tLogStart);
        apr_time_exp_t e;
        apr_size_t rs;

        apr_time_exp_gmt(&e, tNow);
        apr_strftime(newlog.name, &rs, sizeof(newlog.name), config->szLogRoot, &e);
    }
    else {
        if (config->truncate) {
            apr_snprintf(newlog.name, sizeof(newlog.name), "%s", config->szLogRoot);
        }
        else if (config->num_files > 0) { 
            if (status->fileNum == -1 || status->fileNum == (config->num_files - 1)) {
                thisLogNum = 0;
                apr_snprintf(newlog.name, sizeof(newlog.name), "%s", config->szLogRoot);
            }
            else { 
                thisLogNum = status->fileNum + 1;
                apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%d", config->szLogRoot, thisLogNum);
            }
        }
        else {
            apr_snprintf(newlog.name, sizeof(newlog.name), "%s.%010d", config->szLogRoot,
                         tLogStart);
        }
    }
    apr_pool_create(&newlog.pool, status->pool);
    if (config->verbose) {
        fprintf(stderr, "Opening file %s\n", newlog.name);
    }
    rv = apr_file_open(&newlog.fd, newlog.name, APR_WRITE | APR_CREATE | APR_APPEND
                       | (config->truncate || (config->num_files > 0 && status->current.fd) ? APR_TRUNCATE : 0), 
                       APR_OS_DEFAULT, newlog.pool);
    if (rv == APR_SUCCESS) {
        /* Handle post-rotate processing. */
        post_rotate(newlog.pool, &newlog, config, status);

        status->fileNum = thisLogNum;
        /* Close out old (previously 'current') logfile, if any. */
        if (status->current.fd) {
            close_logfile(config, &status->current);
        }

        /* New log file is now 'current'. */
        status->current = newlog;
    }
    else {
        char error[120];

        apr_strerror(rv, error, sizeof error);

        /* Uh-oh. Failed to open the new log file. Try to clear
         * the previous log file, note the lost log entries,
         * and keep on truckin'. */
        if (status->current.fd == NULL) {
            fprintf(stderr, "Could not open log file '%s' (%s)\n", newlog.name, error);
            exit(2);
        }

        /* Throw away new state; it isn't going to be used. */
        apr_pool_destroy(newlog.pool);

        /* Try to keep this error message constant length
         * in case it occurs several times. */
        apr_snprintf(status->errbuf, sizeof status->errbuf,
                     "Resetting log file due to error opening "
                     "new log file, %10d messages lost: %-25.25s\n",
                     status->nMessCount, error);

        truncate_and_write_error(status);
    }

    status->nMessCount = 0;
}