ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/tools.c
Revision: 1.60
Committed: Sat Nov 6 19:09:00 2004 UTC (19 years, 6 months ago) by tdb
Content type: text/plain
Branch: MAIN
Changes since 1.59: +13 -12 lines
Log Message:
atoll is only used in one place in libstatgrab, so move it's definition to
before that one use. Given this hasn't caused us problems I'm guessing that
atoll is actually available on Linux and Cygwin, which would make having
the function here void.

If so, it can simply be removed instead.

File Contents

# User Rev Content
1 tdb 1.23 /*
2 tdb 1.43 * i-scream libstatgrab
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.60 * $Id: tools.c,v 1.59 2004/11/06 14:55:53 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 ats 1.9 #ifdef ALLBSD
34 ats 1.8 #include <fcntl.h>
35 tdb 1.29 #endif
36 tdb 1.34 #if (defined(FREEBSD) && !defined(FREEBSD5)) || defined(DFBSD)
37 ats 1.8 #include <kvm.h>
38 tdb 1.35 #include <paths.h>
39 ats 1.8 #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 ats 1.59 #ifdef HPUX
46     #include <sys/param.h>
47     #include <sys/pstat.h>
48     #endif
49 pajs 1.1
50 ats 1.7 #include "tools.h"
51 tdb 1.46 #include "statgrab.h"
52 ats 1.7
53 pajs 1.14 #ifdef SOLARIS
54 pajs 1.27 #ifdef HAVE_LIBDEVINFO_H
55 pajs 1.14 #include <libdevinfo.h>
56 pajs 1.27 #endif
57 pajs 1.14 #include <kstat.h>
58     #include <unistd.h>
59     #include <ctype.h>
60     #include <sys/types.h>
61     #include <sys/dkio.h>
62     #include <sys/stat.h>
63     #include <fcntl.h>
64     #include <sys/fcntl.h>
65     #include <dirent.h>
66     #endif
67    
68 pajs 1.26 #if defined(SOLARIS) && defined(HAVE_LIBDEVINFO_H)
69 pajs 1.14 struct map{
70     char *bsd;
71     char *svr;
72    
73     struct map *next;
74     };
75     typedef struct map mapping_t;
76    
77     static mapping_t *mapping = NULL;
78 pajs 1.26 #endif
79 pajs 1.14
80 pajs 1.26 #ifdef SOLARIS
81 ats 1.41 const char *sg_get_svr_from_bsd(const char *bsd){
82 pajs 1.26 #ifdef HAVE_LIBDEVINFO_H
83 pajs 1.14 mapping_t *map_ptr;
84     for(map_ptr = mapping; map_ptr != NULL; map_ptr = map_ptr->next)
85     if(!strcmp(map_ptr->bsd, bsd)) return map_ptr->svr;
86 pajs 1.26 #endif
87 pajs 1.14 return bsd;
88     }
89 pajs 1.26 #endif
90 pajs 1.14
91 pajs 1.26 #if defined(SOLARIS) && defined(HAVE_LIBDEVINFO_H)
92 ats 1.41 static void add_mapping(char *bsd, char *svr){
93 pajs 1.14 mapping_t *map_ptr;
94     mapping_t *map_end_ptr;
95    
96     if (mapping == NULL){
97 ats 1.48 mapping = sg_malloc(sizeof(mapping_t));
98 pajs 1.14 if (mapping == NULL) return;
99     map_ptr = mapping;
100     }else{
101     /* See if its already been added */
102     for(map_ptr = mapping; map_ptr != NULL; map_ptr = map_ptr->next){
103     if( (!strcmp(map_ptr->bsd, bsd)) || (!strcmp(map_ptr->svr, svr)) ){
104     return;
105     }
106     map_end_ptr = map_ptr;
107     }
108    
109     /* We've reached end of list and not found the entry.. So we need to malloc
110     * new mapping_t
111     */
112 ats 1.48 map_end_ptr->next = sg_malloc(sizeof(mapping_t));
113 pajs 1.14 if (map_end_ptr->next == NULL) return;
114     map_ptr = map_end_ptr->next;
115     }
116    
117     map_ptr->next = NULL;
118 ats 1.47 map_ptr->bsd = NULL;
119     map_ptr->svr = NULL;
120     if (sg_update_string(&map_ptr->bsd, bsd) < 0
121     || sg_update_string(&map_ptr->svr, svr) < 0) {
122     return;
123     }
124 pajs 1.14
125     return;
126     }
127    
128 ats 1.41
129     static char *read_dir(char *disk_path){
130 pajs 1.14 DIR *dirp;
131 tdb 1.15 struct dirent *dp;
132     struct stat stbuf;
133 ats 1.47 char *svr_name = NULL;
134 tdb 1.15 char current_dir[MAXPATHLEN];
135     char file_name[MAXPATHLEN];
136     char temp_name[MAXPATHLEN];
137     char dir_dname[MAXPATHLEN];
138 pajs 1.14 char *dsk_dir;
139     int x;
140    
141     dsk_dir = "/dev/osa/dev/dsk";
142 tdb 1.15 strncpy(current_dir, dsk_dir, sizeof current_dir);
143     if ((dirp = opendir(current_dir)) == NULL){
144 pajs 1.14 dsk_dir = "/dev/dsk";
145     snprintf(current_dir, sizeof current_dir, "%s", dsk_dir);
146     if ((dirp = opendir(current_dir)) == NULL){
147     return NULL;
148     }
149     }
150    
151 tdb 1.15 while ((dp = readdir(dirp)) != NULL){
152 pajs 1.14 snprintf(temp_name, sizeof temp_name, "../..%s", disk_path);
153     snprintf(dir_dname, sizeof dir_dname, "%s/%s", dsk_dir, dp->d_name);
154     stat(dir_dname,&stbuf);
155    
156     if (S_ISBLK(stbuf.st_mode)){
157     x = readlink(dir_dname, file_name, sizeof(file_name));
158     file_name[x] = '\0';
159     if (strcmp(file_name, temp_name) == 0) {
160 ats 1.47 if (sg_update_string(&svr_name,
161 tdb 1.49 dp->d_name) < 0) {
162 ats 1.47 return NULL;
163     }
164 pajs 1.14 closedir(dirp);
165     return svr_name;
166     }
167     }
168     }
169 tdb 1.16 closedir(dirp);
170 pajs 1.14 return NULL;
171     }
172    
173    
174 ats 1.41 static int get_alias(char *alias){
175 pajs 1.14 char file[MAXPATHLEN];
176     di_node_t root_node;
177     di_node_t node;
178     di_minor_t minor = DI_MINOR_NIL;
179     char tmpnode[MAXPATHLEN];
180     char *phys_path;
181     char *minor_name;
182     char *value;
183     int instance;
184     if ((root_node = di_init("/", DINFOCPYALL)) == DI_NODE_NIL) {
185 ats 1.45 return -1;
186 pajs 1.14 }
187     node = di_drv_first_node(alias, root_node);
188     while (node != DI_NODE_NIL) {
189     if ((minor = di_minor_next(node, DI_MINOR_NIL)) != DI_MINOR_NIL) {
190     instance = di_instance(node);
191     phys_path = di_devfs_path(node);
192     minor_name = di_minor_name(minor);
193     strcpy(tmpnode, alias);
194     sprintf(tmpnode, "%s%d", tmpnode, instance);
195 ats 1.41 sg_strlcpy(file, "/devices", sizeof file);
196     sg_strlcat(file, phys_path, sizeof file);
197     sg_strlcat(file, ":", sizeof file);
198     sg_strlcat(file, minor_name, sizeof file);
199 pajs 1.14 value = read_dir(file);
200     if (value != NULL){
201     add_mapping(tmpnode, value);
202     }
203     di_devfs_path_free(phys_path);
204     node = di_drv_next_node(node);
205     }else{
206     node = di_drv_next_node(node);
207     }
208 tdb 1.15 }
209 pajs 1.14 di_fini(root_node);
210 pajs 1.17 return 0;
211 pajs 1.14 }
212    
213 pajs 1.22
214     #define BIG_ENOUGH 512
215 ats 1.41 static int build_mapping(){
216 pajs 1.22 char device_name[BIG_ENOUGH];
217 pajs 1.14 int x;
218 tdb 1.15 kstat_ctl_t *kc;
219     kstat_t *ksp;
220     kstat_io_t kios;
221 pajs 1.14
222 pajs 1.22 char driver_list[BIG_ENOUGH][BIG_ENOUGH];
223     int list_entries = 0;
224     int found;
225    
226 pajs 1.14 if ((kc = kstat_open()) == NULL) {
227 ats 1.45 return -1;
228 tdb 1.15 }
229 pajs 1.14
230 tdb 1.15 for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
231     if (!strcmp(ksp->ks_class, "disk")) {
232     if(ksp->ks_type != KSTAT_TYPE_IO) continue;
233     /* We dont want metadevices appearing as num_diskio */
234     if(strcmp(ksp->ks_module, "md")==0) continue;
235     if((kstat_read(kc, ksp, &kios))==-1) continue;
236 pajs 1.14 strncpy(device_name, ksp->ks_name, sizeof device_name);
237     for(x=0;x<(sizeof device_name);x++){
238     if( isdigit((int)device_name[x]) ) break;
239     }
240     if(x == sizeof device_name) x--;
241     device_name[x] = '\0';
242 pajs 1.22
243     /* Check if we've not already looked it up */
244     found = 0;
245     for(x=0;x<list_entries;x++){
246     if (x>=BIG_ENOUGH){
247     /* We've got bigger than we thought was massive */
248     /* If we hit this.. Make big enough bigger */
249 ats 1.45 return -1;
250 pajs 1.22 }
251     if( !strncmp(driver_list[x], device_name, BIG_ENOUGH)){
252     found = 1;
253     break;
254     }
255     }
256    
257     if(!found){
258     if((get_alias(device_name)) != 0){
259 ats 1.45 return -1;
260 pajs 1.22 }
261     strncpy(driver_list[x], device_name, BIG_ENOUGH);
262     list_entries++;
263 pajs 1.17 }
264 tdb 1.15 }
265 pajs 1.14 }
266 tdb 1.15
267 pajs 1.17 return 0;
268 pajs 1.14 }
269    
270     #endif
271    
272 tdb 1.52 #if defined(LINUX) || defined(CYGWIN)
273 ats 1.41 char *sg_f_read_line(FILE *f, const char *string){
274 pajs 1.1 /* Max line length. 8k should be more than enough */
275     static char line[8192];
276    
277 pajs 1.2 while((fgets(line, sizeof(line), f))!=NULL){
278 pajs 1.1 if(strncmp(string, line, strlen(string))==0){
279     return line;
280     }
281     }
282    
283 tdb 1.51 sg_set_error(SG_ERROR_PARSE, NULL);
284 pajs 1.1 return NULL;
285 pajs 1.3 }
286    
287 ats 1.41 char *sg_get_string_match(char *line, regmatch_t *match){
288 pajs 1.3 int len=match->rm_eo - match->rm_so;
289 ats 1.48 char *match_string=sg_malloc(len+1);
290 pajs 1.3
291     match_string=strncpy(match_string, line+match->rm_so, len);
292     match_string[len]='\0';
293    
294     return match_string;
295     }
296 ats 1.7
297 tdb 1.60 /* FIXME do Linux and Cygwin always have atoll? */
298 ats 1.13 #ifndef HAVE_ATOLL
299     static long long atoll(const char *s) {
300     long long value = 0;
301     int isneg = 0;
302    
303     while (*s == ' ' || *s == '\t') {
304     s++;
305     }
306     if (*s == '-') {
307     isneg = 1;
308     s++;
309     }
310     while (*s >= '0' && *s <= '9') {
311     value = (10 * value) + (*s - '0');
312     s++;
313     }
314     return (isneg ? -value : value);
315 tdb 1.60 }
316     #endif
317    
318     long long sg_get_ll_match(char *line, regmatch_t *match){
319     char *ptr;
320     long long num;
321    
322     ptr=line+match->rm_so;
323     num=atoll(ptr);
324    
325     return num;
326 ats 1.13 }
327     #endif
328    
329 ats 1.21 /* $OpenBSD: strlcpy.c,v 1.8 2003/06/17 21:56:24 millert Exp $ */
330 pajs 1.19
331     /*
332     * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
333     *
334     * Permission to use, copy, modify, and distribute this software for any
335     * purpose with or without fee is hereby granted, provided that the above
336     * copyright notice and this permission notice appear in all copies.
337     *
338     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
339     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
340     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
341     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
342     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
343     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
344     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
345     */
346    
347     /*
348     * Copy src to string dst of size siz. At most siz-1 characters
349     * will be copied. Always NUL terminates (unless siz == 0).
350     * Returns strlen(src); if retval >= siz, truncation occurred.
351     */
352 ats 1.41 size_t sg_strlcpy(char *dst, const char *src, size_t siz){
353 tdb 1.49 register char *d = dst;
354     register const char *s = src;
355     register size_t n = siz;
356    
357     /* Copy as many bytes as will fit */
358     if (n != 0 && --n != 0) {
359     do {
360     if ((*d++ = *s++) == 0)
361     break;
362     } while (--n != 0);
363     }
364    
365     /* Not enough room in dst, add NUL and traverse rest of src */
366     if (n == 0) {
367     if (siz != 0)
368     *d = '\0'; /* NUL-terminate dst */
369     while (*s++)
370     ;
371     }
372 pajs 1.19
373 tdb 1.49 return(s - src - 1); /* count does not include NUL */
374 pajs 1.19 }
375    
376     /* $OpenBSD: strlcat.c,v 1.11 2003/06/17 21:56:24 millert Exp $ */
377    
378     /*
379     * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
380     *
381     * Permission to use, copy, modify, and distribute this software for any
382     * purpose with or without fee is hereby granted, provided that the above
383     * copyright notice and this permission notice appear in all copies.
384     *
385     * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
386     * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
387     * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
388     * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
389     * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
390     * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
391     * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
392     */
393    
394     /*
395     * Appends src to string dst of size siz (unlike strncat, siz is the
396     * full size of dst, not space left). At most siz-1 characters
397     * will be copied. Always NUL terminates (unless siz <= strlen(dst)).
398     * Returns strlen(src) + MIN(siz, strlen(initial dst)).
399     * If retval >= siz, truncation occurred.
400     */
401 ats 1.41 size_t sg_strlcat(char *dst, const char *src, size_t siz){
402 tdb 1.49 register char *d = dst;
403     register const char *s = src;
404     register size_t n = siz;
405     size_t dlen;
406    
407     /* Find the end of dst and adjust bytes left but don't go past end */
408     while (n-- != 0 && *d != '\0')
409     d++;
410     dlen = d - dst;
411     n = siz - dlen;
412    
413     if (n == 0)
414     return(dlen + strlen(s));
415     while (*s != '\0') {
416     if (n != 1) {
417     *d++ = *s;
418     n--;
419     }
420     s++;
421     }
422     *d = '\0';
423 pajs 1.19
424 tdb 1.49 return(dlen + (s - src)); /* count does not include NUL */
425 pajs 1.19 }
426    
427 ats 1.42 int sg_update_string(char **dest, const char *src) {
428 ats 1.37 char *new;
429    
430 ats 1.42 if (src == NULL) {
431     /* We're being told to set it to NULL. */
432     free(*dest);
433     *dest = NULL;
434     return 0;
435     }
436    
437 ats 1.48 new = sg_realloc(*dest, strlen(src) + 1);
438 ats 1.37 if (new == NULL) {
439 ats 1.42 return -1;
440 ats 1.37 }
441    
442     strcpy(new, src);
443     *dest = new;
444 ats 1.42 return 0;
445 ats 1.8 }
446    
447 tdb 1.34 #if (defined(FREEBSD) && !defined(FREEBSD5)) || defined(DFBSD)
448 ats 1.41 kvm_t *sg_get_kvm() {
449 ats 1.8 static kvm_t *kvmd = NULL;
450    
451     if (kvmd != NULL) {
452     return kvmd;
453     }
454    
455     kvmd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, NULL);
456 tdb 1.51 if(kvmd == NULL) {
457     sg_set_error(SG_ERROR_KVM_OPENFILES, NULL);
458     }
459 ats 1.8 return kvmd;
460 pajs 1.1 }
461 tdb 1.34
462     /* Can't think of a better name for this function */
463 ats 1.41 kvm_t *sg_get_kvm2() {
464 tdb 1.34 static kvm_t *kvmd2 = NULL;
465    
466     if (kvmd2 != NULL) {
467     return kvmd2;
468     }
469    
470     kvmd2 = kvm_openfiles(_PATH_DEVNULL, _PATH_DEVNULL, NULL, O_RDONLY, NULL);
471 tdb 1.51 if(kvmd2 == NULL) {
472     sg_set_error(SG_ERROR_KVM_OPENFILES, NULL);
473     }
474 tdb 1.34 return kvmd2;
475     }
476 pajs 1.4 #endif
477 ats 1.9
478 ats 1.28 #if defined(NETBSD) || defined(OPENBSD)
479 ats 1.41 struct uvmexp *sg_get_uvmexp() {
480 ats 1.28 int mib[2];
481 ats 1.44 size_t size = sizeof(struct uvmexp);
482     static struct uvmexp uvm;
483 ats 1.36 struct uvmexp *new;
484 ats 1.9
485 ats 1.28 mib[0] = CTL_VM;
486     mib[1] = VM_UVMEXP;
487    
488 ats 1.44 if (sysctl(mib, 2, &uvm, &size, NULL, 0) < 0) {
489 ats 1.56 sg_set_error_with_errno(SG_ERROR_SYSCTL, "CTL_VM.VM_UVMEXP");
490 ats 1.9 return NULL;
491     }
492    
493 ats 1.44 return &uvm;
494 ats 1.59 }
495     #endif
496    
497     #ifdef HPUX
498     struct pst_static *sg_get_pstat_static() {
499     static int got = 0;
500     static struct pst_static pst;
501    
502     if (!got) {
503     if (pstat_getstatic(&pst, sizeof pst, 1, 0) == -1) {
504     sg_set_error_with_errno(SG_ERROR_PSTAT,
505     "pstat_static");
506     return NULL;
507     }
508     got = 1;
509     }
510     return &pst;
511 ats 1.9 }
512     #endif
513    
514 ats 1.41 int sg_init(){
515 tdb 1.55 sg_set_error(SG_ERROR_NONE, NULL);
516 ats 1.53
517 tdb 1.33 #if (defined(FREEBSD) && !defined(FREEBSD5)) || defined(DFBSD)
518 ats 1.41 if (sg_get_kvm() == NULL) {
519 ats 1.45 return -1;
520 ats 1.41 }
521     if (sg_get_kvm2() == NULL) {
522 ats 1.45 return -1;
523 ats 1.32 }
524 pajs 1.14 #endif
525     #ifdef SOLARIS
526 pajs 1.20 /* On solaris 7, this will fail if you are not root. But, everything
527     * will still work, just no disk mappings. So we will ignore the exit
528     * status of this, and carry on merrily.
529     */
530 pajs 1.26 #ifdef HAVE_LIBDEVINFO_H
531 pajs 1.20 build_mapping();
532 pajs 1.25 #endif
533 pajs 1.10 #endif
534     return 0;
535     }
536 ats 1.18
537 ats 1.41 int sg_drop_privileges() {
538 tdb 1.57 #ifdef HAVE_SETEGID
539 tdb 1.51 if (setegid(getgid()) != 0) {
540 tdb 1.57 #elif defined(HAVE_SETRESGID)
541     if (setresgid(getgid(), getgid(), getgid()) != 0) {
542     #else
543     {
544     #endif
545 ats 1.56 sg_set_error_with_errno(SG_ERROR_SETEGID, NULL);
546 tdb 1.51 return -1;
547     }
548 tdb 1.57 #ifdef HAVE_SETEUID
549 tdb 1.51 if (seteuid(getuid()) != 0) {
550 tdb 1.57 #elif defined(HAVE_SETRESUID)
551     if (setresuid(getuid(), getuid(), getuid()) != 0) {
552     #else
553     {
554     #endif
555 ats 1.56 sg_set_error_with_errno(SG_ERROR_SETEUID, NULL);
556 tdb 1.51 return -1;
557     }
558 ats 1.18 return 0;
559 tdb 1.46 }
560    
561     void *sg_realloc(void *ptr, size_t size) {
562     void *tmp = NULL;
563     tmp = realloc(ptr, size);
564     if(tmp == NULL) {
565 ats 1.56 sg_set_error_with_errno(SG_ERROR_MALLOC, NULL);
566 tdb 1.46 }
567     return tmp;
568 ats 1.18 }