Browse Source

- Add logging and config handling code from rpdd

- Add default config file
master
decke 7 years ago
parent
commit
e4fe1dc5e5
9 changed files with 372 additions and 24 deletions
  1. 11
    8
      Makefile
  2. 115
    0
      log.c
  3. 48
    0
      log.h
  4. 18
    0
      redqd.conf-dist
  5. 23
    9
      server.c
  6. 0
    5
      server.h
  7. 3
    2
      stomp.c
  8. 117
    0
      util.c
  9. 37
    0
      util.h

+ 11
- 8
Makefile View File

@@ -2,24 +2,27 @@
# Simple libevent based STOMP server
#

# Development flags
CFLAGS+=-g -Wall

LOCALBASE?=/usr/local

CPPFLAGS=-I${LOCALBASE}/include -g -Wall
LDFLAGS=-L${LOCALBASE}/lib/event2 -L${LOCALBASE}/lib
CFLAGS+=-I${LOCALBASE}/include
LDFLAGS+=-L${LOCALBASE}/lib/event2 -L${LOCALBASE}/lib

SRC = server.c common.c stomp.c
OBJS = ${SRC:.c=.o}
SRC= log.c util.c server.c common.c stomp.c
OBJS= ${SRC:.c=.o}

all: redqueue
all: redqd

clean:
@rm -f *.o *.core

redqueue: ${OBJS}
$(CC) $(LDFLAGS) -levent -lleveldb ${OBJS} -o redqueue
redqd: ${OBJS}
$(CC) $(LDFLAGS) -levent -lleveldb ${OBJS} -o redqd

# SUFFIX RULES
.SUFFIXES: .c .o

.c.o:
$(CC) $(CPPFLAGS) -c ${.IMPSRC}
$(CC) $(CFLAGS) -c ${.IMPSRC}

+ 115
- 0
log.c View File

@@ -0,0 +1,115 @@
/*
* Copyright (C) 2011 Bernhard Froehlich <decke@bluelife.at>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Author's name may not be used endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <errno.h>
#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <time.h>

#include "log.h"

char *loglevelnames[] = { "ERROR", "WARN ", "INFO ", "DEBUG" };

int loglevel = LOG_INFO;
FILE *logfile = NULL;

int logopen(char *filename)
{
if(logfile != NULL)
return 1;

logfile = fopen(filename, "a");
if(logfile == NULL)
{
printf("Error %s: Could not open logfile %s\n", strerror(errno), filename);
return 1;
}

return 0;
}

int logclose(void)
{
int retval;

if(logfile == NULL)
return 1;

fflush(logfile);
retval = fclose(logfile);
if(retval != 0)
printf("Error %s on closing logfile\n", strerror(errno));
logfile = NULL;
return retval;
}

int logsetlevel(int loglvl)
{
if(loglvl >= 0 && loglvl < 3)
{
loglevel = loglvl;
return 0;
}

return 1;
}

int logwrite(int loglvl, const char *logfmt, ...)
{
char logmsg[4096];
va_list args;
time_t now;
char timeinfo[32];

if(logfile == NULL)
return 1;

if(loglvl < 0 || loglvl > loglevel)
return 0;

time(&now);
strftime(timeinfo, sizeof(timeinfo), "%c", localtime(&now));

va_start(args, logfmt);
vsprintf(logmsg, logfmt, args);

if(logmsg[strlen(logmsg)-1] == '\n')
logmsg[strlen(logmsg)-1] = '\0';

if(fprintf(logfile, "[%s] %s - %s\n", timeinfo, loglevelnames[loglvl], logmsg) < 0)
{
va_end(args);
return 1;
}

va_end(args);

fflush(logfile);
return 0;
}


+ 48
- 0
log.h View File

@@ -0,0 +1,48 @@
/*
* Copyright (C) 2011 Bernhard Froehlich <decke@bluelife.at>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Author's name may not be used endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _LOG_H_
#define _LOG_H_

enum loglevels
{
LOG_ERROR,
LOG_WARN,
LOG_INFO,
LOG_DEBUG
};

#define logdebug(format, args...) logwrite(LOG_DEBUG, format, ##args)
#define loginfo(format, args...) logwrite(LOG_INFO, format, ##args)
#define logwarn(format, args...) logwrite(LOG_WARN, format, ##args)
#define logerror(format, args...) logwrite(LOG_ERROR, format, ##args)

extern int logopen(char *filename);
extern int logclose(void);
extern int logsetlevel(int loglvl);
extern int logwrite(int loglvl, const char *logfmt, ...);

#endif /* _LOG_H_ */

+ 18
- 0
redqd.conf-dist View File

@@ -0,0 +1,18 @@
# Redqueue STOMP server
#
# redqd.conf

# Listen
listenIP 127.0.0.1
listenPort 8080

# Authentication
#authUser test
#authPass test

# LevelDB Database file
dbFile /tmp/redqueue.db

# Logfile
logFile /var/log/redqd.log


+ 23
- 9
server.c View File

@@ -28,8 +28,8 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <syslog.h>
#include <signal.h>
#include <limits.h>

/* Required by event.h. */
#include <sys/time.h>
@@ -53,6 +53,8 @@
/* LevelDB */
#include <leveldb/c.h>

#include "log.h"
#include "util.h"
#include "common.h"
#include "server.h"
#include "client.h"
@@ -72,11 +74,13 @@ void signal_handler(int sig) {
switch(sig) {
case SIGTERM:
case SIGHUP:
logclose();
logopen(configget("logFile"));
case SIGINT:
event_base_loopbreak(base);
break;
default:
syslog(LOG_WARNING, "Unhandled signal (%d) %s", sig, strsignal(sig));
logwarn("Unhandled signal (%d) %s", sig, strsignal(sig));
break;
}
}
@@ -248,9 +252,9 @@ void on_accept(int fd, short ev, void *arg)

int main(int argc, char **argv)
{
char config[PATH_MAX] = CONF_FILE;
int listen_fd, ch;
int daemon = 0;
int port = SERVER_PORT;
struct sockaddr_in listen_addr;
struct event *ev_accept;
int reuseaddr_on;
@@ -267,17 +271,25 @@ int main(int argc, char **argv)
signal(SIGINT, signal_handler);
signal(SIGQUIT, signal_handler);

while ((ch = getopt(argc, argv, "dp:")) != -1) {
while ((ch = getopt(argc, argv, "d:")) != -1) {
switch (ch) {
case 'd':
daemon = 1;
break;
case 'p':
port = atoi(optarg);
break;
}
}

if(configparse(config)){
printf("Could not load config file %s\n", config);
exit(EXIT_FAILURE);
}
if(logopen(configget("logFile")) != 0)
exit(EXIT_FAILURE);
logwrite(LOG_INFO, "-------------------------------");
logwrite(LOG_INFO, "%s/%s started", DAEMON_NAME, REDQUEUE_VERSION);

if (daemon) {
pid = fork();
if (pid < 0) {
@@ -307,7 +319,7 @@ int main(int argc, char **argv)
leveldb_options_set_create_if_missing(options, 1);
leveldb_options_set_error_if_exists(options, 0);

db = leveldb_open(options, "/tmp/redqueue.db", &error);
db = leveldb_open(options, configget("dbFile"), &error);
CheckNoError(error);
/* Initialize libevent. */
@@ -321,7 +333,7 @@ int main(int argc, char **argv)
memset(&listen_addr, 0, sizeof(listen_addr));
listen_addr.sin_family = AF_INET;
listen_addr.sin_addr.s_addr = INADDR_ANY;
listen_addr.sin_port = htons(port);
listen_addr.sin_port = htons(atoi(configget("listenPort")));

if (bind(listen_fd, (struct sockaddr *)&listen_addr, sizeof(listen_addr)) < 0)
err(1, "bind failed");
@@ -353,5 +365,7 @@ int main(int argc, char **argv)
leveldb_cache_destroy(cache);
leveldb_env_destroy(env);

logclose();

return 0;
}

+ 0
- 5
server.h View File

@@ -32,9 +32,4 @@
#define CONF_FILE "redqd.conf"
#define PID_FILE "/var/run/redqd.pid"

#define SERVER_PORT 8080

#define AUTH_USER ""
#define AUTH_PASS ""
#endif /* _SERVER_H_ */

+ 3
- 2
stomp.c View File

@@ -35,6 +35,7 @@
#include <event2/http.h>
#include <event2/keyvalq_struct.h>

#include "util.h"
#include "server.h"
#include "client.h"
#include "stomp.h"
@@ -140,7 +141,7 @@ int stomp_connect(struct client *client)
const char *login;
const char *passcode;

if(strlen(AUTH_USER) > 0 && strlen(AUTH_PASS) > 0){
if(strlen(configget("authUser")) > 0 && strlen(configget("authPass")) > 0){
login = evhttp_find_header(client->request_headers, "login");
if(login == NULL){
client->response_cmd = STOMP_CMD_ERROR;
@@ -155,7 +156,7 @@ int stomp_connect(struct client *client)
return 1;
}

if(strcmp(login, AUTH_USER) != 0 || strcmp(passcode, AUTH_PASS) != 0){
if(strcmp(login, configget("authUser")) != 0 || strcmp(passcode, configget("authPass")) != 0){
client->response_cmd = STOMP_CMD_ERROR;
evhttp_add_header(client->response_headers, "message", "Authentication failed");
return 1;

+ 117
- 0
util.c View File

@@ -0,0 +1,117 @@
/*
* Copyright (C) 2011 Bernhard Froehlich <decke@bluelife.at>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Author's name may not be used endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <stdlib.h>
#include <string.h>

#include "util.h"

struct configparam
{
char key[CONFIGMAXKEY];
char value[CONFIGMAXVALUE];
};

struct configparam config[] = {
{ "authUser", "" },
{ "authPass", "" },
{ "dbFile", "/tmp/redqueue.db" },
{ "listenIP", "127.0.0.1" },
{ "listenPort", "8080" },
{ "logFile", "/var/log/redqd.log" },
{ "", "" }
};

int configparse(char *filename)
{
char *value;
char line[255];
FILE *file = fopen(filename, "r");

if(file == NULL)
return 1;
while(fgets(line, sizeof(line), file) != NULL)
{
if(line[0] == '#')
continue;
line[strlen(line)-1] = '\0';
if((value = strstr(line, " ")) != NULL || (value = strstr(line, "\t")) != NULL)
{
*value = '\0';
value++;

while(*value == ' ' || *value == '\t')
value++;

if(strlen(line) == 0 || strlen(value) == 0)
continue;

if(configset(line, value) != 0)
return 1;
}
}

fclose(file);
return 0;
}

char* configget(char *key)
{
int i;

for(i=0; config[i].key[0] != '\0'; i++)
{
if(strcmp(key, config[i].key) == 0)
{
return config[i].value;
}
}

return NULL;
}

int configset(char *key, char *value)
{
int i;

for(i=0; config[i].key[0] != '\0'; i++)
{
if(strcmp(key, config[i].key) == 0)
{
strncpy(config[i].value, value, sizeof(config[i].value)-1);
config[i].value[sizeof(config[i].value)-1] = '\0';
return 0;
}
}

printf("configset: Unknown config param <%s>\n", key);

return 1;
}


+ 37
- 0
util.h View File

@@ -0,0 +1,37 @@
/*
* Copyright (C) 2011 Bernhard Froehlich <decke@bluelife.at>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Author's name may not be used endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 _UTIL_H_
#define _UTIL_H_

#define CONFIGMAXKEY 25
#define CONFIGMAXVALUE 50

extern int configparse(char *filename);
extern char* configget(char *key);
extern int configset(char *key, char *value);

#endif /* _UTIL_H_ */

Loading…
Cancel
Save