117 lines
2.7 KiB
C++
117 lines
2.7 KiB
C++
#include <iostream>
|
|
#include <string.h>
|
|
#include <libnotify/notify.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include "Socket.h"
|
|
#include "argpopt.h"
|
|
|
|
void sigHandler(int sig)
|
|
{
|
|
exit(0);
|
|
}
|
|
|
|
bool showMessage(const std::string& title, const std::string& body = "")
|
|
{
|
|
NotifyNotification* message = notify_notification_new (title.c_str(), body.c_str(), nullptr);
|
|
bool ret = notify_notification_show (message, NULL);
|
|
g_object_unref(G_OBJECT(message));
|
|
return ret;
|
|
}
|
|
|
|
void processLineBuffer(std::string& buffer)
|
|
{
|
|
if(buffer.find("bcst:") == 0) buffer.erase(0, 6);
|
|
if(buffer.size() > 5 && buffer.find("MESG") == 0)
|
|
{
|
|
size_t titleEnd = buffer.size();
|
|
size_t bodyBegin = buffer.find("BODY");
|
|
if(bodyBegin != std::string::npos && bodyBegin > 5)
|
|
{
|
|
titleEnd = bodyBegin - 1;
|
|
}
|
|
|
|
const std::string body = (bodyBegin == std::string::npos && buffer.begin()+bodyBegin+5 < buffer.end()) ?
|
|
"" : std::string(buffer.begin()+bodyBegin+5, buffer.end());
|
|
|
|
const std::string title(buffer.begin()+5, buffer.begin()+titleEnd);
|
|
showMessage(title, body);
|
|
}
|
|
|
|
}
|
|
|
|
static TCPSocket* socket = nullptr;
|
|
|
|
void exitHandler()
|
|
{
|
|
notify_uninit();
|
|
if(socket)delete socket;
|
|
}
|
|
|
|
bool reconnect(std::string host, unsigned short port)
|
|
{
|
|
try
|
|
{
|
|
if(socket)delete socket;
|
|
socket = new TCPSocket(host, port);
|
|
}
|
|
catch(SocketException &e)
|
|
{
|
|
std::cerr<<e.what()<<std::endl;
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int main(int argc, char* argv[])
|
|
{
|
|
Config config;
|
|
|
|
notify_init("Message");
|
|
|
|
if( atexit(exitHandler) != 0 )
|
|
{
|
|
std::cerr<<"can not register atexit handler\n";
|
|
return -1;
|
|
}
|
|
argp_parse(&argp, argc, argv, 0, 0, &config);
|
|
|
|
std::cout<<argp_program_version<<std::endl;
|
|
|
|
std::string lineBuffer;
|
|
|
|
signal(SIGINT, sigHandler);
|
|
signal(SIGTERM, sigHandler);
|
|
char buffer[256];
|
|
|
|
if(!reconnect(config.hostName, config.port)) return 1;
|
|
|
|
while(true)
|
|
{
|
|
int len = socket->recv(buffer, sizeof(buffer));
|
|
if(len <= 0)
|
|
{
|
|
std::cerr<<"socket error\n";
|
|
int i = 0;
|
|
for(; i < 30 && reconnect(config.hostName, config.port) == false; ++i) sleep(10);
|
|
if(i >= 10)
|
|
{
|
|
std::cerr<<"reconnect failed\n";
|
|
return 1;
|
|
}
|
|
}
|
|
for(int i = 0; i<len; ++i)
|
|
{
|
|
if(buffer[i] != '\n') lineBuffer.push_back(buffer[i]);
|
|
else
|
|
{
|
|
processLineBuffer(lineBuffer);
|
|
lineBuffer.clear();
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|