ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/tools.c
Revision: 1.31
Committed: Mon Feb 16 14:55:32 2004 UTC (20 years, 3 months ago) by tdb
Content type: text/plain
Branch: MAIN
CVS Tags: LIBSTATGRAB_0_9
Changes since 1.30: +4 -4 lines
Log Message:
Add support for DragonFly BSD 1.0.
Also a minor tweak to the network interface code to make it more portable.

File Contents

# User Rev Content
1 tdb 1.23 /*
2 tdb 1.5 * i-scream central monitoring system
3 tdb 1.6 * http://www.i-scream.org
4 tdb 1.23 * Copyright (C) 2000-2004 i-scream
5 tdb 1.5 *
6 tdb 1.23 * This library is free software; you can redistribute it and/or
7     * modify it under the terms of the GNU Lesser General Public
8     * License as published by the Free Software Foundation; either
9     * version 2.1 of the License, or (at your option) any later version.
10 tdb 1.5 *
11 tdb 1.23 * This library is distributed in the hope that it will be useful,
12 tdb 1.5 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 tdb 1.23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     * Lesser General Public License for more details.
15 tdb 1.5 *
16 tdb 1.23 * You should have received a copy of the GNU Lesser General Public
17     * License along with this library; if not, write to the Free Software
18     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19     * 02111-1307 USA
20 tdb 1.24 *
21 tdb 1.31 * $Id: tools.c,v 1.30 2004/02/14 13:43:37 ats Exp $
22 tdb 1.5 */
23    
24     #ifdef HAVE_CONFIG_H
25     #include "config.h"
26     #endif
27    
28 pajs 1.1 #include <stdio.h>
29     #include <string.h>
30 pajs 1.3 #include <stdlib.h>
31 ats 1.18 #include <unistd.h>
32 pajs 1.3 #include <sys/types.h>
33     #include <regex.h>
34 ats 1.9 #ifdef ALLBSD
35 ats 1.8 #include <fcntl.h>
36 tdb 1.29 #endif
37 tdb 1.31 #if defined(FREEBSD) || defined(DFBSD)
38 ats 1.8 #include <kvm.h>
39     #endif
40 ats 1.28 #if defined(NETBSD) || defined(OPENBSD)
41 ats 1.9 #include <uvm/uvm_extern.h>
42 ats 1.28 #include <sys/param.h>
43     #include <sys/sysctl.h>
44 ats 1.9 #endif
45 pajs 1.1
46 ats 1.7 #include "tools.h"
47    
48 pajs 1.14 #ifdef SOLARIS
49 pajs 1.27 #ifdef HAVE_LIBDEVINFO_H
50 pajs 1.14 #include <libdevinfo.h>
51 pajs 1.27 #endif
52 pajs 1.14 #include <kstat.h>
53     #include <unistd.h>
54     #include <ctype.h>
55     #include <sys/types.h>
56     #include <sys/dkio.h>
57     #include <sys/stat.h>
58     #include <fcntl.h>
59     #include <sys/fcntl.h>
60     #include <dirent.h>
61     #endif
62    
63 pajs 1.26 #if defined(SOLARIS) && defined(HAVE_LIBDEVINFO_H)
64 pajs 1.14 struct map{
65     char *bsd;
66     char *svr;
67    
68     struct map *next;
69     };
70     typedef struct map mapping_t;
71    
72     static mapping_t *mapping = NULL;
73 pajs 1.26 #endif
74 pajs 1.14
75 pajs 1.26 #ifdef SOLARIS
76 pajs 1.14 char *get_svr_from_bsd(char *bsd){
77 pajs 1.26 #ifdef HAVE_LIBDEVINFO_H
78 pajs 1.14 mapping_t *map_ptr;
79     for(map_ptr = mapping; map_ptr != NULL; map_ptr = map_ptr->next)
80     if(!strcmp(map_ptr->bsd, bsd)) return map_ptr->svr;
81 pajs 1.26 #endif
82 pajs 1.14 return bsd;
83     }
84 pajs 1.26 #endif
85 pajs 1.14
86 pajs 1.26 #if defined(SOLARIS) && defined(HAVE_LIBDEVINFO_H)
87 pajs 1.14 void add_mapping(char *bsd, char *svr){
88     mapping_t *map_ptr;
89     mapping_t *map_end_ptr;
90    
91     bsd = strdup(bsd);
92     svr = strdup(svr);
93    
94     if (mapping == NULL){
95     mapping = malloc(sizeof(mapping_t));
96     if (mapping == NULL) return;
97     map_ptr = mapping;
98     }else{
99     /* See if its already been added */
100     for(map_ptr = mapping; map_ptr != NULL; map_ptr = map_ptr->next){
101     if( (!strcmp(map_ptr->bsd, bsd)) || (!strcmp(map_ptr->svr, svr)) ){
102     return;
103     }
104     map_end_ptr = map_ptr;
105     }
106    
107     /* We've reached end of list and not found the entry.. So we need to malloc
108     * new mapping_t
109     */
110     map_end_ptr->next = malloc(sizeof(mapping_t));
111     if (map_end_ptr->next == NULL) return;
112     map_ptr = map_end_ptr->next;
113     }
114    
115     map_ptr->next = NULL;
116     map_ptr->bsd = bsd;
117     map_ptr->svr = svr;
118    
119     return;
120     }
121    
122     char *read_dir(char *disk_path){
123     DIR *dirp;
124 tdb 1.15 struct dirent *dp;
125     struct stat stbuf;
126 pajs 1.14 char *svr_name;
127 tdb 1.15 char current_dir[MAXPATHLEN];
128     char file_name[MAXPATHLEN];
129     char temp_name[MAXPATHLEN];
130     char dir_dname[MAXPATHLEN];
131 pajs 1.14 char *dsk_dir;
132     int x;
133    
134     dsk_dir = "/dev/osa/dev/dsk";
135 tdb 1.15 strncpy(current_dir, dsk_dir, sizeof current_dir);
136     if ((dirp = opendir(current_dir)) == NULL){
137 pajs 1.14 dsk_dir = "/dev/dsk";
138     snprintf(current_dir, sizeof current_dir, "%s", dsk_dir);
139     if ((dirp = opendir(current_dir)) == NULL){
140     return NULL;
141     }
142     }
143    
144 tdb 1.15 while ((dp = readdir(dirp)) != NULL){
145 pajs 1.14 snprintf(temp_name, sizeof temp_name, "../..%s", disk_path);
146     snprintf(dir_dname, sizeof dir_dname, "%s/%s", dsk_dir, dp->d_name);
147     stat(dir_dname,&stbuf);
148    
149     if (S_ISBLK(stbuf.st_mode)){
150     x = readlink(dir_dname, file_name, sizeof(file_name));
151     file_name[x] = '\0';
152     if (strcmp(file_name, temp_name) == 0) {
153     svr_name = strdup(dp->d_name);
154     closedir(dirp);
155     return svr_name;
156     }
157     }
158     }
159 tdb 1.16 closedir(dirp);
160 pajs 1.14 return NULL;
161     }
162    
163    
164    
165     int get_alias(char *alias){
166     char file[MAXPATHLEN];
167     di_node_t root_node;
168     di_node_t node;
169     di_minor_t minor = DI_MINOR_NIL;
170     char tmpnode[MAXPATHLEN];
171     char *phys_path;
172     char *minor_name;
173     char *value;
174     int instance;
175     if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
176 pajs 1.17 return 1;
177 pajs 1.14 }
178     node = di_drv_first_node(alias, root_node);
179     while (node != DI_NODE_NIL) {
180     if ((minor = di_minor_next(node, DI_MINOR_NIL)) != DI_MINOR_NIL) {
181     instance = di_instance(node);
182     phys_path = di_devfs_path(node);
183     minor_name = di_minor_name(minor);
184     strcpy(tmpnode, alias);
185     sprintf(tmpnode, "%s%d", tmpnode, instance);
186 pajs 1.17 strlcpy(file, "/devices", sizeof file);
187     strlcat(file, phys_path, sizeof file);
188     strlcat(file, ":", sizeof file);
189     strlcat(file, minor_name, sizeof file);
190 pajs 1.14 value = read_dir(file);
191     if (value != NULL){
192     add_mapping(tmpnode, value);
193     }
194     di_devfs_path_free(phys_path);
195     node = di_drv_next_node(node);
196     }else{
197     node = di_drv_next_node(node);
198     }
199 tdb 1.15 }
200 pajs 1.14 di_fini(root_node);
201 pajs 1.17 return 0;
202 pajs 1.14 }
203    
204 pajs 1.22
205     #define BIG_ENOUGH 512
206 pajs 1.17 int build_mapping(){
207 pajs 1.22 char device_name[BIG_ENOUGH];
208 pajs 1.14 int x;
209 tdb 1.15 kstat_ctl_t *kc;
210     kstat_t *ksp;
211     kstat_io_t kios;
212 pajs 1.14
213 pajs 1.22 char driver_list[BIG_ENOUGH][BIG_ENOUGH];
214     int list_entries = 0;
215     int found;
216    
217 pajs 1.14 if ((kc = kstat_open()) == NULL) {
218 tdb 1.16 return;
219 tdb 1.15 }
220 pajs 1.14
221 tdb 1.15 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
222     if (!strcmp(ksp->ks_class, "disk")) {
223     if(ksp->ks_type != KSTAT_TYPE_IO) continue;
224     /* We dont want metadevices appearing as num_diskio */
225     if(strcmp(ksp->ks_module, "md")==0) continue;
226     if((kstat_read(kc, ksp, &kios))==-1) continue;
227 pajs 1.14 strncpy(device_name, ksp->ks_name, sizeof device_name);
228     for(x=0;x<(sizeof device_name);x++){
229     if( isdigit((int)device_name[x]) ) break;
230     }
231     if(x == sizeof device_name) x--;
232     device_name[x] = '\0';
233 pajs 1.22
234     /* Check if we've not already looked it up */
235     found = 0;
236     for(x=0;x<list_entries;x++){
237     if (x>=BIG_ENOUGH){
238     /* We've got bigger than we thought was massive */
239     /* If we hit this.. Make big enough bigger */
240     return 1;
241     }
242     if( !strncmp(driver_list[x], device_name, BIG_ENOUGH)){
243     found = 1;
244     break;
245     }
246     }
247    
248     if(!found){
249     if((get_alias(device_name)) != 0){
250     return 1;
251     }
252     strncpy(driver_list[x], device_name, BIG_ENOUGH);
253     list_entries++;
254 pajs 1.17 }
255 tdb 1.15 }
256 pajs 1.14 }
257 tdb 1.15
258 pajs 1.17 return 0;
259 pajs 1.14 }
260    
261     #endif
262    
263    
264    
265 pajs 1.1 char *f_read_line(FILE *f, const char *string){
266     /* Max line length. 8k should be more than enough */
267     static char line[8192];
268    
269 pajs 1.2 while((fgets(line, sizeof(line), f))!=NULL){
270 pajs 1.1 if(strncmp(string, line, strlen(string))==0){
271     return line;
272     }
273     }
274    
275     return NULL;
276 pajs 1.3 }
277    
278     char *get_string_match(char *line, regmatch_t *match){
279     int len=match->rm_eo - match->rm_so;
280     char *match_string=malloc(len+1);
281    
282     match_string=strncpy(match_string, line+match->rm_so, len);
283     match_string[len]='\0';
284    
285     return match_string;
286     }
287 ats 1.7
288 pajs 1.14
289    
290 ats 1.13 #ifndef HAVE_ATOLL
291     static long long atoll(const char *s) {
292     long long value = 0;
293     int isneg = 0;
294    
295     while (*s == ' ' || *s == '\t') {
296     s++;
297     }
298     if (*s == '-') {
299     isneg = 1;
300     s++;
301     }
302     while (*s >= '0' && *s <= '9') {
303     value = (10 * value) + (*s - '0');
304     s++;
305     }
306     return (isneg ? -value : value);
307     }
308     #endif
309    
310 pajs 1.19 #ifndef HAVE_STRLCPY
311 ats 1.21 /* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */
312 pajs 1.19
313     /*
314     * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
315     *
316     * Permission to use, copy, modify, and distribute this software for any
317     * purpose with or without fee is hereby granted, provided that the above
318     * copyright notice and this permission notice appear in all copies.
319     *
320     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
321     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
322     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
323     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
324     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
325     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
326     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
327     */
328    
329     /*
330     * Copy src to string dst of size siz. At most siz-1 characters
331     * will be copied. Always NUL terminates (unless siz == 0).
332     * Returns strlen(src); if retval >= siz, truncation occurred.
333     */
334     size_t strlcpy(char *dst, const char *src, size_t siz){
335     register char *d = dst;
336     register const char *s = src;
337     register size_t n = siz;
338    
339     /* Copy as many bytes as will fit */
340     if (n != 0 && --n != 0) {
341     do {
342     if ((*d++ = *s++) == 0)
343     break;
344     } while (--n != 0);
345     }
346    
347     /* Not enough room in dst, add NUL and traverse rest of src */
348     if (n == 0) {
349     if (siz != 0)
350     *d = '\0'; /* NUL-terminate dst */
351     while (*s++)
352     ;
353     }
354    
355     return(s - src - 1); /* count does not include NUL */
356     }
357     #endif
358    
359     #ifndef HAVE_STRLCAT
360     /* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */
361    
362     /*
363     * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
364     *
365     * Permission to use, copy, modify, and distribute this software for any
366     * purpose with or without fee is hereby granted, provided that the above
367     * copyright notice and this permission notice appear in all copies.
368     *
369     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
370     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
371     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
372     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
373     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
374     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
375     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
376     */
377    
378     /*
379     * Appends src to string dst of size siz (unlike strncat, siz is the
380     * full size of dst, not space left). At most siz-1 characters
381     * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
382     * Returns strlen(src) + MIN(siz, strlen(initial dst)).
383     * If retval >= siz, truncation occurred.
384     */
385     size_t strlcat(char *dst, const char *src, size_t siz){
386     register char *d = dst;
387     register const char *s = src;
388     register size_t n = siz;
389     size_t dlen;
390    
391     /* Find the end of dst and adjust bytes left but don't go past end */
392     while (n-- != 0 && *d != '\0')
393     d++;
394     dlen = d - dst;
395     n = siz - dlen;
396    
397     if (n == 0)
398     return(dlen + strlen(s));
399     while (*s != '\0') {
400     if (n != 1) {
401     *d++ = *s;
402     n--;
403     }
404     s++;
405     }
406     *d = '\0';
407    
408     return(dlen + (s - src)); /* count does not include NUL */
409     }
410    
411     #endif
412    
413 pajs 1.3 long long get_ll_match(char *line, regmatch_t *match){
414     char *ptr;
415     long long num;
416    
417     ptr=line+match->rm_so;
418     num=atoll(ptr);
419    
420     return num;
421 ats 1.8 }
422    
423 tdb 1.31 #if defined(FREEBSD) || defined(DFBSD)
424 ats 1.8 kvm_t *get_kvm() {
425     static kvm_t *kvmd = NULL;
426    
427     if (kvmd != NULL) {
428     return kvmd;
429     }
430    
431     kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL);
432     return kvmd;
433 pajs 1.1 }
434 pajs 1.4 #endif
435 ats 1.9
436 ats 1.28 #if defined(NETBSD) || defined(OPENBSD)
437 ats 1.9 struct uvmexp *get_uvmexp() {
438 ats 1.28 int mib[2];
439     size_t size;
440     static struct uvmexp *uvm = NULL;
441 ats 1.9
442 ats 1.28 mib[0] = CTL_VM;
443     mib[1] = VM_UVMEXP;
444    
445     if (sysctl(mib, 2, NULL, &size, NULL, 0) < 0) {
446 ats 1.9 return NULL;
447     }
448    
449 ats 1.28 uvm = realloc(uvm, size);
450     if (uvm == NULL) {
451     return NULL;
452 ats 1.9 }
453    
454 ats 1.28 if (sysctl(mib, 2, uvm, &size, NULL, 0) < 0) {
455 ats 1.9 return NULL;
456     }
457 ats 1.28
458     return uvm;
459 ats 1.9 }
460     #endif
461    
462 pajs 1.10 int statgrab_init(){
463 tdb 1.31 #if defined(FREEBSD) || defined(DFBSD)
464 pajs 1.11 {
465     kvm_t *kvmd = get_kvm();
466 tdb 1.15 if (kvmd == NULL) return 1;
467 pajs 1.11 }
468 pajs 1.14 #endif
469     #ifdef SOLARIS
470 pajs 1.20 /* On solaris 7, this will fail if you are not root. But, everything
471     * will still work, just no disk mappings. So we will ignore the exit
472     * status of this, and carry on merrily.
473     */
474 pajs 1.26 #ifdef HAVE_LIBDEVINFO_H
475 pajs 1.20 build_mapping();
476 pajs 1.25 #endif
477 pajs 1.10 #endif
478     return 0;
479     }
480 ats 1.18
481     int statgrab_drop_privileges() {
482     if (setegid(getgid()) != 0) return -1;
483     if (seteuid(getuid()) != 0) return -1;
484     return 0;
485     }
486