- add logfile library for easier logging

This commit is contained in:
Babak Farrokhi 2015-10-21 17:13:44 +03:30
parent 00a927fcda
commit 58bd6213eb
5 changed files with 274 additions and 7 deletions

View File

@ -4,13 +4,17 @@ LIB=-L$(PREFIX)/lib -lpidutil
CFLAGS=-Wall -Wextra -g -O2 -pipe -funroll-loops -ffast-math -fno-strict-aliasing
CC?=cc
PROGS = fsipd
PROGS = fsipd logfile_test
CFILES = fsipd.c logfile.c
all: $(PROGS)
all: fsipd
fsipd: fsipd.c
$(CC) $(CFLAGS) $(INC) $(LIB) fsipd.c -o fsipd
fsipd: $(CFILES)
$(CC) $(CFLAGS) $(INC) $(LIB) $(CFILES) -o fsipd
test: logfile.c logfile_test.c
$(CC) $(CFLAGS) $(INC) $(LIB) logfile.c logfile_test.c -o logfile_test
clean:
rm -f *.o *.a a.out core temp.* $(LIBPIDFILE) $(PROGS)
rm -f *.BAK *.log *.o *.a a.out core temp.* $(LIBPIDFILE) $(PROGS)
rm -fr *.dSYM

View File

@ -48,6 +48,8 @@
#include <syslog.h>
#include <pidutil.h>
#include "logfile.h"
#define PORT 5060
#define BACKLOG 1024
@ -55,6 +57,7 @@
struct pidfh *pfh;
struct sockaddr_in sa;
struct protoent *proto_tcp, *proto_udp;
log_t *lh;
/*
* Prepare for a clean shutdown
@ -74,6 +77,7 @@ signal_handler(int sig)
switch (sig) {
case SIGHUP:
log_reopen(&lh);
break;
case SIGINT:
case SIGTERM:
@ -91,7 +95,7 @@ process_request(char *str)
/* check input str for SIP requests */
syslog(LOG_ALERT, "sip: %s, sport: %d, payload: \"%s\"\n",
inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), str);
inet_ntoa(sa.sin_addr), ntohs(sa.sin_port), str);
}
/*
@ -116,7 +120,7 @@ daemon_start()
if (errno == EEXIST) {
errx(EXIT_FAILURE, "Daemon already running, pid: %jd.", (intmax_t)otherpid);
}
err(EXIT_FAILURE,"Cannot open or create pidfile");
err(EXIT_FAILURE, "Cannot open or create pidfile");
}
/* setup socket */
if ((proto_tcp = getprotobyname("tcp")) == NULL)

135
logfile.c Normal file
View File

@ -0,0 +1,135 @@
/*-
* Copyright (c) 2015, Babak Farrokhi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "logfile.h"
log_t *
log_open(const char *path, mode_t mode)
{
log_t *lh;
struct stat sb;
char *filename;
int fd;
if (path == NULL) {
asprintf(&filename, "%s/%s.log", LOGPATH, getprogname());
} else {
filename = (char *)path;
}
/*
* try to create / append the file and make sure it is correctly
* created
*/
if ((fd = open(filename, O_WRONLY | O_APPEND | O_CREAT | O_EXLOCK | O_SYNC, mode)) == -1)
return (NULL);
if (stat(filename, &sb) == -1) {
close(fd);
return (NULL);
}
/* initialize data structure */
lh = calloc(1, sizeof(log_t));
lh->fd = fd;
lh->dev = sb.st_dev;
lh->ino = sb.st_ino;
lh->mode = sb.st_mode;
strncpy(lh->path, filename, strnlen(filename, MAXPATHLEN + 1));
return (lh);
}
void
log_close(const log_t *log)
{
if (!log_isopen(log))
return;
close(log->fd);
free((void *)log);
}
inline bool
log_isopen(const log_t *log)
{
if (log == NULL)
return (false);
return (log->fd != -1);
}
void
log_reopen(log_t **log)
{
log_t *newlog;
if (!log_isopen(*log))
return;
newlog = malloc(sizeof(log_t));
memcpy(newlog, *log, sizeof(log_t));
log_close(*log);
*log = log_open(newlog->path, newlog->mode);
free(newlog);
}
void
log_printf(const log_t *log, const char *format,...)
{
va_list args;
char *message;
/*
* todo: add timestamp and \n example: "Oct 21 13:46:35 %s\n"
*/
if (log_isopen(log)) {
va_start(args, format);
vasprintf(&message, format, args);
va_end(args);
write(log->fd, message, strnlen(message, MAX_MSG_SIZE));
}
}
bool
log_verify(const log_t *log)
{
struct stat sb;
if (log == NULL || log->fd == -1) {
errno = EINVAL;
return (false);
}
if (fstat(log->fd, &sb) == -1)
return (false);
if (log->ino != sb.st_ino || log->dev != sb.st_dev || log->mode != sb.st_mode) {
errno = EINVAL;
return (false);
}
return true;
}

62
logfile.h Normal file
View File

@ -0,0 +1,62 @@
/*-
* Copyright (c) 2015, Babak Farrokhi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _LOGFILE_H
#define _LOGFILE_H
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdarg.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#define LOGPATH "/var/log"
#define MAX_MSG_SIZE 65536
typedef struct _log_t {
int fd;
char path[MAXPATHLEN + 1];
dev_t dev;
ino_t ino;
mode_t mode;
} log_t;
log_t *log_open(const char *path, mode_t mode);
void log_close(const log_t *log);
bool log_isopen(const log_t *log);
bool log_verify(const log_t *log);
void log_reopen(log_t **log);
void log_printf(const log_t *log, const char *format,...);
#endif /* _LOGFILE_H */

62
logfile_test.c Normal file
View File

@ -0,0 +1,62 @@
/*-
* Copyright (c) 2015, Babak Farrokhi
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <err.h>
#include <errno.h>
#include <sysexits.h>
#include "logfile.h"
/*
* dummy program to test logfile functionality
*/
int
main(void)
{
log_t *lh;
if ((lh = log_open("test.log", 0600)) == NULL) {
err(EX_IOERR, "Cannot open log file");
}
if (!log_verify(lh))
err(errno, "Failed to verify integrity of log file");
log_printf(lh, "opened file handle: %d , inode: %llu\n", lh->fd, lh->ino);
printf("logfile: %s, handle: %d, inode: %llu, mode: %d\n", lh->path, lh->fd, lh->ino, lh->mode);
log_reopen(&lh);
if (!log_verify(lh))
err(errno, "Failed to verify integrity of reopened log file");
log_printf(lh, "reopened file handle: %d , inode: %llu\n", lh->fd, lh->ino);
printf("logfile: %s, handle: %d, inode: %llu, mode: %d\n", lh->path, lh->fd, lh->ino, lh->mode);
log_close(lh);
return 0;
}