sigar 0.7.1 → 0.7.2

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