2
parted - a frontend to libparted
3
Copyright (C) 1999-2002, 2006-2012 Free Software Foundation, Inc.
5
This program is free software; you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation; either version 3 of the License, or
8
(at your option) any later version.
10
This program is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
15
You should have received a copy of the GNU General Public License
16
along with this program. If not, see <http://www.gnu.org/licenses/>.
22
#include <parted/parted.h>
23
#include <parted/debug.h>
38
#define N_(String) String
42
# define _(String) dgettext (PACKAGE, String)
44
# define _(String) (String)
45
#endif /* ENABLE_NLS */
47
#ifdef HAVE_LIBREADLINE
52
extern int tgetnum (char* key);
55
#include <readline/readline.h>
56
#include <readline/history.h>
58
#ifndef HAVE_RL_COMPLETION_MATCHES
59
#define rl_completion_matches completion_matches
62
#ifndef rl_compentry_func_t
63
#define rl_compentry_func_t void
66
#endif /* HAVE_LIBREADLINE */
69
# ifndef HAVE_SIGACTION
75
sigaction (int signum, const struct* sigaction, struct* sigaction)
79
# endif /* HAVE_SIGACTON */
85
#endif /* SA_SIGINFO */
88
# define SEGV_MAPERR (INTMAX - 1)
92
# define SEGV_ACCERR (INTMAX - 2)
96
# define FPE_INTDIV (INTMAX - 1)
100
# define FPE_INTOVF (INTMAX - 2)
104
# define FPE_FLTDIV (INTMAX - 3)
108
# define FPE_FLTOVF (INTMAX - 4)
112
# define FPE_FLTUND (INTMAX - 5)
116
# define FPE_FLTRES (INTMAX - 6)
120
# define FPE_FLTINV (INTMAX - 7)
124
# define FPE_FLTSUB (INTMAX - 8)
128
# define ILL_ILLOPC (INTMAX - 1)
132
# define ILL_ILLOPN (INTMAX - 2)
136
# define ILL_ILLADR (INTMAX - 3)
140
# define ILL_ILLTRP (INTMAX - 4)
144
# define ILL_PRVOPC (INTMAX - 5)
148
# define ILL_PRVREG (INTMAX - 6)
152
# define ILL_COPROC (INTMAX - 7)
156
# define ILL_BADSTK (INTMAX - 8)
159
const char* prog_name = "GNU Parted " VERSION "\n";
161
static const char* banner_msg = N_(
162
"Welcome to GNU Parted! Type 'help' to view a list of commands.\n");
164
static const char* usage_msg = N_(
165
"Usage: parted [OPTION]... [DEVICE [COMMAND [PARAMETERS]...]...]\n"
166
"Apply COMMANDs with PARAMETERS to DEVICE. If no COMMAND(s) are given, "
167
"run in\ninteractive mode.\n");
169
static const char* bug_msg = N_(
170
"\n\nYou found a bug in GNU Parted! Here's what you have to do:\n\n"
171
"Don't panic! The bug has most likely not affected any of your data.\n"
172
"Help us to fix this bug by doing the following:\n\n"
173
"Check whether the bug has already been fixed by checking\n"
174
"the last version of GNU Parted that you can find at:\n\n"
175
"\thttp://ftp.gnu.org/gnu/parted/\n\n"
176
"Please check this version prior to bug reporting.\n\n"
177
"If this has not been fixed yet or if you don't know how to check,\n"
178
"please visit the GNU Parted website:\n\n"
179
"\thttp://www.gnu.org/software/parted\n\n"
180
"for further information.\n\n"
181
"Your report should contain the version of this release (%s)\n"
182
"along with the error message below, the output of\n\n"
183
"\tparted DEVICE unit co print unit s print\n\n"
184
"and the following history of commands you entered.\n"
185
"Also include any additional information about your setup you\n"
186
"consider important.\n");
188
#define MAX_WORDS 1024
190
static StrList* command_line;
191
static Command** commands;
192
static StrList* ex_opt_str [64];
193
static StrList* on_list;
194
static StrList* off_list;
195
static StrList* on_off_list;
197
static StrList* align_opt_list;
198
static StrList* align_min_list;
199
static StrList* align_opt_min_list;
201
static StrList* fs_type_list;
202
static StrList* disk_type_list;
205
const StrList* possibilities;
206
const StrList* cur_pos;
208
sigjmp_buf jmp_state;
211
static struct sigaction sig_segv;
212
static struct sigaction sig_int;
213
static struct sigaction sig_fpe;
214
static struct sigaction sig_ill;
216
volatile int got_ctrl_c = 0; /* used in exception_handler */
223
if (opt_script_mode || pretend_input_tty)
224
return 32768; /* no wrapping ;) */
226
/* HACK: don't specify termcap separately - it'll annoy the users. */
227
#ifdef HAVE_LIBREADLINE
228
width = tgetnum ((char *) "co");
248
#ifdef HAVE_LIBREADLINE
249
/* returns matching commands for text */
251
command_generator (char* text, int state)
254
readline_state.cur_pos = readline_state.possibilities;
256
while (readline_state.cur_pos) {
257
const StrList* cur = readline_state.cur_pos;
258
readline_state.cur_pos = cur->next;
259
if (str_list_match_node (cur, text))
260
return str_list_convert_node (cur);
266
/* completion function for readline() */
268
complete_function (char* text, int start, int end)
270
return rl_completion_matches (text,
271
(rl_compentry_func_t*) command_generator);
275
_add_history_unique (const char* line)
277
HIST_ENTRY* last_entry = current_history ();
280
if (!last_entry || strcmp (last_entry->line, line))
281
add_history ((char*) line);
284
/* Prints command history, to be used before aborting */
289
HIST_ENTRY** all_entries = history_list ();
291
fputs (_("\nCommand History:\n"), stdout);
292
while (all_entries[i]) {
293
puts(all_entries[i++]->line);
299
/* Print nothing because Readline is absent. */
305
#endif /* HAVE_LIBREADLINE */
307
/* Resets the environment by jumping to the initial state
308
* saved during ui intitialisation.
309
* Pass 1 as the parameter if you want to quit parted,
310
* 0 if you just want to reset to the command prompt.
315
int in_readline = readline_state.in_readline;
317
readline_state.in_readline = 0;
324
siglongjmp (readline_state.jmp_state, 1);
328
/* Signal handler for SIGINT using 'sigaction'. */
330
sa_sigint_handler (int signum, siginfo_t* info, void *ucontext)
333
sigaction (SIGINT, &sig_int, NULL);
339
/* Signal handler for SIGSEGV using 'sigaction'. */
341
sa_sigsegv_handler (int signum, siginfo_t* info, void* ucontext)
343
fprintf (stderr, bug_msg, VERSION);
349
sigaction (SIGSEGV, &sig_segv, NULL);
351
switch (info->si_code) {
354
fputs(_("\nError: SEGV_MAPERR (Address not mapped "
355
"to object)\n"), stdout);
356
PED_ASSERT(0); /* Force a backtrace */
360
fputs(_("\nError: SEGV_ACCERR (Invalid permissions "
361
"for mapped object)\n"), stdout);
365
fputs(_("\nError: A general SIGSEGV signal was "
366
"encountered.\n"), stdout);
367
PED_ASSERT(0); /* Force a backtrace */
374
/* Signal handler for SIGFPE using 'sigaction'. */
376
sa_sigfpe_handler (int signum, siginfo_t* info, void* ucontext)
378
fprintf (stderr, bug_msg, VERSION);
384
sigaction (SIGFPE, &sig_fpe, NULL);
386
switch (info->si_code) {
389
fputs(_("\nError: FPE_INTDIV (Integer: "
390
"divide by zero)"), stdout);
394
fputs(_("\nError: FPE_INTOVF (Integer: "
395
"overflow)"), stdout);
399
fputs(_("\nError: FPE_FLTDIV (Float: "
400
"divide by zero)"), stdout);
404
fputs(_("\nError: FPE_FLTOVF (Float: "
405
"overflow)"), stdout);
409
fputs(_("\nError: FPE_FLTUND (Float: "
410
"underflow)"), stdout);
414
fputs(_("\nError: FPE_FLTRES (Float: "
415
"inexact result)"), stdout);
419
fputs(_("\nError: FPE_FLTINV (Float: "
420
"invalid operation)"), stdout);
424
fputs(_("\nError: FPE_FLTSUB (Float: "
425
"subscript out of range)"), stdout);
429
fputs(_("\nError: A general SIGFPE signal "
430
"was encountered."), stdout);
438
/* Signal handler for SIGILL using 'sigaction'. */
440
sa_sigill_handler (int signum, siginfo_t* info, void* ucontext)
442
fprintf (stderr, bug_msg, VERSION);
448
sigaction (SIGILL, &sig_ill, NULL);
450
switch (info->si_code) {
453
fputs(_("\nError: ILL_ILLOPC "
454
"(Illegal Opcode)"), stdout);
458
fputs(_("\nError: ILL_ILLOPN "
459
"(Illegal Operand)"), stdout);
463
fputs(_("\nError: ILL_ILLADR "
464
"(Illegal addressing mode)"), stdout);
468
fputs(_("\nError: ILL_ILLTRP "
469
"(Illegal Trap)"), stdout);
473
fputs(_("\nError: ILL_PRVOPC "
474
"(Privileged Opcode)"), stdout);
478
fputs(_("\nError: ILL_PRVREG "
479
"(Privileged Register)"), stdout);
483
fputs(_("\nError: ILL_COPROC "
484
"(Coprocessor Error)"), stdout);
488
fputs(_("\nError: ILL_BADSTK "
489
"(Internal Stack Error)"), stdout);
493
fputs(_("\nError: A general SIGILL "
494
"signal was encountered."), stdout);
510
sigprocmask(SIG_SETMASK, &curr, &prev);
513
/* Signal handler for SIGINT using 'signal'. */
515
s_sigint_handler (int signum)
517
signal (SIGINT, &s_sigint_handler);
519
sa_sigint_handler (signum, NULL, NULL);
522
/* Signal handler for SIGILL using 'signal'. */
524
s_sigill_handler (int signum)
526
signal (SIGILL, &s_sigill_handler);
528
sa_sigill_handler (signum, NULL, NULL);
531
/* Signal handler for SIGSEGV using 'signal'. */
533
s_sigsegv_handler (int signum)
535
signal (SIGSEGV, &s_sigsegv_handler);
537
sa_sigsegv_handler (signum, NULL, NULL);
540
/* Signal handler for SIGFPE using 'signal'. */
542
s_sigfpe_handler (int signum)
544
signal (SIGFPE, &s_sigfpe_handler);
546
sa_sigfpe_handler (signum, NULL, NULL);
551
_readline (const char* prompt, const StrList* possibilities)
555
readline_state.possibilities = possibilities;
556
readline_state.cur_pos = NULL;
557
readline_state.in_readline = 1;
559
if (sigsetjmp (readline_state.jmp_state,1))
563
#ifdef HAVE_LIBREADLINE
564
if (!opt_script_mode) {
565
/* XXX: why isn't prompt const? */
566
line = readline ((char*) prompt);
568
_add_history_unique (line);
572
fputs (prompt, stdout);
574
line = (char*) malloc (256);
575
if (fgets (line, 256, stdin) && strcmp (line, "") != 0) {
576
#ifndef HAVE_LIBREADLINE
577
/* Echo the input line, to be consistent with
578
how readline-5.2 works. */
579
fputs (line, stdout);
582
/* kill trailing NL */
584
line [strlen (line) - 1] = 0;
591
readline_state.in_readline = 0;
595
static PedExceptionOption _GL_ATTRIBUTE_PURE
596
option_get_next (PedExceptionOption options, PedExceptionOption current)
598
PedExceptionOption i;
601
i = PED_EXCEPTION_OPTION_FIRST;
605
for (; i <= options; i *= 2) {
613
_print_exception_text (PedException* ex)
619
if (ex->type == PED_EXCEPTION_BUG) {
620
fprintf (stderr, bug_msg, VERSION);
621
text = str_list_create ("\n", ex->message, "\n\n", NULL);
623
text = str_list_create (
624
_(ped_exception_get_type_string (ex->type)),
625
": ", ex->message, "\n", NULL);
628
str_list_print_wrap (text, screen_width (), 0, 0, stderr);
629
str_list_destroy (text);
632
static PedExceptionOption
633
exception_handler (PedException* ex)
635
PedExceptionOption opt;
637
_print_exception_text (ex);
639
/* only one choice? Take it ;-) */
640
opt = option_get_next (ex->options, 0);
641
if (!option_get_next (ex->options, opt))
644
/* script-mode: don't handle the exception */
645
if (opt_script_mode || (!isatty (0) && !pretend_input_tty))
646
return PED_EXCEPTION_UNHANDLED;
651
opt = command_line_get_ex_opt ("", ex->options);
652
} while (opt == PED_EXCEPTION_UNHANDLED
653
&& (isatty (0) || pretend_input_tty) && !got_ctrl_c);
657
opt = PED_EXCEPTION_UNHANDLED;
664
command_line_push_word (const char* word)
666
command_line = str_list_append (command_line, word);
670
command_line_pop_word ()
675
PED_ASSERT (command_line != NULL);
677
result = str_list_convert_node (command_line);
678
next = command_line->next;
680
str_list_destroy_node (command_line);
686
command_line_flush ()
688
str_list_destroy (command_line);
693
command_line_peek_word ()
696
return str_list_convert_node (command_line);
702
command_line_get_word_count ()
704
return str_list_length (command_line);
707
static int _GL_ATTRIBUTE_PURE
708
_str_is_spaces (const char* str)
710
while (isspace (*str))
716
/* "multi_word mode" is the "normal" mode... many words can be typed,
717
* delimited by spaces, etc.
718
* In single-word mode, only one word is parsed per line.
719
* Leading and trailing spaces are removed. For example: " a b c "
720
* is a single word "a b c". The motivation for this mode is partition
721
* names, etc. In single-word mode, the empty string is a word.
722
* (but not in multi-word mode).
725
command_line_push_line (const char* line, int multi_word)
729
char this_word [256];
737
for (; *line; line++) {
738
if (*line == ' ' && !quoted) {
742
/* single word: check for trailing spaces + eol */
743
if (_str_is_spaces (line))
747
if (!quoted && strchr ("'\"", *line)) {
753
if (quoted && *line == quote_char) {
758
/* hack: escape characters */
759
if (quoted && line[0] == '\\' && line[1])
762
this_word [i++] = *line;
764
if (i || !multi_word) {
766
command_line_push_word (this_word);
768
} while (*line && multi_word);
772
realloc_and_cat (char* str, const char* append)
774
int length = strlen (str) + strlen (append) + 1;
775
char* new_str = realloc (str, length);
777
strcat (new_str, append);
782
_construct_prompt (const char* head, const char* def,
783
const StrList* possibilities)
785
char* prompt = strdup (head);
787
if (def && possibilities)
788
PED_ASSERT (str_list_match_any (possibilities, def));
790
if (possibilities && str_list_length (possibilities) < 8) {
794
prompt = realloc_and_cat (prompt, " ");
796
for (walk = possibilities; walk; walk = walk->next) {
797
if (walk != possibilities)
798
prompt = realloc_and_cat (prompt, "/");
800
if (def && str_list_match_node (walk, def) == 2) {
801
prompt = realloc_and_cat (prompt, "[");
802
prompt = realloc_and_cat (prompt, def);
803
prompt = realloc_and_cat (prompt, "]");
805
char* text = str_list_convert_node (walk);
806
prompt = realloc_and_cat (prompt, text);
810
prompt = realloc_and_cat (prompt, "? ");
813
prompt = realloc_and_cat (prompt, " ");
814
prompt = realloc_and_cat (prompt, "[");
815
prompt = realloc_and_cat (prompt, def);
816
prompt = realloc_and_cat (prompt, "]? ");
819
prompt = realloc_and_cat (prompt, " ");
826
command_line_prompt_words (const char* prompt, const char* def,
827
const StrList* possibilities, int multi_word)
831
char* _def = (char*) def;
832
int _def_needs_free = 0;
834
if (!def && str_list_length (possibilities) == 1) {
835
_def = str_list_convert_node (possibilities);
839
if (opt_script_mode) {
841
command_line_push_line (_def, 0);
846
real_prompt = _construct_prompt (prompt, _def, possibilities);
847
line = _readline (real_prompt, possibilities);
850
/* readline returns NULL to indicate EOF.
851
Treat that like an interrupt. */
856
if (!strlen (line)) {
858
command_line_push_line (_def, 0);
860
command_line_push_line (line, multi_word);
863
} while (!command_line_get_word_count () && !_def);
870
* Get a word from command line.
872
* \param possibilities a StrList of valid strings, NULL if all are valid.
873
* \param multi_word whether multiple words are allowed.
875
* \return The word(s), or NULL if empty.
878
command_line_get_word (const char* prompt, const char* def,
879
const StrList* possibilities, int multi_word)
882
if (command_line_get_word_count ()) {
883
char* result = command_line_pop_word ();
884
StrList* result_node;
889
result_node = str_list_match (possibilities, result);
890
if (result_node == NULL)
891
error (0, 0, _("invalid token: %s"), result);
894
return str_list_convert_node (result_node);
896
command_line_flush ();
901
command_line_prompt_words (prompt, def, possibilities,
903
} while (command_line_get_word_count ());
909
command_line_get_integer (const char* prompt, int* value)
915
snprintf (def_str, 10, "%d", *value);
916
input = command_line_get_word (prompt, *value ? def_str : NULL,
920
valid = sscanf (input, "%d", value);
926
command_line_get_sector (const char* prompt, PedDevice* dev, PedSector* value,
927
PedGeometry** range, char** raw_input)
933
def_str = ped_unit_format (dev, *value);
934
input = command_line_get_word (prompt, *value ? def_str : NULL,
937
/* def_str might have rounded *value a little bit. If the user picked
938
* the default, make sure the selected sector is identical to the
941
if (input && *value && !strcmp (input, def_str)) {
943
*range = ped_geometry_new (dev, *value, 1);
945
return *range != NULL;
961
valid = ped_unit_parse (input, dev, value, range);
971
command_line_get_state (const char* prompt, int* value)
977
def_word = str_list_convert_node (on_list);
979
def_word = str_list_convert_node (off_list);
980
input = command_line_get_word (prompt, def_word, on_off_list, 1);
984
if (str_list_match_any (on_list, input))
993
command_line_get_device (const char* prompt, PedDevice** value)
995
char *def_dev_name = *value ? (*value)->path : NULL;
996
char *dev_name = command_line_get_word (prompt, def_dev_name, NULL, 1);
1000
PedDevice *dev = ped_device_get (dev_name);
1010
command_line_get_disk (const char* prompt, PedDisk** value)
1012
PedDevice* dev = *value ? (*value)->dev : NULL;
1014
if (!command_line_get_device (prompt, &dev))
1018
if (dev != (*value)->dev) {
1019
PedDisk* new_disk = ped_disk_new (dev);
1028
command_line_get_partition (const char* prompt, PedDisk* disk,
1029
PedPartition** value)
1033
/* Flawed logic, doesn't seem to work?!
1034
check = ped_disk_next_partition (disk, part);
1035
part = ped_disk_next_partition (disk, check);
1040
printf (_("The (only) primary partition has "
1041
"been automatically selected\n"));
1046
int num = (*value) ? (*value)->num : 0;
1048
if (!command_line_get_integer (prompt, &num)) {
1049
ped_exception_throw (PED_EXCEPTION_ERROR,
1050
PED_EXCEPTION_CANCEL,
1051
_("Expecting a partition number."));
1055
part = ped_disk_get_partition (disk, num);
1058
ped_exception_throw (PED_EXCEPTION_ERROR,
1059
PED_EXCEPTION_CANCEL,
1060
_("Partition doesn't exist."));
1070
command_line_get_fs_type (const char* prompt, const PedFileSystemType*(* value))
1073
PedFileSystemType* fs_type;
1075
fs_type_name = command_line_get_word (prompt,
1076
*value ? (*value)->name : NULL,
1078
if (!fs_type_name) {
1079
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1080
_("Expecting a file system type."));
1084
fs_type = ped_file_system_type_get (fs_type_name);
1086
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1087
_("Unknown file system type \"%s\"."),
1089
free (fs_type_name);
1093
free (fs_type_name);
1099
command_line_get_disk_type (const char* prompt, const PedDiskType*(* value))
1101
char* disk_type_name;
1103
disk_type_name = command_line_get_word (prompt,
1104
*value ? (*value)->name : NULL,
1106
if (!disk_type_name) {
1107
ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1108
_("Expecting a disk label type."));
1112
*value = ped_disk_type_get (disk_type_name);
1113
free (disk_type_name);
1114
PED_ASSERT (*value != NULL);
1119
command_line_get_disk_flag (const char* prompt, const PedDisk* disk,
1122
StrList* opts = NULL;
1123
PedPartitionFlag walk = 0;
1126
while ( (walk = ped_disk_flag_next (walk)) ) {
1127
if (ped_disk_is_flag_available (disk, walk)) {
1128
const char* walk_name;
1130
walk_name = ped_disk_flag_get_name (walk);
1131
opts = str_list_append (opts, walk_name);
1132
opts = str_list_append_unique (opts, _(walk_name));
1136
flag_name = command_line_get_word (prompt, NULL, opts, 1);
1137
str_list_destroy (opts);
1140
*flag = ped_disk_flag_get_by_name (flag_name);
1148
command_line_get_part_flag (const char* prompt, const PedPartition* part,
1149
PedPartitionFlag* flag)
1151
StrList* opts = NULL;
1152
PedPartitionFlag walk = 0;
1155
while ( (walk = ped_partition_flag_next (walk)) ) {
1156
if (ped_partition_is_flag_available (part, walk)) {
1157
const char* walk_name;
1159
walk_name = ped_partition_flag_get_name (walk);
1160
opts = str_list_append (opts, walk_name);
1161
opts = str_list_append_unique (opts, _(walk_name));
1165
flag_name = command_line_get_word (prompt, NULL, opts, 1);
1166
str_list_destroy (opts);
1169
*flag = ped_partition_flag_get_by_name (flag_name);
1177
_can_create_primary (const PedDisk* disk)
1181
for (i = 1; i <= ped_disk_get_max_primary_partition_count (disk); i++) {
1182
if (!ped_disk_get_partition (disk, i))
1190
_can_create_extended (const PedDisk* disk)
1192
if (!_can_create_primary (disk))
1195
if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1198
if (ped_disk_extended_partition (disk))
1205
_can_create_logical (const PedDisk* disk)
1207
if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1210
return ped_disk_extended_partition (disk) != 0;
1214
command_line_get_part_type (const char* prompt, const PedDisk* disk,
1215
PedPartitionType* type)
1217
StrList* opts = NULL;
1220
if (_can_create_primary (disk)) {
1221
opts = str_list_append_unique (opts, "primary");
1222
opts = str_list_append_unique (opts, _("primary"));
1224
if (_can_create_extended (disk)) {
1225
opts = str_list_append_unique (opts, "extended");
1226
opts = str_list_append_unique (opts, _("extended"));
1228
if (_can_create_logical (disk)) {
1229
opts = str_list_append_unique (opts, "logical");
1230
opts = str_list_append_unique (opts, _("logical"));
1233
ped_exception_throw (
1234
PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1235
_("Can't create any more partitions."));
1239
type_name = command_line_get_word (prompt, NULL, opts, 1);
1240
str_list_destroy (opts);
1243
ped_exception_throw (
1244
PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1245
_("Expecting a partition type."));
1249
if (!strcmp (type_name, "primary")
1250
|| !strcmp (type_name, _("primary"))) {
1253
if (!strcmp (type_name, "extended")
1254
|| !strcmp (type_name, _("extended"))) {
1255
*type = PED_PARTITION_EXTENDED;
1257
if (!strcmp (type_name, "logical")
1258
|| !strcmp (type_name, _("logical"))) {
1259
*type = PED_PARTITION_LOGICAL;
1267
command_line_get_ex_opt (const char* prompt, PedExceptionOption options)
1269
StrList* options_strlist = NULL;
1270
PedExceptionOption opt;
1273
for (opt = option_get_next (options, 0); opt;
1274
opt = option_get_next (options, opt)) {
1275
options_strlist = str_list_append_unique (options_strlist,
1276
_(ped_exception_get_option_string (opt)));
1277
options_strlist = str_list_append_unique (options_strlist,
1278
ped_exception_get_option_string (opt));
1281
opt_name = command_line_get_word (prompt, NULL, options_strlist, 1);
1283
return PED_EXCEPTION_UNHANDLED;
1284
str_list_destroy (options_strlist);
1286
opt = PED_EXCEPTION_OPTION_FIRST;
1288
if (strcmp (opt_name,
1289
ped_exception_get_option_string (opt)) == 0)
1291
if (strcmp (opt_name,
1292
_(ped_exception_get_option_string (opt))) == 0)
1294
opt = option_get_next (options, opt);
1301
command_line_get_align_type (const char *prompt, enum AlignmentType *align_type)
1307
def_word = str_list_convert_node (align_opt_list);
1309
def_word = str_list_convert_node (align_min_list);
1310
input = command_line_get_word (prompt, def_word, align_opt_min_list, 1);
1314
*align_type = (str_list_match_any (align_opt_list, input)
1322
command_line_get_unit (const char* prompt, PedUnit* unit)
1324
StrList* opts = NULL;
1327
const char* default_unit_name;
1329
for (walk = PED_UNIT_FIRST; walk <= PED_UNIT_LAST; walk++)
1330
opts = str_list_append (opts, ped_unit_get_name (walk));
1332
default_unit_name = ped_unit_get_name (ped_unit_get_default ());
1333
unit_name = command_line_get_word (prompt, default_unit_name, opts, 1);
1334
str_list_destroy (opts);
1337
*unit = ped_unit_get_by_name (unit_name);
1345
command_line_is_integer ()
1351
word = command_line_peek_word ();
1355
is_integer = sscanf (word, "%d", &scratch);
1364
PedExceptionOption opt;
1366
for (i = 0; (1 << i) <= PED_EXCEPTION_OPTION_LAST; i++) {
1370
ped_exception_get_option_string (opt),
1371
_(ped_exception_get_option_string (opt)),
1373
if (!ex_opt_str [i])
1377
ex_opt_str [i] = NULL;
1386
for (i=0; ex_opt_str [i]; i++)
1387
str_list_destroy (ex_opt_str [i]);
1393
on_list = str_list_create_unique (_("on"), "on", NULL);
1394
off_list = str_list_create_unique (_("off"), "off", NULL);
1395
on_off_list = str_list_join (str_list_duplicate (on_list),
1396
str_list_duplicate (off_list));
1403
str_list_destroy (on_list);
1404
str_list_destroy (off_list);
1405
str_list_destroy (on_off_list);
1409
init_alignment_type_str ()
1411
align_opt_list = str_list_create_unique (_("optimal"), "optimal", NULL);
1412
align_min_list = str_list_create_unique (_("minimal"), "minimal", NULL);
1413
align_opt_min_list = str_list_join (str_list_duplicate (align_opt_list),
1414
str_list_duplicate (align_min_list));
1419
done_alignment_type_str ()
1421
str_list_destroy (align_opt_list);
1422
str_list_destroy (align_min_list);
1423
str_list_destroy (align_opt_min_list);
1429
PedFileSystemType* walk;
1430
PedFileSystemAlias* alias_walk;
1432
fs_type_list = NULL;
1434
for (walk = ped_file_system_type_get_next (NULL); walk;
1435
walk = ped_file_system_type_get_next (walk))
1437
fs_type_list = str_list_insert (fs_type_list, walk->name);
1441
for (alias_walk = ped_file_system_alias_get_next (NULL); alias_walk;
1442
alias_walk = ped_file_system_alias_get_next (alias_walk))
1444
fs_type_list = str_list_insert (fs_type_list,
1454
init_disk_type_str ()
1458
disk_type_list = NULL;
1460
for (walk = ped_disk_type_get_next (NULL); walk;
1461
walk = ped_disk_type_get_next (walk))
1463
disk_type_list = str_list_insert (disk_type_list, walk->name);
1464
if (!disk_type_list)
1472
init_readline (void)
1474
#ifdef HAVE_LIBREADLINE
1475
if (!opt_script_mode) {
1477
rl_attempted_completion_function = (CPPFunction*) complete_function;
1478
readline_state.in_readline = 0;
1487
if (!init_ex_opt_str ()
1488
|| !init_state_str ()
1489
|| !init_alignment_type_str ()
1490
|| !init_fs_type_str ()
1491
|| !init_disk_type_str ())
1493
ped_exception_set_handler (exception_handler);
1499
sig_segv.sa_sigaction = &sa_sigsegv_handler;
1500
sig_int.sa_sigaction = &sa_sigint_handler;
1501
sig_fpe.sa_sigaction = &sa_sigfpe_handler;
1502
sig_ill.sa_sigaction = &sa_sigill_handler;
1507
sig_ill.sa_mask = curr;
1512
sig_ill.sa_flags = SA_SIGINFO;
1514
sigaction (SIGSEGV, &sig_segv, NULL);
1515
sigaction (SIGINT, &sig_int, NULL);
1516
sigaction (SIGFPE, &sig_fpe, NULL);
1517
sigaction (SIGILL, &sig_ill, NULL);
1519
signal (SIGSEGV, s_sigsegv_handler);
1520
signal (SIGINT, s_sigint_handler);
1521
signal (SIGFPE, s_sigfpe_handler);
1522
signal (SIGILL, s_sigill_handler);
1523
#endif /* SA_SIGINFO */
1531
ped_exception_set_handler (NULL);
1534
done_alignment_type_str ();
1535
str_list_destroy (fs_type_list);
1536
str_list_destroy (disk_type_list);
1542
fputs (_(usage_msg), stdout);
1545
fputs (_("OPTIONs:"), stdout);
1547
print_options_help ();
1550
fputs (_("COMMANDs:"), stdout);
1552
print_commands_help ();
1553
printf (_("\nReport bugs to %s\n"), PACKAGE_BUGREPORT);
1554
exit (EXIT_SUCCESS);
1558
print_using_dev (PedDevice* dev)
1560
printf (_("Using %s\n"), dev->path);
1564
interactive_mode (PedDevice** dev, Command* cmd_list[])
1567
StrList* command_names = command_get_names (cmd_list);
1569
commands = cmd_list; /* FIXME yucky, nasty, evil hack */
1571
fputs (prog_name, stdout);
1573
print_using_dev (*dev);
1575
list = str_list_create (_(banner_msg), NULL);
1576
str_list_print_wrap (list, screen_width (), 0, 0, stdout);
1577
str_list_destroy (list);
1583
while (!command_line_get_word_count ()) {
1588
command_line_prompt_words ("(parted)", NULL,
1592
word = command_line_pop_word ();
1594
cmd = command_get (commands, word);
1597
if (!command_run (cmd, dev))
1598
command_line_flush ();
1600
print_commands_help ();
1609
non_interactive_mode (PedDevice** dev, Command* cmd_list[],
1610
int argc, char* argv[])
1615
commands = cmd_list; /* FIXME yucky, nasty, evil hack */
1617
for (i = 0; i < argc; i++)
1618
command_line_push_line (argv [i], 1);
1620
while (command_line_get_word_count ()) {
1623
word = command_line_pop_word ();
1627
cmd = command_get (commands, word);
1633
if (!(cmd->non_interactive)) {
1634
fputs(_("This command does not make sense in "
1635
"non-interactive mode.\n"), stdout);
1640
if (!command_run (cmd, dev))