~ubuntu-branches/ubuntu/trusty/gdisk/trusty-proposed

« back to all changes in this revision

Viewing changes to gdisk.cc

  • Committer: Bazaar Package Importer
  • Author(s): Guillaume Delacour
  • Date: 2009-12-01 21:04:25 UTC
  • Revision ID: james.westby@ubuntu.com-20091201210425-lznlvi764r2dwkf8
Tags: upstream-0.5.1
ImportĀ upstreamĀ versionĀ 0.5.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// gdisk.cc
 
2
// Program modelled after Linux fdisk, but it manipulates GPT partitions
 
3
// rather than MBR partitions.
 
4
//
 
5
// by Rod Smith, project began February 2009
 
6
 
 
7
/* This program is copyright (c) 2009 by Roderick W. Smith. It is distributed
 
8
  under the terms of the GNU GPL version 2, as detailed in the COPYING file. */
 
9
 
 
10
//#include <iostream>
 
11
#include <stdio.h>
 
12
#include <string.h>
 
13
#include <getopt.h>
 
14
#include "mbr.h"
 
15
#include "gpt.h"
 
16
#include "support.h"
 
17
 
 
18
// Function prototypes....
 
19
// int ReadPartitions(char* filename, struct GPTData* theGPT);
 
20
void MainMenu(char* filename, struct GPTData* theGPT);
 
21
void ShowCommands(void);
 
22
void ExpertsMenu(char* filename, struct GPTData* theGPT);
 
23
void ShowExpertCommands(void);
 
24
void RecoveryMenu(char* filename, struct GPTData* theGPT);
 
25
void ShowRecoveryCommands(void);
 
26
 
 
27
int main(int argc, char* argv[]) {
 
28
   GPTData theGPT;
 
29
   int doMore = 1;
 
30
   char* device = NULL;
 
31
 
 
32
   printf("GPT fdisk (gdisk) version 0.5.1\n\n");
 
33
 
 
34
    if (argc == 2) { // basic usage
 
35
      if (SizesOK()) {
 
36
         doMore = theGPT.LoadPartitions(argv[1]);
 
37
         if (doMore) {
 
38
            MainMenu(argv[1], &theGPT);
 
39
         } // if (doMore)
 
40
      } // if (SizesOK())
 
41
   } else if (argc == 3) { // usage with "-l" option
 
42
      if (SizesOK()) {
 
43
         if (strcmp(argv[1], "-l") == 0) {
 
44
            device = argv[2];
 
45
         } else if (strcmp(argv[2], "-l") == 0) {
 
46
            device = argv[1];
 
47
         } else { // 3 arguments, but none is "-l"
 
48
            fprintf(stderr, "Usage: %s [-l] device_file\n", argv[0]);
 
49
         } // if/elseif/else
 
50
         if (device != NULL) {
 
51
            doMore = theGPT.LoadPartitions(device);
 
52
            if (doMore) theGPT.DisplayGPTData();
 
53
         } // if
 
54
      } // if
 
55
   } else {
 
56
      fprintf(stderr, "Usage: %s [-l] device_file\n", argv[0]);
 
57
   } // if/else
 
58
} // main
 
59
 
 
60
// Accept a command and execute it. Returns only when the user
 
61
// wants to exit (such as after a 'w' or 'q' command).
 
62
void MainMenu(char* filename, struct GPTData* theGPT) {
 
63
   char command, line[255], buFile[255];
 
64
   int goOn = 1;
 
65
   PartTypes typeHelper;
 
66
   uint32_t temp1, temp2;
 
67
 
 
68
   do {
 
69
      printf("\nCommand (? for help): ");
 
70
      fgets(line, 255, stdin);
 
71
      sscanf(line, "%c", &command);
 
72
      switch (command) {
 
73
         case 'b': case 'B':
 
74
            printf("Enter backup filename to save: ");
 
75
            fgets(line, 255, stdin);
 
76
            sscanf(line, "%s", &buFile);
 
77
            theGPT->SaveGPTBackup(buFile);
 
78
            break;
 
79
         case 'c': case 'C':
 
80
            if (theGPT->GetPartRange(&temp1, &temp2) > 0)
 
81
               theGPT->SetName(theGPT->GetPartNum());
 
82
            else
 
83
               printf("No partitions\n");
 
84
            break;
 
85
         case 'd': case 'D':
 
86
            theGPT->DeletePartition();
 
87
            break;
 
88
         case 'i': case 'I':
 
89
            theGPT->ShowDetails();
 
90
            break;
 
91
         case 'l': case 'L':
 
92
            typeHelper.ShowTypes();
 
93
            break;
 
94
         case 'n': case 'N':
 
95
            theGPT->CreatePartition();
 
96
            break;
 
97
         case 'o': case 'O':
 
98
            printf("This option deletes all partitions and creates a new "
 
99
                  "protective MBR.\nProceed? ");
 
100
            if (GetYN() == 'Y') {
 
101
               theGPT->ClearGPTData();
 
102
               theGPT->MakeProtectiveMBR();
 
103
            } // if
 
104
            break;
 
105
         case 'p': case 'P':
 
106
            theGPT->DisplayGPTData();
 
107
            break;
 
108
         case 'q': case 'Q':
 
109
            goOn = 0;
 
110
            break;
 
111
         case 'r': case 'R':
 
112
            RecoveryMenu(filename, theGPT);
 
113
            goOn = 0;
 
114
            break;
 
115
         case 's': case 'S':
 
116
            theGPT->SortGPT();
 
117
            printf("You may need to edit /etc/fstab and/or your boot loader configuration!\n");
 
118
            break;
 
119
         case 't': case 'T':
 
120
            theGPT->ChangePartType();
 
121
            break;
 
122
         case 'v': case 'V':
 
123
            if (theGPT->Verify() > 0) { // problems found
 
124
               printf("You may be able to correct the problems by using options on the experts\n"
 
125
                     "menu (press 'x' at the command prompt). Good luck!\n");
 
126
            } // if
 
127
            break;
 
128
         case 'w': case 'W':
 
129
            if (theGPT->SaveGPTData() == 1)
 
130
               goOn = 0;
 
131
            break;
 
132
         case 'x': case 'X':
 
133
            ExpertsMenu(filename, theGPT);
 
134
            goOn = 0;
 
135
            break;
 
136
         default:
 
137
            ShowCommands();
 
138
            break;
 
139
      } // switch
 
140
   } while (goOn);
 
141
} // MainMenu()
 
142
 
 
143
void ShowCommands(void) {
 
144
   printf("b\tback up GPT data to a file\n");
 
145
   printf("c\tchange a partition's name\n");
 
146
   printf("d\tdelete a partition\n");
 
147
   printf("i\tshow detailed information on a partition\n");
 
148
   printf("l\tlist known partition types\n");
 
149
   printf("n\tadd a new partition\n");
 
150
   printf("o\tcreate a new empty GUID partition table (GPT)\n");
 
151
   printf("p\tprint the partition table\n");
 
152
   printf("q\tquit without saving changes\n");
 
153
   printf("r\trecovery and transformation options (experts only)\n");
 
154
   printf("s\tsort partitions\n");
 
155
   printf("t\tchange a partition's type code\n");
 
156
   printf("v\tverify disk\n");
 
157
   printf("w\twrite table to disk and exit\n");
 
158
   printf("x\textra functionality (experts only)\n");
 
159
   printf("?\tprint this menu\n");
 
160
} // ShowCommands()
 
161
 
 
162
// Accept a recovery & transformation menu command. Returns only when the user
 
163
// issues an exit command, such as 'w' or 'q'.
 
164
void RecoveryMenu(char* filename, struct GPTData* theGPT) {
 
165
   char command, line[255], buFile[255];
 
166
   PartTypes typeHelper;
 
167
   uint32_t temp1;
 
168
   int goOn = 1;
 
169
 
 
170
   do {
 
171
      printf("\nrecovery/transformation command (? for help): ");
 
172
      fgets(line, 255, stdin);
 
173
      sscanf(line, "%c", &command);
 
174
      switch (command) {
 
175
         case 'b': case 'B':
 
176
            theGPT->RebuildMainHeader();
 
177
            break;
 
178
         case 'c': case 'C':
 
179
            printf("Warning! This will probably do weird things if you've converted an MBR to\n"
 
180
                  "GPT form and haven't yet saved the GPT! Proceed? ");
 
181
            if (GetYN() == 'Y')
 
182
               theGPT->LoadSecondTableAsMain();
 
183
            break;
 
184
         case 'd': case 'D':
 
185
            theGPT->RebuildSecondHeader();
 
186
            break;
 
187
         case 'e': case 'E':
 
188
            printf("Warning! This will probably do weird things if you've converted an MBR to\n"
 
189
                  "GPT form and haven't yet saved the GPT! Proceed? ");
 
190
            if (GetYN() == 'Y')
 
191
               theGPT->LoadMainTable();
 
192
            break;
 
193
         case 'f': case 'F':
 
194
            printf("Warning! This will destroy the currently defined partitions! Proceed? ");
 
195
            if (GetYN() == 'Y') {
 
196
               if (theGPT->LoadMBR(filename) == 1) { // successful load
 
197
                  theGPT->XFormPartitions();
 
198
               } else {
 
199
                  printf("Problem loading MBR! GPT is untouched; regenerating protective MBR!\n");
 
200
                  theGPT->MakeProtectiveMBR();
 
201
               } // if/else
 
202
            } // if
 
203
            break;
 
204
         case 'g': case 'G':
 
205
            temp1 = theGPT->XFormToMBR();
 
206
            if (temp1 > 0) {
 
207
               printf("Converted %d partitions. Finalize and exit? ", temp1);
 
208
               if (GetYN() == 'Y') {
 
209
                  if (theGPT->DestroyGPT(0) > 0)
 
210
                     goOn = 0;
 
211
               } else {
 
212
                  theGPT->MakeProtectiveMBR();
 
213
                  printf("Note: New protective MBR created.\n");
 
214
               } // if/else
 
215
            } // if
 
216
            break;
 
217
         case 'h': case 'H':
 
218
            theGPT->MakeHybrid();
 
219
            break;
 
220
         case 'i': case 'I':
 
221
            theGPT->ShowDetails();
 
222
            break;
 
223
         case 'l': case 'L':
 
224
            printf("Enter backup filename to load: ");
 
225
            fgets(line, 255, stdin);
 
226
            sscanf(line, "%s", &buFile);
 
227
            theGPT->LoadGPTBackup(buFile);
 
228
            break;
 
229
         case 'm': case 'M':
 
230
            MainMenu(filename, theGPT);
 
231
            goOn = 0;
 
232
            break;
 
233
         case 'o': case 'O':
 
234
            theGPT->DisplayMBRData();
 
235
            break;
 
236
         case 'p': case 'P':
 
237
            theGPT->DisplayGPTData();
 
238
            break;
 
239
         case 'q': case 'Q':
 
240
            goOn = 0;
 
241
            break;
 
242
         case 't': case 'T':
 
243
            theGPT->XFormDisklabel();
 
244
            break;
 
245
         case 'v': case 'V':
 
246
            theGPT->Verify();
 
247
            break;
 
248
         case 'w': case 'W':
 
249
            if (theGPT->SaveGPTData() == 1) {
 
250
               goOn = 0;
 
251
            } // if
 
252
            break;
 
253
         case 'x': case 'X':
 
254
            ExpertsMenu(filename, theGPT);
 
255
            goOn = 0;
 
256
            break;
 
257
         default:
 
258
            ShowRecoveryCommands();
 
259
            break;
 
260
      } // switch
 
261
   } while (goOn);
 
262
} // RecoveryMenu()
 
263
 
 
264
void ShowRecoveryCommands(void) {
 
265
   printf("b\tuse backup GPT header (rebuilding main)\n");
 
266
   printf("c\tload backup partition table from disk (rebuilding main)\n");
 
267
   printf("d\tuse main GPT header (rebuilding backup)\n");
 
268
   printf("e\tload main partition table from disk (rebuilding backup)\n");
 
269
   printf("f\tload MBR and build fresh GPT from it\n");
 
270
   printf("g\tconvert GPT into MBR and exit\n");
 
271
   printf("h\tmake hybrid MBR\n");
 
272
   printf("i\tshow detailed information on a partition\n");
 
273
   printf("l\tload partition data from a backup file\n");
 
274
   printf("m\treturn to main menu\n");
 
275
   printf("o\tprint protective MBR data\n");
 
276
   printf("p\tprint the partition table\n");
 
277
   printf("q\tquit without saving changes\n");
 
278
   printf("t\ttransform BSD disklabel partition\n");
 
279
   printf("v\tverify disk\n");
 
280
   printf("w\twrite table to disk and exit\n");
 
281
   printf("x\textra functionality (experts only)\n");
 
282
   printf("?\tprint this menu\n");
 
283
} // ShowRecoveryCommands()
 
284
 
 
285
// Accept an experts' menu command. Returns only after the user
 
286
// selects an exit command, such as 'w' or 'q'.
 
287
void ExpertsMenu(char* filename, struct GPTData* theGPT) {
 
288
   char command, line[255];
 
289
   PartTypes typeHelper;
 
290
   uint32_t pn;
 
291
   uint32_t temp1, temp2;
 
292
   int goOn = 1;
 
293
 
 
294
   do {
 
295
      printf("\nExpert command (? for help): ");
 
296
      fgets(line, 255, stdin);
 
297
      sscanf(line, "%c", &command);
 
298
      switch (command) {
 
299
         case 'a': case 'A':
 
300
            if (theGPT->GetPartRange(&temp1, &temp2) > 0)
 
301
               theGPT->SetAttributes(theGPT->GetPartNum());
 
302
           else
 
303
               printf("No partitions\n");
 
304
            break;
 
305
         case 'c': case 'C':
 
306
            if (theGPT->GetPartRange(&temp1, &temp2) > 0) {
 
307
               pn = theGPT->GetPartNum();
 
308
               printf("Enter the partition's new unique GUID:\n");
 
309
               theGPT->SetPartitionGUID(pn, GetGUID());
 
310
            } else printf("No partitions\n");
 
311
            break;
 
312
         case 'e': case 'E':
 
313
            printf("Relocating backup data structures to the end of the disk\n");
 
314
            theGPT->MoveSecondHeaderToEnd();
 
315
            break;
 
316
         case 'g': case 'G':
 
317
            printf("Enter the disk's unique GUID:\n");
 
318
            theGPT->SetDiskGUID(GetGUID());
 
319
            break;
 
320
         case 'i': case 'I':
 
321
            theGPT->ShowDetails();
 
322
            break;
 
323
         case 'm': case 'M':
 
324
            MainMenu(filename, theGPT);
 
325
            goOn = 0;
 
326
            break;
 
327
         case 'n': case 'N':
 
328
            theGPT->MakeProtectiveMBR();
 
329
            break;
 
330
         case 'o': case 'O':
 
331
            theGPT->DisplayMBRData();
 
332
            break;
 
333
         case 'p': case 'P':
 
334
            theGPT->DisplayGPTData();
 
335
            break;
 
336
         case 'q': case 'Q':
 
337
            goOn = 0;
 
338
            break;
 
339
         case 'r': case 'R':
 
340
            RecoveryMenu(filename, theGPT);
 
341
            goOn = 0;
 
342
            break;
 
343
         case 's': case 'S':
 
344
            theGPT->ResizePartitionTable();
 
345
            break;
 
346
         case 'v': case 'V':
 
347
            theGPT->Verify();
 
348
            break;
 
349
         case 'w': case 'W':
 
350
            if (theGPT->SaveGPTData() == 1) {
 
351
               goOn = 0;
 
352
            } // if
 
353
            break;
 
354
         case 'z': case 'Z':
 
355
            if (theGPT->DestroyGPT() == 1) {
 
356
               goOn = 0;
 
357
            }
 
358
            break;
 
359
         default:
 
360
            ShowExpertCommands();
 
361
            break;
 
362
      } // switch
 
363
   } while (goOn);
 
364
} // ExpertsMenu()
 
365
 
 
366
void ShowExpertCommands(void) {
 
367
   printf("a\tset attributes\n");
 
368
   printf("c\tchange partition GUID\n");
 
369
   printf("e\trelocate backup data structures to the end of the disk\n");
 
370
   printf("g\tchange disk GUID\n");
 
371
   printf("i\tshow detailed information on a partition\n");
 
372
   printf("m\treturn to main menu\n");
 
373
   printf("n\tcreate a new protective MBR\n");
 
374
   printf("o\tprint protective MBR data\n");
 
375
   printf("p\tprint the partition table\n");
 
376
   printf("q\tquit without saving changes\n");
 
377
   printf("r\trecovery and transformation options (experts only)\n");
 
378
   printf("s\tresize partition table\n");
 
379
   printf("v\tverify disk\n");
 
380
   printf("w\twrite table to disk and exit\n");
 
381
   printf("z\tzap (destroy) GPT data structures and exit\n");
 
382
   printf("?\tprint this menu\n");
 
383
} // ShowExpertCommands()