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
@@ -0,0 +1,815 @@
1
+ /*
2
+ * Copyright (c) 2004-2005, 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
+ /* ====================================================================
20
+ * The Apache Software License, Version 1.1
21
+ *
22
+ * Copyright (c) 2000-2003 The Apache Software Foundation. All rights
23
+ * reserved.
24
+ *
25
+ * Redistribution and use in source and binary forms, with or without
26
+ * modification, are permitted provided that the following conditions
27
+ * are met:
28
+ *
29
+ * 1. Redistributions of source code must retain the above copyright
30
+ * notice, this list of conditions and the following disclaimer.
31
+ *
32
+ * 2. Redistributions in binary form must reproduce the above copyright
33
+ * notice, this list of conditions and the following disclaimer in
34
+ * the documentation and/or other materials provided with the
35
+ * distribution.
36
+ *
37
+ * 3. The end-user documentation included with the redistribution,
38
+ * if any, must include the following acknowledgment:
39
+ * "This product includes software developed by the
40
+ * Apache Software Foundation (http://www.apache.org/)."
41
+ * Alternately, this acknowledgment may appear in the software itself,
42
+ * if and wherever such third-party acknowledgments normally appear.
43
+ *
44
+ * 4. The names "Apache" and "Apache Software Foundation" must
45
+ * not be used to endorse or promote products derived from this
46
+ * software without prior written permission. For written
47
+ * permission, please contact apache@apache.org.
48
+ *
49
+ * 5. Products derived from this software may not be called "Apache",
50
+ * nor may "Apache" appear in their name, without prior written
51
+ * permission of the Apache Software Foundation.
52
+ *
53
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
54
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
55
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
56
+ * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
57
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
58
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
59
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
60
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
61
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
62
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
63
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64
+ * SUCH DAMAGE.
65
+ * ====================================================================
66
+ *
67
+ * This software consists of voluntary contributions made by many
68
+ * individuals on behalf of the Apache Software Foundation. For more
69
+ * information on the Apache Software Foundation, please see
70
+ * <http://www.apache.org/>.
71
+ */
72
+
73
+ #ifndef WIN32
74
+ # ifdef _AIX
75
+ # define _LARGE_FILES
76
+ # else
77
+ # define _FILE_OFFSET_BITS 64
78
+ # define _LARGEFILE64_SOURCE
79
+ # endif
80
+ #endif
81
+
82
+ #include "sigar.h"
83
+
84
+ #ifndef WIN32
85
+ #if defined(__FreeBSD__) || defined(__OpenBSD__)
86
+ # include <sys/param.h>
87
+ # include <sys/mount.h>
88
+ #else
89
+ # include <sys/statvfs.h>
90
+ # define HAVE_STATVFS
91
+ #endif
92
+ #include <errno.h>
93
+
94
+ #define SIGAR_FS_BLOCKS_TO_BYTES(val, bsize) ((val * bsize) >> 1)
95
+
96
+ int sigar_statvfs(sigar_t *sigar,
97
+ const char *dirname,
98
+ sigar_file_system_usage_t *fsusage)
99
+ {
100
+ sigar_uint64_t val, bsize;
101
+ #ifdef HAVE_STATVFS
102
+ struct statvfs buf;
103
+ int status =
104
+ # if defined(__sun) && !defined(_LP64)
105
+ /* http://bugs.opensolaris.org/view_bug.do?bug_id=4462986 */
106
+ statvfs(dirname, (void *)&buf);
107
+ # else
108
+ statvfs(dirname, &buf);
109
+ # endif
110
+ #else
111
+ struct statfs buf;
112
+ int status = statfs(dirname, &buf);
113
+ #endif
114
+
115
+ if (status != 0) {
116
+ return errno;
117
+ }
118
+
119
+ #ifdef HAVE_STATVFS
120
+ bsize = buf.f_frsize / 512;
121
+ #else
122
+ bsize = buf.f_bsize / 512;
123
+ #endif
124
+ val = buf.f_blocks;
125
+ fsusage->total = SIGAR_FS_BLOCKS_TO_BYTES(val, bsize);
126
+ val = buf.f_bfree;
127
+ fsusage->free = SIGAR_FS_BLOCKS_TO_BYTES(val, bsize);
128
+ val = buf.f_bavail;
129
+ fsusage->avail = SIGAR_FS_BLOCKS_TO_BYTES(val, bsize);
130
+ fsusage->used = fsusage->total - fsusage->free;
131
+ fsusage->files = buf.f_files;
132
+ fsusage->free_files = buf.f_ffree;
133
+
134
+ return SIGAR_OK;
135
+ }
136
+ #endif
137
+
138
+ /*
139
+ * whittled down version of apr/file_info/{unix,win32}/filestat.c
140
+ * to fillin sigar_fileattrs_t
141
+ */
142
+ #include "sigar_fileinfo.h"
143
+ #include "sigar_log.h"
144
+
145
+ #ifndef SIGAR_ZERO
146
+ #define SIGAR_ZERO(s) \
147
+ memset(s, '\0', sizeof(*(s)))
148
+ #endif
149
+
150
+ #ifdef WIN32
151
+ #include <windows.h>
152
+ sigar_uint64_t sigar_FileTimeToTime(FILETIME *ft);
153
+ #else
154
+ #include <string.h>
155
+ #endif
156
+
157
+ static const char* types[] = {
158
+ "none",
159
+ "regular",
160
+ "directory",
161
+ "character device",
162
+ "block device",
163
+ "pipe",
164
+ "symbolic link",
165
+ "socket",
166
+ "unknown"
167
+ };
168
+
169
+ SIGAR_DECLARE(const char *)
170
+ sigar_file_attrs_type_string_get(sigar_file_type_e type)
171
+ {
172
+ if ((type < SIGAR_FILETYPE_NOFILE) ||
173
+ (type > SIGAR_FILETYPE_UNKFILE))
174
+ {
175
+ type = SIGAR_FILETYPE_UNKFILE;
176
+ }
177
+
178
+ return types[type];
179
+ }
180
+
181
+ static const sigar_uint64_t perm_modes[] = {
182
+ SIGAR_UREAD, SIGAR_UWRITE, SIGAR_UEXECUTE,
183
+ SIGAR_GREAD, SIGAR_GWRITE, SIGAR_GEXECUTE,
184
+ SIGAR_WREAD, SIGAR_WWRITE, SIGAR_WEXECUTE
185
+ };
186
+
187
+ static const char perm_chars[] = "rwx";
188
+
189
+ SIGAR_DECLARE(char *)
190
+ sigar_file_attrs_permissions_string_get(sigar_uint64_t permissions,
191
+ char *str)
192
+ {
193
+ char *ptr = str;
194
+ int i=0, j=0;
195
+
196
+ for (i=0; i<9; i+=3) {
197
+ for (j=0; j<3; j++) {
198
+ if (permissions & perm_modes[i+j]) {
199
+ *ptr = perm_chars[j];
200
+ }
201
+ else {
202
+ *ptr = '-';
203
+ }
204
+ ptr++;
205
+ }
206
+ }
207
+
208
+ *ptr = '\0';
209
+ return str;
210
+ }
211
+
212
+ static const int perm_int[] = {
213
+ 400, 200, 100,
214
+ 40, 20, 10,
215
+ 4, 2, 1
216
+ };
217
+
218
+ SIGAR_DECLARE(int)sigar_file_attrs_mode_get(sigar_uint64_t permissions)
219
+ {
220
+ int i=0;
221
+ int perms = 0;
222
+
223
+ /* no doubt there is some fancy bitshifting
224
+ * to convert, but this works fine.
225
+ */
226
+ for (i=0; i<9; i++) {
227
+ if (permissions & perm_modes[i]) {
228
+ perms += perm_int[i];
229
+ }
230
+ }
231
+
232
+ return perms;
233
+ }
234
+
235
+ #define IS_DOTDIR(dir) \
236
+ ((dir[0] == '.') && (!dir[1] || ((dir[1] == '.') && !dir[2])))
237
+
238
+ #define DIR_STAT_WARN() \
239
+ sigar_log_printf(sigar, SIGAR_LOG_WARN, \
240
+ "dir_stat: cannot stat `%s': %s", \
241
+ name, \
242
+ sigar_strerror(sigar, status))
243
+
244
+ #if defined(NETWARE)
245
+
246
+ int sigar_dir_stat_get(sigar_t *sigar,
247
+ const char *dir,
248
+ sigar_dir_stat_t *dirstats)
249
+ {
250
+ return SIGAR_ENOTIMPL;
251
+ }
252
+
253
+ int sigar_file_attrs_get(sigar_t *sigar,
254
+ const char *file,
255
+ sigar_file_attrs_t *fileattrs)
256
+ {
257
+ return SIGAR_ENOTIMPL;
258
+ }
259
+
260
+ int sigar_link_attrs_get(sigar_t *sigar,
261
+ const char *file,
262
+ sigar_file_attrs_t *fileattrs)
263
+ {
264
+ return SIGAR_ENOTIMPL;
265
+ }
266
+
267
+ #elif defined(WIN32)
268
+
269
+ #include <accctrl.h>
270
+ #include <aclapi.h>
271
+
272
+ static void fillin_fileattrs(sigar_file_attrs_t *finfo,
273
+ WIN32_FILE_ATTRIBUTE_DATA *wininfo,
274
+ int linkinfo)
275
+ {
276
+ DWORD *sizes = &wininfo->nFileSizeHigh;
277
+
278
+ finfo->atime = sigar_FileTimeToTime(&wininfo->ftLastAccessTime) / 1000;
279
+ finfo->ctime = sigar_FileTimeToTime(&wininfo->ftCreationTime) / 1000;
280
+ finfo->mtime = sigar_FileTimeToTime(&wininfo->ftLastWriteTime) / 1000;
281
+
282
+ finfo->size =
283
+ (sigar_uint64_t)sizes[1] | ((sigar_uint64_t)sizes[0] << 32);
284
+
285
+ if (linkinfo &&
286
+ (wininfo->dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)) {
287
+ finfo->type = SIGAR_FILETYPE_LNK;
288
+ }
289
+ else if (wininfo->dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
290
+ finfo->type = SIGAR_FILETYPE_DIR;
291
+ }
292
+ else {
293
+ finfo->type = SIGAR_FILETYPE_REG;
294
+ }
295
+ }
296
+
297
+ static sigar_uint64_t convert_perms(ACCESS_MASK acc, sigar_uint64_t scope)
298
+ {
299
+ sigar_uint64_t perms = 0;
300
+ if (acc & FILE_EXECUTE) {
301
+ perms |= SIGAR_WEXECUTE;
302
+ }
303
+ if (acc & FILE_WRITE_DATA) {
304
+ perms |= SIGAR_WWRITE;
305
+ }
306
+ if (acc & FILE_READ_DATA) {
307
+ perms |= SIGAR_WREAD;
308
+ }
309
+
310
+ return (perms << scope);
311
+ }
312
+
313
+ static int get_security_info(sigar_t *sigar,
314
+ const char *file,
315
+ sigar_file_attrs_t *fileattrs)
316
+ {
317
+ DWORD retval;
318
+ PSID user = NULL, group = NULL, world = NULL;
319
+ PACL dacl = NULL;
320
+ PSECURITY_DESCRIPTOR pdesc = NULL;
321
+ SECURITY_INFORMATION sinfo =
322
+ OWNER_SECURITY_INFORMATION |
323
+ GROUP_SECURITY_INFORMATION |
324
+ DACL_SECURITY_INFORMATION;
325
+ TRUSTEE ident = {NULL, NO_MULTIPLE_TRUSTEE, TRUSTEE_IS_SID};
326
+ ACCESS_MASK acc;
327
+ SID_IDENTIFIER_AUTHORITY auth = SECURITY_WORLD_SID_AUTHORITY;
328
+
329
+ retval = GetNamedSecurityInfo((char *)file,
330
+ SE_FILE_OBJECT,
331
+ sinfo,
332
+ &user,
333
+ &group,
334
+ &dacl,
335
+ NULL,
336
+ &pdesc);
337
+
338
+ if (retval != ERROR_SUCCESS) {
339
+ return retval;
340
+ }
341
+
342
+ if (!AllocateAndInitializeSid(&auth, 1, SECURITY_WORLD_RID,
343
+ 0, 0, 0, 0, 0, 0, 0, &world))
344
+ {
345
+ world = NULL;
346
+ }
347
+
348
+ ident.TrusteeType = TRUSTEE_IS_USER;
349
+ ident.ptstrName = user;
350
+ if (GetEffectiveRightsFromAcl(dacl, &ident, &acc) == ERROR_SUCCESS) {
351
+ fileattrs->permissions |= convert_perms(acc, 8);
352
+ }
353
+
354
+ ident.TrusteeType = TRUSTEE_IS_GROUP;
355
+ ident.ptstrName = group;
356
+ if (GetEffectiveRightsFromAcl(dacl, &ident, &acc) == ERROR_SUCCESS) {
357
+ fileattrs->permissions |= convert_perms(acc, 4);
358
+ }
359
+
360
+ if (world) {
361
+ ident.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
362
+ ident.ptstrName = world;
363
+ if (GetEffectiveRightsFromAcl(dacl, &ident, &acc) == ERROR_SUCCESS) {
364
+ fileattrs->permissions |= convert_perms(acc, 0);
365
+ }
366
+ }
367
+
368
+ if (world) {
369
+ FreeSid(world);
370
+ }
371
+
372
+ LocalFree(pdesc);
373
+
374
+ return SIGAR_OK;
375
+ }
376
+
377
+ static int fileattrs_get(sigar_t *sigar,
378
+ const char *file,
379
+ sigar_file_attrs_t *fileattrs,
380
+ int linkinfo)
381
+ {
382
+ BY_HANDLE_FILE_INFORMATION info;
383
+ WIN32_FILE_ATTRIBUTE_DATA attrs;
384
+ HANDLE handle;
385
+ DWORD flags;
386
+
387
+ SIGAR_ZERO(fileattrs);
388
+
389
+ if (!GetFileAttributesExA(file,
390
+ GetFileExInfoStandard,
391
+ &attrs))
392
+ {
393
+ return GetLastError();
394
+ }
395
+
396
+ fillin_fileattrs(fileattrs, &attrs, linkinfo);
397
+
398
+ flags = fileattrs->type == SIGAR_FILETYPE_DIR ?
399
+ FILE_FLAG_BACKUP_SEMANTICS :
400
+ FILE_ATTRIBUTE_NORMAL;
401
+
402
+ /**
403
+ * We need to set dwDesiredAccess to 0 to work in cases where GENERIC_READ can fail.
404
+ *
405
+ * see: http://msdn.microsoft.com/en-us/library/aa363858(VS.85).aspx
406
+ */
407
+ handle = CreateFile(file,
408
+ 0,
409
+ 0,
410
+ NULL,
411
+ OPEN_EXISTING,
412
+ flags,
413
+ NULL);
414
+
415
+ if (handle != INVALID_HANDLE_VALUE) {
416
+ if (GetFileInformationByHandle(handle, &info)) {
417
+ fileattrs->inode =
418
+ info.nFileIndexLow |
419
+ (info.nFileIndexHigh << 32);
420
+ fileattrs->device = info.dwVolumeSerialNumber;
421
+ fileattrs->nlink = info.nNumberOfLinks;
422
+ }
423
+ CloseHandle(handle);
424
+ }
425
+
426
+ get_security_info(sigar, file, fileattrs);
427
+
428
+ return SIGAR_OK;
429
+ }
430
+
431
+ SIGAR_DECLARE(int) sigar_file_attrs_get(sigar_t *sigar,
432
+ const char *file,
433
+ sigar_file_attrs_t *fileattrs)
434
+ {
435
+ return fileattrs_get(sigar, file, fileattrs, 0);
436
+ }
437
+
438
+ SIGAR_DECLARE(int) sigar_link_attrs_get(sigar_t *sigar,
439
+ const char *file,
440
+ sigar_file_attrs_t *fileattrs)
441
+ {
442
+ return fileattrs_get(sigar, file, fileattrs, 1);
443
+ }
444
+
445
+ static __inline int file_type(char *file)
446
+ {
447
+ WIN32_FILE_ATTRIBUTE_DATA attrs;
448
+
449
+ if (!GetFileAttributesExA(file,
450
+ GetFileExInfoStandard,
451
+ &attrs))
452
+ {
453
+ return -1;
454
+ }
455
+
456
+ if (attrs.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
457
+ return SIGAR_FILETYPE_LNK;
458
+ }
459
+ else if (attrs.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
460
+ return SIGAR_FILETYPE_DIR;
461
+ }
462
+ else {
463
+ return SIGAR_FILETYPE_REG;
464
+ }
465
+ }
466
+
467
+ static int dir_stat_get(sigar_t *sigar,
468
+ const char *dir,
469
+ sigar_dir_stat_t *dirstats,
470
+ int recurse)
471
+ {
472
+ int status;
473
+ char name[SIGAR_PATH_MAX+1];
474
+ int len = strlen(dir);
475
+ int max = sizeof(name)-len-1;
476
+ char *ptr = name;
477
+ WIN32_FIND_DATA data;
478
+ HANDLE handle;
479
+ DWORD error;
480
+ char delim;
481
+
482
+ if (file_type((char *)dir) != SIGAR_FILETYPE_DIR) {
483
+ return ERROR_NO_MORE_FILES;
484
+ }
485
+
486
+ strncpy(name, dir, sizeof(name));
487
+ ptr += len;
488
+ if (strchr(dir, '/')) {
489
+ delim = '/';
490
+ }
491
+ else {
492
+ delim = '\\';
493
+ }
494
+ if (name[len] != delim) {
495
+ *ptr++ = delim;
496
+ len++;
497
+ max--;
498
+ }
499
+
500
+ /* e.g. "C:\sigar\*" */
501
+ name[len] = '*';
502
+ name[len+1] = '\0';
503
+
504
+ handle = FindFirstFile(name, &data);
505
+ if (handle == INVALID_HANDLE_VALUE) {
506
+ return GetLastError();
507
+ }
508
+
509
+ do {
510
+ /* skip '.' and '..' */
511
+ if (IS_DOTDIR(data.cFileName)) {
512
+ continue;
513
+ }
514
+
515
+ dirstats->disk_usage +=
516
+ (data.nFileSizeHigh * (MAXDWORD+1)) +
517
+ data.nFileSizeLow;
518
+
519
+ /* e.g. "C:\sigar\lib" */
520
+ strncpy(ptr, data.cFileName, max);
521
+ ptr[max] = '\0';
522
+
523
+ switch (file_type(name)) {
524
+ case -1:
525
+ break;
526
+ case SIGAR_FILETYPE_REG:
527
+ ++dirstats->files;
528
+ break;
529
+ case SIGAR_FILETYPE_DIR:
530
+ ++dirstats->subdirs;
531
+ if (recurse) {
532
+ status =
533
+ dir_stat_get(sigar, name,
534
+ dirstats, recurse);
535
+ if (status != SIGAR_OK) {
536
+ DIR_STAT_WARN();
537
+ }
538
+ }
539
+ break;
540
+ case SIGAR_FILETYPE_LNK:
541
+ ++dirstats->symlinks;
542
+ break;
543
+ case SIGAR_FILETYPE_CHR:
544
+ ++dirstats->chrdevs;
545
+ break;
546
+ case SIGAR_FILETYPE_BLK:
547
+ ++dirstats->blkdevs;
548
+ break;
549
+ case SIGAR_FILETYPE_SOCK:
550
+ ++dirstats->sockets;
551
+ break;
552
+ default:
553
+ ++dirstats->total;
554
+ }
555
+ } while (FindNextFile(handle, &data));
556
+
557
+ error = GetLastError();
558
+
559
+ FindClose(handle);
560
+
561
+ if (error != ERROR_NO_MORE_FILES) {
562
+ return error;
563
+ }
564
+
565
+ dirstats->total =
566
+ dirstats->files +
567
+ dirstats->subdirs +
568
+ dirstats->symlinks +
569
+ dirstats->chrdevs +
570
+ dirstats->blkdevs +
571
+ dirstats->sockets;
572
+
573
+ return SIGAR_OK;
574
+ }
575
+
576
+ #else
577
+
578
+ #include <dirent.h>
579
+ #include <errno.h>
580
+ #include <sys/stat.h>
581
+ #include <sys/types.h>
582
+
583
+ static sigar_file_type_e filetype_from_mode(mode_t mode)
584
+ {
585
+ sigar_file_type_e type;
586
+
587
+ switch (mode & S_IFMT) {
588
+ case S_IFREG:
589
+ type = SIGAR_FILETYPE_REG; break;
590
+ case S_IFDIR:
591
+ type = SIGAR_FILETYPE_DIR; break;
592
+ case S_IFLNK:
593
+ type = SIGAR_FILETYPE_LNK; break;
594
+ case S_IFCHR:
595
+ type = SIGAR_FILETYPE_CHR; break;
596
+ case S_IFBLK:
597
+ type = SIGAR_FILETYPE_BLK; break;
598
+ #if defined(S_IFFIFO)
599
+ case S_IFFIFO:
600
+ type = SIGAR_FILETYPE_PIPE; break;
601
+ #endif
602
+ #if !defined(BEOS) && defined(S_IFSOCK)
603
+ case S_IFSOCK:
604
+ type = SIGAR_FILETYPE_SOCK; break;
605
+ #endif
606
+
607
+ default:
608
+ /* Work around missing S_IFxxx values above
609
+ * for Linux et al.
610
+ */
611
+ #if !defined(S_IFFIFO) && defined(S_ISFIFO)
612
+ if (S_ISFIFO(mode)) {
613
+ type = SIGAR_FILETYPE_PIPE;
614
+ } else
615
+ #endif
616
+ #if !defined(BEOS) && !defined(S_IFSOCK) && defined(S_ISSOCK)
617
+ if (S_ISSOCK(mode)) {
618
+ type = SIGAR_FILETYPE_SOCK;
619
+ } else
620
+ #endif
621
+ type = SIGAR_FILETYPE_UNKFILE;
622
+ }
623
+ return type;
624
+ }
625
+
626
+ static sigar_uint64_t sigar_unix_mode2perms(mode_t mode)
627
+ {
628
+ sigar_uint64_t perms = 0;
629
+
630
+ if (mode & S_IRUSR)
631
+ perms |= SIGAR_UREAD;
632
+ if (mode & S_IWUSR)
633
+ perms |= SIGAR_UWRITE;
634
+ if (mode & S_IXUSR)
635
+ perms |= SIGAR_UEXECUTE;
636
+
637
+ if (mode & S_IRGRP)
638
+ perms |= SIGAR_GREAD;
639
+ if (mode & S_IWGRP)
640
+ perms |= SIGAR_GWRITE;
641
+ if (mode & S_IXGRP)
642
+ perms |= SIGAR_GEXECUTE;
643
+
644
+ if (mode & S_IROTH)
645
+ perms |= SIGAR_WREAD;
646
+ if (mode & S_IWOTH)
647
+ perms |= SIGAR_WWRITE;
648
+ if (mode & S_IXOTH)
649
+ perms |= SIGAR_WEXECUTE;
650
+
651
+ return perms;
652
+ }
653
+
654
+ static void copy_stat_info(sigar_file_attrs_t *fileattrs,
655
+ struct stat *info)
656
+ {
657
+ fileattrs->permissions = sigar_unix_mode2perms(info->st_mode);
658
+ fileattrs->type = filetype_from_mode(info->st_mode);
659
+ fileattrs->uid = info->st_uid;
660
+ fileattrs->gid = info->st_gid;
661
+ fileattrs->size = info->st_size;
662
+ fileattrs->inode = info->st_ino;
663
+ fileattrs->device = info->st_dev;
664
+ fileattrs->nlink = info->st_nlink;
665
+ fileattrs->atime = info->st_atime;
666
+ fileattrs->mtime = info->st_mtime;
667
+ fileattrs->ctime = info->st_ctime;
668
+ fileattrs->atime *= 1000;
669
+ fileattrs->mtime *= 1000;
670
+ fileattrs->ctime *= 1000;
671
+ }
672
+
673
+ int sigar_file_attrs_get(sigar_t *sigar,
674
+ const char *file,
675
+ sigar_file_attrs_t *fileattrs)
676
+ {
677
+ struct stat info;
678
+
679
+ if (stat(file, &info) == 0) {
680
+ copy_stat_info(fileattrs, &info);
681
+ return SIGAR_OK;
682
+ }
683
+ else {
684
+ return errno;
685
+ }
686
+ }
687
+
688
+ int sigar_link_attrs_get(sigar_t *sigar,
689
+ const char *file,
690
+ sigar_file_attrs_t *fileattrs)
691
+ {
692
+ struct stat info;
693
+
694
+ if (lstat(file, &info) == 0) {
695
+ copy_stat_info(fileattrs, &info);
696
+ return SIGAR_OK;
697
+ }
698
+ else {
699
+ return errno;
700
+ }
701
+ }
702
+
703
+ static int dir_stat_get(sigar_t *sigar,
704
+ const char *dir,
705
+ sigar_dir_stat_t *dirstats,
706
+ int recurse)
707
+ {
708
+ int status;
709
+ char name[SIGAR_PATH_MAX+1];
710
+ int len = strlen(dir);
711
+ int max = sizeof(name)-len-1;
712
+ char *ptr = name;
713
+ DIR *dirp = opendir(dir);
714
+ struct dirent *ent;
715
+ struct stat info;
716
+ #ifdef HAVE_READDIR_R
717
+ struct dirent dbuf;
718
+ #endif
719
+
720
+ if (!dirp) {
721
+ return errno;
722
+ }
723
+
724
+ strncpy(name, dir, sizeof(name));
725
+ ptr += len;
726
+ if (name[len] != '/') {
727
+ *ptr++ = '/';
728
+ len++;
729
+ max--;
730
+ }
731
+
732
+ #ifdef HAVE_READDIR_R
733
+ while (readdir_r(dirp, &dbuf, &ent) == 0) {
734
+ if (ent == NULL) {
735
+ break;
736
+ }
737
+ #else
738
+ while ((ent = readdir(dirp))) {
739
+ #endif
740
+ /* skip '.' and '..' */
741
+ if (IS_DOTDIR(ent->d_name)) {
742
+ continue;
743
+ }
744
+
745
+ strncpy(ptr, ent->d_name, max);
746
+ ptr[max] = '\0';
747
+
748
+ if (lstat(name, &info) != 0) {
749
+ continue;
750
+ }
751
+
752
+ dirstats->disk_usage += info.st_size;
753
+
754
+ switch (filetype_from_mode(info.st_mode)) {
755
+ case SIGAR_FILETYPE_REG:
756
+ ++dirstats->files;
757
+ break;
758
+ case SIGAR_FILETYPE_DIR:
759
+ ++dirstats->subdirs;
760
+ if (recurse) {
761
+ status =
762
+ dir_stat_get(sigar, name,
763
+ dirstats, recurse);
764
+ if (status != SIGAR_OK) {
765
+ DIR_STAT_WARN();
766
+ }
767
+ }
768
+ break;
769
+ case SIGAR_FILETYPE_LNK:
770
+ ++dirstats->symlinks;
771
+ break;
772
+ case SIGAR_FILETYPE_CHR:
773
+ ++dirstats->chrdevs;
774
+ break;
775
+ case SIGAR_FILETYPE_BLK:
776
+ ++dirstats->blkdevs;
777
+ break;
778
+ case SIGAR_FILETYPE_SOCK:
779
+ ++dirstats->sockets;
780
+ break;
781
+ default:
782
+ ++dirstats->total;
783
+ }
784
+ }
785
+
786
+ dirstats->total =
787
+ dirstats->files +
788
+ dirstats->subdirs +
789
+ dirstats->symlinks +
790
+ dirstats->chrdevs +
791
+ dirstats->blkdevs +
792
+ dirstats->sockets;
793
+
794
+ closedir(dirp);
795
+
796
+ return SIGAR_OK;
797
+ }
798
+
799
+ #endif
800
+
801
+ SIGAR_DECLARE(int) sigar_dir_stat_get(sigar_t *sigar,
802
+ const char *dir,
803
+ sigar_dir_stat_t *dirstats)
804
+ {
805
+ SIGAR_ZERO(dirstats);
806
+ return dir_stat_get(sigar, dir, dirstats, 0);
807
+ }
808
+
809
+ SIGAR_DECLARE(int) sigar_dir_usage_get(sigar_t *sigar,
810
+ const char *dir,
811
+ sigar_dir_usage_t *dirusage)
812
+ {
813
+ SIGAR_ZERO(dirusage);
814
+ return dir_stat_get(sigar, dir, dirusage, 1);
815
+ }