sigar 0.7.1 → 0.7.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,696 +0,0 @@
1
- /*
2
- * Copyright (c) 2007-2008 Hyperic, Inc.
3
- * Copyright (c) 2009 SpringSource, Inc.
4
- * Copyright (c) 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
- /* Utility functions to provide string formatting of SIGAR data */
20
-
21
- #include "sigar.h"
22
- #include "sigar_private.h"
23
- #include "sigar_util.h"
24
- #include "sigar_os.h"
25
- #include "sigar_format.h"
26
-
27
- #include <errno.h>
28
- #include <stdio.h>
29
-
30
- #ifndef WIN32
31
- #include <netinet/in.h>
32
- #include <arpa/inet.h>
33
- #if defined(__OpenBSD__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_AIX)
34
- #include <sys/socket.h>
35
- #endif
36
- #include <pwd.h>
37
- #include <grp.h>
38
-
39
- /* sysconf(_SC_GET{PW,GR}_R_SIZE_MAX) */
40
- #define R_SIZE_MAX 2048
41
-
42
- int sigar_user_name_get(sigar_t *sigar, int uid, char *buf, int buflen)
43
- {
44
- struct passwd *pw = NULL;
45
- /* XXX cache lookup */
46
-
47
- # ifdef HAVE_GETPWUID_R
48
- struct passwd pwbuf;
49
- char buffer[R_SIZE_MAX];
50
-
51
- if (getpwuid_r(uid, &pwbuf, buffer, sizeof(buffer), &pw) != 0) {
52
- return errno;
53
- }
54
- if (!pw) {
55
- return ENOENT;
56
- }
57
- # else
58
- if ((pw = getpwuid(uid)) == NULL) {
59
- return errno;
60
- }
61
- # endif
62
-
63
- strncpy(buf, pw->pw_name, buflen);
64
- buf[buflen-1] = '\0';
65
-
66
- return SIGAR_OK;
67
- }
68
-
69
- int sigar_group_name_get(sigar_t *sigar, int gid, char *buf, int buflen)
70
- {
71
- struct group *gr;
72
- /* XXX cache lookup */
73
-
74
- # ifdef HAVE_GETGRGID_R
75
- struct group grbuf;
76
- char buffer[R_SIZE_MAX];
77
-
78
- if (getgrgid_r(gid, &grbuf, buffer, sizeof(buffer), &gr) != 0) {
79
- return errno;
80
- }
81
- # else
82
- if ((gr = getgrgid(gid)) == NULL) {
83
- return errno;
84
- }
85
- # endif
86
-
87
- if (gr && gr->gr_name) {
88
- strncpy(buf, gr->gr_name, buflen);
89
- }
90
- else {
91
- /* seen on linux.. apache httpd.conf has:
92
- * Group #-1
93
- * results in uid == -1 and gr == NULL.
94
- * wtf getgrgid_r doesnt fail instead?
95
- */
96
- sprintf(buf, "%d", gid);
97
- }
98
- buf[buflen-1] = '\0';
99
-
100
- return SIGAR_OK;
101
- }
102
-
103
- int sigar_user_id_get(sigar_t *sigar, const char *name, int *uid)
104
- {
105
- /* XXX cache lookup */
106
- struct passwd *pw;
107
-
108
- # ifdef HAVE_GETPWNAM_R
109
- struct passwd pwbuf;
110
- char buf[R_SIZE_MAX];
111
-
112
- if (getpwnam_r(name, &pwbuf, buf, sizeof(buf), &pw) != 0) {
113
- return errno;
114
- }
115
- # else
116
- if (!(pw = getpwnam(name))) {
117
- return errno;
118
- }
119
- # endif
120
-
121
- *uid = (int)pw->pw_uid;
122
- return SIGAR_OK;
123
- }
124
-
125
- #endif /* WIN32 */
126
-
127
- static char *sigar_error_string(int err)
128
- {
129
- switch (err) {
130
- case SIGAR_ENOTIMPL:
131
- return "This function has not been implemented on this platform";
132
- default:
133
- return "Error string not specified yet";
134
- }
135
- }
136
-
137
- SIGAR_DECLARE(char *) sigar_strerror(sigar_t *sigar, int err)
138
- {
139
- char *buf;
140
-
141
- if (err < 0) {
142
- return sigar->errbuf;
143
- }
144
-
145
- if (err > SIGAR_OS_START_ERROR) {
146
- if ((buf = sigar_os_error_string(sigar, err)) != NULL) {
147
- return buf;
148
- }
149
- return "Unknown OS Error"; /* should never happen */
150
- }
151
-
152
- if (err > SIGAR_START_ERROR) {
153
- return sigar_error_string(err);
154
- }
155
-
156
- return sigar_strerror_get(err, sigar->errbuf, sizeof(sigar->errbuf));
157
- }
158
-
159
- char *sigar_strerror_get(int err, char *errbuf, int buflen)
160
- {
161
- char *buf = NULL;
162
- #ifdef WIN32
163
- DWORD len;
164
-
165
- len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM |
166
- FORMAT_MESSAGE_IGNORE_INSERTS,
167
- NULL,
168
- err,
169
- MAKELANGID(LANG_ENGLISH, SUBLANG_DEFAULT), /* force english */
170
- (LPTSTR)errbuf,
171
- (DWORD)buflen,
172
- NULL);
173
- #else
174
-
175
- #if defined(HAVE_STRERROR_R) && defined(HAVE_STRERROR_R_GLIBC)
176
- /*
177
- * strerror_r man page says:
178
- * "The GNU version may, but need not, use the user supplied buffer"
179
- */
180
- buf = strerror_r(err, errbuf, buflen);
181
- #elif defined(HAVE_STRERROR_R)
182
- if (strerror_r(err, errbuf, buflen) < 0) {
183
- buf = "Unknown Error";
184
- }
185
- #else
186
- /* strerror() is thread safe on solaris and hpux */
187
- buf = strerror(err);
188
- #endif
189
-
190
- if (buf != NULL) {
191
- SIGAR_STRNCPY(errbuf, buf, buflen);
192
- }
193
-
194
- #endif
195
- return errbuf;
196
- }
197
-
198
- void sigar_strerror_set(sigar_t *sigar, char *msg)
199
- {
200
- SIGAR_SSTRCPY(sigar->errbuf, msg);
201
- }
202
-
203
- #ifdef WIN32
204
- #define vsnprintf _vsnprintf
205
- #endif
206
-
207
- void sigar_strerror_printf(sigar_t *sigar, const char *format, ...)
208
- {
209
- va_list args;
210
-
211
- va_start(args, format);
212
- vsnprintf(sigar->errbuf, sizeof(sigar->errbuf), format, args);
213
- va_end(args);
214
- }
215
-
216
- /* copy apr_strfsize */
217
- SIGAR_DECLARE(char *) sigar_format_size(sigar_uint64_t size, char *buf)
218
- {
219
- const char ord[] = "KMGTPE";
220
- const char *o = ord;
221
- int remain;
222
-
223
- if (size == SIGAR_FIELD_NOTIMPL) {
224
- buf[0] = '-';
225
- buf[1] = '\0';
226
- return buf;
227
- }
228
-
229
- if (size < 973) {
230
- sprintf(buf, "%3d ", (int) size);
231
- return buf;
232
- }
233
-
234
- do {
235
- remain = (int)(size & 1023);
236
- size >>= 10;
237
-
238
- if (size >= 973) {
239
- ++o;
240
- continue;
241
- }
242
-
243
- if (size < 9 || (size == 9 && remain < 973)) {
244
- if ((remain = ((remain * 5) + 256) / 512) >= 10) {
245
- ++size;
246
- remain = 0;
247
- }
248
- sprintf(buf, "%d.%d%c", (int) size, remain, *o);
249
- return buf;
250
- }
251
-
252
- if (remain >= 512) {
253
- ++size;
254
- }
255
-
256
- sprintf(buf, "%3d%c", (int) size, *o);
257
-
258
- return buf;
259
- } while (1);
260
- }
261
-
262
-
263
- SIGAR_DECLARE(int) sigar_uptime_string(sigar_t *sigar,
264
- sigar_uptime_t *uptime,
265
- char *buffer,
266
- int buflen)
267
- {
268
- char *ptr = buffer;
269
- int time = (int)uptime->uptime;
270
- int minutes, hours, days, offset = 0;
271
-
272
- /* XXX: get rid of sprintf and/or check for overflow */
273
- days = time / (60*60*24);
274
-
275
- if (days) {
276
- offset += sprintf(ptr + offset, "%d day%s, ",
277
- days, (days > 1) ? "s" : "");
278
- }
279
-
280
- minutes = time / 60;
281
- hours = minutes / 60;
282
- hours = hours % 24;
283
- minutes = minutes % 60;
284
-
285
- if (hours) {
286
- offset += sprintf(ptr + offset, "%2d:%02d",
287
- hours, minutes);
288
- }
289
- else {
290
- offset += sprintf(ptr + offset, "%d min", minutes);
291
- }
292
-
293
- return SIGAR_OK;
294
- }
295
-
296
- /* threadsafe alternative to inet_ntoa (inet_ntop4 from apr) */
297
- int sigar_inet_ntoa(sigar_t *sigar,
298
- sigar_uint32_t address,
299
- char *addr_str)
300
- {
301
- char *next=addr_str;
302
- int n=0;
303
- const unsigned char *src =
304
- (const unsigned char *)&address;
305
-
306
- do {
307
- unsigned char u = *src++;
308
- if (u > 99) {
309
- *next++ = '0' + u/100;
310
- u %= 100;
311
- *next++ = '0' + u/10;
312
- u %= 10;
313
- }
314
- else if (u > 9) {
315
- *next++ = '0' + u/10;
316
- u %= 10;
317
- }
318
- *next++ = '0' + u;
319
- *next++ = '.';
320
- n++;
321
- } while (n < 4);
322
-
323
- *--next = 0;
324
-
325
- return SIGAR_OK;
326
- }
327
-
328
- static int sigar_ether_ntoa(char *buff, unsigned char *ptr)
329
- {
330
- sprintf(buff, "%02X:%02X:%02X:%02X:%02X:%02X",
331
- (ptr[0] & 0xff), (ptr[1] & 0xff), (ptr[2] & 0xff),
332
- (ptr[3] & 0xff), (ptr[4] & 0xff), (ptr[5] & 0xff));
333
- return SIGAR_OK;
334
- }
335
-
336
- SIGAR_DECLARE(int) sigar_net_address_equals(sigar_net_address_t *addr1,
337
- sigar_net_address_t *addr2)
338
-
339
- {
340
- if (addr1->family != addr2->family) {
341
- return EINVAL;
342
- }
343
-
344
- switch (addr1->family) {
345
- case SIGAR_AF_INET:
346
- return memcmp(&addr1->addr.in, &addr2->addr.in, sizeof(addr1->addr.in));
347
- case SIGAR_AF_INET6:
348
- return memcmp(&addr1->addr.in6, &addr2->addr.in6, sizeof(addr1->addr.in6));
349
- case SIGAR_AF_LINK:
350
- return memcmp(&addr1->addr.mac, &addr2->addr.mac, sizeof(addr1->addr.mac));
351
- default:
352
- return EINVAL;
353
- }
354
- }
355
-
356
- #if defined(SIGAR_USING_MSC6)
357
- #define sigar_inet_ntop(af, src, dst, size) NULL
358
- #define sigar_inet_ntop_errno SIGAR_ENOTIMPL
359
- #elif defined(WIN32)
360
- static char *sigar_inet_ntop(int af, const void *src, char *dst, int cnt)
361
- {
362
- struct sockaddr_in6 sa; /* note only using this for AF_INET6 */
363
-
364
- memset(&sa, '\0', sizeof(sa));
365
- sa.sin6_family = af;
366
- memcpy(&sa.sin6_addr, src, sizeof(sa.sin6_addr));
367
-
368
- if (getnameinfo((struct sockaddr *)&sa, sizeof(sa),
369
- dst, cnt, NULL, 0, NI_NUMERICHOST))
370
- {
371
- return NULL;
372
- }
373
- else {
374
- return dst;
375
- }
376
- }
377
- #define sigar_inet_ntop_errno GetLastError()
378
- #else
379
- #define sigar_inet_ntop inet_ntop
380
- #define sigar_inet_ntop_errno errno
381
- #endif
382
-
383
- SIGAR_DECLARE(int) sigar_net_address_to_string(sigar_t *sigar,
384
- sigar_net_address_t *address,
385
- char *addr_str)
386
- {
387
- *addr_str = '\0';
388
- switch (address->family) {
389
- case SIGAR_AF_INET6:
390
- if (sigar_inet_ntop(AF_INET6, (const void *)&address->addr.in6,
391
- addr_str, SIGAR_INET6_ADDRSTRLEN))
392
- {
393
- return SIGAR_OK;
394
- }
395
- else {
396
- return sigar_inet_ntop_errno;
397
- }
398
- case SIGAR_AF_INET:
399
- return sigar_inet_ntoa(sigar, address->addr.in, addr_str);
400
- case SIGAR_AF_UNSPEC:
401
- return sigar_inet_ntoa(sigar, 0, addr_str); /*XXX*/
402
- case SIGAR_AF_LINK:
403
- return sigar_ether_ntoa(addr_str, &address->addr.mac[0]);
404
- default:
405
- return EINVAL;
406
- }
407
- }
408
-
409
- SIGAR_DECLARE(const char *)sigar_net_scope_to_string(int type)
410
- {
411
- switch (type) {
412
- case SIGAR_IPV6_ADDR_ANY:
413
- return "Global";
414
- case SIGAR_IPV6_ADDR_LOOPBACK:
415
- return "Host";
416
- case SIGAR_IPV6_ADDR_LINKLOCAL:
417
- return "Link";
418
- case SIGAR_IPV6_ADDR_SITELOCAL:
419
- return "Site";
420
- case SIGAR_IPV6_ADDR_COMPATv4:
421
- return "Compat";
422
- default:
423
- return "Unknown";
424
- }
425
- }
426
-
427
- SIGAR_DECLARE(sigar_uint32_t) sigar_net_address_hash(sigar_net_address_t *address)
428
- {
429
- sigar_uint32_t hash = 0;
430
- unsigned char *data;
431
- int i=0, size, elts;
432
-
433
- switch (address->family) {
434
- case SIGAR_AF_UNSPEC:
435
- case SIGAR_AF_INET:
436
- return address->addr.in;
437
- case SIGAR_AF_INET6:
438
- data = (unsigned char *)&address->addr.in6;
439
- size = sizeof(address->addr.in6);
440
- elts = 4;
441
- break;
442
- case SIGAR_AF_LINK:
443
- data = (unsigned char *)&address->addr.mac;
444
- size = sizeof(address->addr.mac);
445
- elts = 2;
446
- break;
447
- default:
448
- return -1;
449
- }
450
-
451
- while (i<size) {
452
- int j=0;
453
- int component=0;
454
- while (j<elts && i<size) {
455
- component = (component << 8) + data[i];
456
- j++;
457
- i++;
458
- }
459
- hash += component;
460
- }
461
-
462
- return hash;
463
- }
464
-
465
- SIGAR_DECLARE(const char *)sigar_net_connection_type_get(int type)
466
- {
467
- switch (type) {
468
- case SIGAR_NETCONN_TCP:
469
- return "tcp";
470
- case SIGAR_NETCONN_UDP:
471
- return "udp";
472
- case SIGAR_NETCONN_RAW:
473
- return "raw";
474
- case SIGAR_NETCONN_UNIX:
475
- return "unix";
476
- default:
477
- return "unknown";
478
- }
479
- }
480
-
481
- SIGAR_DECLARE(const char *)sigar_net_connection_state_get(int state)
482
- {
483
- switch (state) {
484
- case SIGAR_TCP_ESTABLISHED:
485
- return "ESTABLISHED";
486
- case SIGAR_TCP_SYN_SENT:
487
- return "SYN_SENT";
488
- case SIGAR_TCP_SYN_RECV:
489
- return "SYN_RECV";
490
- case SIGAR_TCP_FIN_WAIT1:
491
- return "FIN_WAIT1";
492
- case SIGAR_TCP_FIN_WAIT2:
493
- return "FIN_WAIT2";
494
- case SIGAR_TCP_TIME_WAIT:
495
- return "TIME_WAIT";
496
- case SIGAR_TCP_CLOSE:
497
- return "CLOSE";
498
- case SIGAR_TCP_CLOSE_WAIT:
499
- return "CLOSE_WAIT";
500
- case SIGAR_TCP_LAST_ACK:
501
- return "LAST_ACK";
502
- case SIGAR_TCP_LISTEN:
503
- return "LISTEN";
504
- case SIGAR_TCP_CLOSING:
505
- return "CLOSING";
506
- case SIGAR_TCP_IDLE:
507
- return "IDLE";
508
- case SIGAR_TCP_BOUND:
509
- return "BOUND";
510
- case SIGAR_TCP_UNKNOWN:
511
- default:
512
- return "UNKNOWN";
513
- }
514
- }
515
-
516
- SIGAR_DECLARE(char *) sigar_net_interface_flags_to_string(sigar_uint64_t flags, char *buf)
517
- {
518
- *buf = '\0';
519
-
520
- if (flags == 0) {
521
- strcat(buf, "[NO FLAGS] ");
522
- }
523
- if (flags & SIGAR_IFF_UP) {
524
- strcat(buf, "UP ");
525
- }
526
- if (flags & SIGAR_IFF_BROADCAST) {
527
- strcat(buf, "BROADCAST ");
528
- }
529
- if (flags & SIGAR_IFF_DEBUG) {
530
- strcat(buf, "DEBUG ");
531
- }
532
- if (flags & SIGAR_IFF_LOOPBACK) {
533
- strcat(buf, "LOOPBACK ");
534
- }
535
- if (flags & SIGAR_IFF_POINTOPOINT) {
536
- strcat(buf, "POINTOPOINT ");
537
- }
538
- if (flags & SIGAR_IFF_NOTRAILERS) {
539
- strcat(buf, "NOTRAILERS ");
540
- }
541
- if (flags & SIGAR_IFF_RUNNING) {
542
- strcat(buf, "RUNNING ");
543
- }
544
- if (flags & SIGAR_IFF_NOARP) {
545
- strcat(buf, "NOARP ");
546
- }
547
- if (flags & SIGAR_IFF_PROMISC) {
548
- strcat(buf, "PROMISC ");
549
- }
550
- if (flags & SIGAR_IFF_ALLMULTI) {
551
- strcat(buf, "ALLMULTI ");
552
- }
553
- if (flags & SIGAR_IFF_MULTICAST) {
554
- strcat(buf, "MULTICAST ");
555
- }
556
- if (flags & SIGAR_IFF_SLAVE) {
557
- strcat(buf, "SLAVE ");
558
- }
559
- if (flags & SIGAR_IFF_MASTER) {
560
- strcat(buf, "MASTER ");
561
- }
562
- if (flags & SIGAR_IFF_DYNAMIC) {
563
- strcat(buf, "DYNAMIC ");
564
- }
565
-
566
- return buf;
567
- }
568
-
569
- #ifdef WIN32
570
- #define NET_SERVICES_FILE "C:\\windows\\system32\\drivers\\etc\\services"
571
- #else
572
- #define NET_SERVICES_FILE "/etc/services"
573
- #endif
574
-
575
- static int net_services_parse(sigar_cache_t *names, char *type)
576
- {
577
- FILE *fp;
578
- char buffer[8192], *ptr;
579
- char *file;
580
-
581
-
582
- if (!(file = getenv("SIGAR_NET_SERVICES_FILE"))) {
583
- file = NET_SERVICES_FILE;
584
- }
585
-
586
- if (!(fp = fopen(file, "r"))) {
587
- return errno;
588
- }
589
-
590
- while ((ptr = fgets(buffer, sizeof(buffer), fp))) {
591
- int port;
592
- char name[256], proto[56];
593
- sigar_cache_entry_t *entry;
594
-
595
- while (sigar_isspace(*ptr)) {
596
- ++ptr;
597
- }
598
- if ((*ptr == '#') || (*ptr == '\0')) {
599
- continue;
600
- }
601
-
602
- if (sscanf(ptr, "%s%d/%s", name, &port, proto) != 3) {
603
- continue;
604
- }
605
- if (!strEQ(type, proto)) {
606
- continue;
607
- }
608
-
609
- entry = sigar_cache_get(names, port);
610
- if (!entry->value) {
611
- entry->value = strdup(name);
612
- }
613
- }
614
-
615
- fclose(fp);
616
- return SIGAR_OK;
617
- }
618
-
619
- SIGAR_DECLARE(char *)sigar_net_services_name_get(sigar_t *sigar,
620
- int protocol, unsigned long port)
621
- {
622
- sigar_cache_entry_t *entry;
623
- sigar_cache_t **names;
624
- char *pname;
625
-
626
- switch (protocol) {
627
- case SIGAR_NETCONN_TCP:
628
- names = &sigar->net_services_tcp;
629
- pname = "tcp";
630
- break;
631
- case SIGAR_NETCONN_UDP:
632
- names = &sigar->net_services_udp;
633
- pname = "udp";
634
- break;
635
- default:
636
- return NULL;
637
- }
638
-
639
- if (*names == NULL) {
640
- *names = sigar_cache_new(1024);
641
- net_services_parse(*names, pname);
642
- }
643
-
644
- if ((entry = sigar_cache_find(*names, port))) {
645
- return (char *)entry->value;
646
- }
647
- else {
648
- return NULL;
649
- }
650
- }
651
-
652
- SIGAR_DECLARE(int) sigar_cpu_perc_calculate(sigar_cpu_t *prev,
653
- sigar_cpu_t *curr,
654
- sigar_cpu_perc_t *perc)
655
- {
656
- double diff_user, diff_sys, diff_nice, diff_idle;
657
- double diff_wait, diff_irq, diff_soft_irq, diff_stolen;
658
- double diff_total;
659
-
660
- diff_user = curr->user - prev->user;
661
- diff_sys = curr->sys - prev->sys;
662
- diff_nice = curr->nice - prev->nice;
663
- diff_idle = curr->idle - prev->idle;
664
- diff_wait = curr->wait - prev->wait;
665
- diff_irq = curr->irq - prev->irq;
666
- diff_soft_irq = curr->soft_irq - prev->soft_irq;
667
- diff_stolen = curr->stolen - prev->stolen;
668
-
669
- diff_user = diff_user < 0 ? 0 : diff_user;
670
- diff_sys = diff_sys < 0 ? 0 : diff_sys;
671
- diff_nice = diff_nice < 0 ? 0 : diff_nice;
672
- diff_idle = diff_idle < 0 ? 0 : diff_idle;
673
- diff_wait = diff_wait < 0 ? 0 : diff_wait;
674
- diff_irq = diff_irq < 0 ? 0 : diff_irq;
675
- diff_soft_irq = diff_soft_irq < 0 ? 0 : diff_soft_irq;
676
- diff_stolen = diff_stolen < 0 ? 0 : diff_stolen;
677
-
678
- diff_total =
679
- diff_user + diff_sys + diff_nice + diff_idle +
680
- diff_wait + diff_irq + diff_soft_irq +
681
- diff_stolen;
682
-
683
- perc->user = diff_user / diff_total;
684
- perc->sys = diff_sys / diff_total;
685
- perc->nice = diff_nice / diff_total;
686
- perc->idle = diff_idle / diff_total;
687
- perc->wait = diff_wait / diff_total;
688
- perc->irq = diff_irq / diff_total;
689
- perc->soft_irq = diff_soft_irq / diff_total;
690
- perc->stolen = diff_stolen / diff_total;
691
-
692
- perc->combined =
693
- perc->user + perc->sys + perc->nice + perc->wait;
694
-
695
- return SIGAR_OK;
696
- }