Update copyright notices.
[liboping.git] / src / liboping.c
index 117cbfa..eca5c16 100644 (file)
@@ -1,6 +1,6 @@
 /**
  * Object oriented C module to send ICMP and ICMPv6 `echo's.
- * Copyright (C) 2006-2016  Florian octo Forster <ff at octo.it>
+ * Copyright (C) 2006-2017  Florian octo Forster <ff at octo.it>
  *
  * This library is free software; you can redistribute it and/or modify it
  * under the terms of the GNU Lesser General Public License as published by the
@@ -957,14 +957,12 @@ static pinghost_t *ping_alloc (void)
 
 static void ping_free (pinghost_t *ph)
 {
-       if (ph->username != NULL)
-               free (ph->username);
-
-       if (ph->hostname != NULL)
-               free (ph->hostname);
+       if (ph == NULL)
+               return;
 
-       if (ph->data != NULL)
-               free (ph->data);
+       free (ph->username);
+       free (ph->hostname);
+       free (ph->data);
 
        free (ph);
 }
@@ -1065,12 +1063,8 @@ static int ping_open_socket(pingobj_t *obj, int addrfam)
 #ifdef SO_TIMESTAMP
        if (1) /* {{{ */
        {
-               int status;
-               int opt = 1;
-
-               status = setsockopt (fd,
-                               SOL_SOCKET, SO_TIMESTAMP,
-                               &opt, sizeof (opt));
+               int status = setsockopt (fd, SOL_SOCKET, SO_TIMESTAMP,
+                                        &(int){1}, sizeof(int));
                if (status != 0)
                {
                        ping_set_errno (obj, errno);
@@ -1087,37 +1081,27 @@ static int ping_open_socket(pingobj_t *obj, int addrfam)
 
        if (addrfam == AF_INET)
        {
-               int opt;
-
 #ifdef IP_RECVTOS
                /* Enable receiving the TOS field */
-               opt = 1;
-               setsockopt (fd, IPPROTO_IP, IP_RECVTOS,
-                               &opt, sizeof (opt));
+               setsockopt (fd, IPPROTO_IP, IP_RECVTOS, &(int){1}, sizeof(int));
 #endif /* IP_RECVTOS */
 
                /* Enable receiving the TTL field */
-               opt = 1;
-               setsockopt (fd, IPPROTO_IP, IP_RECVTTL,
-                               &opt, sizeof (opt));
+               setsockopt (fd, IPPROTO_IP, IP_RECVTTL, &(int){1}, sizeof(int));
        }
 #if defined(IPV6_RECVHOPLIMIT) || defined(IPV6_RECVTCLASS)
        else if (addrfam == AF_INET6)
        {
-               int opt;
-
 # if defined(IPV6_RECVHOPLIMIT)
                /* For details see RFC 3542, section 6.3. */
-               opt = 1;
                setsockopt (fd, IPPROTO_IPV6, IPV6_RECVHOPLIMIT,
-                               &opt, sizeof (opt));
+                           &(int){1}, sizeof(int));
 # endif /* IPV6_RECVHOPLIMIT */
 
 # if defined(IPV6_RECVTCLASS)
                /* For details see RFC 3542, section 6.5. */
-               opt = 1;
                setsockopt (fd, IPPROTO_IPV6, IPV6_RECVTCLASS,
-                               &opt, sizeof (opt));
+                           &(int){1}, sizeof(int));
 # endif /* IPV6_RECVTCLASS */
        }
 #endif /* IPV6_RECVHOPLIMIT || IPV6_RECVTCLASS */
@@ -1139,9 +1123,9 @@ pingobj_t *ping_construct (void)
 {
        pingobj_t *obj;
 
-       if ((obj = (pingobj_t *) malloc (sizeof (pingobj_t))) == NULL)
+       if ((obj = malloc (sizeof (*obj))) == NULL)
                return (NULL);
-       memset (obj, 0, sizeof (pingobj_t));
+       memset (obj, 0, sizeof (*obj));
 
        obj->timeout    = PING_DEF_TIMEOUT;
        obj->ttl        = PING_DEF_TTL;
@@ -1157,29 +1141,22 @@ pingobj_t *ping_construct (void)
 void ping_destroy (pingobj_t *obj)
 {
        pinghost_t *current;
-       pinghost_t *next;
 
        if (obj == NULL)
                return;
 
        current = obj->head;
-       next = NULL;
 
        while (current != NULL)
        {
-               next = current->next;
+               pinghost_t *next = current->next;
                ping_free (current);
                current = next;
        }
 
-       if (obj->data != NULL)
-               free (obj->data);
-
-       if (obj->srcaddr != NULL)
-               free (obj->srcaddr);
-
-       if (obj->device != NULL)
-               free (obj->device);
+       free (obj->data);
+       free (obj->srcaddr);
+       free (obj->device);
 
        if (obj->fd4 != -1)
                close(obj->fd4);
@@ -1367,8 +1344,6 @@ int ping_send (pingobj_t *obj)
        struct timeval nowtime;
        struct timeval timeout;
 
-       int ret = 0;
-
        _Bool need_ipv4_socket = 0;
        _Bool need_ipv6_socket = 0;
 
@@ -1432,6 +1407,12 @@ int ping_send (pingobj_t *obj)
         * receive a "pong" yet. */
        int pings_in_flight = 0;
 
+       /* pongs_received is the number of echo replies received. Unless there
+        * is an error, this is used as the return value of ping_send(). */
+       int pongs_received = 0;
+
+       int error_count = 0;
+
        while (pings_in_flight > 0 || host_to_ping != NULL)
        {
                fd_set read_fds;
@@ -1512,13 +1493,19 @@ int ping_send (pingobj_t *obj)
                if (obj->fd6  != -1 && FD_ISSET (obj->fd6, &read_fds))
                {
                        if (ping_receive_one (obj, &nowtime, AF_INET6) == 0)
+                       {
                                pings_in_flight--;
+                               pongs_received++;
+                       }
                        continue;
                }
                if (obj->fd4 != -1 && FD_ISSET (obj->fd4, &read_fds))
                {
                        if (ping_receive_one (obj, &nowtime, AF_INET) == 0)
+                       {
                                pings_in_flight--;
+                               pongs_received++;
+                       }
                        continue;
                }
 
@@ -1533,13 +1520,15 @@ int ping_send (pingobj_t *obj)
                        if (ping_send_one (obj, host_to_ping, write_fd) == 0)
                                pings_in_flight++;
                        else
-                               ret--;
+                               error_count++;
                        host_to_ping = host_to_ping->next;
                        continue;
                }
        } /* while (1) */
 
-       return (ret);
+       if (error_count)
+               return (-1 * error_count);
+       return (pongs_received);
 } /* int ping_send */
 
 static pinghost_t *ping_host_search (pinghost_t *ph, const char *host)
@@ -1789,6 +1778,20 @@ pingobj_iter_t *ping_iterator_next (pingobj_iter_t *iter)
        return ((pingobj_iter_t *) iter->next);
 }
 
+int ping_iterator_count (pingobj_t *obj)
+{
+       if (obj == NULL)
+               return 0;
+
+       int count = 0;
+       pingobj_iter_t *iter = obj->head;
+       while (iter) {
+               count++;
+               iter = iter->next;
+       }
+       return count;
+}
+
 int ping_iterator_get_info (pingobj_iter_t *iter, int info,
                void *buffer, size_t *buffer_len)
 {