source: rtems/cpukit/libmisc/shell/fdisk.c @ c499856

4.115
Last change on this file since c499856 was c499856, checked in by Chris Johns <chrisj@…>, on 03/20/14 at 21:10:47

Change all references of rtems.com to rtems.org.

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