source: rtems/cpukit/libmisc/shell/fdisk.c @ 834df50

4.104.115
Last change on this file since 834df50 was 834df50, checked in by Thomas Doerfler <Thomas.Doerfler@…>, on May 5, 2009 at 12:53:41 PM

New files

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