diff --git a/CastIt.vcxproj b/CastIt.vcxproj
index 84f5f10..acd95ab 100644
--- a/CastIt.vcxproj
+++ b/CastIt.vcxproj
@@ -97,7 +97,7 @@
Level3
true
ProgramDatabase
- $(ProjectDir);libxml2-2.4.9/include;curl/include;%(AdditionalIncludeDirectories)
+ $(ProjectDir);curl/include;%(AdditionalIncludeDirectories)
WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
.\Debug\
true
@@ -128,7 +128,7 @@
Windows
.\Debug\CastIt.exe
%(AdditionalLibraryDirectories)
- curl/lib/curlstatic.lib;libxml2-2.4.9/win32/libxml2/libxml2_a/libxml2.lib;ws2_32.lib;%(AdditionalDependencies)
+ curl/lib/curlstatic.lib;ws2_32.lib;msxml6.lib;%(AdditionalDependencies)
@@ -142,7 +142,7 @@
MaxSpeed
true
Level3
- $(ProjectDir);libxml2-2.4.9/include;curl/include;%(AdditionalIncludeDirectories)
+ $(ProjectDir);curl/include;%(AdditionalIncludeDirectories)
WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
.\Release\
true
@@ -170,7 +170,7 @@
Windows
.\Release\CastIt.exe
%(AdditionalLibraryDirectories)
- curl/lib/curlstatic.lib;libxml2-2.4.9/win32/libxml2/libxml2_a/libxml2.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;%(AdditionalDependencies)
+ curl/lib/curlstatic.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;msxml6.lib;%(AdditionalDependencies)
@@ -185,7 +185,7 @@
Level3
true
ProgramDatabase
- $(ProjectDir);libxml2-2.4.9/include;curl/include;%(AdditionalIncludeDirectories)
+ $(ProjectDir);curl/include;%(AdditionalIncludeDirectories)
WIN32;_DEBUG;_WINDOWS;%(PreprocessorDefinitions)
.\x64\Debug\
true
@@ -216,7 +216,7 @@
Windows
.\x64\Debug\CastIt.exe
%(AdditionalLibraryDirectories)
- curl/lib/curlstatic.lib;libxml2-2.4.9/win32/libxml2/libxml2_a/libxml2.lib;ws2_32.lib;%(AdditionalDependencies)
+ curl/lib/curlstatic.lib;ws2_32.lib;msxml6.lib;%(AdditionalDependencies)
@@ -230,7 +230,7 @@
MaxSpeed
true
Level3
- $(ProjectDir);libxml2-2.4.9/include;curl/include;%(AdditionalIncludeDirectories)
+ $(ProjectDir);curl/include;%(AdditionalIncludeDirectories)
WIN32;NDEBUG;_WINDOWS;%(PreprocessorDefinitions)
.\x64\Release\
true
@@ -258,7 +258,7 @@
Windows
.\x64\Release\CastIt.exe
%(AdditionalLibraryDirectories)
- curl/lib/curlstatic.lib;libxml2-2.4.9/win32/libxml2/libxml2_a/libxml2.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;%(AdditionalDependencies)
+ curl/lib/curlstatic.lib;ws2_32.lib;kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;wsock32.lib;msxml6.lib;%(AdditionalDependencies)
diff --git a/README.md b/README.md
index 61fd304..6c0346d 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@ Studio 2022._
2. Rebuild in Visual Studio 2022 for x86/x64 targets
3. Update dependency paths for:
- `libcurl`
- - `libxml2`
+ - `MSXML`
- `mysqlclient`
4. Restore and modernize installer pipeline
5. Tag a 2025 re-release binary
diff --git a/scastd.cpp b/scastd.cpp
index 77a1eb7..a709011 100644
--- a/scastd.cpp
+++ b/scastd.cpp
@@ -2,7 +2,8 @@
#include
#include
#include
-#include
+#include
+#include
#include
#include
#include
@@ -15,9 +16,6 @@
#include
#include
#endif
-#include "libxml2/include/libxml2/libxml/nanohttp.h"
-#include "libxml2/include/libxml2/libxml/tree.h"
-#include "libxml2/include/libxml2/libxml/parser.h"
#include
#include
@@ -82,15 +80,6 @@ CString URLizeint(int data)
return tempString;
}
-void parseWebdata(xmlNodePtr cur)
-{
-
- while (cur != NULL) {
- fprintf(stdout, "Webdata: %s\n", cur->name);
- cur = cur->next;
- }
-
-}
void replaceQuote(char *buf) {
for (char *p1 = buf;p1 < buf+strlen(buf); p1++) {
if (*p1 == '\'') {
@@ -151,32 +140,195 @@ char *URLCall(CString URL)
return Result.memory;
}
+
+static void GetNodeTextA(IXMLDOMNode* node, char* buf, size_t bufSize) {
+ if (!node || !buf) {
+ return;
+ }
+ BSTR bstrText = NULL;
+ if (SUCCEEDED(node->get_text(&bstrText)) && bstrText) {
+ WideCharToMultiByte(CP_UTF8, 0, bstrText, -1, buf, (int)bufSize, NULL, NULL);
+ } else {
+ if (bufSize > 0) {
+ buf[0] = '\0';
+ }
+ }
+ if (bstrText) {
+ SysFreeString(bstrText);
+ }
+}
+
+static void ParseStatsNode(IXMLDOMNode* node, serverData* pData, CString serverMountpoint) {
+ if (!node || !pData) {
+ return;
+ }
+
+ BSTR bstrName = NULL;
+ if (FAILED(node->get_nodeName(&bstrName)) || !bstrName) {
+ return;
+ }
+ CString name(bstrName);
+ SysFreeString(bstrName);
+
+ if (name.CompareNoCase("source") == 0) {
+ bool processSource = true;
+ IXMLDOMElement* elem = NULL;
+ if (SUCCEEDED(node->QueryInterface(IID_IXMLDOMElement, (void**)&elem)) && elem) {
+ VARIANT var;
+ VariantInit(&var);
+ BSTR attr = SysAllocString(L"mount");
+ if (SUCCEEDED(elem->getAttribute(attr, &var)) && var.vt == VT_BSTR) {
+ CString mount(var.bstrVal);
+ if (mount.CompareNoCase(serverMountpoint) != 0) {
+ processSource = false;
+ }
+ } else {
+ IXMLDOMNodeList* children = NULL;
+ if (SUCCEEDED(elem->get_childNodes(&children)) && children) {
+ long len = 0;
+ children->get_length(&len);
+ bool found = false;
+ for (long i = 0; i < len && !found; ++i) {
+ IXMLDOMNode* child = NULL;
+ if (SUCCEEDED(children->get_item(i, &child)) && child) {
+ BSTR childName = NULL;
+ child->get_nodeName(&childName);
+ if (childName && !wcscmp(childName, L"mount")) {
+ BSTR childText = NULL;
+ child->get_text(&childText);
+ if (childText) {
+ CString value(childText);
+ if (value.CompareNoCase(serverMountpoint) == 0) {
+ found = true;
+ }
+ SysFreeString(childText);
+ }
+ }
+ if (childName) SysFreeString(childName);
+ child->Release();
+ }
+ }
+ children->Release();
+ processSource = found;
+ }
+ }
+ VariantClear(&var);
+ SysFreeString(attr);
+ elem->Release();
+ }
+ if (!processSource) {
+ return;
+ }
+ }
+
+ char value[1024];
+ GetNodeTextA(node, value, sizeof(value));
+ if (name.CompareNoCase("server_type") == 0) {
+ strcpy_s(pData->icecast2_stream_type, sizeof(pData->icecast2_stream_type), value);
+ } else if (name.CompareNoCase("ice-bitrate") == 0) {
+ pData->icecast2_bitrate = atoi(value);
+ } else if (name.CompareNoCase("bitrate") == 0) {
+ pData->bitrate = atoi(value);
+ } else if (name.CompareNoCase("ice-quality") == 0) {
+ pData->icecast2_quality = atoi(value);
+ } else if (name.CompareNoCase("ice-channels") == 0) {
+ pData->icecast2_channels = atoi(value);
+ } else if (name.CompareNoCase("ice-samplerate") == 0) {
+ pData->icecast2_samplerate = atoi(value);
+ } else if (name.CompareNoCase("connections") == 0) {
+ pData->icecast2_connections = atoi(value);
+ } else if (name.CompareNoCase("listeners") == 0) {
+ pData->icecast2_listeners = atoi(value);
+ } else if (name.CompareNoCase("listener_peak") == 0) {
+ pData->icecast2_peak_listeners = atoi(value);
+ } else if (name.CompareNoCase("server_description") == 0) {
+ strcpy_s(pData->icecast2_serverdescription, sizeof(pData->icecast2_serverdescription), value);
+ } else if (name.CompareNoCase("artist") == 0) {
+ if (strlen(value) > 0) {
+ StringCchCatA(pData->songTitle, _countof(pData->songTitle), value);
+ StringCchCatA(pData->songTitle, _countof(pData->songTitle), " - ");
+ }
+ } else if (name.CompareNoCase("genre") == 0) {
+ strcpy_s(pData->serverGenre, sizeof(pData->serverGenre), value);
+ } else if (name.CompareNoCase("server_name") == 0) {
+ strcpy_s(pData->streamName, sizeof(pData->streamName), value);
+ } else if (name.CompareNoCase("title") == 0) {
+ if (strlen(value) > 0) {
+ StringCchCatA(pData->songTitle, _countof(pData->songTitle), value);
+ }
+ } else if (name.CompareNoCase("CURRENTLISTENERS") == 0) {
+ pData->currentListeners = atoi(value);
+ } else if (name.CompareNoCase("PEAKLISTENERS") == 0) {
+ pData->peakListeners = atoi(value);
+ } else if (name.CompareNoCase("MAXLISTENERS") == 0) {
+ pData->maxListeners = atoi(value);
+ } else if (name.CompareNoCase("REPORTEDLISTENERS") == 0) {
+ pData->reportedListeners = atoi(value);
+ } else if (name.CompareNoCase("AVERAGETIME") == 0) {
+ pData->avgTime = atoi(value);
+ } else if (name.CompareNoCase("WEBHITS") == 0) {
+ pData->webHits = atoi(value);
+ } else if (name.CompareNoCase("STREAMHITS") == 0) {
+ pData->streamHits = atoi(value);
+ } else if (name.CompareNoCase("SERVERTITLE") == 0) {
+ strcpy_s(pData->streamName, sizeof(pData->streamName), value);
+ } else if (name.CompareNoCase("SERVERGENRE") == 0) {
+ strcpy_s(pData->serverGenre, sizeof(pData->serverGenre), value);
+ } else if (name.CompareNoCase("SONGTITLE") == 0) {
+ strcpy_s(pData->songTitle, sizeof(pData->songTitle), value);
+ } else if (name.CompareNoCase("CONTENT") == 0 || name.CompareNoCase("content_type") == 0) {
+ strcpy_s(pData->sc_content_type, sizeof(pData->sc_content_type), value);
+ } else if (name.CompareNoCase("unique_nodes") == 0) {
+ pData->currentListeners = atoi(value);
+ } else if (name.CompareNoCase("max_nodes") == 0) {
+ pData->maxListeners = atoi(value);
+ } else if (name.CompareNoCase("average_connect_time") == 0) {
+ pData->avgTime = atoi(value);
+ } else if (name.CompareNoCase("tuneins") == 0) {
+ pData->streamHits = atoi(value);
+ } else if (name.CompareNoCase("meta_song") == 0) {
+ strcpy_s(pData->songTitle, sizeof(pData->songTitle), value);
+ } else if (name.CompareNoCase("name") == 0) {
+ strcpy_s(pData->streamName, sizeof(pData->streamName), value);
+ } else if (name.CompareNoCase("description") == 0) {
+ strcpy_s(pData->icecast2_serverdescription, sizeof(pData->icecast2_serverdescription), value);
+ } else if (name.CompareNoCase("url") == 0) {
+ strcpy_s(pData->serverURL, sizeof(pData->serverURL), value);
+ }
+
+ IXMLDOMNode* child = NULL;
+ if (SUCCEEDED(node->get_firstChild(&child)) && child) {
+ while (child) {
+ IXMLDOMNode* next = NULL;
+ child->get_nextSibling(&next);
+ ParseStatsNode(child, pData, serverMountpoint);
+ child = next;
+ }
+ }
+ if (child) {
+ child->Release();
+ }
+}
+
int getStats(CString serverURL, CString serverPassword, int serverType, CString serverMountpoint, serverData *pData, char *errorMessage, size_t errorMessageSize)
{
- xmlDocPtr doc = NULL;
-
int ret = 0;
- char *p1;
- xmlNodePtr cur;
- xmlNodePtr cur2;
- xmlNodePtr cur3;
char query[4096] = "";
int port = 0;
int sleeptime = 0;
CString fullURL;
int srvcheck = 0;
-
-
+
fullURL = serverURL;
-
+
if (strcpy_s(pData->serverURL, sizeof(pData->serverURL), serverURL) != 0) {
LogMessage(LOG_ERROR, "serverURL truncated");
}
-
+
pData->serverType = serverType;
if (serverType == 0) {
CString tempString = "";
-
+
tempString.Format("?pass=%s&mode=viewxml", serverPassword);
fullURL += "/admin.cgi" + tempString;
}
@@ -187,362 +339,94 @@ int getStats(CString serverURL, CString serverPassword, int serverType, CString
if (serverType == 2) {
fullURL += "/status.xml";
}
-
+
char *buffer = URLCall(fullURL);
-
+
if (buffer) {
-
+
if (strstr(buffer, "SHOUTcast Administrator")) {
-
- if (sprintf_s(errorMessage, errorMessageSize, "Bad password\n(%s)", serverPassword) < 0) {
- errorMessage[0] = '\\0';
+
+ if (sprintf_s(errorMessage, errorMessageSize, "Bad password
+(%s)", serverPassword) < 0) {
+ errorMessage[0] = '\0';
}
LogMessage(LOG_ERROR, errorMessage);
return 0;
}
- else {
- p1 = buffer;
- if (p1) {
- doc = xmlParseMemory(p1, strlen(p1));
- if (!doc) {
- //commented out for nt service
- if (sprintf_s(errorMessage, errorMessageSize, "Bad parse! (%s)", serverURL) < 0) {
- errorMessage[0] = '\\0';
- }
- LogMessage(LOG_ERROR,"Bad xml parse");
- return 0;
- }
-
- cur = xmlDocGetRootElement(doc);
- if (cur == NULL) {
- //commented out for nt service
- if (sprintf_s(errorMessage, errorMessageSize, "Empty Document! (%s)", serverURL) < 0) {
- errorMessage[0] = '\\0';
- }
- LogMessage(LOG_ERROR,"Empty Document");
- xmlFreeDoc(doc);
- return 0;
- }
- else {//parse xml stats from servers
- memset(pData->songTitle, '\000', sizeof(pData->songTitle));
- cur = cur->xmlChildrenNode;
- while (cur != NULL) {
- // This is an Icecast 2 XML doc
- if (!xmlStrcmp(cur->name, (const xmlChar *) "source")) {
- if (!xmlStrcmp(xmlGetProp(cur, (const xmlChar *) "mount"), (const xmlChar *)(LPCSTR)serverMountpoint)) {
- cur2 = cur->xmlChildrenNode;
- while (cur2 != NULL) {
-
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"server_type")) {
- memset(pData->icecast2_stream_type, '\000', sizeof(pData->icecast2_stream_type));
- char *p1 = (char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->icecast2_stream_type, sizeof(pData->icecast2_stream_type), p1);
- }
- }
-
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"ice-bitrate")) {
- pData->icecast2_bitrate = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
-
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"bitrate")) {
- pData->icecast2_bitrate = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
-
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"ice-quality")) {
- pData->icecast2_quality = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"ice-channels")) {
- pData->icecast2_channels = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"ice-samplerate")) {
- pData->icecast2_samplerate = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
-
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"connections")) {
- pData->icecast2_connections = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"listeners")) {
- pData->icecast2_listeners = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"listener_peak")) {
- pData->icecast2_peak_listeners = atoi((char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode,1));
- }
-
-
-
-
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"server_description")) {
- memset(pData->icecast2_serverdescription, '\000', sizeof(pData->icecast2_serverdescription));
- char *p1 = (char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->icecast2_serverdescription, sizeof(pData->icecast2_serverdescription), p1);
- }
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"artist")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
- if (p1) {
- if (strlen(p1) > 0) {
- StringCchCatA(pData->songTitle, _countof(pData->songTitle), p1);
- StringCchCatA(pData->songTitle, _countof(pData->songTitle), " - ");
- }
- }
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"genre")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
- if (p1) {
- if (strlen(p1) > 0) {
- strcpy_s(pData->serverGenre, sizeof(pData->serverGenre), p1);
- }
- }
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"server_name")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
- if (p1) {
- if (strlen(p1) > 0) {
- strcpy_s(pData->streamName, sizeof(pData->streamName), p1);
- }
- }
- }
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"title")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur2->xmlChildrenNode, 1);
- if (p1) {
- if (strlen(p1) > 0) {
- StringCchCatA(pData->songTitle, _countof(pData->songTitle), p1);
- }
- }
- }
- cur2 = cur2->next;
- }
- }
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "CURRENTLISTENERS")) {
- pData->currentListeners = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "PEAKLISTENERS")) {
- pData->peakListeners = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "MAXLISTENERS")) {
- pData->maxListeners = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "REPORTEDLISTENERS")) {
- pData->reportedListeners = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "AVERAGETIME")) {
- pData->avgTime = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "WEBHITS")) {
- pData->webHits = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "STREAMHITS")) {
- pData->streamHits = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "BITRATE")) {
- pData->bitrate = atoi((char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1));
- }
-
-
- if (!xmlStrcmp(cur->name, (const xmlChar *) "SERVERTITLE")) {
- memset(pData->streamName, '\000', sizeof(pData->streamName));
- char *p1 = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->streamName, sizeof(pData->streamName), p1);
- }
- }
-
- if (!xmlStrcmp(cur->name, (const xmlChar *) "SERVERGENRE")) {
- memset(pData->serverGenre, '\000', sizeof(pData->serverGenre));
- char *p1 = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->serverGenre, sizeof(pData->serverGenre), p1);
- }
- }
-
- if (!xmlStrcmp(cur->name, (const xmlChar *) "SONGTITLE")) {
- memset(pData->songTitle, '\000', sizeof(pData->songTitle));
- char *p1 = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->songTitle, sizeof(pData->songTitle), p1);
- }
- }
- if (!xmlStrcmp(cur->name, (const xmlChar *) "CONTENT")) {
- memset(pData->sc_content_type, '\000', sizeof(pData->sc_content_type));
- char *p1 = (char *)xmlNodeListGetString(doc, cur->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->sc_content_type, sizeof(pData->sc_content_type), p1);
- }
- }
- // This is an Steamcast XML doc
- if (!xmlStrcmp(cur->name, (const xmlChar *) "sources")) {
- cur2 = cur->xmlChildrenNode;
- while (cur2 != NULL) {
- if (!xmlStrcmp(cur2->name, (const xmlChar *)"source")) {
- bool ourSource = false;
- cur3 = cur2->xmlChildrenNode;
- while (cur3 != NULL) {
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "mount")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- if (!strcmp(p1, (LPCSTR)serverMountpoint)) {
- ourSource = true;
- break;
- }
- }
- }
- cur3 = cur3->next;
- }
- if (ourSource) {
- cur3 = cur2->xmlChildrenNode;
- while (cur3 != NULL) {
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "mount")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "status")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "name")) {
- memset(pData->streamName, '\000', sizeof(pData->streamName));
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->streamName, sizeof(pData->streamName), p1);
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "description")) {
- memset(pData->icecast2_serverdescription, '\000', sizeof(pData->icecast2_serverdescription));
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->icecast2_serverdescription, sizeof(pData->icecast2_serverdescription), p1);
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "genre")) {
- memset(pData->serverGenre, '\000', sizeof(pData->serverGenre));
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->serverGenre, sizeof(pData->serverGenre), p1);
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "url")) {
- memset(pData->serverURL, '\000', sizeof(pData->serverURL));
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->serverURL, sizeof(pData->serverURL), p1);
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "bitrate")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- pData->bitrate = atoi((char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "meta_song")) {
- memset(pData->songTitle, '\000', sizeof(pData->songTitle));
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->songTitle, sizeof(pData->songTitle), p1);
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "meta_url")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "nodes")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "unique_nodes")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- pData->currentListeners = atoi((char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "max_nodes")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- pData->maxListeners = atoi((char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "average_connect_time")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- pData->avgTime = atoi((char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "tuneins")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- pData->streamHits = atoi((char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1));
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "connect_time")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "bytes_recv")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "bytes_sent")) {
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- }
- }
- if (!xmlStrcmp(cur3->name, (const xmlChar *) "content_type")) {
- memset(pData->sc_content_type, '\000', sizeof(pData->sc_content_type));
- char *p1 = (char *)xmlNodeListGetString(doc, cur3->xmlChildrenNode, 1);
- if (p1) {
- strcpy_s(pData->sc_content_type, sizeof(pData->sc_content_type), p1);
- }
- }
- cur3 = cur3->next;
- }
- }
- }
- cur2 = cur2->next;
- }
- }
- cur = cur->next;
- }
-
-
-
-
- }//end parsing xml stats from servers
- if (strlen(pData->songTitle) > 0) {
- trimRight(pData->songTitle);
- replaceQuote(pData->songTitle);
- }
+
+ HRESULT hr = CoInitialize(NULL);
+ if (FAILED(hr)) {
+ LogMessage(LOG_ERROR, "Failed to initialize COM");
+ return 0;
+ }
+
+ IXMLDOMDocument* pDoc = NULL;
+ hr = CoCreateInstance(CLSID_DOMDocument60, NULL, CLSCTX_INPROC_SERVER, IID_IXMLDOMDocument, (void**)&pDoc);
+ if (FAILED(hr) || !pDoc) {
+ LogMessage(LOG_ERROR, "Failed to create DOMDocument");
+ CoUninitialize();
+ return 0;
+ }
+
+ pDoc->put_async(VARIANT_FALSE);
+
+ BSTR xml = NULL;
+ int len = MultiByteToWideChar(CP_UTF8, 0, buffer, -1, NULL, 0);
+ if (len > 0) {
+ xml = SysAllocStringLen(NULL, len);
+ MultiByteToWideChar(CP_UTF8, 0, buffer, -1, xml, len);
+ }
+
+ VARIANT_BOOL loaded = VARIANT_FALSE;
+ if (xml) {
+ pDoc->loadXML(xml, &loaded);
+ }
+ if (!xml || loaded != VARIANT_TRUE) {
+ if (sprintf_s(errorMessage, errorMessageSize, "Bad parse! (%s)", serverURL) < 0) {
+ errorMessage[0] = '\0';
}
- else {
-
- if (sprintf_s(errorMessage, errorMessageSize, "Bad data from %s\n", serverURL) < 0) {
- errorMessage[0] = '\\0';
- }
- LogMessage(LOG_ERROR,errorMessage);
- return 0;
+ LogMessage(LOG_ERROR, "Bad xml parse");
+ if (xml) SysFreeString(xml);
+ pDoc->Release();
+ CoUninitialize();
+ return 0;
+ }
+ SysFreeString(xml);
+
+ IXMLDOMElement* root = NULL;
+ pDoc->get_documentElement(&root);
+ if (!root) {
+ if (sprintf_s(errorMessage, errorMessageSize, "Empty Document! (%s)", serverURL) < 0) {
+ errorMessage[0] = '\0';
}
+ LogMessage(LOG_ERROR, "Empty Document");
+ pDoc->Release();
+ CoUninitialize();
+ return 0;
+ }
+
+ memset(pData->songTitle, '\000', sizeof(pData->songTitle));
+ ParseStatsNode(root, pData, serverMountpoint);
+
+ root->Release();
+ pDoc->Release();
+ CoUninitialize();
+
+ if (strlen(pData->songTitle) > 0) {
+ trimRight(pData->songTitle);
+ replaceQuote(pData->songTitle);
}
}
- //LOG AND SEND ERROR MESSAGES HERE IF SERVERS ARE DOWN
else {
- if (sprintf_s(errorMessage, errorMessageSize, "SERVER %s IS DOWN\n", serverURL) < 0) {
- errorMessage[0] = '\\0';
+ if (sprintf_s(errorMessage, errorMessageSize, "SERVER %s IS DOWN
+", serverURL) < 0) {
+ errorMessage[0] = '\0';
}
LogMessage(LOG_ERROR,errorMessage);
srvcheck = 1;
-
- }
- //END SENDING ERROR MESSAGES
- if (doc) {
- xmlFreeDoc(doc);
+
}
return 1;
}
+