main: fix 2 minor warnings for win64 build on debian squeeze
[olsrd.git] / src / main.c
index b2808e5..e741457 100644 (file)
@@ -69,7 +69,9 @@
 #endif /* __linux__ */
 
 #ifdef _WIN32
+#include <process.h>
 #include <winbase.h>
+#define olsr_shutdown(x) SignalHandler(x)
 #define close(x) closesocket(x)
 int __stdcall SignalHandler(unsigned long signo) __attribute__ ((noreturn));
 void ListInterfaces(void);
@@ -93,7 +95,7 @@ static void olsr_shutdown(int) __attribute__ ((noreturn));
 /*
  * Local function prototypes
  */
-void olsr_reconfigure(int) __attribute__ ((noreturn));
+void olsr_reconfigure(int signo) __attribute__ ((noreturn));
 
 static void print_usage(bool error);
 
@@ -210,6 +212,55 @@ static int olsr_create_lock_file(bool noExitOnFail) {
 }
 
 /**
+ * Write the current PID to the configured PID file (if one is configured)
+ */
+static void writePidFile(void) {
+  if (olsr_cnf->pidfile) {
+    char buf[PATH_MAX + 256];
+
+    /* create / open the PID file */
+#ifdef __WIN32
+    mode_t mode = S_IRUSR | S_IWUSR;
+#else
+    mode_t mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;
+#endif
+    int fd = open(olsr_cnf->pidfile, O_CREAT | O_WRONLY, mode);
+    if (fd < 0) {
+      snprintf(buf, sizeof(buf), "Could not open PID file %s", olsr_cnf->pidfile);
+      perror(buf);
+      olsr_shutdown(0);
+    }
+
+    /* write the PID */
+    {
+      pid_t pid = getpid();
+      int chars = snprintf(buf, sizeof(buf), "%d", (int)pid);
+      ssize_t chars_written = write(fd, buf, chars);
+      if (chars_written != chars) {
+        close(fd);
+        snprintf(buf, sizeof(buf), "Could not write the PID %d to the PID file %s", (int)pid, olsr_cnf->pidfile);
+        perror(buf);
+        if (remove(olsr_cnf->pidfile) < 0) {
+          snprintf(buf, sizeof(buf), "Could not remove the PID file %s", olsr_cnf->pidfile);
+          perror(buf);
+        }
+        olsr_shutdown(0);
+      }
+    }
+
+    if (close(fd) < 0) {
+      snprintf(buf, sizeof(buf), "Could not close PID file %s", olsr_cnf->pidfile);
+      perror(buf);
+      if (remove(olsr_cnf->pidfile) < 0) {
+        snprintf(buf, sizeof(buf), "Could not remove the PID file %s", olsr_cnf->pidfile);
+        perror(buf);
+      }
+      olsr_shutdown(0);
+    }
+  }
+}
+
+/**
  * loads a config file
  * @return <0 if load failed, 0 otherwise
  */
@@ -230,6 +281,28 @@ olsrmain_load_config(char *file) {
   return 0;
 }
 
+static void initRandom(void) {
+  unsigned int seed = (unsigned int)time(NULL);
+
+#ifndef _WIN32
+  int randomFile;
+
+  randomFile = open("/dev/random", O_RDONLY);
+  if (randomFile == -1) {
+    randomFile = open("/dev/urandom", O_RDONLY);
+  }
+
+  if (randomFile != -1) {
+    if (read(randomFile, &seed, sizeof(seed)) != sizeof(seed)) {
+      ; /* to fix an 'unused result' compiler warning */
+    }
+    close(randomFile);
+  }
+#endif /* _WIN32 */
+
+  srandom(seed);
+}
+
 /**
  * Main entrypoint
  */
@@ -296,8 +369,8 @@ int main(int argc, char *argv[]) {
   /* Open syslog */
   olsr_openlog("olsrd");
 
-  /* Using PID as random seed */
-  srandom(getpid());
+  /* setup random seed */
+  initRandom();
 
   /* Init widely used statics */
   memset(&all_zero, 0, sizeof(union olsr_ip_addr));
@@ -427,7 +500,10 @@ int main(int argc, char *argv[]) {
     olsr_syslog(OLSR_LOG_ERR, "rtnetlink socket: %m");
     olsr_exit(__func__, 0);
   }
-  fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK);
+
+  if (fcntl(olsr_cnf->rtnl_s, F_SETFL, O_NONBLOCK)) {
+    olsr_syslog(OLSR_LOG_INFO, "rtnetlink could not be set to nonblocking");
+  }
 
   if ((olsr_cnf->rt_monitor_socket = rtnetlink_register_socket(RTMGRP_LINK)) < 0) {
     olsr_syslog(OLSR_LOG_ERR, "rtmonitor socket: %m");
@@ -515,6 +591,15 @@ int main(int argc, char *argv[]) {
     }
   }
 
+#ifdef __linux__
+  /* startup gateway system */
+  if (olsr_cnf->smart_gw_active) {
+    if (olsr_startup_gateways()) {
+      olsr_exit("Cannot startup gateway tunnels", 1);
+    }
+  }
+#endif /* __linux__ */
+
   olsr_do_startup_sleep();
 
   /* Print heartbeat to stdout */
@@ -529,7 +614,9 @@ int main(int argc, char *argv[]) {
   /* Initialize the IPC socket */
 
   if (olsr_cnf->ipc_connections > 0) {
-    ipc_init();
+    if (ipc_init()) {
+      olsr_exit("ipc_init failure", 1);
+    }
   }
   /* Initialisation of different tables to be used. */
   olsr_init_tables();
@@ -545,6 +632,8 @@ int main(int argc, char *argv[]) {
   }
 #endif /* _WIN32 */
 
+  writePidFile();
+
   /*
    * Create locking file for olsrd, will be cleared after olsrd exits
    */
@@ -636,12 +725,12 @@ int main(int argc, char *argv[]) {
   return 1;
 } /* main */
 
+#ifndef _WIN32
 /**
  * Reconfigure olsrd. Currently kind of a hack...
  *
- *@param signal the signal that triggered this callback
+ *@param signo the signal that triggered this callback
  */
-#ifndef _WIN32
 void olsr_reconfigure(int signo __attribute__ ((unused))) {
   /* if we are started with -nofork, we do not want to go into the
    * background here. So we can simply stop on -HUP
@@ -696,7 +785,7 @@ static void olsr_shutdown_messages(void) {
 /**
  *Function called at shutdown. Signal handler
  *
- * @param signal the signal that triggered this call
+ * @param signo the signal that triggered this call
  */
 #ifdef _WIN32
 int __stdcall
@@ -748,6 +837,7 @@ static void olsr_shutdown(int signo __attribute__ ((unused)))
 #ifdef __linux__
   /* trigger gateway selection */
   if (olsr_cnf->smart_gw_active) {
+    olsr_shutdown_gateways();
     olsr_cleanup_gateways();
   }
 
@@ -839,12 +929,13 @@ static void print_usage(bool error) {
         "usage: olsrd [-f <configfile>] [ -i interface1 interface2 ... ]\n"
         "  [-d <debug_level>] [-ipv6] [-multi <IPv6 multicast address>]\n"
         "  [-lql <LQ level>] [-lqw <LQ winsize>] [-lqnt <nat threshold>]\n"
-        "  [-bcast <broadcastaddr>] [-ipc] [-dispin] [-dispout] [-delgw]\n"
+        "  [-bcast <broadcastaddr>] [-ipc] [-delgw]\n"
         "  [-hint <hello interval (secs)>] [-tcint <tc interval (secs)>]\n"
         "  [-midint <mid interval (secs)>] [-hnaint <hna interval (secs)>]\n"
         "  [-T <Polling Rate (secs)>] [-nofork] [-hemu <ip_address>]\n"
-        "  [-lql <LQ level>] [-lqa <LQ aging factor>]\n",
-        error ? "An error occured somwhere between your keyboard and your chair!\n" : "");
+        "  [-lql <LQ level>] [-lqa <LQ aging factor>]\n"
+        "  [-pidfile <pid file>]\n",
+        error ? "Error in command line parameters!\n" : "");
 }
 
 /**
@@ -871,12 +962,8 @@ int set_default_ifcnfs(struct olsr_if *ifs, struct if_config_options *cnf) {
 
 #define NEXT_ARG do { argv++;argc--; } while (0)
 #define CHECK_ARGC do { if(!argc) { \
-      if((argc - 1) == 1){ \
-      fprintf(stderr, "Error parsing command line options!\n"); \
-      } else { \
-      argv--; \
-      fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
-     } \
+     argv--; \
+     fprintf(stderr, "You must provide a parameter when using the %s switch!\n", *argv); \
      olsr_exit(__func__, EXIT_FAILURE); \
      } } while (0)
 
@@ -1075,22 +1162,6 @@ static int olsr_process_arguments(int argc, char *argv[],
     }
 
     /*
-     * Should we display the contents of packages beeing sent?
-     */
-    if (strcmp(*argv, "-dispin") == 0) {
-      parser_set_disp_pack_in(true);
-      continue;
-    }
-
-    /*
-     * Should we display the contents of incoming packages?
-     */
-    if (strcmp(*argv, "-dispout") == 0) {
-      net_set_disp_pack_out(true);
-      continue;
-    }
-
-    /*
      * Should we set up and send on a IPC socket for the front-end?
      */
     if (strcmp(*argv, "-ipc") == 0) {
@@ -1137,7 +1208,8 @@ static int olsr_process_arguments(int argc, char *argv[],
 
       ifa->cnf = get_default_if_config();
       ifa->host_emul = true;
-      memcpy(&ifa->hemu_ip, &in, sizeof(union olsr_ip_addr));
+      memset(&ifa->hemu_ip, 0, sizeof(ifa->hemu_ip));
+      memcpy(&ifa->hemu_ip, &in, sizeof(in));
       cnf->host_emul = true;
 
       continue;
@@ -1156,6 +1228,14 @@ static int olsr_process_arguments(int argc, char *argv[],
       continue;
     }
 
+    if (strcmp(*argv, "-pidfile") == 0) {
+      NEXT_ARG;
+      CHECK_ARGC;
+
+      cnf->pidfile = *argv;
+      continue;
+    }
+
     return -1;
   }
   return 0;