/** * Create a log message for a received/sent raw data byte. * @param byte the raw data byte. * @param received true if the byte was received, false if it was sent. */ static void logRawData(const unsigned char byte, bool received) { if (received) logNotice(lf_bus, "<%02x", byte); else logNotice(lf_bus, ">%02x", byte); }
/** * Main method. * * @param argc the number of command line arguments. * @param argv the command line arguments. */ int main(int argc, char* argv[]) { struct argp argp = { argpoptions, parse_opt, NULL, argpdoc, NULL, NULL, NULL }; setenv("ARGP_HELP_FMT", "no-dup-args-note", 0); if (argp_parse(&argp, argc, argv, ARGP_IN_ORDER, NULL, &opt) != 0) return EINVAL; s_messageMap = new MessageMap(opt.checkConfig && opt.scanConfig); if (opt.checkConfig) { logNotice(lf_main, "Performing configuration check..."); result_t result = loadConfigFiles(s_messageMap, true); if (result == RESULT_OK && opt.checkConfig > 1) { logNotice(lf_main, "Configuration dump:"); s_messageMap->dump(cout); } delete s_messageMap; s_messageMap = NULL; globalTemplates.clear(); return 0; } // open the device Device *device = Device::create(opt.device, !opt.noDeviceCheck, opt.readonly, &logRawData); if (device == NULL) { logError(lf_main, "unable to create device %s", opt.device); return EINVAL; } if (!opt.foreground) { setLogFile(opt.logFile); daemonize(); // make me daemon } // trap signals that we expect to receive signal(SIGHUP, signalHandler); signal(SIGINT, signalHandler); signal(SIGTERM, signalHandler); logNotice(lf_main, PACKAGE_STRING "." REVISION " started"); // load configuration files loadConfigFiles(s_messageMap); if (s_messageMap->sizeConditions()>0 && opt.pollInterval==0) logError(lf_main, "conditions require a poll interval > 0"); // create the MainLoop and run it s_mainLoop = new MainLoop(opt, device, s_messageMap); s_mainLoop->start("mainloop"); s_mainLoop->join(); // shutdown shutdown(); }
static void listener_clientAccept(void *subject, const char *event, void *data, va_list args) { Socket *listener = subject; Socket *client = va_arg(args, Socket *); if(listener == server) { // new IRC proxy client enableSocketPolling(client); // also poll the new socket logNotice("New relay client %d on IRC proxy server", client->fd); IrcProxyClient *pc = ALLOCATE_OBJECT(IrcProxyClient); pc->proxy = NULL; pc->socket = client; pc->authenticated = false; pc->ibuffer = g_string_new(""); attachEventListener(pc, "line", NULL, &listener_clientLine); attachEventListener(client, "read", NULL, &listener_clientRead); attachEventListener(client, "disconnect", NULL, &listener_clientDisconnect); g_hash_table_insert(clients, client, pc); // connect the client socket to the proxy client object proxyClientIrcSend(pc, ":kalisko.proxy NOTICE AUTH :*** Welcome to the Kalisko IRC proxy server! Please use the %cPASS [id]:[password]%c command to authenticate...", (char) 2, (char) 2); } }
result_t loadConfigFiles(MessageMap* messages, bool verbose) { logInfo(lf_main, "loading configuration files from %s", opt.configPath); messages->clear(); globalTemplates.clear(); for (map<string, DataFieldTemplates*>::iterator it = templatesByPath.begin(); it != templatesByPath.end(); it++) { delete it->second; it->second = NULL; } templatesByPath.clear(); result_t result = readConfigFiles(string(opt.configPath), ".csv", messages, !opt.scanConfig || opt.checkConfig, verbose); if (result == RESULT_OK) logInfo(lf_main, "read config files"); else logError(lf_main, "error reading config files: %s, %s", getResultCode(result), messages->getLastError().c_str()); result = messages->resolveConditions(verbose); if (result != RESULT_OK) logError(lf_main, "error resolving conditions: %s, %s", getResultCode(result), messages->getLastError().c_str()); logNotice(lf_main, "found messages: %d (%d conditional on %d conditions, %d poll, %d update)", messages->size(), messages->sizeConditional(), messages->sizeConditions(), messages->sizePoll(), messages->sizePassive()); return result; }
/** * Helper method performing shutdown. */ void shutdown() { // stop main loop and all dependent components if (s_mainLoop != NULL) { delete s_mainLoop; s_mainLoop = NULL; } if (s_messageMap!=NULL) { delete s_messageMap; s_messageMap = NULL; } // free templates for (map<string, DataFieldTemplates*>::iterator it = templatesByPath.begin(); it != templatesByPath.end(); it++) { delete it->second; } templatesByPath.clear(); // reset all signal handlers to default signal(SIGHUP, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGTERM, SIG_DFL); // delete daemon pid file if necessary closePidFile(); logNotice(lf_main, "ebusd stopped"); closeLogFile(); exit(EXIT_SUCCESS); }
void RenderContext::create() { if(s_primedContext || s_creationLock) { logThrowGL("[RenderContext] You cannot create a RenderContext while " "another is primed or being created!"); } s_creationLock = true; // context needs to be current to call glewInit makeCurrent(); // glewExperimental to use context versions above 3.2 // TODO: call glewInit just once (???) glewExperimental = GL_TRUE; GLenum status = glewInit(); // check for errors if(status != GLEW_OK) { logThrowGL("[RenderContext] glewInit() failed with status <", status, ">!"); } // check for GL error (glew often causes one when using new context versions) auto err = glGetError(); if(err != GL_NO_ERROR) { logNotice("[RenderContext] glewInit() caused an openGL error <", translateGLError(err), ">."); } // configure context configure(); // reset state resetCurrent(); s_creationLock = false; m_wasCreated = true; }
/** * The signal handling function. * @param sig the received signal. */ void signalHandler(int sig) { switch (sig) { case SIGHUP: logNotice(lf_main, "SIGHUP received"); break; case SIGINT: logNotice(lf_main, "SIGINT received"); shutdown(); break; case SIGTERM: logNotice(lf_main, "SIGTERM received"); shutdown(); break; default: logNotice(lf_main, "undefined signal %s", strsignal(sig)); break; } }
/* * brief: 获取客户端连接 * 成功返回描述符, 失败打印日志, 返回错误 */ int Cabinet::getConnectFd(int listenFd, string &strIP, int &port) { //logDebug("server get client connect"); int connectFd; if ((connectFd = Util::acceptTcp(listenFd, strIP, port)) == CABINET_ERR) { logWarning("accept connect error"); return CABINET_ERR; } logNotice("receive client connect, client_ip[%s], client_port[%d]", strIP.c_str(), port); return connectFd; }
DB DatabasePool::get() { logDebug("DatabasePool::getConnection(): Get database connection.."); while (true) { logDebug("DatabasePool::getConnection(): lock mutex.."); QMutexLocker mutexLocker(&_getDatabaseConnectionMutex); logDebug("DatabasePool::getConnection(): mutex locked successful.."); // Überprüfen, ob diesem Thread bereits eine Datenbankverbindung hat, wenn ja, dann die selbe wieder zurückgeben: if (_freedDatabaseConnections.contains(QThread::currentThreadId())) { logDebug("DatabasePool::getConnection(): Thread already have a database connection, returns the same..."); return _getThreadConnection(); } try { logDebug("DatabasePool::getConnection(): Free connections in pool: %1", QString::number(_pool.size())); if (_pool.size() > 0) { // Verfügbare Verbindung aus dem Pool holen: logDebug("DatabasePool::getConnection(): Return the next free connection from the pool."); return _getNextConnection(); } // Da keine Verbindung verfügbar, überprüfen, ob das maximale Limit an Verbindungen erreicht wurde? if (_maxConnections > _countConnections) { logNotice("DatabasePool::getConnection(): No db connection available, max %1, created %2, create a new...", QString::number(_maxConnections), QString::number(_countConnections)); _createPoolConnection(); return _getNextConnection(); } logError("DatabasePool::getConnection(): No connection available (max %1, created %2), sleep 50ms..", QString::number(_maxConnections), QString::number(_countConnections)); } catch (SqlException *e) { /** * @TODO: Defekte Datenbankverbindungen filtern??? */ throw e; } // Wenn keine Datenbankverbindung zurückgegeben werden konnte, so Mutex entsperren und 50ms schlafen... mutexLocker.unlock(); usleep(50); } }
void handle_sigint(int sig) { if (sig == SIGINT) { logNotice("Received SIGINT\n\n"); } else if (sig == SIGTERM) { logNotice("Received SIGTERM\n\n"); } else { return; } #ifdef MY_RF24_IRQ_PIN detachInterrupt(MY_RF24_IRQ_PIN); #endif #if defined(MY_GATEWAY_SERIAL) MY_SERIALDEVICE.end(); #endif logClose(); exit(EXIT_SUCCESS); }
TEST_SUITE_END TEST(lexer) { int n = sizeof(lexer_test_solution_tokens) / sizeof(lexer_test_solution_tokens[0]); GPtrArray *results = lexStoreString(lexer_test_input); char *resultsDump = dumpLexResults(results); logNotice("lexer test case dump: %s", resultsDump); free(resultsDump); TEST_ASSERT(results->len == n); for(int i = 0; i < n; i++) { StoreLexResult *result = (StoreLexResult *) results->pdata[i]; TEST_ASSERT(result->token == lexer_test_solution_tokens[i]); switch(result->token) { case STORE_TOKEN_STRING: logNotice("testing string: %s vs %s", result->value.string, lexer_test_solution_values[i].string); TEST_ASSERT(g_strcmp0(result->value.string, lexer_test_solution_values[i].string) == 0); break; case STORE_TOKEN_INTEGER: logNotice("testing int: %d vs %d", result->value.integer, lexer_test_solution_values[i].integer); TEST_ASSERT(result->value.integer == lexer_test_solution_values[i].integer); break; case STORE_TOKEN_FLOAT_NUMBER: logNotice("testing float: %f vs %f", result->value.float_number, lexer_test_solution_values[i].float_number); TEST_ASSERT(result->value.float_number == lexer_test_solution_values[i].float_number); break; } } g_ptr_array_free(results, true); }
static void listener_clientDisconnect(void *subject, const char *event, void *data, va_list args) { Socket *socket = subject; IrcProxyClient *client; if((client = g_hash_table_lookup(clients, socket)) != NULL) { // one of our proxy clients disconnected logNotice("IRC proxy client %d disconnected", client->socket->fd); if(client->proxy != NULL) { // check if the client is already associated to a proxy g_queue_remove(client->proxy->clients, client); // remove the client from its irc proxy } freeIrcProxyClient(client, "Bye"); } }
void DatabasePool::init(int min, int max, const QString &hostname, const QString &username, const QString &password, const QString &database) { logNotice("DatabasePool::init(): init database pool with %1 connections", QString::number(min) ); _minConnections = min; _maxConnections = max; _databaseHostname = hostname; _databaseUsername = username; _databasePassword = password; _databaseName = database; for (int i = 1; i <= min; i++) { logDebug("Create pool connection %1/%2", QString::number(i), QString::number(min)); _createPoolConnection(); } }
void TcpSocketThread::run() { _timeoutTimer = new QTimer(this); _timeoutTimer->moveToThread(this); _timeoutTimer->setInterval(SOCKET_TIMEOUT); connect(_timeoutTimer, SIGNAL(timeout()), this, SLOT(socketTimeout())); _timeoutTimer->start(SOCKET_TIMEOUT); // Ist noch kein Socket Deskriptor gesetzt, so ist beim setzen ein // Fehler aufgetreten, und wir beenden diesen Thread... if (_socket.socketDescriptor() == -1) { logError("Socket descriptor for this socket not set. Exit tcp thread..."); return; } // IP Adresse & Port loggen... logNotice( QString("Client connection from IP %1, port %2, to port %3") .arg(_socket.localAddress().toString(), QString::number( _socket.localPort() ), QString::number( _socket.peerPort() ) ) ); logDebug("Thread for the connection started."); logDebug("Install eventhandler, to close this thread, when tcp connection closed."); connect(&_socket, SIGNAL(disconnected()), this, SLOT(quit())); connect(&_socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); // Wenn neue Daten zum lesen vorhanden sind: connect(&_socket, SIGNAL(readyRead()), this, SLOT(newDataToRead())); // Datenstream auf Socket setzen: _socketBlockSize = 0; /** * Nun fangen wir an, am Tcp Port zu lauschen... */ logDebug("And now, i am waiting for data to read..."); exec(); }
API bool connectClientSocketAsync(Socket *s, int timeout) { if(s->connected) { logError("Cannot connect already connected socket %d", s->fd); return false; } if(s->type != SOCKET_CLIENT) { logError("Cannot asynchronously connect non-client socket"); return false; } struct addrinfo hints; struct addrinfo *server; int ret; memset(&hints, 0, sizeof(struct addrinfo)); hints.ai_family = AF_UNSPEC; // don't care if we use IPv4 or IPv6 to reach our destination hints.ai_socktype = SOCK_STREAM; // TCP stream sockets if((ret = getaddrinfo(s->host, s->port, &hints, &server)) != 0) { logError("Failed to look up address %s:%s: %s", s->host, s->port, gai_strerror(ret)); return false; } if((s->fd = socket(server->ai_family, server->ai_socktype, server->ai_protocol)) == -1) { logSystemError("Failed to create socket"); return false; } if(!setSocketNonBlocking(s->fd)) { logSystemError("Failed to set socket non-blocking"); closeSocket(s); return false; } logNotice("Asynchronously connecting client socket %d to %s:%s...", s->fd, s->host, s->port); if(connect(s->fd, server->ai_addr, server->ai_addrlen) < 0) { // try to connect socket #ifdef WIN32 if(WSAGetLastError() == WSAEINPROGRESS || WSAGetLastError() == WSAEWOULDBLOCK) { #else if(errno == EINPROGRESS) { #endif // free previous timer if present free(s->custom); AsyncConnectionTimer *timer = ALLOCATE_OBJECT(AsyncConnectionTimer); timer->creationTime = getMicroTime(); timer->timeout = timeout; s->custom = timer; g_queue_push_tail(connecting, s); // add to connecting list logInfo("Socket %d delayed connection, queueing...", s->fd); } else { #ifdef WIN32 char *error = g_win32_error_message(WSAGetLastError()); logError("Connection for socket %d failed: %s", s->fd, error); free(error); #else logSystemError("Connection for socket %d failed", s->fd); #endif closeSocket(s); freeaddrinfo(server); return false; } } else { logNotice("Direct response for asynchronous connection on socket %d", s->fd); s->connected = true; triggerEvent(s, "connected"); enableSocketPolling(s); } freeaddrinfo(server); return true; } API bool enableSocketPolling(Socket *socket) { if(isSocketPollingEnabled(socket)) { // Socket with that fd is already polled return false; } int *fd = ALLOCATE_OBJECT(int); *fd = socket->fd; g_hash_table_insert(poll_table, fd, socket); return true; } API bool isSocketPollingEnabled(Socket *socket) { return g_hash_table_lookup(poll_table, &socket->fd) != NULL; } API bool disableSocketPolling(Socket *socket) { return g_hash_table_remove(poll_table, &socket->fd) == true; } API void pollSockets() { if(!polling) { polling = true; // set polling flag to lock our poll table in order to make this function reentrancy safe if(!g_queue_is_empty(connecting)) { GQueue *connectingSockets = g_queue_copy(connecting); // copy the connecting socket list so we may modify the list while polling for(GList *iter = connectingSockets->head; iter != NULL; iter = iter->next) { if(pollConnectingSocket(iter->data)) { // poll the connecting socket // The socket should no longer be polled g_queue_remove(connecting, iter->data); // remove it from the original connecting queue } } g_queue_free(connectingSockets); // remove our temporary iteration list } GList *sockets = g_hash_table_get_values(poll_table); // get a static list of sockets so we may modify the hash table while polling for(GList *iter = sockets; iter != NULL; iter = iter->next) { Socket *poll = iter->data; int fd; // storage for the file descriptor that won't be available anymore in case the socket gets freed before we remove it if(pollSocket(poll, &fd)) { // poll the socket // The socket should no longer be polled g_hash_table_remove(poll_table, &fd); // remove it from the polling table } } g_list_free(sockets); // remove our temporary iteration list polling = false; // release pseudo lock on poll table } } API bool isSocketsPolling() { return polling; } API Socket *getPolledSocketByFd(int fd) { return g_hash_table_lookup(poll_table, &fd); } /** * Callback to poll all sockets signed up for polling */ TIMER_CALLBACK(poll) { pollSockets(); triggerEvent(NULL, "sockets_polled"); TIMER_ADD_TIMEOUT(pollInterval, poll); } /** * Polls a connecting socket and notifies the caller of whether it should be removed from the connecting polling queue afterwards * * @param socket the connecting socket to poll * @result true if the socket should be removed from the connecting polling queue after polling */ static bool pollConnectingSocket(Socket *socket) { assert(!socket->connected); assert(socket->type == SOCKET_CLIENT); assert(socket->custom != NULL); // Check whether the socket has timed out yet AsyncConnectionTimer *timer = socket->custom; if(getMicroTime() - timer->creationTime > timer->timeout) { // connection timed out logWarning("Asynchronous connection on socket %d timed out", socket->fd); closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } // Initialize timeout struct timeval tv = {0, 0}; // Initialize write fd set fd_set fdset; FD_ZERO(&fdset); FD_SET(socket->fd, &fdset); // Select socket for write flag (connected) int ret; if((ret = select(socket->fd + 1, NULL, &fdset, NULL, &tv)) < 0) { #ifdef WIN32 if(WSAGetLastError() != WSAEINTR) { char *error = g_win32_error_message(WSAGetLastError()); logError("Error selecting socket %d for write flag (connected) while polling: %s", socket->fd, error); free(error); #else if(errno != EINTR) { logSystemError("Error selecting socket %d for write flag (connected) while polling", socket->fd); #endif closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } // EINTR at this point means the socket is just not connected yet, so we can safely return and continue polling another time return false; } else if(ret > 0) { // there is a write flag on the socket // Socket selected for write, check if we're indeed connected int valopt; socklen_t lon = sizeof(int); if(getsockopt(socket->fd, SOL_SOCKET, SO_ERROR, (void*) (&valopt), &lon) < 0) { logSystemError("getsockopt() failed on socket %d", socket->fd); closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } else if(valopt != 0) { // There was a connection error logSystemError("Asynchronous connection on socket %d failed", socket->fd); closeSocket(socket); triggerEvent(socket, "disconnect"); return true; } logNotice("Asynchronously connected socket %d", socket->fd); socket->connected = true; triggerEvent(socket, "connected"); enableSocketPolling(socket); return true; } // the socket doesn't have a write flag, so let's just wait until it's connected return false; } /** * Polls a socket and notifies the caller of whether it should be removed from the polling table afterwards * * @param socket the socket to poll * @param fd_p a pointer to an integer field to which the file descriptor of the socket should be written in case the socket should be removed from the polling table and could already be freed at that time * @result true if the socket should be removed from the polling table after polling */ static bool pollSocket(Socket *socket, int *fd_p) { *fd_p = socket->fd; // backup file descriptor if(!socket->connected) { // Socket is disconnected triggerEvent(socket, "disconnect"); return true; } if(socket->type != SOCKET_SERVER && socket->type != SOCKET_SERVER_BLOCK) { int ret; if((ret = socketReadRaw(socket, poll_buffer, SOCKET_POLL_BUFSIZE)) < 0) { if(socket->connected) { // socket is still connected, so the error was not fatal triggerEvent(socket, "error"); return false; } else { // socket was disconnected either by the peer or by a fatal error triggerEvent(socket, "disconnect"); return true; } } else if(ret > 0) { // we actually read something triggerEvent(socket, "read", poll_buffer, ret); } // else nothing to read right now } else { Socket *clientSocket; if((clientSocket = socketAccept(socket)) != NULL) { triggerEvent(socket, "accept", clientSocket); } else { if(socket->connected) { // socket is still connected, so the error was not fatal triggerEvent(socket, "error"); return false; } else { // socket was disconnected either by the peer or by a fatal error triggerEvent(socket, "disconnect"); return true; } } } return false; }
static void listener_clientLine(void *subject, const char *event, void *data, va_list args) { IrcProxyClient *client = subject; IrcMessage *message = va_arg(args, IrcMessage *); if(!client->authenticated) { // not yet authenticated, wait for password if(g_strcmp0(message->command, "PASS") == 0) { char *password = NULL; if(message->params_count > 0 && message->params != NULL && message->params[0] != 0) { // password seems to be in the first param password = message->params[0]; } else { // password must be in trailing space password = message->trailing; } if(password != NULL) { char **parts = g_strsplit(password, ":", 0); int count = 0; while(parts[count] != NULL) { // count parts count++; } if(count >= 2) { // there are at least two parts char *name = parts[0]; IrcProxy *proxy; if((proxy = g_hash_table_lookup(proxies, name)) != NULL) { // it's a valid ID if(g_strcmp0(proxy->password, parts[1]) == 0) { // the password also matches logNotice("IRC proxy client %d authenticated successfully to IRC proxy '%s'", client->socket->fd, name); client->authenticated = true; // associate client and proxy client->proxy = proxy; g_queue_push_head(proxy->clients, client); proxyClientIrcSend(client, ":%s 001 %s :You were successfully authenticated and are now connected to the IRC server", proxy->irc->socket->host, proxy->irc->nick); proxyClientIrcSend(client, ":%s 251 %s :There are %d clients online on this bouncer", client->proxy->irc->socket->host, proxy->irc->nick, g_queue_get_length(proxy->clients)); triggerEvent(proxy, "client_authenticated", client); } else { proxyClientIrcSend(client, ":kalisko.proxy NOTICE AUTH :*** Login incorrect for IRC proxy ID %c%s%c", (char) 2, name, (char) 2); } } else { proxyClientIrcSend(client, ":kalisko.proxy NOTICE AUTH :*** Invalid IRC proxy ID %c%s%c", (char) 2, name, (char) 2); } } g_strfreev(parts); } } } else if(g_strcmp0(message->command, "PING") == 0) { // reply to pings if(message->trailing != NULL) { proxyClientIrcSend(client, "PONG :%s", message->trailing); } } else if(g_strcmp0(message->command, "USER") == 0) { // prevent user command from being passed through return; } else if(g_strcmp0(message->command, "QUIT") == 0) { // client disconnects logInfo("IRC proxy client %d sent QUIT message, disconnecting...", client->socket->fd); disconnectSocket(client->socket); } else { if((g_strcmp0(message->command, "PRIVMSG") == 0 || g_strcmp0(message->command, "NOTICE") == 0) && message->params_count > 0) { // potential filtered command for(GList *iter = client->proxy->relay_exceptions->head; iter != NULL; iter = iter->next) { if(g_strcmp0(iter->data, message->params[0]) == 0) { // target matches, so don't relay! return; } } } // Relay message to IRC server ircSend(client->proxy->irc, "%s", message->raw_message); } }
result_t loadScanConfigFile(MessageMap* messages, unsigned char address, SymbolString& data, string& relativeFile) { PartType partType; if (isMaster(address)) { address = (unsigned char)(data[0]+5); // slave address of sending master partType = pt_masterData; if (data.size()<5+1+5+2+2) // skip QQ ZZ PB SB NN return RESULT_EMPTY; } else { partType = pt_slaveData; if (data.size()<1+1+5+2+2) // skip NN return RESULT_EMPTY; } DataFieldSet* identFields = DataFieldSet::getIdentFields(); // MANUFACTURER/ZZ. ( C.S.H., C.H., C.S., S.H., C., S., H., "" ) .*csv string path, prefix, ident, sw, hw; // path: cfgpath/MANUFACTURER, prefix: ZZ., ident: C[C[C[C[C]]]], sw: xxxx, hw: xxxx ostringstream out; unsigned char offset = 0; size_t field = 0; result_t result = (*identFields)[field]->read(partType, data, offset, out, 0); // manufacturer name if (result==RESULT_ERR_NOTFOUND) result = (*identFields)[field]->read(partType, data, offset, out, OF_NUMERIC); // manufacturer name if (result==RESULT_OK) { path = out.str(); transform(path.begin(), path.end(), path.begin(), ::tolower); path = string(opt.configPath) + "/" + path; out.str(""); out << setw(2) << hex << setfill('0') << nouppercase << static_cast<unsigned>(address) << "."; prefix = out.str(); out.str(""); out.clear(); offset = (unsigned char)(offset+(*identFields)[field++]->getLength(partType)); result = (*identFields)[field]->read(partType, data, offset, out, 0); // identification string } if (result==RESULT_OK) { ident = out.str(); out.str(""); offset = (unsigned char)(offset+(*identFields)[field++]->getLength(partType)); result = (*identFields)[field]->read(partType, data, offset, out, 0); // software version number } if (result==RESULT_OK) { sw = out.str(); out.str(""); offset = (unsigned char)(offset+(*identFields)[field++]->getLength(partType)); result = (*identFields)[field]->read(partType, data, offset, out, 0); // hardware version number } if (result!=RESULT_OK) { logDebug(lf_main, "load scan config files: %s", getResultCode(result)); return result; } vector<string> files; bool hasTemplates = false; if (result==RESULT_OK) { hw = out.str(); result = collectConfigFiles(path, prefix, ".csv", files, NULL, &hasTemplates); } logDebug(lf_main, "found %d matching scan config files from %s with prefix %s: %s", files.size(), path.c_str(), prefix.c_str(), getResultCode(result)); if (result!=RESULT_OK) return result; if (files.empty()) return RESULT_ERR_NOTFOUND; // complete name: cfgpath/MANUFACTURER/ZZ[.C[C[C[C[C]]]]][.SWxxxx][.HWxxxx][.*].csv for (string::iterator it = ident.begin(); it!=ident.end(); it++) { if (::isspace(*it)) { ident.erase(it--); } else { *it = (char)::tolower(*it); } } size_t prefixLen = path.length()+1+prefix.length()-1; size_t bestMatch = 0; string best; for (vector<string>::iterator it = files.begin(); it!=files.end(); it++) { string name = *it; name = name.substr(prefixLen, name.length()-prefixLen+1-strlen(".csv")); // .*. size_t match = 1; if (name.length()>2) { // more than just "." size_t pos = name.rfind(".SW"); // check for ".SWxxxx." if (pos!=string::npos && name.find(".", pos+1)==pos+7) { if (name.substr(pos+3, 4)==sw) match += 6; else { continue; // SW mismatch } } pos = name.rfind(".HW"); // check for ".HWxxxx." if (pos!=string::npos && name.find(".", pos+1)==pos+7) { if (name.substr(pos+3, 4)==hw) match += 6; else { continue; // HW mismatch } } pos = name.find(".", 1); // check for ".C[C[C[C[C]]]]." if (ident.length()>0 && pos!=string::npos && pos>1 && pos<=6) { // up to 5 chars between two "."s, immediately after "ZZ." string check = name.substr(1, pos-1); string remain = ident; bool matches = false; while (remain.length()>0 && remain.length()>=check.length()) { if (check==remain) { matches = true; break; } if (remain[remain.length()-1]!='0') break; remain.erase(remain.length()-1); } if (matches) match += remain.length(); else { continue; // IDENT mismatch } } } if (match>=bestMatch) { bestMatch = match; best = *it; } } if (best.length()==0) return RESULT_ERR_NOTFOUND; // found the right file. load the templates if necessary, then load the file itself bool readCommon = false; DataFieldTemplates* templates = getTemplates(path, ".csv", hasTemplates, false, &readCommon); if (readCommon) { result = collectConfigFiles(path, "", ".csv", files); if (result==RESULT_OK && !files.empty()) { for (vector<string>::iterator it = files.begin(); it!=files.end(); it++) { string name = *it; name = name.substr(path.length()+1, name.length()-path.length()-strlen(".csv")); // *. if (name=="_templates.") // skip templates continue; if (name.length()<3 || name.find_first_of('.')!=2) { // different from the scheme "ZZ." name = *it; result = messages->readFromFile(name, templates); if (result==RESULT_OK) logNotice(lf_main, "read common config file %s for scan %s", name.c_str(), ident.c_str()); else logError(lf_main, "error reading common config file %s for scan %s: %s", name.c_str(), ident.c_str(), getResultCode(result)); } } } } result = messages->readFromFile(best, templates); if (result!=RESULT_OK) { logError(lf_main, "error reading config file %s for scan %s: %s", best.c_str(), ident.c_str(), getResultCode(result)); return result; } logNotice(lf_main, "read config file %s for scan %s", best.c_str(), ident.c_str()); result = messages->resolveConditions(false); if (result != RESULT_OK) logError(lf_main, "error resolving conditions: %s, %s", getResultCode(result), messages->getLastError().c_str()); logNotice(lf_main, "found messages: %d (%d conditional on %d conditions, %d poll, %d update)", messages->size(), messages->sizeConditional(), messages->sizeConditions(), messages->sizePoll(), messages->sizePassive()); relativeFile = best.substr(strlen(opt.configPath)+1); return RESULT_OK; }
void TcpSocketThread::newDataToRead() { QTime timeStart( QTime::currentTime() ); try { // Die zu verarbeitenden Daten, welche vom Client zum Server gesendet wurden... QByteArray clientData; logDebug("New Data to read available."); // Wurde schon bestimmt, wie viele Bytes vom Client erwarten zu sind? if (_socketBlockSize == 0) { logDebug("Try to detect the size of the incoming data..."); // Wurden schon genug Daten empfangen, um die zu erwartenden Block zu bestimmen? if (_socket.bytesAvailable() <= sizeof(quint32) ) { // Wir müssen auf mehr Daten des Clients warten... logDebug("Not enough data arrived. I wait for more data..."); return; } // Anzahl erwartende Bytes: QDataStream dataStream(&_socket); dataStream >> _socketBlockSize; logDebug( QString("Size of incoming data detected. Size are %1 bits").arg(QString::number(_socketBlockSize)) ); } // Wurden vom Client bereits alle Daten empfangen??? if (_socket.bytesAvailable() != _socketBlockSize) { logDebug("Not all data packages from the client arrived (%1 from %2 bytes) Wait for more data...", QString::number(_socket.bytesAvailable()), QString::number(_socketBlockSize) ); return; } else { logDebug("All data from the client arrived. Start parsing the data..."); clientData = _socket.read(_socketBlockSize); } QDataStream dataStreamRead(&clientData, QIODevice::ReadWrite); /** * Alle Daten vom Client empfangen, jetzt folgt die Bearbeitung der * empfangenen Daten */ logDebug("Start extract the incoming datas..."); // Art des Befehls: // 0 -> TcpCommand group/command // 1 -> timeout reseter quint8 tcpType; UtilDataStream::read(dataStreamRead, tcpType); switch (tcpType) { case 0: /** * Tcp Command: */ { // Kommunikations- ID: quint16 commId; UtilDataStream::read(dataStreamRead, commId); // Gruppenname, in welcher sich diese Aktion befindet. QByteArray group; UtilDataStream::read(dataStreamRead, group); // Name der auszuführenden Aktion QByteArray action; UtilDataStream::read(dataStreamRead, action); logNotice("Try to find action %1/%2...", group, action); std::auto_ptr<TcpAbstractCommand> command( TcpCommandFactories::instance()->createCommand(group, action) ); // Wurde 0 zurückgegeben, so existiert der Befehl nicht... if (command.get() == 0) { logError("Could not run tcp command '%1/%2'. Action does not exists!", group, action); close(); return; } command->setCommId(commId); command->setSocket(&_socket); command->setUserAccount(&_user); command->setDataStreamRead(&dataStreamRead); /** * Überprüfen, ob Befehl ausgeführt werden darf... */ TcpAbstractCommand::TCP_RESPONSE_TYPE answerType = TcpAbstractCommand::NORMAL_RESPONSE; // Hat User die Berechtigungen, diesen Befehl auszuführen?? if (! UtilUsers::canRunTcpCommand(_user.getColumn("id").toInt(), group, action) ) { /** * Benutzer hat nicht entsprechende Berechtigungen, um diesen Befehl auszuführen: */ logError("User has not enough permissions to run the tcp action %1/%2", group, action); answerType = TcpAbstractCommand::TCP_PERMISSION_ERROR; } else { // Befehl ausführen: logDebug("Run action %1/%2...", group, action); QVariant execReturn = command->exec(); logDebug("Run postExec()."); command->postExec( execReturn ); } logDebug("Tramsit data over the tcp socket to the client..."); command->writeDataStream(answerType); logDebug("Datastream transmitted success!..."); break; } case 1: { /** * Timeout Reseter: */ logDebug("Reset socket timeout."); // wir schreiben den Client die Zahl "15253" zurück... QByteArray dataStreamWriteArray; QDataStream dataStreamWrite(&dataStreamWriteArray, QIODevice::WriteOnly); quint16 answer = 15253; dataStreamWrite << (quint32) sizeof(quint16); dataStreamWrite << answer; _socket.write(dataStreamWriteArray); _socket.flush(); break; } default: logError("Unknown tcpType. Bye!"); close(); return; } logError("Tcp transction time: " + QString::number(timeStart.msecsTo(QTime::currentTime())) + "ms"); _timeoutTimer->stop(); _timeoutTimer->start(SOCKET_TIMEOUT); }