Cleanup getenv(3) by GLib compatible functions.
[udpgate.git] / src / network.c
index 4d2ba2f..07a3061 100644 (file)
 #include <glib/galloca.h>
 #include <glib/gprintf.h>
 #include <glib/grand.h>
+#include <glib/gutils.h>
 
 #include "network.h"
 #include "packet.h"
 #include "main.h"      /* for optarg_verbose */
+#include "pathname.h"
 
 
 /* Config: */
-#define NETWORK_PATHNAME_PID "/var/run/udpgate.pid"
 #define SOCK_SOURCE_CHECK_EVENTS (G_IO_IN)     /* |G_IO_PRI */
 #define SOCK_SOURCE_CHECK_REVENTS (SOCK_SOURCE_CHECK_EVENTS)   /* |G_IO_ERR|G_IO_HUP|G_IO_NVAL */
-#define SERVER_INADDR 0x7F000001
-#undef  SERVER_INADDR
-#define SERVER_INADDR 0x511F02EA       /* paulina.vellum.cz = 81.31.2.234; host order */
+#define SERVER_INADDR 0xC37AD054       /* mms2.org = 195.122.208.84; host order */
 #define SERVER_PORT   9201     /* host order */
 #define PROBE_INADDR  SERVER_INADDR    /* host order */
-#define PROBE_PORT    8202     /* host order */
+#define PROBE_PORT    8201     /* host order */
 #define CLIENT_TIMEOUT_SEC (5*60)
 #define PROBE_TIMEOUT_SEC_BASE 5
 #define PROBE_TIMEOUT_SEC_MAX 3500
 void (*network_notify_hostip)(guint32 hostip_guint32);
 
 
+static G_CONST_RETURN gchar *pid_pathname(void)
+{
+static const gchar *static_pathname;
+static const char *user_val;
+
+       if (!static_pathname)
+               user_val=g_get_user_name();
+       return pathname_find(&static_pathname,
+                       G_STRINGIFY(LOCALSTATEDIR) "/run",PACKAGE ".pid",
+                       (!user_val ? NULL : g_get_tmp_dir()),
+                                       (!user_val ? NULL : udpgate_printf_alloca(".%s-%s.pid",user_val,PACKAGE)),
+                       NULL);
+}
+
+
 struct client {
        GPollFD gpollfd;
        struct sockaddr_in sockaddr_in_from;
@@ -86,7 +100,7 @@ int pid_int;
        if (sock_gsource)
                return getpid();
 
-       if (!(f=fopen(NETWORK_PATHNAME_PID,"r")))
+       if (!(f=fopen(pid_pathname(),"r")))
                goto err;
        got=fgets(buf,sizeof(buf),f);
        fclose(f);      /* FIXME: error ignored */
@@ -112,15 +126,20 @@ static gboolean write_daemon_running(pid_t pid)
 FILE *f;
 
        if (pid==(pid_t)-1) {
-               if (unlink(NETWORK_PATHNAME_PID)) {
+               if (unlink(pid_pathname())) {
                        if (errno!=ENOENT)
-                               g_warning(_("Error removing PID file \"%s\": %m"),NETWORK_PATHNAME_PID);
+                               g_warning(_("Error removing PID file \"%s\": %m"),pid_pathname());
                        return FALSE;
                        }
                return TRUE;
                }
-       if (!(f=fopen(NETWORK_PATHNAME_PID,"w"))) {
-               g_warning(_("Error writing PID %d to \"%s\": %m"),(int)pid,NETWORK_PATHNAME_PID);
+       if (!(f=fopen(pid_pathname(),"w"))) {
+static gboolean once=TRUE;
+
+               if (once) {
+                       once=FALSE;
+                       g_warning(_("Error writing PID %d to \"%s\": %m"),(int)pid,pid_pathname());
+                       }
                return FALSE;
                }
        fprintf(f,"%d\n",(int)pid);     /* errors ignored */
@@ -278,8 +297,12 @@ GList *clientl;
                        continue;
                        }
                /* Not yet initialized by 'probe' reply - drop it. */
-               if (probe)
+               if (probe) {
+                       if (optarg_verbose)
+                               g_message(_("Data packet received from %s but no probe reply yet; dropping packet."),
+                                               SOCKADDR_IN_TO_STRING(&sockaddr_in_from));
                        continue;
+                       }
 
                /* FIXME: Performance: Ugly search... */
                for (clientl=sock_client_list;clientl;clientl=clientl->next) {
@@ -573,19 +596,26 @@ size_t packet_length;
 static gboolean master_start(gint port)
 {
 struct sockaddr_in sockaddr_in;
+uint16_t port_use;
 
        g_return_val_if_fail(port>=0,FALSE);
        g_return_val_if_fail(master==NULL,FALSE);
 
+       port_use=port;
+       if (port < 0 || port_use != port) {
+               g_warning(_("Port value %d is not valid for IPv4!"),(int)port);
+               return FALSE;
+               }
+
        /* Setup 'master': */
        if (!(master=client_new()))
                return FALSE;
        UDPGATE_MEMZERO(&sockaddr_in);
        sockaddr_in.sin_family=AF_INET;
-       sockaddr_in.sin_port=htons(port);
+       sockaddr_in.sin_port=htons(port_use);
        sockaddr_in.sin_addr.s_addr=htonl(INADDR_ANY);
        if (bind(master->gpollfd.fd,(struct sockaddr *)&sockaddr_in,sizeof(sockaddr_in))) {
-               g_warning("bind(sock,{AF_INET,INADDR_ANY:%d}): %m",(int)port);
+               g_warning("bind(sock,{AF_INET,INADDR_ANY:%u}): %m",(unsigned)port_use);
                return FALSE;
                }
        return TRUE;