void SocketIO::Connect() { SET_SEGV_LOCATION(); struct addrinfo *servinfo; int rv = 0; if((rv = getaddrinfo(this->ip.c_str(), this->port.c_str(), NULL, &servinfo)) != 0) throw SocketException(printfify("Could not resolve server (%s:%u): %s", this->ip.c_str(), this->port.c_str(), gai_strerror(rv))); int c = connect(this->GetFD(), servinfo->ai_addr, servinfo->ai_addrlen); if( c == -1) { if(errno != EINPROGRESS) throw SocketException(printfify("Cannot connect to %s: %s", this->ip.c_str(), strerror(errno))); else { FD_SET(this->GetFD(), &WriteFD); } } else { // put OnConnect stuff here? Log(LOG_DEBUG) << "Connected to " << this->server << ":" << this->port << ' ' << '(' << this->ip << ')'; } freeaddrinfo(servinfo); //Clear up used memory we don't need anymore }
/** * \fn void ModuleHandler::SanitizeRuntime() * \brief Deletes all files in the runtime directory. */ void ModuleHandler::SanitizeRuntime() { Log(LOG_DEBUG) << "Cleaning up runtime directory."; Flux::string dirbuf = binary_dir + "/runtime/"; if(!TextFile::IsDirectory(dirbuf)) { #ifndef _WIN32 if(mkdir(dirbuf.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) != 0) throw CoreException(printfify("Error making new runtime directory: %s", strerror(errno))); #else if(!CreateDirectory(dirbuf.c_str(), NULL)) throw CoreException(printfify("Error making runtime new directory: %s", strerror(errno))); #endif } else { Flux::vector files = TextFile::DirectoryListing(dirbuf); for(Flux::vector::iterator it = files.begin(); it != files.end(); ++it) Delete(Flux::string(dirbuf + (*it)).c_str()); } }
/** The equivalent of inet_pton * @param type AF_INET or AF_INET6 * @param address The address to place in the sockaddr structures * @param pport An option port to include in the sockaddr structures * @throws A socket exception if given invalid IPs */ void sockaddrs::pton(int type, const Flux::string &address, int pport) { switch (type) { case AF_INET: int i = inet_pton(type, address.c_str(), &sa4.sin_addr); if (i == 0) throw SocketException("Invalid host"); else if (i <= -1) throw SocketException(printfify("Invalid host: %s", strerror(errno))); sa4.sin_family = type; sa4.sin_port = htons(pport); return; case AF_INET6: int i = inet_pton(type, address.c_str(), &sa6.sin6_addr); if (i == 0) throw SocketException("Invalid host"); else if (i <= -1) throw SocketException(printfify("Invalid host: %s", strerror(errno))); sa6.sin6_family = type; sa6.sin6_port = htons(pport); return; default: break; } throw CoreException("Invalid socket type"); }
Flux::string do_strftime(const time_t &t, bool short_output) { tm tm = *localtime(&t); char buf[BUFSIZE]; strftime(buf, sizeof(buf), "%b %d %H:%M:%S %Y %Z", &tm); if (short_output) return buf; if (t < time(NULL)) return Flux::string(buf) + " " + printfify("(%s ago)", duration(time(NULL) - t).c_str()); else return Flux::string(buf) + " " + printfify("(%s from now)", duration(t - time(NULL)).c_str()); }
void Run(CommandSource &source, const std::vector<Flux::string> ¶ms) { User *u = source.u; source.Reply("Quitting.."); Log(u) << "quit the bot from network: \"" << source.n->name << "\""; source.n->Disconnect(printfify("Requested From \2%s\17.", u->nick.c_str())); }
Flux::string Clock::PST() { int h = (ptm->tm_hour) - isdst ? 6 : 7; Log(LOG_TERMINAL) << "IS DST: " << std::boolalpha << isdst << " " << ptm->tm_isdst; CorrectHour(h); return printfify("%02d:%02d:%02d", h, ptm->tm_min, ptm->tm_sec); }
/** Constructor * @param bindip The IP to bind to * @param port The port to listen on * @param ipv6 true for ipv6 */ ListenSocket::ListenSocket(const Flux::string &bindip, int port, bool ipv6) : Socket(-1, ipv6) { this->SetNonBlocking(); const char op = 1; setsockopt(this->GetFD(), SOL_SOCKET, SO_REUSEADDR, &op, sizeof(op)); this->bindaddr.pton(IPv6 ? AF_INET6 : AF_INET, bindip, port); this->IO->Bind(this, bindip, port); if (listen(Sock, SOMAXCONN) == -1) throw SocketException(printfify("Unable to listen: %s", strerror(errno))); }
/** Accept a connection from a socket * @param s The socket * @return The new client socket */ ClientSocket *SocketIO::Accept(ListenSocket *s) { sockaddrs conaddr; socklen_t size = sizeof(conaddr); int newsock = accept(s->GetFD(), &conaddr.sa, &size); if (newsock >= 0) { ClientSocket *ns = s->OnAccept(newsock, conaddr); ns->SetStatus(SF_ACCEPTED, true); ns->OnAccept(); return ns; } else throw SocketException(printfify("Unable to accept connection: %s", strerror(errno))); }
int uname(struct utsname *info) { // get the system information. OSVERSIONINFOEX wininfo; SYSTEM_INFO si; Flux::string WindowsVer = GetWindowsVersion(); Flux::string cputype; char hostname[256] = "\0"; ZeroMemory(&wininfo, sizeof(OSVERSIONINFOEX)); ZeroMemory(&si, sizeof(SYSTEM_INFO)); wininfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if(!GetVersionEx(reinterpret_cast<OSVERSIONINFO *>(&wininfo))) return -1; GetSystemInfo(&si); // Get the hostname if(gethostname(hostname, sizeof(hostname)) == SOCKET_ERROR) return -1; if(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) cputype = "64-bit"; else if(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_INTEL) cputype = "32-bit"; else if(si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) cputype = "Itanium 64-bit"; // Fill the utsname struct with the windows system info strcpy(info->sysname, "Windows"); strcpy(info->nodename, hostname); strcpy(info->release, WindowsVer.c_str()); strcpy(info->version, printfify("%ld.%ld-%ld", wininfo.dwMajorVersion, wininfo.dwMinorVersion, wininfo.dwBuildNumber).c_str()); strcpy(info->machine, cputype.c_str()); // Null-Terminate info->nodename[strlen(info->nodename) - 1] = '\0'; info->sysname[strlen(info->sysname) - 1] = '\0'; info->release[strlen(info->sysname) - 1] = '\0'; info->version[strlen(info->version) - 1] = '\0'; info->machine[strlen(info->machine) - 1] = '\0'; }
Flux::string Clock::AUS() { int h = (ptm->tm_hour) + isdst ? 11 : 12; CorrectHour(h); return printfify("%02d:%02d:%02d", h, ptm->tm_min, ptm->tm_sec); }
Flux::string Clock::CCT() { int h = (ptm->tm_hour) + 15; CorrectHour(h); return printfify("%02d:%02d:%02d", h, ptm->tm_min, ptm->tm_sec); }
Flux::string Clock::EST() { int h = (ptm->tm_hour) - isdst ? 9 : 10; CorrectHour(h); return printfify("%02d:%02d:%02d", h, ptm->tm_min, ptm->tm_sec); }
Flux::string Clock::MST() { int h = ptm->tm_hour - isdst ? 6 : 7; CorrectHour(h); return printfify("%02d:%02d:%02d", h, ptm->tm_min, ptm->tm_sec); }
Flux::string Clock::CustomOffset(int i) { int h = (ptm->tm_hour + i); CorrectHour(h); return printfify("%02d:%02d:%02d", h, ptm->tm_min, ptm->tm_sec); }
void SocketIO::Process() { SET_SEGV_LOCATION(); timeval timeout; timeout.tv_sec = Config->SockWait; timeout.tv_usec = 0; //this timeout keeps the bot from being a CPU hog for no reason :) fd_set read = ReadFD, write = WriteFD, except = ExceptFD; FD_ZERO(&read); FD_SET(this->GetFD(), &read); int sres = select(this->GetFD() + 1, &read, &write, &except, &timeout); if(sres == -1 && errno != EINTR) { Log(LOG_DEBUG) << "Select() error: " << strerror(errno); return; } if(throwex) //throw a socket exception if we want to. mainly used for ping timeouts. throw SocketException(throwmsg); bool has_read = FD_ISSET(this->GetFD(), &read); bool has_write = FD_ISSET(this->GetFD(), &write); bool has_error = FD_ISSET(this->GetFD(), &except); if(has_error) { int optval = 0; socklen_t optlen = sizeof(optval); getsockopt(this->GetFD(), SOL_SOCKET, SO_ERROR, reinterpret_cast<char *>(&optval), &optlen); errno = optval; FOREACH_MOD(I_OnSocketError, OnSocketError(optval ? strerror(errno) : "Unknown socket error")); throw SocketException("Socket error"); } if(has_read) { char tbuf[BUFSIZE + 1] = "\0"; size_t i = recv(this->GetFD(), tbuf, BUFSIZE, 0); if(i <= 0) throw SocketException(printfify("Socket Error: %s", strerror(errno))); sepstream sep(tbuf, '\n'); Flux::string buf; while(sep.GetToken(buf)) { this->LastBuf.clear(); this->LastBuf = buf; if(!this->Read(buf)) throw SocketException("Error reading socket"); } FD_CLR(this->GetFD(), &ReadFD); } if(has_write) { Flux::string buf; while(!this->WriteBuffer.empty()) { buf = this->WriteBuffer.front(); this->WriteBuffer.pop(); int i = ::send(this->GetFD(), buf.c_str(), buf.size(), MSG_NOSIGNAL); if(i <= -1 && !quitting) throw SocketException(printfify("Error writing \"%s\" to socket: %s", buf.c_str(), strerror(errno))); Log(LOG_RAWIO) << "Sent: " << buf << " | " << buf.size() << " bytes"; this->LastBuf.clear(); this->LastBuf = buf; buf.clear(); } FD_CLR(this->GetFD(), &WriteFD); } }
/** Bind a socket * @param s The socket * @param ip The IP to bind to * @param port The optional port to bind to */ void SocketIO::Bind(Socket *s, const Flux::string &ip, int port) { s->bindaddr.pton(s->IsIPv6() ? AF_INET6 : AF_INET, ip, port); if (bind(s->GetFD(), &s->bindaddr.sa, s->bindaddr.size()) == -1) throw SocketException(printfify("Unable to bind to address: %s", strerror(errno))); }