You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
297 lines
6.8 KiB
297 lines
6.8 KiB
/**
|
|
* \file
|
|
*
|
|
* \author Georg Hopp
|
|
*
|
|
* \copyright
|
|
* Copyright © 2012 Georg Hopp
|
|
*
|
|
* 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 3 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, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <fcntl.h>
|
|
|
|
#include <sys/time.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/types.h>
|
|
#include <sys/wait.h>
|
|
#include <sys/time.h>
|
|
#include <sys/signal.h>
|
|
#include <sys/param.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/mman.h>
|
|
#include <errno.h>
|
|
|
|
#include <trbase.h>
|
|
#include <trhash.h>
|
|
#include <trio.h>
|
|
|
|
#include "server.h"
|
|
#include "http/worker.h"
|
|
#include "auth.h"
|
|
#include "application/application.h"
|
|
#include "application/adapter/http.h"
|
|
#include "config/config.h"
|
|
#include "config/value.h"
|
|
|
|
#include "utils/signalHandling.h"
|
|
#include "utils/mime_type.h"
|
|
|
|
#define DEFAULT_SECS 10
|
|
//#define DEFAULT_USECS (1000000 / HZ * 2)
|
|
//#define DEFAULT_SECS 1
|
|
#define DEFAULT_USECS 0
|
|
|
|
|
|
void nullhandler() {}
|
|
|
|
void daemonize(void);
|
|
|
|
TR_Logger logger;
|
|
Config config;
|
|
|
|
int
|
|
main()
|
|
{
|
|
long psize = sysconf(_SC_PAGESIZE);
|
|
struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY};
|
|
|
|
pid_t pid;
|
|
int status;
|
|
int shm;
|
|
struct randval * value;
|
|
|
|
logger = TR_new(TR_LoggerSyslog, TR_LOGGER_DEBUG);
|
|
config = TR_new(Config, CONFIGDIR "/taskrambler.conf");
|
|
|
|
if (NULL == config) {
|
|
TR_loggerLog(logger, TR_LOGGER_INFO,
|
|
"unable to load configuration file: %s\n",
|
|
CONFIGDIR "/taskrambler.conf");
|
|
|
|
if (! TR_INSTANCE_OF(TR_LoggerStderr, logger)) {
|
|
fprintf(stderr,
|
|
"unable to load configuration file: %s\n",
|
|
CONFIGDIR "/taskrambler.conf");
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
setrlimit(RLIMIT_CPU, &limit);
|
|
|
|
getrlimit(RLIMIT_NOFILE, &limit);
|
|
limit.rlim_cur = limit.rlim_max;
|
|
setrlimit(RLIMIT_NOFILE, &limit);
|
|
|
|
init_signals();
|
|
daemonize();
|
|
|
|
shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU);
|
|
if (-1 == ftruncate(shm, psize)) {
|
|
doShutdown = 1;
|
|
}
|
|
|
|
switch((pid = fork())) {
|
|
case -1:
|
|
break;
|
|
|
|
case 0:
|
|
{
|
|
sigset_t block_these, pause_mask;
|
|
struct sigaction s;
|
|
struct itimerval interval;
|
|
|
|
value = mmap (0, sizeof(struct randval), PROT_READ|PROT_WRITE,
|
|
MAP_SHARED, shm, 0);
|
|
value->timestamp = 0;
|
|
value->value = 0;
|
|
|
|
close(shm);
|
|
|
|
// Block SIGALRM
|
|
sigemptyset(&block_these);
|
|
sigaddset(&block_these, SIGALRM);
|
|
sigprocmask(SIG_BLOCK, &block_these, &pause_mask);
|
|
|
|
// Set up handler for SIGALRM
|
|
sigemptyset(&s.sa_mask);
|
|
sigaddset(&s.sa_mask, SIGINT);
|
|
s.sa_flags = 0;
|
|
s.sa_handler = nullhandler;
|
|
if (sigaction(SIGALRM, &s, NULL) < 0) {
|
|
perror("sigaction SIGALRM");
|
|
exit (1);
|
|
}
|
|
|
|
interval.it_value.tv_sec = DEFAULT_SECS;
|
|
interval.it_value.tv_usec = DEFAULT_USECS;
|
|
interval.it_interval.tv_sec = DEFAULT_SECS;
|
|
interval.it_interval.tv_usec = DEFAULT_USECS;
|
|
|
|
setitimer(ITIMER_REAL, &interval, NULL);
|
|
|
|
// child
|
|
while(!doShutdown) {
|
|
value->timestamp = time(NULL);
|
|
value->value = rand() % 100;
|
|
sigsuspend(&pause_mask);
|
|
}
|
|
}
|
|
break;
|
|
|
|
default:
|
|
{
|
|
Storage users;
|
|
Storage passwords;
|
|
Auth auth;
|
|
Application application;
|
|
Router router;
|
|
ApplicationAdapterHttp adapterHttp;
|
|
HttpWorker worker;
|
|
Server server;
|
|
TR_Uuid user_namespace;
|
|
|
|
ConfigValue ldap_base =
|
|
configGet(config, CSTRA("ldap_base"));
|
|
ConfigValue ldap_host =
|
|
configGet(config, CSTRA("ldap_host"));
|
|
ConfigValue runtime_dir =
|
|
configGet(config, CSTRA("runtime_dir"));
|
|
ConfigValue port =
|
|
configGet(config, CSTRA("port"));
|
|
|
|
char user_storage[512];
|
|
char password_storage[512];
|
|
|
|
strcpy(user_storage, (runtime_dir->value).string);
|
|
strcpy(password_storage, (runtime_dir->value).string);
|
|
strcat(user_storage, "/users.db");
|
|
strcat(password_storage, "/passwords.db");
|
|
|
|
value = mmap (0, sizeof(int), PROT_READ|PROT_WRITE,
|
|
MAP_SHARED, shm, 0);
|
|
|
|
shm_unlink("/fooshm");
|
|
close(shm);
|
|
|
|
auth = TR_new(Auth);
|
|
authCreate(
|
|
auth,
|
|
AUTH_LDAP,
|
|
(ldap_host->value).string,
|
|
CONFSTRA(ldap_base));
|
|
|
|
users = TR_new(Storage, user_storage);
|
|
passwords = TR_new(Storage, password_storage);
|
|
|
|
if (NULL == users || NULL == passwords) {
|
|
puts("error opening database files...\n");
|
|
doShutdown = 1;
|
|
}
|
|
|
|
authCreate(auth, AUTH_STORAGE, passwords);
|
|
|
|
user_namespace = TR_uuidParse("14de9e60-d497-4754-be72-f3bed52541fc");
|
|
|
|
application = TR_new(
|
|
Application,
|
|
value,
|
|
users,
|
|
passwords,
|
|
user_namespace,
|
|
auth);
|
|
|
|
router = TR_new(Router, application);
|
|
adapterHttp = TR_new(ApplicationAdapterHttp, application, router);
|
|
|
|
worker = TR_new(HttpWorker, "taskrambler");
|
|
TR_subjectAttach(worker, adapterHttp);
|
|
|
|
server = TR_new(
|
|
Server,
|
|
logger,
|
|
worker,
|
|
(int)(port->value).number,
|
|
SOMAXCONN);
|
|
|
|
if (NULL != server && !doShutdown) {
|
|
serverRun(server);
|
|
}
|
|
else {
|
|
kill(pid, SIGINT);
|
|
}
|
|
|
|
do {
|
|
pid_t w;
|
|
|
|
w = waitpid(pid, &status, 0);
|
|
|
|
while (w == -1) {
|
|
switch(errno) {
|
|
case EINTR: w = waitpid(pid, &status, 0);
|
|
break;
|
|
case ECHILD: perror("no child");
|
|
// DROP THROUGH
|
|
default: w = 0;
|
|
}
|
|
}
|
|
|
|
if (0 < w) {
|
|
if (WIFEXITED(status)) {
|
|
TR_loggerLog(logger, TR_LOGGER_INFO,
|
|
"child exited, status=%d\n",
|
|
WEXITSTATUS(status));
|
|
} else if (WIFSIGNALED(status)) {
|
|
TR_loggerLog(logger, TR_LOGGER_INFO,
|
|
"killed by signal %d\n",
|
|
WTERMSIG(status));
|
|
} else if (WIFSTOPPED(status)) {
|
|
TR_loggerLog(logger, TR_LOGGER_INFO,
|
|
"stopped by signal %d\n",
|
|
WSTOPSIG(status));
|
|
} else if (WIFCONTINUED(status)) {
|
|
TR_loggerLog(logger, TR_LOGGER_INFO, "continued\n");
|
|
}
|
|
}
|
|
} while (!WIFEXITED(status) && !WIFSIGNALED(status));
|
|
|
|
TR_delete(server);
|
|
TR_delete(worker);
|
|
TR_delete(adapterHttp);
|
|
TR_delete(router);
|
|
TR_delete(application);
|
|
TR_delete(user_namespace);
|
|
TR_delete(passwords);
|
|
TR_delete(users);
|
|
TR_delete(auth);
|
|
|
|
clearMimeTypes();
|
|
assetPoolCleanup();
|
|
}
|
|
|
|
break;
|
|
}
|
|
|
|
TR_delete(config);
|
|
TR_delete(logger);
|
|
TR_cleanup();
|
|
|
|
return 0;
|
|
}
|
|
|
|
// vim: set ts=4 sw=4:
|