This repository has been archived on 2020-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
eilduscd/src/main.c

157 lines
3.5 KiB
C

#include <stdio.h>
#include <stdint.h>
#include <unistd.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
#include <getopt.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "netlink_watch.h"
#include "nwstatus.h"
#include "ildus-manager.h"
int
main_loop(void) {
netstatus_init();
netlink_init();
for (;;) {
struct timeval t;
printf("-----------------------------------\n");
print_status();
printf("***********************\n");
if (ildus_manager_do_update(get_best_v4_address(), get_best_v6_address())) {
/* Nothing to do anymore. We could set an indefinite timeout, but this
* will do */
t.tv_sec = 24 * 3600;
} else {
/* Something went wrong during the update, try again in 60 seconds */
t.tv_sec = 60;
}
t.tv_usec = 0;
/* Got some updates, now wait some time for things to stabilize */
for (;;) {
fd_set set;
int ret;
FD_ZERO(&set);
FD_SET(netlink_get_fd(), &set);
ret = select(netlink_get_fd() + 1, &set, NULL, NULL, &t);
if (ret < 0) {
/* Some kind of error, uhm, uhuh */
perror("Select failed?: ");
return -1;
} else if (ret == 0) {
break;
}
/* Some data, 2 second timeout so things can stabilize a little before
* we send a potential update the ildus server */
netlink_recv();
netlink_flush();
t.tv_sec = 2;
t.tv_usec = 0;
}
}
return 0;
}
void
usage(char *progname) {
printf("Usage: %s [OPTIONS]\n", progname);
printf("\t-f \tRun on the foreground instead of deamonizing\n");
printf("\t-c file \tSpecify an alternate config file\n");
}
void
load_config(char *file) {
#define BUFSIZE 1024
char *config[5];
char buffer[BUFSIZE];
int i = 0;
FILE *f;
f = fopen(file, "r");
if (f == NULL) {
fprintf(stderr, "Failed to open config file: %s\n", strerror(errno));
exit(1);
}
while (i < 5) {
int n;
if (feof(f)) {
fprintf(stderr, "Premature end config file: %s\n", file);
exit(1);
}
if (fgets(buffer, BUFSIZE, f) == NULL) {
fprintf(stderr, "Read failure in config file: %s\n", strerror(errno));
exit(1);
}
if (buffer[0] == '#') {
continue;
}
for (n = strlen(buffer) - 1; n >= 0 && isspace(buffer[n]) ; n--) {
buffer[n] = '\0';
}
if (buffer[0] == '\0') {
continue;
}
config[i] = strdup(buffer);
i++;
}
fclose(f);
ildus_manager_init(config[0], atoi(config[1]),
config[2], config[3], config[4]);
}
int
main(int argc, char **argv) {
char *configfile = "/etc/eilduscd.conf";
int daemonize = 1;
int op;
while ((op = getopt(argc, argv,"fc:")) > 0) {
switch (op) {
case 'f':
daemonize = 0;
break;
case 'c':
configfile = optarg;
break;
default:
usage(argv[0]);
exit(1);
}
}
load_config(configfile);
if (daemonize) {
int devnull;
devnull = open("/dev/null", O_RDWR);
if (devnull < 0) {
fprintf(stderr, "Couldn't open /dev/null\n");
exit(1);
}
switch (fork()) {
case -1:
fprintf(stderr, "Couldn't fork :(\n");
exit(1);
break;
case 0: /* child */
chdir("/");
dup2(devnull, STDIN_FILENO);
dup2(devnull, STDOUT_FILENO);
dup2(devnull, STDERR_FILENO);
close(devnull);
break;
default: /* parent */
exit(0);
}
}
return main_loop();
}