hyperic-sigar 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/COPYING +339 -0
- data/EXCEPTIONS +104 -0
- data/README +2 -0
- data/Rakefile +87 -0
- data/bindings/SigarWrapper.pm +2934 -0
- data/bindings/ruby/examples/cpu_info.rb +16 -0
- data/bindings/ruby/examples/df.rb +32 -0
- data/bindings/ruby/examples/free.rb +19 -0
- data/bindings/ruby/examples/ifconfig.rb +67 -0
- data/bindings/ruby/examples/netstat.rb +54 -0
- data/bindings/ruby/examples/pargs.rb +18 -0
- data/bindings/ruby/examples/penv.rb +14 -0
- data/bindings/ruby/examples/route.rb +31 -0
- data/bindings/ruby/examples/who.rb +13 -0
- data/bindings/ruby/extconf.rb +110 -0
- data/bindings/ruby/rbsigar.c +628 -0
- data/include/sigar.h +901 -0
- data/include/sigar_fileinfo.h +141 -0
- data/include/sigar_format.h +65 -0
- data/include/sigar_getline.h +18 -0
- data/include/sigar_log.h +82 -0
- data/include/sigar_private.h +365 -0
- data/include/sigar_ptql.h +55 -0
- data/include/sigar_util.h +192 -0
- data/src/os/aix/aix_sigar.c +1927 -0
- data/src/os/aix/sigar_os.h +71 -0
- data/src/os/darwin/darwin_sigar.c +3450 -0
- data/src/os/darwin/sigar_os.h +82 -0
- data/src/os/hpux/dlpi.c +284 -0
- data/src/os/hpux/hpux_sigar.c +1205 -0
- data/src/os/hpux/sigar_os.h +51 -0
- data/src/os/linux/linux_sigar.c +2595 -0
- data/src/os/linux/sigar_os.h +84 -0
- data/src/os/netware/netware_sigar.c +719 -0
- data/src/os/netware/sigar_os.h +26 -0
- data/src/os/osf1/osf1_sigar.c +593 -0
- data/src/os/osf1/sigar_os.h +42 -0
- data/src/os/solaris/get_mib2.c +321 -0
- data/src/os/solaris/get_mib2.h +127 -0
- data/src/os/solaris/hmekstat.h +77 -0
- data/src/os/solaris/kstats.c +182 -0
- data/src/os/solaris/procfs.c +99 -0
- data/src/os/solaris/sigar_os.h +225 -0
- data/src/os/solaris/solaris_sigar.c +2561 -0
- data/src/os/stub/sigar_os.h +8 -0
- data/src/os/stub/stub_sigar.c +303 -0
- data/src/os/win32/peb.c +213 -0
- data/src/os/win32/sigar_os.h +623 -0
- data/src/os/win32/sigar_pdh.h +49 -0
- data/src/os/win32/win32_sigar.c +3718 -0
- data/src/sigar.c +2292 -0
- data/src/sigar_cache.c +181 -0
- data/src/sigar_fileinfo.c +792 -0
- data/src/sigar_format.c +649 -0
- data/src/sigar_getline.c +1849 -0
- data/src/sigar_ptql.c +1966 -0
- data/src/sigar_signal.c +218 -0
- data/src/sigar_util.c +1061 -0
- data/version.properties +11 -0
- metadata +112 -0
data/src/sigar.c
ADDED
@@ -0,0 +1,2292 @@
|
|
1
|
+
/*
|
2
|
+
* Copyright (C) [2004, 2005, 2006], Hyperic, Inc.
|
3
|
+
* This file is part of SIGAR.
|
4
|
+
*
|
5
|
+
* SIGAR is free software; you can redistribute it and/or modify
|
6
|
+
* it under the terms version 2 of the GNU General Public License as
|
7
|
+
* published by the Free Software Foundation. This program is distributed
|
8
|
+
* in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
|
9
|
+
* even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
10
|
+
* PARTICULAR PURPOSE. See the GNU General Public License for more
|
11
|
+
* details.
|
12
|
+
*
|
13
|
+
* You should have received a copy of the GNU General Public License
|
14
|
+
* along with this program; if not, write to the Free Software
|
15
|
+
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
|
16
|
+
* USA.
|
17
|
+
*/
|
18
|
+
|
19
|
+
#include <errno.h>
|
20
|
+
#include <stdio.h>
|
21
|
+
|
22
|
+
#ifndef WIN32
|
23
|
+
#include <sys/types.h>
|
24
|
+
#include <sys/socket.h>
|
25
|
+
#include <sys/time.h>
|
26
|
+
#endif
|
27
|
+
#if defined(__OpenBSD__) || defined(__FreeBSD__)
|
28
|
+
#include <netinet/in.h>
|
29
|
+
#endif
|
30
|
+
#ifndef WIN32
|
31
|
+
#include <arpa/inet.h>
|
32
|
+
#endif
|
33
|
+
|
34
|
+
#include "sigar.h"
|
35
|
+
#include "sigar_private.h"
|
36
|
+
#include "sigar_util.h"
|
37
|
+
#include "sigar_os.h"
|
38
|
+
#include "sigar_format.h"
|
39
|
+
|
40
|
+
SIGAR_DECLARE(int) sigar_open(sigar_t **sigar)
|
41
|
+
{
|
42
|
+
int status = sigar_os_open(sigar);
|
43
|
+
|
44
|
+
if (status == SIGAR_OK) {
|
45
|
+
/* use env to revert to old behavior */
|
46
|
+
(*sigar)->cpu_list_cores = getenv("SIGAR_CPU_LIST_SOCKETS") ? 0 : 1;
|
47
|
+
(*sigar)->pid = 0;
|
48
|
+
(*sigar)->ifconf_buf = NULL;
|
49
|
+
(*sigar)->ifconf_len = 0;
|
50
|
+
(*sigar)->log_level = -1; /* log nothing by default */
|
51
|
+
(*sigar)->log_impl = NULL;
|
52
|
+
(*sigar)->log_data = NULL;
|
53
|
+
(*sigar)->ptql_re_impl = NULL;
|
54
|
+
(*sigar)->ptql_re_data = NULL;
|
55
|
+
(*sigar)->self_path = NULL;
|
56
|
+
(*sigar)->fsdev = NULL;
|
57
|
+
(*sigar)->pids = NULL;
|
58
|
+
(*sigar)->proc_cpu = NULL;
|
59
|
+
(*sigar)->net_listen = NULL;
|
60
|
+
(*sigar)->net_services_tcp = NULL;
|
61
|
+
(*sigar)->net_services_udp = NULL;
|
62
|
+
}
|
63
|
+
|
64
|
+
return status;
|
65
|
+
}
|
66
|
+
|
67
|
+
SIGAR_DECLARE(int) sigar_close(sigar_t *sigar)
|
68
|
+
{
|
69
|
+
if (sigar->ifconf_buf) {
|
70
|
+
free(sigar->ifconf_buf);
|
71
|
+
}
|
72
|
+
if (sigar->self_path) {
|
73
|
+
free(sigar->self_path);
|
74
|
+
}
|
75
|
+
if (sigar->pids) {
|
76
|
+
sigar_proc_list_destroy(sigar, sigar->pids);
|
77
|
+
free(sigar->pids);
|
78
|
+
}
|
79
|
+
if (sigar->fsdev) {
|
80
|
+
sigar_cache_destroy(sigar->fsdev);
|
81
|
+
}
|
82
|
+
if (sigar->proc_cpu) {
|
83
|
+
sigar_cache_destroy(sigar->proc_cpu);
|
84
|
+
}
|
85
|
+
if (sigar->net_listen) {
|
86
|
+
sigar_cache_destroy(sigar->net_listen);
|
87
|
+
}
|
88
|
+
if (sigar->net_services_tcp) {
|
89
|
+
sigar_cache_destroy(sigar->net_services_tcp);
|
90
|
+
}
|
91
|
+
if (sigar->net_services_udp) {
|
92
|
+
sigar_cache_destroy(sigar->net_services_udp);
|
93
|
+
}
|
94
|
+
|
95
|
+
return sigar_os_close(sigar);
|
96
|
+
}
|
97
|
+
|
98
|
+
#ifndef __linux__ /* linux has a special case */
|
99
|
+
SIGAR_DECLARE(sigar_pid_t) sigar_pid_get(sigar_t *sigar)
|
100
|
+
{
|
101
|
+
if (!sigar->pid) {
|
102
|
+
sigar->pid = getpid();
|
103
|
+
}
|
104
|
+
|
105
|
+
return sigar->pid;
|
106
|
+
}
|
107
|
+
#endif
|
108
|
+
|
109
|
+
/* XXX: add clear() function */
|
110
|
+
/* XXX: check for stale-ness using start_time */
|
111
|
+
SIGAR_DECLARE(int) sigar_proc_cpu_get(sigar_t *sigar, sigar_pid_t pid,
|
112
|
+
sigar_proc_cpu_t *proccpu)
|
113
|
+
{
|
114
|
+
sigar_cache_entry_t *entry;
|
115
|
+
sigar_proc_cpu_t *prev;
|
116
|
+
sigar_uint64_t otime, time_now = sigar_time_now_millis();
|
117
|
+
sigar_uint64_t time_diff, total_diff;
|
118
|
+
int status;
|
119
|
+
|
120
|
+
if (!sigar->proc_cpu) {
|
121
|
+
sigar->proc_cpu = sigar_cache_new(128);
|
122
|
+
}
|
123
|
+
|
124
|
+
entry = sigar_cache_get(sigar->proc_cpu, pid);
|
125
|
+
if (entry->value) {
|
126
|
+
prev = (sigar_proc_cpu_t *)entry->value;
|
127
|
+
}
|
128
|
+
else {
|
129
|
+
prev = entry->value = malloc(sizeof(*prev));
|
130
|
+
SIGAR_ZERO(prev);
|
131
|
+
}
|
132
|
+
|
133
|
+
time_diff = time_now - prev->last_time;
|
134
|
+
proccpu->last_time = prev->last_time = time_now;
|
135
|
+
|
136
|
+
if (time_diff == 0) {
|
137
|
+
/* we were just called within < 1 second ago. */
|
138
|
+
memcpy(proccpu, prev, sizeof(*proccpu));
|
139
|
+
return SIGAR_OK;
|
140
|
+
}
|
141
|
+
|
142
|
+
otime = prev->total;
|
143
|
+
|
144
|
+
status =
|
145
|
+
sigar_proc_time_get(sigar, pid,
|
146
|
+
(sigar_proc_time_t *)proccpu);
|
147
|
+
|
148
|
+
if (status != SIGAR_OK) {
|
149
|
+
return status;
|
150
|
+
}
|
151
|
+
|
152
|
+
memcpy(prev, proccpu, sizeof(*prev));
|
153
|
+
|
154
|
+
if (proccpu->total < otime) {
|
155
|
+
/* XXX this should not happen */
|
156
|
+
otime = 0;
|
157
|
+
}
|
158
|
+
|
159
|
+
if (otime == 0) {
|
160
|
+
proccpu->percent = 0.0;
|
161
|
+
/* first time called */
|
162
|
+
return SIGAR_OK;
|
163
|
+
}
|
164
|
+
|
165
|
+
total_diff = proccpu->total - otime;
|
166
|
+
proccpu->percent = total_diff / (double)time_diff;
|
167
|
+
|
168
|
+
return SIGAR_OK;
|
169
|
+
}
|
170
|
+
|
171
|
+
SIGAR_DECLARE(int) sigar_proc_stat_get(sigar_t *sigar,
|
172
|
+
sigar_proc_stat_t *procstat)
|
173
|
+
{
|
174
|
+
int status, i;
|
175
|
+
sigar_proc_list_t *pids;
|
176
|
+
|
177
|
+
SIGAR_ZERO(procstat);
|
178
|
+
procstat->threads = SIGAR_FIELD_NOTIMPL;
|
179
|
+
|
180
|
+
if ((status = sigar_proc_list_get(sigar, NULL)) != SIGAR_OK) {
|
181
|
+
return status;
|
182
|
+
}
|
183
|
+
|
184
|
+
pids = sigar->pids;
|
185
|
+
procstat->total = pids->number;
|
186
|
+
|
187
|
+
for (i=0; i<pids->number; i++) {
|
188
|
+
sigar_proc_state_t state;
|
189
|
+
|
190
|
+
status = sigar_proc_state_get(sigar, pids->data[i], &state);
|
191
|
+
if (status != SIGAR_OK) {
|
192
|
+
continue;
|
193
|
+
}
|
194
|
+
|
195
|
+
if (state.threads != SIGAR_FIELD_NOTIMPL) {
|
196
|
+
procstat->threads += state.threads;
|
197
|
+
}
|
198
|
+
|
199
|
+
switch (state.state) {
|
200
|
+
case SIGAR_PROC_STATE_IDLE:
|
201
|
+
procstat->idle++;
|
202
|
+
break;
|
203
|
+
case SIGAR_PROC_STATE_RUN:
|
204
|
+
procstat->running++;
|
205
|
+
break;
|
206
|
+
case SIGAR_PROC_STATE_SLEEP:
|
207
|
+
procstat->sleeping++;
|
208
|
+
break;
|
209
|
+
case SIGAR_PROC_STATE_STOP:
|
210
|
+
procstat->stopped++;
|
211
|
+
break;
|
212
|
+
case SIGAR_PROC_STATE_ZOMBIE:
|
213
|
+
procstat->zombie++;
|
214
|
+
break;
|
215
|
+
default:
|
216
|
+
break;
|
217
|
+
}
|
218
|
+
}
|
219
|
+
|
220
|
+
return SIGAR_OK;
|
221
|
+
}
|
222
|
+
|
223
|
+
SIGAR_DECLARE(int) sigar_sys_info_get(sigar_t *sigar,
|
224
|
+
sigar_sys_info_t *sysinfo)
|
225
|
+
{
|
226
|
+
SIGAR_ZERO(sysinfo);
|
227
|
+
|
228
|
+
#ifndef WIN32
|
229
|
+
sigar_sys_info_get_uname(sysinfo);
|
230
|
+
#endif
|
231
|
+
|
232
|
+
sigar_os_sys_info_get(sigar, sysinfo);
|
233
|
+
|
234
|
+
return SIGAR_OK;
|
235
|
+
}
|
236
|
+
|
237
|
+
#ifndef WIN32
|
238
|
+
|
239
|
+
#include <sys/utsname.h>
|
240
|
+
|
241
|
+
int sigar_sys_info_get_uname(sigar_sys_info_t *sysinfo)
|
242
|
+
{
|
243
|
+
struct utsname name;
|
244
|
+
|
245
|
+
uname(&name);
|
246
|
+
|
247
|
+
SIGAR_SSTRCPY(sysinfo->version, name.release);
|
248
|
+
SIGAR_SSTRCPY(sysinfo->vendor_name, name.sysname);
|
249
|
+
SIGAR_SSTRCPY(sysinfo->name, name.sysname);
|
250
|
+
SIGAR_SSTRCPY(sysinfo->machine, name.machine);
|
251
|
+
SIGAR_SSTRCPY(sysinfo->arch, name.machine);
|
252
|
+
SIGAR_SSTRCPY(sysinfo->patch_level, "unknown");
|
253
|
+
|
254
|
+
return SIGAR_OK;
|
255
|
+
}
|
256
|
+
|
257
|
+
SIGAR_DECLARE(int)
|
258
|
+
sigar_proc_cred_name_get(sigar_t *sigar, sigar_pid_t pid,
|
259
|
+
sigar_proc_cred_name_t *proccredname)
|
260
|
+
{
|
261
|
+
sigar_proc_cred_t cred;
|
262
|
+
|
263
|
+
int status = sigar_proc_cred_get(sigar, pid, &cred);
|
264
|
+
|
265
|
+
if (status != SIGAR_OK) {
|
266
|
+
return status;
|
267
|
+
}
|
268
|
+
|
269
|
+
status = sigar_user_name_get(sigar, cred.uid,
|
270
|
+
proccredname->user,
|
271
|
+
sizeof(proccredname->user));
|
272
|
+
|
273
|
+
if (status != SIGAR_OK) {
|
274
|
+
return status;
|
275
|
+
}
|
276
|
+
|
277
|
+
status = sigar_group_name_get(sigar, cred.gid,
|
278
|
+
proccredname->group,
|
279
|
+
sizeof(proccredname->group));
|
280
|
+
|
281
|
+
return status;
|
282
|
+
}
|
283
|
+
|
284
|
+
#endif /* WIN32 */
|
285
|
+
|
286
|
+
int sigar_proc_list_create(sigar_proc_list_t *proclist)
|
287
|
+
{
|
288
|
+
proclist->number = 0;
|
289
|
+
proclist->size = SIGAR_PROC_LIST_MAX;
|
290
|
+
proclist->data = malloc(sizeof(*(proclist->data)) *
|
291
|
+
proclist->size);
|
292
|
+
return SIGAR_OK;
|
293
|
+
}
|
294
|
+
|
295
|
+
int sigar_proc_list_grow(sigar_proc_list_t *proclist)
|
296
|
+
{
|
297
|
+
proclist->data = realloc(proclist->data,
|
298
|
+
sizeof(*(proclist->data)) *
|
299
|
+
(proclist->size + SIGAR_PROC_LIST_MAX));
|
300
|
+
proclist->size += SIGAR_PROC_LIST_MAX;
|
301
|
+
|
302
|
+
return SIGAR_OK;
|
303
|
+
}
|
304
|
+
|
305
|
+
SIGAR_DECLARE(int) sigar_proc_list_destroy(sigar_t *sigar,
|
306
|
+
sigar_proc_list_t *proclist)
|
307
|
+
{
|
308
|
+
if (proclist->size) {
|
309
|
+
free(proclist->data);
|
310
|
+
proclist->number = proclist->size = 0;
|
311
|
+
}
|
312
|
+
|
313
|
+
return SIGAR_OK;
|
314
|
+
}
|
315
|
+
|
316
|
+
SIGAR_DECLARE(int) sigar_proc_list_get(sigar_t *sigar,
|
317
|
+
sigar_proc_list_t *proclist)
|
318
|
+
{
|
319
|
+
if (proclist == NULL) {
|
320
|
+
/* internal re-use */
|
321
|
+
if (sigar->pids == NULL) {
|
322
|
+
sigar->pids = malloc(sizeof(*sigar->pids));
|
323
|
+
sigar_proc_list_create(sigar->pids);
|
324
|
+
}
|
325
|
+
else {
|
326
|
+
sigar->pids->number = 0;
|
327
|
+
}
|
328
|
+
proclist = sigar->pids;
|
329
|
+
}
|
330
|
+
else {
|
331
|
+
sigar_proc_list_create(proclist);
|
332
|
+
}
|
333
|
+
|
334
|
+
return sigar_os_proc_list_get(sigar, proclist);
|
335
|
+
}
|
336
|
+
|
337
|
+
int sigar_proc_args_create(sigar_proc_args_t *procargs)
|
338
|
+
{
|
339
|
+
procargs->number = 0;
|
340
|
+
procargs->size = SIGAR_PROC_ARGS_MAX;
|
341
|
+
procargs->data = malloc(sizeof(*(procargs->data)) *
|
342
|
+
procargs->size);
|
343
|
+
return SIGAR_OK;
|
344
|
+
}
|
345
|
+
|
346
|
+
int sigar_proc_args_grow(sigar_proc_args_t *procargs)
|
347
|
+
{
|
348
|
+
procargs->data = realloc(procargs->data,
|
349
|
+
sizeof(*(procargs->data)) *
|
350
|
+
(procargs->size + SIGAR_PROC_ARGS_MAX));
|
351
|
+
procargs->size += SIGAR_PROC_ARGS_MAX;
|
352
|
+
|
353
|
+
return SIGAR_OK;
|
354
|
+
}
|
355
|
+
|
356
|
+
SIGAR_DECLARE(int) sigar_proc_args_destroy(sigar_t *sigar,
|
357
|
+
sigar_proc_args_t *procargs)
|
358
|
+
{
|
359
|
+
unsigned int i;
|
360
|
+
|
361
|
+
if (procargs->size) {
|
362
|
+
for (i=0; i<procargs->number; i++) {
|
363
|
+
free(procargs->data[i]);
|
364
|
+
}
|
365
|
+
free(procargs->data);
|
366
|
+
procargs->number = procargs->size = 0;
|
367
|
+
}
|
368
|
+
|
369
|
+
return SIGAR_OK;
|
370
|
+
}
|
371
|
+
|
372
|
+
SIGAR_DECLARE(int) sigar_proc_args_get(sigar_t *sigar,
|
373
|
+
sigar_pid_t pid,
|
374
|
+
sigar_proc_args_t *procargs)
|
375
|
+
{
|
376
|
+
sigar_proc_args_create(procargs);
|
377
|
+
return sigar_os_proc_args_get(sigar, pid, procargs);
|
378
|
+
}
|
379
|
+
|
380
|
+
int sigar_file_system_list_create(sigar_file_system_list_t *fslist)
|
381
|
+
{
|
382
|
+
fslist->number = 0;
|
383
|
+
fslist->size = SIGAR_FS_MAX;
|
384
|
+
fslist->data = malloc(sizeof(*(fslist->data)) *
|
385
|
+
fslist->size);
|
386
|
+
return SIGAR_OK;
|
387
|
+
}
|
388
|
+
|
389
|
+
int sigar_file_system_list_grow(sigar_file_system_list_t *fslist)
|
390
|
+
{
|
391
|
+
fslist->data = realloc(fslist->data,
|
392
|
+
sizeof(*(fslist->data)) *
|
393
|
+
(fslist->size + SIGAR_FS_MAX));
|
394
|
+
fslist->size += SIGAR_FS_MAX;
|
395
|
+
|
396
|
+
return SIGAR_OK;
|
397
|
+
}
|
398
|
+
|
399
|
+
/* indexed with sigar_file_system_type_e */
|
400
|
+
static const char *fstype_names[] = {
|
401
|
+
"unknown", "none", "local", "remote", "ram", "cdrom", "swap"
|
402
|
+
};
|
403
|
+
|
404
|
+
static int sigar_common_fs_type_get(sigar_file_system_t *fsp)
|
405
|
+
{
|
406
|
+
char *type = fsp->sys_type_name;
|
407
|
+
|
408
|
+
switch (*type) {
|
409
|
+
case 'n':
|
410
|
+
if (strEQ(type, "nfs")) {
|
411
|
+
fsp->type = SIGAR_FSTYPE_NETWORK;
|
412
|
+
}
|
413
|
+
break;
|
414
|
+
case 's':
|
415
|
+
if (strEQ(type, "smbfs")) { /* samba */
|
416
|
+
fsp->type = SIGAR_FSTYPE_NETWORK;
|
417
|
+
}
|
418
|
+
else if (strEQ(type, "swap")) {
|
419
|
+
fsp->type = SIGAR_FSTYPE_SWAP;
|
420
|
+
}
|
421
|
+
break;
|
422
|
+
case 'a':
|
423
|
+
if (strEQ(type, "afs")) {
|
424
|
+
fsp->type = SIGAR_FSTYPE_NETWORK;
|
425
|
+
}
|
426
|
+
break;
|
427
|
+
case 'i':
|
428
|
+
if (strEQ(type, "iso9660")) {
|
429
|
+
fsp->type = SIGAR_FSTYPE_CDROM;
|
430
|
+
}
|
431
|
+
break;
|
432
|
+
case 'c':
|
433
|
+
if (strEQ(type, "cvfs")) {
|
434
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
435
|
+
}
|
436
|
+
break;
|
437
|
+
case 'm':
|
438
|
+
if (strEQ(type, "msdos") || strEQ(type, "minix")) {
|
439
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
440
|
+
}
|
441
|
+
break;
|
442
|
+
case 'h':
|
443
|
+
if (strEQ(type, "hpfs")) {
|
444
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
445
|
+
}
|
446
|
+
break;
|
447
|
+
case 'v':
|
448
|
+
if (strEQ(type, "vxfs")) {
|
449
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
450
|
+
}
|
451
|
+
else if (strEQ(type, "vfat")) {
|
452
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
453
|
+
}
|
454
|
+
break;
|
455
|
+
case 'z':
|
456
|
+
if (strEQ(type, "zfs")) {
|
457
|
+
fsp->type = SIGAR_FSTYPE_LOCAL_DISK;
|
458
|
+
}
|
459
|
+
break;
|
460
|
+
}
|
461
|
+
|
462
|
+
return fsp->type;
|
463
|
+
}
|
464
|
+
|
465
|
+
void sigar_fs_type_get(sigar_file_system_t *fsp)
|
466
|
+
{
|
467
|
+
if (!(fsp->type || /* already set */
|
468
|
+
sigar_os_fs_type_get(fsp) || /* try os specifics first */
|
469
|
+
sigar_common_fs_type_get(fsp))) /* try common ones last */
|
470
|
+
{
|
471
|
+
fsp->type = SIGAR_FSTYPE_NONE;
|
472
|
+
}
|
473
|
+
|
474
|
+
if (fsp->type >= SIGAR_FSTYPE_MAX) {
|
475
|
+
fsp->type = SIGAR_FSTYPE_NONE;
|
476
|
+
}
|
477
|
+
|
478
|
+
strcpy(fsp->type_name, fstype_names[fsp->type]);
|
479
|
+
}
|
480
|
+
|
481
|
+
|
482
|
+
SIGAR_DECLARE(int)
|
483
|
+
sigar_file_system_list_destroy(sigar_t *sigar,
|
484
|
+
sigar_file_system_list_t *fslist)
|
485
|
+
{
|
486
|
+
if (fslist->size) {
|
487
|
+
free(fslist->data);
|
488
|
+
fslist->number = fslist->size = 0;
|
489
|
+
}
|
490
|
+
|
491
|
+
return SIGAR_OK;
|
492
|
+
}
|
493
|
+
|
494
|
+
#ifndef NFS_PROGRAM
|
495
|
+
#define NFS_PROGRAM 100003
|
496
|
+
#endif
|
497
|
+
|
498
|
+
#ifndef NFS_VERSION
|
499
|
+
#define NFS_VERSION 2
|
500
|
+
#endif
|
501
|
+
|
502
|
+
SIGAR_DECLARE(int)
|
503
|
+
sigar_file_system_ping(sigar_t *sigar,
|
504
|
+
sigar_file_system_t *fs)
|
505
|
+
{
|
506
|
+
int status = SIGAR_OK;
|
507
|
+
#ifndef WIN32
|
508
|
+
char *ptr;
|
509
|
+
|
510
|
+
if ((fs->type == SIGAR_FSTYPE_NETWORK) &&
|
511
|
+
strEQ(fs->sys_type_name, "nfs") &&
|
512
|
+
(ptr = strchr(fs->dev_name, ':')))
|
513
|
+
{
|
514
|
+
*ptr = '\0'; /* "hostname:/mount" -> "hostname" */
|
515
|
+
|
516
|
+
status = sigar_rpc_ping(fs->dev_name,
|
517
|
+
SIGAR_NETCONN_UDP,
|
518
|
+
NFS_PROGRAM, NFS_VERSION);
|
519
|
+
|
520
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
521
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
522
|
+
"[fs_ping] %s -> %s: %s",
|
523
|
+
fs->dir_name, fs->dev_name,
|
524
|
+
((status == SIGAR_OK) ?
|
525
|
+
"OK" : sigar_rpc_strerror(status)));
|
526
|
+
}
|
527
|
+
|
528
|
+
*ptr = ':'; /* "hostname" -> "hostname:/mount" */
|
529
|
+
}
|
530
|
+
#endif
|
531
|
+
return status;
|
532
|
+
}
|
533
|
+
|
534
|
+
int sigar_cpu_info_list_create(sigar_cpu_info_list_t *cpu_infos)
|
535
|
+
{
|
536
|
+
cpu_infos->number = 0;
|
537
|
+
cpu_infos->size = SIGAR_CPU_INFO_MAX;
|
538
|
+
cpu_infos->data = malloc(sizeof(*(cpu_infos->data)) *
|
539
|
+
cpu_infos->size);
|
540
|
+
return SIGAR_OK;
|
541
|
+
}
|
542
|
+
|
543
|
+
int sigar_cpu_info_list_grow(sigar_cpu_info_list_t *cpu_infos)
|
544
|
+
{
|
545
|
+
cpu_infos->data = realloc(cpu_infos->data,
|
546
|
+
sizeof(*(cpu_infos->data)) *
|
547
|
+
(cpu_infos->size + SIGAR_CPU_INFO_MAX));
|
548
|
+
cpu_infos->size += SIGAR_CPU_INFO_MAX;
|
549
|
+
|
550
|
+
return SIGAR_OK;
|
551
|
+
}
|
552
|
+
|
553
|
+
SIGAR_DECLARE(int)
|
554
|
+
sigar_cpu_info_list_destroy(sigar_t *sigar,
|
555
|
+
sigar_cpu_info_list_t *cpu_infos)
|
556
|
+
{
|
557
|
+
if (cpu_infos->size) {
|
558
|
+
free(cpu_infos->data);
|
559
|
+
cpu_infos->number = cpu_infos->size = 0;
|
560
|
+
}
|
561
|
+
|
562
|
+
return SIGAR_OK;
|
563
|
+
}
|
564
|
+
|
565
|
+
int sigar_cpu_list_create(sigar_cpu_list_t *cpulist)
|
566
|
+
{
|
567
|
+
cpulist->number = 0;
|
568
|
+
cpulist->size = SIGAR_CPU_INFO_MAX;
|
569
|
+
cpulist->data = malloc(sizeof(*(cpulist->data)) *
|
570
|
+
cpulist->size);
|
571
|
+
return SIGAR_OK;
|
572
|
+
}
|
573
|
+
|
574
|
+
int sigar_cpu_list_grow(sigar_cpu_list_t *cpulist)
|
575
|
+
{
|
576
|
+
cpulist->data = realloc(cpulist->data,
|
577
|
+
sizeof(*(cpulist->data)) *
|
578
|
+
(cpulist->size + SIGAR_CPU_INFO_MAX));
|
579
|
+
cpulist->size += SIGAR_CPU_INFO_MAX;
|
580
|
+
|
581
|
+
return SIGAR_OK;
|
582
|
+
}
|
583
|
+
|
584
|
+
SIGAR_DECLARE(int) sigar_cpu_list_destroy(sigar_t *sigar,
|
585
|
+
sigar_cpu_list_t *cpulist)
|
586
|
+
{
|
587
|
+
if (cpulist->size) {
|
588
|
+
free(cpulist->data);
|
589
|
+
cpulist->number = cpulist->size = 0;
|
590
|
+
}
|
591
|
+
|
592
|
+
return SIGAR_OK;
|
593
|
+
}
|
594
|
+
|
595
|
+
int sigar_net_route_list_create(sigar_net_route_list_t *routelist)
|
596
|
+
{
|
597
|
+
routelist->number = 0;
|
598
|
+
routelist->size = SIGAR_NET_ROUTE_LIST_MAX;
|
599
|
+
routelist->data = malloc(sizeof(*(routelist->data)) *
|
600
|
+
routelist->size);
|
601
|
+
return SIGAR_OK;
|
602
|
+
}
|
603
|
+
|
604
|
+
int sigar_net_route_list_grow(sigar_net_route_list_t *routelist)
|
605
|
+
{
|
606
|
+
routelist->data =
|
607
|
+
realloc(routelist->data,
|
608
|
+
sizeof(*(routelist->data)) *
|
609
|
+
(routelist->size + SIGAR_NET_ROUTE_LIST_MAX));
|
610
|
+
routelist->size += SIGAR_NET_ROUTE_LIST_MAX;
|
611
|
+
|
612
|
+
return SIGAR_OK;
|
613
|
+
}
|
614
|
+
|
615
|
+
SIGAR_DECLARE(int) sigar_net_route_list_destroy(sigar_t *sigar,
|
616
|
+
sigar_net_route_list_t *routelist)
|
617
|
+
{
|
618
|
+
if (routelist->size) {
|
619
|
+
free(routelist->data);
|
620
|
+
routelist->number = routelist->size = 0;
|
621
|
+
}
|
622
|
+
|
623
|
+
return SIGAR_OK;
|
624
|
+
}
|
625
|
+
|
626
|
+
int sigar_net_interface_list_create(sigar_net_interface_list_t *iflist)
|
627
|
+
{
|
628
|
+
iflist->number = 0;
|
629
|
+
iflist->size = SIGAR_NET_IFLIST_MAX;
|
630
|
+
iflist->data = malloc(sizeof(*(iflist->data)) *
|
631
|
+
iflist->size);
|
632
|
+
return SIGAR_OK;
|
633
|
+
}
|
634
|
+
|
635
|
+
int sigar_net_interface_list_grow(sigar_net_interface_list_t *iflist)
|
636
|
+
{
|
637
|
+
iflist->data = realloc(iflist->data,
|
638
|
+
sizeof(*(iflist->data)) *
|
639
|
+
(iflist->size + SIGAR_NET_IFLIST_MAX));
|
640
|
+
iflist->size += SIGAR_NET_IFLIST_MAX;
|
641
|
+
|
642
|
+
return SIGAR_OK;
|
643
|
+
}
|
644
|
+
|
645
|
+
SIGAR_DECLARE(int)
|
646
|
+
sigar_net_interface_list_destroy(sigar_t *sigar,
|
647
|
+
sigar_net_interface_list_t *iflist)
|
648
|
+
{
|
649
|
+
unsigned int i;
|
650
|
+
|
651
|
+
if (iflist->size) {
|
652
|
+
for (i=0; i<iflist->number; i++) {
|
653
|
+
free(iflist->data[i]);
|
654
|
+
}
|
655
|
+
free(iflist->data);
|
656
|
+
iflist->number = iflist->size = 0;
|
657
|
+
}
|
658
|
+
|
659
|
+
return SIGAR_OK;
|
660
|
+
}
|
661
|
+
|
662
|
+
int sigar_net_connection_list_create(sigar_net_connection_list_t *connlist)
|
663
|
+
{
|
664
|
+
connlist->number = 0;
|
665
|
+
connlist->size = SIGAR_NET_CONNLIST_MAX;
|
666
|
+
connlist->data = malloc(sizeof(*(connlist->data)) *
|
667
|
+
connlist->size);
|
668
|
+
return SIGAR_OK;
|
669
|
+
}
|
670
|
+
|
671
|
+
int sigar_net_connection_list_grow(sigar_net_connection_list_t *connlist)
|
672
|
+
{
|
673
|
+
connlist->data =
|
674
|
+
realloc(connlist->data,
|
675
|
+
sizeof(*(connlist->data)) *
|
676
|
+
(connlist->size + SIGAR_NET_CONNLIST_MAX));
|
677
|
+
connlist->size += SIGAR_NET_CONNLIST_MAX;
|
678
|
+
|
679
|
+
return SIGAR_OK;
|
680
|
+
}
|
681
|
+
|
682
|
+
SIGAR_DECLARE(int)
|
683
|
+
sigar_net_connection_list_destroy(sigar_t *sigar,
|
684
|
+
sigar_net_connection_list_t *connlist)
|
685
|
+
{
|
686
|
+
if (connlist->size) {
|
687
|
+
free(connlist->data);
|
688
|
+
connlist->number = connlist->size = 0;
|
689
|
+
}
|
690
|
+
|
691
|
+
return SIGAR_OK;
|
692
|
+
}
|
693
|
+
|
694
|
+
#if !defined(__linux__)
|
695
|
+
/*
|
696
|
+
* implement sigar_net_connection_list_get using sigar_net_connection_walk
|
697
|
+
* linux has its own list_get impl.
|
698
|
+
*/
|
699
|
+
static int net_connection_list_walker(sigar_net_connection_walker_t *walker,
|
700
|
+
sigar_net_connection_t *conn)
|
701
|
+
{
|
702
|
+
sigar_net_connection_list_t *connlist =
|
703
|
+
(sigar_net_connection_list_t *)walker->data;
|
704
|
+
|
705
|
+
SIGAR_NET_CONNLIST_GROW(connlist);
|
706
|
+
memcpy(&connlist->data[connlist->number++],
|
707
|
+
conn, sizeof(*conn));
|
708
|
+
|
709
|
+
return SIGAR_OK; /* continue loop */
|
710
|
+
}
|
711
|
+
|
712
|
+
SIGAR_DECLARE(int)
|
713
|
+
sigar_net_connection_list_get(sigar_t *sigar,
|
714
|
+
sigar_net_connection_list_t *connlist,
|
715
|
+
int flags)
|
716
|
+
{
|
717
|
+
int status;
|
718
|
+
sigar_net_connection_walker_t walker;
|
719
|
+
|
720
|
+
sigar_net_connection_list_create(connlist);
|
721
|
+
|
722
|
+
walker.sigar = sigar;
|
723
|
+
walker.flags = flags;
|
724
|
+
walker.data = connlist;
|
725
|
+
walker.add_connection = net_connection_list_walker;
|
726
|
+
|
727
|
+
status = sigar_net_connection_walk(&walker);
|
728
|
+
|
729
|
+
if (status != SIGAR_OK) {
|
730
|
+
sigar_net_connection_list_destroy(sigar, connlist);
|
731
|
+
}
|
732
|
+
|
733
|
+
return status;
|
734
|
+
}
|
735
|
+
#endif
|
736
|
+
|
737
|
+
static void sigar_net_listen_address_add(sigar_t *sigar,
|
738
|
+
sigar_net_connection_t *conn)
|
739
|
+
{
|
740
|
+
sigar_cache_entry_t *entry =
|
741
|
+
sigar_cache_get(sigar->net_listen, conn->local_port);
|
742
|
+
|
743
|
+
if (entry->value) {
|
744
|
+
if (conn->local_address.family == SIGAR_AF_INET6) {
|
745
|
+
return; /* prefer ipv4 */
|
746
|
+
}
|
747
|
+
}
|
748
|
+
else {
|
749
|
+
entry->value = malloc(sizeof(conn->local_address));
|
750
|
+
}
|
751
|
+
|
752
|
+
memcpy(entry->value, &conn->local_address,
|
753
|
+
sizeof(conn->local_address));
|
754
|
+
}
|
755
|
+
|
756
|
+
SIGAR_DECLARE(int)
|
757
|
+
sigar_net_listen_address_get(sigar_t *sigar,
|
758
|
+
unsigned long port,
|
759
|
+
sigar_net_address_t *address)
|
760
|
+
{
|
761
|
+
if (!sigar->net_listen ||
|
762
|
+
!sigar_cache_find(sigar->net_listen, port))
|
763
|
+
{
|
764
|
+
sigar_net_stat_t netstat;
|
765
|
+
int status =
|
766
|
+
sigar_net_stat_get(sigar, &netstat,
|
767
|
+
SIGAR_NETCONN_SERVER|SIGAR_NETCONN_TCP);
|
768
|
+
|
769
|
+
if (status != SIGAR_OK) {
|
770
|
+
return status;
|
771
|
+
}
|
772
|
+
}
|
773
|
+
|
774
|
+
if (sigar_cache_find(sigar->net_listen, port)) {
|
775
|
+
void *value = sigar_cache_get(sigar->net_listen, port)->value;
|
776
|
+
memcpy(address, value, sizeof(*address));
|
777
|
+
return SIGAR_OK;
|
778
|
+
}
|
779
|
+
else {
|
780
|
+
return ENOENT;
|
781
|
+
}
|
782
|
+
}
|
783
|
+
|
784
|
+
typedef struct {
|
785
|
+
sigar_net_stat_t *netstat;
|
786
|
+
sigar_net_connection_list_t *connlist;
|
787
|
+
} net_stat_getter_t;
|
788
|
+
|
789
|
+
static int net_stat_walker(sigar_net_connection_walker_t *walker,
|
790
|
+
sigar_net_connection_t *conn)
|
791
|
+
{
|
792
|
+
int state = conn->state;
|
793
|
+
sigar_cache_t *listen_ports = walker->sigar->net_listen;
|
794
|
+
net_stat_getter_t *getter =
|
795
|
+
(net_stat_getter_t *)walker->data;
|
796
|
+
|
797
|
+
if (conn->type == SIGAR_NETCONN_TCP) {
|
798
|
+
getter->netstat->tcp_states[state]++;
|
799
|
+
|
800
|
+
/* XXX listen_ports may get stale */
|
801
|
+
if (state == SIGAR_TCP_LISTEN) {
|
802
|
+
sigar_net_listen_address_add(walker->sigar, conn);
|
803
|
+
}
|
804
|
+
else {
|
805
|
+
if (sigar_cache_find(listen_ports,
|
806
|
+
conn->local_port))
|
807
|
+
{
|
808
|
+
getter->netstat->tcp_inbound_total++;
|
809
|
+
}
|
810
|
+
else {
|
811
|
+
getter->netstat->tcp_outbound_total++;
|
812
|
+
}
|
813
|
+
}
|
814
|
+
}
|
815
|
+
else if (conn->type == SIGAR_NETCONN_UDP) {
|
816
|
+
/*XXX*/
|
817
|
+
}
|
818
|
+
|
819
|
+
getter->netstat->all_inbound_total =
|
820
|
+
getter->netstat->tcp_inbound_total;
|
821
|
+
|
822
|
+
getter->netstat->all_outbound_total =
|
823
|
+
getter->netstat->tcp_outbound_total;
|
824
|
+
|
825
|
+
return SIGAR_OK;
|
826
|
+
}
|
827
|
+
|
828
|
+
SIGAR_DECLARE(int)
|
829
|
+
sigar_net_stat_get(sigar_t *sigar,
|
830
|
+
sigar_net_stat_t *netstat,
|
831
|
+
int flags)
|
832
|
+
{
|
833
|
+
sigar_net_connection_walker_t walker;
|
834
|
+
net_stat_getter_t getter;
|
835
|
+
|
836
|
+
if (!sigar->net_listen) {
|
837
|
+
sigar->net_listen = sigar_cache_new(32);
|
838
|
+
}
|
839
|
+
|
840
|
+
SIGAR_ZERO(netstat);
|
841
|
+
|
842
|
+
getter.netstat = netstat;
|
843
|
+
|
844
|
+
walker.sigar = sigar;
|
845
|
+
walker.data = &getter;
|
846
|
+
walker.add_connection = net_stat_walker;
|
847
|
+
|
848
|
+
walker.flags = flags;
|
849
|
+
|
850
|
+
return sigar_net_connection_walk(&walker);
|
851
|
+
}
|
852
|
+
|
853
|
+
typedef struct {
|
854
|
+
sigar_net_stat_t *netstat;
|
855
|
+
sigar_net_address_t *address;
|
856
|
+
unsigned long port;
|
857
|
+
} net_stat_port_getter_t;
|
858
|
+
|
859
|
+
static int net_stat_port_walker(sigar_net_connection_walker_t *walker,
|
860
|
+
sigar_net_connection_t *conn)
|
861
|
+
{
|
862
|
+
net_stat_port_getter_t *getter =
|
863
|
+
(net_stat_port_getter_t *)walker->data;
|
864
|
+
sigar_net_stat_t *netstat = getter->netstat;
|
865
|
+
|
866
|
+
if (conn->type == SIGAR_NETCONN_TCP) {
|
867
|
+
if (conn->local_port == getter->port) {
|
868
|
+
netstat->all_inbound_total++;
|
869
|
+
|
870
|
+
if (sigar_net_address_equals(getter->address,
|
871
|
+
&conn->local_address) == SIGAR_OK)
|
872
|
+
{
|
873
|
+
netstat->tcp_inbound_total++;
|
874
|
+
}
|
875
|
+
}
|
876
|
+
else if (conn->remote_port == getter->port) {
|
877
|
+
netstat->all_outbound_total++;
|
878
|
+
|
879
|
+
if (sigar_net_address_equals(getter->address,
|
880
|
+
&conn->remote_address) == SIGAR_OK)
|
881
|
+
{
|
882
|
+
netstat->tcp_outbound_total++;
|
883
|
+
}
|
884
|
+
}
|
885
|
+
else {
|
886
|
+
return SIGAR_OK;
|
887
|
+
}
|
888
|
+
|
889
|
+
netstat->tcp_states[conn->state]++;
|
890
|
+
}
|
891
|
+
else if (conn->type == SIGAR_NETCONN_UDP) {
|
892
|
+
/*XXX*/
|
893
|
+
}
|
894
|
+
|
895
|
+
return SIGAR_OK;
|
896
|
+
}
|
897
|
+
|
898
|
+
SIGAR_DECLARE(int)
|
899
|
+
sigar_net_stat_port_get(sigar_t *sigar,
|
900
|
+
sigar_net_stat_t *netstat,
|
901
|
+
int flags,
|
902
|
+
sigar_net_address_t *address,
|
903
|
+
unsigned long port)
|
904
|
+
{
|
905
|
+
sigar_net_connection_walker_t walker;
|
906
|
+
net_stat_port_getter_t getter;
|
907
|
+
|
908
|
+
SIGAR_ZERO(netstat);
|
909
|
+
|
910
|
+
getter.netstat = netstat;
|
911
|
+
getter.address = address;
|
912
|
+
getter.port = port;
|
913
|
+
|
914
|
+
walker.sigar = sigar;
|
915
|
+
walker.data = &getter;
|
916
|
+
walker.add_connection = net_stat_port_walker;
|
917
|
+
|
918
|
+
walker.flags = flags;
|
919
|
+
|
920
|
+
if (SIGAR_LOG_IS_DEBUG(sigar)) {
|
921
|
+
char name[SIGAR_FQDN_LEN];
|
922
|
+
sigar_net_address_to_string(sigar, address, name);
|
923
|
+
|
924
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
925
|
+
"[net_stat_port] using address '%s:%d'",
|
926
|
+
name, port);
|
927
|
+
}
|
928
|
+
|
929
|
+
return sigar_net_connection_walk(&walker);
|
930
|
+
}
|
931
|
+
|
932
|
+
static int tcp_curr_estab_count(sigar_net_connection_walker_t *walker,
|
933
|
+
sigar_net_connection_t *conn)
|
934
|
+
{
|
935
|
+
if ((conn->state == SIGAR_TCP_ESTABLISHED) ||
|
936
|
+
(conn->state == SIGAR_TCP_CLOSE_WAIT))
|
937
|
+
{
|
938
|
+
((sigar_tcp_t *)walker->data)->curr_estab++;
|
939
|
+
}
|
940
|
+
|
941
|
+
return SIGAR_OK;
|
942
|
+
}
|
943
|
+
|
944
|
+
/* TCP-MIB::tcpCurrEstab */
|
945
|
+
int sigar_tcp_curr_estab(sigar_t *sigar, sigar_tcp_t *tcp)
|
946
|
+
{
|
947
|
+
sigar_net_connection_walker_t walker;
|
948
|
+
|
949
|
+
walker.sigar = sigar;
|
950
|
+
walker.data = tcp;
|
951
|
+
walker.add_connection = tcp_curr_estab_count;
|
952
|
+
walker.flags = SIGAR_NETCONN_CLIENT|SIGAR_NETCONN_TCP;
|
953
|
+
|
954
|
+
tcp->curr_estab = 0;
|
955
|
+
|
956
|
+
return sigar_net_connection_walk(&walker);
|
957
|
+
}
|
958
|
+
|
959
|
+
int sigar_who_list_create(sigar_who_list_t *wholist)
|
960
|
+
{
|
961
|
+
wholist->number = 0;
|
962
|
+
wholist->size = SIGAR_WHO_LIST_MAX;
|
963
|
+
wholist->data = malloc(sizeof(*(wholist->data)) *
|
964
|
+
wholist->size);
|
965
|
+
return SIGAR_OK;
|
966
|
+
}
|
967
|
+
|
968
|
+
int sigar_who_list_grow(sigar_who_list_t *wholist)
|
969
|
+
{
|
970
|
+
wholist->data = realloc(wholist->data,
|
971
|
+
sizeof(*(wholist->data)) *
|
972
|
+
(wholist->size + SIGAR_WHO_LIST_MAX));
|
973
|
+
wholist->size += SIGAR_WHO_LIST_MAX;
|
974
|
+
|
975
|
+
return SIGAR_OK;
|
976
|
+
}
|
977
|
+
|
978
|
+
SIGAR_DECLARE(int) sigar_who_list_destroy(sigar_t *sigar,
|
979
|
+
sigar_who_list_t *wholist)
|
980
|
+
{
|
981
|
+
if (wholist->size) {
|
982
|
+
free(wholist->data);
|
983
|
+
wholist->number = wholist->size = 0;
|
984
|
+
}
|
985
|
+
|
986
|
+
return SIGAR_OK;
|
987
|
+
}
|
988
|
+
|
989
|
+
#ifdef DARWIN
|
990
|
+
#include <AvailabilityMacros.h>
|
991
|
+
#endif
|
992
|
+
#ifdef MAC_OS_X_VERSION_10_5
|
993
|
+
# if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5
|
994
|
+
# define SIGAR_NO_UTMP
|
995
|
+
# endif
|
996
|
+
/* else 10.4 and earlier or compiled with -mmacosx-version-min=10.3 */
|
997
|
+
#endif
|
998
|
+
|
999
|
+
#if defined(__sun)
|
1000
|
+
# include <utmpx.h>
|
1001
|
+
# define SIGAR_UTMP_FILE _UTMPX_FILE
|
1002
|
+
# define ut_time ut_tv.tv_sec
|
1003
|
+
#elif defined(WIN32)
|
1004
|
+
/* XXX may not be the default */
|
1005
|
+
#define SIGAR_UTMP_FILE "C:\\cygwin\\var\\run\\utmp"
|
1006
|
+
#define UT_LINESIZE 16
|
1007
|
+
#define UT_NAMESIZE 16
|
1008
|
+
#define UT_HOSTSIZE 256
|
1009
|
+
#define UT_IDLEN 2
|
1010
|
+
#define ut_name ut_user
|
1011
|
+
|
1012
|
+
struct utmp {
|
1013
|
+
short ut_type;
|
1014
|
+
int ut_pid;
|
1015
|
+
char ut_line[UT_LINESIZE];
|
1016
|
+
char ut_id[UT_IDLEN];
|
1017
|
+
time_t ut_time;
|
1018
|
+
char ut_user[UT_NAMESIZE];
|
1019
|
+
char ut_host[UT_HOSTSIZE];
|
1020
|
+
long ut_addr;
|
1021
|
+
};
|
1022
|
+
#elif defined(NETWARE)
|
1023
|
+
static char *getpass(const char *prompt)
|
1024
|
+
{
|
1025
|
+
static char password[BUFSIZ];
|
1026
|
+
|
1027
|
+
fputs(prompt, stderr);
|
1028
|
+
fgets((char *)&password, sizeof(password), stdin);
|
1029
|
+
|
1030
|
+
return (char *)&password;
|
1031
|
+
}
|
1032
|
+
#elif !defined(SIGAR_NO_UTMP)
|
1033
|
+
# include <utmp.h>
|
1034
|
+
# ifdef UTMP_FILE
|
1035
|
+
# define SIGAR_UTMP_FILE UTMP_FILE
|
1036
|
+
# else
|
1037
|
+
# define SIGAR_UTMP_FILE _PATH_UTMP
|
1038
|
+
# endif
|
1039
|
+
#endif
|
1040
|
+
|
1041
|
+
#if defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__NetBSD__) || defined(DARWIN)
|
1042
|
+
# define ut_user ut_name
|
1043
|
+
#endif
|
1044
|
+
|
1045
|
+
#ifdef DARWIN
|
1046
|
+
/* XXX from utmpx.h; sizeof changed in 10.5 */
|
1047
|
+
/* additionally, utmpx does not work on 10.4 */
|
1048
|
+
#define SIGAR_HAS_UTMPX
|
1049
|
+
#define _PATH_UTMPX "/var/run/utmpx"
|
1050
|
+
#define _UTX_USERSIZE 256 /* matches MAXLOGNAME */
|
1051
|
+
#define _UTX_LINESIZE 32
|
1052
|
+
#define _UTX_IDSIZE 4
|
1053
|
+
#define _UTX_HOSTSIZE 256
|
1054
|
+
struct utmpx {
|
1055
|
+
char ut_user[_UTX_USERSIZE]; /* login name */
|
1056
|
+
char ut_id[_UTX_IDSIZE]; /* id */
|
1057
|
+
char ut_line[_UTX_LINESIZE]; /* tty name */
|
1058
|
+
pid_t ut_pid; /* process id creating the entry */
|
1059
|
+
short ut_type; /* type of this entry */
|
1060
|
+
struct timeval ut_tv; /* time entry was created */
|
1061
|
+
char ut_host[_UTX_HOSTSIZE]; /* host name */
|
1062
|
+
__uint32_t ut_pad[16]; /* reserved for future use */
|
1063
|
+
};
|
1064
|
+
#define ut_xtime ut_tv.tv_sec
|
1065
|
+
#define UTMPX_USER_PROCESS 7
|
1066
|
+
/* end utmpx.h */
|
1067
|
+
#define SIGAR_UTMPX_FILE _PATH_UTMPX
|
1068
|
+
#endif
|
1069
|
+
|
1070
|
+
#if !defined(NETWARE) && !defined(_AIX)
|
1071
|
+
|
1072
|
+
#define WHOCPY(dest, src) \
|
1073
|
+
SIGAR_SSTRCPY(dest, src); \
|
1074
|
+
if (sizeof(src) < sizeof(dest)) \
|
1075
|
+
dest[sizeof(src)] = '\0'
|
1076
|
+
|
1077
|
+
#ifdef SIGAR_HAS_UTMPX
|
1078
|
+
static int sigar_who_utmpx(sigar_t *sigar,
|
1079
|
+
sigar_who_list_t *wholist)
|
1080
|
+
{
|
1081
|
+
FILE *fp;
|
1082
|
+
struct utmpx ut;
|
1083
|
+
|
1084
|
+
if (!(fp = fopen(SIGAR_UTMPX_FILE, "r"))) {
|
1085
|
+
return errno;
|
1086
|
+
}
|
1087
|
+
|
1088
|
+
while (fread(&ut, sizeof(ut), 1, fp) == 1) {
|
1089
|
+
sigar_who_t *who;
|
1090
|
+
|
1091
|
+
if (*ut.ut_user == '\0') {
|
1092
|
+
continue;
|
1093
|
+
}
|
1094
|
+
|
1095
|
+
#ifdef UTMPX_USER_PROCESS
|
1096
|
+
if (ut.ut_type != UTMPX_USER_PROCESS) {
|
1097
|
+
continue;
|
1098
|
+
}
|
1099
|
+
#endif
|
1100
|
+
|
1101
|
+
SIGAR_WHO_LIST_GROW(wholist);
|
1102
|
+
who = &wholist->data[wholist->number++];
|
1103
|
+
|
1104
|
+
WHOCPY(who->user, ut.ut_user);
|
1105
|
+
WHOCPY(who->device, ut.ut_line);
|
1106
|
+
WHOCPY(who->host, ut.ut_host);
|
1107
|
+
|
1108
|
+
who->time = ut.ut_xtime;
|
1109
|
+
}
|
1110
|
+
|
1111
|
+
fclose(fp);
|
1112
|
+
|
1113
|
+
return SIGAR_OK;
|
1114
|
+
}
|
1115
|
+
#endif
|
1116
|
+
|
1117
|
+
#if defined(SIGAR_NO_UTMP) && defined(SIGAR_HAS_UTMPX)
|
1118
|
+
#define sigar_who_utmp sigar_who_utmpx
|
1119
|
+
#else
|
1120
|
+
static int sigar_who_utmp(sigar_t *sigar,
|
1121
|
+
sigar_who_list_t *wholist)
|
1122
|
+
{
|
1123
|
+
FILE *fp;
|
1124
|
+
#ifdef __sun
|
1125
|
+
/* use futmpx w/ pid32_t for sparc64 */
|
1126
|
+
struct futmpx ut;
|
1127
|
+
#else
|
1128
|
+
struct utmp ut;
|
1129
|
+
#endif
|
1130
|
+
if (!(fp = fopen(SIGAR_UTMP_FILE, "r"))) {
|
1131
|
+
#ifdef SIGAR_HAS_UTMPX
|
1132
|
+
/* Darwin 10.5 */
|
1133
|
+
return sigar_who_utmpx(sigar, wholist);
|
1134
|
+
#endif
|
1135
|
+
return errno;
|
1136
|
+
}
|
1137
|
+
|
1138
|
+
while (fread(&ut, sizeof(ut), 1, fp) == 1) {
|
1139
|
+
sigar_who_t *who;
|
1140
|
+
|
1141
|
+
if (*ut.ut_name == '\0') {
|
1142
|
+
continue;
|
1143
|
+
}
|
1144
|
+
|
1145
|
+
#ifdef USER_PROCESS
|
1146
|
+
if (ut.ut_type != USER_PROCESS) {
|
1147
|
+
continue;
|
1148
|
+
}
|
1149
|
+
#endif
|
1150
|
+
|
1151
|
+
SIGAR_WHO_LIST_GROW(wholist);
|
1152
|
+
who = &wholist->data[wholist->number++];
|
1153
|
+
|
1154
|
+
WHOCPY(who->user, ut.ut_user);
|
1155
|
+
WHOCPY(who->device, ut.ut_line);
|
1156
|
+
WHOCPY(who->host, ut.ut_host);
|
1157
|
+
|
1158
|
+
who->time = ut.ut_time;
|
1159
|
+
}
|
1160
|
+
|
1161
|
+
fclose(fp);
|
1162
|
+
|
1163
|
+
return SIGAR_OK;
|
1164
|
+
}
|
1165
|
+
#endif /* SIGAR_NO_UTMP */
|
1166
|
+
#endif /* NETWARE */
|
1167
|
+
|
1168
|
+
#if defined(WIN32)
|
1169
|
+
|
1170
|
+
int sigar_who_list_get_win32(sigar_t *sigar,
|
1171
|
+
sigar_who_list_t *wholist);
|
1172
|
+
|
1173
|
+
SIGAR_DECLARE(int) sigar_who_list_get(sigar_t *sigar,
|
1174
|
+
sigar_who_list_t *wholist)
|
1175
|
+
{
|
1176
|
+
sigar_who_list_create(wholist);
|
1177
|
+
|
1178
|
+
/* cygwin ssh */
|
1179
|
+
sigar_who_utmp(sigar, wholist);
|
1180
|
+
|
1181
|
+
sigar_who_list_get_win32(sigar, wholist);
|
1182
|
+
|
1183
|
+
return SIGAR_OK;
|
1184
|
+
}
|
1185
|
+
|
1186
|
+
SIGAR_DECLARE(int) sigar_resource_limit_get(sigar_t *sigar,
|
1187
|
+
sigar_resource_limit_t *rlimit)
|
1188
|
+
{
|
1189
|
+
MEMORY_BASIC_INFORMATION meminfo;
|
1190
|
+
memset(rlimit, 0x7fffffff, sizeof(*rlimit));
|
1191
|
+
|
1192
|
+
if (VirtualQuery((LPCVOID)&meminfo, &meminfo, sizeof(meminfo))) {
|
1193
|
+
rlimit->stack_cur =
|
1194
|
+
(DWORD)&meminfo - (DWORD)meminfo.AllocationBase;
|
1195
|
+
rlimit->stack_max =
|
1196
|
+
((DWORD)meminfo.BaseAddress + meminfo.RegionSize) -
|
1197
|
+
(DWORD)meminfo.AllocationBase;
|
1198
|
+
}
|
1199
|
+
|
1200
|
+
rlimit->virtual_memory_max = rlimit->virtual_memory_cur =
|
1201
|
+
0x80000000UL;
|
1202
|
+
|
1203
|
+
return SIGAR_OK;
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
#elif defined(NETWARE)
|
1207
|
+
int sigar_resource_limit_get(sigar_t *sigar,
|
1208
|
+
sigar_resource_limit_t *rlimit)
|
1209
|
+
{
|
1210
|
+
return SIGAR_ENOTIMPL;
|
1211
|
+
}
|
1212
|
+
|
1213
|
+
int sigar_who_list_get(sigar_t *sigar,
|
1214
|
+
sigar_who_list_t *wholist)
|
1215
|
+
{
|
1216
|
+
return SIGAR_ENOTIMPL;
|
1217
|
+
}
|
1218
|
+
#else
|
1219
|
+
|
1220
|
+
#ifndef _AIX
|
1221
|
+
int sigar_who_list_get(sigar_t *sigar,
|
1222
|
+
sigar_who_list_t *wholist)
|
1223
|
+
{
|
1224
|
+
int status;
|
1225
|
+
|
1226
|
+
sigar_who_list_create(wholist);
|
1227
|
+
|
1228
|
+
status = sigar_who_utmp(sigar, wholist);
|
1229
|
+
if (status != SIGAR_OK) {
|
1230
|
+
sigar_who_list_destroy(sigar, wholist);
|
1231
|
+
return status;
|
1232
|
+
}
|
1233
|
+
|
1234
|
+
return SIGAR_OK;
|
1235
|
+
}
|
1236
|
+
#endif
|
1237
|
+
|
1238
|
+
static int sigar_get_default_gateway(sigar_t *sigar,
|
1239
|
+
char *gateway)
|
1240
|
+
{
|
1241
|
+
int status, i;
|
1242
|
+
sigar_net_route_list_t routelist;
|
1243
|
+
|
1244
|
+
status = sigar_net_route_list_get(sigar, &routelist);
|
1245
|
+
if (status != SIGAR_OK) {
|
1246
|
+
return status;
|
1247
|
+
}
|
1248
|
+
|
1249
|
+
for (i=0; i<routelist.number; i++) {
|
1250
|
+
if ((routelist.data[i].flags & SIGAR_RTF_GATEWAY) &&
|
1251
|
+
(routelist.data[i].destination.addr.in == 0))
|
1252
|
+
{
|
1253
|
+
sigar_net_address_to_string(sigar,
|
1254
|
+
&routelist.data[i].gateway,
|
1255
|
+
gateway);
|
1256
|
+
break;
|
1257
|
+
}
|
1258
|
+
}
|
1259
|
+
|
1260
|
+
sigar_net_route_list_destroy(sigar, &routelist);
|
1261
|
+
|
1262
|
+
return SIGAR_OK;
|
1263
|
+
}
|
1264
|
+
|
1265
|
+
int sigar_net_info_get(sigar_t *sigar,
|
1266
|
+
sigar_net_info_t *netinfo)
|
1267
|
+
{
|
1268
|
+
int size;
|
1269
|
+
char buffer[BUFSIZ], *ptr;
|
1270
|
+
FILE *fp;
|
1271
|
+
|
1272
|
+
SIGAR_ZERO(netinfo);
|
1273
|
+
|
1274
|
+
if ((fp = fopen("/etc/resolv.conf", "r"))) {
|
1275
|
+
while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
|
1276
|
+
int len;
|
1277
|
+
|
1278
|
+
SIGAR_SKIP_SPACE(ptr);
|
1279
|
+
if ((*ptr == '#') ||
|
1280
|
+
!(ptr = strstr(ptr, "nameserver")))
|
1281
|
+
{
|
1282
|
+
continue;
|
1283
|
+
}
|
1284
|
+
ptr += 10;
|
1285
|
+
SIGAR_SKIP_SPACE(ptr);
|
1286
|
+
|
1287
|
+
len = strlen(ptr);
|
1288
|
+
ptr[len-1] = '\0'; /* chop \n */
|
1289
|
+
|
1290
|
+
if (!netinfo->primary_dns[0]) {
|
1291
|
+
SIGAR_SSTRCPY(netinfo->primary_dns, ptr);
|
1292
|
+
}
|
1293
|
+
else if (!netinfo->secondary_dns[0]) {
|
1294
|
+
SIGAR_SSTRCPY(netinfo->secondary_dns, ptr);
|
1295
|
+
}
|
1296
|
+
else {
|
1297
|
+
break;
|
1298
|
+
}
|
1299
|
+
}
|
1300
|
+
fclose(fp);
|
1301
|
+
} /* else /etc/resolv.conf may not exist if unplugged (MacOSX) */
|
1302
|
+
|
1303
|
+
size = sizeof(netinfo->host_name)-1;
|
1304
|
+
if (gethostname(netinfo->host_name, size) == 0) {
|
1305
|
+
netinfo->host_name[size] = '\0';
|
1306
|
+
}
|
1307
|
+
else {
|
1308
|
+
netinfo->host_name[0] = '\0';
|
1309
|
+
}
|
1310
|
+
|
1311
|
+
size = sizeof(netinfo->domain_name)-1;
|
1312
|
+
if (getdomainname(netinfo->domain_name, size) == 0) {
|
1313
|
+
netinfo->domain_name[size] = '\0';
|
1314
|
+
}
|
1315
|
+
else {
|
1316
|
+
netinfo->domain_name[0] = '\0';
|
1317
|
+
}
|
1318
|
+
|
1319
|
+
sigar_get_default_gateway(sigar, netinfo->default_gateway);
|
1320
|
+
|
1321
|
+
return SIGAR_OK;
|
1322
|
+
}
|
1323
|
+
|
1324
|
+
#include <sys/resource.h>
|
1325
|
+
|
1326
|
+
#define OffsetOf(structure, field) \
|
1327
|
+
(size_t)(&((structure *)NULL)->field)
|
1328
|
+
|
1329
|
+
#define RlimitOffsets(field) \
|
1330
|
+
OffsetOf(sigar_resource_limit_t, field##_cur), \
|
1331
|
+
OffsetOf(sigar_resource_limit_t, field##_max)
|
1332
|
+
|
1333
|
+
#define RlimitSet(structure, ptr, val) \
|
1334
|
+
*(sigar_uint64_t *)((char *)structure + (int)(long)ptr) = val
|
1335
|
+
|
1336
|
+
typedef struct {
|
1337
|
+
int resource;
|
1338
|
+
int factor;
|
1339
|
+
size_t cur;
|
1340
|
+
size_t max;
|
1341
|
+
} rlimit_field_t;
|
1342
|
+
|
1343
|
+
#ifndef RLIMIT_RSS
|
1344
|
+
#define RLIMIT_RSS (RLIM_NLIMITS+1)
|
1345
|
+
#endif
|
1346
|
+
|
1347
|
+
#ifndef RLIMIT_NPROC
|
1348
|
+
#define RLIMIT_NPROC (RLIM_NLIMITS+2)
|
1349
|
+
#endif
|
1350
|
+
|
1351
|
+
#define RLIMIT_PSIZE (RLIM_NLIMITS+3)
|
1352
|
+
|
1353
|
+
#ifndef RLIMIT_AS
|
1354
|
+
# if defined(RLIMIT_VMEM)
|
1355
|
+
# define RLIMIT_AS RLIMIT_VMEM
|
1356
|
+
# elif defined(RLIMIT_RSS)
|
1357
|
+
# define RLIMIT_AS RLIMIT_RSS
|
1358
|
+
# endif
|
1359
|
+
#endif
|
1360
|
+
|
1361
|
+
static rlimit_field_t sigar_rlimits[] = {
|
1362
|
+
{ RLIMIT_CPU, 1, RlimitOffsets(cpu) },
|
1363
|
+
{ RLIMIT_FSIZE, 1024, RlimitOffsets(file_size) },
|
1364
|
+
{ RLIMIT_DATA, 1024, RlimitOffsets(data) },
|
1365
|
+
{ RLIMIT_STACK, 1024, RlimitOffsets(stack) },
|
1366
|
+
{ RLIMIT_PSIZE, 512, RlimitOffsets(pipe_size) },
|
1367
|
+
{ RLIMIT_CORE, 1024, RlimitOffsets(core) },
|
1368
|
+
{ RLIMIT_RSS, 1024, RlimitOffsets(memory) },
|
1369
|
+
{ RLIMIT_NPROC, 1, RlimitOffsets(processes) },
|
1370
|
+
{ RLIMIT_NOFILE, 1, RlimitOffsets(open_files) },
|
1371
|
+
{ RLIMIT_AS, 1024, RlimitOffsets(virtual_memory) },
|
1372
|
+
{ -1 }
|
1373
|
+
};
|
1374
|
+
|
1375
|
+
#define RlimitScale(val) \
|
1376
|
+
if (val != RLIM_INFINITY) val /= r->factor
|
1377
|
+
|
1378
|
+
#define RlimitHS(val) \
|
1379
|
+
rl.rlim_cur = rl.rlim_max = (val)
|
1380
|
+
|
1381
|
+
int sigar_resource_limit_get(sigar_t *sigar,
|
1382
|
+
sigar_resource_limit_t *rlimit)
|
1383
|
+
{
|
1384
|
+
int i;
|
1385
|
+
|
1386
|
+
for (i=0; sigar_rlimits[i].resource != -1; i++) {
|
1387
|
+
struct rlimit rl;
|
1388
|
+
rlimit_field_t *r = &sigar_rlimits[i];
|
1389
|
+
|
1390
|
+
if (r->resource > RLIM_NLIMITS) {
|
1391
|
+
switch (r->resource) {
|
1392
|
+
case RLIMIT_NPROC:
|
1393
|
+
RlimitHS(sysconf(_SC_CHILD_MAX));
|
1394
|
+
break;
|
1395
|
+
case RLIMIT_PSIZE:
|
1396
|
+
RlimitHS(PIPE_BUF/512);
|
1397
|
+
break;
|
1398
|
+
default:
|
1399
|
+
RlimitHS(RLIM_INFINITY);
|
1400
|
+
break;
|
1401
|
+
}
|
1402
|
+
}
|
1403
|
+
else if (getrlimit(r->resource, &rl) != 0) {
|
1404
|
+
RlimitHS(RLIM_INFINITY);
|
1405
|
+
}
|
1406
|
+
else {
|
1407
|
+
RlimitScale(rl.rlim_cur);
|
1408
|
+
RlimitScale(rl.rlim_max);
|
1409
|
+
}
|
1410
|
+
|
1411
|
+
RlimitSet(rlimit, r->cur, rl.rlim_cur);
|
1412
|
+
RlimitSet(rlimit, r->max, rl.rlim_max);
|
1413
|
+
}
|
1414
|
+
|
1415
|
+
return SIGAR_OK;
|
1416
|
+
}
|
1417
|
+
#endif
|
1418
|
+
|
1419
|
+
#if !defined(WIN32) && !defined(NETWARE) && !defined(DARWIN) && \
|
1420
|
+
!defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__)
|
1421
|
+
|
1422
|
+
/* XXX: prolly will be moving these stuffs into os_net.c */
|
1423
|
+
#include <sys/ioctl.h>
|
1424
|
+
#include <net/if.h>
|
1425
|
+
|
1426
|
+
#ifndef SIOCGIFCONF
|
1427
|
+
#include <sys/sockio.h>
|
1428
|
+
#endif
|
1429
|
+
|
1430
|
+
#if defined(_AIX) || defined(__osf__) /* good buddies */
|
1431
|
+
|
1432
|
+
#include <net/if_dl.h>
|
1433
|
+
|
1434
|
+
static void hwaddr_aix_lookup(sigar_t *sigar, sigar_net_interface_config_t *ifconfig)
|
1435
|
+
{
|
1436
|
+
char *ent, *end;
|
1437
|
+
struct ifreq *ifr;
|
1438
|
+
|
1439
|
+
/* XXX: assumes sigar_net_interface_list_get has been called */
|
1440
|
+
end = sigar->ifconf_buf + sigar->ifconf_len;
|
1441
|
+
|
1442
|
+
for (ent = sigar->ifconf_buf;
|
1443
|
+
ent < end;
|
1444
|
+
ent += sizeof(*ifr))
|
1445
|
+
{
|
1446
|
+
ifr = (struct ifreq *)ent;
|
1447
|
+
|
1448
|
+
if (ifr->ifr_addr.sa_family != AF_LINK) {
|
1449
|
+
continue;
|
1450
|
+
}
|
1451
|
+
|
1452
|
+
if (strEQ(ifr->ifr_name, ifconfig->name)) {
|
1453
|
+
struct sockaddr_dl *sdl = (struct sockaddr_dl *)&ifr->ifr_addr;
|
1454
|
+
|
1455
|
+
sigar_net_address_mac_set(ifconfig->hwaddr,
|
1456
|
+
LLADDR(sdl),
|
1457
|
+
sdl->sdl_alen);
|
1458
|
+
return;
|
1459
|
+
}
|
1460
|
+
}
|
1461
|
+
|
1462
|
+
sigar_hwaddr_set_null(ifconfig);
|
1463
|
+
}
|
1464
|
+
|
1465
|
+
#elif !defined(SIOCGIFHWADDR)
|
1466
|
+
|
1467
|
+
#include <net/if_arp.h>
|
1468
|
+
|
1469
|
+
static void hwaddr_arp_lookup(sigar_net_interface_config_t *ifconfig, int sock)
|
1470
|
+
{
|
1471
|
+
struct arpreq areq;
|
1472
|
+
struct sockaddr_in *sa;
|
1473
|
+
|
1474
|
+
memset(&areq, 0, sizeof(areq));
|
1475
|
+
sa = (struct sockaddr_in *)&areq.arp_pa;
|
1476
|
+
sa->sin_family = AF_INET;
|
1477
|
+
sa->sin_addr.s_addr = ifconfig->address.addr.in;
|
1478
|
+
|
1479
|
+
if (ioctl(sock, SIOCGARP, &areq) < 0) {
|
1480
|
+
/* ho-hum */
|
1481
|
+
sigar_hwaddr_set_null(ifconfig);
|
1482
|
+
}
|
1483
|
+
else {
|
1484
|
+
sigar_net_address_mac_set(ifconfig->hwaddr,
|
1485
|
+
areq.arp_ha.sa_data,
|
1486
|
+
SIGAR_IFHWADDRLEN);
|
1487
|
+
}
|
1488
|
+
}
|
1489
|
+
|
1490
|
+
#endif
|
1491
|
+
|
1492
|
+
#ifdef __linux__
|
1493
|
+
|
1494
|
+
#include <net/if_arp.h>
|
1495
|
+
|
1496
|
+
static void get_interface_type(sigar_net_interface_config_t *ifconfig,
|
1497
|
+
int family)
|
1498
|
+
{
|
1499
|
+
char *type;
|
1500
|
+
|
1501
|
+
switch (family) {
|
1502
|
+
case ARPHRD_NETROM:
|
1503
|
+
type = SIGAR_NIC_NETROM;
|
1504
|
+
break;
|
1505
|
+
/* XXX more */
|
1506
|
+
default:
|
1507
|
+
type = SIGAR_NIC_ETHERNET;
|
1508
|
+
break;
|
1509
|
+
}
|
1510
|
+
|
1511
|
+
SIGAR_SSTRCPY(ifconfig->type, type);
|
1512
|
+
}
|
1513
|
+
|
1514
|
+
#endif
|
1515
|
+
|
1516
|
+
int sigar_net_interface_config_get(sigar_t *sigar, const char *name,
|
1517
|
+
sigar_net_interface_config_t *ifconfig)
|
1518
|
+
{
|
1519
|
+
int sock;
|
1520
|
+
struct ifreq ifr;
|
1521
|
+
|
1522
|
+
if (!name) {
|
1523
|
+
return sigar_net_interface_config_primary_get(sigar, ifconfig);
|
1524
|
+
}
|
1525
|
+
|
1526
|
+
SIGAR_ZERO(ifconfig);
|
1527
|
+
|
1528
|
+
if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
|
1529
|
+
return errno;
|
1530
|
+
}
|
1531
|
+
|
1532
|
+
SIGAR_SSTRCPY(ifconfig->name, name);
|
1533
|
+
SIGAR_SSTRCPY(ifr.ifr_name, name);
|
1534
|
+
|
1535
|
+
#define ifr_s_addr(ifr) \
|
1536
|
+
((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr
|
1537
|
+
|
1538
|
+
if (!ioctl(sock, SIOCGIFADDR, &ifr)) {
|
1539
|
+
sigar_net_address_set(ifconfig->address,
|
1540
|
+
ifr_s_addr(ifr));
|
1541
|
+
}
|
1542
|
+
|
1543
|
+
if (!ioctl(sock, SIOCGIFNETMASK, &ifr)) {
|
1544
|
+
sigar_net_address_set(ifconfig->netmask,
|
1545
|
+
ifr_s_addr(ifr));
|
1546
|
+
}
|
1547
|
+
|
1548
|
+
if (!ioctl(sock, SIOCGIFFLAGS, &ifr)) {
|
1549
|
+
sigar_uint64_t flags = ifr.ifr_flags;
|
1550
|
+
#ifdef __linux__
|
1551
|
+
int is_mcast = flags & IFF_MULTICAST;
|
1552
|
+
int is_slave = flags & IFF_SLAVE;
|
1553
|
+
/*
|
1554
|
+
* XXX: should just define SIGAR_IFF_*
|
1555
|
+
* and test IFF_* bits on given platform.
|
1556
|
+
* this is the only diff between solaris/hpux/linux
|
1557
|
+
* for the flags we care about.
|
1558
|
+
*
|
1559
|
+
*/
|
1560
|
+
flags &= ~(IFF_MULTICAST|IFF_SLAVE);
|
1561
|
+
if (is_mcast) {
|
1562
|
+
flags |= SIGAR_IFF_MULTICAST;
|
1563
|
+
}
|
1564
|
+
if (is_slave) {
|
1565
|
+
flags |= SIGAR_IFF_SLAVE;
|
1566
|
+
}
|
1567
|
+
#endif
|
1568
|
+
ifconfig->flags = flags;
|
1569
|
+
}
|
1570
|
+
else {
|
1571
|
+
/* should always be able to get flags for existing device */
|
1572
|
+
/* other ioctls may fail if device is not enabled: ok */
|
1573
|
+
close(sock);
|
1574
|
+
return errno;
|
1575
|
+
}
|
1576
|
+
|
1577
|
+
if (ifconfig->flags & IFF_LOOPBACK) {
|
1578
|
+
sigar_net_address_set(ifconfig->destination,
|
1579
|
+
ifconfig->address.addr.in);
|
1580
|
+
sigar_net_address_set(ifconfig->broadcast, 0);
|
1581
|
+
sigar_hwaddr_set_null(ifconfig);
|
1582
|
+
SIGAR_SSTRCPY(ifconfig->type,
|
1583
|
+
SIGAR_NIC_LOOPBACK);
|
1584
|
+
}
|
1585
|
+
else {
|
1586
|
+
if (!ioctl(sock, SIOCGIFDSTADDR, &ifr)) {
|
1587
|
+
sigar_net_address_set(ifconfig->destination,
|
1588
|
+
ifr_s_addr(ifr));
|
1589
|
+
}
|
1590
|
+
|
1591
|
+
if (!ioctl(sock, SIOCGIFBRDADDR, &ifr)) {
|
1592
|
+
sigar_net_address_set(ifconfig->broadcast,
|
1593
|
+
ifr_s_addr(ifr));
|
1594
|
+
}
|
1595
|
+
|
1596
|
+
#if defined(SIOCGIFHWADDR)
|
1597
|
+
if (!ioctl(sock, SIOCGIFHWADDR, &ifr)) {
|
1598
|
+
get_interface_type(ifconfig,
|
1599
|
+
ifr.ifr_hwaddr.sa_family);
|
1600
|
+
sigar_net_address_mac_set(ifconfig->hwaddr,
|
1601
|
+
ifr.ifr_hwaddr.sa_data,
|
1602
|
+
IFHWADDRLEN);
|
1603
|
+
}
|
1604
|
+
#elif defined(_AIX) || defined(__osf__)
|
1605
|
+
hwaddr_aix_lookup(sigar, ifconfig);
|
1606
|
+
SIGAR_SSTRCPY(ifconfig->type,
|
1607
|
+
SIGAR_NIC_ETHERNET);
|
1608
|
+
#else
|
1609
|
+
hwaddr_arp_lookup(ifconfig, sock);
|
1610
|
+
SIGAR_SSTRCPY(ifconfig->type,
|
1611
|
+
SIGAR_NIC_ETHERNET);
|
1612
|
+
#endif
|
1613
|
+
}
|
1614
|
+
|
1615
|
+
#if defined(SIOCGLIFMTU) && !defined(__hpux)
|
1616
|
+
{
|
1617
|
+
struct lifreq lifr;
|
1618
|
+
SIGAR_SSTRCPY(lifr.lifr_name, name);
|
1619
|
+
if(!ioctl(sock, SIOCGLIFMTU, &lifr)) {
|
1620
|
+
ifconfig->mtu = lifr.lifr_mtu;
|
1621
|
+
}
|
1622
|
+
}
|
1623
|
+
#elif defined(SIOCGIFMTU)
|
1624
|
+
if (!ioctl(sock, SIOCGIFMTU, &ifr)) {
|
1625
|
+
# if defined(__hpux)
|
1626
|
+
ifconfig->mtu = ifr.ifr_metric;
|
1627
|
+
# else
|
1628
|
+
ifconfig->mtu = ifr.ifr_mtu;
|
1629
|
+
#endif
|
1630
|
+
}
|
1631
|
+
#else
|
1632
|
+
ifconfig->mtu = 0; /*XXX*/
|
1633
|
+
#endif
|
1634
|
+
|
1635
|
+
if (!ioctl(sock, SIOCGIFMETRIC, &ifr)) {
|
1636
|
+
ifconfig->metric = ifr.ifr_metric ? ifr.ifr_metric : 1;
|
1637
|
+
}
|
1638
|
+
|
1639
|
+
close(sock);
|
1640
|
+
|
1641
|
+
/* XXX can we get a better description like win32? */
|
1642
|
+
SIGAR_SSTRCPY(ifconfig->description,
|
1643
|
+
ifconfig->name);
|
1644
|
+
|
1645
|
+
return SIGAR_OK;
|
1646
|
+
}
|
1647
|
+
|
1648
|
+
#ifdef _AIX
|
1649
|
+
# define MY_SIOCGIFCONF CSIOCGIFCONF
|
1650
|
+
#else
|
1651
|
+
# define MY_SIOCGIFCONF SIOCGIFCONF
|
1652
|
+
#endif
|
1653
|
+
|
1654
|
+
#ifdef __osf__
|
1655
|
+
static int sigar_netif_configured(sigar_t *sigar, char *name)
|
1656
|
+
{
|
1657
|
+
int status;
|
1658
|
+
sigar_net_interface_config_t ifconfig;
|
1659
|
+
|
1660
|
+
status = sigar_net_interface_config_get(sigar, name, &ifconfig);
|
1661
|
+
|
1662
|
+
return status == SIGAR_OK;
|
1663
|
+
}
|
1664
|
+
#endif
|
1665
|
+
|
1666
|
+
#ifdef __linux__
|
1667
|
+
static SIGAR_INLINE int has_interface(sigar_net_interface_list_t *iflist,
|
1668
|
+
char *name)
|
1669
|
+
{
|
1670
|
+
register int i;
|
1671
|
+
register int num = iflist->number;
|
1672
|
+
register char **data = iflist->data;
|
1673
|
+
for (i=0; i<num; i++) {
|
1674
|
+
if (strEQ(name, data[i])) {
|
1675
|
+
return 1;
|
1676
|
+
}
|
1677
|
+
}
|
1678
|
+
return 0;
|
1679
|
+
}
|
1680
|
+
|
1681
|
+
static int proc_net_interface_list_get(sigar_t *sigar,
|
1682
|
+
sigar_net_interface_list_t *iflist)
|
1683
|
+
{
|
1684
|
+
/* certain interfaces such as VMware vmnic
|
1685
|
+
* are not returned by ioctl(SIOCGIFCONF).
|
1686
|
+
* check /proc/net/dev for any ioctl missed.
|
1687
|
+
*/
|
1688
|
+
char buffer[BUFSIZ];
|
1689
|
+
FILE *fp = fopen("/proc/net/dev", "r");
|
1690
|
+
|
1691
|
+
if (!fp) {
|
1692
|
+
return errno;
|
1693
|
+
}
|
1694
|
+
|
1695
|
+
/* skip header */
|
1696
|
+
fgets(buffer, sizeof(buffer), fp);
|
1697
|
+
fgets(buffer, sizeof(buffer), fp);
|
1698
|
+
|
1699
|
+
while (fgets(buffer, sizeof(buffer), fp)) {
|
1700
|
+
char *ptr, *dev;
|
1701
|
+
|
1702
|
+
dev = buffer;
|
1703
|
+
while (isspace(*dev)) {
|
1704
|
+
dev++;
|
1705
|
+
}
|
1706
|
+
|
1707
|
+
if (!(ptr = strchr(dev, ':'))) {
|
1708
|
+
continue;
|
1709
|
+
}
|
1710
|
+
|
1711
|
+
*ptr++ = 0;
|
1712
|
+
|
1713
|
+
if (has_interface(iflist, dev)) {
|
1714
|
+
continue;
|
1715
|
+
}
|
1716
|
+
|
1717
|
+
SIGAR_NET_IFLIST_GROW(iflist);
|
1718
|
+
|
1719
|
+
iflist->data[iflist->number++] =
|
1720
|
+
sigar_strdup(dev);
|
1721
|
+
}
|
1722
|
+
|
1723
|
+
fclose(fp);
|
1724
|
+
|
1725
|
+
return SIGAR_OK;
|
1726
|
+
}
|
1727
|
+
#endif
|
1728
|
+
|
1729
|
+
int sigar_net_interface_list_get(sigar_t *sigar,
|
1730
|
+
sigar_net_interface_list_t *iflist)
|
1731
|
+
{
|
1732
|
+
int n, lastlen=0;
|
1733
|
+
struct ifreq *ifr;
|
1734
|
+
struct ifconf ifc;
|
1735
|
+
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
1736
|
+
|
1737
|
+
if (sock < 0) {
|
1738
|
+
return errno;
|
1739
|
+
}
|
1740
|
+
|
1741
|
+
for (;;) {
|
1742
|
+
if (!sigar->ifconf_buf || lastlen) {
|
1743
|
+
sigar->ifconf_len += sizeof(struct ifreq) * SIGAR_NET_IFLIST_MAX;
|
1744
|
+
sigar->ifconf_buf = realloc(sigar->ifconf_buf, sigar->ifconf_len);
|
1745
|
+
}
|
1746
|
+
|
1747
|
+
ifc.ifc_len = sigar->ifconf_len;
|
1748
|
+
ifc.ifc_buf = sigar->ifconf_buf;
|
1749
|
+
|
1750
|
+
if (ioctl(sock, MY_SIOCGIFCONF, &ifc) < 0) {
|
1751
|
+
/* EINVAL should mean num_interfaces > ifc.ifc_len */
|
1752
|
+
if ((errno != EINVAL) ||
|
1753
|
+
(lastlen == ifc.ifc_len))
|
1754
|
+
{
|
1755
|
+
free(ifc.ifc_buf);
|
1756
|
+
return errno;
|
1757
|
+
}
|
1758
|
+
}
|
1759
|
+
|
1760
|
+
if (ifc.ifc_len < sigar->ifconf_len) {
|
1761
|
+
break; /* got em all */
|
1762
|
+
}
|
1763
|
+
|
1764
|
+
if (ifc.ifc_len != lastlen) {
|
1765
|
+
/* might be more */
|
1766
|
+
lastlen = ifc.ifc_len;
|
1767
|
+
continue;
|
1768
|
+
}
|
1769
|
+
|
1770
|
+
break;
|
1771
|
+
}
|
1772
|
+
|
1773
|
+
close(sock);
|
1774
|
+
|
1775
|
+
iflist->number = 0;
|
1776
|
+
iflist->size = ifc.ifc_len;
|
1777
|
+
iflist->data = malloc(sizeof(*(iflist->data)) *
|
1778
|
+
iflist->size);
|
1779
|
+
|
1780
|
+
ifr = ifc.ifc_req;
|
1781
|
+
for (n = 0; n < ifc.ifc_len; n += sizeof(struct ifreq), ifr++) {
|
1782
|
+
#if defined(_AIX) || defined(__osf__) /* pass the bourbon */
|
1783
|
+
if (ifr->ifr_addr.sa_family != AF_LINK) {
|
1784
|
+
/* XXX: dunno if this is right.
|
1785
|
+
* otherwise end up with two 'en0' and three 'lo0'
|
1786
|
+
* with the same ip address.
|
1787
|
+
*/
|
1788
|
+
continue;
|
1789
|
+
}
|
1790
|
+
# ifdef __osf__
|
1791
|
+
/* weed out "sl0", "tun0" and the like */
|
1792
|
+
/* XXX must be a better way to check this */
|
1793
|
+
if (!sigar_netif_configured(sigar, ifr->ifr_name)) {
|
1794
|
+
continue;
|
1795
|
+
}
|
1796
|
+
# endif
|
1797
|
+
#endif
|
1798
|
+
iflist->data[iflist->number++] =
|
1799
|
+
sigar_strdup(ifr->ifr_name);
|
1800
|
+
}
|
1801
|
+
|
1802
|
+
#ifdef __linux__
|
1803
|
+
proc_net_interface_list_get(sigar, iflist);
|
1804
|
+
#endif
|
1805
|
+
|
1806
|
+
return SIGAR_OK;
|
1807
|
+
}
|
1808
|
+
|
1809
|
+
#endif /* WIN32 */
|
1810
|
+
|
1811
|
+
SIGAR_DECLARE(int)
|
1812
|
+
sigar_net_interface_config_primary_get(sigar_t *sigar,
|
1813
|
+
sigar_net_interface_config_t *ifconfig)
|
1814
|
+
{
|
1815
|
+
int i, status, found=0;
|
1816
|
+
sigar_net_interface_list_t iflist;
|
1817
|
+
sigar_net_interface_config_t possible_config;
|
1818
|
+
|
1819
|
+
possible_config.flags = 0;
|
1820
|
+
|
1821
|
+
if ((status = sigar_net_interface_list_get(sigar, &iflist)) != SIGAR_OK) {
|
1822
|
+
return status;
|
1823
|
+
}
|
1824
|
+
|
1825
|
+
for (i=0; i<iflist.number; i++) {
|
1826
|
+
status = sigar_net_interface_config_get(sigar,
|
1827
|
+
iflist.data[i], ifconfig);
|
1828
|
+
|
1829
|
+
if ((status != SIGAR_OK) ||
|
1830
|
+
(ifconfig->flags & SIGAR_IFF_LOOPBACK) ||
|
1831
|
+
!ifconfig->hwaddr.addr.in) /* no mac address */
|
1832
|
+
{
|
1833
|
+
continue;
|
1834
|
+
}
|
1835
|
+
|
1836
|
+
if (!possible_config.flags) {
|
1837
|
+
/* save for later for use if we're not connected to the net
|
1838
|
+
* or all interfaces are aliases (e.g. solaris zone)
|
1839
|
+
*/
|
1840
|
+
memcpy(&possible_config, ifconfig, sizeof(*ifconfig));
|
1841
|
+
}
|
1842
|
+
if (!ifconfig->address.addr.in) {
|
1843
|
+
continue; /* no ip address */
|
1844
|
+
}
|
1845
|
+
if (strchr(iflist.data[i], ':')) {
|
1846
|
+
continue; /* alias */
|
1847
|
+
}
|
1848
|
+
|
1849
|
+
found = 1;
|
1850
|
+
break;
|
1851
|
+
}
|
1852
|
+
|
1853
|
+
sigar_net_interface_list_destroy(sigar, &iflist);
|
1854
|
+
|
1855
|
+
if (found) {
|
1856
|
+
return SIGAR_OK;
|
1857
|
+
}
|
1858
|
+
else if (possible_config.flags) {
|
1859
|
+
memcpy(ifconfig, &possible_config, sizeof(*ifconfig));
|
1860
|
+
return SIGAR_OK;
|
1861
|
+
}
|
1862
|
+
else {
|
1863
|
+
return SIGAR_ENXIO;
|
1864
|
+
}
|
1865
|
+
}
|
1866
|
+
|
1867
|
+
static int fqdn_ip_get(sigar_t *sigar, char *name)
|
1868
|
+
{
|
1869
|
+
sigar_net_interface_config_t ifconfig;
|
1870
|
+
int status;
|
1871
|
+
|
1872
|
+
status = sigar_net_interface_config_primary_get(sigar, &ifconfig);
|
1873
|
+
|
1874
|
+
if (status != SIGAR_OK) {
|
1875
|
+
return status;
|
1876
|
+
}
|
1877
|
+
if (!ifconfig.address.addr.in) {
|
1878
|
+
return SIGAR_ENXIO;
|
1879
|
+
}
|
1880
|
+
|
1881
|
+
sigar_net_address_to_string(sigar, &ifconfig.address, name);
|
1882
|
+
|
1883
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
1884
|
+
"[fqdn] using ip address '%s' for fqdn",
|
1885
|
+
name);
|
1886
|
+
|
1887
|
+
return SIGAR_OK;
|
1888
|
+
}
|
1889
|
+
|
1890
|
+
struct hostent *sigar_gethostbyname(const char *name,
|
1891
|
+
sigar_hostent_t *data)
|
1892
|
+
{
|
1893
|
+
struct hostent *hp = NULL;
|
1894
|
+
|
1895
|
+
#if defined(__linux__)
|
1896
|
+
gethostbyname_r(name, &data->hs,
|
1897
|
+
data->buffer, sizeof(data->buffer),
|
1898
|
+
&hp, &data->error);
|
1899
|
+
#elif defined(__sun)
|
1900
|
+
hp = gethostbyname_r(name, &data->hs,
|
1901
|
+
data->buffer, sizeof(data->buffer),
|
1902
|
+
&data->error);
|
1903
|
+
#elif defined(SIGAR_HAS_HOSTENT_DATA)
|
1904
|
+
if (gethostbyname_r(name, &data->hs, &data->hd) == 0) {
|
1905
|
+
hp = &data->hs;
|
1906
|
+
}
|
1907
|
+
else {
|
1908
|
+
data->error = h_errno;
|
1909
|
+
}
|
1910
|
+
#else
|
1911
|
+
hp = gethostbyname(name);
|
1912
|
+
#endif
|
1913
|
+
|
1914
|
+
return hp;
|
1915
|
+
}
|
1916
|
+
|
1917
|
+
static struct hostent *sigar_gethostbyaddr(const char *addr,
|
1918
|
+
int len, int type,
|
1919
|
+
sigar_hostent_t *data)
|
1920
|
+
{
|
1921
|
+
struct hostent *hp = NULL;
|
1922
|
+
|
1923
|
+
#if defined(__linux__)
|
1924
|
+
gethostbyaddr_r(addr, len, type,
|
1925
|
+
&data->hs,
|
1926
|
+
data->buffer, sizeof(data->buffer),
|
1927
|
+
&hp, &data->error);
|
1928
|
+
#elif defined(__sun)
|
1929
|
+
hp = gethostbyaddr_r(addr, len, type,
|
1930
|
+
&data->hs,
|
1931
|
+
data->buffer, sizeof(data->buffer),
|
1932
|
+
&data->error);
|
1933
|
+
#elif defined(SIGAR_HAS_HOSTENT_DATA)
|
1934
|
+
if (gethostbyaddr_r((char *)addr, len, type,
|
1935
|
+
&data->hs, &data->hd) == 0)
|
1936
|
+
{
|
1937
|
+
hp = &data->hs;
|
1938
|
+
}
|
1939
|
+
else {
|
1940
|
+
data->error = h_errno;
|
1941
|
+
}
|
1942
|
+
#else
|
1943
|
+
if (!(hp = gethostbyaddr(addr, len, type))) {
|
1944
|
+
data->error = h_errno;
|
1945
|
+
}
|
1946
|
+
#endif
|
1947
|
+
|
1948
|
+
return hp;
|
1949
|
+
}
|
1950
|
+
#define IS_FQDN(name) \
|
1951
|
+
(name && strchr(name, '.'))
|
1952
|
+
|
1953
|
+
#define IS_FQDN_MATCH(lookup, name) \
|
1954
|
+
(IS_FQDN(lookup) && strnEQ(lookup, name, strlen(name)))
|
1955
|
+
|
1956
|
+
#define FQDN_SET(fqdn) \
|
1957
|
+
SIGAR_STRNCPY(name, fqdn, namelen)
|
1958
|
+
|
1959
|
+
SIGAR_DECLARE(int) sigar_fqdn_get(sigar_t *sigar, char *name, int namelen)
|
1960
|
+
{
|
1961
|
+
register int is_debug = SIGAR_LOG_IS_DEBUG(sigar);
|
1962
|
+
sigar_hostent_t data;
|
1963
|
+
struct hostent *p;
|
1964
|
+
char domain[SIGAR_FQDN_LEN + 1];
|
1965
|
+
#ifdef WIN32
|
1966
|
+
int status = sigar_wsa_init(sigar);
|
1967
|
+
|
1968
|
+
if (status != SIGAR_OK) {
|
1969
|
+
return status;
|
1970
|
+
}
|
1971
|
+
#endif
|
1972
|
+
|
1973
|
+
if (gethostname(name, namelen - 1) != 0) {
|
1974
|
+
sigar_log_printf(sigar, SIGAR_LOG_ERROR,
|
1975
|
+
"[fqdn] gethostname failed: %s",
|
1976
|
+
sigar_strerror(sigar, errno));
|
1977
|
+
return errno;
|
1978
|
+
}
|
1979
|
+
else {
|
1980
|
+
if (is_debug) {
|
1981
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
1982
|
+
"[fqdn] gethostname()=='%s'",
|
1983
|
+
name);
|
1984
|
+
}
|
1985
|
+
}
|
1986
|
+
|
1987
|
+
if (!(p = sigar_gethostbyname(name, &data))) {
|
1988
|
+
if (is_debug) {
|
1989
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
1990
|
+
"[fqdn] gethostbyname(%s) failed: %s",
|
1991
|
+
name, sigar_strerror(sigar, errno));
|
1992
|
+
}
|
1993
|
+
|
1994
|
+
if (!IS_FQDN(name)) {
|
1995
|
+
fqdn_ip_get(sigar, name);
|
1996
|
+
}
|
1997
|
+
|
1998
|
+
return SIGAR_OK;
|
1999
|
+
}
|
2000
|
+
|
2001
|
+
if (IS_FQDN_MATCH(p->h_name, name)) {
|
2002
|
+
FQDN_SET(p->h_name);
|
2003
|
+
|
2004
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG,
|
2005
|
+
"[fqdn] resolved using gethostbyname.h_name");
|
2006
|
+
|
2007
|
+
return SIGAR_OK;
|
2008
|
+
}
|
2009
|
+
else {
|
2010
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
2011
|
+
"[fqdn] unresolved using gethostbyname.h_name");
|
2012
|
+
}
|
2013
|
+
|
2014
|
+
if (p->h_aliases) {
|
2015
|
+
int i;
|
2016
|
+
|
2017
|
+
for (i=0; p->h_aliases[i]; i++) {
|
2018
|
+
if (IS_FQDN_MATCH(p->h_aliases[i], name)) {
|
2019
|
+
FQDN_SET(p->h_aliases[i]);
|
2020
|
+
|
2021
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG,
|
2022
|
+
"[fqdn] resolved using gethostbyname.h_aliases");
|
2023
|
+
|
2024
|
+
return SIGAR_OK;
|
2025
|
+
}
|
2026
|
+
else if (is_debug) {
|
2027
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
2028
|
+
"[fqdn] gethostbyname(%s).alias[%d]=='%s'",
|
2029
|
+
name, i, p->h_aliases[i]);
|
2030
|
+
}
|
2031
|
+
}
|
2032
|
+
}
|
2033
|
+
|
2034
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
2035
|
+
"[fqdn] unresolved using gethostbyname.h_aliases");
|
2036
|
+
|
2037
|
+
if (p->h_addr_list) {
|
2038
|
+
int i,j;
|
2039
|
+
|
2040
|
+
for (i=0; p->h_addr_list[i]; i++) {
|
2041
|
+
char addr[SIGAR_INET6_ADDRSTRLEN];
|
2042
|
+
struct in_addr *in =
|
2043
|
+
(struct in_addr *)p->h_addr_list[i];
|
2044
|
+
|
2045
|
+
struct hostent *q =
|
2046
|
+
sigar_gethostbyaddr(p->h_addr_list[i],
|
2047
|
+
p->h_length,
|
2048
|
+
p->h_addrtype,
|
2049
|
+
&data);
|
2050
|
+
|
2051
|
+
if (is_debug) {
|
2052
|
+
sigar_inet_ntoa(sigar, in->s_addr, addr);
|
2053
|
+
}
|
2054
|
+
|
2055
|
+
if (!q) {
|
2056
|
+
if (is_debug) {
|
2057
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
2058
|
+
"[fqdn] gethostbyaddr(%s) failed: %s",
|
2059
|
+
addr,
|
2060
|
+
sigar_strerror(sigar, errno));
|
2061
|
+
}
|
2062
|
+
continue;
|
2063
|
+
}
|
2064
|
+
|
2065
|
+
if (IS_FQDN_MATCH(q->h_name, name)) {
|
2066
|
+
FQDN_SET(q->h_name);
|
2067
|
+
|
2068
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG,
|
2069
|
+
"[fqdn] resolved using gethostbyaddr.h_name");
|
2070
|
+
|
2071
|
+
return SIGAR_OK;
|
2072
|
+
}
|
2073
|
+
else {
|
2074
|
+
if (is_debug) {
|
2075
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
2076
|
+
"[fqdn] gethostbyaddr(%s)=='%s'",
|
2077
|
+
addr, q->h_name);
|
2078
|
+
}
|
2079
|
+
|
2080
|
+
for (j=0; q->h_aliases[j]; j++) {
|
2081
|
+
if (IS_FQDN_MATCH(q->h_aliases[j], name)) {
|
2082
|
+
FQDN_SET(q->h_aliases[j]);
|
2083
|
+
|
2084
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG,
|
2085
|
+
"[fqdn] resolved using "
|
2086
|
+
"gethostbyaddr.h_aliases");
|
2087
|
+
|
2088
|
+
return SIGAR_OK;
|
2089
|
+
}
|
2090
|
+
else if (is_debug) {
|
2091
|
+
sigar_log_printf(sigar, SIGAR_LOG_DEBUG,
|
2092
|
+
"[fqdn] gethostbyaddr(%s).alias[%d]=='%s'",
|
2093
|
+
addr, j, q->h_aliases[j]);
|
2094
|
+
}
|
2095
|
+
}
|
2096
|
+
}
|
2097
|
+
}
|
2098
|
+
}
|
2099
|
+
|
2100
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG,
|
2101
|
+
"[fqdn] unresolved using gethostbyname.h_addr_list");
|
2102
|
+
|
2103
|
+
#if !defined(WIN32) && !defined(NETWARE)
|
2104
|
+
if (!IS_FQDN(name) && /* e.g. aix gethostname is already fqdn */
|
2105
|
+
(getdomainname(domain, sizeof(domain) - 1) == 0) &&
|
2106
|
+
(domain[0] != '\0') &&
|
2107
|
+
(domain[0] != '(')) /* linux default is "(none)" */
|
2108
|
+
{
|
2109
|
+
/* sprintf(name, "%s.%s", name, domain); */
|
2110
|
+
char *ptr = name;
|
2111
|
+
int len = strlen(name);
|
2112
|
+
ptr += len;
|
2113
|
+
*ptr++ = '.';
|
2114
|
+
namelen -= (len+1);
|
2115
|
+
SIGAR_STRNCPY(ptr, domain, namelen);
|
2116
|
+
|
2117
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG,
|
2118
|
+
"[fqdn] resolved using getdomainname");
|
2119
|
+
}
|
2120
|
+
else {
|
2121
|
+
sigar_log(sigar, SIGAR_LOG_DEBUG,
|
2122
|
+
"[fqdn] getdomainname failed");
|
2123
|
+
}
|
2124
|
+
#endif
|
2125
|
+
|
2126
|
+
if (!IS_FQDN(name)) {
|
2127
|
+
fqdn_ip_get(sigar, name);
|
2128
|
+
}
|
2129
|
+
|
2130
|
+
return SIGAR_OK;
|
2131
|
+
}
|
2132
|
+
|
2133
|
+
#ifndef MAX_STRING_LEN
|
2134
|
+
#define MAX_STRING_LEN 8192
|
2135
|
+
#endif
|
2136
|
+
|
2137
|
+
#ifdef WIN32
|
2138
|
+
/* The windows version of getPasswordNative was lifted from apr */
|
2139
|
+
SIGAR_DECLARE(char *) sigar_password_get(const char *prompt)
|
2140
|
+
{
|
2141
|
+
static char password[MAX_STRING_LEN];
|
2142
|
+
int n = 0;
|
2143
|
+
int ch;
|
2144
|
+
|
2145
|
+
fputs(prompt, stderr);
|
2146
|
+
fflush(stderr);
|
2147
|
+
|
2148
|
+
while ((ch = _getch()) != '\r') {
|
2149
|
+
if (ch == EOF) /* EOF */ {
|
2150
|
+
return NULL;
|
2151
|
+
}
|
2152
|
+
else if (ch == 0 || ch == 0xE0) {
|
2153
|
+
/* FN Keys (0 or E0) are a sentinal for a FN code */
|
2154
|
+
ch = (ch << 4) | _getch();
|
2155
|
+
/* Catch {DELETE}, {<--}, Num{DEL} and Num{<--} */
|
2156
|
+
if ((ch == 0xE53 || ch == 0xE4B || ch == 0x053 || ch == 0x04b) && n) {
|
2157
|
+
password[--n] = '\0';
|
2158
|
+
fputs("\b \b", stderr);
|
2159
|
+
fflush(stderr);
|
2160
|
+
}
|
2161
|
+
else {
|
2162
|
+
fputc('\a', stderr);
|
2163
|
+
fflush(stderr);
|
2164
|
+
}
|
2165
|
+
}
|
2166
|
+
else if ((ch == '\b' || ch == 127) && n) /* BS/DEL */ {
|
2167
|
+
password[--n] = '\0';
|
2168
|
+
fputs("\b \b", stderr);
|
2169
|
+
fflush(stderr);
|
2170
|
+
}
|
2171
|
+
else if (ch == 3) /* CTRL+C */ {
|
2172
|
+
/* _getch() bypasses Ctrl+C but not Ctrl+Break detection! */
|
2173
|
+
fputs("^C\n", stderr);
|
2174
|
+
fflush(stderr);
|
2175
|
+
exit(-1);
|
2176
|
+
}
|
2177
|
+
else if (ch == 26) /* CTRL+Z */ {
|
2178
|
+
fputs("^Z\n", stderr);
|
2179
|
+
fflush(stderr);
|
2180
|
+
return NULL;
|
2181
|
+
}
|
2182
|
+
else if (ch == 27) /* ESC */ {
|
2183
|
+
fputc('\n', stderr);
|
2184
|
+
fputs(prompt, stderr);
|
2185
|
+
fflush(stderr);
|
2186
|
+
n = 0;
|
2187
|
+
}
|
2188
|
+
else if ((n < sizeof(password) - 1) && !iscntrl(ch)) {
|
2189
|
+
password[n++] = ch;
|
2190
|
+
fputc(' ', stderr);
|
2191
|
+
fflush(stderr);
|
2192
|
+
}
|
2193
|
+
else {
|
2194
|
+
fputc('\a', stderr);
|
2195
|
+
fflush(stderr);
|
2196
|
+
}
|
2197
|
+
}
|
2198
|
+
|
2199
|
+
fputc('\n', stderr);
|
2200
|
+
fflush(stderr);
|
2201
|
+
password[n] = '\0';
|
2202
|
+
|
2203
|
+
return password;
|
2204
|
+
}
|
2205
|
+
|
2206
|
+
#else
|
2207
|
+
|
2208
|
+
/* linux/hpux/solaris getpass() prototype lives here */
|
2209
|
+
#include <unistd.h>
|
2210
|
+
|
2211
|
+
#include <termios.h>
|
2212
|
+
|
2213
|
+
/* from apr_getpass.c */
|
2214
|
+
|
2215
|
+
#if defined(SIGAR_HPUX)
|
2216
|
+
# define getpass termios_getpass
|
2217
|
+
#elif defined(SIGAR_SOLARIS)
|
2218
|
+
# define getpass getpassphrase
|
2219
|
+
#endif
|
2220
|
+
|
2221
|
+
#ifdef SIGAR_HPUX
|
2222
|
+
static char *termios_getpass(const char *prompt)
|
2223
|
+
{
|
2224
|
+
struct termios attr;
|
2225
|
+
static char password[MAX_STRING_LEN];
|
2226
|
+
unsigned int n=0;
|
2227
|
+
|
2228
|
+
fputs(prompt, stderr);
|
2229
|
+
fflush(stderr);
|
2230
|
+
|
2231
|
+
if (tcgetattr(STDIN_FILENO, &attr) != 0) {
|
2232
|
+
return NULL;
|
2233
|
+
}
|
2234
|
+
|
2235
|
+
attr.c_lflag &= ~(ECHO);
|
2236
|
+
|
2237
|
+
if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &attr) != 0) {
|
2238
|
+
return NULL;
|
2239
|
+
}
|
2240
|
+
|
2241
|
+
while ((password[n] = getchar()) != '\n') {
|
2242
|
+
if (n < (sizeof(password) - 1) &&
|
2243
|
+
(password[n] >= ' ') &&
|
2244
|
+
(password[n] <= '~'))
|
2245
|
+
{
|
2246
|
+
n++;
|
2247
|
+
}
|
2248
|
+
else {
|
2249
|
+
fprintf(stderr, "\n");
|
2250
|
+
fputs(prompt, stderr);
|
2251
|
+
fflush(stderr);
|
2252
|
+
n = 0;
|
2253
|
+
}
|
2254
|
+
}
|
2255
|
+
|
2256
|
+
password[n] = '\0';
|
2257
|
+
printf("\n");
|
2258
|
+
|
2259
|
+
if (n > (MAX_STRING_LEN - 1)) {
|
2260
|
+
password[MAX_STRING_LEN - 1] = '\0';
|
2261
|
+
}
|
2262
|
+
|
2263
|
+
attr.c_lflag |= ECHO;
|
2264
|
+
tcsetattr(STDIN_FILENO, TCSANOW, &attr);
|
2265
|
+
|
2266
|
+
return (char *)&password;
|
2267
|
+
}
|
2268
|
+
#endif
|
2269
|
+
|
2270
|
+
SIGAR_DECLARE(char *) sigar_password_get(const char *prompt)
|
2271
|
+
{
|
2272
|
+
char *buf = NULL;
|
2273
|
+
|
2274
|
+
/* the linux version of getpass prints the prompt to the tty; ok.
|
2275
|
+
* the solaris version prints the prompt to stderr; not ok.
|
2276
|
+
* so print the prompt to /dev/tty ourselves if possible (always should be)
|
2277
|
+
*/
|
2278
|
+
|
2279
|
+
FILE *tty = NULL;
|
2280
|
+
|
2281
|
+
if ((tty = fopen("/dev/tty", "w"))) {
|
2282
|
+
fprintf(tty, "%s", prompt);
|
2283
|
+
fflush(tty);
|
2284
|
+
|
2285
|
+
buf = getpass(tty ? "" : prompt);
|
2286
|
+
fclose(tty);
|
2287
|
+
}
|
2288
|
+
|
2289
|
+
return buf;
|
2290
|
+
}
|
2291
|
+
|
2292
|
+
#endif /* WIN32 */
|