summaryrefslogtreecommitdiffstats
path: root/btime/btime.c
diff options
context:
space:
mode:
authorNate Straz <nstraz@redhat.com>2005-09-13 15:48:30 +0000
committerNathan Straz <nstraz@redhat.com>2008-09-23 09:37:44 -0400
commitc38e0fba0a10d5af0bb25f674177cb6404f73991 (patch)
tree9e77bcfd7b48187972a951f9cd1a08351d7f01bf /btime/btime.c
parent89f8670f4e60cfafbb153bef681b6ada593ea626 (diff)
downloadqarsh-c38e0fba0a10d5af0bb25f674177cb6404f73991.tar.gz
qarsh-c38e0fba0a10d5af0bb25f674177cb6404f73991.tar.xz
qarsh-c38e0fba0a10d5af0bb25f674177cb6404f73991.zip
Copy btime and qarsh over from sistina-test tree
Diffstat (limited to 'btime/btime.c')
-rw-r--r--btime/btime.c111
1 files changed, 111 insertions, 0 deletions
diff --git a/btime/btime.c b/btime/btime.c
new file mode 100644
index 0000000..f22c08b
--- /dev/null
+++ b/btime/btime.c
@@ -0,0 +1,111 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <netdb.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#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;
+}