/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /*************************************************************************** * queryhandlerpentominos.cc * * Thu Jan 15 11:35:31 CET 2009 * Copyright 2009 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 "queryhandlerpentominos.h" #include "debug.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); } QueryHandlerPentominos::QueryHandlerPentominos(TCPSocket *socket, std::string cpr) : QueryHandler() { this->cpr = cpr; this->socket = socket; } QueryResult QueryHandlerPentominos::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*/ PRACRO_DEBUG(queryhandler, header); sprintf(buf, " \n", cpr.c_str(), "pracro", #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*/ PRACRO_DEBUG(queryhandler, buf); sprintf(buf, " \n", query.attributes["class"].c_str(), query.attributes["class"].c_str()); #ifndef WITHOUT_PENTOMINOS socket->write(buf, strlen(buf)); #endif/*WITHOUT_PENTOMINOS*/ PRACRO_DEBUG(queryhandler, buf); sprintf(buf, ""); #ifndef WITHOUT_PENTOMINOS socket->write(buf, strlen(buf)); #endif/*WITHOUT_PENTOMINOS*/ PRACRO_DEBUG(queryhandler, buf); QueryResult result; #ifndef WITHOUT_PENTOMINOS QueryParser parser; ssize_t size; // Read until we've got the entire result. while((size = socket->read(buf, sizeof(buf))) > 0) { // fwrite(buf, size, 1, stdout); fflush(stdout); if(parser.parse(buf, size)) break; } result = parser.result; #endif/*WITHOUT_PENTOMINOS*/ PRACRO_INFO(queryhandler, "Done handling query\n"); result.print(); return result; } #ifdef TEST_QUERYHANDLERPENTOMINOS int main() { TCPSocket s; try { s.connect("localhost", 11108); } catch(Exception &e) { printf("ERROR: %s\n", e.what()); printf("A running instance of the artefact server in needed on localhost, port 11108 in order for this test to run.\n"); return 1; } QueryHandlerPentominos qh(&s, "2003791613"); Query q1; q1.attributes["device_id"] = "lensmeter"; q1.attributes["device_type"] = "lensmeter"; QueryResult res = qh.exec(q1); res.print(); return 0; } #endif/*TEST_QUERYHANDLERPENTOMINOS*/