taskrambler  0.1.9
Web server and task management solution.
taskrambler.c File Reference
#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/signal.h>
#include <sys/param.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <errno.h>
#include "server.h"
#include "logger.h"
#include "http/worker.h"
#include "auth.h"
#include "application/application.h"
#include "application/adapter/http.h"
#include "interface/subject.h"
#include "config/config.h"
#include "config/value.h"
#include "class.h"
#include "utils/signalHandling.h"
#include "utils/memory.h"
#include "utils/mime_type.h"
+ Include dependency graph for taskrambler.c:

Go to the source code of this file.

Macros

#define DEFAULT_SECS   10
 
#define DEFAULT_USECS   0
 

Functions

void nullhandler ()
 
void daemonize (void)
 
int main ()
 

Variables

Logger logger
 
Config config
 

Detailed Description

Author
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/.

Definition in file taskrambler.c.

Macro Definition Documentation

#define DEFAULT_SECS   10

Definition at line 56 of file taskrambler.c.

Referenced by main().

#define DEFAULT_USECS   0

Definition at line 59 of file taskrambler.c.

Referenced by main().

Function Documentation

void daemonize ( void  )

Definition at line 38 of file daemonize.c.

References UMASK.

Referenced by main().

38  {
39  pid_t pid;
40 
41  if (0 > ((pid = fork()))) {
42  perror("deamoinze[fork]");
43  exit(EXIT_FAILURE);
44  } else if (0 != pid) {
45  exit(EXIT_SUCCESS);
46  }
47 
48  // make new child session leader
49  setsid();
50 
51  if (0 > ((pid = fork()))) {
52  perror("deamoinze[fork]");
53  exit(EXIT_FAILURE);
54  } else if (0 != pid) {
55  exit(EXIT_SUCCESS);
56  }
57 
58  // set umask and change to working directory to /
59  umask(UMASK);
60  if (-1 == chdir("/")) {
61  perror("daemonize");
62  exit(EXIT_FAILURE);
63  }
64 
65  // we should close all open filedescriptors now.
66  // But I assume that this function is called at the very start of the
67  // program and no more filedescriptors are open than the standard
68  // ones.
69 
70  // connect all standard streams to /dev/null
71  stderr = freopen("/dev/null", "w", stderr);
72  stdin = freopen("/dev/null", "r", stdin);
73  stdout = freopen("/dev/null", "w", stdout);
74 }
#define UMASK
Definition: daemonize.c:36

+ Here is the caller graph for this function:

int main ( )

Definition at line 70 of file taskrambler.c.

References assetPoolCleanup(), AUTH_LDAP, AUTH_STORAGE, authCreate(), clearMimeTypes(), config, configGet(), CONFSTRA, CSTRA, daemonize(), DEFAULT_SECS, DEFAULT_USECS, doShutdown, init_signals(), INSTANCE_OF, logger, LOGGER_DEBUG, LOGGER_INFO, loggerLog(), memCleanup(), nullhandler(), serverRun(), subjectAttach(), and randval::value.

71 {
72  long psize = sysconf(_SC_PAGESIZE);
73  struct rlimit limit = {RLIM_INFINITY, RLIM_INFINITY};
74 
75  pid_t pid;
76  int status;
77  int shm;
78  struct randval * value;
79 
80  logger = new(LoggerSyslog, LOGGER_DEBUG);
81  config = new(Config, CONFIGDIR "/taskrambler.conf");
82 
83  if (NULL == config) {
85  "unable to load configuration file: %s\n",
86  CONFIGDIR "/taskrambler.conf");
87 
88  if (! INSTANCE_OF(LoggerStderr, logger)) {
89  fprintf(stderr,
90  "unable to load configuration file: %s\n",
91  CONFIGDIR "/taskrambler.conf");
92  }
93 
94  return 1;
95  }
96 
97  setrlimit(RLIMIT_CPU, &limit);
98 
99  getrlimit(RLIMIT_NOFILE, &limit);
100  limit.rlim_cur = limit.rlim_max;
101  setrlimit(RLIMIT_NOFILE, &limit);
102 
103  init_signals();
104  daemonize();
105 
106  shm = shm_open("/fooshm", O_RDWR|O_CREAT, S_IRWXU);
107  if (-1 == ftruncate(shm, psize)) {
108  doShutdown = 1;
109  }
110 
111  switch((pid = fork())) {
112  case -1:
113  break;
114 
115  case 0:
116  {
117  sigset_t block_these, pause_mask;
118  struct sigaction s;
119  struct itimerval interval;
120 
121  value = mmap (0, sizeof(struct randval), PROT_READ|PROT_WRITE,
122  MAP_SHARED, shm, 0);
123  value->timestamp = 0;
124  value->value = 0;
125 
126  close(shm);
127 
128  // Block SIGALRM
129  sigemptyset(&block_these);
130  sigaddset(&block_these, SIGALRM);
131  sigprocmask(SIG_BLOCK, &block_these, &pause_mask);
132 
133  // Set up handler for SIGALRM
134  sigemptyset(&s.sa_mask);
135  sigaddset(&s.sa_mask, SIGINT);
136  s.sa_flags = 0;
137  s.sa_handler = nullhandler;
138  if (sigaction(SIGALRM, &s, NULL) < 0) {
139  perror("sigaction SIGALRM");
140  exit (1);
141  }
142 
143  interval.it_value.tv_sec = DEFAULT_SECS;
144  interval.it_value.tv_usec = DEFAULT_USECS;
145  interval.it_interval.tv_sec = DEFAULT_SECS;
146  interval.it_interval.tv_usec = DEFAULT_USECS;
147 
148  setitimer(ITIMER_REAL, &interval, NULL);
149 
150  // child
151  while(!doShutdown) {
152  value->timestamp = time(NULL);
153  value->value = rand() % 100;
154  sigsuspend(&pause_mask);
155  }
156  }
157  break;
158 
159  default:
160  {
161  Storage users;
162  Storage passwords;
163  Auth auth;
164  Application application;
165  Router router;
166  ApplicationAdapterHttp adapterHttp;
167  HttpWorker worker;
168  Server server;
169 
170  ConfigValue ldap_base =
171  configGet(config, CSTRA("ldap_base"));
172  ConfigValue ldap_host =
173  configGet(config, CSTRA("ldap_host"));
174  ConfigValue runtime_dir =
175  configGet(config, CSTRA("runtime_dir"));
176  ConfigValue port =
177  configGet(config, CSTRA("port"));
178 
179  char user_storage[512];
180  char password_storage[512];
181 
182  strcpy(user_storage, (runtime_dir->value).string);
183  strcpy(password_storage, (runtime_dir->value).string);
184  strcat(user_storage, "/users.db");
185  strcat(password_storage, "/passwords.db");
186 
187  value = mmap (0, sizeof(int), PROT_READ|PROT_WRITE,
188  MAP_SHARED, shm, 0);
189 
190  shm_unlink("/fooshm");
191  close(shm);
192 
193  auth = new(Auth);
194  authCreate(
195  auth,
196  AUTH_LDAP,
197  (ldap_host->value).string,
198  CONFSTRA(ldap_base));
199 
200  users = new(Storage, user_storage);
201  passwords = new(Storage, password_storage);
202 
203  if (NULL == users || NULL == passwords) {
204  puts("error opening database files...\n");
205  doShutdown = 1;
206  }
207 
208  authCreate(auth, AUTH_STORAGE, passwords);
209 
210  application = new(
211  Application,
212  value,
213  users,
214  passwords,
215  "14de9e60-d497-4754-be72-f3bed52541fc",
216  auth);
217 
218  router = new(Router, application);
219  adapterHttp = new(ApplicationAdapterHttp, application, router);
220 
221  worker = new(HttpWorker, "taskrambler");
222  subjectAttach(worker, adapterHttp);
223 
224  server = new(
225  Server,
226  logger,
227  worker,
228  (int)(port->value).number,
229  SOMAXCONN);
230 
231  if (NULL != server && !doShutdown) {
232  serverRun(server);
233  }
234  else {
235  kill(pid, SIGINT);
236  }
237 
238  do {
239  pid_t w;
240 
241  w = waitpid(pid, &status, 0);
242 
243  while (w == -1) {
244  switch(errno) {
245  case EINTR: w = waitpid(pid, &status, 0);
246  break;
247  case ECHILD: perror("no child");
248  // DROP THROUGH
249  default: w = 0;
250  }
251  }
252 
253  if (0 < w) {
254  if (WIFEXITED(status)) {
255  loggerLog(logger, LOGGER_INFO,
256  "child exited, status=%d\n",
257  WEXITSTATUS(status));
258  } else if (WIFSIGNALED(status)) {
259  loggerLog(logger, LOGGER_INFO,
260  "killed by signal %d\n",
261  WTERMSIG(status));
262  } else if (WIFSTOPPED(status)) {
263  loggerLog(logger, LOGGER_INFO,
264  "stopped by signal %d\n",
265  WSTOPSIG(status));
266  } else if (WIFCONTINUED(status)) {
267  loggerLog(logger, LOGGER_INFO, "continued\n");
268  }
269  }
270  } while (!WIFEXITED(status) && !WIFSIGNALED(status));
271 
272  delete(server);
273  delete(worker);
274  delete(adapterHttp);
275  delete(router);
276  delete(application);
277  delete(passwords);
278  delete(users);
279  delete(auth);
280 
281  clearMimeTypes();
283  }
284 
285  break;
286  }
287 
288  delete(config);
289  delete(logger);
290  memCleanup();
291 
292  return 0;
293 }
int authCreate(Auth, AuthModule,...)
Definition: auth/create.c:33
ConfigValue configGet(Config, const char *, size_t)
Definition: config/get.c:31
Logger logger
Definition: taskrambler.c:66
int value
Definition: application.h:42
void assetPoolCleanup(void)
Definition: pool.c:88
Config config
Definition: taskrambler.c:67
#define CSTRA(val)
Const STRing Argument.
Definition: memory.h:26
void serverRun(Server this)
Definition: run.c:36
void loggerLog(void *, logger_level, const char *const,...)
Definition: i_logger.c:38
#define DEFAULT_USECS
Definition: taskrambler.c:59
void daemonize(void)
Definition: daemonize.c:38
volatile int doShutdown
#define DEFAULT_SECS
Definition: taskrambler.c:56
void subjectAttach(void *, void *)
Definition: subject.c:32
void init_signals(void)
void memCleanup()
Definition: memory.c:862
#define INSTANCE_OF(class, obj)
Definition: class/class.h:89
void clearMimeTypes(void)
Definition: mime_type.c:106
void nullhandler()
Definition: taskrambler.c:62
#define CONFSTRA(val)
Definition: config/value.h:33

+ Here is the call graph for this function:

void nullhandler ( )

Definition at line 62 of file taskrambler.c.

Referenced by main().

62 {}

+ Here is the caller graph for this function:

Variable Documentation

Config config

Definition at line 67 of file taskrambler.c.

Referenced by CLASS(), configCtor(), configDtor(), configGet(), httpWorkerProcess(), and main().