source: rtems/cpukit/libmisc/shell/fdisk.c @ 255fe43

Last change on this file since 255fe43 was 255fe43, checked in by Joel Sherrill <joel@…>, on 03/01/22 at 20:40:44

cpukit/: Scripted embedded brains header file clean up

Updates #4625.

  • Property mode set to 100644
File size: 6.8 KB
Line 
1/**
2 * @file
3 *
4 * Block device partition management.
5 */
6
7/*
8 * Copyright (c) 2009, 2020
9 *
10 * The license and distribution terms for this file may be
11 * found in the file LICENSE in this distribution or at
12 * http://www.rtems.org/license/LICENSE.
13 */
14
15#ifdef HAVE_CONFIG_H
16#include "config.h"
17#endif
18
19#include <stdio.h>
20#include <stdlib.h>
21#include <string.h>
22
23#include <rtems/bdpart.h>
24#include <rtems/error.h>
25#include <rtems/shell.h>
26
27#define RTEMS_BDPART_SHELL_ERROR( fmt, ...) \
28  do { \
29    printf( "error: " fmt "\n", ##__VA_ARGS__); \
30    return -1; \
31  } while (0)
32
33#define RTEMS_BDPART_SHELL_ERROR_SC( sc, fmt, ...) \
34  if ((sc) != RTEMS_SUCCESSFUL) { \
35    printf( "error: " fmt ": %s\n", ##__VA_ARGS__, rtems_status_text( sc)); \
36    return -1; \
37  }
38
39typedef enum {
40  RTEMS_BDPART_SHELL_FS,
41  RTEMS_BDPART_SHELL_N,
42  RTEMS_BDPART_SHELL_MBR,
43  RTEMS_BDPART_SHELL_GPT
44} rtems_bdpart_shell_state;
45
46static const char rtems_bdpart_shell_usage [] =
47  "disk format and utility functions\n"
48  "\n"
49  "fdisk DISK_NAME\n"
50  "\tprints the partition table\n"
51  "\n"
52  "fdisk DISK_NAME [FS N1 [N2 ... ]] ... [write] [FORMAT]\n"
53  "\tcreates a new partition table\n"
54  "\n"
55  "fdisk DISK_NAME register\n"
56  "\tcreates a logical disk for each partition of the disk\n"
57  "\n"
58  "fdisk DISK_NAME unregister\n"
59  "\tdeletes the logical disks associated with the partitions\n"
60  "\tof the disk\n"
61  "\n"
62  "option values:\n"
63  "\tDISK_NAME: absolute path to disk device like '/dev/hda'\n"
64  "\tN*: weights of positive integers\n"
65  "\tFS: 0x00 ... 0xff, fat12, fat16, fat32, data\n"
66  "\twrite: write the new partition table to the disk\n"
67  "\tFORMAT: mbr [[no]dos], gpt";
68
69static int rtems_bdpart_shell_main( int argc, char **argv)
70{
71  rtems_status_code sc = RTEMS_SUCCESSFUL;
72  rtems_bdpart_format format;
73  rtems_bdpart_partition pt [RTEMS_BDPART_PARTITION_NUMBER_HINT];
74  unsigned dist [RTEMS_BDPART_PARTITION_NUMBER_HINT];
75  size_t count = RTEMS_BDPART_PARTITION_NUMBER_HINT;
76  const char *disk_name = NULL;
77  bool do_create = false;
78  bool do_read = false;
79  bool do_write = false;
80  bool do_register = false;
81  bool do_unregister = false;
82  bool do_dump = false;
83
84  if (argc < 2) {
85    puts( rtems_bdpart_shell_usage);
86    return -1;
87  }
88
89  disk_name = argv [1];
90
91  if (argc == 2) {
92    do_read = true;
93    do_dump = true;
94  } else if (argc == 3) {
95    /* Check option */
96    if (strcmp( argv [2], "register") == 0) {
97      do_read = true;
98      do_register = true;
99    } else if (strcmp( argv [2], "unregister") == 0) {
100      do_read = true;
101      do_unregister = true;
102    } else {
103      RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [2]);
104    }
105  } else {
106    rtems_bdpart_shell_state state = RTEMS_BDPART_SHELL_FS;
107    uint8_t current_type = RTEMS_BDPART_MBR_FAT_32;
108    size_t i = 0;
109    int ai = 0;
110
111    /* Clear partition table */
112    memset( pt, 0, sizeof( pt));
113
114    /* Default format */
115    format.type = RTEMS_BDPART_FORMAT_MBR;
116    format.mbr.disk_id = 0;
117    format.mbr.dos_compatibility = true;
118
119    for (ai = 2; ai < argc; ++ai) {
120      char *s = argv [ai];
121      unsigned long v = 0;
122      char *end = NULL;
123
124      if (strlen( s) == 0) {
125        continue;
126      } else if (strcmp( s, "write") == 0) {
127        do_write = true;
128        continue;
129      } else if (strcmp( s, "mbr") == 0) {
130        state = RTEMS_BDPART_SHELL_MBR;
131        format.type = RTEMS_BDPART_FORMAT_MBR;
132        continue;
133      } else if (strcmp( s, "gpt") == 0) {
134        state = RTEMS_BDPART_SHELL_GPT;
135        format.type = RTEMS_BDPART_FORMAT_GPT;
136        continue;
137      }
138
139      switch (state) {
140        case RTEMS_BDPART_SHELL_FS:
141          v = strtoul( s, &end, 16);
142          if (*end == '\0') {
143            if (v <= 0xffU) {
144              current_type = (uint8_t) v;
145            } else {
146              RTEMS_BDPART_SHELL_ERROR( "type value out of range: %s", argv [ai]);
147            }
148          } else if (strcmp( s, "fat32") == 0) {
149            current_type = RTEMS_BDPART_MBR_FAT_32;
150          } else if (strcmp( s, "data") == 0) {
151            current_type = RTEMS_BDPART_MBR_DATA;
152          } else if (strcmp( s, "fat16") == 0) {
153            current_type = RTEMS_BDPART_MBR_FAT_16;
154          } else if (strcmp( s, "fat12") == 0) {
155            current_type = RTEMS_BDPART_MBR_FAT_12;
156          } else {
157            RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]);
158          }
159          state = RTEMS_BDPART_SHELL_N;
160          break;
161        case RTEMS_BDPART_SHELL_N:
162          v = strtoul( s, &end, 10);
163          if (*end == '\0') {
164            rtems_bdpart_to_partition_type( current_type, pt [i].type);
165            dist [i] = v;
166            if (i < count) {
167              ++i;
168            } else {
169              RTEMS_BDPART_SHELL_ERROR( "too many partitions");
170            }
171          } else {
172            --ai;
173            state = RTEMS_BDPART_SHELL_FS;
174          }
175          break;
176        case RTEMS_BDPART_SHELL_MBR:
177          if (strcmp( s, "dos") == 0) {
178            format.mbr.dos_compatibility = true;
179          } else if (strcmp( s, "nodos") == 0) {
180            format.mbr.dos_compatibility = false;
181          } else {
182            RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]);
183          }
184          break;
185        case RTEMS_BDPART_SHELL_GPT:
186          RTEMS_BDPART_SHELL_ERROR( "unexpected option: %s", argv [ai]);
187        default:
188          RTEMS_BDPART_SHELL_ERROR( "fdisk interal error");
189      }
190    }
191
192    /* Partition number */
193    count = i;
194
195    /* Actions */
196    do_create = true;
197    do_dump = true;
198    if (do_write) {
199      do_read = true;
200    }
201  }
202
203  if (do_create) {
204    /* Create partitions */
205    sc = rtems_bdpart_create( disk_name, &format, pt, dist, count);
206    RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot create partitions for '%s'", disk_name);
207  }
208
209  if (do_write) {
210    /* Write partitions */
211    sc = rtems_bdpart_write( disk_name, &format, pt, count);
212    RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot write partitions to '%s'", disk_name);
213  }
214
215  if (do_read) {
216    /* Read partitions */
217    count = RTEMS_BDPART_PARTITION_NUMBER_HINT;
218    sc = rtems_bdpart_read( disk_name, &format, pt, &count);
219    RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot read partitions from '%s'", disk_name);
220  }
221
222  if (do_register) {
223    /* Register partitions */
224    sc = rtems_bdpart_register( disk_name, pt, count);
225    RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot register partitions of '%s'", disk_name);
226  }
227
228  if (do_unregister) {
229    /* Unregister partitions */
230    sc = rtems_bdpart_unregister( disk_name, pt, count);
231    RTEMS_BDPART_SHELL_ERROR_SC( sc, "cannot unregister partitions of '%s'", disk_name);
232  }
233
234  if (do_dump) {
235    /* Dump partitions */
236    rtems_bdpart_dump( pt, count);
237  }
238
239  return 0;
240}
241
242struct rtems_shell_cmd_tt rtems_shell_FDISK_Command = {
243  .name = "fdisk",
244  .usage = rtems_bdpart_shell_usage,
245  .topic = "files",
246  .command = rtems_bdpart_shell_main,
247  .alias = NULL,
248  .next = NULL
249};
Note: See TracBrowser for help on using the repository browser.