ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/i-scream/projects/libstatgrab/src/libstatgrab/tools.c
Revision: 1.25
Committed: Tue Feb 10 16:07:43 2004 UTC (20 years, 3 months ago) by pajs
Content type: text/plain
Branch: MAIN
Changes since 1.24: +4 -2 lines
Log Message:
Solaris 6 doesn't have libdevinfo. So, as a way to get it to compile, we will
not do the drive mappings sol 6 and lower.

File Contents

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