⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 misc.c

📁 reiserfsprogs-3.6.19.tar.gz 源码 给有需要的人!
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 1996-2004 by Hans Reiser, licensing governed by  * reiserfsprogs/README */#define _GNU_SOURCE#include "misc.h"#include <stdio.h>#include <stdarg.h>#include <string.h>#include <errno.h>#include <mntent.h>#include <sys/vfs.h>#include <time.h>#include <utime.h>#include <ctype.h>#include <linux/hdreg.h>#include <dirent.h>#include <assert.h>#include <sys/ioctl.h>#include <signal.h>/* Debian modifications by Ed Boraas <ed@debian.org> */#include <sys/mount.h>/* End Debian mods */#define STAT_FIELD(Field, Type)						\inline Type misc_device_##Field(char *device) {				\	struct stat st;							\									\	if (stat(device, &st) == 0)					\		return st.st_##Field;					\									\	fprintf(stderr, "Stat of the device '%s' failed.", device);	\	exit(8);							\}STAT_FIELD(mode, mode_t);STAT_FIELD(rdev, dev_t);STAT_FIELD(size, off_t);STAT_FIELD(blocks, blkcnt_t);void die (char * fmt, ...){    static char buf[1024];    va_list args;    va_start (args, fmt);    vsprintf (buf, fmt, args);    va_end (args);    fprintf (stderr, "\n%s\n", buf);    abort ();}#define MEM_BEGIN "_mem_begin_"#define MEM_END "mem_end"#define MEM_FREED "__free_"#define CONTROL_SIZE (strlen (MEM_BEGIN) + 1 + sizeof (int) + strlen (MEM_END) + 1)unsigned int get_mem_size(char *p) {    char *begin;        begin = p - strlen (MEM_BEGIN) - 1 - sizeof(int);    return *(int *)(begin + strlen (MEM_BEGIN) + 1);}void checkmem (char * p, int size){    char * begin;    char * end;      begin = p - strlen (MEM_BEGIN) - 1 - sizeof (int);    if (strcmp (begin, MEM_BEGIN))	die ("checkmem: memory corrupted - invalid head sign");    if (*(int *)(begin + strlen (MEM_BEGIN) + 1) != size)	die ("checkmem: memory corrupted - invalid size");    end = begin + size + CONTROL_SIZE - strlen (MEM_END) - 1;    if (strcmp (end, MEM_END))	die ("checkmem: memory corrupted - invalid end sign");}void *getmem (int size){    char * mem;    if ((mem = mem_alloc(size)) == NULL)	die ("getmem: no more memory (%d)", size);        memset (mem, 0, size);//    checkmem (mem, size);    return mem;}void *mem_alloc(int size) {    char * p;    char * mem;    p = (char *)malloc (CONTROL_SIZE + size);    if (!p)	die ("getmem: no more memory (%d)", size);    /* Write the MEM_BEGIN magic in the beginning of allocated memory. */    strcpy (p, MEM_BEGIN);    p += strlen (MEM_BEGIN) + 1;    /* Write the size after the magic. */    *(int *)p = size;    p += sizeof (int);    mem = p;    p += size;    strcpy (p, MEM_END);    return mem;}void * expandmem (void * vp, int size, int by){    int allocated;    char * mem, * p = vp;    int expand_by = by;    if (p) {	checkmem (p, size);	allocated = CONTROL_SIZE + size;	p -= (strlen (MEM_BEGIN) + 1 + sizeof (int));    } else {	allocated = 0;	/* add control bytes to the new allocated area */	expand_by += CONTROL_SIZE;    }    p = realloc (p, allocated + expand_by);    if (!p)	die ("expandmem: no more memory (%d)", size);    if (!vp) {	strcpy (p, MEM_BEGIN);    }    mem = p + strlen (MEM_BEGIN) + 1 + sizeof (int);    *(int *)(p + strlen (MEM_BEGIN) + 1) = size + by;    /* fill new allocated area by 0s */    if(by > 0)        memset (mem + size, 0, by);    strcpy (mem + size + by, MEM_END);//    checkmem (mem, size + by);    return mem;}void freemem (void * vp){    char * p = vp;    int size;      if (!p)	return;    size = get_mem_size (vp);    checkmem (p, size);    p -= (strlen (MEM_BEGIN) + 1 + sizeof (int));    strcpy (p, MEM_FREED);    strcpy (p + size + CONTROL_SIZE - strlen (MEM_END) - 1, MEM_FREED);    free (p);}typedef int (*func_t) (char *);/* Lookup the @file in the @mntfile. @file is mntent.mnt_fsname if @fsname    is set; mntent.mnt_dir otherwise. Return the mnt entry from the @mntfile.      Warning: if the root fs is mounted RO, the content of /etc/mtab may be    not correct. */static struct mntent *misc_mntent_lookup(char *mntfile, 					 char *file, 					 int path) {	struct mntent *mnt;	int name_match = 0;	struct stat st;	dev_t rdev = 0;	dev_t dev = 0;	ino_t ino = 0;	char *name;	FILE *fp;		assert(mntfile != NULL);	assert(file != NULL);	if (stat(file, &st) == 0) {		/* Devices is stated. */		if (S_ISBLK(st.st_mode)) {			rdev = st.st_rdev;		} else {			dev = st.st_dev;			ino = st.st_ino;		}	}	if ((fp = setmntent(mntfile, "r")) == NULL)		return INVAL_PTR;	while ((mnt = getmntent(fp)) != NULL) {		/* Check if names match. */		name = path ? mnt->mnt_dir : mnt->mnt_fsname;				if (strcmp(file, name) == 0)			name_match = 1;		if (stat(name, &st))			continue;				/* If names do not match, check if stats match. */		if (!name_match) {			if (rdev && S_ISBLK(st.st_mode)) {				if (rdev != st.st_rdev)					continue;			} else if (dev && !S_ISBLK(st.st_mode)) {				if (dev != st.st_dev ||				    ino != st.st_ino)					continue;			} else {				continue;			}		}		/* If not path and not block device do not check anything more. */		if (!path && !rdev) 			break;		if (path) {			/* Either names or stats match. Make sure the st_dev of 			   the path is same as @mnt_fsname device rdev. */			if (stat(mnt->mnt_fsname, &st) == 0 && 			    dev == st.st_rdev)				break;		} else {			/* Either names or stats match. Make sure the st_dev of 			   the mount entry is same as the given device rdev. */			if (stat(mnt->mnt_dir, &st) == 0 && 			    rdev == st.st_dev)				break;		}	}	endmntent (fp);        return mnt;}static int misc_root_mounted(char *device) {	struct stat rootst, devst;		assert(device != NULL);	if (stat("/", &rootst) != 0) 		return -1;	if (stat(device, &devst) != 0)		return -1;	if (!S_ISBLK(devst.st_mode) || 	    devst.st_rdev != rootst.st_dev)		return 0;	return 1;}static int misc_file_ro(char *file) {	if (utime(file, 0) == -1) {		if (errno == EROFS)			return 1;	}	return 0;}struct mntent *misc_mntent(char *device) {	int proc = 0, path = 0, root = 0;		struct mntent *mnt;	struct statfs stfs;	assert(device != NULL);		/* Check if the root. */	if (misc_root_mounted(device) == 1)		root = 1;	#ifdef __linux__	/* Check if /proc is procfs. */	if (statfs("/proc", &stfs) == 0 && stfs.f_type == 0x9fa0) {		proc = 1;				if (root) {			/* Lookup the "/" entry in /proc/mounts. Special 			   case as root entry can present as:				rootfs / rootfs rw 0 0			   Look up the mount point in this case. */			mnt = misc_mntent_lookup("/proc/mounts", "/", 1);		} else {			/* Lookup the @device /proc/mounts */			mnt = misc_mntent_lookup("/proc/mounts", device, 0);		}				if (mnt == INVAL_PTR) 			proc = 0;		else if (mnt)			return mnt;	}#endif /* __linux__ */#if defined(MOUNTED) || defined(_PATH_MOUNTED)#ifndef MOUNTED    #define MOUNTED _PATH_MOUNTED#endif	/* Check in MOUNTED (/etc/mtab) if RW. */	if (!misc_file_ro(MOUNTED)) {		path = 1;		if (root) {			mnt = misc_mntent_lookup(MOUNTED, "/", 1);		} else {			mnt = misc_mntent_lookup(MOUNTED, device, 0);		}		if (mnt == INVAL_PTR) 			path = 0;		else if (mnt)			return mnt;	}#endif /* defined(MOUNTED) || defined(_PATH_MOUNTED) */		/* If has not been checked in neither /proc/mounts nor /etc/mtab (or 	   errors have occured), return INVAL_PTR, NULL otherwise. */	return (!proc && !path) ? INVAL_PTR : NULL;}int misc_device_mounted(char *device) {	struct mntent *mnt;		/* Check for the "/" first to avoid any possible problem with 	   reflecting the root fs info in mtab files. */	if (misc_root_mounted(device) == 1) {		return misc_file_ro("/") ? MF_RO : MF_RW;	}		/* Lookup the mount entry. */	if ((mnt = misc_mntent(device)) == NULL) {		return MF_NOT_MOUNTED;	} else if (mnt == INVAL_PTR) {		return 0;	}	return hasmntopt(mnt, MNTOPT_RO) ? MF_RO : MF_RW;}char buf1 [100];char buf2 [100];void print_how_fast (unsigned long passed, unsigned long total,		     int cursor_pos, int reset_time){    static time_t t0 = 0, t1 = 0, t2 = 0;    int speed;    int indent;    if (reset_time)	time (&t0);    time (&t1);    if (t1 != t0) {	speed = passed / (t1 - t0);	if (total - passed) {	    if (t1 - t2 < 1)	        return;	    t2 = t1;	}	    } else	speed = 0;    /* what has to be written */    if (total)      sprintf (buf1, "left %lu, %d /sec", total - passed, speed);    else {	/*(*passed) ++;*/	sprintf (buf1, "done %lu, %d /sec", passed, speed);    }        /* make indent */    indent = 79 - cursor_pos - strlen (buf1);    memset (buf2, ' ', indent);    buf2[indent] = 0;    fprintf (stderr, "%s%s", buf2, buf1);    memset (buf2, '\b', indent + strlen (buf1));    buf2 [indent + strlen (buf1)] = 0;    fprintf (stderr, "%s", buf2);    fflush (stderr);}static char * strs[] ={"0%",".",".",".",".","20%",".",".",".",".","40%",".",".",".",".","60%",".",".",".",".","80%",".",".",".",".","100%"};static char progress_to_be[1024];static char current_progress[1024];static void str_to_be (char * buf, int prosents){    int i;    prosents -= prosents % 4;    buf[0] = 0;    for (i = 0; i <= prosents / 4; i ++)	strcat (buf, strs[i]);}void print_how_far (FILE * fp,		    unsigned long * passed, unsigned long total,		    unsigned int inc, int quiet){    int percent;    if (*passed == 0)	current_progress[0] = 0;    (*passed) += inc;    if (*passed > total) {/*	fprintf (fp, "\nprint_how_far: total %lu has been reached already. cur=%lu\n",	total, *passed);*/	return;    }    percent = ((*passed) * 100) / total;    str_to_be (progress_to_be, percent);    if (strlen (current_progress) != strlen (progress_to_be)) {	fprintf (fp, "%s", progress_to_be + strlen (current_progress));    }    strcat (current_progress, progress_to_be + strlen (current_progress));    if (!quiet) {	print_how_fast(*passed /* - inc*/, total, strlen (progress_to_be),	    (*passed == inc) ? 1 : 0);    }    fflush (fp);}#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)/* Note! Despite this call being called with *64, it must be encoded to * return only sizeof(size_t), since in earlier kernel versions it was * declared _IOR(0x12, 114, sizeof(u64)), making it use sizeof(sizeof(u64)). * * However, the call itself does always return 64bit! */#   define BLKGETSIZE64 _IOR(0x12, 114, size_t)#endif/* To not have problem with last sectors on the block device when switching    to smaller one. */#define MAX_BS (64 * 1024)int valid_offset( int fd, loff_t offset) {    char ch;    loff_t res;    /*res = reiserfs_llseek (fd, offset, 0);*/    res = lseek (fd, offset, SEEK_SET);    if (res < 0)	return 0;    /* if (read (fd, &ch, 1) < 0) does not wirk on files */    if (read (fd, &ch, 1) < 1)	return 0;    return 1;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -