/* * Copyright 1996-2004 by Hans Reiser, licensing governed by * reiserfsprogs/README */ #ifdef HAVE_CONFIG_H # include #endif #include "misc/malloc.h" #include "misc/misc.h" #include #include #include #include #include #include #include void misc_die (char * fmt, ...) { static char buf[4096]; va_list args; va_start (args, fmt); vsprintf (buf, fmt, args); va_end (args); fprintf (stderr, "\n%s\n", buf); abort (); } __u32 misc_random (void) { srandom (time (0)); return random (); } /* this implements binary search in the array 'base' among 'num' elements each of those is 'width' bytes long. 'comp_func' is used to compare keys */ int misc_bin_search (const void * key, void * base, __u32 num, int width, int * ppos, misc_comp_func_t comp_func) { __u32 rbound, lbound, j; int ret; if (num == 0 || base == NULL) { /* objectid map may be 0 elements long */ *ppos = 0; return 0; } lbound = 0; rbound = num - 1; for (j = (rbound + lbound) / 2; lbound <= rbound; j = (rbound + lbound) / 2) { ret = comp_func ((void *)((char *)base + j * width), key ) ; if (ret < 0) { /* second is greater */ lbound = j + 1; continue; } else if (ret > 0) { /* first is greater */ if (j == 0) break; rbound = j - 1; continue; } else { /* equal */ *ppos = j; return 1; } } *ppos = lbound; return 0; } #define BLOCKLIST__ELEMENT_NUMBER 10 /*element is block number and device*/ int blockdev_list_compare (const void * block1, const void * block2) { if (*(__u32 *)block1 < *(__u32 *)block2) return -1; if (*(__u32 *)block1 > *(__u32 *)block2) return 1; if (*((__u32 *)block1 + 1) < *((__u32 *)block2 + 1)) return -1; if (*((__u32 *)block1 + 1) > *((__u32 *)block2 + 1)) return 1; return 0; } void blocklist__insert_in_position (void *elem, void **base, __u32 *count, int elem_size, int *position) { if (elem_size == 0) return; if (*base == NULL) *base = misc_getmem (BLOCKLIST__ELEMENT_NUMBER * elem_size); if (*count == misc_memsize((void *)*base) / elem_size) *base = misc_expandmem (*base, misc_memsize((void *)*base), BLOCKLIST__ELEMENT_NUMBER * elem_size); if (*position < *count) { memmove (*base + (*position + 1), *base + (*position), (*count - *position) * elem_size); } memcpy (*base + (char) *position * elem_size, elem, elem_size); *count+=1; } int misc_device_rdev_match(char *path, void *data) { dev_t *rdev = (dev_t *)data; struct stat st; /* If stat fails just continue walking. */ if (stat(path, &st)) return 0; /* Only block files are interesting. */ if (!S_ISBLK(st.st_mode)) return 0; /* Matched rdev wanted. */ if (st.st_rdev != *rdev) return 0; /* Stop walking. */ return 1; } /* The method walks through all subtree of the path, open all directories and walk through them recursevely. Return values: positive: stop walking; negative: error occured. */ int misc_dir_walk(char *path, dir_walk_func_t func, void *data) { struct dirent *dirent; struct stat st; off_t pos; DIR *dir; int len; int res; strcat(path, "/"); if (!(dir = opendir(path))) return 0; len = strlen(path); while ((dirent = readdir(dir)) != NULL) { path[len] = 0; if (strcmp(dirent->d_name, ".") == 0 || strcmp(dirent->d_name, "..") == 0) { continue; } strcat(path, dirent->d_name); if ((res = func(path, data))) { closedir(dir); return res; } if (stat(path, &st) != 0) continue; if ((S_ISDIR(st.st_mode))) { pos = telldir(dir); closedir(dir); if ((res = misc_dir_walk(path, func, data))) return res; path[len] = 0; if (!(dir = opendir(path))) return -1; seekdir(dir, pos); } } closedir(dir); return 0; }