25 #include <sys/socket.h>
27 #include <netinet/in.h>
34 # include <sys/statvfs.h>
35 # include <sys/sysinfo.h>
37 # include <sys/param.h>
38 # include <sys/mount.h>
40 # include <sys/statfs.h>
41 # else // if !__CYGWIN__
42 # include <sys/sysctl.h>
43 # endif // !__CYGWIN__
47 static constexpr
int MSG_NOSIGNAL { 0 };
55 static inline void ADD_STR(std::string& list,
const std::string& s)
56 { list += s; list +=
"[]:[]"; };
57 static inline void ADD_INT(std::string& list,
int n)
58 { list += std::to_string(n); list +=
"[]:[]"; };
111 std::cout <<
"loading zm config from " << configfile << std::endl;
113 std::ifstream ifs(configfile);
116 fprintf(
stderr,
"Can't open %s\n", configfile.c_str());
120 while ( std::getline(ifs, line) )
123 constexpr
const char *whitespace =
" \t\r\n";
124 auto begin = line.find_first_not_of(whitespace);
125 if (begin == std::string::npos)
127 auto end = line.find_last_not_of(whitespace);
128 if (end != std::string::npos)
130 line = line.substr(begin, end);
133 if ( line.empty() || line[0] ==
'#' )
137 auto index = line.find(
'=');
138 if (index == std::string::npos)
140 fprintf(
stderr,
"Invalid data in %s: '%s'\n", configfile.c_str(), line.c_str() );
145 std::string name = line.substr(0,index);
146 std::string val = line.substr(index+1);
149 end = name.find_last_not_of(whitespace);
150 if (end != std::string::npos)
152 name = name.substr(0, end);
155 begin = val.find_first_not_of(whitespace);
156 if (begin != std::string::npos)
157 val = val.substr(begin);
160 std::transform(name.cbegin(), name.cend(), name.begin(), ::toupper);
162 if ( name ==
"ZM_DB_HOST" )
g_server = val;
163 else if ( name ==
"ZM_DB_NAME" )
g_database = val;
164 else if ( name ==
"ZM_DB_USER" )
g_user = val;
165 else if ( name ==
"ZM_DB_PASS" )
g_password = val;
166 else if ( name ==
"ZM_PATH_WEB" )
g_webPath = val;
167 else if ( name ==
"ZM_PATH_BIN" )
g_binPath = val;
168 else if ( name ==
"ZM_WEB_USER" )
g_webUser = val;
169 else if ( name ==
"ZM_VERSION" )
g_zmversion = val;
170 else if ( name ==
"ZM_PATH_MAP" )
g_mmapPath = val;
175 #if !defined(MARIADB_BASE_VERSION) && MYSQL_VERSION_ID >= 80000
185 std::cout <<
"Error: Can't initialise structure: " << mysql_error(&
g_dbConn) << std::endl;
186 exit(
static_cast<int>(mysql_errno(&
g_dbConn)));
190 mysql_options(&
g_dbConn, MYSQL_OPT_RECONNECT, &reconnect);
195 std::cout <<
"Error: Can't connect to server: " << mysql_error(&
g_dbConn) << std::endl;
196 exit(
static_cast<int>(mysql_errno( &
g_dbConn)));
201 std::cout <<
"Error: Can't select database: " << mysql_error(&
g_dbConn) << std::endl;
202 exit(
static_cast<int>(mysql_errno(&
g_dbConn)));
212 std::cout <<
"Kicking database connection" << std::endl;
216 if (mysql_query(&
g_dbConn,
"SELECT NULL;") == 0)
218 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
220 mysql_free_result(res);
224 std::cout <<
"Lost connection to DB - trying to reconnect" << std::endl;
235 size_t shared_data_size = 0;
270 #if _POSIX_MAPPED_FILES > 0L
275 std::stringstream mmap_filename;
276 mmap_filename << mmapPath <<
"/zm.mmap." <<
m_monId;
278 m_mapFile = open(mmap_filename.str().c_str(), O_RDONLY, 0
x0);
282 std::cout <<
"Opened mmap file: " << mmap_filename.str() << std::endl;
284 m_shmPtr = mmap(
nullptr, shared_data_size, PROT_READ,
288 std::cout <<
"Failed to map shared memory from file ["
289 << mmap_filename.str() <<
"] " <<
"for monitor: "
294 std::cout <<
"Failed to close mmap file" << std::endl;
308 std::cout <<
"Failed to open mmap file [" << mmap_filename.str() <<
"] "
310 <<
" : " << strerror(errno) << std::endl;
311 std::cout <<
"Falling back to the legacy shared memory method" << std::endl;
319 int shmid = shmget((shmKey & 0xffff0000) |
m_monId,
320 shared_data_size, SHM_R);
323 std::cout <<
"Failed to shmget for monitor: " <<
m_monId << std::endl;
327 case EACCES: std::cout <<
"EACCES - no rights to access segment\n";
break;
328 case EEXIST: std::cout <<
"EEXIST - segment already exists\n";
break;
329 case EINVAL: std::cout <<
"EINVAL - size < SHMMIN or size > SHMMAX\n";
break;
330 case ENFILE: std::cout <<
"ENFILE - limit on open files has been reached\n";
break;
331 case ENOENT: std::cout <<
"ENOENT - no segment exists for the given key\n";
break;
332 case ENOMEM: std::cout <<
"ENOMEM - couldn't reserve memory for segment\n";
break;
333 case ENOSPC: std::cout <<
"ENOSPC - shmmni or shmall limit reached\n";
break;
339 m_shmPtr = shmat(shmid,
nullptr, SHM_RDONLY);
344 std::cout <<
"Failed to shmat for monitor: " <<
m_monId << std::endl;
434 std::stringstream out;
527 if (!setting.empty())
530 sscanf(setting.c_str(),
"%20llx", &
tmp);
536 std::cout <<
"Shared memory key is: 0x"
537 << std::hex << (
unsigned int)
m_shmKey
538 << std::dec << std::endl;
549 std::cout <<
"Memory path directory is: " <<
m_mmapPath << std::endl;
554 int eventDigits = atoi(setting.c_str());
555 std::string eventDigitsFmt =
"%0" + std::to_string(eventDigits) +
"d";
570 std::cout <<
"using deep storage directory structure" << std::endl;
572 std::cout <<
"using flat directory structure" << std::endl;
580 std::cout <<
"using analysis images" << std::endl;
582 std::cout <<
"not using analysis images" << std::endl;
592 if (mon->m_mapFile != -1)
594 if (
close(mon->m_mapFile) == -1)
595 std::cout <<
"Failed to close mapFile" << std::endl;
598 std::cout <<
"Closed mapFile for monitor: " << mon->m_name << std::endl;
608 std::cout <<
"ZMServer destroyed\n";
615 std::string::size_type startPos = 0;
616 std::string::size_type endPos = 0;
618 while((endPos = command.find(
"[]:[]", startPos)) != std::string::npos)
620 token = command.substr(startPos, endPos - startPos);
621 tokens.push_back(token);
622 startPos = endPos + 5;
626 if (endPos != command.length())
628 token = command.substr(startPos);
629 tokens.push_back(token);
641 int dataLen = atoi(len);
645 std::string s(buf+8);
646 std::vector<std::string> tokens;
653 std::cout <<
"Processing: '" << tokens[0] <<
"'" << std::endl;
655 if (tokens[0] ==
"HELLO")
657 else if (tokens[0] ==
"QUIT")
659 else if (tokens[0] ==
"GET_SERVER_STATUS")
661 else if (tokens[0] ==
"GET_MONITOR_STATUS")
663 else if (tokens[0] ==
"GET_ALARM_STATES")
665 else if (tokens[0] ==
"GET_EVENT_LIST")
667 else if (tokens[0] ==
"GET_EVENT_DATES")
669 else if (tokens[0] ==
"GET_EVENT_FRAME")
671 else if (tokens[0] ==
"GET_ANALYSE_FRAME")
673 else if (tokens[0] ==
"GET_LIVE_FRAME")
675 else if (tokens[0] ==
"GET_FRAME_LIST")
677 else if (tokens[0] ==
"GET_CAMERA_LIST")
679 else if (tokens[0] ==
"GET_MONITOR_LIST")
681 else if (tokens[0] ==
"DELETE_EVENT")
683 else if (tokens[0] ==
"DELETE_EVENT_LIST")
685 else if (tokens[0] ==
"RUN_ZMAUDIT")
687 else if (tokens[0] ==
"SET_MONITOR_FUNCTION")
690 send(
"UNKNOWN_COMMAND");
698 std::string str =
"0000000" + std::to_string(s.size());
699 str.erase(0, str.size()-8);
700 int status =
::send(
m_sock, str.data(), 8, MSG_NOSIGNAL);
705 status =
::send(
m_sock, s.c_str(), s.size(), MSG_NOSIGNAL);
709 bool ZMServer::send(
const std::string &s,
const unsigned char *buffer,
int dataLen)
const
712 std::string str =
"0000000" + std::to_string(s.size());
713 str.erase(0, str.size()-8);
714 int status =
::send(
m_sock, str.data(), 8, MSG_NOSIGNAL);
719 status =
::send(
m_sock, s.c_str(), s.size(), MSG_NOSIGNAL);
748 long long freespace = -1;
766 freespace = freespace >> 10;
768 used = total - freespace;
784 std::array<double,3> loads {};
792 std::string buf = std::to_string(loads[0]);
793 buf.resize(buf.size() - 4);
800 std::string eventsDir =
g_webPath +
"/events/";
802 std::string buf = std::to_string(
static_cast<int>((used * 100) / total)) +
"%";
819 ADD_INT(outStr, monitor->m_monId);
822 ADD_INT(outStr, monitor->getState());
832 if (tokens.size() != 5)
838 const std::string& monitor = tokens[1];
839 bool oldestFirst = (tokens[2] ==
"1");
840 const std::string& date = tokens[3];
841 bool includeContinuous = (tokens[4] ==
"1");
844 std::cout <<
"Loading events for monitor: " << monitor <<
", date: " << date << std::endl;
848 std::string sql(
"SELECT E.Id, E.Name, M.Id AS MonitorID, M.Name AS MonitorName, E.StartTime, "
849 "E.Length, M.Width, M.Height, M.DefaultRate, M.DefaultScale "
850 "from Events as E inner join Monitors as M on E.MonitorId = M.Id ");
852 if (monitor !=
"<ANY>")
854 sql +=
"WHERE M.Name = '" + monitor +
"' ";
857 sql +=
"AND DATE(E.StartTime) = DATE('" + date +
"') ";
863 sql +=
"WHERE DATE(E.StartTime) = DATE('" + date +
"') ";
865 if (!includeContinuous)
866 sql +=
"AND Cause != 'Continuous' ";
869 if (!includeContinuous)
871 sql +=
"WHERE Cause != 'Continuous' ";
876 sql +=
"ORDER BY E.StartTime ASC";
878 sql +=
"ORDER BY E.StartTime DESC";
880 if (mysql_query(&
g_dbConn, sql.c_str()))
887 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
888 int eventCount = mysql_num_rows(res);
891 std::cout <<
"Got " << eventCount <<
" events" << std::endl;
895 for (
int x = 0; x < eventCount; x++)
897 MYSQL_ROW row = mysql_fetch_row(res);
910 std::cout <<
"Failed to get mysql row" << std::endl;
916 mysql_free_result(res);
925 if (tokens.size() != 3)
931 const std::string& monitor = tokens[1];
932 bool oldestFirst = (tokens[2] ==
"1");
935 std::cout <<
"Loading event dates for monitor: " << monitor << std::endl;
939 std::string sql(
"SELECT DISTINCT DATE(E.StartTime) "
940 "from Events as E inner join Monitors as M on E.MonitorId = M.Id ");
942 if (monitor !=
"<ANY>")
943 sql +=
"WHERE M.Name = '" + monitor +
"' ";
946 sql +=
"ORDER BY E.StartTime ASC";
948 sql +=
"ORDER BY E.StartTime DESC";
950 if (mysql_query(&
g_dbConn, sql.c_str()))
957 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
958 int dateCount = mysql_num_rows(res);
961 std::cout <<
"Got " << dateCount <<
" dates" << std::endl;
965 for (
int x = 0; x < dateCount; x++)
967 MYSQL_ROW row = mysql_fetch_row(res);
974 std::cout <<
"Failed to get mysql row" << std::endl;
980 mysql_free_result(res);
992 std::string sql(
"SELECT Id, Name, Type, Device, Host, Channel, `Function`, Enabled "
994 if (mysql_query(&
g_dbConn, sql.c_str()))
1001 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
1004 int monitorCount = mysql_num_rows(res);
1007 std::cout <<
"Got " << monitorCount <<
" monitors" << std::endl;
1009 ADD_INT(outStr, monitorCount);
1011 for (
int x = 0; x < monitorCount; x++)
1013 MYSQL_ROW row = mysql_fetch_row(res);
1016 std::string
id = row[0];
1017 std::string
type = row[2];
1018 std::string device = row[3];
1019 std::string host = row[4] ? row[4] :
"";
1020 std::string channel = row[5];
1021 std::string
function = row[6];
1022 std::string enabled = row[7];
1023 std::string name = row[1];
1025 std::string zmcStatus;
1026 std::string zmaStatus;
1028 zmcStatus, zmaStatus, enabled);
1030 std::string sql2(
"SELECT count(if(Archived=0,1,NULL)) AS EventCount "
1032 "WHERE MonitorId = " +
id);
1034 if (mysql_query(&
g_dbConn, sql2.c_str()))
1041 MYSQL_RES *res2 = mysql_store_result(&
g_dbConn);
1042 if (mysql_num_rows(res2) > 0)
1044 MYSQL_ROW row2 = mysql_fetch_row(res2);
1049 std::cout <<
"Failed to get mysql row" << std::endl;
1063 mysql_free_result(res2);
1067 std::cout <<
"Failed to get mysql row" << std::endl;
1073 mysql_free_result(res);
1081 FILE *fd = popen(command.c_str(),
"r");
1082 std::array<char,100> buffer {};
1084 while (fgets(buffer.data(), buffer.size(), fd) !=
nullptr)
1086 outStr += buffer.data();
1093 const std::string &device,
const std::string &host,
1094 const std::string &channel,
const std::string &
function,
1095 std::string &zmcStatus, std::string &zmaStatus,
1096 const std::string &enabled)
1101 std::string command(
g_binPath +
"/zmdc.pl status");
1104 if (
type ==
"Local")
1107 zmaStatus = device +
"(" + channel +
") [-]";
1108 else if (status.find(
"'zma -m " +
id +
"' running") != std::string::npos)
1109 zmaStatus = device +
"(" + channel +
") [R]";
1111 zmaStatus = device +
"(" + channel +
") [S]";
1116 zmaStatus = host +
" [-]";
1117 else if (status.find(
"'zma -m " +
id +
"' running") != std::string::npos)
1118 zmaStatus = host +
" [R]";
1120 zmaStatus = host +
" [S]";
1123 if (
type ==
"Local")
1126 zmcStatus =
function +
" [-]";
1127 else if (status.find(
"'zmc -d "+ device +
"' running") != std::string::npos)
1128 zmcStatus =
function +
" [R]";
1130 zmcStatus =
function +
" [S]";
1135 zmcStatus =
function +
" [-]";
1136 else if (status.find(
"'zmc -m " +
id +
"' running") != std::string::npos)
1137 zmcStatus =
function +
" [R]";
1139 zmcStatus =
function +
" [S]";
1147 if (tokens.size() != 5)
1153 const std::string& monitorID(tokens[1]);
1154 const std::string& eventID(tokens[2]);
1155 int frameNo = atoi(tokens[3].c_str());
1156 const std::string& eventTime(tokens[4]);
1160 std::cout <<
"Getting frame " << frameNo <<
" for event " << eventID
1161 <<
" on monitor " << monitorID <<
" event time is " << eventTime
1170 std::string filepath;
1171 std::string str (100,
'\0');
1179 sscanf(eventTime.data(),
"%2d/%2d/%2d", &year, &month, &day);
1180 sprintf(str.data(),
"20%02d-%02d-%02d", year, month, day);
1182 filepath =
g_eventsPath +
"/" + monitorID +
"/" + str +
"/" + eventID +
"/";
1190 filepath =
g_webPath +
"/events/" + monitorID +
"/" + eventTime +
"/";
1196 filepath =
g_webPath +
"/events/" + monitorID +
"/" + eventID +
"/";
1203 FILE *fd = fopen(filepath.c_str(),
"r" );
1206 fileSize = fread(s_buffer.data(), 1, s_buffer.size(), fd);
1211 std::cout <<
"Can't open " << filepath <<
": " << strerror(errno) << std::endl;
1217 std::cout <<
"Frame size: " << fileSize << std::endl;
1223 send(outStr, s_buffer.data(), fileSize);
1229 std::array<char,100> str {};
1231 if (tokens.size() != 5)
1237 const std::string& monitorID(tokens[1]);
1238 const std::string& eventID(tokens[2]);
1239 int frameNo = atoi(tokens[3].c_str());
1240 const std::string& eventTime(tokens[4]);
1246 std::cout <<
"Getting analysis frame " << frameNo <<
" for event " << eventID
1247 <<
" on monitor " << monitorID <<
" event time is " << eventTime
1253 sql +=
"SELECT FrameId FROM Frames ";
1254 sql +=
"WHERE EventID = " + eventID +
" ";
1255 sql +=
"AND Type = 'Alarm' ";
1256 sql +=
"ORDER BY FrameID";
1258 if (mysql_query(&
g_dbConn, sql.c_str()))
1265 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
1266 frameCount = mysql_num_rows(res);
1269 if (frameCount == 0)
1271 mysql_free_result(res);
1273 sql =
"SELECT FrameId FROM Frames ";
1274 sql +=
"WHERE EventID = " + eventID +
" ";
1275 sql +=
"ORDER BY FrameID";
1277 if (mysql_query(&
g_dbConn, sql.c_str()))
1284 res = mysql_store_result(&
g_dbConn);
1285 frameCount = mysql_num_rows(res);
1289 if (frameCount == 0)
1291 std::cout <<
"handleGetAnalyseFrame: Failed to find any frames" << std::endl;
1297 if (frameNo == 0 || frameNo < 0 || frameNo > frameCount)
1298 frameNo = (frameCount / 2) + 1;
1301 MYSQL_ROW row =
nullptr;
1302 for (
int x = 0; x < frameNo; x++)
1304 row = mysql_fetch_row(res);
1309 frameID = atoi(row[0]);
1313 std::cout <<
"handleGetAnalyseFrame: Failed to get mysql row for frameNo " << frameNo << std::endl;
1318 mysql_free_result(res);
1321 std::string filepath;
1322 std::string frameFile;
1330 sscanf(eventTime.c_str(),
"%2d/%2d/%2d", &year, &month, &day);
1331 sprintf(str.data(),
"20%02d-%02d-%02d", year, month, day);
1332 filepath =
g_eventsPath +
"/" + monitorID +
"/" + str.data() +
"/" + eventID +
"/";
1337 filepath =
g_webPath +
"/events/" + monitorID +
"/" + eventTime +
"/";
1339 filepath =
g_webPath +
"/events/" + monitorID +
"/" + eventID +
"/";
1351 frameFile = filepath + str.data();
1353 fd = fopen(frameFile.c_str(),
"r" );
1356 fileSize = fread(s_buffer.data(), 1, s_buffer.size(), fd);
1360 std::cout <<
"Frame size: " << fileSize << std::endl;
1366 send(outStr, s_buffer.data(), fileSize);
1373 frameFile = filepath + str.data();
1375 fd = fopen(frameFile.c_str(),
"r" );
1378 fileSize = fread(s_buffer.data(), 1, s_buffer.size(), fd);
1383 std::cout <<
"Can't open " << frameFile <<
": " << strerror(errno) << std::endl;
1389 std::cout <<
"Frame size: " << fileSize << std::endl;
1395 send(outStr, s_buffer.data(), fileSize);
1408 if (tokens.size() != 2)
1414 int monitorID = atoi(tokens[1].c_str());
1417 std::cout <<
"Getting live frame from monitor: " << monitorID << std::endl;
1442 int dataSize =
getFrame(s_buffer, monitor);
1445 std::cout <<
"Frame size: " << dataSize << std::endl;
1451 ADD_STR(outStr,
"WARNING - No new frame available");
1463 send(outStr, s_buffer.data(), dataSize);
1468 std::string eventID;
1471 if (tokens.size() != 2)
1477 eventID = tokens[1];
1480 std::cout <<
"Loading frames for event: " << eventID << std::endl;
1485 std::string sql =
"SELECT Cause, Length, Frames FROM Events ";
1486 sql +=
"WHERE Id = " + eventID +
" ";
1488 if (mysql_query(&
g_dbConn, sql.c_str()))
1495 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
1496 MYSQL_ROW row = mysql_fetch_row(res);
1499 if (row[1] ==
nullptr || row[2] ==
nullptr)
1505 std::string cause = row[0];
1506 double length = atof(row[1]);
1507 int frameCount = atoi(row[2]);
1509 mysql_free_result(res);
1511 if (cause ==
"Continuous")
1516 std::cout <<
"Got " << frameCount <<
" frames (continuous event)" << std::endl;
1522 double delta = length / frameCount;
1524 for (
int x = 0; x < frameCount; x++)
1527 ADD_STR(outStr, std::to_string(delta));
1533 sql =
"SELECT Type, Delta FROM Frames ";
1534 sql +=
"WHERE EventID = " + eventID +
" ";
1535 sql +=
"ORDER BY FrameID";
1537 if (mysql_query(&
g_dbConn, sql.c_str()))
1544 res = mysql_store_result(&
g_dbConn);
1545 frameCount = mysql_num_rows(res);
1548 std::cout <<
"Got " << frameCount <<
" frames" << std::endl;
1552 for (
int x = 0; x < frameCount; x++)
1554 row = mysql_fetch_row(res);
1562 std::cout <<
"handleGetFrameList: Failed to get mysql row " << x << std::endl;
1568 mysql_free_result(res);
1584 ADD_STR(outStr, monitor->m_name);
1597 std::cout <<
"We have " <<
m_monitors.size() <<
" monitors" << std::endl;
1603 ADD_INT(outStr, mon->m_monId);
1605 ADD_INT(outStr, mon->m_width);
1606 ADD_INT(outStr, mon->m_height);
1607 ADD_INT(outStr, mon->m_bytesPerPixel);
1611 std::cout <<
"id: " << mon->m_monId << std::endl;
1612 std::cout <<
"name: " << mon->m_name << std::endl;
1613 std::cout <<
"width: " << mon->m_width << std::endl;
1614 std::cout <<
"height: " << mon->m_height << std::endl;
1615 std::cout <<
"palette: " << mon->m_palette << std::endl;
1616 std::cout <<
"byte per pixel: " << mon->m_bytesPerPixel << std::endl;
1617 std::cout <<
"sub pixel order:" << mon->getSubpixelOrder() << std::endl;
1618 std::cout <<
"-------------------" << std::endl;
1627 std::string eventID;
1630 if (tokens.size() != 2)
1636 eventID = tokens[1];
1639 std::cout <<
"Deleting event: " << eventID << std::endl;
1644 sql +=
"DELETE FROM Events WHERE Id = " + eventID;
1646 if (mysql_query(&
g_dbConn, sql.c_str()))
1654 std::string command(
g_binPath +
"/zmaudit.pl &");
1656 if (system(command.c_str()) < 0 && errno)
1657 std::cerr <<
"Failed to run '" << command <<
"'" << std::endl;
1664 std::string eventList;
1667 auto it = tokens.begin();
1668 if (it != tokens.end())
1670 while (it != tokens.end())
1672 if (eventList.empty())
1675 eventList +=
"," + (*it);
1681 std::cout <<
"Deleting events: " << eventList << std::endl;
1684 sql +=
"DELETE FROM Events WHERE Id IN (" + eventList +
")";
1686 if (mysql_query(&
g_dbConn, sql.c_str()))
1702 std::string command(
g_binPath +
"/zmaudit.pl &");
1705 std::cout <<
"Running command: " << command << std::endl;
1708 if (system(command.c_str()) < 0 && errno)
1709 std::cerr <<
"Failed to run '" << command <<
"'" << std::endl;
1721 std::string sql(
"SELECT Id, Name, Width, Height, ImageBufferCount, MaxFPS, Palette, ");
1722 sql +=
" Type, `Function`, Enabled, Device, Host, Controllable, TrackMotion";
1727 sql +=
" FROM Monitors";
1728 sql +=
" ORDER BY Sequence";
1730 if (mysql_query(&
g_dbConn, sql.c_str()))
1736 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
1737 int monitorCount = mysql_num_rows(res);
1740 std::cout <<
"Got " << monitorCount <<
" monitors" << std::endl;
1742 for (
int x = 0; x < monitorCount; x++)
1744 MYSQL_ROW row = mysql_fetch_row(res);
1750 m->m_width = atoi(row[2]);
1751 m->m_height = atoi(row[3]);
1752 m->m_imageBufferCount = atoi(row[4]);
1753 m->m_palette = atoi(row[6]);
1755 m->m_function = row[8];
1756 m->m_enabled = atoi(row[9]);
1757 m->m_device = row[10];
1758 m->m_host = row[11] ? row[11] :
"";
1759 m->m_controllable = atoi(row[12]);
1760 m->m_trackMotion = atoi(row[13]);
1765 m->m_bytesPerPixel = atoi(row[14]);
1767 if (m->m_palette == 1)
1768 m->m_bytesPerPixel = 1;
1770 m->m_bytesPerPixel = 3;
1779 std::cout <<
"Failed to get mysql row" << std::endl;
1784 mysql_free_result(res);
1828 unsigned int rpos = 0;
1829 unsigned int wpos = 0;
1835 for (wpos = 0, rpos = 0; wpos < (
unsigned int) (monitor->
m_width * monitor->
m_height * 3); wpos += 3, rpos += 1)
1837 buffer[wpos + 0] = data[rpos + 0];
1838 buffer[wpos + 1] = data[rpos + 0];
1839 buffer[wpos + 2] = data[rpos + 0];
1847 for (wpos = 0, rpos = 0; wpos < (
unsigned int) (monitor->
m_width * monitor->
m_height * 3); wpos += 3, rpos += 3)
1849 buffer[wpos + 0] = data[rpos + 0];
1850 buffer[wpos + 1] = data[rpos + 1];
1851 buffer[wpos + 2] = data[rpos + 2];
1859 for (wpos = 0, rpos = 0; wpos < (
unsigned int) (monitor->
m_width * monitor->
m_height * 3); wpos += 3, rpos += 3)
1861 buffer[wpos + 0] = data[rpos + 2];
1862 buffer[wpos + 1] = data[rpos + 1];
1863 buffer[wpos + 2] = data[rpos + 0];
1870 for (wpos = 0, rpos = 0; wpos < (
unsigned int) (monitor->
m_width * monitor->
m_height * 3); wpos += 3, rpos += 4)
1872 buffer[wpos + 0] = data[rpos + 2];
1873 buffer[wpos + 1] = data[rpos + 1];
1874 buffer[wpos + 2] = data[rpos + 0];
1882 for (wpos = 0, rpos = 0; wpos < (
unsigned int) (monitor->
m_width * monitor->
m_height * 3 ); wpos += 3, rpos += 4)
1884 buffer[wpos + 0] = data[rpos + 0];
1885 buffer[wpos + 1] = data[rpos + 1];
1886 buffer[wpos + 2] = data[rpos + 2];
1894 for (wpos = 0, rpos = 0; wpos < (
unsigned int) (monitor->
m_width * monitor->
m_height * 3); wpos += 3, rpos += 4)
1896 buffer[wpos + 0] = data[rpos + 3];
1897 buffer[wpos + 1] = data[rpos + 2];
1898 buffer[wpos + 2] = data[rpos + 1];
1906 for (wpos = 0, rpos = 0; wpos < (
unsigned int) (monitor->
m_width * monitor->
m_height * 3); wpos += 3, rpos += 4)
1908 buffer[wpos + 0] = data[rpos + 1];
1909 buffer[wpos + 1] = data[rpos + 2];
1910 buffer[wpos + 2] = data[rpos + 3];
1923 std::string sql(
"SELECT Name, Value FROM Config ");
1924 sql +=
"WHERE Name = '" + setting +
"'";
1926 if (mysql_query(&
g_dbConn, sql.c_str()))
1932 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
1933 MYSQL_ROW row = mysql_fetch_row(res);
1940 std::cout <<
"Failed to get mysql row" << std::endl;
1945 std::cout <<
"getZMSetting: " << setting <<
" Result: " << result << std::endl;
1947 mysql_free_result(res);
1956 if (tokens.size() != 4)
1962 const std::string& monitorID(tokens[1]);
1963 const std::string&
function(tokens[2]);
1964 const std::string& enabled(tokens[3]);
1981 if (enabled !=
"0" && enabled !=
"1")
1988 std::cout <<
"User input validated OK" << std::endl;
1993 std::string oldFunction = monitor->
m_function;
1994 const std::string& newFunction =
function;
1996 int newEnabled = atoi(enabled.c_str());
2002 std::cout <<
"SetMonitorFunction MonitorId: " << monitorID << std::endl
2003 <<
" oldEnabled: " << oldEnabled << std::endl
2004 <<
" newEnabled: " << newEnabled << std::endl
2005 <<
" oldFunction: " << oldFunction << std::endl
2006 <<
" newFunction: " << newFunction << std::endl;
2009 if ( newFunction != oldFunction || newEnabled != oldEnabled)
2011 std::string sql(
"UPDATE Monitors ");
2012 sql +=
"SET Function = '" +
function +
"', ";
2013 sql +=
"Enabled = '" + enabled +
"' ";
2014 sql +=
"WHERE Id = '" + monitorID +
"'";
2016 if (mysql_query(&
g_dbConn, sql.c_str()))
2024 std::cout <<
"Monitor function SQL update OK" << std::endl;
2032 std::cout <<
"Monitor function Refreshing daemons" << std::endl;
2036 (newEnabled != oldEnabled);
2047 std::cout <<
"zm daemons are not running" << std::endl;
2052 std::cout <<
"Not updating monitor function as identical to existing configuration" << std::endl;
2061 std::string zmcArgs;
2063 sql +=
"SELECT count(if(Function!='None',1,NULL)) as ActiveCount ";
2064 sql +=
"FROM Monitors ";
2066 if (monitor->
m_type ==
"Local" )
2068 sql +=
"WHERE Device = '" + monitor->
m_device +
"'";
2069 zmcArgs =
"-d " + monitor->
m_device;
2073 sql +=
"WHERE Id = '" + monitor->
getIdStr() +
"'";
2074 zmcArgs =
"-m " + monitor->
getIdStr();
2077 if (mysql_query(&
g_dbConn, sql.c_str()))
2084 MYSQL_RES *res = mysql_store_result(&
g_dbConn);
2085 MYSQL_ROW row = mysql_fetch_row(res);
2091 int activeCount = atoi(row[0]);
2106 int zmOptControl = atoi(
getZMSetting(
"ZM_OPT_CONTROL").c_str());
2107 int zmOptFrameServer = atoi(
getZMSetting(
"ZM_OPT_FRAME_SERVER").c_str());
2121 if (zmOptFrameServer)
2125 if (zmOptFrameServer)
2144 if (zmOptFrameServer)