#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "btime_int.h" static unsigned int get_btime(void); int main(int argc, char **argv) { int sd; char inmsg[BTIME_MSGLEN]; char btimeonly[BTIME_MSGLEN]; char cookiemsg[BTIME_MSGLEN]; char *outmsg; struct sockaddr_in cli_addr; socklen_t cli_addr_len; ssize_t nbytes; unsigned int local_btime; openlog("btimed", LOG_PID, LOG_USER); /* Running out of (x)inetd the socket was duped onto stdin. */ sd = fileno(stdin); /* We want to exit after 30 seconds of inactivity */ alarm(30); /* Generate the standard btime message */ memset(btimeonly, 0, BTIME_MSGLEN); local_btime = get_btime(); sprintf(btimeonly, "%u\n", local_btime); syslog(LOG_INFO, "started with btime = %u", local_btime); for (;;) { memset(&cli_addr, 0, sizeof cli_addr); memset(inmsg, 0, BTIME_MSGLEN); cli_addr_len = sizeof cli_addr; nbytes = recvfrom(sd, &inmsg, BTIME_MSGLEN, MSG_WAITALL, (struct sockaddr *)&cli_addr, &cli_addr_len); if (nbytes < 0) { /* Bail, we may have had an alarm(), or other error. * client side resends request, no need to retry here. */ syslog(LOG_INFO, "exitting"); exit(0); } if (inmsg[0] == 'B' && inmsg[1] == 'T' ) { /* New style heartbeat with cookie */ /* Copy cookie to message and append timestamp */ memset(cookiemsg, 0, BTIME_MSGLEN); memcpy(cookiemsg, inmsg, COOKIE_LEN); strcpy(cookiemsg + COOKIE_LEN, btimeonly); outmsg = cookiemsg; } else { outmsg = btimeonly; } sendto(sd, outmsg, BTIME_MSGLEN, MSG_DONTWAIT, (struct sockaddr *)&cli_addr, cli_addr_len); /* We want to exit after 30 seconds of inactivity */ alarm(30); } return 0; } /* *--------------------------------------------------------------------------- * * get_btime -- * * Return machine's boot time. * * Returns: * 0 on failure * non-zero on success. * *--------------------------------------------------------------------------- */ static unsigned int get_btime(void) { FILE *statf; char line[1024]; unsigned int btime = 0; if ((statf = fopen("/proc/stat", "r")) == NULL) { syslog(LOG_ERR, "/proc/stat open failure: %s\n", strerror(errno)); exit(1); } while (fgets(line, 1024, statf) != NULL) { if (strstr(line, "btime") != NULL) { sscanf(line, "%*s%u", &btime); } } fclose(statf); return btime; }