📄 misc.c
字号:
/* calculates number of blocks in a file. Returns 0 for "sparse" regular files and files other than regular files and block devices */unsigned long count_blocks (char * filename, int blocksize){ loff_t high, low; unsigned long sz; __u64 size; int fd; if (!S_ISBLK(misc_device_mode(filename)) && !S_ISREG(misc_device_mode(filename))) return 0; fd = open (filename, O_RDONLY); if (fd == -1) { fprintf(stderr, "Failed to open '%s': %s.\n", filename, strerror(errno)); return 0; }#ifdef BLKGETSIZE64 { if (ioctl (fd, BLKGETSIZE64, &size) >= 0) { size = (size / MAX_BS) * MAX_BS / blocksize; sz = size; if ((__u64)sz != size) die ("count_blocks: block device too large"); close(fd); return sz; } }#endif#ifdef BLKGETSIZE { if (ioctl (fd, BLKGETSIZE, &sz) >= 0) { size = sz; close(fd); return (size * 512 / MAX_BS) * MAX_BS / blocksize; } }#endif low = 0; for( high = 1; valid_offset (fd, high); high *= 2 ) low = high; while (low < high - 1) { const loff_t mid = ( low + high ) / 2; if (valid_offset (fd, mid)) low = mid; else high = mid; } valid_offset (fd, 0); close (fd); return (low + 1) * MAX_BS / MAX_BS / blocksize;}/* there are masks for certain bits */__u16 mask16 (int from, int count){ __u16 mask; mask = (0xffff >> from); mask <<= from; mask <<= (16 - from - count); mask >>= (16 - from - count); return mask;}__u32 mask32 (int from, int count){ __u32 mask; mask = (0xffffffff >> from); mask <<= from; mask <<= (32 - from - count); mask >>= (32 - from - count); return mask;}__u64 mask64 (int from, int count){ __u64 mask; mask = (0xffffffffffffffffLL >> from); mask <<= from; mask <<= (64 - from - count); mask >>= (64 - from - count); return mask;}__u32 get_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 reiserfs_bin_search (void * key, void * base, __u32 num, int width, __u32 * ppos, comparison_fn_t comp_func){ __u32 rbound, lbound, j; int ret; if (num == 0 || base == NULL) { /* objectid map may be 0 elements long */ *ppos = 0; return POSITION_NOT_FOUND; } 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 POSITION_FOUND; } } *ppos = lbound; return POSITION_NOT_FOUND;}#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, __u32 *position) { if (elem_size == 0) return; if (*base == NULL) *base = getmem (BLOCKLIST__ELEMENT_NUMBER * elem_size); if (*count == get_mem_size((void *)*base) / elem_size) *base = expandmem (*base, get_mem_size((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;}/* 0 - dma is not supported, scsi or regular file *//* 1 - xt drive *//* 2 - ide drive */static void get_dma_support(dma_info_t *dma_info){ if (S_ISREG(dma_info->st.st_mode)) dma_info->st.st_rdev = dma_info->st.st_dev; if (IDE_DISK_MAJOR(major(dma_info->st.st_rdev))) { dma_info->support_type = 2; return; } #ifdef XT_DISK_MAJOR if (major(dma_info->st.st_rdev) == XT_DISK_MAJOR) { dma_info->support_type = 1; return; }#endif dma_info->support_type = 0;}/* * Return values: * 0 - ok; * 1 - preparation cannot be done * -1 - preparation failed */int prepare_dma_check(dma_info_t *dma_info) { DIR *dir; struct dirent *dirent; struct stat st; dev_t rdev; int rem; char buf[256];#ifndef HDIO_GET_DMA return -1;#endif if (fstat(dma_info->fd, &dma_info->st)) die("stat on device failed\n"); get_dma_support(dma_info); /* dma should be supported */ if (dma_info->support_type == 0) return 1; if (dma_info->support_type == 2) { rdev = dma_info->st.st_rdev; if ((rem = (minor(rdev) % 64)) != 0) { rdev -= rem; if(!(dir = opendir("/dev/"))) { dma_info->support_type = 1; return 0; } while ((dirent = readdir(dir)) != NULL) { if (strncmp(dirent->d_name, ".", 1) == 0 || strncmp(dirent->d_name, "..", 2) == 0) continue; memset(buf, 0, 256); strncat(buf, "/dev/", 5); strncat(buf, dirent->d_name, strlen(dirent->d_name)); if (stat(buf, &st)) break; if (S_ISBLK(st.st_mode) && st.st_rdev == rdev) { dma_info->st = st; dma_info->fd = open(buf, O_RDONLY#if defined(O_LARGEFILE) | O_LARGEFILE#endif ); closedir(dir); return 0; } } closedir(dir); dma_info->support_type = 1; return 1; } } return 0;}static int is_dma_on (int fd) {#ifdef HDIO_GET_DMA static long parm; if (ioctl(fd, HDIO_GET_DMA, &parm)) return -1; else return parm;#endif return 0;}static __u64 dma_speed(int fd, int support_type) { static struct hd_driveid id; __u64 speed = 0; if (support_type != 2) return 0;#ifdef HDIO_OBSOLETE_IDENTITY if (!ioctl(fd, HDIO_GET_IDENTITY, &id) || !ioctl(fd, HDIO_OBSOLETE_IDENTITY)) {#else if (!ioctl(fd, HDIO_GET_IDENTITY, &id)) {#endif speed |= (__u64)id.dma_1word & ~(__u64)0xff; speed |= ((__u64)id.dma_mword & ~(__u64)0xff) << 16; speed |= ((__u64)id.dma_ultra & ~(__u64)0xff) << 32; } else if (errno == -ENOMSG) return -1; else return -1; return speed;}int get_dma_info(dma_info_t *dma_info) { if ((dma_info->dma = is_dma_on(dma_info->fd)) == -1) return -1; if ((dma_info->speed = dma_speed(dma_info->fd, dma_info->support_type)) == (__u64)-1) return -1; return 0;}void clean_after_dma_check(int fd, dma_info_t *dma_info) { signal(SIGALRM, SIG_IGN); if (dma_info->fd && fd != dma_info->fd) close(dma_info->fd);}/* Only le bitops operations are used. */inline int misc_set_bit (unsigned long long nr, void * addr) { __u8 * p, mask; int retval; p = (__u8 *)addr; p += nr >> 3; mask = 1 << (nr & 0x7); /*cli();*/ retval = (mask & *p) != 0; *p |= mask; /*sti();*/ return retval;}inline int misc_clear_bit (unsigned long long nr, void * addr) { __u8 * p, mask; int retval; p = (__u8 *)addr; p += nr >> 3; mask = 1 << (nr & 0x7); /*cli();*/ retval = (mask & *p) != 0; *p &= ~mask; /*sti();*/ return retval;}inline int misc_test_bit(unsigned long long nr, const void * addr) { __u8 * p, mask; p = (__u8 *)addr; p += nr >> 3; mask = 1 << (nr & 0x7); return ((mask & *p) != 0);}inline unsigned long long misc_find_first_zero_bit (const void *vaddr, unsigned long long size) { const __u8 *p = vaddr, *addr = vaddr; unsigned long long res; if (!size) return 0; size = (size >> 3) + ((size & 0x7) > 0); while (*p++ == 255) { if (--size == 0) return (unsigned long long)(p - addr) << 3; } --p; for (res = 0; res < 8; res++) if (!misc_test_bit (res, p)) break; return res + (p - addr) * 8;}inline unsigned long long misc_find_next_zero_bit (const void *vaddr, unsigned long long size, unsigned long long offset) { const __u8 *addr = vaddr; const __u8 *p = addr + (offset >> 3); int bit = offset & 7; unsigned long long res; if (offset >= size) return size; if (bit) { /* Look for zero in first char */ for (res = bit; res < 8; res++) if (!misc_test_bit (res, p)) return res + (p - addr) * 8; p++; } /* No zero yet, search remaining full bytes for a zero */ res = misc_find_first_zero_bit (p, size - 8 * (p - addr)); return res + (p - addr) * 8;}inline unsigned long long misc_find_first_set_bit (const void *vaddr, unsigned long long size) { const __u8 *p = vaddr, *addr = vaddr; unsigned long long res; if (!size) return 0; size = (size >> 3) + ((size & 0x7) > 0); while (*p++ == 0) { if (--size == 0) return (unsigned long long)(p - addr) << 3; } --p; for (res = 0; res < 8; res++) if (misc_test_bit (res, p)) break; return res + (p - addr) * 8;}inline unsigned long long misc_find_next_set_bit(const void *vaddr, unsigned long long size, unsigned long long offset){ const __u8 *addr = vaddr; const __u8 *p = addr + (offset >> 3); int bit = offset & 7; unsigned long long res; if (offset >= size) return size; if (bit) { /* Look for zero in first char */ for (res = bit; res < 8; res++) if (misc_test_bit (res, p)) return res + (p - addr) * 8; p++; } /* No set bit yet, search remaining full bytes for a 1 */ res = misc_find_first_set_bit (p, size - 8 * (p - addr)); return res + (p - addr) * 8;}#include "credits.h"/* Reads the "CREDITS" file and prints one paragraph from it. */void misc_print_credit(FILE *out) { char *line; __u32 num1, num2; fprintf(out, "A pair of credits:\n"); srandom (time (0)); num1 = random() % CREDITS_COUNT; line = credits[num1]; fprintf(out, "%s\n", line); while ((num1 == (num2 = random() % CREDITS_COUNT))) {} line = credits[num2]; fprintf(out, "%s\n", line);}int user_confirmed (FILE * fp, char * q, char * yes) { char * answer = 0; size_t n = 0; fprintf (fp, "%s", q); if (getline (&answer, &n, stdin) != (ssize_t)strlen (yes) || strcmp (yes, answer)) return 0; return 1;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -