From bf489daffc4902db3a9eb95d485fd867ac1ea524 Mon Sep 17 00:00:00 2001 From: Nate Straz Date: Tue, 13 Sep 2005 16:01:28 +0000 Subject: Flatten the qarsh tree. --- btime.c | 111 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 btime.c (limited to 'btime.c') diff --git a/btime.c b/btime.c new file mode 100644 index 0000000..f22c08b --- /dev/null +++ b/btime.c @@ -0,0 +1,111 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "btime_int.h" + +/* + * btime -- + * + * Return the boot time of a remote host if that host is running the + * btimed deamon. + * + * Returns: + * btime, or 0 on failure. + */ + +unsigned int +btime(const char *host) +{ + int sd; + char msg[BTIME_MSGLEN]; + struct sockaddr_in serv_addr; + struct sockaddr_in my_addr; + int serv_addr_len; + struct hostent *hostent; + in_addr_t inaddr; + unsigned int btime; + ssize_t nbytes; + int retry; + + if ((sd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + fprintf(stderr, "Could not create socket: %s\n", + strerror(errno)); + return 0; + } + + memset(&serv_addr, 0, sizeof serv_addr); + serv_addr.sin_family = AF_INET; + serv_addr.sin_port = htons(BTIME_PORT); + + if ((inaddr = inet_addr(host)) != INADDR_NONE) { + memcpy(&serv_addr.sin_addr, &inaddr, sizeof inaddr); + } else { + if ((hostent = gethostbyname(host)) == NULL) { + return 0; + } + + memcpy(&serv_addr.sin_addr, hostent->h_addr, hostent->h_length); + } + + memset(&my_addr, 0, sizeof my_addr); + my_addr.sin_family = AF_INET; + my_addr.sin_addr.s_addr = htonl(INADDR_ANY); + my_addr.sin_port = htons(0); + if (bind(sd, (struct sockaddr *)&my_addr, sizeof my_addr) < 0) { + fprintf(stderr, "Could not bind to local address: %s\n", + strerror(errno)); + return 0; + } + + memset(msg, 0, BTIME_MSGLEN); + for (retry = 0; retry < MAX_RETRY; retry++) { + serv_addr_len = sizeof serv_addr; + if ((nbytes = sendto(sd, &msg, BTIME_MSGLEN, MSG_DONTWAIT, + (struct sockaddr *)&serv_addr, serv_addr_len)) < 0) { + if (errno == EAGAIN) { + usleep(retry * 100); + } else { + /* Non EAGAIN error... */ + break; + } + } else { + break; + } + } + + + memset(msg, 0, BTIME_MSGLEN); + for (retry = 0; retry < MAX_RETRY; retry++) { + serv_addr_len = sizeof serv_addr; + if ((nbytes = recvfrom(sd, &msg, BTIME_MSGLEN, MSG_DONTWAIT, + (struct sockaddr *)&serv_addr, &serv_addr_len)) < 0) { + if (errno == EAGAIN) { + usleep(retry * 100); + } else { + /* Non EAGAIN error... */ + break; + } + } else { + break; + } + } + + if (nbytes == 0) { + btime = 0; + } else { + btime = strtoul(msg, (char **)NULL, 10); + } + + close(sd); + + return btime; +} -- cgit