1 --- src/loop.c.orig 2019-01-02 14:28:47.000000000 +0000
2 +++ src/loop.c 2020-11-07 20:49:06.982768448 +0000
4 #include <sys/resource.h>
7 +#include <sys/types.h>
8 +#include <sys/socket.h>
11 #if !defined(WCOREDUMP)
12 # define WCOREDUMP(x) 0
14 u_int ctimeout, utest;
16 struct child *children;
18 + struct pollfd *pfd, *sfd;
19 + struct sockaddr_in *addr;
20 + int ntarget = target_getmax();
21 struct sigaction sa, saved_sa;
26 memset((void *) children, 0, (max+1)*sizeof(struct child));
28 + sfd = (struct pollfd *) malloc(ntarget * sizeof(struct pollfd));
31 + perror("malloc failed");
36 + memset((void *) sfd, 0, ntarget * sizeof(struct pollfd));
38 + while (idx < ntarget)
41 + addr = (struct sockaddr_in *)malloc(ntarget * sizeof(struct sockaddr_in));
44 + perror("malloc failed");
50 + memset((void *) addr, 0, ntarget * sizeof(struct sockaddr_in));
52 /* Setup SIGINT handler */
53 sigemptyset(&sa.sa_mask);
56 /* Run fping if requested */
62 - cargv[0] = "fping"; cargv[1] = "-t"; cargv[2] = ping; cargv[3] = NULL;
63 - children[0].pid = exec(&(pfd[0].fd), &(pfd[1].fd), &(pfd[2].fd),
65 - if (children[0].pid == -1)
66 - /* Error message was given by exec() */
67 - spawn_mode = SPAWN_FATAL;
70 - init_child(&(children[0]));
71 + int ret, flags, setfl, ndone = 0;
73 + struct in_addr *haddr;
75 + while (target_next(1) == 0) {
77 + if ((sfd[idx].fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
78 + eprint("Ping(create socket) failed for %s: %s", target_getname(), strerror(errno));
82 + sfd[idx].events = POLLIN;
84 - pfd[1].events = POLLIN;
85 - pfd[2].events = POLLIN;
86 + if ((flags = fcntl(sfd[idx].fd, F_GETFL, 0)) == -1) {
87 + eprint("Ping(get status flag) failed for %s: %s", target_getname(), strerror(errno));
93 + if ((setfl = fcntl(sfd[idx].fd, F_SETFL, flags | O_NONBLOCK)) == -1) {
94 + eprint("Ping(set status flag) failed for %s: %s", target_getname(), strerror(errno));
101 - while (target_next(1) == 0)
104 + if ((hp = gethostbyname(target_getname())) == NULL) {
105 + eprint("Ping(get host entry) failed for %s: %s", target_getname(), strerror(errno));
106 + close(sfd[idx].fd);
111 + haddr = (struct in_addr *)*hp->h_addr_list;
112 + addr[idx].sin_family = AF_INET;
113 + addr[idx].sin_addr = *haddr;
114 + addr[idx].sin_port = htons((short)80);
115 + bzero(&(addr[idx].sin_zero), 8);
119 - tname = strchr(target_getname(), '@');
121 - tname = target_getname();
124 - write(pfd[0].fd, tname, strlen(tname));
125 - write(pfd[0].fd, "\n", 1);
127 - close(pfd[0].fd); pfd[0].fd = -1;
128 - iprint("Pinging %u targets...", count);
129 - dprint("fping pid = %d (idx=0) %d/%d/%d",
130 - children[0].pid, pfd[0].fd, pfd[1].fd, pfd[2].fd);
133 + ret = connect(sfd[idx].fd, (struct sockaddr *)&addr[idx], sizeof(struct sockaddr));
134 + if (ret == 0) { //this case may happen on localhost
136 + close(sfd[idx].fd);
143 + time_t t1 = time(NULL);
144 + while (time(NULL) - t1 < atoi(ping) && ndone != ntarget) {
145 + ret = poll(sfd, ntarget, 1000);
146 + if (ret == -1 && errno != EINTR) {
147 + eprint("poll failed: %s", strerror(errno));
149 + } else if (ret > 0) {
150 + for (idx = 0; idx < ntarget; idx++) {
151 + if (sfd[idx].revents > 0) {
152 + target_setbynum(idx);
154 + close(sfd[idx].fd);
158 + if (ndone == ntarget) {
165 + if (ndone < ntarget) {
166 + dprint("ping is done or timed out");
167 + while (target_pong(NULL) == 0) {
168 + idx = target_getnum();
169 + if (sfd[idx].fd > 0) {
170 + eprint("Ping timed out for %s", target_getname());
172 + close(sfd[idx].fd);
175 + eprint("%s assumed to be alive (missing from ping results)", target_getname());
185 /* No fping, let's move on to the next phase then */