jabberd2  2.2.16
sm/mod_iq_version.c
Go to the documentation of this file.
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 }