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

📄 integck.c

📁 mtd-utils 是一套更改linux mtd設備的工具
💻 C
📖 第 1 页 / 共 4 页
字号:
			buf[written] = rand();		/* Write a block of data */		if (remains > BUFFER_SIZE)			block = BUFFER_SIZE;		else			block = remains;		written = write(fd, buf, block);		CHECK(written == block);		remains -= written;	}}static void save_file(int fd, struct file_info *file){	int w_fd;	struct write_info *w;	char buf[BUFFER_SIZE];	char name[256];	/* Open file to save contents to */	strcpy(name, "/tmp/");	strcat(name, file->name);	strcat(name, ".integ.sav.read");	fprintf(stderr, "Saving %s\n", name);	w_fd = open(name, O_CREAT | O_WRONLY, 0777);	CHECK(w_fd != -1);	/* Start at the beginning */	CHECK(lseek(fd, 0, SEEK_SET) != (off_t) -1);	for (;;) {		ssize_t r = read(fd, buf, BUFFER_SIZE);		CHECK(r != -1);		if (!r)			break;		CHECK(write(w_fd, buf, r) == r);	}	CHECK(close(w_fd) != -1);	/* Open file to save contents to */	strcpy(name, "/tmp/");	strcat(name, file->name);	strcat(name, ".integ.sav.written");	fprintf(stderr, "Saving %s\n", name);	w_fd = open(name, O_CREAT | O_WRONLY, 0777);	CHECK(w_fd != -1);	for (w = file->writes; w; w = w->next)		file_rewrite_data(w_fd, w, buf);	CHECK(close(w_fd) != -1);}static void file_check_hole(	struct file_info *file,				int fd, off_t offset,				size_t size){	size_t remains, block, i;	char buf[BUFFER_SIZE];	CHECK(lseek(fd, offset, SEEK_SET) != (off_t) -1);	remains = size;	while (remains) {		if (remains > BUFFER_SIZE)			block = BUFFER_SIZE;		else			block = remains;		CHECK(read(fd, buf, block) == block);		for (i = 0; i < block; ++i) {			if (buf[i] != 0) {				fprintf(stderr, "file_check_hole failed at %u "					"checking hole at %u size %u\n",					(unsigned) (size - remains + i),					(unsigned) offset,					(unsigned) size);				file_info_display(file);				save_file(fd, file);			}			CHECK(buf[i] == 0);		}		remains -= block;	}}static void file_check_data(	struct file_info *file,				int fd,				struct write_info *w){	size_t remains, block, i;	off_t r;	char buf[BUFFER_SIZE];	srand(w->random_seed);	for (r = 0; r < w->random_offset; ++r)		rand();	CHECK(lseek(fd, w->offset, SEEK_SET) != (off_t) -1);	remains = w->size;	while (remains) {		if (remains > BUFFER_SIZE)			block = BUFFER_SIZE;		else			block = remains;		CHECK(read(fd, buf, block) == block);		for (i = 0; i < block; ++i) {			char c = (char) rand();			if (buf[i] != c) {				fprintf(stderr, "file_check_data failed at %u "					"checking data at %u size %u\n",					(unsigned) (w->size - remains + i),					(unsigned) w->offset,					(unsigned) w->size);				file_info_display(file);				save_file(fd, file);			}			CHECK(buf[i] == c);		}		remains -= block;	}}static void file_check(struct file_info *file, int fd){	int open_and_close = 0, link_count = 0;	char *path = NULL;	off_t pos;	struct write_info *w;	struct dir_entry_info *entry;	struct stat st;	/* Do not check files that have errored */	if (!check_nospc_files && file->no_space_error)		return;	/* Do not check the same file twice */	if (file->check_run_no == check_run_no)		return;	file->check_run_no = check_run_no;	if (fd == -1)		open_and_close = 1;	if (open_and_close) {		/* Open file */		path = dir_path(file->links->parent, file->links->name);		fd = open(path, O_RDONLY);		CHECK(fd != -1);	}	/* Check length */	pos = lseek(fd, 0, SEEK_END);	if (pos != file->length) {		fprintf(stderr, "file_check failed checking length "			"expected %u actual %u\n",			(unsigned) file->length,			(unsigned) pos);		file_info_display(file);		save_file(fd, file);	}	CHECK(pos == file->length);	/* Check each write */	pos = 0;	for (w = file->writes; w; w = w->next) {		if (w->offset > pos)			file_check_hole(file, fd, pos, w->offset - pos);		file_check_data(file, fd, w);		pos = w->offset + w->size;	}	if (file->length > pos)		file_check_hole(file, fd, pos, file->length - pos);	CHECK(fstat(fd, &st) != -1);	CHECK(file->link_count == st.st_nlink);	if (open_and_close) {		CHECK(close(fd) != -1);		free(path);	}	entry = file->links;	while (entry) {		link_count += 1;		entry = entry->next_link;	}	CHECK(link_count == file->link_count);}static char *symlink_path(const char *path, const char *target_pathname){	char *p;	size_t len, totlen, tarlen;	if (target_pathname[0] == '/')		return copy_string(target_pathname);	p = strrchr(path, '/');	len = p - path;	len += 1;	tarlen = strlen(target_pathname);	totlen = len + tarlen + 1;	p = malloc(totlen);	CHECK(p != NULL);	strncpy(p, path, len);	p[len] = '\0';	strcat(p, target_pathname);	return p;}void symlink_check(const struct symlink_info *symlink){	char *path, buf[8192], *target;	struct stat st1, st2;	ssize_t len;	int ret1, ret2;	path = dir_path(symlink->entry->parent, symlink->entry->name);	CHECK(lstat(path, &st1) != -1);	CHECK(S_ISLNK(st1.st_mode));	CHECK(st1.st_nlink == 1);	len = readlink(path, buf, 8192);	CHECK(len > 0 && len < 8192);	buf[len] = '\0';	CHECK(strlen(symlink->target_pathname) == len);	CHECK(strncmp(symlink->target_pathname, buf, len) == 0);	/* Check symlink points where it should */	ret1 = stat(path, &st1);	target = symlink_path(path, symlink->target_pathname);	ret2 = stat(target, &st2);	CHECK(ret1 == ret2);	if (ret1 != -1) {		CHECK(st1.st_dev == st2.st_dev);		CHECK(st1.st_ino == st2.st_ino);	}	free(target);	free(path);}static int search_comp(const void *pa, const void *pb){	const struct dirent *a = (const struct dirent *) pa;	const struct dir_entry_info *b = * (const struct dir_entry_info **) pb;	return strcmp(a->d_name, b->name);}static void dir_entry_check(struct dir_entry_info **entry_array,			size_t number_of_entries,			struct dirent *ent){	struct dir_entry_info **found;	struct dir_entry_info *entry;	size_t sz;	sz = sizeof(struct dir_entry_info *);	found = bsearch(ent, entry_array, number_of_entries, sz, search_comp);	CHECK(found != NULL);	entry = *found;	CHECK(!entry->checked);	entry->checked = 1;}static int sort_comp(const void *pa, const void *pb){	const struct dir_entry_info *a = * (const struct dir_entry_info **) pa;	const struct dir_entry_info *b = * (const struct dir_entry_info **) pb;	return strcmp(a->name, b->name);}static void dir_check(struct dir_info *dir){	struct dir_entry_info **entry_array, **p;	size_t sz, n;	struct dir_entry_info *entry;	DIR *d;	struct dirent *ent;	unsigned checked = 0;	char *path;	int link_count = 2; /* Parent and dot */	struct stat st;	/* Create an array of entries */	sz = sizeof(struct dir_entry_info *);	n = dir->number_of_entries;	entry_array = (struct dir_entry_info **) malloc(sz * n);	CHECK(entry_array != NULL);	entry = dir->first;	p = entry_array;	while (entry) {		*p++ = entry;		entry->checked = 0;		entry = entry->next;	}	/* Sort it by name */	qsort(entry_array, n, sz, sort_comp);	/* Go through directory on file system checking entries match */	path = dir_path(dir->parent, dir->name);	d = opendir(path);	CHECK(d != NULL);	for (;;) {		errno = 0;		ent = readdir(d);		if (ent) {			if (strcmp(".",ent->d_name) != 0 &&					strcmp("..",ent->d_name) != 0) {				dir_entry_check(entry_array, n, ent);				checked += 1;			}		} else {			CHECK(errno == 0);			break;		}	}	CHECK(closedir(d) != -1);	CHECK(checked == dir->number_of_entries);	/* Now check each entry */	entry = dir->first;	while (entry) {		if (entry->type == 'd') {			dir_check(entry->entry.dir);			link_count += 1; /* <subdir>/.. */		} else if (entry->type == 'f')			file_check(entry->entry.file, -1);		else if (entry->type == 's')			symlink_check(entry->entry.symlink);		else			CHECK(0);		entry = entry->next;	}	CHECK(stat(path, &st) != -1);	CHECK(link_count == st.st_nlink);	free(entry_array);	free(path);}static void check_deleted_files(void){	struct open_file_info *ofi;	for (ofi = open_files; ofi; ofi = ofi->next)		if (ofi->fdi->file->deleted)			file_check(ofi->fdi->file, ofi->fdi->fd);}static void close_open_files(void){	struct open_file_info *ofi;	for (ofi = open_files; ofi; ofi = open_files)		file_close(ofi->fdi);}static char *make_name(struct dir_info *dir){	static char name[256];	struct dir_entry_info *entry;	int found;	do {		found = 0;		if (tests_random_no(5) == 1) {			int i, n = tests_random_no(tests_max_fname_len) + 1;			CHECK(n > 0 && n < 256);			for (i = 0; i < n; i++)				name[i] = 'a' + tests_random_no(26);			name[i] = '\0';		} else			sprintf(name, "%u", (unsigned) tests_random_no(1000000));		for (entry = dir->first; entry; entry = entry->next) {			if (strcmp(entry->name, name) == 0) {				found = 1;				break;			}		}	} while (found);	return name;}static struct file_info *pick_file(void){	struct dir_info *dir = top_dir;	for (;;) {		struct dir_entry_info *entry;		size_t r;		r = tests_random_no(dir->number_of_entries);		entry = dir->first;		while (entry && r) {			entry = entry->next;			--r;		}		for (;;) {			if (!entry)				return NULL;			if (entry->type == 'f')				return entry->entry.file;			if (entry->type == 'd')				if (entry->entry.dir->number_of_entries != 0)					break;			entry = entry->next;		}		dir = entry->entry.dir;	}}static struct dir_info *pick_dir(void){	struct dir_info *dir = top_dir;	if (tests_random_no(40) >= 30)		return dir;	for (;;) {		struct dir_entry_info *entry;		size_t r;		r = tests_random_no(dir->number_of_entries);		entry = dir->first;		while (entry && r) {			entry = entry->next;			--r;		}		for (;;) {			if (!entry)				break;			if (entry->type == 'd')				break;			entry = entry->next;		}		if (!entry) {			entry = dir->first;			for (;;) {				if (!entry)					break;				if (entry->type == 'd')					break;				entry = entry->next;			}		}		if (!entry)			return dir;		dir = entry->entry.dir;		if (tests_random_no(40) >= 30)			return dir;	}}static char *pick_rename_name(struct dir_info **parent,			      struct dir_entry_info **rename_entry, int isdir){	struct dir_info *dir = pick_dir();	struct dir_entry_info *entry;	size_t r;	*parent = dir;	*rename_entry = NULL;	if (grow || tests_random_no(20) < 10)		return copy_string(make_name(dir));	r = tests_random_no(dir->number_of_entries);	entry = dir->first;	while (entry && r) {		entry = entry->next;		--r;	}	if (!entry)		entry = dir->first;	if (!entry ||	    (entry->type == 'd' && entry->entry.dir->number_of_entries != 0))		return copy_string(make_name(dir));	if ((isdir && entry->type != 'd') ||	    (!isdir && entry->type == 'd'))		return copy_string(make_name(dir));	*rename_entry = entry;	return copy_string(entry->name);}static void rename_entry(struct dir_entry_info *entry){	struct dir_entry_info *rename_entry = NULL;	struct dir_info *parent;	char *path, *to, *name;	int ret, isdir, retry;	if (!entry->parent)		return;	for (retry = 0; retry < 3; retry++) {		path = dir_path(entry->parent, entry->name);		isdir = entry->type == 'd' ? 1 : 0;		name = pick_rename_name(&parent, &rename_entry, isdir);		to = dir_path(parent, name);		/*		 * Check we are not trying to move a directory to a subdirectory		 * of itself.		 */		if (isdir) {			struct dir_info *p;			for (p = parent; p; p = p->parent)				if (p == entry->entry.dir)					break;			if (p == entry->entry.dir) {				free(path);				free(name);				free(to);				path = NULL;				continue;			}		}		break;	}	if (!path)		return;	ret = rename(path, to);	if (ret == -1) {

⌨️ 快捷键说明

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