예제 #1
0
static const char *
parse_version_string (const char *s, int *major, int *minor)
{
  s = parse_version_number (s, major);
  if (!s || *s != '.')
    return NULL;
  s++;
  s = parse_version_number (s, minor);
  if (!s)
    return NULL;
  return s;  /* Patchlevel.  */
}
예제 #2
0
const char *
parse_version_string (const char *s, int *major, int *minor, int *micro)
{
  if (!s)
    return NULL;
  *major = parse_version_number (&s);
  if (*s != '.')
    return NULL;
  s++;
  *minor = parse_version_number (&s);
  if (*s != '.')
    return NULL;
  s++;
  *micro = parse_version_number (&s);
  return s;
}
예제 #3
0
/* The parse version functions were copied from libgcrypt.
 */
static const char *
parse_version_string (const char *s, int *major, int *minor, int *micro)
{
  s = parse_version_number (s, major);
  if (!s || *s != '.')
    return NULL;
  s++;
  s = parse_version_number (s, minor);
  if (!s)
    return NULL;
  if (*s != '.')
    {
      *micro = 0;
      return s;
    }
  s++;
  s = parse_version_number (s, micro);
  if (!s)
    return NULL;
  return s;			/* patchlevel */
}
예제 #4
0
파일: mke2fs.c 프로젝트: OPSF/uClinux
static void PRS(int argc, char *argv[])
{
	int		b, c;
	int		size;
	char 		*tmp, *tmp2;
	int		blocksize = 0;
	int		inode_ratio = 0;
	int		inode_size = 0;
	double		reserved_ratio = 5.0;
	int		sector_size = 0;
	int		show_version_only = 0;
	ext2_ino_t	num_inodes = 0;
	errcode_t	retval;
	char *		oldpath = getenv("PATH");
	char *		extended_opts = 0;
	const char *	fs_type = 0;
	blk_t		dev_size;
#ifdef __linux__
	struct 		utsname ut;
#endif
	long		sysval;
	int		s_opt = -1, r_opt = -1;
	char		*fs_features = 0;
	int		use_bsize;

	/* Update our PATH to include /sbin  */
	if (oldpath) {
		char *newpath;
		
		newpath = malloc(sizeof (PATH_SET) + 1 + strlen (oldpath));
		strcpy (newpath, PATH_SET);
		strcat (newpath, ":");
		strcat (newpath, oldpath);
		putenv (newpath);
	} else
		putenv (PATH_SET);

	tmp = getenv("MKE2FS_SYNC");
	if (tmp)
		sync_kludge = atoi(tmp);

	/* Determine the system page size if possible */
#ifdef HAVE_SYSCONF
#if (!defined(_SC_PAGESIZE) && defined(_SC_PAGE_SIZE))
#define _SC_PAGESIZE _SC_PAGE_SIZE
#endif
#ifdef _SC_PAGESIZE
	sysval = sysconf(_SC_PAGESIZE);
	if (sysval > 0)
		sys_page_size = sysval;
#endif /* _SC_PAGESIZE */
#endif /* HAVE_SYSCONF */

	if ((tmp = getenv("MKE2FS_CONFIG")) != NULL)
		config_fn[0] = tmp;
	profile_set_syntax_err_cb(syntax_err_report);
	profile_init(config_fn, &profile);
	
	setbuf(stdout, NULL);
	setbuf(stderr, NULL);
	initialize_ext2_error_table();
	memset(&fs_param, 0, sizeof(struct ext2_super_block));
	fs_param.s_rev_level = 1;  /* Create revision 1 filesystems now */

#ifdef __linux__
	if (uname(&ut)) {
		perror("uname");
		exit(1);
	}
	linux_version_code = parse_version_number(ut.release);
	if (linux_version_code && linux_version_code < (2*65536 + 2*256))
		fs_param.s_rev_level = 0;
#endif

	if (argc && *argv) {
		program_name = get_progname(*argv);

		/* If called as mkfs.ext3, create a journal inode */
		if (!strcmp(program_name, "mkfs.ext3"))
			journal_size = -1;
	}

	while ((c = getopt (argc, argv,
		    "b:cf:g:i:jl:m:no:qr:s:tvE:FI:J:L:M:N:O:R:ST:V")) != EOF) {
		switch (c) {
		case 'b':
			blocksize = strtol(optarg, &tmp, 0);
			b = (blocksize > 0) ? blocksize : -blocksize;
			if (b < EXT2_MIN_BLOCK_SIZE ||
			    b > EXT2_MAX_BLOCK_SIZE || *tmp) {
				com_err(program_name, 0,
					_("invalid block size - %s"), optarg);
				exit(1);
			}
			if (blocksize > 4096)
				fprintf(stderr, _("Warning: blocksize %d not "
						  "usable on most systems.\n"),
					blocksize);
			if (blocksize > 0) 
				fs_param.s_log_block_size =
					int_log2(blocksize >>
						 EXT2_MIN_BLOCK_LOG_SIZE);
			break;
		case 'c':	/* Check for bad blocks */
		case 't':	/* deprecated */
			cflag++;
			break;
		case 'f':
			size = strtoul(optarg, &tmp, 0);
			if (size < EXT2_MIN_BLOCK_SIZE ||
			    size > EXT2_MAX_BLOCK_SIZE || *tmp) {
				com_err(program_name, 0,
					_("invalid fragment size - %s"),
					optarg);
				exit(1);
			}
			fs_param.s_log_frag_size =
				int_log2(size >> EXT2_MIN_BLOCK_LOG_SIZE);
			fprintf(stderr, _("Warning: fragments not supported.  "
			       "Ignoring -f option\n"));
			break;
		case 'g':
			fs_param.s_blocks_per_group = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				com_err(program_name, 0,
					_("Illegal number for blocks per group"));
				exit(1);
			}
			if ((fs_param.s_blocks_per_group % 8) != 0) {
				com_err(program_name, 0,
				_("blocks per group must be multiple of 8"));
				exit(1);
			}
			break;
		case 'i':
			inode_ratio = strtoul(optarg, &tmp, 0);
			if (inode_ratio < EXT2_MIN_BLOCK_SIZE ||
			    inode_ratio > EXT2_MAX_BLOCK_SIZE * 1024 ||
			    *tmp) {
				com_err(program_name, 0,
					_("invalid inode ratio %s (min %d/max %d)"),
					optarg, EXT2_MIN_BLOCK_SIZE,
					EXT2_MAX_BLOCK_SIZE);
				exit(1);
			}
			break;
		case 'J':
			parse_journal_opts(optarg);
			break;
		case 'j':
			if (!journal_size)
				journal_size = -1;
			break;
		case 'l':
			bad_blocks_filename = malloc(strlen(optarg)+1);
			if (!bad_blocks_filename) {
				com_err(program_name, ENOMEM,
					_("in malloc for bad_blocks_filename"));
				exit(1);
			}
			strcpy(bad_blocks_filename, optarg);
			break;
		case 'm':
			reserved_ratio = strtod(optarg, &tmp);
			if (reserved_ratio > 50 || *tmp) {
				com_err(program_name, 0,
					_("invalid reserved blocks percent - %s"),
					optarg);
				exit(1);
			}
			break;
		case 'n':
			noaction++;
			break;
		case 'o':
			creator_os = optarg;
			break;
		case 'q':
			quiet = 1;
			break;
		case 'r':
			r_opt = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				com_err(program_name, 0,
					_("bad revision level - %s"), optarg);
				exit(1);
			}
			fs_param.s_rev_level = r_opt;
			break;
		case 's':	/* deprecated */
			s_opt = atoi(optarg);
			break;
#ifdef EXT2_DYNAMIC_REV
		case 'I':
			inode_size = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				com_err(program_name, 0,
					_("invalid inode size - %s"), optarg);
				exit(1);
			}
			break;
#endif
		case 'v':
			verbose = 1;
			break;
		case 'F':
			force = 1;
			break;
		case 'L':
			volume_label = optarg;
			break;
		case 'M':
			mount_dir = optarg;
			break;
		case 'N':
			num_inodes = strtoul(optarg, &tmp, 0);
			if (*tmp) {
				com_err(program_name, 0,
					_("bad num inodes - %s"), optarg);
					exit(1);
			}
			break;
		case 'O':
			fs_features = optarg;
			break;
		case 'E':
		case 'R':
			extended_opts = optarg;
			break;
		case 'S':
			super_only = 1;
			break;
		case 'T':
			fs_type = optarg;
			break;
		case 'V':
			/* Print version number and exit */
			show_version_only++;
			break;
		default:
			usage();
		}
	}
	if ((optind == argc) && !show_version_only)
		usage();
	device_name = argv[optind++];

	if (!quiet || show_version_only)
		fprintf (stderr, "mke2fs %s (%s)\n", E2FSPROGS_VERSION, 
			 E2FSPROGS_DATE);

	if (show_version_only) {
		fprintf(stderr, _("\tUsing %s\n"), 
			error_message(EXT2_ET_BASE));
		exit(0);
	}

	/*
	 * If there's no blocksize specified and there is a journal
	 * device, use it to figure out the blocksize
	 */
	if (blocksize <= 0 && journal_device) {
		ext2_filsys	jfs;
		io_manager	io_ptr;

#ifdef CONFIG_TESTIO_DEBUG
		io_ptr = test_io_manager;
		test_io_backing_manager = unix_io_manager;
#else
		io_ptr = unix_io_manager;
#endif
		retval = ext2fs_open(journal_device,
				     EXT2_FLAG_JOURNAL_DEV_OK, 0,
				     0, io_ptr, &jfs);
		if (retval) {
			com_err(program_name, retval,
				_("while trying to open journal device %s\n"),
				journal_device);
			exit(1);
		}
		if ((blocksize < 0) && (jfs->blocksize < (unsigned) (-blocksize))) {
			com_err(program_name, 0,
				_("Journal dev blocksize (%d) smaller than "
				  "minimum blocksize %d\n"), jfs->blocksize,
				-blocksize);
			exit(1);
		}
		blocksize = jfs->blocksize;
		fs_param.s_log_block_size =
			int_log2(blocksize >> EXT2_MIN_BLOCK_LOG_SIZE);
		ext2fs_close(jfs);
	}
예제 #5
0
bool ScanDataBuilder::Parse(char*& buffer, size_t& size) {

    char* prev_buf = NULL;
    bool success;
    while (method_index <= 25) {
//        std::cout << "method index: " << method_index <<std::endl;
        prev_buf = buffer;
        switch (method_index) {
        case -1:
            success = parse_byte(buffer, size, lms100_cola::STX_BYTE);
            break;
        case 0:
            success = parse_command_type(buffer, size, data);
            break;
        case 1:
            success = parse_command(buffer, size, data);
            break;
        case 2:
            success = parse_version_number(buffer, size, data);
            break;
        case 3:
            success = parse_device_number(buffer, size, data);
            break;
        case 4:
            success = parse_serial_number(buffer, size, data);
            break;
        case 5:
            success = parse_device_status(buffer, size, data);
            break;
        case 6:
            success = parse_telegram_counter(buffer, size, data);
            break;
        case 7:
            success = parse_scan_counter(buffer, size, data);
            break;
        case 8:
            success = parse_time_since_startup(buffer, size, data);
            break;
        case 9:
            success = parse_time_of_transmission(buffer, size, data);
            break;
        case 10:
            success = parse_status_of_digital_inputs(buffer, size, data);
            break;
        case 11:
            success = parse_status_of_digital_outputs(buffer, size, data);
            break;
        case 12:
            success = parse_reserved_byte(buffer, size, data);
            break;
        case 13:
            success = parse_scan_frequency(buffer, size, data);
            break;
        case 14:
            success = parse_measurement_frequency(buffer, size, data);
            break;
        case 15:
            success = parse_encoders(buffer, size, data);
            break;
        case 16:
            success = parse_amount_of_16_bit_channels(buffer, size, data);
            break;
        case 17:
            success = parse_content(buffer, size, data);
            break;
        case 18:
            success = parse_scale_factor(buffer, size, data);
            break;
        case 19:
            success = parse_scale_factor_offset(buffer, size, data);
            break;
        case 20:
            success = parse_start_angle(buffer, size, data);
            break;
        case 21:
            success = parse_steps(buffer, size, data);
            break;
        case 22:
            success = parse_amount_of_data(buffer, size, data);
            break;
        case 23:
            success = parse_data(buffer, size, data);
            break;
        case 24:
            success = parse_irrelevant_data(buffer, size);
            break;
        case 25:
            success = parse_byte(buffer, size, lms100_cola::ETX_BYTE);
            break;
        default:
            return false;
        }

        // method didn't have enough data to parse
        if (!success) {
            return false;
        }

        method_index += 1;
    }

    return true;
}
예제 #6
0
파일: online.c 프로젝트: djwong/e2fsprogs
errcode_t online_resize_fs(ext2_filsys fs, const char *mtpt,
			   blk64_t *new_size, int flags EXT2FS_ATTR((unused)))
{
#ifdef __linux__
	struct ext2_new_group_input input;
	struct ext4_new_group_input input64;
	struct ext2_super_block *sb = fs->super;
	unsigned long		new_desc_blocks;
	ext2_filsys 		new_fs;
	errcode_t 		retval;
	double			percent;
	dgrp_t			i;
	blk_t			size;
	int			fd, overhead;
	int			use_old_ioctl = 1;
	int			no_meta_bg_resize = 0;
	int			no_resize_ioctl = 0;

	if (getenv("RESIZE2FS_KERNEL_VERSION")) {
		char *version_to_emulate = getenv("RESIZE2FS_KERNEL_VERSION");
		int kvers = parse_version_number(version_to_emulate);

		if (kvers < VERSION_CODE(3, 7, 0))
			no_meta_bg_resize = 1;
		if (kvers < VERSION_CODE(3, 3, 0))
			no_resize_ioctl = 1;
	}

	if (ext2fs_has_feature_sparse_super2(fs->super) &&
	    (access("/sys/fs/ext4/features/sparse_super2", R_OK) != 0)) {
		com_err(program_name, 0, _("kernel does not support online "
					   "resize with sparse_super2"));
		exit(1);
	}

	printf(_("Filesystem at %s is mounted on %s; "
		 "on-line resizing required\n"), fs->device_name, mtpt);

	if (*new_size < ext2fs_blocks_count(sb)) {
		com_err(program_name, 0, _("On-line shrinking not supported"));
		exit(1);
	}

	/*
	 * If the number of descriptor blocks is going to increase,
	 * the on-line resizing inode must be present.
	 */
	new_desc_blocks = ext2fs_div_ceil(
		ext2fs_div64_ceil(*new_size -
				  fs->super->s_first_data_block,
				  EXT2_BLOCKS_PER_GROUP(fs->super)),
		EXT2_DESC_PER_BLOCK(fs->super));
	printf("old_desc_blocks = %lu, new_desc_blocks = %lu\n",
	       fs->desc_blocks, new_desc_blocks);

	/*
	 * Do error checking to make sure the resize will be successful.
	 */
	if ((access("/sys/fs/ext4/features/meta_bg_resize", R_OK) != 0) ||
	    no_meta_bg_resize) {
		if (!ext2fs_has_feature_resize_inode(fs->super) &&
		    (new_desc_blocks != fs->desc_blocks)) {
			com_err(program_name, 0,
				_("Filesystem does not support online resizing"));
			exit(1);
		}

		if (ext2fs_has_feature_resize_inode(fs->super) &&
		    new_desc_blocks > (fs->desc_blocks +
				       fs->super->s_reserved_gdt_blocks)) {
			com_err(program_name, 0,
				_("Not enough reserved gdt blocks for resizing"));
			exit(1);
		}

		if ((ext2fs_blocks_count(sb) > MAX_32_NUM) ||
		    (*new_size > MAX_32_NUM)) {
			com_err(program_name, 0,
				_("Kernel does not support resizing a file system this large"));
			exit(1);
		}
	}

	fd = open(mtpt, O_RDONLY);
	if (fd < 0) {
		com_err(program_name, errno,
			_("while trying to open mountpoint %s"), mtpt);
		exit(1);
	}

	if (no_resize_ioctl) {
		printf(_("Old resize interface requested.\n"));
	} else if (ioctl(fd, EXT4_IOC_RESIZE_FS, new_size)) {
		/*
		 * If kernel does not support EXT4_IOC_RESIZE_FS, use the
		 * old online resize. Note that the old approach does not
		 * handle >32 bit file systems
		 *
		 * Sigh, if we are running a 32-bit binary on a 64-bit
		 * kernel (which happens all the time on the MIPS
		 * architecture in Debian, but can happen on other CPU
		 * architectures as well) we will get EINVAL returned
		 * when an ioctl doesn't exist, at least up to Linux
		 * 3.1.  See compat_sys_ioctl() in fs/compat_ioctl.c
		 * in the kernel sources.  This is probably a kernel
		 * bug, but work around it here.
		 */
		if ((errno != ENOTTY) && (errno != EINVAL)) {
			if (errno == EPERM)
				com_err(program_name, 0,
				_("Permission denied to resize filesystem"));
			else
				com_err(program_name, errno,
				_("While checking for on-line resizing "
				  "support"));
			exit(1);
		}
	} else {
		close(fd);
		return 0;
	}

	size = ext2fs_blocks_count(sb);

	if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
		if (errno == EPERM)
			com_err(program_name, 0,
				_("Permission denied to resize filesystem"));
		else if (errno == ENOTTY)
			com_err(program_name, 0,
			_("Kernel does not support online resizing"));
		else
			com_err(program_name, errno,
			_("While checking for on-line resizing support"));
		exit(1);
	}

	percent = (ext2fs_r_blocks_count(sb) * 100.0) /
		ext2fs_blocks_count(sb);

	retval = ext2fs_read_bitmaps(fs);
	if (retval) {
		close(fd);
		return retval;
	}

	retval = ext2fs_dup_handle(fs, &new_fs);
	if (retval) {
		close(fd);
		return retval;
	}

	/* The current method of adding one block group at a time to a
	 * mounted filesystem means it is impossible to accommodate the
	 * flex_bg allocation method of placing the metadata together
	 * in a single block group.  For now we "fix" this issue by
	 * using the traditional layout for new block groups, where
	 * each block group is self-contained and contains its own
	 * bitmap blocks and inode tables.  This means we don't get
	 * the layout advantages of flex_bg in the new block groups,
	 * but at least it allows on-line resizing to function.
	 */
	ext2fs_clear_feature_flex_bg(new_fs->super);
	retval = adjust_fs_info(new_fs, fs, 0, *new_size);
	if (retval) {
		close(fd);
		return retval;
	}

	printf(_("Performing an on-line resize of %s to %llu (%dk) blocks.\n"),
	       fs->device_name, *new_size, fs->blocksize / 1024);

	size = fs->group_desc_count * sb->s_blocks_per_group +
		sb->s_first_data_block;
	if (size > *new_size)
		size = *new_size;

	if (ioctl(fd, EXT2_IOC_GROUP_EXTEND, &size)) {
		com_err(program_name, errno,
			_("While trying to extend the last group"));
		exit(1);
	}

	for (i = fs->group_desc_count;
	     i < new_fs->group_desc_count; i++) {

		overhead = (int) (2 + new_fs->inode_blocks_per_group);

		if (ext2fs_bg_has_super(new_fs, new_fs->group_desc_count - 1))
			overhead += 1 + new_fs->desc_blocks +
				new_fs->super->s_reserved_gdt_blocks;

		input.group = i;
		input.block_bitmap = ext2fs_block_bitmap_loc(new_fs, i);
		input.inode_bitmap = ext2fs_inode_bitmap_loc(new_fs, i);
		input.inode_table = ext2fs_inode_table_loc(new_fs, i);
		input.blocks_count = ext2fs_group_blocks_count(new_fs, i);
		input.reserved_blocks = (blk_t) (percent * input.blocks_count
						 / 100.0);

#if 0
		printf("new block bitmap is at 0x%04x\n", input.block_bitmap);
		printf("new inode bitmap is at 0x%04x\n", input.inode_bitmap);
		printf("new inode table is at 0x%04x-0x%04x\n",
		       input.inode_table,
		       input.inode_table + new_fs->inode_blocks_per_group-1);
		printf("new group has %u blocks\n", input.blocks_count);
		printf("new group will reserve %d blocks\n",
		       input.reserved_blocks);
		printf("new group has %d free blocks\n",
		       ext2fs_bg_free_blocks_count(new_fs, i),
		printf("new group has %d free inodes (%d blocks)\n",
		       ext2fs_bg_free_inodes_count(new_fs, i),
		       new_fs->inode_blocks_per_group);
		printf("Adding group #%d\n", input.group);
#endif

		if (use_old_ioctl &&
		    ioctl(fd, EXT2_IOC_GROUP_ADD, &input) == 0)
			continue;
		else
			use_old_ioctl = 0;

		input64.group = input.group;
		input64.block_bitmap = input.block_bitmap;
		input64.inode_bitmap = input.inode_bitmap;
		input64.inode_table = input.inode_table;
		input64.blocks_count = input.blocks_count;
		input64.reserved_blocks = input.reserved_blocks;
		input64.unused = input.unused;

		if (ioctl(fd, EXT4_IOC_GROUP_ADD, &input64) < 0) {
			com_err(program_name, errno,
				_("While trying to add group #%d"),
				input.group);
			exit(1);
		}
	}

	ext2fs_free(new_fs);
	close(fd);

	return 0;
#else
	printf(_("Filesystem at %s is mounted on %s, and on-line resizing is "
		 "not supported on this system.\n"), fs->device_name, mtpt);
	exit(1);
#endif
}