2 parted - a frontend to libparted
3 Copyright (C) 1999-2002, 2006-2011 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
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);
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_part_flag (const char* prompt, const PedPartition* part,
1120 PedPartitionFlag* flag)
1122 StrList* opts = NULL;
1123 PedPartitionFlag walk = 0;
1126 while ( (walk = ped_partition_flag_next (walk)) ) {
1127 if (ped_partition_is_flag_available (part, walk)) {
1128 const char* walk_name;
1130 walk_name = ped_partition_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_partition_flag_get_by_name (flag_name);
1148 _can_create_primary (const PedDisk* disk)
1152 for (i = 1; i <= ped_disk_get_max_primary_partition_count (disk); i++) {
1153 if (!ped_disk_get_partition (disk, i))
1161 _can_create_extended (const PedDisk* disk)
1163 if (!_can_create_primary (disk))
1166 if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1169 if (ped_disk_extended_partition (disk))
1176 _can_create_logical (const PedDisk* disk)
1178 if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1181 return ped_disk_extended_partition (disk) != 0;
1185 command_line_get_part_type (const char* prompt, const PedDisk* disk,
1186 PedPartitionType* type)
1188 StrList* opts = NULL;
1191 if (_can_create_primary (disk)) {
1192 opts = str_list_append_unique (opts, "primary");
1193 opts = str_list_append_unique (opts, _("primary"));
1195 if (_can_create_extended (disk)) {
1196 opts = str_list_append_unique (opts, "extended");
1197 opts = str_list_append_unique (opts, _("extended"));
1199 if (_can_create_logical (disk)) {
1200 opts = str_list_append_unique (opts, "logical");
1201 opts = str_list_append_unique (opts, _("logical"));
1204 ped_exception_throw (
1205 PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1206 _("Can't create any more partitions."));
1210 type_name = command_line_get_word (prompt, NULL, opts, 1);
1211 str_list_destroy (opts);
1214 ped_exception_throw (
1215 PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1216 _("Expecting a partition type."));
1220 if (!strcmp (type_name, "primary")
1221 || !strcmp (type_name, _("primary"))) {
1224 if (!strcmp (type_name, "extended")
1225 || !strcmp (type_name, _("extended"))) {
1226 *type = PED_PARTITION_EXTENDED;
1228 if (!strcmp (type_name, "logical")
1229 || !strcmp (type_name, _("logical"))) {
1230 *type = PED_PARTITION_LOGICAL;
1238 command_line_get_ex_opt (const char* prompt, PedExceptionOption options)
1240 StrList* options_strlist = NULL;
1241 PedExceptionOption opt;
1244 for (opt = option_get_next (options, 0); opt;
1245 opt = option_get_next (options, opt)) {
1246 options_strlist = str_list_append_unique (options_strlist,
1247 _(ped_exception_get_option_string (opt)));
1248 options_strlist = str_list_append_unique (options_strlist,
1249 ped_exception_get_option_string (opt));
1252 opt_name = command_line_get_word (prompt, NULL, options_strlist, 1);
1254 return PED_EXCEPTION_UNHANDLED;
1255 str_list_destroy (options_strlist);
1257 opt = PED_EXCEPTION_OPTION_FIRST;
1259 if (strcmp (opt_name,
1260 ped_exception_get_option_string (opt)) == 0)
1262 if (strcmp (opt_name,
1263 _(ped_exception_get_option_string (opt))) == 0)
1265 opt = option_get_next (options, opt);
1272 command_line_get_align_type (const char *prompt, enum AlignmentType *align_type)
1278 def_word = str_list_convert_node (align_opt_list);
1280 def_word = str_list_convert_node (align_min_list);
1281 input = command_line_get_word (prompt, def_word, align_opt_min_list, 1);
1285 *align_type = (str_list_match_any (align_opt_list, input)
1293 command_line_get_unit (const char* prompt, PedUnit* unit)
1295 StrList* opts = NULL;
1298 const char* default_unit_name;
1300 for (walk = PED_UNIT_FIRST; walk <= PED_UNIT_LAST; walk++)
1301 opts = str_list_append (opts, ped_unit_get_name (walk));
1303 default_unit_name = ped_unit_get_name (ped_unit_get_default ());
1304 unit_name = command_line_get_word (prompt, default_unit_name, opts, 1);
1305 str_list_destroy (opts);
1308 *unit = ped_unit_get_by_name (unit_name);
1316 command_line_is_integer ()
1322 word = command_line_peek_word ();
1326 is_integer = sscanf (word, "%d", &scratch);
1335 PedExceptionOption opt;
1337 for (i = 0; (1 << i) <= PED_EXCEPTION_OPTION_LAST; i++) {
1341 ped_exception_get_option_string (opt),
1342 _(ped_exception_get_option_string (opt)),
1344 if (!ex_opt_str [i])
1348 ex_opt_str [i] = NULL;
1357 for (i=0; ex_opt_str [i]; i++)
1358 str_list_destroy (ex_opt_str [i]);
1364 on_list = str_list_create_unique (_("on"), "on", NULL);
1365 off_list = str_list_create_unique (_("off"), "off", NULL);
1366 on_off_list = str_list_join (str_list_duplicate (on_list),
1367 str_list_duplicate (off_list));
1374 str_list_destroy (on_list);
1375 str_list_destroy (off_list);
1376 str_list_destroy (on_off_list);
1380 init_alignment_type_str ()
1382 align_opt_list = str_list_create_unique (_("optimal"), "optimal", NULL);
1383 align_min_list = str_list_create_unique (_("minimal"), "minimal", NULL);
1384 align_opt_min_list = str_list_join (str_list_duplicate (align_opt_list),
1385 str_list_duplicate (align_min_list));
1390 done_alignment_type_str ()
1392 str_list_destroy (align_opt_list);
1393 str_list_destroy (align_min_list);
1394 str_list_destroy (align_opt_min_list);
1400 PedFileSystemType* walk;
1401 PedFileSystemAlias* alias_walk;
1403 fs_type_list = NULL;
1405 for (walk = ped_file_system_type_get_next (NULL); walk;
1406 walk = ped_file_system_type_get_next (walk))
1408 fs_type_list = str_list_insert (fs_type_list, walk->name);
1412 for (alias_walk = ped_file_system_alias_get_next (NULL); alias_walk;
1413 alias_walk = ped_file_system_alias_get_next (alias_walk))
1415 fs_type_list = str_list_insert (fs_type_list,
1425 init_disk_type_str ()
1429 disk_type_list = NULL;
1431 for (walk = ped_disk_type_get_next (NULL); walk;
1432 walk = ped_disk_type_get_next (walk))
1434 disk_type_list = str_list_insert (disk_type_list, walk->name);
1435 if (!disk_type_list)
1443 init_readline (void)
1445 #ifdef HAVE_LIBREADLINE
1446 if (!opt_script_mode) {
1448 rl_attempted_completion_function = (CPPFunction*) complete_function;
1449 readline_state.in_readline = 0;
1458 if (!init_ex_opt_str ()
1459 || !init_state_str ()
1460 || !init_alignment_type_str ()
1461 || !init_fs_type_str ()
1462 || !init_disk_type_str ())
1464 ped_exception_set_handler (exception_handler);
1470 sig_segv.sa_sigaction = &sa_sigsegv_handler;
1471 sig_int.sa_sigaction = &sa_sigint_handler;
1472 sig_fpe.sa_sigaction = &sa_sigfpe_handler;
1473 sig_ill.sa_sigaction = &sa_sigill_handler;
1478 sig_ill.sa_mask = curr;
1483 sig_ill.sa_flags = SA_SIGINFO;
1485 sigaction (SIGSEGV, &sig_segv, NULL);
1486 sigaction (SIGINT, &sig_int, NULL);
1487 sigaction (SIGFPE, &sig_fpe, NULL);
1488 sigaction (SIGILL, &sig_ill, NULL);
1490 signal (SIGSEGV, s_sigsegv_handler);
1491 signal (SIGINT, s_sigint_handler);
1492 signal (SIGFPE, s_sigfpe_handler);
1493 signal (SIGILL, s_sigill_handler);
1494 #endif /* SA_SIGINFO */
1502 ped_exception_set_handler (NULL);
1505 done_alignment_type_str ();
1506 str_list_destroy (fs_type_list);
1507 str_list_destroy (disk_type_list);
1513 fputs (_(usage_msg), stdout);
1516 fputs (_("OPTIONs:"), stdout);
1518 print_options_help ();
1521 fputs (_("COMMANDs:"), stdout);
1523 print_commands_help ();
1524 printf (_("\nReport bugs to %s\n"), PACKAGE_BUGREPORT);
1525 exit (EXIT_SUCCESS);
1529 print_using_dev (PedDevice* dev)
1531 printf (_("Using %s\n"), dev->path);
1535 interactive_mode (PedDevice** dev, Command* cmd_list[])
1538 StrList* command_names = command_get_names (cmd_list);
1540 commands = cmd_list; /* FIXME yucky, nasty, evil hack */
1542 fputs (prog_name, stdout);
1544 print_using_dev (*dev);
1546 list = str_list_create (_(banner_msg), NULL);
1547 str_list_print_wrap (list, screen_width (), 0, 0, stdout);
1548 str_list_destroy (list);
1554 while (!command_line_get_word_count ()) {
1559 command_line_prompt_words ("(parted)", NULL,
1563 word = command_line_pop_word ();
1565 cmd = command_get (commands, word);
1568 if (!command_run (cmd, dev))
1569 command_line_flush ();
1571 print_commands_help ();
1580 non_interactive_mode (PedDevice** dev, Command* cmd_list[],
1581 int argc, char* argv[])
1586 commands = cmd_list; /* FIXME yucky, nasty, evil hack */
1588 for (i = 0; i < argc; i++)
1589 command_line_push_line (argv [i], 1);
1591 while (command_line_get_word_count ()) {
1594 word = command_line_pop_word ();
1598 cmd = command_get (commands, word);
1604 if (!(cmd->non_interactive)) {
1605 fputs(_("This command does not make sense in "
1606 "non-interactive mode.\n"), stdout);
1611 if (!command_run (cmd, dev))