jabberd2  2.3.4
mod_iq_version.c
Go to the documentation of this file.
1 /*
2  * jabberd - Jabber Open Source Server
3  * Copyright (c) 2002 Jeremie Miller, Thomas Muldowney,
4  * Ryan Eatmon, Robert Norris
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA02111-1307USA
19  */
20 
21 #include "sm.h"
22 
30 #ifdef HAVE_SYS_UTSNAME_H
31 # include <sys/utsname.h>
32 #endif
33 
34 typedef struct _mod_iq_version_config_st {
35  char *app_name;
36  char *app_version;
38  char *os_name;
39  char *os_release;
41 
42 static int ns_VERSION = 0;
43 
45 #if defined(HAVE_UNAME)
46  struct utsname un;
47 
48 #elif defined(_WIN32)
49  char sysname[64];
50  char release[64];
51 
52  OSVERSIONINFOEX osvi;
53  BOOL bOsVersionInfoEx;
54  BOOL bSomeError = FALSE;
55 
56  sysname[0] = '\0';
57  release[0] = '\0';
58 #endif
59 
60  /* figure out the os type */
61 #if defined(HAVE_UNAME)
62  if(uname(&un) == 0) {
63  config->os_name = strdup(un.sysname);
64  config->os_release = strdup(un.machine);
65 
66  return;
67  }
68 #elif defined(_WIN32)
69  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
70  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
71  if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
72  {
73  /* If OSVERSIONINFOEX doesn't work, try OSVERSIONINFO. */
74 
75  osvi.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
76  if (! GetVersionEx ( (OSVERSIONINFO *) &osvi) )
77  {
78  snprintf(sysname, 64, "unknown");
79  bSomeError = TRUE;
80  }
81  }
82  if (!bSomeError)
83  {
84  switch (osvi.dwPlatformId)
85  {
86  case VER_PLATFORM_WIN32_NT:
87  /* Test for the product. */
88  if ( osvi.dwMajorVersion <= 4 )
89  snprintf(sysname, 64, "Microsoft Windows NT");
90 
91  if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
92  snprintf(sysname, 64, "Microsoft Windows 2000");
93 
94  if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
95  snprintf(sysname, 64, "Microsoft Windows XP");
96 
97  /* Test for product type. */
98 
99  if( bOsVersionInfoEx )
100  {
101  if ( osvi.wProductType == VER_NT_WORKSTATION )
102  {
103  if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
104  snprintf(release, 64, "Personal" );
105  else
106  snprintf(release, 64, "Professional" );
107  }
108 
109  else if ( osvi.wProductType == VER_NT_SERVER )
110  {
111  if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
112  snprintf(release, 64, "DataCenter Server" );
113  else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
114  snprintf(release, 64, "Advanced Server" );
115  else
116  snprintf(release, 64, "Server" );
117  }
118  }
119  else
120  {
121  HKEY hKey;
122  char szProductType[80];
123  DWORD dwBufLen;
124 
125  RegOpenKeyEx( HKEY_LOCAL_MACHINE,
126  "SYSTEM\\CurrentControlSet\\Control\\ProductOptions",
127  0, KEY_QUERY_VALUE, &hKey );
128  RegQueryValueEx( hKey, "ProductType", NULL, NULL,
129  (LPBYTE) szProductType, &dwBufLen);
130  RegCloseKey( hKey );
131  if ( lstrcmpi( "WINNT", szProductType) == 0 )
132  snprintf(release, 64, "Professional" );
133  if ( lstrcmpi( "LANMANNT", szProductType) == 0 )
134  snprintf(release, 64, "Server" );
135  if ( lstrcmpi( "SERVERNT", szProductType) == 0 )
136  snprintf(release, 64, "Advanced Server" );
137  }
138  break;
139 
140  case VER_PLATFORM_WIN32_WINDOWS:
141 
142  if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0)
143  {
144  snprintf(sysname, 64, "Microsoft Windows 95");
145  if ( osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B' )
146  snprintf(release, 64, "OSR2" );
147  }
148 
149  if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10)
150  {
151  snprintf(sysname, 64, "Microsoft Windows 98");
152  if ( osvi.szCSDVersion[1] == 'A' )
153  snprintf(release, 64, "SE" );
154  }
155 
156  if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90)
157  {
158  snprintf(sysname, 64, "Microsoft Windows Me");
159  }
160  break;
161 
162  case VER_PLATFORM_WIN32s:
163 
164  snprintf(sysname, 64, "Microsoft Win32s");
165  break;
166  }
167  }
168 
169  config->os_name = strdup(sysname);
170  config->os_release = strdup(release);
171 
172  return;
173 #endif
174 }
175 
177  module_t mod = mi->mod;
179  char buf[256];
180 
181  /* we only want to play with iq:version gets */
182  if(pkt->type != pkt_IQ || pkt->ns != ns_VERSION)
183  return mod_PASS;
184 
185  nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "name", config->app_name);
186  nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "version", config->app_version);
187 
188  /* figure out the os type */
189  if(config->os_name != NULL) {
190  if(config->os_release)
191  snprintf(buf, 256, "%s %s", config->os_name, config->os_release);
192  else
193  snprintf(buf, 256, "%s", config->os_name);
194  nad_insert_elem(pkt->nad, 2, NAD_ENS(pkt->nad, 1), "os", buf);
195  }
196 
197  /* tell them */
198  nad_set_attr(pkt->nad, 1, -1, "type", "result", 6);
199  pkt_router(pkt_tofrom(pkt));
200 
201  return mod_HANDLED;
202 }
203 
205 {
206  module_t mod = mi->mod;
208  int ns;
209 
210  log_debug(ZONE, "in mod_iq_version disco-extend");
211 
212  ns = nad_add_namespace(pkt->nad, uri_XDATA, NULL);
213  /* there may be several XDATA siblings, so need to enforce the NS */
214  pkt->nad->scope = ns;
215 
216  nad_append_elem(pkt->nad, ns, "x", 3);
217  nad_append_attr(pkt->nad, -1, "type", "result");
218  /* hidden form type field*/
219  nad_append_elem(pkt->nad, -1, "field", 4);
220  nad_append_attr(pkt->nad, -1, "var", "FORM_TYPE");
221  nad_append_attr(pkt->nad, -1, "type", "hidden");
222  nad_append_elem(pkt->nad, -1, "value", 5);
224 
225  nad_append_elem(pkt->nad, -1, "field", 4);
226  nad_append_attr(pkt->nad, -1, "var", "software");
227  nad_append_elem(pkt->nad, -1, "value", 5);
228  nad_append_cdata(pkt->nad, config->app_name, strlen(config->app_name), 6);
229 
230  nad_append_elem(pkt->nad, -1, "field", 4);
231  nad_append_attr(pkt->nad, -1, "var", "software_version");
232  nad_append_elem(pkt->nad, -1, "value", 5);
233  nad_append_cdata(pkt->nad, config->app_version, strlen(config->app_version), 6);
234 
235  if(config->os_name != NULL) {
236  nad_append_elem(pkt->nad, -1, "field", 4);
237  nad_append_attr(pkt->nad, -1, "var", "os");
238  nad_append_elem(pkt->nad, -1, "value", 5);
239  nad_append_cdata(pkt->nad, config->os_name, strlen(config->os_name), 6);
240  }
241 
242  if(config->os_name != NULL) {
243  nad_append_elem(pkt->nad, -1, "field", 4);
244  nad_append_attr(pkt->nad, -1, "var", "os_version");
245  nad_append_elem(pkt->nad, -1, "value", 5);
246  nad_append_cdata(pkt->nad, config->os_release, strlen(config->os_release), 6);
247  }
248 }
249 
250 static void _iq_version_free(module_t mod) {
252 
255 
256  if(config->os_name != NULL) free(config->os_name);
257  if(config->os_release != NULL) free(config->os_release);
258 
259  free(config);
260 }
261 
262 DLLEXPORT int module_init(mod_instance_t mi, const char *arg) {
264  module_t mod = mi->mod;
265 
266  if(mod->init) return 0;
267 
268  config = (mod_iq_version_config_t) calloc(1, sizeof(struct _mod_iq_version_config_st));
269  config->app_name = PACKAGE;
270  config->app_version = VERSION;
271  config->app_signature = mi->sm->signature;
273 
274  mod->private = config;
275 
276  mod->pkt_sm = _iq_version_pkt_sm;
278  mod->free = _iq_version_free;
279 
282 
283  return 0;
284 }
static int ns_VERSION
pkt_type_t type
packet type
Definition: sm.h:138
int sm_register_ns(sm_t sm, const char *uri)
register a new global ns
Definition: sm.c:324
int nad_append_attr(nad_t nad, int ns, const char *name, const char *val)
attach new attr to the last elem
Definition: nad.c:701
data structures and prototypes for the session manager
int nad_insert_elem(nad_t nad, int parent, int ns, const char *name, const char *cdata)
shove in a new child elem after the given one
Definition: nad.c:405
void sm_unregister_ns(sm_t sm, const char *uri)
unregister a global ns
Definition: sm.c:338
pkt_t pkt_tofrom(pkt_t pkt)
swap a packet's to and from attributes
Definition: pkt.c:57
single instance of a module in a chain
Definition: sm.h:446
void nad_append_cdata(nad_t nad, const char *cdata, int len, int depth)
append new cdata to the last elem
Definition: nad.c:709
int init
number of times the module intialiser has been called
Definition: sm.h:416
struct _mod_iq_version_config_st * mod_iq_version_config_t
int nad_add_namespace(nad_t nad, const char *uri, const char *prefix)
bring a new namespace into scope
Definition: nad.c:734
void _iq_version_get_os_version(mod_iq_version_config_t config)
#define urn_SOFTWAREINFO
Definition: uri.h:83
int nad_append_elem(nad_t nad, int ns, const char *name, int depth)
create a new elem on the list
Definition: nad.c:667
mm_t mm
module manager
Definition: sm.h:404
DLLEXPORT int module_init(mod_instance_t mi, const char *arg)
#define DLLEXPORT
Definition: c2s.h:47
void nad_set_attr(nad_t nad, int elem, int ns, const char *name, const char *val, int vallen)
create, update, or zap any matching attr on this elem
Definition: nad.c:375
sm_t sm
sm context
Definition: sm.h:366
static void _iq_version_disco_extend(mod_instance_t mi, pkt_t pkt)
static mod_ret_t _iq_version_pkt_sm(mod_instance_t mi, pkt_t pkt)
module_t mod
module that this is an instance of
Definition: sm.h:449
void feature_unregister(sm_t sm, const char *feature)
unregister feature
Definition: feature.c:45
void * private
module private data
Definition: sm.h:418
packet summary data wrapper
Definition: sm.h:129
nad_t nad
nad of the entire packet
Definition: sm.h:146
#define uri_XDATA
Definition: uri.h:55
void pkt_router(pkt_t pkt)
Definition: pkt.c:379
#define log_debug(...)
Definition: log.h:65
void feature_register(sm_t sm, const char *feature)
register a feature
Definition: feature.c:37
info/query (get)
Definition: sm.h:106
packet was unhandled, should be passed to the next module
Definition: sm.h:340
int ns
iq sub-namespace
Definition: sm.h:142
packet was handled (and freed)
Definition: sm.h:339
char signature[2048]
server signature
Definition: sm.h:217
int scope
Definition: nad.h:107
mod_ret_t(* pkt_sm)(mod_instance_t mi, pkt_t pkt)
pkt-sm handler
Definition: sm.h:429
void(* disco_extend)(mod_instance_t mi, pkt_t pkt)
disco-extend handler
Definition: sm.h:440
#define ZONE
Definition: mio_impl.h:76
void(* free)(module_t mod)
called when module is freed
Definition: sm.h:442
data for a single module
Definition: sm.h:403
#define uri_VERSION
Definition: uri.h:69
mod_ret_t
module return values
Definition: sm.h:338
sm_t sm
sm context
Definition: sm.h:447
#define NAD_ENS(N, E)
Definition: nad.h:196
static void _iq_version_free(module_t mod)