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. */ }
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; }
/* 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 */ }
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); }
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; }
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 }