log.c revision e0d98b5e6f4b658de5303bf8d74576d2555db68e
/**
* The contents of this file are subject to the terms of the Common Development and
* Distribution License (the License). You may not use this file except in compliance with the
* License.
*
* You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
* specific language governing permission and limitations under the License.
*
* When distributing Covered Software, include this CDDL Header Notice in each file and include
* the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
* Header, with the fields enclosed by brackets [] replaced by your own identifying
* information: "Portions copyright [year] [name of copyright owner]".
*
* Copyright 2014 - 2015 ForgeRock AS.
*/
#include "platform.h"
#include "am.h"
#include "utility.h"
#include "version.h"
#if defined(_WIN32)
static semaphore_t ic_sem;
#else
#endif
/**
* This flag says we want debugging messages when the instance id is zero
*/
struct am_shared_log {
void *area;
char area_file_name[AM_PATH_SIZE];
#ifdef _WIN32
int reader_pid;
#else
int area_file_id;
#endif
};
#ifdef _WIN32
struct am_shared_log_lock_s {
};
#endif
struct am_log {
volatile unsigned int in;
volatile unsigned int out;
volatile unsigned int read_count;
volatile unsigned int write_count;
unsigned int bucket_count;
unsigned int bucket_size;
#ifndef _WIN32
#endif
struct log_bucket {
char data[AM_LOG_MESSAGE_SIZE];
unsigned long instance_id;
int level;
volatile char ready_to_read;
struct log_files {
int used;
unsigned long instance_id;
char name_debug[AM_PATH_SIZE];
char name_audit[AM_PATH_SIZE];
int owner;
int fd_debug;
int fd_audit;
int max_size_debug;
int max_size_audit;
int level_debug;
int level_audit;
#ifndef _WIN32
#endif
int owner; /* current log reader process id */
struct valid_url {
unsigned long instance_id;
int url_index;
int running;
char config_path[AM_PATH_SIZE];
struct instance_init {
unsigned long instance_id;
int in_progress;
} init[AM_MAX_INSTANCES];
};
#ifndef _WIN32
/*****************************************************************************************/
switch (pthread_mutex_trylock(mtx)) {
case 0:
return AM_TRUE;
case EBUSY:
return AM_FALSE;
}
return AM_TRUE;
}
/*****************************************************************************************/
static void rename_file(const char *file_name) {
unsigned int idx = 1;
static char tmp[AM_PATH_SIZE];
do {
idx++;
}
}
#endif /* _WIN32 */
/*****************************************************************************************/
return AM_TRUE;
}
return AM_FALSE;
}
/*****************************************************************************************/
static void *am_log_worker(void *arg) {
unsigned int index;
char *data;
unsigned long instance_id;
struct log_files *f;
return NULL;
}
#ifdef _WIN32
#else
#endif
for (;;) {
#ifdef _WIN32
return NULL;
}
}
}
#else
return NULL;
}
}
}
#endif /* _WIN32 */
#ifdef _WIN32
#else
#endif /* _WIN32 */
f = NULL;
for (i = 0; i < AM_MAX_INSTANCES; i++) {
break;
}
}
if (f != NULL) {
if (ISINVALID(f->name_debug)) {
f->fd_debug = -1;
f->fd_audit = -1;
return NULL;
}
if (ISINVALID(f->name_audit)) {
f->fd_debug = -1;
f->fd_audit = -1;
return NULL;
}
/* log files are not opened yet, do it now */
#ifdef _WIN32
}
}
#else
}
}
#endif
}
if (f->fd_debug == -1) {
} else if (f->fd_audit == -1) {
} else {
#ifdef _WIN32
int wrote;
#else
#endif
#ifdef _WIN32
/* check file timestamp; rotate by date if set so */
unsigned int idx = 1;
static char tmp[AM_PATH_SIZE];
do {
idx++;
if (is_audit) {
} else {
}
} else {
file_name, GetLastError());
}
}
/* check file size; rotate by size if set so */
if (max_size > 0) {
}
unsigned int idx = 1;
static char tmp[AM_PATH_SIZE];
do {
idx++;
if (is_audit) {
} else {
}
} else {
file_name, GetLastError());
}
}
}
if (is_audit) {
f->fd_audit = -1;
} else {
f->fd_debug = -1;
}
#else
/* check file timestamp; rotate by date if set so */
}
/* check file size; rotate by size if set so */
}
/* reset file inode number (in case it has changed as a result of rename_file) */
if (is_audit) {
} else {
}
}
}
#endif
}
}
#ifdef _WIN32
#else
#endif
log->read_count--;
#ifdef _WIN32
#else
#endif
}
return NULL;
}
/*****************************************************************************************/
void am_log_re_init(int status) {
#ifdef _WIN32
}
#endif
}
/*****************************************************************************************/
int i;
char opened = 0;
#ifdef _WIN32
#endif
return;
}
if (am_log_handle == NULL) {
if (am_log_handle == NULL) {
return;
}
}
#ifndef _WIN32
return;
}
#endif
#ifdef __sun
"/am_log_%d"
#else
AM_GLOBAL_PREFIX"am_log_%d"
#endif
, id);
#ifdef _WIN32
}
return;
}
opened = 1;
}
0, 0, am_log_handle->area_size);
}
}
}
}
}
for (i = 0; i < AM_MAX_INSTANCES; i++) {
f->instance_id = 0;
f->max_size_debug = f->max_size_audit = 0;
}
}
}
#else
am_log_handle->area_file_id = shm_open(am_log_handle->area_file_name, O_CREAT | O_EXCL | O_RDWR, 0666);
return;
}
/* already there, open without O_EXCL and go; if
* something goes wrong, close and cleanup */
return;
} else {
opened = 1;
}
} else {
/* we just created the shm area, must setup; if
* something goes wrong, delete the shm area and
* cleanup
*/
return;
}
}
} else {
for (i = 0; i < AM_MAX_INSTANCES; i++) {
f->instance_id = 0;
f->max_size_debug = f->max_size_audit = 0;
}
}
}
}
#endif
}
/*****************************************************************************************/
#ifdef _WIN32
#endif
}
/**
* This function simply returns true or false depending on whether "level" specifies we
* need to log given the logger level settings for this instance. Note that the function
* should return an am_bool_t, but because of a circular dependency between am.h (which
* defines that type) and log.h (which needs that type), I'm changing it to "int".
*/
int i;
int log_level = AM_LOG_LEVEL_NONE;
int audit_level = AM_LOG_LEVEL_NONE;
/* If the instance id is zero, we are either running a test case, or installing something */
if (instance_id == 0) {
return zero_instance_logging_is_wanted;
}
/* We simply cannot log if the shared memory segment is not initialised */
return AM_FALSE;
}
#ifdef _WIN32
#else
#endif
for (i = 0; i < AM_MAX_INSTANCES; i++) {
break;
}
}
#ifdef _WIN32
#else
#endif
/* Do not log in the following cases:
*
* requested log level is set to LEVEL_NONE
* or
* selected (in a configuration) log level is LEVEL_NONE and requested log level is not LEVEL_AUDIT
* or
* selected audit level is LEVE_NONE and requested log level is LEVEL_AUDIT
*/
if (level == AM_LOG_LEVEL_NONE ||
return AM_FALSE;
}
/* In case requested log level is not LEVEL_AUDIT (as we must log audit message in case we
* got past the previous check) and its not LEVEL_ALWAYS (which must be logged too)
* and requested log level is "higher" than selected log level according to
* "DEBUG > INFO > WARNING > ERROR" schema - do not log.
*/
return AM_FALSE;
}
return AM_TRUE;
}
/**
* This routine is primarily responsible for all logging within this application.
* instance_id: the instance that has something to log
* level: the level we want to log at, see constants AM_LOG_LEVEL_* in am.h
* header: a header consisting of various time information and the current logging level as a string
* header_sz: header string length
* format: the printf style format string telling us about the variadic arguments
* args: the variadic arguments themselves.
*
* Normally, this routine logs into a block of shared memory, which is subsequently written to a file.
* However if we're running a unit test, this block of memory won't have been set up, even though we
* would still like to log something somewhere. If test cases ensure that instance_id is set to zero,
* then logging messages are written to the standard error.
*
* Note that if you're calling this function from one of the macros in log.h, then the function
* perform_logging will already have been called. If you're not, then consider calling that function
* first as it will save you a lot of work figuring out you didn't really want to log a message at
* your current logging level.
*/
void am_log_write(unsigned long instance_id, int level, const char* header, int header_sz, const char *format, ...) {
unsigned int index;
/**
* An instance id of zero indicates that we are running in unit test mode, shared memory is not
* initialised and so our only option, if we want to log, is to write to the standard error.
* Note that we ALWAYS log, no matter what the level.
*/
if (instance_id == 0) {
return;
}
return;
}
#ifdef _WIN32
}
#else
}
#endif
log->write_count++;
#ifdef _WIN32
#else
#endif
/* copy header into the bucket */
/* and the rest of the message */
}
#ifdef _WIN32
#else
#endif
log->read_count++;
log->write_count--;
#ifdef _WIN32
#else
#endif
}
void am_log_shutdown(int id) {
static const char *thisfunc = "am_log_shutdown():";
int i;
return;
}
/* notify the logger exit */
for (i = 0; i < AM_MAX_INSTANCES; i++) {
}
}
#ifdef _WIN32
}
/* close log file(s) */
for (i = 0; i < AM_MAX_INSTANCES; i++) {
if (f->fd_debug != -1) {
f->fd_debug = -1;
}
if (f->fd_audit != -1) {
f->fd_audit = -1;
}
f->instance_id = 0;
f->owner = 0;
f->max_size_debug = f->max_size_audit = 0;
break;
}
}
#else
/* close log file(s) */
for (i = 0; i < AM_MAX_INSTANCES; i++) {
if (f->fd_debug != -1) {
f->fd_debug = -1;
}
if (f->fd_audit != -1) {
f->fd_audit = -1;
}
f->instance_id = 0;
f->max_size_debug = f->max_size_audit = 0;
}
}
}
#endif
}
int am_log_get_current_owner() {
int rv = 0;
return rv;
}
#ifdef _WIN32
#else
#endif
#ifdef _WIN32
#else
#endif
return rv;
}
/***************************************************************************/
void am_log_register_instance(unsigned long instance_id, const char *debug_log, int log_level, int log_size,
int i, exist = AM_NOT_FOUND;
return;
}
#ifdef _WIN32
}
#else
#endif
for (i = 0; i < AM_MAX_INSTANCES; i++) {
if (f->instance_id == instance_id) {
exist = AM_SUCCESS;
break;
}
}
if (exist == AM_NOT_FOUND) {
for (i = 0; i < AM_MAX_INSTANCES; i++) {
if (!f->used) {
f->instance_id = instance_id;
f->max_size_audit = audit_size > 0 && audit_size < DEFAULT_LOG_SIZE ? DEFAULT_LOG_SIZE : audit_size;
f->level_debug = log_level;
f->level_audit = audit_level;
f->created_debug = f->created_audit = 0;
f->owner = 0;
break;
}
}
/* register instance in valid-url-index table */
if (ISVALID(config_file)) {
for (i = 0; i < AM_MAX_INSTANCES; i++) {
if (vf->instance_id == 0) {
break;
}
}
}
} else {
/* update instance logging level configuration */
f->max_size_audit = audit_size > 0 && audit_size < DEFAULT_LOG_SIZE ? DEFAULT_LOG_SIZE : audit_size;
f->level_debug = log_level;
f->level_audit = audit_level;
}
#ifdef _WIN32
#else
#endif
#define AM_LOG_HEADER "\r\n\r\n\t######################################################\r\n\t# %-51s#\r\n\t# Version: %-42s#\r\n\t# %-51s#\r\n\t# Build date: %s %-27s#\r\n\t######################################################\r\n"
}
}
/***************************************************************************/
int get_valid_url_index(unsigned long instance_id) {
int i, value = 0;
return value;
}
#ifdef _WIN32
#else
#endif
for (i = 0; i < AM_MAX_INSTANCES; i++) {
break;
}
}
#ifdef _WIN32
#else
#endif
return value;
}
int i, j = 0;
return AM_EINVAL;
}
#ifdef _WIN32
#else
#endif
for (i = 0; i < AM_MAX_INSTANCES; i++) {
j++;
}
}
#ifdef _WIN32
#else
#endif
return j > 0 ? AM_SUCCESS : AM_NOT_FOUND;
}
/***************************************************************************/
int i;
return;
}
#ifdef _WIN32
#else
#endif
for (i = 0; i < AM_MAX_INSTANCES; i++) {
break;
}
}
#ifdef _WIN32
#else
#endif
}
int i;
return;
}
#ifdef _WIN32
#else
#endif
for (i = 0; i < AM_MAX_INSTANCES; i++) {
break;
}
}
#ifdef _WIN32
#else
#endif
}
int am_agent_instance_init_init(int id) {
#if defined(_WIN32)
}
status = AM_SUCCESS;
}
if (rv == KERN_SUCCESS) {
status = AM_SUCCESS;
}
#else
#ifdef __sun
#else
#endif
if (ic_sem != SEM_FAILED) {
status = AM_SUCCESS;
}
#endif
return status;
}
void am_agent_instance_init_lock() {
#if defined(_WIN32)
#else
#endif
}
void am_agent_instance_init_unlock() {
#if defined(_WIN32)
#else
#endif
}
#if defined(_WIN32)
#else
if (unlink) {
#ifdef __sun
#else
#endif
, id));
}
#endif
}
int i;
return;
}
if (lock) {
}
for (i = 0; i < AM_MAX_INSTANCES; i++) {
if (val == AM_UNKNOWN) {
/* find first empty slot */
break;
}
} else {
break;
}
}
}
if (lock) {
}
}
return status;
}
if (lock) {
}
for (i = 0; i < AM_MAX_INSTANCES; i++) {
/* get status value */
break;
}
}
if (lock) {
}
return status;
}
/**
* This function gives controlled access to the flag which says whether to log or not when
* running the installation code.
*
* @param wanted true to enable zero instance id logging, false to disable
* @return the previous value of the flag.
*/
return result;
}