if (client==probe) {
network_stop();
/* Never destroy 'client' now - it has been destroyed by network_stop()! */
- if (network_notify_hostip)
- (*network_notify_hostip)(0);
+ g_warning(_("No probe response from the server, stopping the daemon. Please check your public Internet connectivity."));
}
else {
client_destroy(client);
static void handle_master(struct client *master)
{
+ g_return_if_fail(master!=NULL);
+
+ for (;;) {
+char packet[0x10000];
ssize_t gotlen;
struct sockaddr_in sockaddr_in_from;
-char packet[0x10000];
struct client *client;
struct sockaddr_in sockaddr_in_server;
socklen_t sockaddr_in_from_length;
-
- g_return_if_fail(master!=NULL);
-
- sockaddr_in_from_length=sizeof(sockaddr_in_from);
- while (-1!=(gotlen=recvfrom(
- master->gpollfd.fd, /* s */
- packet, /* buf */
- sizeof(packet), /* len */
- 0, /* flags */
- (struct sockaddr *)&sockaddr_in_from, /* from */
- &sockaddr_in_from_length))) { /* fromlen */
GList *clientl;
+ sockaddr_in_from_length=sizeof(sockaddr_in_from);
+ if (-1==(gotlen=recvfrom(
+ master->gpollfd.fd, /* s */
+ packet, /* buf */
+ sizeof(packet), /* len */
+ 0, /* flags */
+ (struct sockaddr *)&sockaddr_in_from, /* from */
+ &sockaddr_in_from_length))) /* fromlen */
+ break;
+
if (sockaddr_in_from_length!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */
continue;
static void handle_probe(struct client *probe)
{
+ g_return_if_fail(probe!=NULL);
+
+ for (;;) {
ssize_t gotlen;
struct sockaddr_in sockaddr_in_from;
char packet[0x10000];
socklen_t sockaddr_in_from_length;
- g_return_if_fail(probe!=NULL);
-
- sockaddr_in_from_length=sizeof(sockaddr_in_from);
- while (-1!=(gotlen=recvfrom(
- master->gpollfd.fd, /* s */
- packet, /* buf */
- sizeof(packet), /* len */
- 0, /* flags */
- (struct sockaddr *)&sockaddr_in_from, /* from */
- &sockaddr_in_from_length))) { /* fromlen */
+ sockaddr_in_from_length=sizeof(sockaddr_in_from);
+ if (-1==(gotlen=recvfrom(
+ master->gpollfd.fd, /* s */
+ packet, /* buf */
+ sizeof(packet), /* len */
+ 0, /* flags */
+ (struct sockaddr *)&sockaddr_in_from, /* from */
+ &sockaddr_in_from_length))) /* fromlen */
+ break;
if (sockaddr_in_from_length!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */
continue;
static void handle_client(struct client *client)
{
+ g_return_if_fail(client!=NULL);
+ g_return_if_fail(master!=NULL);
+
+ for (;;) {
ssize_t gotlen;
struct sockaddr_in sockaddr_in_from;
char packet [0x10000];
socklen_t sockaddr_in_from_length;
- g_return_if_fail(client!=NULL);
- g_return_if_fail(master!=NULL);
-
- while (-1!=(gotlen=recvfrom(
- client->gpollfd.fd, /* s */
- packet, /* buf */
- sizeof(packet), /* len */
- 0, /* flags */
- (struct sockaddr *)&sockaddr_in_from, /* from */
- &sockaddr_in_from_length))) { /* fromlen */
+ sockaddr_in_from_length=sizeof(sockaddr_in_from);
+ if (-1==(gotlen=recvfrom(
+ client->gpollfd.fd, /* s */
+ packet, /* buf */
+ sizeof(packet), /* len */
+ 0, /* flags */
+ (struct sockaddr *)&sockaddr_in_from, /* from */
+ &sockaddr_in_from_length))) /* fromlen */
+ break;
if (sockaddr_in_from_length!=sizeof(sockaddr_in_from)) /* FIXME: errors reporting */
continue;
client_touch(client);
sock_gsource=NULL;
}
- write_daemon_running((pid_t)-1); /* unlink */
+ write_daemon_running((pid_t)-1); /* unlink; errors ignored */
}
static gboolean sock_gsource_new(void)
if (!sock_gsource_new())
return FALSE;
- if (-1==(sock=socket(AF_INET,SOCK_DGRAM,0))) {
- g_warning("socket(AF_INET,SOCK_DGRAM): %m");
+ if (-1==(sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP))) {
+ g_warning("socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP): %m");
return NULL;
}
if (ioctl(sock,FIONBIO,&oneul)) { /* non-blocking mode */
probe_send(probe,port);
client_touch(probe); /* timeout */
- write_daemon_running(getpid());
+ write_daemon_running(getpid()); /* errors ignored */
+ if (network_notify_hostip)
+ (*network_notify_hostip)(0);
+ return TRUE;
+}
+
+gboolean optarg_port_set_string(const gchar *port_string)
+{
+char *endp;
+long port_long;
+
+ g_return_val_if_fail(port_string!=NULL,FALSE);
+
+ port_long=strtol(port_string,&endp,0);
+ if (endp && *endp) {
+ g_warning(_("Invalid port specification, offending string: %s"),endp);
+ return FALSE;
+ }
+ if (port_long<1 || port_long>=G_MAXINT || (endp && *endp)) {
+ g_warning(_("Invalid port integer number specification (%ld)"),port_long);
+ return FALSE;
+ }
+ optarg_port=port_long;
return TRUE;
}
}
if (daemon_pid==getpid()) {
sock_gsource_destroy();
- return TRUE;
+ goto ok;
}
errno=0;
kill(daemon_pid,SIGKILL);
errno_save=errno;
+ write_daemon_running((pid_t)-1); /* unlink; errors ignored */
if (errno_save) {
g_warning(udpgate_printf_alloca(_("Unable to stop the daemon at PID %d: %s"),
(int)daemon_pid,strerror(errno_save)));
return FALSE;
}
+ok:
+ if (network_notify_hostip)
+ (*network_notify_hostip)(0);
return TRUE;
}
+
+static GMainLoop *gmainloop;
+static void network_detach_network_notify_hostip(guint32 hostip_guint32)
+{
+ if (!hostip_guint32)
+ g_main_loop_quit(gmainloop);
+}
+
+gboolean network_detach(void)
+{
+pid_t daemon_pid,forked_pid;
+
+ if ((pid_t)-1==(daemon_pid=is_daemon_running()))
+ return TRUE;
+ if (getpid()!=daemon_pid)
+ return TRUE;
+ if (!optarg_no_fork) {
+ if ((pid_t)-1==(forked_pid=fork())) {
+ g_warning("fork(2): %m");
+ return FALSE;
+ }
+ if (forked_pid) {
+ /* parent */
+ return TRUE;
+ }
+ write_daemon_running(getpid()); /* errors ignored */
+ optarg_verbose=0;
+ close(STDIN_FILENO);
+ close(STDOUT_FILENO);
+ close(STDERR_FILENO);
+ setpgrp();
+ setsid();
+ }
+
+ network_notify_hostip=network_detach_network_notify_hostip;
+ gmainloop=g_main_loop_new(
+ NULL, /* context */
+ TRUE); /* is_running; ignored */
+ g_main_loop_run(gmainloop); /* loop */
+ /* Unable to contact the server, aborting. */
+ return FALSE;
+}