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