sigar 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. data/README +2 -0
  2. data/Rakefile +105 -0
  3. data/bindings/SigarBuild.pm +310 -0
  4. data/bindings/SigarWrapper.pm +2978 -0
  5. data/bindings/ruby/examples/arp.rb +24 -0
  6. data/bindings/ruby/examples/cpu_info.rb +35 -0
  7. data/bindings/ruby/examples/df.rb +49 -0
  8. data/bindings/ruby/examples/free.rb +36 -0
  9. data/bindings/ruby/examples/ifconfig.rb +101 -0
  10. data/bindings/ruby/examples/logging.rb +58 -0
  11. data/bindings/ruby/examples/net_info.rb +31 -0
  12. data/bindings/ruby/examples/netstat.rb +71 -0
  13. data/bindings/ruby/examples/pargs.rb +35 -0
  14. data/bindings/ruby/examples/penv.rb +31 -0
  15. data/bindings/ruby/examples/route.rb +48 -0
  16. data/bindings/ruby/examples/version.rb +40 -0
  17. data/bindings/ruby/examples/who.rb +30 -0
  18. data/bindings/ruby/extconf.rb +128 -0
  19. data/bindings/ruby/rbsigar.c +888 -0
  20. data/bindings/ruby/test/cpu_test.rb +40 -0
  21. data/bindings/ruby/test/file_system_test.rb +43 -0
  22. data/bindings/ruby/test/helper.rb +57 -0
  23. data/bindings/ruby/test/loadavg_test.rb +30 -0
  24. data/bindings/ruby/test/mem_test.rb +45 -0
  25. data/bindings/ruby/test/swap_test.rb +36 -0
  26. data/bindings/ruby/test/uptime_test.rb +26 -0
  27. data/include/sigar.h +939 -0
  28. data/include/sigar_fileinfo.h +157 -0
  29. data/include/sigar_format.h +65 -0
  30. data/include/sigar_getline.h +18 -0
  31. data/include/sigar_log.h +80 -0
  32. data/include/sigar_private.h +422 -0
  33. data/include/sigar_ptql.h +53 -0
  34. data/include/sigar_util.h +191 -0
  35. data/src/os/aix/aix_sigar.c +2151 -0
  36. data/src/os/aix/sigar_os.h +73 -0
  37. data/src/os/darwin/Info.plist.in +27 -0
  38. data/src/os/darwin/darwin_sigar.c +3709 -0
  39. data/src/os/darwin/sigar_os.h +80 -0
  40. data/src/os/hpux/hpux_sigar.c +1342 -0
  41. data/src/os/hpux/sigar_os.h +49 -0
  42. data/src/os/linux/linux_sigar.c +2782 -0
  43. data/src/os/linux/sigar_os.h +82 -0
  44. data/src/os/solaris/get_mib2.c +321 -0
  45. data/src/os/solaris/get_mib2.h +127 -0
  46. data/src/os/solaris/kstats.c +181 -0
  47. data/src/os/solaris/procfs.c +97 -0
  48. data/src/os/solaris/sigar_os.h +224 -0
  49. data/src/os/solaris/solaris_sigar.c +2717 -0
  50. data/src/os/win32/peb.c +212 -0
  51. data/src/os/win32/sigar.rc.in +40 -0
  52. data/src/os/win32/sigar_os.h +653 -0
  53. data/src/os/win32/sigar_pdh.h +47 -0
  54. data/src/os/win32/win32_sigar.c +3911 -0
  55. data/src/sigar.c +2428 -0
  56. data/src/sigar_cache.c +179 -0
  57. data/src/sigar_fileinfo.c +815 -0
  58. data/src/sigar_format.c +696 -0
  59. data/src/sigar_getline.c +1849 -0
  60. data/src/sigar_ptql.c +1967 -0
  61. data/src/sigar_signal.c +216 -0
  62. data/src/sigar_util.c +1060 -0
  63. data/src/sigar_version.c.in +22 -0
  64. data/src/sigar_version_autoconf.c.in +22 -0
  65. data/version.properties +11 -0
  66. metadata +131 -0
@@ -0,0 +1,179 @@
1
+ /*
2
+ * Copyright (c) 2004-2006 Hyperic, Inc.
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ #include "sigar.h"
18
+ #include "sigar_private.h"
19
+ #include "sigar_util.h"
20
+ #include <stdio.h>
21
+ /*
22
+ * hash table to cache values where key is a unique number
23
+ * such as:
24
+ * pid -> some process data
25
+ * uid -> user name
26
+ * gid -> group name
27
+ */
28
+
29
+ #define ENTRIES_SIZE(n) \
30
+ (sizeof(sigar_cache_entry_t *) * (n))
31
+
32
+ /* wrap free() for use w/ dmalloc */
33
+ static void free_value(void *ptr)
34
+ {
35
+ free(ptr);
36
+ }
37
+
38
+ sigar_cache_t *sigar_cache_new(int size)
39
+ {
40
+ sigar_cache_t *table = malloc(sizeof(*table));
41
+ table->count = 0;
42
+ table->size = size;
43
+ table->entries = malloc(ENTRIES_SIZE(size));
44
+ memset(table->entries, '\0', ENTRIES_SIZE(size));
45
+ table->free_value = free_value;
46
+ return table;
47
+ }
48
+
49
+ #ifdef DEBUG_CACHE
50
+ /* see how well entries are distributed */
51
+ static void sigar_cache_dump(sigar_cache_t *table)
52
+ {
53
+ int i;
54
+ sigar_cache_entry_t **entries = table->entries;
55
+
56
+ for (i=0; i<table->size; i++) {
57
+ sigar_cache_entry_t *entry = *entries++;
58
+
59
+ printf("|");
60
+ while (entry) {
61
+ printf("%lld", entry->id);
62
+ if (entry->next) {
63
+ printf(",");
64
+ }
65
+ entry = entry->next;
66
+ }
67
+ }
68
+ printf("\n");
69
+ fflush(stdout);
70
+ }
71
+ #endif
72
+
73
+ static void sigar_cache_rehash(sigar_cache_t *table)
74
+ {
75
+ int i;
76
+ unsigned int new_size = table->size * 2 + 1;
77
+ sigar_cache_entry_t **entries = table->entries;
78
+ sigar_cache_entry_t **new_entries =
79
+ malloc(ENTRIES_SIZE(new_size));
80
+
81
+ memset(new_entries, '\0', ENTRIES_SIZE(new_size));
82
+
83
+ for (i=0; i<table->size; i++) {
84
+ sigar_cache_entry_t *entry = *entries++;
85
+
86
+ while (entry) {
87
+ sigar_cache_entry_t *next = entry->next;
88
+ sigar_uint64_t hash = entry->id % new_size;
89
+
90
+ entry->next = new_entries[hash];
91
+ new_entries[hash] = entry;
92
+ entry = next;
93
+ }
94
+ }
95
+
96
+ free(table->entries);
97
+ table->entries = new_entries;
98
+ table->size = new_size;
99
+ }
100
+
101
+ #define SIGAR_CACHE_IX(t, k) \
102
+ t->entries + (k % t->size)
103
+
104
+ sigar_cache_entry_t *sigar_cache_find(sigar_cache_t *table,
105
+ sigar_uint64_t key)
106
+ {
107
+ sigar_cache_entry_t *entry, **ptr;
108
+
109
+ for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
110
+ entry;
111
+ ptr = &entry->next, entry = *ptr)
112
+ {
113
+ if (entry->id == key) {
114
+ return entry;
115
+ }
116
+ }
117
+
118
+ return NULL;
119
+ }
120
+
121
+ /* create entry if it does not exist */
122
+ sigar_cache_entry_t *sigar_cache_get(sigar_cache_t *table,
123
+ sigar_uint64_t key)
124
+ {
125
+ sigar_cache_entry_t *entry, **ptr;
126
+
127
+ for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
128
+ entry;
129
+ ptr = &entry->next, entry = *ptr)
130
+ {
131
+ if (entry->id == key) {
132
+ return entry;
133
+ }
134
+ }
135
+
136
+ if (table->count++ > table->size) {
137
+ sigar_cache_rehash(table);
138
+
139
+ for (ptr = SIGAR_CACHE_IX(table, key), entry = *ptr;
140
+ entry;
141
+ ptr = &entry->next, entry = *ptr)
142
+ {
143
+ }
144
+ }
145
+
146
+ *ptr = entry = malloc(sizeof(*entry));
147
+ entry->id = key;
148
+ entry->value = NULL;
149
+ entry->next = NULL;
150
+
151
+ return entry;
152
+ }
153
+
154
+ void sigar_cache_destroy(sigar_cache_t *table)
155
+ {
156
+ int i;
157
+ sigar_cache_entry_t **entries = table->entries;
158
+
159
+ #ifdef DEBUG_CACHE
160
+ sigar_cache_dump(table);
161
+ #endif
162
+
163
+ for (i=0; i<table->size; i++) {
164
+ sigar_cache_entry_t *entry, *ptr;
165
+ entry = *entries++;
166
+
167
+ while (entry) {
168
+ if (entry->value) {
169
+ table->free_value(entry->value);
170
+ }
171
+ ptr = entry->next;
172
+ free(entry);
173
+ entry = ptr;
174
+ }
175
+ }
176
+
177
+ free(table->entries);
178
+ free(table);
179
+ }
@@ -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
+ }