{
CoreApplication a(argc, argv, help);
Leds leds;
std::string basePath("/mnt/usbdrive/waran/route");
std::string stationName("unamed");
std::string interface("ath0");
bool doFork=true;
bool master=false;
uint16_t udpport=2976;
uint16_t tcpport=2975;
int beaconDelay=5000;
int timeoutDelay=15000;
int maskSize=24;
int i, j=1;
for(i=1; i<argc; i++) {
const char * arg=argv[i];
if(arg[0]=='-') {
if(strcmp(arg, "-p-tcp")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
tcpport=atoi(argv[i]);
} else if(strcmp(arg, "-p-udp")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
udpport=atoi(argv[i]);
} else if(strcmp(arg, "-s")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
stationName=argv[i];
} else if(strcmp(arg, "-b")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
basePath=argv[i];
} else if(strcmp(arg, "-i")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
interface=argv[i];
} else if(strcmp(arg, "-N")==0) {
doFork=false;
} else if(strcmp(arg, "-m")==0) {
master=true;
} else if(strcmp(arg, "-subnet-size")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
maskSize=32-atoi(argv[i]);
} else if(strcmp(arg, "-beacon-delay")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
beaconDelay=atoi(argv[i]);
} else if(strcmp(arg, "-timeout-delay")==0) {
CoreApplication::checkOptionArg(i, argc, argv, true);
timeoutDelay=atoi(argv[i]);
} else {
fprintf(stderr, "%s: bad option %s, see -help\n", a.applicationName(), argv[i]);
CoreApplication::exit(2);
}
} else {
argv[j++]=argv[i];
}
}
if(j < argc) {
argv[j]=0;
argc=j;
}
struct stat sInfo;
int sErr;
FILE * fpid;
if(doFork) {
sErr=stat("/var/run/waranrouted.pid", &sInfo);
if(sErr==0) {
syslog(LOG_ERR, "waranrouted is already running (stop it and remove /var/run/waranrouted.pid)\n");
}
pid_t pid, sid;
pid=fork();
if(pid < 0) {
syslog(LOG_ERR, "Cannot fork off the parent process\n");
CoreApplication::exit(2);
}
if(pid > 0) {
fpid=fopen("/var/run/waranrouted.pid","wt");
if(!fpid) {
syslog(LOG_ERR, "Cannot create /var/run/waranrouted.pid\n");
CoreApplication::exit(2);
}
fprintf(fpid, "%u\n", pid);
fclose(fpid);
exit(0);
}
umask(0);
openlog ("waranrouted", LOG_NDELAY | LOG_PID, LOG_DAEMON);
sid=setsid();
if(sid < 0) {
syslog(LOG_ERR, "Cannot create a new SID for the child process\n");
CoreApplication::exit(2);
}
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
}
signal(SIGTERM, interrupted);
signal(SIGINT, interrupted);
signal(SIGPIPE, nop);
signal(SIGSEGV, crashed);
signal(SIGABRT, crashed);
basePath+="/";
Log log;
if(doFork) {
std::string logFile=basePath;
logFile+=stationName;
logFile+=".log";
log.setFile(logFile.data());
}
Log::write(0, "start new daemon with pid %i\n",getpid());
Address::setMaskSize(24);
Address::identifyMe(interface.data());
if(!Address::me().isValid()) {
Log::write(1, "cannot get host address, check interface (option -i).\n");
return 2;
}
EventLoop loop;
BeaconTimer beacon(udpport, beaconDelay);
beacon.start();
PeerTracker * peers=new PeerTracker(interface.data(), tcpport);
while(!peers->listen(udpport)) {
Log::write(1, "cannot listen to port %hu, retry in 10 seconds\n", udpport);
sleep(10);
}
if(master) {
peers->setAsMaster();
}
loop.addStream(peers);
LinkServer * server=new LinkServer;
while(!server->listen(tcpport, 50)) {
Log::write(1, "cannot listen to port %hu, retry in 10 seconds\n", tcpport);
sleep(10);
}
loop.addStream(server);
DeadPeersTimer deadPeers(timeoutDelay);
deadPeers.start();
loop.exec();
delete server;
delete peers;
Log::write(0, "stop daemon with pid %i\n",getpid());
return 0;
}