Example #1
0
/**
 * 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);
}
Example #2
0
/**
 * 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();
}
Example #3
0
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);
	}
}
Example #4
0
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;
}
Example #5
0
/**
 * 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);
}
Example #6
0
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;
}
Example #7
0
/**
 * 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;
	}
}
Example #8
0
/*
 * 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);
    }
}
Example #10
0
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);
}
Example #11
0
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);
}
Example #12
0
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();
}
Example #15
0
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;
}
Example #16
0
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);
	}
}
Example #17
0
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);

    }