/* EnergyMech, IRC bot software Copyright (c) 1997-2018 proton This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ #define UPTIME_C #include "config.h" #ifdef UPTIME #include "defines.h" #include "structs.h" #include "global.h" #include "h.h" #include "text.h" #include "mcmd.h" /* * Uptime stuffies */ typedef struct { int regnr; int pid; int type; uint32_t packets_sent; uint32_t uptime; uint32_t ontime; uint32_t mytime; uint32_t sysup; } PackStub; typedef struct { int regnr; int pid; int type; uint32_t packets_sent; uint32_t uptime; uint32_t ontime; uint32_t mytime; uint32_t sysup; char string[512]; } PackUp; void init_uptime(void) { struct sockaddr_in sai; uptimepackets = 0; if (!uptimehost) { set_mallocdoer(init_uptime); uptimehost = stringdup(defaultuptimehost); } if ((uptimesock = socket(AF_INET,SOCK_DGRAM,0)) < 0) { uptimesock = -1; return; } memset(&sai,0,sizeof(sai)); sai.sin_family = AF_INET; sai.sin_addr.s_addr = INADDR_ANY; if (bind(uptimesock,(struct sockaddr*)&sai,sizeof(sai)) < 0) { close(uptimesock); uptimesock = -1; return; } SockFlags(uptimesock); } void send_uptime(int type) { PackUp *upPack; struct sockaddr_in sai; Server *sp; const char *server,*nick; int sz; if (uptimehost == NULL || uptimeport == 0) return; #ifdef RAWDNS if (uptimeip == -1 && uptimehost) { char *host; uptimelast = now + 10; if ((host = poll_rawdns(uptimehost))) { if ((uptimeip = inet_addr(host)) != -1) { Free((char**)&uptimehost); set_mallocdoer(send_uptime); uptimehost = stringdup(host); } } else { if (type < UPTIME_GENERICDEATH) rawdns(uptimehost); return; } } #endif /* RAWDNS */ upPack = (PackUp*)&globaldata; /* * update the time when we last sent packet */ sz = (uptimelast + 1) & 7; uptimelast = (now & ~7) + 21600 + sz; /* 21600 seconds = 6 hours */ uptimepackets = uptimepackets + 1; upPack->packets_sent = htonl(uptimepackets); upPack->mytime = htonl(now); upPack->regnr = uptimeregnr; upPack->type = htonl(type); upPack->uptime = htonl(uptime); upPack->ontime = 0; /* set a few lines down */ /* * callouts to other functions should be done last (think compiler optimizations) */ upPack->pid = htonl(getpid()); upPack->sysup = htonl(cx.system_uptime); server = UNKNOWN; nick = BOTLOGIN; /* * set bot related stuff from the first bot in the list */ if (botlist) { nick = getbotnick(botlist); upPack->ontime = htonl(botlist->ontime); if ((sp = find_server(botlist->server))) { server = (*sp->realname) ? sp->realname : sp->name; } } if (uptimenick) { nick = uptimenick; } #ifndef RAWDNS if ((uptimeip == -1) || ((uptimelast & 7) == 0)) { uptimeip = get_ip(uptimehost); if (uptimeip == -1) return; } #endif /* ! RAWDNS */ sz = sizeof(PackStub) + snprintf(upPack->string,256,"%s %s %s",nick,server,VERSION); #ifdef DEBUG debug("(send_uptime) packets sent %i, my pid %i, my ident = \"%s\"\n",uptimepackets,ntohl(upPack->pid),upPack->string); #endif /* DEBUG */ /* * udp sending... */ memset((char*)&sai,0,sizeof(sai)); sai.sin_family = AF_INET; sai.sin_addr.s_addr = uptimeip; sai.sin_port = htons(uptimeport); sendto(uptimesock,(void*)upPack,sz,0,(struct sockaddr*)&sai,sizeof(sai)); } void uptime_death(int type) { #ifdef DEBUG debug("(uptime_death) sending death message\n"); #endif /* DEBUG */ time(&now); uptimelast = 0; /* avoid resolving the hostname */ send_uptime(type); uptimeport = 0; /* avoid sending more packets */ } void process_uptime(void) { struct sockaddr_in sai; unsigned int sz; int res; struct { int regnr; uint32_t cookie; } regPack; if (uptimesock == -1) return; if (FD_ISSET(uptimesock,&read_fds)) { sz = sizeof(sai); res = recvfrom(uptimesock,(void*)®Pack,sizeof(regPack),0,(struct sockaddr*)&sai,&sz); if (res == sizeof(regPack)) { if (uptimepackets == ntohl(regPack.cookie)) { if (uptimeregnr == 0) uptimeregnr = ntohl(regPack.regnr); } } } if (uptimelast < now) { send_uptime(UPTIME_BOTTYPE); } } /* * * commands related to uptimes * */ void do_upsend(COMMAND_ARGS) { /* * on_msg checks: GAXS */ send_uptime(UPTIME_BOTTYPE); } #endif /* UPTIME */