/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * queryhandler.cc * * Tue May 6 14:50:56 CEST 2008 * Copyright 2008 Bent Bisballe Nyeng * deva@aasimon.org ****************************************************************************/ /* * This file is part of Pracro. * * Pracro 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. * * Pracro 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 Pracro; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include "queryhandler.h" #include // For time #include #include #include #include // For getpid #include #include // For time #include // For strerror and errno #include // For socket and friends #include #include #include #include // For ioctl #include #include "queryparser.h" typedef struct { in_addr_t ip; time_t time; pid_t pid; unsigned short int count; } UID; #define SIOCGIFCONF 0x8912 // get iface list static in_addr_t getIP(const char *interface) { in_addr_t ret = 0; int numreqs = 30, sd, n; struct ifconf ifc; struct ifreq *ifr; struct in_addr *ia; sd = socket(AF_INET, SOCK_STREAM, 0); if(sd == -1) { // throw Pentominos::UIDCouldNotConnectException(strerror(errno)); } ifc.ifc_buf = NULL; ifc.ifc_len = sizeof(struct ifreq) * numreqs; ifc.ifc_buf = (char*)malloc(ifc.ifc_len); if(ifc.ifc_buf == NULL) { // throw Pentominos::UIDOutOfMemoryException(); } if (ioctl(sd, SIOCGIFCONF, &ifc) < 0) { // throw Pentominos::UIDInterfaceListException(strerror(errno)); } ifr = ifc.ifc_req; for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq)) { ia = (struct in_addr *)((ifr->ifr_ifru.ifru_addr.sa_data)+2); if(!strcmp(ifr->ifr_ifrn.ifrn_name, interface)) { ret = *(in_addr_t*)ia; } ifr++; } if(!ret) { // Still no interface... We're fucked! // throw Pentominos::UIDInterfaceException(interface); } free(ifc.ifc_buf); return ret; } static unsigned short counter = 0; static unsigned short getCounter() { return counter++; } static UID uid = {0,0,0,0}; static std::string getUID(const char *interface) { if(!uid.ip) uid.ip = getIP(interface); time_t t = time(NULL); if(uid.time != t) counter = 0; // If time differes, reset the counter uid.time = t; // We need this value every time. if(!uid.pid) uid.pid = getpid(); uid.count = getCounter(); char buf[32]; sprintf(buf, "%08x%08x%04x%04x", uid.ip, (unsigned int)uid.time, uid.pid, uid.count); return std::string(buf); } QueryHandler::QueryHandler(TCPSocket *socket, std::string cpr) { this->cpr = cpr; this->socket = socket; } QueryResult QueryHandler::exec(Query &query) { time_t timestamp = time(NULL); std::string uid = getUID("eth0"); char buf[512]; char header[] = "\n" "\n"; #ifndef WITHOUT_PENTOMINOS socket->write(header, strlen(header)); #endif/*WITHOUT_PENTOMINOS*/ #ifdef WITH_DEBUG printf(header); #endif/*WITH_DEBUG*/ sprintf(buf, " \n", cpr.c_str(), #ifndef WITHOUT_PENTOMINOS socket->srcaddr().c_str(), socket->dstaddr().c_str(), #else "127.0.0.1", "127.0.0.1", #endif/*WITHOUT_PENTOMINOS*/ (unsigned int)timestamp, uid.c_str()); #ifndef WITHOUT_PENTOMINOS socket->write(buf, strlen(buf)); #endif/*WITHOUT_PENTOMINOS*/ #ifdef WITH_DEBUG printf(buf); #endif/*WITH_DEBUG*/ sprintf(buf, " \n", query.attributes["class"].c_str(), query.attributes["class"].c_str()); #ifndef WITHOUT_PENTOMINOS socket->write(buf, strlen(buf)); #endif/*WITHOUT_PENTOMINOS*/ #ifdef WITH_DEBUG printf(buf); #endif/*WITH_DEBUG*/ sprintf(buf, ""); #ifndef WITHOUT_PENTOMINOS socket->write(buf, strlen(buf)); #endif/*WITHOUT_PENTOMINOS*/ #ifdef WITH_DEBUG printf(buf); #endif/*WITH_DEBUG*/ QueryResult result; #ifndef WITHOUT_PENTOMINOS QueryParser parser; int asize; char abuf[64]; memset(abuf, 0, sizeof(abuf)); // Read until we've got the entire result. while((asize = socket->read(abuf, sizeof(abuf) - 1)) != -1 && parser.parse(abuf, asize) == false) { memset(abuf, 0, sizeof(abuf)); } result = parser.result; #endif/*WITHOUT_PENTOMINOS*/ return result; } #ifdef TEST_QUERYHANDLER int main() { TCPSocket s; s.connect("localhost", 11108); QueryHandler qh(&s, "2003791613"); Query q1; q1.attributes["device_id"] = "lensmeter"; q1.attributes["device_type"] = "lensmeter"; qh.addQuery(q1); std::string res = qh.exec(); printf("%s\n", res.c_str()); return 0; } #endif/*TEST_QUERYHANDLER*/