Esempio n. 1
0
static int ext2_file_type(unsigned int mode)
{
	if (LINUX_S_ISREG(mode))
		return EXT2_FT_REG_FILE;

	if (LINUX_S_ISDIR(mode))
		return EXT2_FT_DIR;

	if (LINUX_S_ISCHR(mode))
		return EXT2_FT_CHRDEV;

	if (LINUX_S_ISBLK(mode))
		return EXT2_FT_BLKDEV;

	if (LINUX_S_ISLNK(mode))
		return EXT2_FT_SYMLINK;

	if (LINUX_S_ISFIFO(mode))
		return EXT2_FT_FIFO;

	if (LINUX_S_ISSOCK(mode))
		return EXT2_FT_SOCK;

	return 0;
}
Esempio n. 2
0
/*
 * This function expands '%IX' expressions
 */
static _INLINE_ void expand_inode_expression(FILE *f, ext2_filsys fs, char ch,
					     struct problem_context *ctx)
{
	struct ext2_inode	*inode;
	struct ext2_inode_large	*large_inode;

	if (!ctx || !ctx->inode)
		goto no_inode;

	inode = ctx->inode;
	large_inode = (struct ext2_inode_large *) inode;

	switch (ch) {
	case 's':
		if (LINUX_S_ISDIR(inode->i_mode))
			fprintf(f, "%u", inode->i_size);
		else {
#ifdef EXT2_NO_64_TYPE
			if (inode->i_size_high)
				fprintf(f, "0x%x%08x", inode->i_size_high,
					inode->i_size);
			else
				fprintf(f, "%u", inode->i_size);
#else
			fprintf(f, "%llu", EXT2_I_SIZE(inode));
#endif
		}
		break;
	case 'S':
		fprintf(f, "%u", large_inode->i_extra_isize);
		break;
	case 'b':
		if (ext2fs_has_feature_huge_file(fs->super))
			fprintf(f, "%llu", inode->i_blocks +
				(((long long) inode->osd2.linux2.l_i_blocks_hi)
				 << 32));
		else
			fprintf(f, "%u", inode->i_blocks);
		break;
	case 'l':
		fprintf(f, "%d", inode->i_links_count);
		break;
	case 'm':
		fprintf(f, "0%o", inode->i_mode);
		break;
	case 'M':
		print_time(f, inode->i_mtime);
		break;
	case 'F':
		fprintf(f, "%u", inode->i_faddr);
		break;
	case 'f':
		fprintf(f, "%llu", ext2fs_file_acl_block(fs, inode));
		break;
	case 'd':
		fprintf(f, "%u", (LINUX_S_ISDIR(inode->i_mode) ?
				  inode->i_dir_acl : 0));
		break;
	case 'u':
		fprintf(f, "%d", inode_uid(*inode));
		break;
	case 'g':
		fprintf(f, "%d", inode_gid(*inode));
		break;
	case 't':
		if (LINUX_S_ISREG(inode->i_mode))
			fputs(_("regular file"), f);
		else if (LINUX_S_ISDIR(inode->i_mode))
			fputs(_("directory"), f);
		else if (LINUX_S_ISCHR(inode->i_mode))
			fputs(_("character device"), f);
		else if (LINUX_S_ISBLK(inode->i_mode))
			fputs(_("block device"), f);
		else if (LINUX_S_ISFIFO(inode->i_mode))
			fputs(_("named pipe"), f);
		else if (LINUX_S_ISLNK(inode->i_mode))
			fputs(_("symbolic link"), f);
		else if (LINUX_S_ISSOCK(inode->i_mode))
			fputs(_("socket"), f);
		else
			fprintf(f, _("unknown file type with mode 0%o"),
				inode->i_mode);
		break;
	default:
	no_inode:
		fprintf(f, "%%I%c", ch);
		break;
	}
}
Esempio n. 3
0
extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
				    ext2_ino_t ino, char *buf)
{
	ext2_filsys fs = ctx->fs;
	struct ext2_inode	inode;
	int			inode_modified = 0;
	int			not_fixed = 0;
	unsigned char		*frag, *fsize;
	struct problem_context	pctx;
	int	problem = 0;

	e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");

	clear_problem_context(&pctx);
	pctx.ino = ino;
	pctx.dir = dir;
	pctx.inode = &inode;

	if (ext2fs_file_acl_block(fs, &inode) &&
	    !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR)) {
		if (fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
			ext2fs_file_acl_block_set(fs, &inode, 0);
			inode_modified++;
		} else
			not_fixed++;
	}

	if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
	    !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
	    !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
	    !(LINUX_S_ISSOCK(inode.i_mode)))
		problem = PR_2_BAD_MODE;
	else if (LINUX_S_ISCHR(inode.i_mode)
		 && !e2fsck_pass1_check_device_inode(fs, &inode))
		problem = PR_2_BAD_CHAR_DEV;
	else if (LINUX_S_ISBLK(inode.i_mode)
		 && !e2fsck_pass1_check_device_inode(fs, &inode))
		problem = PR_2_BAD_BLOCK_DEV;
	else if (LINUX_S_ISFIFO(inode.i_mode)
		 && !e2fsck_pass1_check_device_inode(fs, &inode))
		problem = PR_2_BAD_FIFO;
	else if (LINUX_S_ISSOCK(inode.i_mode)
		 && !e2fsck_pass1_check_device_inode(fs, &inode))
		problem = PR_2_BAD_SOCKET;
	else if (LINUX_S_ISLNK(inode.i_mode)
		 && !e2fsck_pass1_check_symlink(fs, ino, &inode, buf)) {
		problem = PR_2_INVALID_SYMLINK;
	}

	if (problem) {
		if (fix_problem(ctx, problem, &pctx)) {
			deallocate_inode(ctx, ino, 0);
			if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
				return 0;
			return 1;
		} else
			not_fixed++;
		problem = 0;
	}

	if (inode.i_faddr) {
		if (fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
			inode.i_faddr = 0;
			inode_modified++;
		} else
			not_fixed++;
	}

	switch (fs->super->s_creator_os) {
	    case EXT2_OS_HURD:
		frag = &inode.osd2.hurd2.h_i_frag;
		fsize = &inode.osd2.hurd2.h_i_fsize;
		break;
	    default:
		frag = fsize = 0;
	}
	if (frag && *frag) {
		pctx.num = *frag;
		if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
			*frag = 0;
			inode_modified++;
		} else
			not_fixed++;
		pctx.num = 0;
	}
	if (fsize && *fsize) {
		pctx.num = *fsize;
		if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
			*fsize = 0;
			inode_modified++;
		} else
			not_fixed++;
		pctx.num = 0;
	}

	if ((fs->super->s_creator_os == EXT2_OS_LINUX) &&
	    !(fs->super->s_feature_ro_compat &
	      EXT4_FEATURE_RO_COMPAT_HUGE_FILE) &&
	    (inode.osd2.linux2.l_i_blocks_hi != 0)) {
		pctx.num = inode.osd2.linux2.l_i_blocks_hi;
		if (fix_problem(ctx, PR_2_BLOCKS_HI_ZERO, &pctx)) {
			inode.osd2.linux2.l_i_blocks_hi = 0;
			inode_modified++;
		}
	}

	if (!(fs->super->s_feature_incompat & 
	     EXT4_FEATURE_INCOMPAT_64BIT) &&
	    inode.osd2.linux2.l_i_file_acl_high != 0) {
		pctx.num = inode.osd2.linux2.l_i_file_acl_high;
		if (fix_problem(ctx, PR_2_I_FILE_ACL_HI_ZERO, &pctx)) {
			inode.osd2.linux2.l_i_file_acl_high = 0;
			inode_modified++;
		} else
			not_fixed++;
	}

	if (ext2fs_file_acl_block(fs, &inode) &&
	    ((ext2fs_file_acl_block(fs, &inode) < fs->super->s_first_data_block) ||
	     (ext2fs_file_acl_block(fs, &inode) >= ext2fs_blocks_count(fs->super)))) {
		if (fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
			ext2fs_file_acl_block_set(fs, &inode, 0);
			inode_modified++;
		} else
			not_fixed++;
	}
	if (inode.i_dir_acl &&
	    LINUX_S_ISDIR(inode.i_mode)) {
		if (fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
			inode.i_dir_acl = 0;
			inode_modified++;
		} else
			not_fixed++;
	}

	if (inode_modified)
		e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
	if (!not_fixed && ctx->inode_bad_map)
		ext2fs_unmark_inode_bitmap2(ctx->inode_bad_map, ino);
	return 0;
}
Esempio n. 4
0
/*
 * This function expands '%IX' expressions
 */
static _INLINE_ void expand_inode_expression(char ch, 
					     struct problem_context *ctx)
{
	struct ext2_inode	*inode;
	struct ext2_inode_large	*large_inode;
	const char *		time_str;
	time_t			t;
	int			do_gmt = -1;

	if (!ctx || !ctx->inode)
		goto no_inode;
	
	inode = ctx->inode;
	large_inode = (struct ext2_inode_large *) inode;

	switch (ch) {
	case 's':
		if (LINUX_S_ISDIR(inode->i_mode))
			printf("%u", inode->i_size);
		else {
#ifdef EXT2_NO_64_TYPE
			if (inode->i_size_high)
				printf("0x%x%08x", inode->i_size_high,
				       inode->i_size);
			else
				printf("%u", inode->i_size);
#else
			printf("%llu", inode->i_size |
				       ((long long)inode->i_size_high << 32));
#endif
		}
		break;
	case 'S':
		printf("%u", large_inode->i_extra_isize);
		break;
	case 'b':
		printf("%u", inode->i_blocks);
		break;
	case 'l':
		printf("%d", inode->i_links_count);
		break;
	case 'm':
		printf("0%o", inode->i_mode);
		break;
	case 'M':
		/* The diet libc doesn't respect the TZ environemnt variable */
		if (do_gmt == -1) {
			time_str = getenv("TZ");
			if (!time_str)
				time_str = "";
			do_gmt = !strcmp(time_str, "GMT");
		}
		t = inode->i_mtime;
		time_str = asctime(do_gmt ? gmtime(&t) : localtime(&t));
		printf("%.24s", time_str);
		break;
	case 'F':
		printf("%u", inode->i_faddr);
		break;
	case 'f':
		printf("%u", inode->i_file_acl);
		break;
	case 'd':
		printf("%u", (LINUX_S_ISDIR(inode->i_mode) ?
			      inode->i_dir_acl : 0));
		break;
	case 'u':
		printf("%d", inode_uid(*inode));
		break;
	case 'g':
		printf("%d", inode_gid(*inode));
		break;
	case 't':
		if (LINUX_S_ISREG(inode->i_mode)) 
			printf(_("regular file"));
		else if (LINUX_S_ISDIR(inode->i_mode)) 
			printf(_("directory"));
		else if (LINUX_S_ISCHR(inode->i_mode)) 
			printf(_("character device"));
		else if (LINUX_S_ISBLK(inode->i_mode)) 
			printf(_("block device"));
		else if (LINUX_S_ISFIFO(inode->i_mode)) 
			printf(_("named pipe"));
		else if (LINUX_S_ISLNK(inode->i_mode)) 
			printf(_("symbolic link"));
		else if (LINUX_S_ISSOCK(inode->i_mode))
			printf(_("socket"));
		else
			printf(_("unknown file type with mode 0%o"),
			       inode->i_mode);
		break;
	default:
	no_inode:
		printf("%%I%c", ch);
		break;
	}
}
Esempio n. 5
0
void addFilespec(FILE *fd, int squash_uids, int squash_perms)
{

	unsigned long rmode, mode, uid, gid, major, minor, i;
	unsigned long start, increment, count, octmode, decmode;
	char *c, *dir, *name, *dname = NULL, *path = NULL, *path2 = NULL, *line = NULL;
	char type;
	size_t len;
	int argv, i2, overWrite = 0, lineno = 0;
	__u16 inodeType;

	while ( getline(&line, &len, fd) >= 0 ) {
		rmode = mode = uid = gid = major = minor = start = count = overWrite = 0;
		increment = 1;
		lineno++;

		if (( c = strchr(line, '#'))) *c = 0;
		if ( path ) {
			free( path ); path = NULL;
		}
		if ( path2 ) {
			free( path2 ); path2 = NULL;
		}

		argv = sscanf(line, "%" SCANF_PREFIX "s %c %ld %lu %lu %lu %lu %lu %lu %lu",
			      SCANF_STRING(path), &type, &rmode, &uid, &gid, &major, &minor,
			      &start, &increment, &count);

		if ( argv < 3 ) {
			if ( argv > 0 )
				log_warning("device table[%d]: bad format for entry '%s' [skip]", lineno, path);
			continue;
		}

		i2 = 0;
		octmode = rmode;
		decmode = 0;
		while ( octmode != 0 ) {
			decmode = decmode + (octmode % 10) * pow(8, i2++);
			octmode = octmode / 10;
		}

		if ( squash_uids ) uid = gid = 0;

		mode = decmode;
		path2 = strdup( path );
		name = basename( path );
		dir = dirname( path2 );

		if (( !strcmp(name, ".")) || ( !strcmp(name, "..")) || ( !strcmp(name, "/"))) {
			log_warning("device table[%d]: [skip]", lineno);
			continue;
		}

		log_action(ACT_CHDIR, dir, NULL, 0, 0, 0, 0, 0, 0, 0);
		if ( !do_chdir(dir)) {
			log_warning("device table[%d]: target directory '%s' for entry '%s' does not exist [skip]", lineno, dir, name);
			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir("/"))
				log_error("[Filesystem error] cannot chdir to root");
			continue;
		}

		if (( type != 'd' ) && ( type != 'f' ) && ( type != 'p' ) && ( type != 'c' ) && ( type != 'b' ) && ( type != 's')) {
			log_warning("device table[%d]: bad type '%c' for entry '%s' [skip]", lineno, type, name);
			continue;
		}

		if (squash_perms) {
			mode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO );
			rmode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO);
		}

		if ( count > 0 ) {

			if ( dname ) {
				free( dname );
				dname = NULL;
			}

			unsigned len;
			len = strlen(name) + 10;
			dname = malloc(len + 1);

			for ( i = start; i < count; i++ ) {
				snprintf(dname, len, "%s%lu", name, i);

				if (( overWrite = name_to_inode(dname)))
					inodeType = inode_mode(dname);

				if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
					log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname);
				else if (( type != 'd' ) && ( overWrite )) {

					if ( LINUX_S_ISDIR(inodeType))
						log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname);

					if ((!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
					    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
					    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
						log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), dname, inodeType);
				}

				switch ( type ) {
				case 'd':
					mode |= LINUX_S_IFDIR;
					log_action(ACT_MKDIR, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);

					if ( !overWrite )
						if ( !do_mkdir(dname))
							log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), dname);

					break;

				case 'c':
				case 'b':
					if ( type == 'c' )
						mode |= LINUX_S_IFCHR;
					else
						mode |= LINUX_S_IFBLK;

					if ( overWrite ) {
						log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);
						if ( !do_rm(dname))
							log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname);
					}

					log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, major, minor + ((i * increment) - start), overWrite);
					if ( !do_mknod(dname, type, major, minor + ((i * increment) - start)))
						log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname);
					break;

				case 's':
				case 'p':
					if ( type == 's' )
						mode |= LINUX_S_IFSOCK;
					else mode |= LINUX_S_IFIFO;

					if ( overWrite ) {
						log_action(ACT_RM, dname, NULL, 0, 0, 0, 0, 0, 0, overWrite);
						if ( !do_rm(dname))
							log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), dname);
					}

					log_action(ACT_MKNOD, dname, NULL, 0, 0, 0, type, 0, 0, overWrite);
					if ( !do_mknod(dname, type, 0, 0))
						log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), dname);

					break;
				}

				log_action(ACT_CHMOD, dname, NULL, rmode, 0, 0, 0, 0, 0, 0);
				if ( !do_chmod(dname, rmode))
					log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), dname);
				log_action(ACT_CHOWN, dname, NULL, 0, uid, gid, 0, 0, 0, 0);
				if ( !do_chown(dname, uid, gid))
					log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), dname);
			}

			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir("/"))
				log_error("[Filesystem error] cannot chdir to root");
			free(dname);
			dname = NULL;

		} else {

			if (( overWrite = name_to_inode(name)))
				inodeType = inode_mode(name);

			if (( type == 'd' ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
				log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), dname);
			else if ( type != 'd' ) {
				if (( overWrite ) && ( LINUX_S_ISDIR(inodeType)))
					log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), dname);

				if (( overWrite ) && (!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
				    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
				    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
					log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].",  log_cwd(), dname, inodeType);
			}

			switch ( type ) {
			case 'd':
				mode |= LINUX_S_IFDIR;
				log_action(ACT_MKDIR, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);

				if ( !overWrite )
					if ( !do_mkdir(name))
						log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), name);
				break;

			case 'c':
			case 'b':
				if ( type == 'c' )
					mode |= LINUX_S_IFCHR;
				else
					mode |= LINUX_S_IFBLK;

				if ( overWrite ) {
					log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
					if ( !do_rm(name))
						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name);
				}

				log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, major, minor, overWrite);
				if ( !do_mknod(name, type, major, minor))
					log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name);
				break;

			case 's':
			case 'p':
				if ( type == 's' )
					mode |= LINUX_S_IFSOCK;
				else mode |= LINUX_S_IFIFO;

				if ( overWrite ) {
					log_action(ACT_RM, name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
					if ( !do_rm(name))
						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), name);
				}

				log_action(ACT_MKNOD, name, NULL, 0, 0, 0, type, 0, 0, overWrite);
				if ( !do_mknod(name, type, 0, 0))
					log_error("[Filesystem error] cannot mknod %s/%s", log_cwd(), name);
				break;
			}

			log_action(ACT_CHMOD, name, NULL, rmode, 0, 0, 0, 0, 0, 0);
			if ( !do_chmod(name, rmode))
				log_error("[Filesystem error] cannot chmod %s/%s", log_cwd(), name);
			log_action(ACT_CHOWN, name, NULL, 0, uid, gid, 0, 0, 0, 0);
			if ( !do_chown(name, uid, gid))
				log_error("[Filesystem error] cannot chown %s/%s", log_cwd(), name);
			log_action(ACT_CHDIR, "/", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir("/"))
				log_error("[Filesystem error] cannot chdir to root");
		}

	}


	if ( line ) {
		free( line ); line = NULL;
	}
	if ( path ) {
		free( path ); path = NULL;
	}
	if ( path2 ) {
		free( path2 ); path2 = NULL;
	}

}
Esempio n. 6
0
void addPath(const char *path, int squash_uids, int squash_perms)
{
	size_t len;
	char *full_name = NULL, *lnk = NULL;
	struct dirent *file = NULL;
	DIR *direc = NULL;
	struct stat st;
	int overWrite;
	__u16 inodeType;

	direc = opendir(path);

	if ( !direc )
		log_error("[Local fs opendir] Cannot open directory %s", path);

	while (( file = readdir(direc)) != NULL ) {

		if (( !strcmp(file->d_name, "." )) || ( !strcmp(file->d_name, ".." )))
			continue;

		len = strlen(path) + strlen( file->d_name ) + 3;

		if ( full_name ) {
			free( full_name );
			full_name = NULL;
		}

		full_name = (char*)malloc(len + 2);
		if ( !full_name )
			log_error("[Local fs stat] Memory allocation error ( full_name --> %s/%s )", path, file->d_name);

		memset(full_name, 0, len + 2);
		snprintf(full_name, len, "%s/%s", path, file->d_name);

		lstat(full_name, &st);
		mode_t fmt = st.st_mode & S_IFMT;

		if ( squash_uids )
			st.st_uid = st.st_gid = 0;

		if ( squash_perms )
			st.st_mode &= ~( LINUX_S_IRWXG | LINUX_S_IRWXO );

		overWrite = name_to_inode( file->d_name );

		if ( st.st_nlink > 1 ) {
			if (( lnk = linklist_add(st.st_dev, st.st_ino, full_name + modPath_path_len))) {

				if ( overWrite ) {
					log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
					if ( !do_rm(file->d_name))
						log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
				}

				log_action(ACT_HARDLINK, file->d_name, lnk, 0, 0, 0, 0, 0, 0, overWrite);
				if (!do_hardlink(&st, lnk, file->d_name))
					log_error("[Filesystem error] cannot hardlink %s --> %s", file->d_name, lnk);
				continue;
			}
		}

		if ( overWrite )
			inodeType = inode_mode( file->d_name );

		if (( fmt == S_IFDIR ) && ( overWrite ) && ( !LINUX_S_ISDIR(inodeType)))
			log_error("[Remote fs mismatch] %s/%s exists but isn't a directory when it should be.", log_cwd(), file->d_name);
		else if (( fmt != S_IFDIR) && ( overWrite )) {
			if ( LINUX_S_ISDIR(inodeType))
				log_error("[Remote fs mismatch] %s/%s exists but is a directory when it shouldn't be.", log_cwd(), file->d_name);

			if ((!LINUX_S_ISREG(inodeType)) && (!LINUX_S_ISLNK(inodeType)) &&
			    (!LINUX_S_ISBLK(inodeType)) && (!LINUX_S_ISCHR(inodeType)) &&
			    (!LINUX_S_ISFIFO(inodeType)) && (!LINUX_S_ISSOCK(inodeType)))
				log_error("[Remote fs mismatch] Existing file %s/%s has unknown/unsupported type [0x%x].", log_cwd(), file->d_name);
		}

		switch ( fmt ) {
		case S_IFDIR:         // Directory
			log_action(ACT_MKDIR, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);

			if ( !overWrite )
				if ( !do_mkdir( &st, file->d_name ))
					log_error("[Filesystem error] cannot mkdir %s/%s", log_cwd(), file->d_name);

			log_action(ACT_CHMODE, file->d_name, NULL, st.st_mode, 0, 0, 0, 0, 0, overWrite);
			if ( !do_chmode(file->d_name, st.st_mode))
				log_error("[Filesystem error] Failed to chmode 0x%x for directory %s/%s", st.st_mode, log_cwd(), file->d_name);
			log_action(ACT_CHOWN, file->d_name, NULL, 0, st.st_uid, st.st_gid, 0, 0, 0, 0);
			if ( !do_chown(file->d_name, st.st_uid, st.st_gid))
				log_error("[Filesystem error] Failed to chown %ld, %ld for directory %s/%s", st.st_uid, st.st_gid, log_cwd(), file->d_name);

			log_action(ACT_CHDIR, file->d_name, NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir( file->d_name ))
				log_error("[Filesystem error] cannot chdir to newly created %s/%s", log_cwd(), file->d_name);

			addPath(full_name, squash_uids, squash_perms);

			log_action(ACT_CHDIR, "..", NULL, 0, 0, 0, 0, 0, 0, 0);
			if ( !do_chdir(".."))
				log_error("[Filesystem error] cannot chdir to parent directory");
			break;

		case S_IFREG:         // Regular file

			if ( overWrite ) {
				log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
				if ( !do_rm(file->d_name))
					log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
			}

			log_action(ACT_WRITE, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
			if ( !do_write(full_name, file->d_name))
				log_error("[Filesystem error] cannot write %s/%s", log_cwd(), file->d_name);
			break;

		case S_IFLNK:         // Symbolic link

			lnk = (char*)malloc(MAX_PATHSIZE + 2);
			if ( !lnk )
				log_error("[symlink] Memory allocation error (lnk)");
			int len = readlink(full_name, lnk, MAX_PATHSIZE);
			if ( len == -1 ) {
				free(lnk);
				log_error("[Local filesystem error] Cannot read destination for link %s/%s", log_cwd(), file->d_name);
			} else lnk[len] = '\0';

			if ( overWrite ) {
				log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
				if ( !do_rm(file->d_name))
					log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
			}

			log_action(ACT_SYMLINK, file->d_name, lnk, 0, 0, 0, 0, 0, 0, overWrite);
			if ( !do_symlink(&st, lnk, file->d_name))
				log_error("[Filesystem error] cannot symlink %s/%s --> %s", log_cwd(), file->d_name, lnk);

			free(lnk);
			break;

		case S_IFBLK:           // Block device node
		case S_IFCHR:           // Character device node
		case S_IFSOCK:          // socket
		case S_IFIFO:           // fifo

			if ( overWrite ) {
				log_action(ACT_RM, file->d_name, NULL, 0, 0, 0, 0, 0, 0, overWrite);
				if ( !do_rm(file->d_name))
					log_error("[Filesystem error] cannot rm %s/%s", log_cwd(), file->d_name);
			}

			char nodetype = ( fmt == S_IFBLK ? 'b' : ( fmt == S_IFCHR ? 'c' : ( fmt == S_IFSOCK ? 's' : 'p' )));
			unsigned long major = 0, minor = 0;

			if (( nodetype == 'b' ) || ( nodetype == 'c' )) {
				major = (long)major(st.st_rdev);
				minor = (long)minor(st.st_rdev);
			}

			log_action(ACT_MKNOD, file->d_name, NULL, 0, 0, 0, nodetype, major, minor, overWrite);
			if ( !do_mknod(file->d_name, nodetype, major, minor))
				log_error("[Filesystem error] cannot mknod %c %ld,%ld %s/%s", log_cwd(), nodetype, major, minor, log_cwd(), file->d_name);
			break;
		}

		if ( fmt != S_IFDIR ) { // Not dir ?
			log_action(ACT_CHMODE, file->d_name, NULL, st.st_mode, 0, 0, 0, 0, 0, overWrite);
			if ( !do_chmode(file->d_name, st.st_mode))
				log_error("[Filesystem error] Failed to chmode 0x%x for file %s/%s", st.st_mode, log_cwd(), file->d_name);
			log_action(ACT_CHOWN, file->d_name, NULL, 0, st.st_uid, st.st_gid, 0, 0, 0, 0);
			if ( !do_chown(file->d_name, st.st_uid, st.st_gid))
				log_error("[Filesystem error] Failed to chown %ld, %ld for file %s/%s", st.st_uid, st.st_gid, log_cwd(), file->d_name);
		}

		if ( full_name ) {
			free( full_name );
			full_name = NULL;
		}
	}

	closedir(direc);

}
Esempio n. 7
0
// recover Datafile
int recover_file( char* des_dir,char* pathname, char* filename, struct ext2_inode *inode, ext2_ino_t inode_nr, int flag){
	int rec_error = 255;
	char err_string[9];
	int retval =-1;
	int hardlink = 0;
	char i = 0;
	char *buf=NULL;
	struct privat priv;
	struct stat  filestat;
	char *helpname = NULL;
	char *recovername = NULL;
	char *linkname = NULL;
	char *p1;
	unsigned long long i_size;
	struct utimbuf   touchtime;
	mode_t i_mode;
	int major, minor, type;

#ifdef DEBUG
	printf("RECOVER : INODE=%ld FILENAME=%s/%s\n",inode_nr, pathname,filename);
	dump_inode(stdout, "",inode_nr, (struct ext2_inode *)inode, 0);
#endif	
	
	if (!(inode->i_mode & LINUX_S_IFMT)) //no type flag - no recover
		return 1;

	p1 = pathname;
	while   (*p1 == '/') p1++;
	helpname = malloc(strlen(des_dir) + 15);
	recovername = malloc(strlen(des_dir) + strlen(pathname) + strlen(filename) +10);
	if (helpname && recovername){	
		strcpy(helpname,des_dir);
		strcat(helpname,"/");
		strcpy(recovername,helpname);
		strcat(recovername,p1);
		if (strlen(p1)) 
			strcat(recovername,"/");
		strcat(recovername,filename);
		while (!(stat(recovername, &filestat)) && (i<5)){
			strcat(recovername,"#");
			i++;
		}

		p1 = strchr(helpname,0);
		sprintf(p1,"#%u#",inode_nr);
		unlink (helpname);

		priv.flag = flag;

//FIXME: hardlink
		if (inode->i_links_count > 1){
			p1 = check_link_stack(inode_nr, inode->i_generation);
			if (p1) {
				//hardlink found
				if (! stat(p1, &filestat)){
					retval = check_dir(recovername);
					if (retval)
						fprintf(stderr,"Unknown error at target directory by file: %s\ntrying to continue normal\n", recovername);
					else {
						if (! link(p1,recovername)){
							if (match_link_stack(inode_nr, inode->i_generation))
								rec_error  -= CREATE_ERROR ;
							goto out;
						}
						else{	
							rec_error  -= CREATE_ERROR ;
						}
					}
				}
			}
			else{
				//flag as hardlink
				hardlink = 1;
			}
		}

	
		switch (inode->i_mode  & LINUX_S_IFMT){
//regular File;
		case LINUX_S_IFREG :
			priv.fd = open(helpname, O_WRONLY | O_CREAT | O_TRUNC | O_LARGEFILE, S_IRWXU);
			if (! priv.fd ){ 
				fprintf(stderr,"Error: open File %s for writing\n",helpname);
				retval = errno;
				goto errout;
			}
			buf=malloc(current_fs->blocksize);
			if (buf) {
				priv.buf = buf;
				priv.error = 0;
				// iterate Data Blocks and if not allocated, write to file
				retval = local_block_iterate3 ( current_fs, *inode, BLOCK_FLAG_DATA_ONLY, NULL, write_block, &priv );
#ifdef DEBUG
				printf("\n");
#endif
				if (retval || priv.error){
					// error or blocks allocated , we delete the tempfile and goto out
					close(priv.fd);
					unlink(helpname);
					retval = -1;
					goto errout;
				}
				else{
				i_size = (unsigned long long)(inode->i_size | ((unsigned long long)inode->i_size_high << 32));
					retval = ftruncate(priv.fd,i_size);
					if (retval){
						rec_error -= SEEK_ERROR ;	
					}
				}
		
			}
			else {
				fprintf(stderr,"ERROR: can no allocate memory\n");
				retval = -1;
				close(priv.fd);
				goto errout;
 			}
			close(priv.fd);
		 break;

//symbolic link	
		case LINUX_S_IFLNK :
			  if (ext2fs_inode_data_blocks(current_fs,inode)){
				buf = malloc(current_fs->blocksize + 1); 
				if (buf) {
					memset(buf,0,current_fs->blocksize + 1);
					priv.buf = buf;
					priv.error = 0;
					
					retval = local_block_iterate3 ( current_fs, *inode, BLOCK_FLAG_DATA_ONLY, NULL, read_syslink_block, &priv );
					if (retval || priv.error)
							 goto errout;
				}
				else {
					fprintf(stderr,"ERROR: can no allocate memory\n");
					retval = -1;
					goto errout;
	 			}
			}
			else {
				int i;
			
				if((! inode->i_size) || (inode->i_size >= 60)) 
					goto errout; 
				buf = malloc(inode->i_size + 1);
				linkname = (char*) &(inode->i_block[0]);
				for (i = 0; i < inode->i_size ; i++){
					*(buf+i) = (char) *linkname;
					linkname++;
				}		 
				*(buf+i) = 0;
			}
			linkname = buf;
			retval = symlink(linkname, helpname);
			if (retval){
				rec_error  -= (CREATE_ERROR + SEEK_ERROR);
			}
		break;

//block or char device
		case LINUX_S_IFBLK :
		case LINUX_S_IFCHR :
			type = (LINUX_S_ISBLK(inode->i_mode)) ? S_IFBLK : S_IFCHR ; 

        	        if (inode->i_block[0]) {
                	        major = (inode->i_block[0] >> 8) & 255;
                        	minor = inode->i_block[0] & 255;
                	} else {
Esempio n. 8
0
int
fstat(int fd, struct stat *st)
{
	int ret;
	struct linux_stat lst;
	struct ifreq ifr;

	ret = syscall(SYS_fstat, fd, &lst);
	if (ret == -1) {
		errno = EBADF;
		return -1;
	}

	st->st_size = lst.st_size;

	switch (lst.st_mode & LINUX_S_IFMT) {
	case LINUX_S_IFSOCK:
		__platform_socket_fd = fd;
		/* currently no support for raw socket networking */
		lst.st_mode = 0;
		break;
	case LINUX_S_IFBLK:
		syscall(SYS_ioctl, fd, BLKGETSIZE64, &st->st_size);
		break;
	case LINUX_S_IFCHR:
		/* macvtap has a dynamic major number, so hard to test */
		if (lst.st_rdev != makedev(10, 200) && major(lst.st_rdev) < 128)
			break;
		ret = syscall(SYS_ioctl, fd, TUNGETIFF, &ifr);
		if (ret == 0) {
			/* we do not yet support macvtap offload facilities */
			if (ifr.ifr_flags & IFF_VNET_HDR) {
				ifr.ifr_flags &= ~IFF_VNET_HDR;
				syscall(SYS_ioctl, fd, TUNSETIFF, &ifr);
			}
			/* use sock type to tell config we are network */
			lst.st_mode = LINUX_S_IFSOCK;
			/* find mac address */
			ret = syscall(SYS_ioctl, fd, SIOCGIFHWADDR, &ifr);
			if (ret == -1 && __platform_socket_fd != -1)
				ret = syscall(SYS_ioctl, __platform_socket_fd, SIOCGIFHWADDR, &ifr);
			if (ret == 0) {
				memcpy(st->st_hwaddr, ifr.ifr_addr.sa_data, 6);
			}
			__platform_pollfd[__platform_npoll].fd = fd;
			__platform_pollfd[__platform_npoll].events = POLLIN | POLLPRI;
			__platform_npoll++;
		}
		break;
	}
	st->st_mode = (LINUX_S_ISDIR (lst.st_mode) ? S_IFDIR  : 0) |
		      (LINUX_S_ISCHR (lst.st_mode) ? S_IFCHR  : 0) |
		      (LINUX_S_ISBLK (lst.st_mode) ? S_IFBLK  : 0) |
		      (LINUX_S_ISREG (lst.st_mode) ? S_IFREG  : 0) |
		      (LINUX_S_ISFIFO(lst.st_mode) ? S_IFIFO  : 0) |
		      (LINUX_S_ISLNK (lst.st_mode) ? S_IFLNK  : 0) |
		      (LINUX_S_ISSOCK(lst.st_mode) ? S_IFSOCK : 0);

	/* if we are passed in /dev/urandom use as a random source */
	if (LINUX_S_ISCHR(lst.st_mode) && lst.st_rdev == makedev(1, 9))
		__platform_random_fd = fd;

	return 0;
}
Esempio n. 9
0
extern int e2fsck_process_bad_inode(e2fsck_t ctx, ext2_ino_t dir,
                                    ext2_ino_t ino)
{
    ext2_filsys fs = ctx->fs;
    struct ext2_inode	inode;
    int			inode_modified = 0;
    unsigned char		*frag, *fsize;
    struct problem_context	pctx;
    int	problem = 0;

    e2fsck_read_inode(ctx, ino, &inode, "process_bad_inode");

    clear_problem_context(&pctx);
    pctx.ino = ino;
    pctx.dir = dir;
    pctx.inode = &inode;

    if (!LINUX_S_ISDIR(inode.i_mode) && !LINUX_S_ISREG(inode.i_mode) &&
            !LINUX_S_ISCHR(inode.i_mode) && !LINUX_S_ISBLK(inode.i_mode) &&
            !LINUX_S_ISLNK(inode.i_mode) && !LINUX_S_ISFIFO(inode.i_mode) &&
            !(LINUX_S_ISSOCK(inode.i_mode)))
        problem = PR_2_BAD_MODE;
    else if (LINUX_S_ISCHR(inode.i_mode)
             && !e2fsck_pass1_check_device_inode(&inode))
        problem = PR_2_BAD_CHAR_DEV;
    else if (LINUX_S_ISBLK(inode.i_mode)
             && !e2fsck_pass1_check_device_inode(&inode))
        problem = PR_2_BAD_BLOCK_DEV;
    else if (LINUX_S_ISFIFO(inode.i_mode)
             && !e2fsck_pass1_check_device_inode(&inode))
        problem = PR_2_BAD_FIFO;
    else if (LINUX_S_ISSOCK(inode.i_mode)
             && !e2fsck_pass1_check_device_inode(&inode))
        problem = PR_2_BAD_SOCKET;
    else if (LINUX_S_ISLNK(inode.i_mode)
             && !e2fsck_pass1_check_symlink(fs, &inode)) {
        problem = PR_2_SYMLINK_SIZE;
    }

    if (problem) {
        if (fix_problem(ctx, problem, &pctx)) {
            deallocate_inode(ctx, ino, 0);
            if (ctx->flags & E2F_FLAG_SIGNAL_MASK)
                return 0;
            return 1;
        }
        problem = 0;
    }

    if (inode.i_faddr &&
            fix_problem(ctx, PR_2_FADDR_ZERO, &pctx)) {
        inode.i_faddr = 0;
        inode_modified++;
    }

    switch (fs->super->s_creator_os) {
    case EXT2_OS_LINUX:
        frag = &inode.osd2.linux2.l_i_frag;
        fsize = &inode.osd2.linux2.l_i_fsize;
        break;
    case EXT2_OS_HURD:
        frag = &inode.osd2.hurd2.h_i_frag;
        fsize = &inode.osd2.hurd2.h_i_fsize;
        break;
    case EXT2_OS_MASIX:
        frag = &inode.osd2.masix2.m_i_frag;
        fsize = &inode.osd2.masix2.m_i_fsize;
        break;
    default:
        frag = fsize = 0;
    }
    if (frag && *frag) {
        pctx.num = *frag;
        if (fix_problem(ctx, PR_2_FRAG_ZERO, &pctx)) {
            *frag = 0;
            inode_modified++;
        }
        pctx.num = 0;
    }
    if (fsize && *fsize) {
        pctx.num = *fsize;
        if (fix_problem(ctx, PR_2_FSIZE_ZERO, &pctx)) {
            *fsize = 0;
            inode_modified++;
        }
        pctx.num = 0;
    }

    if (inode.i_file_acl &&
            !(fs->super->s_feature_compat & EXT2_FEATURE_COMPAT_EXT_ATTR) &&
            fix_problem(ctx, PR_2_FILE_ACL_ZERO, &pctx)) {
        inode.i_file_acl = 0;
        inode_modified++;
    }
    if (inode.i_file_acl &&
            ((inode.i_file_acl < fs->super->s_first_data_block) ||
             (inode.i_file_acl >= fs->super->s_blocks_count)) &&
            fix_problem(ctx, PR_2_FILE_ACL_BAD, &pctx)) {
        inode.i_file_acl = 0;
        inode_modified++;
    }
    if (inode.i_dir_acl &&
            LINUX_S_ISDIR(inode.i_mode) &&
            fix_problem(ctx, PR_2_DIR_ACL_ZERO, &pctx)) {
        inode.i_dir_acl = 0;
        inode_modified++;
    }
    if (inode_modified)
        e2fsck_write_inode(ctx, ino, &inode, "process_bad_inode");
    return 0;
}