sigar-test 0.7.3.1

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