jabberd2
2.2.16
|
00001 /* 00002 * jabberd - Jabber Open Source Server 00003 * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney, 00004 * Ryan Eatmon, Robert Norris 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA 00019 */ 00020 00021 #include "sm.h" 00022 00030 #ifdef HAVE_SYS_UTSNAME_H 00031 # include <sys/utsname.h> 00032 #endif 00033 00034 typedef struct _mod_iq_version_config_st { 00035 char *app_name; 00036 char *app_version; 00037 char *app_signature; 00038 char *os_name; 00039 char *os_release; 00040 } *mod_iq_version_config_t; 00041 00042 static int ns_VERSION = 0; 00043 00044 void _iq_version_get_os_version(mod_iq_version_config_t config) { 00045 #if defined(HAVE_UNAME) 00046 struct utsname un; 00047 00048 #elif defined(_WIN32) 00049 char sysname[64]; 00050 char release[64]; 00051 00052 OSVERSIONINFOEX osvi; 00053 BOOL bOsVersionInfoEx; 00054 BOOL bSomeError = FALSE; 00055 00056 sysname[0] = '\0'; 00057 release[0] = '\0'; 00058 #endif 00059 00060 /* figure out the os type */ 00061 #if defined(HAVE_UNAME) 00062 if(uname(&un) == 0) { 00063 config->os_name = strdup(un.sysname); 00064 config->os_release = strdup(un.machine); 00065 00066 return; 00067 } 00068 #elif defined(_WIN32) 00069 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX)); 00070 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); 00071 if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) ) 00072 { 00073 /* If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO. */ 00074 00075 osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO); 00076 if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) ) 00077 { 00078 snprintf(sysname, 64, "unknown"); 00079 bSomeError = TRUE; 00080 } 00081 } 00082 if (!bSomeError) 00083 { 00084 switch (osvi.dwPlatformId) 00085 { 00086 case VER_PLATFORM_WIN32_NT: 00087 /* Test for the product. */ 00088 if ( osvi.dwMajorVersion <= 4 ) 00089 snprintf(sysname, 64, "Microsoft Windows NT"); 00090 00091 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 ) 00092 snprintf(sysname, 64, "Microsoft Windows 2000"); 00093 00094 if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 ) 00095 snprintf(sysname, 64, "Microsoft Windows XP"); 00096 00097 /* Test for product type. */ 00098 00099 if( bOsVersionInfoEx ) 00100 { 00101 if ( osvi.wProductType == VER_NT_WORKSTATION ) 00102 { 00103 if( osvi.wSuiteMask & VER_SUITE_PERSONAL ) 00104 snprintf(release, 64, "Personal" ); 00105 else 00106 snprintf(release, 64, "Professional" ); 00107 } 00108 00109 else if ( osvi.wProductType == VER_NT_SERVER ) 00110 { 00111 if( osvi.wSuiteMask & VER_SUITE_DATACENTER ) 00112 snprintf(release, 64, "DataCenter Server" ); 00113 else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE ) 00114 snprintf(release, 64, "Advanced Server" ); 00115 else 00116 snprintf(release, 64, "Server" ); 00117 } 00118 } 00119 else 00120 { 00121 HKEY hKey; 00122 char szProductType[80]; 00123 DWORD dwBufLen; 00124 00125 RegOpenKeyEx( HKEY_LOCAL_MACHINE, 00126 "SYSTEM\\CurrentControlSet\\Control\\ProductOptions", 00127 0, KEY_QUERY_VALUE, &hKey ); 00128 RegQueryValueEx( hKey, "ProductType", NULL, NULL, 00129 (LPBYTE) szProductType, &dwBufLen); 00130 RegCloseKey( hKey ); 00131 if ( lstrcmpi( "WINNT", szProductType) == 0 ) 00132 snprintf(release, 64, "Professional" ); 00133 if ( lstrcmpi( "LANMANNT", szProductType) == 0 ) 00134 snprintf(release, 64, "Server" ); 00135 if ( lstrcmpi( "SERVERNT", szProductType) == 0 ) 00136 snprintf(release, 64, "Advanced Server" ); 00137 } 00138 break; 00139 00140 case VER_PLATFORM_WIN32_WINDOWS: 00141 00142 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) 00143 { 00144 snprintf(sysname, 64, "Microsoft Windows 95"); 00145 if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' ) 00146 snprintf(release, 64, "OSR2" ); 00147 } 00148 00149 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) 00150 { 00151 snprintf(sysname, 64, "Microsoft Windows 98"); 00152 if ( osvi.szCSDVersion[1] == 'A' ) 00153 snprintf(release, 64, "SE" ); 00154 } 00155 00156 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) 00157 { 00158 snprintf(sysname, 64, "Microsoft Windows Me"); 00159 } 00160 break; 00161 00162 case VER_PLATFORM_WIN32s: 00163 00164 snprintf(sysname, 64, "Microsoft Win32s"); 00165 break; 00166 } 00167 } 00168 00169 config->os_name = strdup(sysname); 00170 config->os_release = strdup(release); 00171 00172 return; 00173 #endif 00174 } 00175 00176 static mod_ret_t _iq_version_pkt_sm(mod_instance_t mi, pkt_t pkt) { 00177 module_t mod = mi->mod; 00178 mod_iq_version_config_t config = (mod_iq_version_config_t) mod->private; 00179 char buf[256]; 00180 00181 /* we only want to play with iq:version gets */ 00182 if(pkt->type != pkt_IQ || pkt->ns != ns_VERSION) 00183 return mod_PASS; 00184 00185 nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "name", config->app_name); 00186 nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "version", config->app_version); 00187 00188 /* figure out the os type */ 00189 if(config->os_name != NULL) { 00190 if(config->os_release) 00191 snprintf(buf, 256, "%s %s", config->os_name, config->os_release); 00192 else 00193 snprintf(buf, 256, "%s", config->os_name); 00194 nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "os", buf); 00195 } 00196 00197 /* tell them */ 00198 nad_set_attr(pkt->nad, 1, -1, "type", "result", 6); 00199 pkt_router(pkt_tofrom(pkt)); 00200 00201 return mod_HANDLED; 00202 } 00203 00204 static void _iq_version_disco_extend(mod_instance_t mi, pkt_t pkt) 00205 { 00206 module_t mod = mi->mod; 00207 mod_iq_version_config_t config = (mod_iq_version_config_t) mod->private; 00208 int ns; 00209 00210 log_debug(ZONE, "in mod_iq_version disco-extend"); 00211 00212 ns = nad_add_namespace(pkt->nad, uri_XDATA, NULL); 00213 /* there may be several XDATA siblings, so need to enforce the NS */ 00214 pkt->nad->scope = ns; 00215 00216 nad_append_elem(pkt->nad, ns, "x", 3); 00217 nad_append_attr(pkt->nad, -1, "type", "result"); 00218 /* hidden form type field*/ 00219 nad_append_elem(pkt->nad, -1, "field", 4); 00220 nad_append_attr(pkt->nad, -1, "var", "FORM_TYPE"); 00221 nad_append_attr(pkt->nad, -1, "type", "hidden"); 00222 nad_append_elem(pkt->nad, -1, "value", 5); 00223 nad_append_cdata(pkt->nad, urn_SOFTWAREINFO, strlen(urn_SOFTWAREINFO), 6); 00224 00225 nad_append_elem(pkt->nad, -1, "field", 4); 00226 nad_append_attr(pkt->nad, -1, "var", "software"); 00227 nad_append_elem(pkt->nad, -1, "value", 5); 00228 nad_append_cdata(pkt->nad, config->app_name, strlen(config->app_name), 6); 00229 00230 nad_append_elem(pkt->nad, -1, "field", 4); 00231 nad_append_attr(pkt->nad, -1, "var", "software_version"); 00232 nad_append_elem(pkt->nad, -1, "value", 5); 00233 nad_append_cdata(pkt->nad, config->app_version, strlen(config->app_version), 6); 00234 00235 if(config->os_name != NULL) { 00236 nad_append_elem(pkt->nad, -1, "field", 4); 00237 nad_append_attr(pkt->nad, -1, "var", "os"); 00238 nad_append_elem(pkt->nad, -1, "value", 5); 00239 nad_append_cdata(pkt->nad, config->os_name, strlen(config->os_name), 6); 00240 } 00241 00242 if(config->os_name != NULL) { 00243 nad_append_elem(pkt->nad, -1, "field", 4); 00244 nad_append_attr(pkt->nad, -1, "var", "os_version"); 00245 nad_append_elem(pkt->nad, -1, "value", 5); 00246 nad_append_cdata(pkt->nad, config->os_release, strlen(config->os_release), 6); 00247 } 00248 } 00249 00250 static void _iq_version_free(module_t mod) { 00251 mod_iq_version_config_t config = (mod_iq_version_config_t) mod->private; 00252 00253 sm_unregister_ns(mod->mm->sm, uri_VERSION); 00254 feature_unregister(mod->mm->sm, uri_VERSION); 00255 00256 if(config->os_name != NULL) free(config->os_name); 00257 if(config->os_release != NULL) free(config->os_release); 00258 00259 free(config); 00260 } 00261 00262 DLLEXPORT int module_init(mod_instance_t mi, char *arg) { 00263 mod_iq_version_config_t config; 00264 module_t mod = mi->mod; 00265 00266 if(mod->init) return 0; 00267 00268 config = (mod_iq_version_config_t) calloc(1, sizeof(struct _mod_iq_version_config_st)); 00269 config->app_name = PACKAGE; 00270 config->app_version = VERSION; 00271 config->app_signature = mi->sm->signature; 00272 _iq_version_get_os_version(config); 00273 00274 mod->private = config; 00275 00276 mod->pkt_sm = _iq_version_pkt_sm; 00277 mod->disco_extend = _iq_version_disco_extend; 00278 mod->free = _iq_version_free; 00279 00280 ns_VERSION = sm_register_ns(mod->mm->sm, uri_VERSION); 00281 feature_register(mod->mm->sm, uri_VERSION); 00282 00283 return 0; 00284 }