File indexing completed on 2025-05-11 08:24:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifdef HAVE_CONFIG_H
0016 #include "config.h"
0017 #endif
0018
0019 #include <stdio.h>
0020 #include <stdlib.h>
0021 #include <string.h>
0022
0023 #include <rtems/bdpart.h>
0024 #include <rtems/error.h>
0025 #include <rtems/shell.h>
0026
0027 #define RTEMS_BDPART_SHELL_ERROR( fmt, ...) \
0028 do { \
0029 printf( "error: " fmt "\n", ##__VA_ARGS__); \
0030 return -1; \
0031 } while (0)
0032
0033 #define RTEMS_BDPART_SHELL_ERROR_SC( sc, fmt, ...) \
0034 if ((sc) != RTEMS_SUCCESSFUL) { \
0035 printf( "error: " fmt ": %s\n", ##__VA_ARGS__, rtems_status_text( sc)); \
0036 return -1; \
0037 }
0038
0039 typedef enum {
0040 RTEMS_BDPART_SHELL_FS,
0041 RTEMS_BDPART_SHELL_N,
0042 RTEMS_BDPART_SHELL_MBR,
0043 RTEMS_BDPART_SHELL_GPT
0044 } rtems_bdpart_shell_state;
0045
0046 static const char rtems_bdpart_shell_usage [] =
0047 "disk format and utility functions\n"
0048 "\n"
0049 "fdisk DISK_NAME\n"
0050 "\tprints the partition table\n"
0051 "\n"
0052 "fdisk DISK_NAME [FS N1 [N2 ... ]] ... [write] [FORMAT]\n"
0053 "\tcreates a new partition table\n"
0054 "\n"
0055 "fdisk DISK_NAME register\n"
0056 "\tcreates a logical disk for each partition of the disk\n"
0057 "\n"
0058 "fdisk DISK_NAME unregister\n"
0059 "\tdeletes the logical disks associated with the partitions\n"
0060 "\tof the disk\n"
0061 "\n"
0062 "option values:\n"
0063 "\tDISK_NAME: absolute path to disk device like '/dev/hda'\n"
0064 "\tN*: weights of positive integers\n"
0065 "\tFS: 0x00 ... 0xff, fat12, fat16, fat32, data\n"
0066 "\twrite: write the new partition table to the disk\n"
0067 "\tFORMAT: mbr [[no]dos], gpt";
0068
0069 static int rtems_bdpart_shell_main( int argc, char **argv)
0070 {
0071 rtems_status_code sc = RTEMS_SUCCESSFUL;
0072 rtems_bdpart_format format;
0073 rtems_bdpart_partition pt [RTEMS_BDPART_PARTITION_NUMBER_HINT];
0074 unsigned dist [RTEMS_BDPART_PARTITION_NUMBER_HINT];
0075 size_t count = RTEMS_BDPART_PARTITION_NUMBER_HINT;
0076 const char *disk_name = NULL;
0077 bool do_create = false;
0078 bool do_read = false;
0079 bool do_write = false;
0080 bool do_register = false;
0081 bool do_unregister = false;
0082 bool do_dump = false;
0083
0084 if (argc < 2) {
0085 puts( rtems_bdpart_shell_usage);
0086 return -1;
0087 }
0088
0089 disk_name = argv [1];
0090
0091 if (argc == 2) {
0092 do_read = true;
0093 do_dump = true;
0094 } else if (argc == 3) {
0095
0096 if (strcmp( argv [2], "register") == 0) {
0097 do_read = true;
0098 do_register = true;
0099 } else if (strcmp( argv [2], "unregister") == 0) {
0100 do_read = true;
0101 do_unregister = true;
0102 } else {
0103 RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [2]);
0104 }
0105 } else {
0106 rtems_bdpart_shell_state state = RTEMS_BDPART_SHELL_FS;
0107 uint8_t current_type = RTEMS_BDPART_MBR_FAT_32;
0108 size_t i = 0;
0109 int ai = 0;
0110
0111
0112 memset( pt, 0, sizeof( pt));
0113
0114
0115 format.type = RTEMS_BDPART_FORMAT_MBR;
0116 format.mbr.disk_id = 0;
0117 format.mbr.dos_compatibility = true;
0118
0119 for (ai = 2; ai < argc; ++ai) {
0120 char *s = argv [ai];
0121 unsigned long v = 0;
0122 char *end = NULL;
0123
0124 if (strlen( s) == 0) {
0125 continue;
0126 } else if (strcmp( s, "write") == 0) {
0127 do_write = true;
0128 continue;
0129 } else if (strcmp( s, "mbr") == 0) {
0130 state = RTEMS_BDPART_SHELL_MBR;
0131 format.type = RTEMS_BDPART_FORMAT_MBR;
0132 continue;
0133 } else if (strcmp( s, "gpt") == 0) {
0134 state = RTEMS_BDPART_SHELL_GPT;
0135 format.type = RTEMS_BDPART_FORMAT_GPT;
0136 continue;
0137 }
0138
0139 switch (state) {
0140 case RTEMS_BDPART_SHELL_FS:
0141 v = strtoul( s, &end, 16);
0142 if (*end == '\0') {
0143 if (v <= 0xffU) {
0144 current_type = (uint8_t) v;
0145 } else {
0146 RTEMS_BDPART_SHELL_ERROR( "type value out of range: %s", argv [ai]);
0147 }
0148 } else if (strcmp( s, "fat32") == 0) {
0149 current_type = RTEMS_BDPART_MBR_FAT_32;
0150 } else if (strcmp( s, "data") == 0) {
0151 current_type = RTEMS_BDPART_MBR_DATA;
0152 } else if (strcmp( s, "fat16") == 0) {
0153 current_type = RTEMS_BDPART_MBR_FAT_16;
0154 } else if (strcmp( s, "fat12") == 0) {
0155 current_type = RTEMS_BDPART_MBR_FAT_12;
0156 } else {
0157 RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]);
0158 }
0159 state = RTEMS_BDPART_SHELL_N;
0160 break;
0161 case RTEMS_BDPART_SHELL_N:
0162 v = strtoul( s, &end, 10);
0163 if (*end == '\0') {
0164 rtems_bdpart_to_partition_type( current_type, pt [i].type);
0165 dist [i] = v;
0166 if (i < count) {
0167 ++i;
0168 } else {
0169 RTEMS_BDPART_SHELL_ERROR( "too many partitions");
0170 }
0171 } else {
0172 --ai;
0173 state = RTEMS_BDPART_SHELL_FS;
0174 }
0175 break;
0176 case RTEMS_BDPART_SHELL_MBR:
0177 if (strcmp( s, "dos") == 0) {
0178 format.mbr.dos_compatibility = true;
0179 } else if (strcmp( s, "nodos") == 0) {
0180 format.mbr.dos_compatibility = false;
0181 } else {
0182 RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]);
0183 }
0184 break;
0185 case RTEMS_BDPART_SHELL_GPT:
0186 RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]);
0187 default:
0188 RTEMS_BDPART_SHELL_ERROR( "fdisk interal error");
0189 }
0190 }
0191
0192
0193 count = i;
0194
0195
0196 do_create = true;
0197 do_dump = true;
0198 if (do_write) {
0199 do_read = true;
0200 }
0201 }
0202
0203 if (do_create) {
0204
0205 sc = rtems_bdpart_create( disk_name, &format, pt, dist, count);
0206 RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot create partitions for '%s'", disk_name);
0207 }
0208
0209 if (do_write) {
0210
0211 sc = rtems_bdpart_write( disk_name, &format, pt, count);
0212 RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot write partitions to '%s'", disk_name);
0213 }
0214
0215 if (do_read) {
0216
0217 count = RTEMS_BDPART_PARTITION_NUMBER_HINT;
0218 sc = rtems_bdpart_read( disk_name, &format, pt, &count);
0219 RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot read partitions from '%s'", disk_name);
0220 }
0221
0222 if (do_register) {
0223
0224 sc = rtems_bdpart_register( disk_name, pt, count);
0225 RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot register partitions of '%s'", disk_name);
0226 }
0227
0228 if (do_unregister) {
0229
0230 sc = rtems_bdpart_unregister( disk_name, pt, count);
0231 RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot unregister partitions of '%s'", disk_name);
0232 }
0233
0234 if (do_dump) {
0235
0236 rtems_bdpart_dump( pt, count);
0237 }
0238
0239 return 0;
0240 }
0241
0242 struct rtems_shell_cmd_tt rtems_shell_FDISK_Command = {
0243 .name = "fdisk",
0244 .usage = rtems_bdpart_shell_usage,
0245 .topic = "files",
0246 .command = rtems_bdpart_shell_main,
0247 .alias = NULL,
0248 .next = NULL
0249 };