--- /dev/null
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+#ifndef EXFILE_H
+#define EXFILE_H
+/*
+ * $Id$
+ *
+ * @file exfile.h
+ * @brief Functions for managing concurrent file access.
+ *
+ * @copyright 2014 The FreeRADIUS server project
+ */
+RCSIDH(exfile_h, "$Id$")
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/*
+ * Multiple threads logging to one or more files.
+ */
+typedef struct exfile_t exfile_t;
+
+exfile_t *exfile_init(TALLOC_CTX *ctx, uint32_t entries, uint32_t idle);
+int exfile_open(exfile_t *lf, char const *filename, mode_t permissions);
+int exfile_close(exfile_t *lf, int fd);
+int exfile_unlock(exfile_t *lf, int fd);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
void fr_canonicalize_error(TALLOC_CTX *ctx, char **spaces, char **text, ssize_t slen, char const *msg);
/*
- * Multiple threads logging to one or more files.
- */
-typedef struct fr_logfile_t fr_logfile_t;
-
-fr_logfile_t *fr_logfile_init(TALLOC_CTX *ctx);
-int fr_logfile_open(fr_logfile_t *lf, char const *filename, mode_t permissions);
-int fr_logfile_close(fr_logfile_t *lf, int fd);
-int fr_logfile_unlock(fr_logfile_t *lf, int fd);
-
-/*
* Logging macros.
*
* For server code, do not call radlog, vradlog et al directly, use one of the logging macros instead.
--- /dev/null
+/*
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+/*
+ * $Id$
+ *
+ * @file exfile.c
+ * @brief Allow multiple threads to write to the same set of files.
+ *
+ * @author Alan DeKok <aland@freeradius.org>
+ * @copyright 2014 The FreeRADIUS server project
+ */
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/exfile.h>
+
+#include <sys/stat.h>
+#include <fcntl.h>
+
+typedef struct exfile_entry_t {
+ int fd; //!< File descriptor associated with an entry.
+ int dup;
+ uint32_t hash; //!< Hash for cheap comparison.
+ time_t last_used; //!< Last time the entry was used.
+ char *filename; //!< Filename.
+} exfile_entry_t;
+
+
+struct exfile_t {
+ uint32_t max_entries; //!< How many file descriptors we keep track of.
+ uint32_t max_idle; //!< Maximum idle time for a descriptor.
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_t mutex;
+#endif
+ exfile_entry_t *entries;
+};
+
+
+#ifdef HAVE_PTHREAD_H
+#define PTHREAD_MUTEX_LOCK pthread_mutex_lock
+#define PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock
+
+#else
+/*
+ * This is easier than ifdef's throughout the code.
+ */
+#define PTHREAD_MUTEX_LOCK(_x)
+#define PTHREAD_MUTEX_UNLOCK(_x)
+#endif
+
+static int _exfile_free(exfile_t *ef)
+{
+ uint32_t i;
+
+ PTHREAD_MUTEX_LOCK(&ef->mutex);
+
+ for (i = 0; i < ef->max_entries; i++) {
+ if (!ef->entries[i].filename) continue;
+
+ close(ef->entries[i].fd);
+ }
+
+ PTHREAD_MUTEX_UNLOCK(&ef->mutex);
+
+#ifdef HAVE_PTHREAD_H
+ pthread_mutex_destroy(&ef->mutex);
+#endif
+
+ return 0;
+}
+
+
+/** Initialize a way for multiple threads to log to one or more files.
+ *
+ * @param ctx The talloc context
+ * @param max_entries Max file descriptors to cache, and manage locks for.
+ * @param max_idle Maximum time a file descriptor can be idle before it's closed.
+ * @return the new context, or NULL on error.
+ */
+exfile_t *exfile_init(TALLOC_CTX *ctx, uint32_t max_entries, uint32_t max_idle)
+{
+ exfile_t *ef;
+
+ ef = talloc_zero(ctx, exfile_t);
+ if (!ef) return NULL;
+
+ ef->entries = talloc_zero_array(ef, exfile_entry_t, max_entries);
+ if (!ef->entries) {
+ talloc_free(ef);
+ return NULL;
+ }
+
+#ifdef HAVE_PTHREAD_H
+ if (pthread_mutex_init(&ef->mutex, NULL) != 0) {
+ talloc_free(ef);
+ return NULL;
+ }
+#endif
+
+ ef->max_entries = max_entries;
+ ef->max_idle = max_idle;
+
+ talloc_set_destructor(ef, _exfile_free);
+
+ return ef;
+}
+
+/** Open a new log file, or maybe an existing one.
+ *
+ * When multithreaded, the FD is locked via a mutex. This way we're
+ * sure that no other thread is writing to the file.
+ *
+ * @param ef The logfile context returned from exfile_init().
+ * @param filename the file to open.
+ * @param permissions to use.
+ * @return an FD used to write to the file, or -1 on error.
+ */
+int exfile_open(exfile_t *ef, char const *filename, mode_t permissions)
+{
+ uint32_t i;
+ uint32_t hash;
+ time_t now = time(NULL);
+ struct stat st;
+
+ if (!ef || !filename) return -1;
+
+ hash = fr_hash_string(filename);
+
+ PTHREAD_MUTEX_LOCK(&ef->mutex);
+
+ /*
+ * Clean up old entries.
+ */
+ for (i = 0; i < ef->max_entries; i++) {
+ if (!ef->entries[i].filename) continue;
+ if ((ef->entries[i].last_used + ef->max_idle) < now) {
+ /*
+ * This will block forever if a thread is
+ * doing something stupid.
+ */
+ TALLOC_FREE(ef->entries[i].filename);
+ close(ef->entries[i].fd);
+ }
+ }
+
+ /*
+ * Find the matching entry.
+ */
+ for (i = 0; i < ef->max_entries; i++) {
+ if (!ef->entries[i].filename) continue;
+
+ if (ef->entries[i].hash == hash) {
+ /*
+ * Same hash but different filename. Give up.
+ */
+ if (strcmp(ef->entries[i].filename, filename) != 0) {
+ PTHREAD_MUTEX_UNLOCK(&ef->mutex);
+ return -1;
+ }
+ /*
+ * Someone else failed to create the entry.
+ */
+ if (!ef->entries[i].filename) {
+ PTHREAD_MUTEX_UNLOCK(&ef->mutex);
+ return -1;
+ }
+ goto do_return;
+ }
+ }
+
+ /*
+ * Find an unused entry
+ */
+ for (i = 0; i < ef->max_entries; i++) {
+ if (!ef->entries[i].filename) break;
+ }
+
+ if (i >= ef->max_entries) {
+ fr_strerror_printf("Too many different filenames");
+ PTHREAD_MUTEX_UNLOCK(&(ef->mutex));
+ return -1;
+ }
+
+ /*
+ * Create a new entry.
+ */
+
+ ef->entries[i].hash = hash;
+ ef->entries[i].filename = talloc_strdup(ef->entries, filename);
+ ef->entries[i].fd = -1;
+
+ ef->entries[i].fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, permissions);
+ if (ef->entries[i].fd < 0) {
+ mode_t dirperm;
+ char *p, *dir;
+
+ /*
+ * Maybe the directory doesn't exist. Try to
+ * create it.
+ */
+ dir = talloc_strdup(ef, filename);
+ if (!dir) goto error;
+ p = strrchr(dir, FR_DIR_SEP);
+ if (!p) {
+ fr_strerror_printf("No '/' in '%s'", filename);
+ goto error;
+ }
+ *p = '\0';
+
+ /*
+ * Ensure that the 'x' bit is set, so that we can
+ * read the directory.
+ */
+ dirperm = permissions;
+ if ((dirperm & 0600) != 0) dirperm |= 0100;
+ if ((dirperm & 0060) != 0) dirperm |= 0010;
+ if ((dirperm & 0006) != 0) dirperm |= 0001;
+
+ if (rad_mkdir(dir, dirperm) < 0) {
+ fr_strerror_printf("Failed to create directory %s: %s",
+ dir, strerror(errno));
+ talloc_free(dir);
+ goto error;
+ }
+ talloc_free(dir);
+
+ ef->entries[i].fd = open(filename, O_WRONLY | O_CREAT, permissions);
+ if (ef->entries[i].fd < 0) {
+ fr_strerror_printf("Failed to open file %s: %s",
+ filename, strerror(errno));
+ goto error;
+ } /* else fall through to creating the rest of the entry */
+ } /* else the file was already opened */
+
+do_return:
+ /*
+ * Lock from the start of the file.
+ */
+ if (lseek(ef->entries[i].fd, 0, SEEK_SET) < 0) {
+ fr_strerror_printf("Failed to seek in file %s: %s", filename, strerror(errno));
+
+ error:
+ ef->entries[i].hash = 0;
+ TALLOC_FREE(ef->entries[i].filename);
+ close(ef->entries[i].fd);
+ ef->entries[i].fd = -1;
+
+ PTHREAD_MUTEX_UNLOCK(&(ef->mutex));
+ return -1;
+ }
+
+ if (rad_lockfd(ef->entries[i].fd, 0) < 0) {
+ fr_strerror_printf("Failed to lock file %s: %s", filename, strerror(errno));
+ goto error;
+ }
+
+ /*
+ * Maybe someone deleted the file while we were waiting
+ * for the lock. If so, re-open it.
+ */
+ if (fstat(ef->entries[i].fd, &st) < 0) {
+ fr_strerror_printf("Failed to stat file %s: %s", filename, strerror(errno));
+ goto error;
+ }
+
+ if (st.st_nlink == 0) {
+ close(ef->entries[i].fd);
+ ef->entries[i].fd = open(filename, O_WRONLY | O_CREAT, permissions);
+ if (ef->entries[i].fd < 0) {
+ fr_strerror_printf("Failed to open file %s: %s",
+ filename, strerror(errno));
+ goto error;
+ }
+ }
+
+ /*
+ * Seek to the end of the file before returning the FD to
+ * the caller.
+ */
+ lseek(ef->entries[i].fd, 0, SEEK_END);
+
+ /*
+ * Return holding the mutex for the entry.
+ */
+ ef->entries[i].last_used = now;
+ ef->entries[i].dup = dup(ef->entries[i].fd);
+ if (ef->entries[i].dup < 0) {
+ fr_strerror_printf("Failed calling dup(): %s",
+ strerror(errno));
+ goto error;
+ }
+
+ return ef->entries[i].dup;
+}
+
+/** Close the log file. Really just return it to the pool.
+ *
+ * When multithreaded, the FD is locked via a mutex. This way we're
+ * sure that no other thread is writing to the file. This function
+ * will unlock the mutex, so that other threads can write to the file.
+ *
+ * @param ef The logfile context returned from exfile_init()
+ * @param fd the FD to close (i.e. return to the pool)
+ * @return 0 on success, or -1 on error
+ */
+int exfile_close(exfile_t *ef, int fd)
+{
+ uint32_t i;
+
+ for (i = 0; i < ef->max_entries; i++) {
+ if (!ef->entries[i].filename) continue;
+
+ /*
+ * Unlock the bytes that we had previously locked.
+ */
+ if (ef->entries[i].dup == fd) {
+ (void) rad_unlockfd(ef->entries[i].dup, 0);
+ close(ef->entries[i].dup); /* releases the fcntl lock */
+ ef->entries[i].dup = -1;
+
+ PTHREAD_MUTEX_UNLOCK(&(ef->mutex));
+ return 0;
+ }
+ }
+
+ PTHREAD_MUTEX_UNLOCK(&(ef->mutex));
+
+ fr_strerror_printf("Attempt to unlock file which does not exist");
+ return -1;
+}
+
+int exfile_unlock(exfile_t *ef, int fd)
+{
+ uint32_t i;
+
+ for (i = 0; i < ef->max_entries; i++) {
+ if (!ef->entries[i].filename) continue;
+
+ if (ef->entries[i].dup == fd) {
+ ef->entries[i].dup = -1;
+ PTHREAD_MUTEX_UNLOCK(&(ef->mutex));
+ return 0;
+ }
+ }
+
+ PTHREAD_MUTEX_UNLOCK(&(ef->mutex));
+
+ fr_strerror_printf("Attempt to unlock file which does not exist");
+ return -1;
+}
SOURCES := conffile.c \
evaluate.c \
exec.c \
+ exfile.c \
log.c \
parser.c \
map.c \
*text = value;
}
-
-typedef struct fr_logfile_entry_t {
- int fd;
- int dup;
- uint32_t hash;
- time_t last_used;
- char *filename;
-} fr_logfile_entry_t;
-
-
-struct fr_logfile_t {
- uint32_t max_entries;
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_t mutex;
-#endif
- fr_logfile_entry_t *entries;
-};
-
-
-#ifdef HAVE_PTHREAD_H
-#define PTHREAD_MUTEX_LOCK pthread_mutex_lock
-#define PTHREAD_MUTEX_UNLOCK pthread_mutex_unlock
-
-#else
-/*
- * This is easier than ifdef's throughout the code.
- */
-#define PTHREAD_MUTEX_LOCK(_x)
-#define PTHREAD_MUTEX_UNLOCK(_x)
-#endif
-
-static int _logfile_free(fr_logfile_t *lf)
-{
- uint32_t i;
-
- PTHREAD_MUTEX_LOCK(&lf->mutex);
-
- for (i = 0; i < lf->max_entries; i++) {
- if (!lf->entries[i].filename) continue;
-
- close(lf->entries[i].fd);
- }
-
- PTHREAD_MUTEX_UNLOCK(&lf->mutex);
-
-#ifdef HAVE_PTHREAD_H
- pthread_mutex_destroy(&lf->mutex);
-#endif
-
- return 0;
-}
-
-
-/** Initialize a way for multiple threads to log to one or more files.
- *
- * @param ctx The talloc context
- * @return the new context, or NULL on error.
- */
-fr_logfile_t *fr_logfile_init(TALLOC_CTX *ctx)
-{
- fr_logfile_t *lf;
-
- lf = talloc_zero(ctx, fr_logfile_t);
- if (!lf) return NULL;
-
- lf->entries = talloc_zero_array(lf, fr_logfile_entry_t, 64);
- if (!lf->entries) {
- talloc_free(lf);
- return NULL;
- }
-
-#ifdef HAVE_PTHREAD_H
- if (pthread_mutex_init(&lf->mutex, NULL) != 0) {
- talloc_free(lf);
- return NULL;
- }
-#endif
-
- lf->max_entries = 64;
-
- talloc_set_destructor(lf, _logfile_free);
-
- return lf;
-}
-
-
-/** Open a new log file, or maybe an existing one.
- *
- * When multithreaded, the FD is locked via a mutex. This way we're
- * sure that no other thread is writing to the file.
- *
- * @param lf The logfile context returned from fr_logfile_init().
- * @param filename the file to open.
- * @param permissions to use.
- * @return an FD used to write to the file, or -1 on error.
- */
-int fr_logfile_open(fr_logfile_t *lf, char const *filename, mode_t permissions)
-{
- uint32_t i;
- uint32_t hash;
- time_t now = time(NULL);
- struct stat st;
-
- if (!lf || !filename) return -1;
-
- hash = fr_hash_string(filename);
-
- PTHREAD_MUTEX_LOCK(&lf->mutex);
-
- /*
- * Clean up old entries.
- */
- for (i = 0; i < lf->max_entries; i++) {
- if (!lf->entries[i].filename) continue;
-
- /*
- * FIXME: make this configurable?
- */
- if ((lf->entries[i].last_used + 30) < now) {
- /*
- * This will block forever if a thread is
- * doing something stupid.
- */
- TALLOC_FREE(lf->entries[i].filename);
- close(lf->entries[i].fd);
- }
- }
-
- /*
- * Find the matching entry.
- */
- for (i = 0; i < lf->max_entries; i++) {
- if (!lf->entries[i].filename) continue;
-
- if (lf->entries[i].hash == hash) {
- /*
- * Same hash but different filename. Give up.
- */
- if (strcmp(lf->entries[i].filename, filename) != 0) {
- PTHREAD_MUTEX_UNLOCK(&lf->mutex);
- return -1;
- }
- /*
- * Someone else failed to create the entry.
- */
- if (!lf->entries[i].filename) {
- PTHREAD_MUTEX_UNLOCK(&lf->mutex);
- return -1;
- }
- goto do_return;
- }
- }
-
- /*
- * Find an unused entry
- */
- for (i = 0; i < lf->max_entries; i++) {
- if (!lf->entries[i].filename) break;
- }
-
- if (i >= lf->max_entries) {
- fr_strerror_printf("Too many different filenames");
- PTHREAD_MUTEX_UNLOCK(&(lf->mutex));
- return -1;
- }
-
- /*
- * Create a new entry.
- */
-
- lf->entries[i].hash = hash;
- lf->entries[i].filename = talloc_strdup(lf->entries, filename);
- lf->entries[i].fd = -1;
-
- lf->entries[i].fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, permissions);
- if (lf->entries[i].fd < 0) {
- mode_t dirperm;
- char *p, *dir;
-
- /*
- * Maybe the directory doesn't exist. Try to
- * create it.
- */
- dir = talloc_strdup(lf, filename);
- if (!dir) goto error;
- p = strrchr(dir, FR_DIR_SEP);
- if (!p) {
- fr_strerror_printf("No '/' in '%s'", filename);
- goto error;
- }
- *p = '\0';
-
- /*
- * Ensure that the 'x' bit is set, so that we can
- * read the directory.
- */
- dirperm = permissions;
- if ((dirperm & 0600) != 0) dirperm |= 0100;
- if ((dirperm & 0060) != 0) dirperm |= 0010;
- if ((dirperm & 0006) != 0) dirperm |= 0001;
-
- if (rad_mkdir(dir, dirperm) < 0) {
- fr_strerror_printf("Failed to create directory %s: %s",
- dir, strerror(errno));
- talloc_free(dir);
- goto error;
- }
- talloc_free(dir);
-
- lf->entries[i].fd = open(filename, O_WRONLY | O_CREAT, permissions);
- if (lf->entries[i].fd < 0) {
- fr_strerror_printf("Failed to open file %s: %s",
- filename, strerror(errno));
- goto error;
- } /* else fall through to creating the rest of the entry */
- } /* else the file was already opened */
-
-do_return:
- /*
- * Lock from the start of the file.
- */
- if (lseek(lf->entries[i].fd, 0, SEEK_SET) < 0) {
- fr_strerror_printf("Failed to seek in file %s: %s",
- filename, strerror(errno));
-
- error:
- lf->entries[i].hash = 0;
- TALLOC_FREE(lf->entries[i].filename);
- close(lf->entries[i].fd);
- lf->entries[i].fd = -1;
-
- PTHREAD_MUTEX_UNLOCK(&(lf->mutex));
- return -1;
- }
-
- if (rad_lockfd(lf->entries[i].fd, 0) < 0) {
- fr_strerror_printf("Failed to lock file %s: %s",
- filename, strerror(errno));
- goto error;
- }
-
- /*
- * Maybe someone deleted the file while we were waiting
- * for the lock. If so, re-open it.
- */
- if (fstat(lf->entries[i].fd, &st) < 0) {
- fr_strerror_printf("Failed to stat file %s: %s",
- filename, strerror(errno));
- goto error;
- }
-
- if (st.st_nlink == 0) {
- close(lf->entries[i].fd);
- lf->entries[i].fd = open(filename, O_WRONLY | O_CREAT, permissions);
- if (lf->entries[i].fd < 0) {
- fr_strerror_printf("Failed to open file %s: %s",
- filename, strerror(errno));
- goto error;
- }
- }
-
- /*
- * Seek to the end of the file before returning the FD to
- * the caller.
- */
- lseek(lf->entries[i].fd, 0, SEEK_END);
-
- /*
- * Return holding the mutex for the entry.
- */
- lf->entries[i].last_used = now;
- lf->entries[i].dup = dup(lf->entries[i].fd);
- if (lf->entries[i].dup < 0) {
- fr_strerror_printf("Failed calling dup(): %s",
- strerror(errno));
- goto error;
- }
-
- return lf->entries[i].dup;
-}
-
-/** Close the log file. Really just return it to the pool.
- *
- * When multithreaded, the FD is locked via a mutex. This way we're
- * sure that no other thread is writing to the file. This function
- * will unlock the mutex, so that other threads can write to the file.
- *
- * @param lf The logfile context returned from fr_logfile_init()
- * @param fd the FD to close (i.e. return to the pool)
- * @return 0 on success, or -1 on error
- */
-int fr_logfile_close(fr_logfile_t *lf, int fd)
-{
- uint32_t i;
-
- for (i = 0; i < lf->max_entries; i++) {
- if (!lf->entries[i].filename) continue;
-
- /*
- * Unlock the bytes that we had previously locked.
- */
- if (lf->entries[i].dup == fd) {
- (void) rad_unlockfd(lf->entries[i].dup, 0);
- close(lf->entries[i].dup); /* releases the fcntl lock */
- lf->entries[i].dup = -1;
-
- PTHREAD_MUTEX_UNLOCK(&(lf->mutex));
- return 0;
- }
- }
-
- PTHREAD_MUTEX_UNLOCK(&(lf->mutex));
-
- fr_strerror_printf("Attempt to unlock file which does not exist");
- return -1;
-}
-
-int fr_logfile_unlock(fr_logfile_t *lf, int fd)
-{
- uint32_t i;
-
- for (i = 0; i < lf->max_entries; i++) {
- if (!lf->entries[i].filename) continue;
-
- if (lf->entries[i].dup == fd) {
- lf->entries[i].dup = -1;
- PTHREAD_MUTEX_UNLOCK(&(lf->mutex));
- return 0;
- }
- }
-
- PTHREAD_MUTEX_UNLOCK(&(lf->mutex));
-
- fr_strerror_printf("Attempt to unlock file which does not exist");
- return -1;
-}
#include <freeradius-devel/modules.h>
#include <freeradius-devel/rad_assert.h>
#include <freeradius-devel/detail.h>
+#include <freeradius-devel/exfile.h>
#include <ctype.h>
#include <fcntl.h>
bool log_srcdst; //!< Add IP src/dst attributes to entries.
- fr_logfile_t *lf; //!< Log file handler
+ exfile_t *ef; //!< Log file handler
fr_hash_table_t *ht; //!< Holds suppressed attributes.
} detail_instance_t;
inst->name = cf_section_name1(conf);
}
- inst->lf= fr_logfile_init(inst);
- if (!inst->lf) {
+ inst->ef = exfile_init(inst, 64, 30);
+ if (!inst->ef) {
cf_log_err_cs(conf, "Failed creating log file context");
return -1;
}
#endif
#endif
- outfd = fr_logfile_open(inst->lf, buffer, inst->perm);
+ outfd = exfile_open(inst->ef, buffer, inst->perm);
if (outfd < 0) {
RERROR("Couldn't open file %s: %s", buffer, fr_strerror());
return RLM_MODULE_FAIL;
RERROR("Couldn't open file %s: %s", buffer, fr_syserror(errno));
fail:
if (outfp) fclose(outfp);
- fr_logfile_unlock(inst->lf, outfd);
+ exfile_unlock(inst->ef, outfd);
return RLM_MODULE_FAIL;
}
* Flush everything
*/
fclose(outfp);
- fr_logfile_unlock(inst->lf, outfd); /* do NOT close outfp */
+ exfile_unlock(inst->ef, outfd); /* do NOT close outfp */
/*
* And everything is fine.
#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
#include <freeradius-devel/rad_assert.h>
+#include <freeradius-devel/exfile.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
char const *group;
char const *line;
char const *reference;
- fr_logfile_t *lf;
+ exfile_t *ef;
} rlm_linelog_t;
/*
return -1;
}
- inst->lf = fr_logfile_init(inst);
- if (!inst->lf) {
+ inst->ef = exfile_init(inst, 64, 30);
+ if (!inst->ef) {
cf_log_err_cs(conf, "Failed creating log file context");
return -1;
}
*p = '/';
}
- fd = fr_logfile_open(inst->lf, path, inst->permissions);
+ fd = exfile_open(inst->ef, path, inst->permissions);
if (fd == -1) {
ERROR("rlm_linelog: Failed to open %s: %s",
path, fr_syserror(errno));
*/
if (value && (radius_xlat(line, sizeof(line) - 1, request, value, linelog_escape_func, NULL) < 0)) {
if (fd > -1) {
- fr_logfile_close(inst->lf, fd);
+ exfile_close(inst->ef, fd);
}
return RLM_MODULE_FAIL;
if (write(fd, line, strlen(line)) < 0) {
ERROR("rlm_linelog: Failed writing: %s", fr_syserror(errno));
- fr_logfile_close(inst->lf, fd);
+ exfile_close(inst->ef, fd);
return RLM_MODULE_FAIL;
}
- fr_logfile_close(inst->lf, fd);
+ exfile_close(inst->ef, fd);
#ifdef HAVE_SYSLOG_H
} else {
#include <freeradius-devel/modules.h>
#include <freeradius-devel/token.h>
#include <freeradius-devel/rad_assert.h>
+#include <freeradius-devel/exfile.h>
#include <sys/stat.h>
}
}
- inst->lf = fr_logfile_init(inst);
- if (!inst->lf) {
+ inst->ef = exfile_init(inst, 64, 30);
+ if (!inst->ef) {
cf_log_err_cs(conf, "Failed creating log file context");
return -1;
}
RCSIDH(rlm_sql_h, "$Id$")
-#include <freeradius-devel/radiusd.h>
-#include <freeradius-devel/connection.h>
-#include <freeradius-devel/modpriv.h>
+#include <freeradius-devel/radiusd.h>
+#include <freeradius-devel/connection.h>
+#include <freeradius-devel/modpriv.h>
+#include <freeradius-devel/exfile.h>
#define PW_ITEM_CHECK 0
#define PW_ITEM_REPLY 1
DICT_ATTR const *sql_user; //!< Cached pointer to SQL-User-Name
//!< dictionary attribute.
- fr_logfile_t *lf;
+ exfile_t *ef;
void *handle;
rlm_sql_module_t *module;
return;
}
- fd = fr_logfile_open(inst->lf, filename, 0640);
+ fd = exfile_open(inst->ef, filename, 0640);
if (fd < 0) {
ERROR("rlm_sql (%s): Couldn't open logfile '%s': %s", inst->config->xlat_name,
expanded, fr_syserror(errno));
}
talloc_free(expanded);
- fr_logfile_close(inst->lf, fd);
+ exfile_close(inst->ef, fd);
}