1N/A/*
1N/A parted - a frontend to libparted
1N/A Copyright (C) 1999-2002, 2006-2010 Free Software Foundation, Inc.
1N/A
1N/A This program is free software; you can redistribute it and/or modify
1N/A it under the terms of the GNU General Public License as published by
1N/A the Free Software Foundation; either version 3 of the License, or
1N/A (at your option) any later version.
1N/A
1N/A This program is distributed in the hope that it will be useful,
1N/A but WITHOUT ANY WARRANTY; without even the implied warranty of
1N/A MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1N/A GNU General Public License for more details.
1N/A
1N/A You should have received a copy of the GNU General Public License
1N/A along with this program. If not, see <http://www.gnu.org/licenses/>.
1N/A*/
1N/A#include <config.h>
1N/A
1N/A#include <parted/parted.h>
1N/A#include <parted/debug.h>
1N/A
1N/A#include <ctype.h>
1N/A#include <signal.h>
1N/A#include <stdlib.h>
1N/A#include <string.h>
1N/A#include <unistd.h>
1N/A#include <setjmp.h>
1N/A#include <assert.h>
1N/A
1N/A#include "command.h"
1N/A#include "strlist.h"
1N/A#include "ui.h"
1N/A#include "error.h"
1N/A
1N/A#define N_(String) String
1N/A#if ENABLE_NLS
1N/A# include <libintl.h>
1N/A# include <locale.h>
1N/A# define _(String) dgettext (PACKAGE, String)
1N/A#else
1N/A# define _(String) (String)
1N/A#endif /* ENABLE_NLS */
1N/A
1N/A#ifdef HAVE_LIBREADLINE
1N/A
1N/A#ifdef HAVE_TERMCAP_H
1N/A#include <termcap.h>
1N/A#else
1N/Aextern int tgetnum (char* key);
1N/A#endif
1N/A
1N/A#include <readline/readline.h>
1N/A#include <readline/history.h>
1N/A
1N/A#ifndef HAVE_RL_COMPLETION_MATCHES
1N/A#define rl_completion_matches completion_matches
1N/A#endif
1N/A
1N/A#ifndef rl_compentry_func_t
1N/A#define rl_compentry_func_t void
1N/A#endif
1N/A
1N/A#endif /* HAVE_LIBREADLINE */
1N/A
1N/A#ifndef SA_SIGINFO
1N/A# ifndef HAVE_SIGACTION
1N/A
1N/Astruct sigaction {
1N/A};
1N/A
1N/Astatic inline int
1N/Asigaction (int signum, const struct* sigaction, struct* sigaction)
1N/A{
1N/A}
1N/A
1N/A# endif /* HAVE_SIGACTON */
1N/A
1N/Astruct siginfo_t {
1N/A int si_code;
1N/A};
1N/A
1N/A#endif /* SA_SIGINFO */
1N/A
1N/A#ifndef SEGV_MAPERR
1N/A# define SEGV_MAPERR (INTMAX - 1)
1N/A#endif
1N/A
1N/A#ifndef SEGV_ACCERR
1N/A# define SEGV_ACCERR (INTMAX - 2)
1N/A#endif
1N/A
1N/A#ifndef FPE_INTDIV
1N/A# define FPE_INTDIV (INTMAX - 1)
1N/A#endif
1N/A
1N/A#ifndef FPE_INTOVF
1N/A# define FPE_INTOVF (INTMAX - 2)
1N/A#endif
1N/A
1N/A#ifndef FPE_FLTDIV
1N/A# define FPE_FLTDIV (INTMAX - 3)
1N/A#endif
1N/A
1N/A#ifndef FPE_FLTOVF
1N/A# define FPE_FLTOVF (INTMAX - 4)
1N/A#endif
1N/A
1N/A#ifndef FPE_FLTUND
1N/A# define FPE_FLTUND (INTMAX - 5)
1N/A#endif
1N/A
1N/A#ifndef FPE_FLTRES
1N/A# define FPE_FLTRES (INTMAX - 6)
1N/A#endif
1N/A
1N/A#ifndef FPE_FLTINV
1N/A# define FPE_FLTINV (INTMAX - 7)
1N/A#endif
1N/A
1N/A#ifndef FPE_FLTSUB
1N/A# define FPE_FLTSUB (INTMAX - 8)
1N/A#endif
1N/A
1N/A#ifndef ILL_ILLOPC
1N/A# define ILL_ILLOPC (INTMAX - 1)
1N/A#endif
1N/A
1N/A#ifndef ILL_ILLOPN
1N/A# define ILL_ILLOPN (INTMAX - 2)
1N/A#endif
1N/A
1N/A#ifndef ILL_ILLADR
1N/A# define ILL_ILLADR (INTMAX - 3)
1N/A#endif
1N/A
1N/A#ifndef ILL_ILLTRP
1N/A# define ILL_ILLTRP (INTMAX - 4)
1N/A#endif
1N/A
1N/A#ifndef ILL_PRVOPC
1N/A# define ILL_PRVOPC (INTMAX - 5)
1N/A#endif
1N/A
1N/A#ifndef ILL_PRVREG
1N/A# define ILL_PRVREG (INTMAX - 6)
1N/A#endif
1N/A
1N/A#ifndef ILL_COPROC
1N/A# define ILL_COPROC (INTMAX - 7)
1N/A#endif
1N/A
1N/A#ifndef ILL_BADSTK
1N/A# define ILL_BADSTK (INTMAX - 8)
1N/A#endif
1N/A
1N/Aconst char* prog_name = "GNU Parted " VERSION "\n";
1N/A
1N/Astatic const char* banner_msg = N_(
1N/A"Welcome to GNU Parted! Type 'help' to view a list of commands.\n");
1N/A
1N/Astatic const char* usage_msg = N_(
1N/A"Usage: parted [OPTION]... [DEVICE [COMMAND [PARAMETERS]...]...]\n"
1N/A"Apply COMMANDs with PARAMETERS to DEVICE. If no COMMAND(s) are given, "
1N/A"run in\ninteractive mode.\n");
1N/A
1N/Astatic const char* bug_msg = N_(
1N/A"\n\nYou found a bug in GNU Parted! Here's what you have to do:\n\n"
1N/A"Don't panic! The bug has most likely not affected any of your data.\n"
1N/A"Help us to fix this bug by doing the following:\n\n"
1N/A"Check whether the bug has already been fixed by checking\n"
1N/A"the last version of GNU Parted that you can find at:\n\n"
1N/A"\thttp://ftp.gnu.org/gnu/parted/\n\n"
1N/A"Please check this version prior to bug reporting.\n\n"
1N/A"If this has not been fixed yet or if you don't know how to check,\n"
1N/A"please visit the GNU Parted website:\n\n"
1N/A"\thttp://www.gnu.org/software/parted\n\n"
1N/A"for further information.\n\n"
1N/A"Your report should contain the version of this release (%s)\n"
1N/A"along with the error message below, the output of\n\n"
1N/A"\tparted DEVICE unit co print unit s print\n\n"
1N/A"and the following history of commands you entered.\n"
1N/A"Also include any additional information about your setup you\n"
1N/A"consider important.\n");
1N/A
1N/A#define MAX_WORDS 1024
1N/A
1N/Astatic StrList* command_line;
1N/Astatic Command** commands;
1N/Astatic StrList* ex_opt_str [64];
1N/Astatic StrList* on_list;
1N/Astatic StrList* off_list;
1N/Astatic StrList* on_off_list;
1N/A
1N/Astatic StrList* align_opt_list;
1N/Astatic StrList* align_min_list;
1N/Astatic StrList* align_opt_min_list;
1N/A
1N/Astatic StrList* fs_type_list;
1N/Astatic StrList* disk_type_list;
1N/A
1N/Astatic struct {
1N/A const StrList* possibilities;
1N/A const StrList* cur_pos;
1N/A int in_readline;
1N/A sigjmp_buf jmp_state;
1N/A} readline_state;
1N/A
1N/Astatic struct sigaction sig_segv;
1N/Astatic struct sigaction sig_int;
1N/Astatic struct sigaction sig_fpe;
1N/Astatic struct sigaction sig_ill;
1N/A
1N/Avolatile int got_ctrl_c = 0; /* used in exception_handler */
1N/A
1N/Aint
1N/Ascreen_width ()
1N/A{
1N/A int width = 0;
1N/A
1N/A if (opt_script_mode || pretend_input_tty)
1N/A return 32768; /* no wrapping ;) */
1N/A
1N/A/* HACK: don't specify termcap separately - it'll annoy the users. */
1N/A#ifdef HAVE_LIBREADLINE
1N/A width = tgetnum ((char *) "co");
1N/A#endif
1N/A
1N/A if (width <= 0)
1N/A width = 80;
1N/A
1N/A return width;
1N/A}
1N/A
1N/Avoid
1N/Awipe_line ()
1N/A{
1N/A if (opt_script_mode)
1N/A return;
1N/A
1N/A /* yuck */
1N/A fputs ("\r "
1N/A " \r", stdout);
1N/A}
1N/A
1N/A#ifdef HAVE_LIBREADLINE
1N/A/* returns matching commands for text */
1N/Astatic char*
1N/Acommand_generator (char* text, int state)
1N/A{
1N/A if (!state)
1N/A readline_state.cur_pos = readline_state.possibilities;
1N/A
1N/A while (readline_state.cur_pos) {
1N/A const StrList* cur = readline_state.cur_pos;
1N/A readline_state.cur_pos = cur->next;
1N/A if (str_list_match_node (cur, text))
1N/A return str_list_convert_node (cur);
1N/A }
1N/A
1N/A return NULL;
1N/A}
1N/A
1N/A/* completion function for readline() */
1N/Achar**
1N/Acomplete_function (char* text, int start, int end)
1N/A{
1N/A return rl_completion_matches (text,
1N/A (rl_compentry_func_t*) command_generator);
1N/A}
1N/A
1N/Astatic void
1N/A_add_history_unique (const char* line)
1N/A{
1N/A HIST_ENTRY* last_entry = current_history ();
1N/A if (!strlen (line))
1N/A return;
1N/A if (!last_entry || strcmp (last_entry->line, line))
1N/A add_history ((char*) line);
1N/A}
1N/A
1N/A/* Prints command history, to be used before aborting */
1N/Astatic void
1N/A_dump_history ()
1N/A{
1N/A int i = 0;
1N/A HIST_ENTRY** all_entries = history_list ();
1N/A
1N/A fputs (_("\nCommand History:\n"), stdout);
1N/A while (all_entries[i]) {
1N/A puts(all_entries[i++]->line);
1N/A }
1N/A}
1N/A
1N/A#else
1N/A
1N/A/* Print nothing because Readline is absent. */
1N/Astatic inline void
1N/A_dump_history (void)
1N/A{
1N/A}
1N/A
1N/A#endif /* HAVE_LIBREADLINE */
1N/A
1N/A/* Resets the environment by jumping to the initial state
1N/A * saved during ui intitialisation.
1N/A * Pass 1 as the parameter if you want to quit parted,
1N/A * 0 if you just want to reset to the command prompt.
1N/A */
1N/Astatic void
1N/Areset_env (int quit)
1N/A{
1N/A int in_readline = readline_state.in_readline;
1N/A
1N/A readline_state.in_readline = 0;
1N/A
1N/A if (in_readline) {
1N/A putchar ('\n');
1N/A if (quit)
1N/A exit (EXIT_SUCCESS);
1N/A
1N/A siglongjmp (readline_state.jmp_state, 1);
1N/A }
1N/A}
1N/A
1N/A/* Signal handler for SIGINT using 'sigaction'. */
1N/Astatic void
1N/Asa_sigint_handler (int signum, siginfo_t* info, void *ucontext)
1N/A{
1N/A if (info)
1N/A sigaction (SIGINT, &sig_int, NULL);
1N/A
1N/A got_ctrl_c = 1;
1N/A reset_env (0);
1N/A}
1N/A
1N/A/* Signal handler for SIGSEGV using 'sigaction'. */
1N/Astatic void
1N/Asa_sigsegv_handler (int signum, siginfo_t* info, void* ucontext)
1N/A{
1N/A printf (bug_msg, VERSION);
1N/A _dump_history ();
1N/A
1N/A if (!info)
1N/A abort ();
1N/A
1N/A sigaction (SIGSEGV, &sig_segv, NULL);
1N/A
1N/A switch (info->si_code) {
1N/A
1N/A case SEGV_MAPERR:
1N/A fputs(_("\nError: SEGV_MAPERR (Address not mapped "
1N/A "to object)\n"), stdout);
1N/A PED_ASSERT(0, break); /* Force a backtrace */
1N/A break;
1N/A
1N/A case SEGV_ACCERR:
1N/A fputs(_("\nError: SEGV_ACCERR (Invalid permissions "
1N/A "for mapped object)\n"), stdout);
1N/A break;
1N/A
1N/A default:
1N/A fputs(_("\nError: A general SIGSEGV signal was "
1N/A "encountered.\n"), stdout);
1N/A PED_ASSERT(0, break); /* Force a backtrace */
1N/A break;
1N/A }
1N/A
1N/A abort ();
1N/A}
1N/A
1N/A/* Signal handler for SIGFPE using 'sigaction'. */
1N/Astatic void
1N/Asa_sigfpe_handler (int signum, siginfo_t* info, void* ucontext)
1N/A{
1N/A printf (bug_msg, VERSION);
1N/A _dump_history ();
1N/A
1N/A if (!info)
1N/A abort ();
1N/A
1N/A sigaction (SIGFPE, &sig_fpe, NULL);
1N/A
1N/A switch (info->si_code) {
1N/A
1N/A case FPE_INTDIV:
1N/A fputs(_("\nError: FPE_INTDIV (Integer: "
1N/A "divide by zero)"), stdout);
1N/A break;
1N/A
1N/A case FPE_INTOVF:
1N/A fputs(_("\nError: FPE_INTOVF (Integer: "
1N/A "overflow)"), stdout);
1N/A break;
1N/A
1N/A case FPE_FLTDIV:
1N/A fputs(_("\nError: FPE_FLTDIV (Float: "
1N/A "divide by zero)"), stdout);
1N/A break;
1N/A
1N/A case FPE_FLTOVF:
1N/A fputs(_("\nError: FPE_FLTOVF (Float: "
1N/A "overflow)"), stdout);
1N/A break;
1N/A
1N/A case FPE_FLTUND:
1N/A fputs(_("\nError: FPE_FLTUND (Float: "
1N/A "underflow)"), stdout);
1N/A break;
1N/A
1N/A case FPE_FLTRES:
1N/A fputs(_("\nError: FPE_FLTRES (Float: "
1N/A "inexact result)"), stdout);
1N/A break;
1N/A
1N/A case FPE_FLTINV:
1N/A fputs(_("\nError: FPE_FLTINV (Float: "
1N/A "invalid operation)"), stdout);
1N/A break;
1N/A
1N/A case FPE_FLTSUB:
1N/A fputs(_("\nError: FPE_FLTSUB (Float: "
1N/A "subscript out of range)"), stdout);
1N/A break;
1N/A
1N/A default:
1N/A fputs(_("\nError: A general SIGFPE signal "
1N/A "was encountered."), stdout);
1N/A break;
1N/A
1N/A }
1N/A
1N/A abort ();
1N/A}
1N/A
1N/A/* Signal handler for SIGILL using 'sigaction'. */
1N/Astatic void
1N/Asa_sigill_handler (int signum, siginfo_t* info, void* ucontext)
1N/A{
1N/A printf (bug_msg, VERSION);
1N/A _dump_history ();
1N/A
1N/A if (!info)
1N/A abort();
1N/A
1N/A sigaction (SIGILL, &sig_ill, NULL);
1N/A
1N/A switch (info->si_code) {
1N/A
1N/A case ILL_ILLOPC:
1N/A fputs(_("\nError: ILL_ILLOPC "
1N/A "(Illegal Opcode)"), stdout);
1N/A break;
1N/A
1N/A case ILL_ILLOPN:
1N/A fputs(_("\nError: ILL_ILLOPN "
1N/A "(Illegal Operand)"), stdout);
1N/A break;
1N/A
1N/A case ILL_ILLADR:
1N/A fputs(_("\nError: ILL_ILLADR "
1N/A "(Illegal addressing mode)"), stdout);
1N/A break;
1N/A
1N/A case ILL_ILLTRP:
1N/A fputs(_("\nError: ILL_ILLTRP "
1N/A "(Illegal Trap)"), stdout);
1N/A break;
1N/A
1N/A case ILL_PRVOPC:
1N/A fputs(_("\nError: ILL_PRVOPC "
1N/A "(Privileged Opcode)"), stdout);
1N/A break;
1N/A
1N/A case ILL_PRVREG:
1N/A fputs(_("\nError: ILL_PRVREG "
1N/A "(Privileged Register)"), stdout);
1N/A break;
1N/A
1N/A case ILL_COPROC:
1N/A fputs(_("\nError: ILL_COPROC "
1N/A "(Coprocessor Error)"), stdout);
1N/A break;
1N/A
1N/A case ILL_BADSTK:
1N/A fputs(_("\nError: ILL_BADSTK "
1N/A "(Internal Stack Error)"), stdout);
1N/A break;
1N/A
1N/A default:
1N/A fputs(_("\nError: A general SIGILL "
1N/A "signal was encountered."), stdout);
1N/A break;
1N/A }
1N/A
1N/A abort ();
1N/A}
1N/A
1N/A#ifndef SA_SIGINFO
1N/A
1N/Astatic void
1N/Amask_signal()
1N/A{
1N/A sigset_t curr;
1N/A sigset_t prev;
1N/A
1N/A sigfillset(&curr);
1N/A sigprocmask(SIG_SETMASK, &curr, &prev);
1N/A}
1N/A
1N/A/* Signal handler for SIGINT using 'signal'. */
1N/Astatic void
1N/As_sigint_handler (int signum)
1N/A{
1N/A signal (SIGINT, &s_sigint_handler);
1N/A mask_signal ();
1N/A sa_sigint_handler (signum, NULL, NULL);
1N/A}
1N/A
1N/A/* Signal handler for SIGILL using 'signal'. */
1N/Astatic void
1N/As_sigill_handler (int signum)
1N/A{
1N/A signal (SIGILL, &s_sigill_handler);
1N/A mask_signal ();
1N/A sa_sigill_handler (signum, NULL, NULL);
1N/A}
1N/A
1N/A/* Signal handler for SIGSEGV using 'signal'. */
1N/Astatic void
1N/As_sigsegv_handler (int signum)
1N/A{
1N/A signal (SIGSEGV, &s_sigsegv_handler);
1N/A mask_signal ();
1N/A sa_sigsegv_handler (signum, NULL, NULL);
1N/A}
1N/A
1N/A/* Signal handler for SIGFPE using 'signal'. */
1N/Astatic void
1N/As_sigfpe_handler (int signum)
1N/A{
1N/A signal (SIGFPE, &s_sigfpe_handler);
1N/A mask_signal ();
1N/A sa_sigfpe_handler (signum, NULL, NULL);
1N/A}
1N/A#endif
1N/A
1N/Astatic char*
1N/A_readline (const char* prompt, const StrList* possibilities)
1N/A{
1N/A char* line;
1N/A
1N/A readline_state.possibilities = possibilities;
1N/A readline_state.cur_pos = NULL;
1N/A readline_state.in_readline = 1;
1N/A
1N/A if (sigsetjmp (readline_state.jmp_state,1))
1N/A return NULL;
1N/A
1N/A wipe_line ();
1N/A#ifdef HAVE_LIBREADLINE
1N/A if (!opt_script_mode) {
1N/A /* XXX: why isn't prompt const? */
1N/A line = readline ((char*) prompt);
1N/A if (line)
1N/A _add_history_unique (line);
1N/A } else
1N/A#endif
1N/A {
1N/A fputs (prompt, stdout);
1N/A fflush (stdout);
1N/A line = (char*) malloc (256);
1N/A if (fgets (line, 256, stdin) && strcmp (line, "") != 0) {
1N/A#ifndef HAVE_LIBREADLINE
1N/A /* Echo the input line, to be consistent with
1N/A how readline-5.2 works. */
1N/A fputs (line, stdout);
1N/A fflush (stdout);
1N/A#endif
1N/A /* kill trailing NL */
1N/A if (strlen (line))
1N/A line [strlen (line) - 1] = 0;
1N/A } else {
1N/A free (line);
1N/A line = NULL;
1N/A }
1N/A }
1N/A
1N/A readline_state.in_readline = 0;
1N/A return line;
1N/A}
1N/A
1N/Astatic PedExceptionOption
1N/Aoption_get_next (PedExceptionOption options, PedExceptionOption current)
1N/A{
1N/A PedExceptionOption i;
1N/A
1N/A if (current == 0)
1N/A i = PED_EXCEPTION_OPTION_FIRST;
1N/A else
1N/A i = current * 2;
1N/A
1N/A for (; i <= options; i *= 2) {
1N/A if (options & i)
1N/A return i;
1N/A }
1N/A return 0;
1N/A}
1N/A
1N/Astatic void
1N/A_print_exception_text (PedException* ex)
1N/A{
1N/A StrList* text;
1N/A
1N/A wipe_line ();
1N/A
1N/A if (ex->type == PED_EXCEPTION_BUG) {
1N/A printf (bug_msg, VERSION);
1N/A text = str_list_create ("\n", ex->message, "\n\n", NULL);
1N/A } else {
1N/A text = str_list_create (
1N/A _(ped_exception_get_type_string (ex->type)),
1N/A ": ", ex->message, "\n", NULL);
1N/A }
1N/A
1N/A str_list_print_wrap (text, screen_width (), 0, 0);
1N/A str_list_destroy (text);
1N/A}
1N/A
1N/Astatic PedExceptionOption
1N/Aexception_handler (PedException* ex)
1N/A{
1N/A PedExceptionOption opt;
1N/A
1N/A _print_exception_text (ex);
1N/A
1N/A /* only one choice? Take it ;-) */
1N/A opt = option_get_next (ex->options, 0);
1N/A if (!option_get_next (ex->options, opt))
1N/A return opt;
1N/A
1N/A /* script-mode: don't handle the exception */
1N/A if (opt_script_mode || (!isatty (0) && !pretend_input_tty))
1N/A return PED_EXCEPTION_UNHANDLED;
1N/A
1N/A got_ctrl_c = 0;
1N/A
1N/A do {
1N/A opt = command_line_get_ex_opt ("", ex->options);
1N/A } while (opt == PED_EXCEPTION_UNHANDLED
1N/A && (isatty (0) || pretend_input_tty) && !got_ctrl_c);
1N/A
1N/A if (got_ctrl_c) {
1N/A got_ctrl_c = 0;
1N/A opt = PED_EXCEPTION_UNHANDLED;
1N/A }
1N/A
1N/A return opt;
1N/A}
1N/A
1N/Avoid
1N/Acommand_line_push_word (const char* word)
1N/A{
1N/A command_line = str_list_append (command_line, word);
1N/A}
1N/A
1N/Achar*
1N/Acommand_line_pop_word ()
1N/A{
1N/A char* result;
1N/A StrList* next;
1N/A
1N/A PED_ASSERT (command_line != NULL, return NULL);
1N/A
1N/A result = str_list_convert_node (command_line);
1N/A next = command_line->next;
1N/A
1N/A str_list_destroy_node (command_line);
1N/A command_line = next;
1N/A return result;
1N/A}
1N/A
1N/Avoid
1N/Acommand_line_flush ()
1N/A{
1N/A str_list_destroy (command_line);
1N/A command_line = NULL;
1N/A}
1N/A
1N/Achar*
1N/Acommand_line_peek_word ()
1N/A{
1N/A if (command_line)
1N/A return str_list_convert_node (command_line);
1N/A else
1N/A return NULL;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_word_count ()
1N/A{
1N/A return str_list_length (command_line);
1N/A}
1N/A
1N/Astatic int
1N/A_str_is_spaces (const char* str)
1N/A{
1N/A while (isspace (*str))
1N/A str++;
1N/A
1N/A return *str == 0;
1N/A}
1N/A
1N/A/* "multi_word mode" is the "normal" mode... many words can be typed,
1N/A * delimited by spaces, etc.
1N/A * In single-word mode, only one word is parsed per line.
1N/A * Leading and trailing spaces are removed. For example: " a b c "
1N/A * is a single word "a b c". The motivation for this mode is partition
1N/A * names, etc. In single-word mode, the empty string is a word.
1N/A * (but not in multi-word mode).
1N/A */
1N/Avoid
1N/Acommand_line_push_line (const char* line, int multi_word)
1N/A{
1N/A int quoted = 0;
1N/A char quote_char = 0;
1N/A char this_word [256];
1N/A int i;
1N/A
1N/A do {
1N/A while (*line == ' ')
1N/A line++;
1N/A
1N/A i = 0;
1N/A for (; *line; line++) {
1N/A if (*line == ' ' && !quoted) {
1N/A if (multi_word)
1N/A break;
1N/A
1N/A /* single word: check for trailing spaces + eol */
1N/A if (_str_is_spaces (line))
1N/A break;
1N/A }
1N/A
1N/A if (!quoted && strchr ("'\"", *line)) {
1N/A quoted = 1;
1N/A quote_char = *line;
1N/A continue;
1N/A }
1N/A
1N/A if (quoted && *line == quote_char) {
1N/A quoted = 0;
1N/A continue;
1N/A }
1N/A
1N/A /* hack: escape characters */
1N/A if (quoted && line[0] == '\\' && line[1])
1N/A line++;
1N/A
1N/A this_word [i++] = *line;
1N/A }
1N/A if (i || !multi_word) {
1N/A this_word [i] = 0;
1N/A command_line_push_word (this_word);
1N/A }
1N/A } while (*line && multi_word);
1N/A}
1N/A
1N/Astatic char*
1N/Arealloc_and_cat (char* str, const char* append)
1N/A{
1N/A int length = strlen (str) + strlen (append) + 1;
1N/A char* new_str = realloc (str, length);
1N/A
1N/A strcat (new_str, append);
1N/A return new_str;
1N/A}
1N/A
1N/Astatic char*
1N/A_construct_prompt (const char* head, const char* def,
1N/A const StrList* possibilities)
1N/A{
1N/A char* prompt = strdup (head);
1N/A
1N/A if (def && possibilities)
1N/A PED_ASSERT (str_list_match_any (possibilities, def),
1N/A return NULL);
1N/A
1N/A if (possibilities && str_list_length (possibilities) < 8) {
1N/A const StrList* walk;
1N/A
1N/A if (strlen (prompt))
1N/A prompt = realloc_and_cat (prompt, " ");
1N/A
1N/A for (walk = possibilities; walk; walk = walk->next) {
1N/A if (walk != possibilities)
1N/A prompt = realloc_and_cat (prompt, "/");
1N/A
1N/A if (def && str_list_match_node (walk, def) == 2) {
1N/A prompt = realloc_and_cat (prompt, "[");
1N/A prompt = realloc_and_cat (prompt, def);
1N/A prompt = realloc_and_cat (prompt, "]");
1N/A } else {
1N/A char* text = str_list_convert_node (walk);
1N/A prompt = realloc_and_cat (prompt, text);
1N/A free (text);
1N/A }
1N/A }
1N/A prompt = realloc_and_cat (prompt, "? ");
1N/A } else if (def) {
1N/A if (strlen (prompt))
1N/A prompt = realloc_and_cat (prompt, " ");
1N/A prompt = realloc_and_cat (prompt, "[");
1N/A prompt = realloc_and_cat (prompt, def);
1N/A prompt = realloc_and_cat (prompt, "]? ");
1N/A } else {
1N/A if (strlen (prompt))
1N/A prompt = realloc_and_cat (prompt, " ");
1N/A }
1N/A
1N/A return prompt;
1N/A}
1N/A
1N/Avoid
1N/Acommand_line_prompt_words (const char* prompt, const char* def,
1N/A const StrList* possibilities, int multi_word)
1N/A{
1N/A char* line;
1N/A char* real_prompt;
1N/A char* _def = (char*) def;
1N/A int _def_needs_free = 0;
1N/A
1N/A if (!def && str_list_length (possibilities) == 1) {
1N/A _def = str_list_convert_node (possibilities);
1N/A _def_needs_free = 1;
1N/A }
1N/A
1N/A if (opt_script_mode) {
1N/A if (_def)
1N/A command_line_push_line (_def, 0);
1N/A return;
1N/A }
1N/A
1N/A do {
1N/A real_prompt = _construct_prompt (prompt, _def, possibilities);
1N/A line = _readline (real_prompt, possibilities);
1N/A free (real_prompt);
1N/A if (!line) {
1N/A /* readline returns NULL to indicate EOF.
1N/A Treat that like an interrupt. */
1N/A got_ctrl_c = 1;
1N/A break;
1N/A }
1N/A
1N/A if (!strlen (line)) {
1N/A if (_def)
1N/A command_line_push_line (_def, 0);
1N/A } else {
1N/A command_line_push_line (line, multi_word);
1N/A }
1N/A free (line);
1N/A } while (!command_line_get_word_count () && !_def);
1N/A
1N/A if (_def_needs_free)
1N/A free (_def);
1N/A}
1N/A
1N/A/**
1N/A * Get a word from command line.
1N/A *
1N/A * \param possibilities a StrList of valid strings, NULL if all are valid.
1N/A * \param multi_word whether multiple words are allowed.
1N/A *
1N/A * \return The word(s), or NULL if empty.
1N/A */
1N/Achar*
1N/Acommand_line_get_word (const char* prompt, const char* def,
1N/A const StrList* possibilities, int multi_word)
1N/A{
1N/A do {
1N/A if (command_line_get_word_count ()) {
1N/A char* result = command_line_pop_word ();
1N/A StrList* result_node;
1N/A
1N/A if (!possibilities)
1N/A return result;
1N/A
1N/A result_node = str_list_match (possibilities, result);
1N/A if (result_node == NULL)
1N/A error (0, 0, _("invalid token: %s"), result);
1N/A free (result);
1N/A if (result_node)
1N/A return str_list_convert_node (result_node);
1N/A
1N/A command_line_flush ();
1N/A if (opt_script_mode)
1N/A return NULL;
1N/A }
1N/A
1N/A command_line_prompt_words (prompt, def, possibilities,
1N/A multi_word);
1N/A } while (command_line_get_word_count ());
1N/A
1N/A return NULL;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_integer (const char* prompt, int* value)
1N/A{
1N/A char def_str [10];
1N/A char* input;
1N/A int valid;
1N/A
1N/A snprintf (def_str, 10, "%d", *value);
1N/A input = command_line_get_word (prompt, *value ? def_str : NULL,
1N/A NULL, 1);
1N/A if (!input)
1N/A return 0;
1N/A valid = sscanf (input, "%d", value);
1N/A free (input);
1N/A return valid;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_sector (const char* prompt, PedDevice* dev, PedSector* value,
1N/A PedGeometry** range)
1N/A{
1N/A char* def_str;
1N/A char* input;
1N/A int valid;
1N/A
1N/A def_str = ped_unit_format (dev, *value);
1N/A input = command_line_get_word (prompt, *value ? def_str : NULL,
1N/A NULL, 1);
1N/A
1N/A /* def_str might have rounded *value a little bit. If the user picked
1N/A * the default, make sure the selected sector is identical to the
1N/A * default.
1N/A */
1N/A if (input && *value && !strcmp (input, def_str)) {
1N/A if (range) {
1N/A *range = ped_geometry_new (dev, *value, 1);
1N/A free (def_str);
1N/A return *range != NULL;
1N/A }
1N/A
1N/A free (def_str);
1N/A return 1;
1N/A }
1N/A
1N/A free (def_str);
1N/A if (!input) {
1N/A *value = 0;
1N/A if (range)
1N/A *range = NULL;
1N/A return 0;
1N/A }
1N/A
1N/A valid = ped_unit_parse (input, dev, value, range);
1N/A
1N/A free (input);
1N/A return valid;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_state (const char* prompt, int* value)
1N/A{
1N/A char* def_word;
1N/A char* input;
1N/A
1N/A if (*value)
1N/A def_word = str_list_convert_node (on_list);
1N/A else
1N/A def_word = str_list_convert_node (off_list);
1N/A input = command_line_get_word (prompt, def_word, on_off_list, 1);
1N/A free (def_word);
1N/A if (!input)
1N/A return 0;
1N/A if (str_list_match_any (on_list, input))
1N/A *value = 1;
1N/A else
1N/A *value = 0;
1N/A free (input);
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_device (const char* prompt, PedDevice** value)
1N/A{
1N/A char *def_dev_name = *value ? (*value)->path : NULL;
1N/A char *dev_name = command_line_get_word (prompt, def_dev_name, NULL, 1);
1N/A if (!dev_name)
1N/A return 0;
1N/A
1N/A PedDevice *dev = ped_device_get (dev_name);
1N/A free (dev_name);
1N/A if (!dev)
1N/A return 0;
1N/A
1N/A *value = dev;
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_disk (const char* prompt, PedDisk** value)
1N/A{
1N/A PedDevice* dev = *value ? (*value)->dev : NULL;
1N/A
1N/A if (!command_line_get_device (prompt, &dev))
1N/A return 0;
1N/A
1N/A assert (*value);
1N/A if (dev != (*value)->dev) {
1N/A PedDisk* new_disk = ped_disk_new (dev);
1N/A if (!new_disk)
1N/A return 0;
1N/A *value = new_disk;
1N/A }
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_partition (const char* prompt, PedDisk* disk,
1N/A PedPartition** value)
1N/A{
1N/A PedPartition* part;
1N/A
1N/A /* Flawed logic, doesn't seem to work?!
1N/A check = ped_disk_next_partition (disk, part);
1N/A part = ped_disk_next_partition (disk, check);
1N/A
1N/A if (part == NULL) {
1N/A
1N/A *value = check;
1N/A printf (_("The (only) primary partition has "
1N/A "been automatically selected\n"));
1N/A return 1;
1N/A
1N/A } else {
1N/A */
1N/A int num = (*value) ? (*value)->num : 0;
1N/A
1N/A if (!command_line_get_integer (prompt, &num)) {
1N/A ped_exception_throw (PED_EXCEPTION_ERROR,
1N/A PED_EXCEPTION_CANCEL,
1N/A _("Expecting a partition number."));
1N/A return 0;
1N/A }
1N/A
1N/A part = ped_disk_get_partition (disk, num);
1N/A
1N/A if (!part) {
1N/A ped_exception_throw (PED_EXCEPTION_ERROR,
1N/A PED_EXCEPTION_CANCEL,
1N/A _("Partition doesn't exist."));
1N/A return 0;
1N/A }
1N/A
1N/A *value = part;
1N/A return 1;
1N/A //}
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_fs_type (const char* prompt, const PedFileSystemType*(* value))
1N/A{
1N/A char* fs_type_name;
1N/A PedFileSystemType* fs_type;
1N/A
1N/A fs_type_name = command_line_get_word (prompt,
1N/A *value ? (*value)->name : NULL,
1N/A fs_type_list, 1);
1N/A if (!fs_type_name) {
1N/A ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1N/A _("Expecting a file system type."));
1N/A return 0;
1N/A }
1N/A
1N/A fs_type = ped_file_system_type_get (fs_type_name);
1N/A if (!fs_type) {
1N/A ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1N/A _("Unknown file system type \"%s\"."),
1N/A fs_type_name);
1N/A return 0;
1N/A }
1N/A
1N/A free (fs_type_name);
1N/A *value = fs_type;
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_disk_type (const char* prompt, const PedDiskType*(* value))
1N/A{
1N/A char* disk_type_name;
1N/A
1N/A disk_type_name = command_line_get_word (prompt,
1N/A *value ? (*value)->name : NULL,
1N/A disk_type_list, 1);
1N/A if (!disk_type_name) {
1N/A ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1N/A _("Expecting a disk label type."));
1N/A return 0;
1N/A }
1N/A
1N/A *value = ped_disk_type_get (disk_type_name);
1N/A free (disk_type_name);
1N/A PED_ASSERT (*value != NULL, return 0);
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_part_flag (const char* prompt, const PedPartition* part,
1N/A PedPartitionFlag* flag)
1N/A{
1N/A StrList* opts = NULL;
1N/A PedPartitionFlag walk = 0;
1N/A char* flag_name;
1N/A
1N/A while ( (walk = ped_partition_flag_next (walk)) ) {
1N/A if (ped_partition_is_flag_available (part, walk)) {
1N/A const char* walk_name;
1N/A
1N/A walk_name = ped_partition_flag_get_name (walk);
1N/A opts = str_list_append (opts, walk_name);
1N/A opts = str_list_append_unique (opts, _(walk_name));
1N/A }
1N/A }
1N/A
1N/A flag_name = command_line_get_word (prompt, NULL, opts, 1);
1N/A str_list_destroy (opts);
1N/A
1N/A if (flag_name) {
1N/A *flag = ped_partition_flag_get_by_name (flag_name);
1N/A free (flag_name);
1N/A return 1;
1N/A } else
1N/A return 0;
1N/A}
1N/A
1N/Astatic int
1N/A_can_create_primary (const PedDisk* disk)
1N/A{
1N/A int i;
1N/A
1N/A for (i = 1; i <= ped_disk_get_max_primary_partition_count (disk); i++) {
1N/A if (!ped_disk_get_partition (disk, i))
1N/A return 1;
1N/A }
1N/A
1N/A return 0;
1N/A}
1N/A
1N/Astatic int
1N/A_can_create_extended (const PedDisk* disk)
1N/A{
1N/A if (!_can_create_primary (disk))
1N/A return 0;
1N/A
1N/A if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1N/A return 0;
1N/A
1N/A if (ped_disk_extended_partition (disk))
1N/A return 0;
1N/A
1N/A return 1;
1N/A}
1N/A
1N/Astatic int
1N/A_can_create_logical (const PedDisk* disk)
1N/A{
1N/A if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1N/A return 0;
1N/A
1N/A return ped_disk_extended_partition (disk) != 0;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_part_type (const char* prompt, const PedDisk* disk,
1N/A PedPartitionType* type)
1N/A{
1N/A StrList* opts = NULL;
1N/A char* type_name;
1N/A
1N/A if (_can_create_primary (disk)) {
1N/A opts = str_list_append_unique (opts, "primary");
1N/A opts = str_list_append_unique (opts, _("primary"));
1N/A }
1N/A if (_can_create_extended (disk)) {
1N/A opts = str_list_append_unique (opts, "extended");
1N/A opts = str_list_append_unique (opts, _("extended"));
1N/A }
1N/A if (_can_create_logical (disk)) {
1N/A opts = str_list_append_unique (opts, "logical");
1N/A opts = str_list_append_unique (opts, _("logical"));
1N/A }
1N/A if (!opts) {
1N/A ped_exception_throw (
1N/A PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1N/A _("Can't create any more partitions."));
1N/A return 0;
1N/A }
1N/A
1N/A type_name = command_line_get_word (prompt, NULL, opts, 1);
1N/A str_list_destroy (opts);
1N/A
1N/A if (!type_name) {
1N/A ped_exception_throw (
1N/A PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1N/A _("Expecting a partition type."));
1N/A return 0;
1N/A }
1N/A
1N/A if (!strcmp (type_name, "primary")
1N/A || !strcmp (type_name, _("primary"))) {
1N/A *type = 0;
1N/A }
1N/A if (!strcmp (type_name, "extended")
1N/A || !strcmp (type_name, _("extended"))) {
1N/A *type = PED_PARTITION_EXTENDED;
1N/A }
1N/A if (!strcmp (type_name, "logical")
1N/A || !strcmp (type_name, _("logical"))) {
1N/A *type = PED_PARTITION_LOGICAL;
1N/A }
1N/A
1N/A free (type_name);
1N/A return 1;
1N/A}
1N/A
1N/APedExceptionOption
1N/Acommand_line_get_ex_opt (const char* prompt, PedExceptionOption options)
1N/A{
1N/A StrList* options_strlist = NULL;
1N/A PedExceptionOption opt;
1N/A char* opt_name;
1N/A
1N/A for (opt = option_get_next (options, 0); opt;
1N/A opt = option_get_next (options, opt)) {
1N/A options_strlist = str_list_append_unique (options_strlist,
1N/A _(ped_exception_get_option_string (opt)));
1N/A options_strlist = str_list_append_unique (options_strlist,
1N/A ped_exception_get_option_string (opt));
1N/A }
1N/A
1N/A opt_name = command_line_get_word (prompt, NULL, options_strlist, 1);
1N/A if (!opt_name)
1N/A return PED_EXCEPTION_UNHANDLED;
1N/A str_list_destroy (options_strlist);
1N/A
1N/A opt = PED_EXCEPTION_OPTION_FIRST;
1N/A while (1) {
1N/A if (strcmp (opt_name,
1N/A ped_exception_get_option_string (opt)) == 0)
1N/A break;
1N/A if (strcmp (opt_name,
1N/A _(ped_exception_get_option_string (opt))) == 0)
1N/A break;
1N/A opt = option_get_next (options, opt);
1N/A }
1N/A free (opt_name);
1N/A return opt;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_align_type (const char *prompt, enum AlignmentType *align_type)
1N/A{
1N/A char* def_word;
1N/A char* input;
1N/A
1N/A if (*align_type)
1N/A def_word = str_list_convert_node (align_opt_list);
1N/A else
1N/A def_word = str_list_convert_node (align_min_list);
1N/A input = command_line_get_word (prompt, def_word, align_opt_min_list, 1);
1N/A free (def_word);
1N/A if (!input)
1N/A return 0;
1N/A *align_type = (str_list_match_any (align_opt_list, input)
1N/A ? PA_OPTIMUM
1N/A : PA_MINIMUM);
1N/A free (input);
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_get_unit (const char* prompt, PedUnit* unit)
1N/A{
1N/A StrList* opts = NULL;
1N/A PedUnit walk;
1N/A char* unit_name;
1N/A const char* default_unit_name;
1N/A
1N/A for (walk = PED_UNIT_FIRST; walk <= PED_UNIT_LAST; walk++)
1N/A opts = str_list_append (opts, ped_unit_get_name (walk));
1N/A
1N/A default_unit_name = ped_unit_get_name (ped_unit_get_default ());
1N/A unit_name = command_line_get_word (prompt, default_unit_name, opts, 1);
1N/A str_list_destroy (opts);
1N/A
1N/A if (unit_name) {
1N/A *unit = ped_unit_get_by_name (unit_name);
1N/A free (unit_name);
1N/A return 1;
1N/A } else
1N/A return 0;
1N/A}
1N/A
1N/Aint
1N/Acommand_line_is_integer ()
1N/A{
1N/A char* word;
1N/A int is_integer;
1N/A int scratch;
1N/A
1N/A word = command_line_peek_word ();
1N/A if (!word)
1N/A return 0;
1N/A
1N/A is_integer = sscanf (word, "%d", &scratch);
1N/A free (word);
1N/A return is_integer;
1N/A}
1N/A
1N/Astatic int
1N/Ainit_ex_opt_str ()
1N/A{
1N/A int i;
1N/A PedExceptionOption opt;
1N/A
1N/A for (i = 0; (1 << i) <= PED_EXCEPTION_OPTION_LAST; i++) {
1N/A opt = (1 << i);
1N/A ex_opt_str [i]
1N/A = str_list_create (
1N/A ped_exception_get_option_string (opt),
1N/A _(ped_exception_get_option_string (opt)),
1N/A NULL);
1N/A if (!ex_opt_str [i])
1N/A return 0;
1N/A }
1N/A
1N/A ex_opt_str [i] = NULL;
1N/A return 1;
1N/A}
1N/A
1N/Astatic void
1N/Adone_ex_opt_str ()
1N/A{
1N/A int i;
1N/A
1N/A for (i=0; ex_opt_str [i]; i++)
1N/A str_list_destroy (ex_opt_str [i]);
1N/A}
1N/A
1N/Astatic int
1N/Ainit_state_str ()
1N/A{
1N/A on_list = str_list_create_unique (_("on"), "on", NULL);
1N/A off_list = str_list_create_unique (_("off"), "off", NULL);
1N/A on_off_list = str_list_join (str_list_duplicate (on_list),
1N/A str_list_duplicate (off_list));
1N/A return 1;
1N/A}
1N/A
1N/Astatic void
1N/Adone_state_str ()
1N/A{
1N/A str_list_destroy (on_list);
1N/A str_list_destroy (off_list);
1N/A str_list_destroy (on_off_list);
1N/A}
1N/A
1N/Astatic int
1N/Ainit_alignment_type_str ()
1N/A{
1N/A align_opt_list = str_list_create_unique (_("optimal"), "optimal", NULL);
1N/A align_min_list = str_list_create_unique (_("minimal"), "minimal", NULL);
1N/A align_opt_min_list = str_list_join (str_list_duplicate (align_opt_list),
1N/A str_list_duplicate (align_min_list));
1N/A return 1;
1N/A}
1N/A
1N/Astatic void
1N/Adone_alignment_type_str ()
1N/A{
1N/A str_list_destroy (align_opt_list);
1N/A str_list_destroy (align_min_list);
1N/A str_list_destroy (align_opt_min_list);
1N/A}
1N/A
1N/Astatic int
1N/Ainit_fs_type_str ()
1N/A{
1N/A PedFileSystemType* walk;
1N/A PedFileSystemAlias* alias_walk;
1N/A
1N/A fs_type_list = NULL;
1N/A
1N/A for (walk = ped_file_system_type_get_next (NULL); walk;
1N/A walk = ped_file_system_type_get_next (walk))
1N/A {
1N/A fs_type_list = str_list_insert (fs_type_list, walk->name);
1N/A if (!fs_type_list)
1N/A return 0;
1N/A }
1N/A for (alias_walk = ped_file_system_alias_get_next (NULL); alias_walk;
1N/A alias_walk = ped_file_system_alias_get_next (alias_walk))
1N/A {
1N/A fs_type_list = str_list_insert (fs_type_list,
1N/A alias_walk->alias);
1N/A if (!fs_type_list)
1N/A return 0;
1N/A }
1N/A
1N/A return 1;
1N/A}
1N/A
1N/Astatic int
1N/Ainit_disk_type_str ()
1N/A{
1N/A PedDiskType* walk;
1N/A
1N/A disk_type_list = NULL;
1N/A
1N/A for (walk = ped_disk_type_get_next (NULL); walk;
1N/A walk = ped_disk_type_get_next (walk))
1N/A {
1N/A disk_type_list = str_list_insert (disk_type_list, walk->name);
1N/A if (!disk_type_list)
1N/A return 0;
1N/A }
1N/A
1N/A return 1;
1N/A}
1N/A
1N/Aint
1N/Ainit_readline (void)
1N/A{
1N/A#ifdef HAVE_LIBREADLINE
1N/A if (!opt_script_mode) {
1N/A rl_initialize ();
1N/A rl_attempted_completion_function = (CPPFunction*) complete_function;
1N/A readline_state.in_readline = 0;
1N/A }
1N/A#endif
1N/A return 0;
1N/A}
1N/A
1N/Aint
1N/Ainit_ui ()
1N/A{
1N/A if (!init_ex_opt_str ()
1N/A || !init_state_str ()
1N/A || !init_alignment_type_str ()
1N/A || !init_fs_type_str ()
1N/A || !init_disk_type_str ())
1N/A return 0;
1N/A ped_exception_set_handler (exception_handler);
1N/A
1N/A#ifdef SA_SIGINFO
1N/A sigset_t curr;
1N/A sigfillset (&curr);
1N/A
1N/A sig_segv.sa_sigaction = &sa_sigsegv_handler;
1N/A sig_int.sa_sigaction = &sa_sigint_handler;
1N/A sig_fpe.sa_sigaction = &sa_sigfpe_handler;
1N/A sig_ill.sa_sigaction = &sa_sigill_handler;
1N/A
1N/A sig_segv.sa_mask =
1N/A sig_int.sa_mask =
1N/A sig_fpe.sa_mask =
1N/A sig_ill.sa_mask = curr;
1N/A
1N/A sig_segv.sa_flags =
1N/A sig_int.sa_flags =
1N/A sig_fpe.sa_flags =
1N/A sig_ill.sa_flags = SA_SIGINFO;
1N/A
1N/A sigaction (SIGSEGV, &sig_segv, NULL);
1N/A sigaction (SIGINT, &sig_int, NULL);
1N/A sigaction (SIGFPE, &sig_fpe, NULL);
1N/A sigaction (SIGILL, &sig_ill, NULL);
1N/A#else
1N/A signal (SIGSEGV, s_sigsegv_handler);
1N/A signal (SIGINT, s_sigint_handler);
1N/A signal (SIGFPE, s_sigfpe_handler);
1N/A signal (SIGILL, s_sigill_handler);
1N/A#endif /* SA_SIGINFO */
1N/A
1N/A return 1;
1N/A}
1N/A
1N/Avoid
1N/Adone_ui ()
1N/A{
1N/A ped_exception_set_handler (NULL);
1N/A done_ex_opt_str ();
1N/A done_state_str ();
1N/A done_alignment_type_str ();
1N/A str_list_destroy (fs_type_list);
1N/A str_list_destroy (disk_type_list);
1N/A}
1N/A
1N/Avoid
1N/Ahelp_msg ()
1N/A{
1N/A fputs (_(usage_msg), stdout);
1N/A
1N/A putchar ('\n');
1N/A fputs (_("OPTIONs:"), stdout);
1N/A putchar ('\n');
1N/A print_options_help ();
1N/A
1N/A putchar ('\n');
1N/A fputs (_("COMMANDs:"), stdout);
1N/A putchar ('\n');
1N/A print_commands_help ();
1N/A printf (_("\nReport bugs to %s\n"), PACKAGE_BUGREPORT);
1N/A exit (EXIT_SUCCESS);
1N/A}
1N/A
1N/Avoid
1N/Aprint_using_dev (PedDevice* dev)
1N/A{
1N/A printf (_("Using %s\n"), dev->path);
1N/A}
1N/A
1N/Aint
1N/Ainteractive_mode (PedDevice** dev, Command* cmd_list[])
1N/A{
1N/A StrList* list;
1N/A StrList* command_names = command_get_names (cmd_list);
1N/A
1N/A commands = cmd_list; /* FIXME yucky, nasty, evil hack */
1N/A
1N/A fputs (prog_name, stdout);
1N/A
1N/A print_using_dev (*dev);
1N/A
1N/A list = str_list_create (_(banner_msg), NULL);
1N/A str_list_print_wrap (list, screen_width (), 0, 0);
1N/A str_list_destroy (list);
1N/A
1N/A while (1) {
1N/A char* word;
1N/A Command* cmd;
1N/A
1N/A while (!command_line_get_word_count ()) {
1N/A if (feof (stdin)) {
1N/A putchar ('\n');
1N/A return 1;
1N/A }
1N/A command_line_prompt_words ("(parted)", NULL,
1N/A command_names, 1);
1N/A }
1N/A
1N/A word = command_line_pop_word ();
1N/A if (word) {
1N/A cmd = command_get (commands, word);
1N/A free (word);
1N/A if (cmd) {
1N/A if (!command_run (cmd, dev))
1N/A command_line_flush ();
1N/A } else
1N/A print_commands_help ();
1N/A }
1N/A }
1N/A
1N/A return 1;
1N/A}
1N/A
1N/A
1N/Aint
1N/Anon_interactive_mode (PedDevice** dev, Command* cmd_list[],
1N/A int argc, char* argv[])
1N/A{
1N/A int i;
1N/A Command* cmd;
1N/A
1N/A commands = cmd_list; /* FIXME yucky, nasty, evil hack */
1N/A
1N/A for (i = 0; i < argc; i++)
1N/A command_line_push_line (argv [i], 1);
1N/A
1N/A while (command_line_get_word_count ()) {
1N/A char* word;
1N/A
1N/A word = command_line_pop_word ();
1N/A if (!word)
1N/A break;
1N/A
1N/A cmd = command_get (commands, word);
1N/A free (word);
1N/A if (!cmd) {
1N/A help_msg ();
1N/A goto error;
1N/A }
1N/A if (!(cmd->non_interactive)) {
1N/A fputs(_("This command does not make sense in "
1N/A "non-interactive mode.\n"), stdout);
1N/A exit(EXIT_FAILURE);
1N/A goto error;
1N/A }
1N/A
1N/A if (!command_run (cmd, dev))
1N/A goto error;
1N/A }
1N/A return 1;
1N/A
1N/Aerror:
1N/A return 0;
1N/A}