diff options
author | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2009-05-05 12:53:41 +0000 |
---|---|---|
committer | Thomas Doerfler <Thomas.Doerfler@embedded-brains.de> | 2009-05-05 12:53:41 +0000 |
commit | 834df50c906689b7e6f2652b664a852bd53fe760 (patch) | |
tree | 21ccdeb62df806d2db07f56a3d09b9f5ea92ec7f /cpukit/libmisc | |
parent | Update (diff) | |
download | rtems-834df50c906689b7e6f2652b664a852bd53fe760.tar.bz2 |
New files
Diffstat (limited to 'cpukit/libmisc')
-rw-r--r-- | cpukit/libmisc/shell/fdisk.c | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/cpukit/libmisc/shell/fdisk.c b/cpukit/libmisc/shell/fdisk.c new file mode 100644 index 0000000000..8405e70d4a --- /dev/null +++ b/cpukit/libmisc/shell/fdisk.c @@ -0,0 +1,276 @@ +/** + * @file + * + * Block device partition management. + */ + +/* + * Copyright (c) 2009 + * embedded brains GmbH + * Obere Lagerstr. 30 + * D-82178 Puchheim + * Germany + * <rtems@embedded-brains.de> + * + * The license and distribution terms for this file may be + * found in the file LICENSE in this distribution or at + * http://www.rtems.com/license/LICENSE. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <rtems/bdpart.h> +#include <rtems/error.h> +#include <rtems/shell.h> + +#define RTEMS_BDPART_SHELL_ERROR( fmt, ...) \ + do { \ + printf( "error: " fmt "\n", ##__VA_ARGS__); \ + return -1; \ + } while (0) + +#define RTEMS_BDPART_SHELL_ERROR_SC( sc, fmt, ...) \ + if ((sc) != RTEMS_SUCCESSFUL) { \ + printf( "error: " fmt ": %s\n", ##__VA_ARGS__, rtems_status_text( sc)); \ + return -1; \ + } + +typedef enum { + RTEMS_BDPART_SHELL_FS, + RTEMS_BDPART_SHELL_N, + RTEMS_BDPART_SHELL_MBR, + RTEMS_BDPART_SHELL_GPT +} rtems_bdpart_shell_state; + +static const char rtems_bdpart_shell_usage [] = + "disk format and utility functions\n" + "\n" + "fdisk DISK_NAME\n" + "\tprints the partition table\n" + "\n" + "fdisk DISK_NAME [FS N1 [N2 ... ]] ... [write] [FORMAT]\n" + "\tcreates a new partition table\n" + "\n" + "fdisk DISK_NAME register\n" + "\tcreates a logical disk for each partition of the disk\n" + "\n" + "fdisk DISK_NAME unregister\n" + "\tdeletes the logical disks associated with the partitions of the disk\n" + "\n" + "fdisk DISK_NAME mount\n" + "\tmounts the file system of each partition of the disk\n" + "\n" + "fdisk DISK_NAME unmount\n" + "\tunmounts the file system of each partition of the disk\n" + "\n" + "option values:\n" + "\tDISK_NAME: absolute path to disk device like '/dev/hda'\n" + "\tN*: weights of positive integers\n" + "\tFS: 0x00 ... 0xff, fat12, fat16, fat32, data\n" + "\twrite: write the new partition table to the disk\n" + "\tFORMAT: mbr [[no]dos], gpt"; + +static int rtems_bdpart_shell_main( int argc, char **argv) +{ + rtems_status_code sc = RTEMS_SUCCESSFUL; + rtems_bdpart_format format; + rtems_bdpart_partition pt [RTEMS_BDPART_PARTITION_NUMBER_HINT]; + unsigned dist [RTEMS_BDPART_PARTITION_NUMBER_HINT]; + size_t count = RTEMS_BDPART_PARTITION_NUMBER_HINT; + const char *disk_name = NULL; + const char *mount_base = "/mnt"; + bool do_create = false; + bool do_read = false; + bool do_write = false; + bool do_register = false; + bool do_unregister = false; + bool do_mount = false; + bool do_unmount = false; + bool do_dump = false; + + if (argc < 2) { + puts( rtems_bdpart_shell_usage); + return -1; + } + + disk_name = argv [1]; + + if (argc == 2) { + do_read = true; + do_dump = true; + } else if (argc == 3) { + /* Check option */ + if (strcmp( argv [2], "register") == 0) { + do_read = true; + do_register = true; + } else if (strcmp( argv [2], "unregister") == 0) { + do_read = true; + do_unregister = true; + } else if (strcmp( argv [2], "mount") == 0) { + do_read = true; + do_mount = true; + } else if (strcmp( argv [2], "unmount") == 0) { + do_read = true; + do_unmount = true; + } else { + RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [2]); + } + } else { + rtems_bdpart_shell_state state = RTEMS_BDPART_SHELL_FS; + uint8_t current_type = RTEMS_BDPART_MBR_FAT_32; + size_t i = 0; + int ai = 0; + + /* Clear partition table */ + memset( pt, 0, sizeof( pt)); + + /* Default format */ + format.type = RTEMS_BDPART_FORMAT_MBR; + format.mbr.disk_id = 0; + format.mbr.dos_compatibility = true; + + for (ai = 2; ai < argc; ++ai) { + char *s = argv [ai]; + unsigned long v = 0; + char *end = NULL; + + if (strlen( s) == 0) { + continue; + } else if (strcmp( s, "write") == 0) { + do_write = true; + continue; + } else if (strcmp( s, "mbr") == 0) { + state = RTEMS_BDPART_SHELL_MBR; + format.type = RTEMS_BDPART_FORMAT_MBR; + continue; + } else if (strcmp( s, "gpt") == 0) { + state = RTEMS_BDPART_SHELL_GPT; + format.type = RTEMS_BDPART_FORMAT_GPT; + continue; + } + + switch (state) { + case RTEMS_BDPART_SHELL_FS: + v = strtoul( s, &end, 16); + if (*end == '\0') { + if (v <= 0xffU) { + current_type = (uint8_t) v; + } else { + RTEMS_BDPART_SHELL_ERROR( "type value out of range: %s", argv [ai]); + } + } else if (strcmp( s, "fat32") == 0) { + current_type = RTEMS_BDPART_MBR_FAT_32; + } else if (strcmp( s, "data") == 0) { + current_type = RTEMS_BDPART_MBR_DATA; + } else if (strcmp( s, "fat16") == 0) { + current_type = RTEMS_BDPART_MBR_FAT_16; + } else if (strcmp( s, "fat12") == 0) { + current_type = RTEMS_BDPART_MBR_FAT_12; + } else { + RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]); + } + state = RTEMS_BDPART_SHELL_N; + break; + case RTEMS_BDPART_SHELL_N: + v = strtoul( s, &end, 10); + if (*end == '\0') { + rtems_bdpart_to_partition_type( current_type, pt [i].type); + dist [i] = v; + if (i < count) { + ++i; + } else { + RTEMS_BDPART_SHELL_ERROR( "too many partitions"); + } + } else { + --ai; + state = RTEMS_BDPART_SHELL_FS; + } + break; + case RTEMS_BDPART_SHELL_MBR: + if (strcmp( s, "dos") == 0) { + format.mbr.dos_compatibility = true; + } else if (strcmp( s, "nodos") == 0) { + format.mbr.dos_compatibility = false; + } else { + RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]); + } + break; + case RTEMS_BDPART_SHELL_GPT: + RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]); + default: + RTEMS_BDPART_SHELL_ERROR( "fdisk interal error"); + } + } + + /* Partition number */ + count = i; + + /* Actions */ + do_create = true; + do_dump = true; + if (do_write) { + do_read = true; + } + } + + if (do_create) { + /* Create partitions */ + sc = rtems_bdpart_create( disk_name, &format, pt, dist, count); + RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot create partitions for '%s'", disk_name); + } + + if (do_write) { + /* Write partitions */ + sc = rtems_bdpart_write( disk_name, &format, pt, count); + RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot write partitions to '%s'", disk_name); + } + + if (do_read) { + /* Read partitions */ + count = RTEMS_BDPART_PARTITION_NUMBER_HINT; + sc = rtems_bdpart_read( disk_name, &format, pt, &count); + RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot read partitions from '%s'", disk_name); + } + + if (do_register) { + /* Register partitions */ + sc = rtems_bdpart_register( disk_name, pt, count); + RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot register partitions of '%s'", disk_name); + } + + if (do_unregister) { + /* Unregister partitions */ + sc = rtems_bdpart_unregister( disk_name, pt, count); + RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot unregister partitions of '%s'", disk_name); + } + + if (do_mount) { + /* Mount partitions */ + sc = rtems_bdpart_mount( disk_name, pt, count, mount_base); + RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot mount partitions of '%s' to '%s'", disk_name, mount_base); + } + + if (do_unmount) { + /* Unmount partitions */ + sc = rtems_bdpart_unmount( disk_name, pt, count, mount_base); + RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot unmount partitions of '%s'", disk_name); + } + + if (do_dump) { + /* Dump partitions */ + rtems_bdpart_dump( pt, count); + } + + return 0; +} + +struct rtems_shell_cmd_tt rtems_shell_FDISK_Command = { + .name = "fdisk", + .usage = rtems_bdpart_shell_usage, + .topic = "files", + .command = rtems_bdpart_shell_main, + .alias = NULL, + .next = NULL +}; |