#include "sm.h"
#ifdef HAVE_SYS_UTSNAME_H
# include <sys/utsname.h>
#endif
static mod_ret_t _iq_version_pkt_sm(mod_instance_t mi, pkt_t pkt) {
char buf[256];
#if defined(HAVE_UNAME)
struct utsname un;
#elif defined(WIN32)
char sysname[64];
char release[64];
char version[64];
OSVERSIONINFOEX osvi;
BOOL bOsVersionInfoEx;
BOOL bSomeError = FALSE;
sysname[0] = 0;
release[0] = 0;
version[0] = 0;
#endif
if(pkt->type != pkt_IQ || pkt->ns != ns_VERSION)
return mod_PASS;
nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "name", "session manager (jabberd)");
nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "version", mi->sm->signature);
#if defined(HAVE_UNAME)
uname(&un);
snprintf(buf, 256, "%s %s", un.sysname, un.release);
nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "os", buf);
#elif defined(WIN32)
ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
{
osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
{
snprintf(sysname, 64, "unknown");
bSomeError = TRUE;
}
}
if (!bSomeError)
{
switch (osvi.dwPlatformId)
{
case VER_PLATFORM_WIN32_NT:
if ( osvi.dwMajorVersion <= 4 )
snprintf(sysname, 64, "Microsoft Windows NT");
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
snprintf(sysname, 64, "Microsoft Windows 2000");
if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
snprintf(sysname, 64, "Microsoft Windows XP");
if( bOsVersionInfoEx )
{
if ( osvi.wProductType == VER_NT_WORKSTATION )
{
if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
snprintf(release, 64, "Personal" );
else
snprintf(release, 64, "Professional" );
}
else if ( osvi.wProductType == VER_NT_SERVER )
{
if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
snprintf(release, 64, "DataCenter Server" );
else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
snprintf(release, 64, "Advanced Server" );
else
snprintf(release, 64, "Server" );
}
}
else
{
HKEY hKey;
char szProductType[80];
DWORD dwBufLen;
RegOpenKeyEx( HKEY_LOCAL_MACHINE,
"SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
0, KEY_QUERY_VALUE, &hKey );
RegQueryValueEx( hKey, "ProductType", NULL, NULL,
(LPBYTE) szProductType, &dwBufLen);
RegCloseKey( hKey );
if ( lstrcmpi( "WINNT", szProductType) == 0 )
snprintf(release, 64, "Professional" );
if ( lstrcmpi( "LANMANNT", szProductType) == 0 )
snprintf(release, 64, "Server" );
if ( lstrcmpi( "SERVERNT", szProductType) == 0 )
snprintf(release, 64, "Advanced Server" );
}
if ( osvi.dwMajorVersion <= 4 )
{
snprintf(version, 64, "version %d.%d %s (Build %d)",
osvi.dwMajorVersion,
osvi.dwMinorVersion,
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
}
else
{
snprintf(version, 64, "%s (Build %d)",
osvi.szCSDVersion,
osvi.dwBuildNumber & 0xFFFF);
}
break;
case VER_PLATFORM_WIN32_WINDOWS:
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
{
snprintf(sysname, 64, "Microsoft Windows 95");
if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
snprintf(release, 64, "OSR2" );
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
{
snprintf(sysname, 64, "Microsoft Windows 98");
if ( osvi.szCSDVersion[1] == 'A' )
snprintf(release, 64, "SE" );
}
if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
{
snprintf(sysname, 64, "Microsoft Windows Me");
}
break;
case VER_PLATFORM_WIN32s:
snprintf(sysname, 64, "Microsoft Win32s");
break;
}
}
snprintf(buf, 256, "%s %s %s", sysname, release, version);
buf[256] = '\0';
nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "os", buf);
#else
nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "os", "unknown");
#endif
nad_set_attr(pkt->nad, 1, -1, "type", "result", 6);
pkt_router(pkt_tofrom(pkt));
return mod_HANDLED;
}
int iq_version_init(mod_instance_t mi, char *arg)
{
module_t mod = mi->mod;
if(mod->init) return 0;
mod->pkt_sm = _iq_version_pkt_sm;
feature_register(mod->mm->sm, uri_VERSION);
return 0;
}