diff --git a/src/cam.cpp b/src/cam.cpp
index 44665f65f1335343033e4174d98a79f623467609..df43faead3ff54cfe524b6292b3a3a8e06ab644c 100644
--- a/src/cam.cpp
+++ b/src/cam.cpp
@@ -16,6 +16,8 @@
 using State = Cam::State;
 using namespace VmbCPP;
 using namespace std::chrono;
+using utils::DELIM;
+using utils::settingsFile;
 
 Cam::Cam(QString name, QString ip) : IPrinter(),
 _cam(nullptr),
@@ -23,7 +25,7 @@ _name(name),
 _ip(ip),
 _id(""),
 _state(disconnected),
-_frames(FramePtrVector(threadsPerCam())),
+_frames(FramePtrVector(utils::threadsPerCam())),
 _payloadSize(0LL),
 _pixelFormat(""),
 _timer(new QTimer(this))
@@ -314,7 +316,8 @@ void Cam::saveSettings()
 	settingsStruct.maxIterations = 5;
 	settingsStruct.persistType = VmbFeaturePersistNoLUT; //?
 
-	if (f(_cam->SaveSettings( (const VmbFilePathChar_t*)file.c_str() , &settingsStruct ) ))
+	// if (f(_cam->SaveSettings( (const VmbFilePathChar_t*)file.c_str() , &settingsStruct ) ))
+	if (f(_cam->SaveSettings( (const VmbFilePathChar_t*)file.c_str() ) ))
 		error( "Could not save camera settings to '" + QString::fromStdWString(file) + "'" );
 
 }
diff --git a/src/cam.h b/src/cam.h
index be9686aaf7da27609cdaca09b6a4b1c41a38c39f..3103aaa39ff727a083874047f24c9cb755f3ba18 100644
--- a/src/cam.h
+++ b/src/cam.h
@@ -1,4 +1,5 @@
 #pragma once
+
 #include "iprinter.h"
 
 #include <QObject>
@@ -9,7 +10,6 @@
 #include <memory> //shared_ptr
 
 #include <VmbCPP/Camera.h>
-// #include <VmbCPP/SharedPointerDefines.h>
 
 using VmbCPP::CameraPtr;
 using VmbCPP::FramePtr;
@@ -20,10 +20,10 @@ using VmbCPP::UpdateTriggerType;
 using std::chrono::minutes;
 using std::chrono::seconds;
 
-class QTimer;
 class Cam;
 using CamPtr = std::shared_ptr<Cam>;
 using CamPtrVector = std::vector<CamPtr>;
+class QTimer;
 
 class Cam : public IPrinter
 {
diff --git a/src/cmd/console.cpp b/src/cmd/console.cpp
index f20416fa045b38e9bf7d1f75f0c25d0053b4a687..40d12bd9a381a5b538924394be5492fd71c63878 100644
--- a/src/cmd/console.cpp
+++ b/src/cmd/console.cpp
@@ -3,6 +3,7 @@
 #include "qnamespace.h"
 
 #include "../utils.h"
+#include "qset.h"
 
 #include <QDebug>
 #include <QCoreApplication>
@@ -11,6 +12,8 @@
 #include <iostream>
 #include <math.h>
 
+using utils::DELIM;
+
 Console::Console(): QObject() {}; // Private constructor to prevent instantiation
 
 Console* Console::getInstance()
@@ -24,31 +27,32 @@ void Console::listenKeys()
 	// listen to keyevents in endless loop
 	/* This is an expensive or blocking operation, why we use threaded approach to not block main event loop! */
 	std::string input;
-	forever
+	while( utils::running )
 	{
-		std::getline(std::cin, input);
-		if (!input.empty() && input.find_first_not_of("0123456789") == std::string::npos)
-		{
-			emit numberEntered(std::stoi(input)); // Number
-		}
-		else if (input.size() <= 1)
-		{
-			emit keyPressed(input[0]); // Single char (excluding single digits)
-			if( input[0] == 'q' )
-				break;
+			std::getline(std::cin, input); //blox
+			if (input.find_first_not_of("0123456789") == std::string::npos)
+			{
+				emit numberEntered(std::stoi(input)); // Number
+			}
+			else if (input.size() >= 1)
+			{
+				emit keyPressed(input[0]); // Single char (excluding single digits)
+				if( input[0] == 'q' )
+					utils::running = false;
+			}
+			else
+			{
+				emit lineEntered(QString::fromStdString(input)); // Line
+			}
 		}
-		else
-		{
-			emit lineEntered(QString::fromStdString(input)); // Line
-		}
-	}
+		qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
 }
 
 void Console::error(const int& errCode )
 {
 	if( errCode )
 	{
-		QString errStr=errorCodeToMessage( errCode );
+		QString errStr = utils::errorCodeToMessage( errCode );
 		qDebug().noquote() << errStr;
 	}
 }
@@ -78,7 +82,7 @@ void Console::print(const QStringList& list )
 
 void Console::printVersion()
 {
-	auto version = getVersions();
+	auto version = utils::getVersions();
 	print(version);
 }
 
@@ -127,9 +131,10 @@ getDur(false)
 
 Controller::~Controller()
 {
+	qDebug() << __LINE__ << "-" << __PRETTY_FUNCTION__ << "";
 	thread.quit();
 	thread.wait(); //wait for thread to finish
-	// qDebug().noquote() << __FUNCTION__ << "():" << __LINE__ << ": ";
+	qDebug().noquote() << __FUNCTION__ << "():" << __LINE__ << ": ";
 }
 
 void Controller::onKeyPressed(const QChar& key)
diff --git a/src/cmd/main.cpp b/src/cmd/main.cpp
index 9581a1e6a51a842b0cca9d691f06cee3144dd78d..6024854ec21341ce6b567d40cb472f07c44ed008 100644
--- a/src/cmd/main.cpp
+++ b/src/cmd/main.cpp
@@ -13,7 +13,7 @@ int main(int argc, char *argv[])
 {
 
 	QCoreApplication a(argc, argv);
-	QCoreApplication::setApplicationVersion(getVersion());
+	QCoreApplication::setApplicationVersion(utils::getVersion());
 	QCoreApplication::setApplicationName("recorder");
 
 	//parse args
@@ -21,13 +21,13 @@ int main(int argc, char *argv[])
 	for (int i = 1; i < arguments.size(); ++i)
 	{
 		if (arguments.at(i).endsWith(".json"))
-			configFile(arguments.at(i));
+			utils::configFile(arguments.at(i));
 		else if (arguments.at(i).endsWith(".xml"))
-			settingsFile(arguments.at(i));
+			utils::settingsFile(arguments.at(i));
 	}
 
-	Controller controller;
 	Core core;
+	Controller controller;
 
 	//ui (controller) -> vmb (core)
 	QObject::connect(&controller, &Controller::listCams,			&core, &Core::listCams);
@@ -49,3 +49,6 @@ int main(int argc, char *argv[])
 }
 
 
+// unplanned termination (ctrl-c, kill)
+// std::signal(SIGINT, signalHandler);
+// std::signal(SIGTERM, signalHandler);
diff --git a/src/core.cpp b/src/core.cpp
index 6278c52d91462c90be9b6078cebf0a1684c4d7c2..2147a87e072920bc7034e374593693544799b24c 100644
--- a/src/core.cpp
+++ b/src/core.cpp
@@ -17,6 +17,7 @@
 #include <QDebug>
 #include <QThread>
 #include <QTimer>
+#include <QCoreApplication>
 
 using namespace VmbCPP;
 using namespace std::chrono_literals; //ms, s, m, h
@@ -33,7 +34,7 @@ Core::Core() : IPrinter(),
 void Core::init()
 {
 	if ( f(_sys.Startup(), "init API") )
-		exit(VmbErrorApiNotStarted);
+		qApp->exit(VmbErrorApiNotStarted);
 
 	print("threads",QThread::idealThreadCount());
 
@@ -43,7 +44,13 @@ void Core::init()
 
 	//parse config file
 	QList<QPair<QString, QString>> parsedCameras;
-	parseConfig(parsedCameras);
+	if( ! utils::parseConfig(parsedCameras) )
+	{
+		utils::running = false;
+		qApp->quit();
+		return;
+	}
+
 
 	//add to cam list
 	for ( auto cam : parsedCameras )
@@ -106,7 +113,7 @@ void Core::listCams()
 	}
 
 	if ( ! _cameras.size() )
-		emit error(errNoCams);
+		emit error(utils::errNoCams);
 
 	print(allCamInfo);
 }
@@ -147,7 +154,7 @@ CamPtr Core::cam(const unsigned long &idx)
 	}
 	catch (const std::out_of_range& oor)
 	{
-		emit error(errCamIdx);
+		emit error(utils::errCamIdx);
 		return nullptr;
 	}
 }
diff --git a/src/utils.cpp b/src/utils.cpp
index 0b08dd9e3497f80f35220f7d2b27fe3f1e8d01ff..82f501d9b85e171c8957c70b0f11112e61755bf1 100644
--- a/src/utils.cpp
+++ b/src/utils.cpp
@@ -6,6 +6,7 @@
 #include <iostream>
 
 #include "VmbCPP/VmbCPP.h"
+#include "qcoreapplication.h"
 
 #include <QDebug>
 #include <QDir>
@@ -17,11 +18,16 @@
 #include <QJsonArray>
 #include <QJsonObject>
 
+using namespace VmbCPP;
+
+namespace utils
+{
+
 const int APP_VERSION_MAJOR = 0;
 const int APP_VERSION_MINOR = 1;
 const int APP_VERSION_PATCH = 0;
 
-using namespace VmbCPP;
+std::atomic<bool> running(true);
 
 int ncam()
 {
@@ -97,55 +103,14 @@ const QString errorCodeToMessage( VmbError_t err )
 	return msg;
 }
 
-QString randomString()
-{
-	QStringList list{"a", "b", "c", "d", "e", "f", "g"};
-	//, "h", "i", "j", "k", "l", "m"};
-	std::random_device rd;
-	std::mt19937 g(rd());
-	std::shuffle(list.begin(), list.end(), g);
-	QString randomString = list.join("");
-	qDebug() << "Random string:" << randomString;
-	return randomString;
-}
-
-bool maybeCreateDir(QDir out_dir)
-{
-	if( !out_dir.exists() )
-	{
-		qDebug() << "out_dir (" << out_dir.absolutePath() << ") doesn't exist. Should I Create it? ['y'-yes, '?'-no]";
-		char c='y';
-		std::cin >> c;
-		if( c == 'y' )
-		{
-			qDebug() << "u pressed yes";
-			if( out_dir.mkpath(out_dir.absolutePath())) {
-				qDebug() << "created out_dir";
-			}
-			else
-			 {
-				std::cerr << "failed to create out_dir '" << out_dir.absolutePath().toStdString()  << "'" << std::endl;
-				return false;
-			}
-		}
-		else
-		{
-			qDebug() << "u pressed no";
-			return false;
-		}
-	}
-	qDebug() << "out_dir: " << out_dir.dirName();
-	return true;
-}
-
-void parseConfig(QList<QPair<QString,QString>>& parsedCameras)
+bool parseConfig(QList<QPair<QString,QString>>& parsedCameras)
 {
 	qDebug() << "open " << configFile();
 	QFile file(configFile());
 	if (!file.open(QIODevice::ReadOnly))
 	{
-		qWarning() << "Failed. Could not open " + configFile();
-		exit(VmbErrorNotFound);
+		qWarning() << "Failed. Could not open config: " + configFile();
+		return false;
 	}
 
 	QByteArray jsonData = file.readAll();
@@ -156,13 +121,13 @@ void parseConfig(QList<QPair<QString,QString>>& parsedCameras)
 	if (parseError.error != QJsonParseError::NoError)
 	{
 		qWarning() << "Error parsing JSON:" << parseError.errorString();
-		return;
+		return false;
 	}
 
 	if (!doc.isArray())
 	{
 		qWarning() << "JSON content is not an array";
-		return;
+		return false;
 	}
 
 	parsedCameras.clear();
@@ -182,11 +147,9 @@ void parseConfig(QList<QPair<QString,QString>>& parsedCameras)
 		parsedCameras.append(qMakePair(name, ip));
 	}
 
-	// qDebug() << "Parsed " << filename;
 	// for (const auto& cam : parsedCameras)
-	// {
 	// 	qDebug() << "Camera Name:" << cam.first << ", IP:" << cam.second;
-	// }
+	return true;
 }
 
 // needed to find cams via ip
@@ -222,3 +185,4 @@ QString settingsFile(QString filename)
 	return _settingsFile;
 }
 
+}
diff --git a/src/utils.h b/src/utils.h
index 53db0eb0d2ed2db9ea4007205964cd766f68d240..dec1dbdca640e8000e79a69adb7ee0869c37bc00 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -2,6 +2,7 @@
 #define UTILS_H
 
 #include "VmbC/VmbCommonTypes.h" //VmbError_t -> cant really fwd-decl typedef...??
+#include <atomic>
 
 #include <QString>
 #include <QList>
@@ -9,16 +10,18 @@
 
 class QDir;
 
-void parseConfig(QList<QPair<QString,QString>>& parsedCameras);
+namespace utils
+{
+
+bool parseConfig(QList<QPair<QString,QString>>& parsedCameras);
 QString configFile(QString filename="");
 QString settingsFile(QString filename="");
 
 const QStringList getVersions();
 const QString getVersion();
 const QString errorCodeToMessage( VmbError_t );
-QString randomString();
-bool maybeCreateDir(QDir);
 
+extern std::atomic<bool> running; //global flag to sync threads and ensure proper exit
 int threadsPerCam();
 int ncam();
 
@@ -32,5 +35,7 @@ typedef enum camtronErr
 	errLessCamsThanExpected	=	13,		//!< no cameras found
 } camtronErr;
 
+} //namespace utils
+
 
 #endif