157 lines
3.5 KiB
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();
|
|
}
|