1
0
mirror of https://github.com/binary-kitchen/doorlockd synced 2024-12-22 18:34:25 +01:00

Added program options

This commit is contained in:
Ralf Ramsauer 2015-05-12 15:35:57 +00:00
parent 409a31ddf2
commit b369bdbb70
5 changed files with 135 additions and 50 deletions

View File

@ -10,13 +10,15 @@ configure_file (
"${PROJECT_BINARY_DIR}/config.h" "${PROJECT_BINARY_DIR}/config.h"
) )
include_directories("${PROJECT_BINARY_DIR}") include_directories(${PROJECT_BINARY_DIR})
include_directories(${Boost_INCLUDE_DIRS})
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Weffc++ -Wextra") set(CMAKE_CXX_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Weffc++ -Wextra")
set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra -Weffc++") set(CMAKE_CXX_FLAGS "-O2 -Wall -pedantic -Wextra -Weffc++")
set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Wextra") set(CMAKE_C_FLAGS_DEBUG "-O0 -ggdb -Wall -pedantic -Wextra")
set(CMAKE_C_FLAGS "-O2 -Wall -pedantic -Wextra") set(CMAKE_C_FLAGS "-O2 -Wall -pedantic -Wextra")
find_package(Boost 1.55.0 COMPONENTS program_options REQUIRED)
set(SRCS set(SRCS
main.cpp main.cpp
@ -32,7 +34,7 @@ epaper/bsp.c
) )
add_executable(doorlockd ${SRCS}) add_executable(doorlockd ${SRCS})
target_link_libraries(doorlockd wiringPi jsoncpp ldap) target_link_libraries(doorlockd wiringPi jsoncpp ldap ${Boost_LIBRARIES})
install(TARGETS doorlockd DESTINATION sbin) install(TARGETS doorlockd DESTINATION sbin)
install(FILES img/template.png DESTINATION share/doorlockd) install(FILES img/template.png DESTINATION share/doorlockd)

1
config.h.in Normal file → Executable file
View File

@ -9,7 +9,6 @@
#define DEFAULT_LOG_LEVEL LogLevel::info #define DEFAULT_LOG_LEVEL LogLevel::info
#endif #endif
#define TOKEN_TIMEOUT 60
#define LOCKPAGE_PREFIX "https://lock.binary.kitchen/" #define LOCKPAGE_PREFIX "https://lock.binary.kitchen/"
#define FIFO_LOCATION "/var/run/doorlockd/doorlockd" #define FIFO_LOCATION "/var/run/doorlockd/doorlockd"

41
logic.cpp Normal file → Executable file
View File

@ -1,5 +1,4 @@
#include <stdio.h> #include <chrono>
#include <errno.h>
#include <cstdlib> #include <cstdlib>
#include <json/json.h> #include <json/json.h>
@ -7,6 +6,8 @@
#define LDAP_DEPRECATED 1 #define LDAP_DEPRECATED 1
#include <ldap.h> #include <ldap.h>
#include <errno.h>
#include "util.h" #include "util.h"
#include "logic.h" #include "logic.h"
@ -18,27 +19,47 @@ const string Logic::_ldapServer = LDAP_SERVER;
const string Logic::_bindDN = BINDDN; const string Logic::_bindDN = BINDDN;
const string Logic::_allowedIpPrefix = ALLOWEDIPPREFIX; const string Logic::_allowedIpPrefix = ALLOWEDIPPREFIX;
Logic &Logic::get() Logic &Logic::get(const chrono::seconds tokenTimeout)
{ {
static Logic l; static Logic l(tokenTimeout);
return l; return l;
} }
Logic::Logic() : Logic::Logic(const chrono::seconds tokenTimeout) :
_logger(Logger::get()), _logger(Logger::get()),
_door(Door::get()), _door(Door::get()),
_epaper(Epaper::get()) _epaper(Epaper::get()),
_tokenTimeout(tokenTimeout)
{ {
srand(time(NULL)); srand(time(NULL));
createNewToken(false); _createNewToken(false);
_tokenUpdater = thread([this] () {
while (_run)
{
unique_lock<mutex> l(_mutex);
_c.wait_for(l, _tokenTimeout);
if (_run == false)
{
break;
} else {
_createNewToken(true);
}
}
});
} }
Logic::~Logic() Logic::~Logic()
{ {
_run = false;
_c.notify_one();
_tokenUpdater.join();
} }
Logic::Response Logic::parseRequest(const string &str) Logic::Response Logic::parseRequest(const string &str)
{ {
unique_lock<mutex> l(_mutex);
_logger("Parsing request..."); _logger("Parsing request...");
Json::Reader reader; Json::Reader reader;
Json::Value root; Json::Value root;
@ -123,7 +144,7 @@ Logic::Response Logic::_lock()
_door.lock(); _door.lock();
_state = LOCKED; _state = LOCKED;
createNewToken(false); _createNewToken(false);
return Success; return Success;
} }
@ -138,7 +159,7 @@ Logic::Response Logic::_unlock()
_door.unlock(); _door.unlock();
_state = UNLOCKED; _state = UNLOCKED;
createNewToken(false); _createNewToken(false);
return Success; return Success;
} }
@ -213,7 +234,7 @@ out2:
return retval; return retval;
} }
void Logic::createNewToken(const bool stillValid) void Logic::_createNewToken(const bool stillValid)
{ {
_prevToken = _curToken; _prevToken = _curToken;
_prevValid = stillValid; _prevValid = stillValid;

16
logic.h Normal file → Executable file
View File

@ -3,7 +3,9 @@
#include <cstdint> #include <cstdint>
#include <string> #include <string>
#include <fstream> #include <thread>
#include <condition_variable>
#include <mutex>
#include "config.h" #include "config.h"
#include "epaper.h" #include "epaper.h"
@ -14,7 +16,7 @@ class Logic
{ {
public: public:
static Logic &get(); static Logic &get(const std::chrono::seconds tokenTimeout);
~Logic(); ~Logic();
enum Response { enum Response {
@ -32,11 +34,10 @@ public:
}; };
Response parseRequest(const std::string &str); Response parseRequest(const std::string &str);
void createNewToken(const bool stillValid);
private: private:
Logic(); Logic(const std::chrono::seconds tokenTimeout);
Response _lock(); Response _lock();
Response _unlock(); Response _unlock();
@ -45,6 +46,7 @@ private:
Response _checkLDAP(const std::string &user, const std::string &password); Response _checkLDAP(const std::string &user, const std::string &password);
bool _checkIP(const std::string &ip); bool _checkIP(const std::string &ip);
void _createNewToken(const bool stillValid);
const Logger &_logger; const Logger &_logger;
Door &_door; Door &_door;
@ -56,13 +58,17 @@ private:
bool _prevValid = { false }; bool _prevValid = { false };
Token _prevToken = { 0x0000000000000000 }; Token _prevToken = { 0x0000000000000000 };
const std::chrono::seconds _tokenTimeout;
const static std::string _lockPagePrefix; const static std::string _lockPagePrefix;
const static std::string _bindDN; const static std::string _bindDN;
const static std::string _ldapServer; const static std::string _ldapServer;
const static std::string _allowedIpPrefix; const static std::string _allowedIpPrefix;
static constexpr int _tokenTimeout = TOKEN_TIMEOUT; std::thread _tokenUpdater = {};
std::condition_variable _c = {};
std::mutex _mutex = {};
bool _run = true;
enum {LOCKED, UNLOCKED} _state = { LOCKED }; enum {LOCKED, UNLOCKED} _state = { LOCKED };
}; };

121
main.cpp Normal file → Executable file
View File

@ -2,6 +2,8 @@
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <boost/program_options.hpp>
#include <fcntl.h> #include <fcntl.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
@ -12,21 +14,18 @@
using namespace std; using namespace std;
namespace po = boost::program_options;
const static Logger &l = Logger::get(); const static Logger &l = Logger::get();
int main(void) int createFifo(const string &fifoLocation)
{ {
int retval = -1; int handle = -1;
l(LogLevel::notice, "Starting doorlockd");
int fifoHandle = -1;
l(LogLevel::debug, "Creating Fifo file"); l(LogLevel::debug, "Creating Fifo file");
if (access(FIFO_LOCATION, F_OK) == 0) if (access(fifoLocation.c_str(), F_OK) == 0)
{ {
l(LogLevel::warning, "Fifo file aready existing, trying to delete"); l(LogLevel::warning, "Fifo file aready existing, trying to delete");
if (unlink(FIFO_LOCATION) != 0) if (unlink(fifoLocation.c_str()) != 0)
{ {
fprintf(stderr, "Unable to delete Fifo file"); fprintf(stderr, "Unable to delete Fifo file");
goto out; goto out;
@ -35,42 +34,107 @@ int main(void)
umask(0); umask(0);
if (mkfifo(FIFO_LOCATION, 0770) != 0) if (mkfifo(fifoLocation.c_str(), 0770) != 0)
{ {
fprintf(stderr, "Unable to create Fifo"); fprintf(stderr, "Unable to create Fifo");
goto out; goto out;
} }
fifoHandle = open(FIFO_LOCATION, O_RDWR | O_NONBLOCK); handle = open(fifoLocation.c_str(), O_RDWR | O_NONBLOCK);
if (fifoHandle == -1) if (handle == -1)
{ {
fprintf(stderr, "Unable to open Fifo"); fprintf(stderr, "Unable to open Fifo");
goto out; goto out;
} }
if (fchown(fifoHandle, 0, 1001) != 0) if (fchown(handle, 0, 1001) != 0)
{ {
fprintf(stderr, "Fifo chown failed"); fprintf(stderr, "Fifo chown failed");
goto out1; close(handle);
handle = -1;
goto out;
} }
out:
return handle;
}
int closeFifo(int handle)
{
int retval = -1;
if (handle != -1)
{
close(handle);
}
l(LogLevel::debug, "Removing Fifo file");
if (unlink(FIFO_LOCATION) != 0)
{
l(LogLevel::error, "Unable to delete Fifo file");
retval = -1;
goto out;
}
retval = 0;
out:
return retval;
}
int main(int argc, char** argv)
{
int retval = -1;
int fifoHandle = -1;
std::chrono::seconds tokenTimeout;
try { try {
Logic &logic = Logic::get(); unsigned int timeout;
struct timeval tv; po::options_description desc("usage: doorlockd");
desc.add_options()
("help,h", "print help")
("tokentimeout,t", po::value<unsigned int>(&timeout)->required(), "tokentimeout in seconds");
po::variables_map vm;
po::store(po::command_line_parser(argc, argv).options(desc).run(), vm);
if (vm.count("help"))
{
std::cout << desc << std::endl;
retval = 0;
goto out;
}
po::notify(vm);
tokenTimeout = std::chrono::seconds(timeout>3 ? timeout-3 : timeout); // Epaper refresh takes ~3 seconds
}
catch(const std::exception &e)
{
std::cerr << "Error: " << e.what() << "\n";
goto out;
}
l(LogLevel::notice, "Starting doorlockd");
fifoHandle = createFifo(FIFO_LOCATION);
if (fifoHandle == -1)
{
goto out;
}
try {
Logic &logic = Logic::get(tokenTimeout);
fd_set set; fd_set set;
for (;;) for (;;)
{ {
FD_ZERO(&set); FD_ZERO(&set);
FD_SET(fifoHandle, &set); FD_SET(fifoHandle, &set);
tv.tv_sec = TOKEN_TIMEOUT;
tv.tv_usec = 0;
int i = select(fifoHandle+1, &set, nullptr, nullptr, &tv); int i = select(fifoHandle+1, &set, nullptr, nullptr, nullptr);
if (i == 0) if (i == 0)
{ {
logic.createNewToken(true);
continue; continue;
} else if (i == -1) { } else if (i == -1) {
throw "Fifo select() failed"; throw "Fifo select() failed";
@ -99,7 +163,7 @@ int main(void)
} }
} }
int rc = logic.parseRequest(payload); const auto rc = logic.parseRequest(payload);
} }
retval = 0; retval = 0;
@ -109,20 +173,13 @@ int main(void)
str << "FATAL ERROR: " << ex; str << "FATAL ERROR: " << ex;
l(str, LogLevel::error); l(str, LogLevel::error);
retval = -1; retval = -1;
goto out1;
} }
retval = 0;
out1: out1:
if (fifoHandle != -1) retval = closeFifo(fifoHandle);
{
close(fifoHandle);
}
l(LogLevel::debug, "Removing Fifo file");
if (unlink(FIFO_LOCATION) != 0)
{
throw("Unable to delete Fifo file");
}
out: out:
Door::get().lock(); Door::get().lock();
l(LogLevel::notice, "Doorlockd stopped"); l(LogLevel::notice, "Doorlockd stopped");