xref: /onnv-gate/usr/src/cmd/parted/ui.c (revision 9663:ace9a2ac3683)
1*9663SMark.Logan@Sun.COM /*
2*9663SMark.Logan@Sun.COM     parted - a frontend to libparted
3*9663SMark.Logan@Sun.COM     Copyright (C) 1999, 2000, 2001, 2002, 2006, 2007
4*9663SMark.Logan@Sun.COM     Free Software Foundation, Inc.
5*9663SMark.Logan@Sun.COM 
6*9663SMark.Logan@Sun.COM     This program is free software; you can redistribute it and/or modify
7*9663SMark.Logan@Sun.COM     it under the terms of the GNU General Public License as published by
8*9663SMark.Logan@Sun.COM     the Free Software Foundation; either version 3 of the License, or
9*9663SMark.Logan@Sun.COM     (at your option) any later version.
10*9663SMark.Logan@Sun.COM 
11*9663SMark.Logan@Sun.COM     This program is distributed in the hope that it will be useful,
12*9663SMark.Logan@Sun.COM     but WITHOUT ANY WARRANTY; without even the implied warranty of
13*9663SMark.Logan@Sun.COM     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14*9663SMark.Logan@Sun.COM     GNU General Public License for more details.
15*9663SMark.Logan@Sun.COM 
16*9663SMark.Logan@Sun.COM     You should have received a copy of the GNU General Public License
17*9663SMark.Logan@Sun.COM     along with this program.  If not, see <http://www.gnu.org/licenses/>.
18*9663SMark.Logan@Sun.COM */
19*9663SMark.Logan@Sun.COM 
20*9663SMark.Logan@Sun.COM #include <parted/parted.h>
21*9663SMark.Logan@Sun.COM #include <parted/debug.h>
22*9663SMark.Logan@Sun.COM 
23*9663SMark.Logan@Sun.COM #include <ctype.h>
24*9663SMark.Logan@Sun.COM #include <signal.h>
25*9663SMark.Logan@Sun.COM #include <stdlib.h>
26*9663SMark.Logan@Sun.COM #include <string.h>
27*9663SMark.Logan@Sun.COM #include <unistd.h>
28*9663SMark.Logan@Sun.COM #include <setjmp.h>
29*9663SMark.Logan@Sun.COM 
30*9663SMark.Logan@Sun.COM #include <config.h>
31*9663SMark.Logan@Sun.COM #include "command.h"
32*9663SMark.Logan@Sun.COM #include "strlist.h"
33*9663SMark.Logan@Sun.COM #include "ui.h"
34*9663SMark.Logan@Sun.COM #include "error.h"
35*9663SMark.Logan@Sun.COM 
36*9663SMark.Logan@Sun.COM #define N_(String) String
37*9663SMark.Logan@Sun.COM #if ENABLE_NLS
38*9663SMark.Logan@Sun.COM #  include <libintl.h>
39*9663SMark.Logan@Sun.COM #  include <locale.h>
40*9663SMark.Logan@Sun.COM #  define _(String) dgettext (PACKAGE, String)
41*9663SMark.Logan@Sun.COM #else
42*9663SMark.Logan@Sun.COM #  define _(String) (String)
43*9663SMark.Logan@Sun.COM #endif /* ENABLE_NLS */
44*9663SMark.Logan@Sun.COM 
45*9663SMark.Logan@Sun.COM #ifdef HAVE_LIBREADLINE
46*9663SMark.Logan@Sun.COM 
47*9663SMark.Logan@Sun.COM #ifdef HAVE_TERMCAP_H
48*9663SMark.Logan@Sun.COM #include <termcap.h>
49*9663SMark.Logan@Sun.COM #else
50*9663SMark.Logan@Sun.COM extern int tgetnum (char* key);
51*9663SMark.Logan@Sun.COM #endif
52*9663SMark.Logan@Sun.COM 
53*9663SMark.Logan@Sun.COM #include <readline/readline.h>
54*9663SMark.Logan@Sun.COM #include <readline/history.h>
55*9663SMark.Logan@Sun.COM 
56*9663SMark.Logan@Sun.COM #ifndef HAVE_RL_COMPLETION_MATCHES
57*9663SMark.Logan@Sun.COM #define rl_completion_matches completion_matches
58*9663SMark.Logan@Sun.COM #endif
59*9663SMark.Logan@Sun.COM 
60*9663SMark.Logan@Sun.COM #ifndef rl_compentry_func_t
61*9663SMark.Logan@Sun.COM #define rl_compentry_func_t void
62*9663SMark.Logan@Sun.COM #endif
63*9663SMark.Logan@Sun.COM 
64*9663SMark.Logan@Sun.COM #endif /* HAVE_LIBREADLINE */
65*9663SMark.Logan@Sun.COM 
66*9663SMark.Logan@Sun.COM #ifndef SA_SIGINFO
67*9663SMark.Logan@Sun.COM #  ifndef HAVE_SIGACTION
68*9663SMark.Logan@Sun.COM 
69*9663SMark.Logan@Sun.COM struct sigaction {
70*9663SMark.Logan@Sun.COM };
71*9663SMark.Logan@Sun.COM 
72*9663SMark.Logan@Sun.COM static inline int
sigaction(int signum,const struct * sigaction,struct * sigaction)73*9663SMark.Logan@Sun.COM sigaction (int signum, const struct* sigaction, struct* sigaction)
74*9663SMark.Logan@Sun.COM {
75*9663SMark.Logan@Sun.COM }
76*9663SMark.Logan@Sun.COM 
77*9663SMark.Logan@Sun.COM #  endif /* HAVE_SIGACTON */
78*9663SMark.Logan@Sun.COM 
79*9663SMark.Logan@Sun.COM struct siginfo_t {
80*9663SMark.Logan@Sun.COM         int si_code;
81*9663SMark.Logan@Sun.COM };
82*9663SMark.Logan@Sun.COM 
83*9663SMark.Logan@Sun.COM #endif /* SA_SIGINFO */
84*9663SMark.Logan@Sun.COM 
85*9663SMark.Logan@Sun.COM #ifndef SEGV_MAPERR
86*9663SMark.Logan@Sun.COM #  define SEGV_MAPERR (INTMAX - 1)
87*9663SMark.Logan@Sun.COM #endif
88*9663SMark.Logan@Sun.COM 
89*9663SMark.Logan@Sun.COM #ifndef SEGV_ACCERR
90*9663SMark.Logan@Sun.COM #  define SEGV_ACCERR (INTMAX - 2)
91*9663SMark.Logan@Sun.COM #endif
92*9663SMark.Logan@Sun.COM 
93*9663SMark.Logan@Sun.COM #ifndef FPE_INTDIV
94*9663SMark.Logan@Sun.COM #  define FPE_INTDIV (INTMAX - 1)
95*9663SMark.Logan@Sun.COM #endif
96*9663SMark.Logan@Sun.COM 
97*9663SMark.Logan@Sun.COM #ifndef FPE_INTOVF
98*9663SMark.Logan@Sun.COM #  define FPE_INTOVF (INTMAX - 2)
99*9663SMark.Logan@Sun.COM #endif
100*9663SMark.Logan@Sun.COM 
101*9663SMark.Logan@Sun.COM #ifndef FPE_FLTDIV
102*9663SMark.Logan@Sun.COM #  define FPE_FLTDIV (INTMAX - 3)
103*9663SMark.Logan@Sun.COM #endif
104*9663SMark.Logan@Sun.COM 
105*9663SMark.Logan@Sun.COM #ifndef FPE_FLTOVF
106*9663SMark.Logan@Sun.COM #  define FPE_FLTOVF (INTMAX - 4)
107*9663SMark.Logan@Sun.COM #endif
108*9663SMark.Logan@Sun.COM 
109*9663SMark.Logan@Sun.COM #ifndef FPE_FLTUND
110*9663SMark.Logan@Sun.COM #  define FPE_FLTUND (INTMAX - 5)
111*9663SMark.Logan@Sun.COM #endif
112*9663SMark.Logan@Sun.COM 
113*9663SMark.Logan@Sun.COM #ifndef FPE_FLTRES
114*9663SMark.Logan@Sun.COM #  define FPE_FLTRES (INTMAX - 6)
115*9663SMark.Logan@Sun.COM #endif
116*9663SMark.Logan@Sun.COM 
117*9663SMark.Logan@Sun.COM #ifndef FPE_FLTINV
118*9663SMark.Logan@Sun.COM #  define FPE_FLTINV (INTMAX - 7)
119*9663SMark.Logan@Sun.COM #endif
120*9663SMark.Logan@Sun.COM 
121*9663SMark.Logan@Sun.COM #ifndef FPE_FLTSUB
122*9663SMark.Logan@Sun.COM #  define FPE_FLTSUB (INTMAX - 8)
123*9663SMark.Logan@Sun.COM #endif
124*9663SMark.Logan@Sun.COM 
125*9663SMark.Logan@Sun.COM #ifndef ILL_ILLOPC
126*9663SMark.Logan@Sun.COM #  define ILL_ILLOPC (INTMAX - 1)
127*9663SMark.Logan@Sun.COM #endif
128*9663SMark.Logan@Sun.COM 
129*9663SMark.Logan@Sun.COM #ifndef ILL_ILLOPN
130*9663SMark.Logan@Sun.COM #  define ILL_ILLOPN (INTMAX - 2)
131*9663SMark.Logan@Sun.COM #endif
132*9663SMark.Logan@Sun.COM 
133*9663SMark.Logan@Sun.COM #ifndef ILL_ILLADR
134*9663SMark.Logan@Sun.COM #  define ILL_ILLADR (INTMAX - 3)
135*9663SMark.Logan@Sun.COM #endif
136*9663SMark.Logan@Sun.COM 
137*9663SMark.Logan@Sun.COM #ifndef ILL_ILLTRP
138*9663SMark.Logan@Sun.COM #  define ILL_ILLTRP (INTMAX - 4)
139*9663SMark.Logan@Sun.COM #endif
140*9663SMark.Logan@Sun.COM 
141*9663SMark.Logan@Sun.COM #ifndef ILL_PRVOPC
142*9663SMark.Logan@Sun.COM #  define ILL_PRVOPC (INTMAX - 5)
143*9663SMark.Logan@Sun.COM #endif
144*9663SMark.Logan@Sun.COM 
145*9663SMark.Logan@Sun.COM #ifndef ILL_PRVREG
146*9663SMark.Logan@Sun.COM #  define ILL_PRVREG (INTMAX - 6)
147*9663SMark.Logan@Sun.COM #endif
148*9663SMark.Logan@Sun.COM 
149*9663SMark.Logan@Sun.COM #ifndef ILL_COPROC
150*9663SMark.Logan@Sun.COM #  define ILL_COPROC (INTMAX - 7)
151*9663SMark.Logan@Sun.COM #endif
152*9663SMark.Logan@Sun.COM 
153*9663SMark.Logan@Sun.COM #ifndef ILL_BADSTK
154*9663SMark.Logan@Sun.COM #  define ILL_BADSTK (INTMAX - 8)
155*9663SMark.Logan@Sun.COM #endif
156*9663SMark.Logan@Sun.COM 
157*9663SMark.Logan@Sun.COM char* prog_name = "GNU Parted " VERSION "\n";
158*9663SMark.Logan@Sun.COM 
159*9663SMark.Logan@Sun.COM static char* banner_msg = N_(
160*9663SMark.Logan@Sun.COM "Welcome to GNU Parted! Type 'help' to view a list of commands.\n");
161*9663SMark.Logan@Sun.COM 
162*9663SMark.Logan@Sun.COM static char* usage_msg = N_(
163*9663SMark.Logan@Sun.COM "Usage: parted [OPTION]... [DEVICE [COMMAND [PARAMETERS]...]...]\n"
164*9663SMark.Logan@Sun.COM "Apply COMMANDs with PARAMETERS to DEVICE.  If no COMMAND(s) are given, "
165*9663SMark.Logan@Sun.COM "run in\ninteractive mode.\n");
166*9663SMark.Logan@Sun.COM 
167*9663SMark.Logan@Sun.COM static char* bug_msg = N_(
168*9663SMark.Logan@Sun.COM "\n\nYou found a bug in GNU Parted! Here's what you have to do:\n\n"
169*9663SMark.Logan@Sun.COM "Don't panic! The bug has most likely not affected any of your data.\n"
170*9663SMark.Logan@Sun.COM "Help us to fix this bug by doing the following:\n\n"
171*9663SMark.Logan@Sun.COM "Check whether the bug has already been fixed by checking\n"
172*9663SMark.Logan@Sun.COM "the last version of GNU Parted that you can find at:\n\n"
173*9663SMark.Logan@Sun.COM "\thttp://ftp.gnu.org/gnu/parted/\n\n"
174*9663SMark.Logan@Sun.COM "Please check this version prior to bug reporting.\n\n"
175*9663SMark.Logan@Sun.COM "If this has not been fixed yet or if you don't know how to check,\n"
176*9663SMark.Logan@Sun.COM "please visit the GNU Parted website:\n\n"
177*9663SMark.Logan@Sun.COM "\thttp://www.gnu.org/software/parted\n\n"
178*9663SMark.Logan@Sun.COM "for further information.\n\n"
179*9663SMark.Logan@Sun.COM "Your report should contain the version of this release (%s)\n"
180*9663SMark.Logan@Sun.COM "along with the error message below, the output of\n\n"
181*9663SMark.Logan@Sun.COM "\tparted DEVICE unit co print unit s print\n\n"
182*9663SMark.Logan@Sun.COM "and the following history of commands you entered.\n"
183*9663SMark.Logan@Sun.COM "Also include any additional information about your setup you\n"
184*9663SMark.Logan@Sun.COM "consider important.\n");
185*9663SMark.Logan@Sun.COM 
186*9663SMark.Logan@Sun.COM #define MAX_WORDS    1024
187*9663SMark.Logan@Sun.COM 
188*9663SMark.Logan@Sun.COM static StrList*     command_line;
189*9663SMark.Logan@Sun.COM static Command**    commands;
190*9663SMark.Logan@Sun.COM static StrList*     ex_opt_str [64];
191*9663SMark.Logan@Sun.COM static StrList*     on_list;
192*9663SMark.Logan@Sun.COM static StrList*     off_list;
193*9663SMark.Logan@Sun.COM static StrList*     on_off_list;
194*9663SMark.Logan@Sun.COM static StrList*     fs_type_list;
195*9663SMark.Logan@Sun.COM static StrList*     disk_type_list;
196*9663SMark.Logan@Sun.COM 
197*9663SMark.Logan@Sun.COM static struct {
198*9663SMark.Logan@Sun.COM         const StrList*    possibilities;
199*9663SMark.Logan@Sun.COM         const StrList*    cur_pos;
200*9663SMark.Logan@Sun.COM         int               in_readline;
201*9663SMark.Logan@Sun.COM         sigjmp_buf        jmp_state;
202*9663SMark.Logan@Sun.COM } readline_state;
203*9663SMark.Logan@Sun.COM 
204*9663SMark.Logan@Sun.COM static struct sigaction    sig_segv;
205*9663SMark.Logan@Sun.COM static struct sigaction    sig_int;
206*9663SMark.Logan@Sun.COM static struct sigaction    sig_fpe;
207*9663SMark.Logan@Sun.COM static struct sigaction    sig_ill;
208*9663SMark.Logan@Sun.COM 
209*9663SMark.Logan@Sun.COM volatile int got_ctrl_c = 0;    /* used in exception_handler */
210*9663SMark.Logan@Sun.COM 
211*9663SMark.Logan@Sun.COM int
screen_width()212*9663SMark.Logan@Sun.COM screen_width ()
213*9663SMark.Logan@Sun.COM {
214*9663SMark.Logan@Sun.COM         int    width = 0;
215*9663SMark.Logan@Sun.COM 
216*9663SMark.Logan@Sun.COM         if (opt_script_mode || pretend_input_tty)
217*9663SMark.Logan@Sun.COM                 return 32768;    /* no wrapping ;) */
218*9663SMark.Logan@Sun.COM 
219*9663SMark.Logan@Sun.COM /* HACK: don't specify termcap separately - it'll annoy the users. */
220*9663SMark.Logan@Sun.COM #ifdef HAVE_LIBREADLINE
221*9663SMark.Logan@Sun.COM         width = tgetnum ("co");
222*9663SMark.Logan@Sun.COM #endif
223*9663SMark.Logan@Sun.COM 
224*9663SMark.Logan@Sun.COM         if (width <= 0)
225*9663SMark.Logan@Sun.COM                 width = 80;
226*9663SMark.Logan@Sun.COM 
227*9663SMark.Logan@Sun.COM         return width;
228*9663SMark.Logan@Sun.COM }
229*9663SMark.Logan@Sun.COM 
230*9663SMark.Logan@Sun.COM void
wipe_line()231*9663SMark.Logan@Sun.COM wipe_line ()
232*9663SMark.Logan@Sun.COM {
233*9663SMark.Logan@Sun.COM         if (opt_script_mode)
234*9663SMark.Logan@Sun.COM                 return;
235*9663SMark.Logan@Sun.COM 
236*9663SMark.Logan@Sun.COM         /* yuck */
237*9663SMark.Logan@Sun.COM         fputs ("\r                                     "
238*9663SMark.Logan@Sun.COM                "                                     \r", stdout);
239*9663SMark.Logan@Sun.COM }
240*9663SMark.Logan@Sun.COM 
241*9663SMark.Logan@Sun.COM #ifdef HAVE_LIBREADLINE
242*9663SMark.Logan@Sun.COM /* returns matching commands for text */
243*9663SMark.Logan@Sun.COM static char*
command_generator(char * text,int state)244*9663SMark.Logan@Sun.COM command_generator (char* text, int state)
245*9663SMark.Logan@Sun.COM {
246*9663SMark.Logan@Sun.COM         if (!state)
247*9663SMark.Logan@Sun.COM                 readline_state.cur_pos = readline_state.possibilities;
248*9663SMark.Logan@Sun.COM 
249*9663SMark.Logan@Sun.COM         while (readline_state.cur_pos) {
250*9663SMark.Logan@Sun.COM                 const StrList*    cur = readline_state.cur_pos;
251*9663SMark.Logan@Sun.COM                 readline_state.cur_pos = cur->next;
252*9663SMark.Logan@Sun.COM                 if (str_list_match_node (cur, text))
253*9663SMark.Logan@Sun.COM                         return str_list_convert_node (cur);
254*9663SMark.Logan@Sun.COM         }
255*9663SMark.Logan@Sun.COM 
256*9663SMark.Logan@Sun.COM         return NULL;
257*9663SMark.Logan@Sun.COM }
258*9663SMark.Logan@Sun.COM 
259*9663SMark.Logan@Sun.COM /* completion function for readline() */
260*9663SMark.Logan@Sun.COM char**
complete_function(char * text,int start,int end)261*9663SMark.Logan@Sun.COM complete_function (char* text, int start, int end)
262*9663SMark.Logan@Sun.COM {
263*9663SMark.Logan@Sun.COM         return rl_completion_matches (text,
264*9663SMark.Logan@Sun.COM                 (rl_compentry_func_t*) command_generator);
265*9663SMark.Logan@Sun.COM }
266*9663SMark.Logan@Sun.COM 
267*9663SMark.Logan@Sun.COM static void
_add_history_unique(const char * line)268*9663SMark.Logan@Sun.COM _add_history_unique (const char* line)
269*9663SMark.Logan@Sun.COM {
270*9663SMark.Logan@Sun.COM         HIST_ENTRY*    last_entry = current_history ();
271*9663SMark.Logan@Sun.COM         if (!strlen (line))
272*9663SMark.Logan@Sun.COM                 return;
273*9663SMark.Logan@Sun.COM         if (!last_entry || strcmp (last_entry->line, line))
274*9663SMark.Logan@Sun.COM                 add_history ((char*) line);
275*9663SMark.Logan@Sun.COM }
276*9663SMark.Logan@Sun.COM 
277*9663SMark.Logan@Sun.COM /* Prints command history, to be used before aborting */
278*9663SMark.Logan@Sun.COM static void
_dump_history()279*9663SMark.Logan@Sun.COM _dump_history ()
280*9663SMark.Logan@Sun.COM {
281*9663SMark.Logan@Sun.COM         int             i = 0;
282*9663SMark.Logan@Sun.COM         HIST_ENTRY**    all_entries = history_list ();
283*9663SMark.Logan@Sun.COM 
284*9663SMark.Logan@Sun.COM         fputs (_("\nCommand History:\n"), stdout);
285*9663SMark.Logan@Sun.COM         while (all_entries[i]) {
286*9663SMark.Logan@Sun.COM                 puts(all_entries[i++]->line);
287*9663SMark.Logan@Sun.COM         }
288*9663SMark.Logan@Sun.COM }
289*9663SMark.Logan@Sun.COM 
290*9663SMark.Logan@Sun.COM #else
291*9663SMark.Logan@Sun.COM 
292*9663SMark.Logan@Sun.COM /* Print nothing because Readline is absent. */
293*9663SMark.Logan@Sun.COM static inline void
_dump_history(void)294*9663SMark.Logan@Sun.COM _dump_history (void)
295*9663SMark.Logan@Sun.COM {
296*9663SMark.Logan@Sun.COM }
297*9663SMark.Logan@Sun.COM 
298*9663SMark.Logan@Sun.COM #endif /* HAVE_LIBREADLINE */
299*9663SMark.Logan@Sun.COM 
300*9663SMark.Logan@Sun.COM static void
mask_signal()301*9663SMark.Logan@Sun.COM mask_signal()
302*9663SMark.Logan@Sun.COM {
303*9663SMark.Logan@Sun.COM         sigset_t    curr;
304*9663SMark.Logan@Sun.COM         sigset_t    prev;
305*9663SMark.Logan@Sun.COM 
306*9663SMark.Logan@Sun.COM         sigfillset(&curr);
307*9663SMark.Logan@Sun.COM         sigprocmask(SIG_SETMASK, &curr, &prev);
308*9663SMark.Logan@Sun.COM }
309*9663SMark.Logan@Sun.COM 
310*9663SMark.Logan@Sun.COM /* Resets the environment by jumping to the initial state
311*9663SMark.Logan@Sun.COM  * saved during ui intitialisation.
312*9663SMark.Logan@Sun.COM  * Pass 1 as the parameter if you want to quit parted,
313*9663SMark.Logan@Sun.COM  * 0 if you just want to reset to the command prompt.
314*9663SMark.Logan@Sun.COM  */
315*9663SMark.Logan@Sun.COM static void
reset_env(int quit)316*9663SMark.Logan@Sun.COM reset_env (int quit)
317*9663SMark.Logan@Sun.COM {
318*9663SMark.Logan@Sun.COM         int    in_readline = readline_state.in_readline;
319*9663SMark.Logan@Sun.COM 
320*9663SMark.Logan@Sun.COM         readline_state.in_readline = 0;
321*9663SMark.Logan@Sun.COM 
322*9663SMark.Logan@Sun.COM         if (in_readline) {
323*9663SMark.Logan@Sun.COM                 putchar ('\n');
324*9663SMark.Logan@Sun.COM                 if (quit)
325*9663SMark.Logan@Sun.COM                         exit (0);
326*9663SMark.Logan@Sun.COM 
327*9663SMark.Logan@Sun.COM                 siglongjmp (readline_state.jmp_state, 1);
328*9663SMark.Logan@Sun.COM         }
329*9663SMark.Logan@Sun.COM }
330*9663SMark.Logan@Sun.COM 
331*9663SMark.Logan@Sun.COM /* Signal handler for SIGINT using 'sigaction'. */
332*9663SMark.Logan@Sun.COM static void
sa_sigint_handler(int signum,siginfo_t * info,void * ucontext)333*9663SMark.Logan@Sun.COM sa_sigint_handler (int signum, siginfo_t* info, void *ucontext)
334*9663SMark.Logan@Sun.COM {
335*9663SMark.Logan@Sun.COM         if (info)
336*9663SMark.Logan@Sun.COM                 sigaction (SIGINT, &sig_int, NULL);
337*9663SMark.Logan@Sun.COM 
338*9663SMark.Logan@Sun.COM         got_ctrl_c = 1;
339*9663SMark.Logan@Sun.COM         reset_env (0);
340*9663SMark.Logan@Sun.COM }
341*9663SMark.Logan@Sun.COM 
342*9663SMark.Logan@Sun.COM /* Signal handler for SIGINT using 'signal'. */
343*9663SMark.Logan@Sun.COM static void
s_sigint_handler(int signum)344*9663SMark.Logan@Sun.COM s_sigint_handler (int signum)
345*9663SMark.Logan@Sun.COM {
346*9663SMark.Logan@Sun.COM         signal (SIGINT, &s_sigint_handler);
347*9663SMark.Logan@Sun.COM         mask_signal ();
348*9663SMark.Logan@Sun.COM         sa_sigint_handler (signum, NULL, NULL);
349*9663SMark.Logan@Sun.COM }
350*9663SMark.Logan@Sun.COM 
351*9663SMark.Logan@Sun.COM /* Signal handler for SIGSEGV using 'sigaction'. */
352*9663SMark.Logan@Sun.COM static void
sa_sigsegv_handler(int signum,siginfo_t * info,void * ucontext)353*9663SMark.Logan@Sun.COM sa_sigsegv_handler (int signum, siginfo_t* info, void* ucontext)
354*9663SMark.Logan@Sun.COM {
355*9663SMark.Logan@Sun.COM         printf (bug_msg, VERSION);
356*9663SMark.Logan@Sun.COM         _dump_history ();
357*9663SMark.Logan@Sun.COM 
358*9663SMark.Logan@Sun.COM         if (!info)
359*9663SMark.Logan@Sun.COM                 abort ();
360*9663SMark.Logan@Sun.COM 
361*9663SMark.Logan@Sun.COM         sigaction (SIGSEGV, &sig_segv, NULL);
362*9663SMark.Logan@Sun.COM 
363*9663SMark.Logan@Sun.COM         switch (info->si_code) {
364*9663SMark.Logan@Sun.COM 
365*9663SMark.Logan@Sun.COM                 case SEGV_MAPERR:
366*9663SMark.Logan@Sun.COM                         fputs(_("\nError: SEGV_MAPERR (Address not mapped "
367*9663SMark.Logan@Sun.COM                                 "to object)\n"), stdout);
368*9663SMark.Logan@Sun.COM                         PED_ASSERT(0, break); /* Force a backtrace */
369*9663SMark.Logan@Sun.COM                         break;
370*9663SMark.Logan@Sun.COM 
371*9663SMark.Logan@Sun.COM                 case SEGV_ACCERR:
372*9663SMark.Logan@Sun.COM                         fputs(_("\nError: SEGV_ACCERR (Invalid permissions "
373*9663SMark.Logan@Sun.COM                                 "for mapped object)\n"), stdout);
374*9663SMark.Logan@Sun.COM                         break;
375*9663SMark.Logan@Sun.COM 
376*9663SMark.Logan@Sun.COM                 default:
377*9663SMark.Logan@Sun.COM                         fputs(_("\nError: A general SIGSEGV signal was "
378*9663SMark.Logan@Sun.COM                                 "encountered.\n"), stdout);
379*9663SMark.Logan@Sun.COM                         PED_ASSERT(0, break); /* Force a backtrace */
380*9663SMark.Logan@Sun.COM                         break;
381*9663SMark.Logan@Sun.COM         }
382*9663SMark.Logan@Sun.COM 
383*9663SMark.Logan@Sun.COM         abort ();
384*9663SMark.Logan@Sun.COM }
385*9663SMark.Logan@Sun.COM 
386*9663SMark.Logan@Sun.COM /* Signal handler for SIGSEGV using 'signal'. */
387*9663SMark.Logan@Sun.COM static void
s_sigsegv_handler(int signum)388*9663SMark.Logan@Sun.COM s_sigsegv_handler (int signum)
389*9663SMark.Logan@Sun.COM {
390*9663SMark.Logan@Sun.COM         signal (SIGSEGV, &s_sigsegv_handler);
391*9663SMark.Logan@Sun.COM         mask_signal ();
392*9663SMark.Logan@Sun.COM         sa_sigsegv_handler (signum, NULL, NULL);
393*9663SMark.Logan@Sun.COM }
394*9663SMark.Logan@Sun.COM 
395*9663SMark.Logan@Sun.COM /* Signal handler for SIGFPE using 'sigaction'. */
396*9663SMark.Logan@Sun.COM static void
sa_sigfpe_handler(int signum,siginfo_t * info,void * ucontext)397*9663SMark.Logan@Sun.COM sa_sigfpe_handler (int signum, siginfo_t* info, void* ucontext)
398*9663SMark.Logan@Sun.COM {
399*9663SMark.Logan@Sun.COM         printf (bug_msg, VERSION);
400*9663SMark.Logan@Sun.COM         _dump_history ();
401*9663SMark.Logan@Sun.COM 
402*9663SMark.Logan@Sun.COM         if (!info)
403*9663SMark.Logan@Sun.COM                 abort ();
404*9663SMark.Logan@Sun.COM 
405*9663SMark.Logan@Sun.COM         sigaction (SIGFPE, &sig_fpe, NULL);
406*9663SMark.Logan@Sun.COM 
407*9663SMark.Logan@Sun.COM         switch (info->si_code) {
408*9663SMark.Logan@Sun.COM 
409*9663SMark.Logan@Sun.COM                 case FPE_INTDIV:
410*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_INTDIV (Integer: "
411*9663SMark.Logan@Sun.COM                                 "divide by zero)"), stdout);
412*9663SMark.Logan@Sun.COM                         break;
413*9663SMark.Logan@Sun.COM 
414*9663SMark.Logan@Sun.COM                 case FPE_INTOVF:
415*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_INTOVF (Integer: "
416*9663SMark.Logan@Sun.COM                                 "overflow)"), stdout);
417*9663SMark.Logan@Sun.COM                         break;
418*9663SMark.Logan@Sun.COM 
419*9663SMark.Logan@Sun.COM                 case FPE_FLTDIV:
420*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_FLTDIV (Float: "
421*9663SMark.Logan@Sun.COM                                 "divide by zero)"), stdout);
422*9663SMark.Logan@Sun.COM                         break;
423*9663SMark.Logan@Sun.COM 
424*9663SMark.Logan@Sun.COM                 case FPE_FLTOVF:
425*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_FLTOVF (Float: "
426*9663SMark.Logan@Sun.COM                                 "overflow)"), stdout);
427*9663SMark.Logan@Sun.COM                         break;
428*9663SMark.Logan@Sun.COM 
429*9663SMark.Logan@Sun.COM                 case FPE_FLTUND:
430*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_FLTUND (Float: "
431*9663SMark.Logan@Sun.COM                                 "underflow)"), stdout);
432*9663SMark.Logan@Sun.COM                         break;
433*9663SMark.Logan@Sun.COM 
434*9663SMark.Logan@Sun.COM                 case FPE_FLTRES:
435*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_FLTRES (Float: "
436*9663SMark.Logan@Sun.COM                                 "inexact result)"), stdout);
437*9663SMark.Logan@Sun.COM                         break;
438*9663SMark.Logan@Sun.COM 
439*9663SMark.Logan@Sun.COM                 case FPE_FLTINV:
440*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_FLTINV (Float: "
441*9663SMark.Logan@Sun.COM                                 "invalid operation)"), stdout);
442*9663SMark.Logan@Sun.COM                         break;
443*9663SMark.Logan@Sun.COM 
444*9663SMark.Logan@Sun.COM                 case FPE_FLTSUB:
445*9663SMark.Logan@Sun.COM                         fputs(_("\nError: FPE_FLTSUB (Float: "
446*9663SMark.Logan@Sun.COM                                 "subscript out of range)"), stdout);
447*9663SMark.Logan@Sun.COM                         break;
448*9663SMark.Logan@Sun.COM 
449*9663SMark.Logan@Sun.COM                 default:
450*9663SMark.Logan@Sun.COM                         fputs(_("\nError: A general SIGFPE signal "
451*9663SMark.Logan@Sun.COM                                 "was encountered."), stdout);
452*9663SMark.Logan@Sun.COM                         break;
453*9663SMark.Logan@Sun.COM 
454*9663SMark.Logan@Sun.COM         }
455*9663SMark.Logan@Sun.COM 
456*9663SMark.Logan@Sun.COM         abort ();
457*9663SMark.Logan@Sun.COM }
458*9663SMark.Logan@Sun.COM 
459*9663SMark.Logan@Sun.COM /* Signal handler for SIGFPE using 'signal'. */
460*9663SMark.Logan@Sun.COM static void
s_sigfpe_handler(int signum)461*9663SMark.Logan@Sun.COM s_sigfpe_handler (int signum)
462*9663SMark.Logan@Sun.COM {
463*9663SMark.Logan@Sun.COM         signal (SIGFPE, &s_sigfpe_handler);
464*9663SMark.Logan@Sun.COM         mask_signal ();
465*9663SMark.Logan@Sun.COM         sa_sigfpe_handler (signum, NULL, NULL);
466*9663SMark.Logan@Sun.COM }
467*9663SMark.Logan@Sun.COM 
468*9663SMark.Logan@Sun.COM /* Signal handler for SIGILL using 'sigaction'. */
469*9663SMark.Logan@Sun.COM static void
sa_sigill_handler(int signum,siginfo_t * info,void * ucontext)470*9663SMark.Logan@Sun.COM sa_sigill_handler (int signum, siginfo_t* info, void* ucontext)
471*9663SMark.Logan@Sun.COM {
472*9663SMark.Logan@Sun.COM         printf (bug_msg, VERSION);
473*9663SMark.Logan@Sun.COM         _dump_history ();
474*9663SMark.Logan@Sun.COM 
475*9663SMark.Logan@Sun.COM         if (!info)
476*9663SMark.Logan@Sun.COM                 abort();
477*9663SMark.Logan@Sun.COM 
478*9663SMark.Logan@Sun.COM         sigaction (SIGILL, &sig_ill, NULL);
479*9663SMark.Logan@Sun.COM 
480*9663SMark.Logan@Sun.COM         switch (info->si_code) {
481*9663SMark.Logan@Sun.COM 
482*9663SMark.Logan@Sun.COM                 case ILL_ILLOPC:
483*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_ILLOPC "
484*9663SMark.Logan@Sun.COM                                 "(Illegal Opcode)"), stdout);
485*9663SMark.Logan@Sun.COM                         break;
486*9663SMark.Logan@Sun.COM 
487*9663SMark.Logan@Sun.COM                 case ILL_ILLOPN:
488*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_ILLOPN "
489*9663SMark.Logan@Sun.COM                                 "(Illegal Operand)"), stdout);
490*9663SMark.Logan@Sun.COM                         break;
491*9663SMark.Logan@Sun.COM 
492*9663SMark.Logan@Sun.COM                 case ILL_ILLADR:
493*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_ILLADR "
494*9663SMark.Logan@Sun.COM                                 "(Illegal addressing mode)"), stdout);
495*9663SMark.Logan@Sun.COM                         break;
496*9663SMark.Logan@Sun.COM 
497*9663SMark.Logan@Sun.COM                 case ILL_ILLTRP:
498*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_ILLTRP "
499*9663SMark.Logan@Sun.COM                                 "(Illegal Trap)"), stdout);
500*9663SMark.Logan@Sun.COM                         break;
501*9663SMark.Logan@Sun.COM 
502*9663SMark.Logan@Sun.COM                 case ILL_PRVOPC:
503*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_PRVOPC "
504*9663SMark.Logan@Sun.COM                                 "(Privileged Opcode)"), stdout);
505*9663SMark.Logan@Sun.COM                         break;
506*9663SMark.Logan@Sun.COM 
507*9663SMark.Logan@Sun.COM                 case ILL_PRVREG:
508*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_PRVREG "
509*9663SMark.Logan@Sun.COM                                 "(Privileged Register)"), stdout);
510*9663SMark.Logan@Sun.COM                         break;
511*9663SMark.Logan@Sun.COM 
512*9663SMark.Logan@Sun.COM                 case ILL_COPROC:
513*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_COPROC "
514*9663SMark.Logan@Sun.COM                                 "(Coprocessor Error)"), stdout);
515*9663SMark.Logan@Sun.COM                         break;
516*9663SMark.Logan@Sun.COM 
517*9663SMark.Logan@Sun.COM                 case ILL_BADSTK:
518*9663SMark.Logan@Sun.COM                         fputs(_("\nError: ILL_BADSTK "
519*9663SMark.Logan@Sun.COM                                 "(Internal Stack Error)"), stdout);
520*9663SMark.Logan@Sun.COM                         break;
521*9663SMark.Logan@Sun.COM 
522*9663SMark.Logan@Sun.COM                 default:
523*9663SMark.Logan@Sun.COM                         fputs(_("\nError: A general SIGILL "
524*9663SMark.Logan@Sun.COM                                 "signal was encountered."), stdout);
525*9663SMark.Logan@Sun.COM                         break;
526*9663SMark.Logan@Sun.COM         }
527*9663SMark.Logan@Sun.COM 
528*9663SMark.Logan@Sun.COM         abort ();
529*9663SMark.Logan@Sun.COM }
530*9663SMark.Logan@Sun.COM 
531*9663SMark.Logan@Sun.COM /* Signal handler for SIGILL using 'signal'. */
532*9663SMark.Logan@Sun.COM static void
s_sigill_handler(int signum)533*9663SMark.Logan@Sun.COM s_sigill_handler (int signum)
534*9663SMark.Logan@Sun.COM {
535*9663SMark.Logan@Sun.COM         signal (SIGILL, &s_sigill_handler);
536*9663SMark.Logan@Sun.COM         mask_signal ();
537*9663SMark.Logan@Sun.COM         sa_sigill_handler (signum, NULL, NULL);
538*9663SMark.Logan@Sun.COM }
539*9663SMark.Logan@Sun.COM 
540*9663SMark.Logan@Sun.COM static char*
_readline(const char * prompt,const StrList * possibilities)541*9663SMark.Logan@Sun.COM _readline (const char* prompt, const StrList* possibilities)
542*9663SMark.Logan@Sun.COM {
543*9663SMark.Logan@Sun.COM         char*    line;
544*9663SMark.Logan@Sun.COM 
545*9663SMark.Logan@Sun.COM         readline_state.possibilities = possibilities;
546*9663SMark.Logan@Sun.COM         readline_state.cur_pos = NULL;
547*9663SMark.Logan@Sun.COM         readline_state.in_readline = 1;
548*9663SMark.Logan@Sun.COM 
549*9663SMark.Logan@Sun.COM         if (sigsetjmp (readline_state.jmp_state,1))
550*9663SMark.Logan@Sun.COM                 return NULL;
551*9663SMark.Logan@Sun.COM 
552*9663SMark.Logan@Sun.COM         wipe_line ();
553*9663SMark.Logan@Sun.COM #ifdef HAVE_LIBREADLINE
554*9663SMark.Logan@Sun.COM         if (!opt_script_mode) {
555*9663SMark.Logan@Sun.COM                 /* XXX: why isn't prompt const? */
556*9663SMark.Logan@Sun.COM                 line = readline ((char*) prompt);
557*9663SMark.Logan@Sun.COM                 if (line)
558*9663SMark.Logan@Sun.COM                         _add_history_unique (line);
559*9663SMark.Logan@Sun.COM         } else
560*9663SMark.Logan@Sun.COM #endif
561*9663SMark.Logan@Sun.COM         {
562*9663SMark.Logan@Sun.COM                 fputs (prompt, stdout);
563*9663SMark.Logan@Sun.COM                 fflush (stdout);
564*9663SMark.Logan@Sun.COM                 line = (char*) malloc (256);
565*9663SMark.Logan@Sun.COM                 if (fgets (line, 256, stdin) && strcmp (line, "") != 0) {
566*9663SMark.Logan@Sun.COM #ifndef HAVE_LIBREADLINE
567*9663SMark.Logan@Sun.COM                         /* Echo the input line, to be consistent with
568*9663SMark.Logan@Sun.COM                            how readline-5.2 works.  */
569*9663SMark.Logan@Sun.COM                         fputs (line, stdout);
570*9663SMark.Logan@Sun.COM                         fflush (stdout);
571*9663SMark.Logan@Sun.COM #endif
572*9663SMark.Logan@Sun.COM                         line [strlen (line) - 1] = 0;    /* kill trailing CR */
573*9663SMark.Logan@Sun.COM                 } else {
574*9663SMark.Logan@Sun.COM                         free (line);
575*9663SMark.Logan@Sun.COM                         line = NULL;
576*9663SMark.Logan@Sun.COM                 }
577*9663SMark.Logan@Sun.COM         }
578*9663SMark.Logan@Sun.COM 
579*9663SMark.Logan@Sun.COM         readline_state.in_readline = 0;
580*9663SMark.Logan@Sun.COM         return line;
581*9663SMark.Logan@Sun.COM }
582*9663SMark.Logan@Sun.COM 
583*9663SMark.Logan@Sun.COM static PedExceptionOption
option_get_next(PedExceptionOption options,PedExceptionOption current)584*9663SMark.Logan@Sun.COM option_get_next (PedExceptionOption options, PedExceptionOption current)
585*9663SMark.Logan@Sun.COM {
586*9663SMark.Logan@Sun.COM         PedExceptionOption    i;
587*9663SMark.Logan@Sun.COM 
588*9663SMark.Logan@Sun.COM         if (current == 0)
589*9663SMark.Logan@Sun.COM                 i = PED_EXCEPTION_OPTION_FIRST;
590*9663SMark.Logan@Sun.COM         else
591*9663SMark.Logan@Sun.COM                 i = current * 2;
592*9663SMark.Logan@Sun.COM 
593*9663SMark.Logan@Sun.COM         for (; i <= options; i *= 2) {
594*9663SMark.Logan@Sun.COM                 if (options & i)
595*9663SMark.Logan@Sun.COM                         return i;
596*9663SMark.Logan@Sun.COM         }
597*9663SMark.Logan@Sun.COM         return 0;
598*9663SMark.Logan@Sun.COM }
599*9663SMark.Logan@Sun.COM 
600*9663SMark.Logan@Sun.COM static void
_print_exception_text(PedException * ex)601*9663SMark.Logan@Sun.COM _print_exception_text (PedException* ex)
602*9663SMark.Logan@Sun.COM {
603*9663SMark.Logan@Sun.COM         StrList*    text;
604*9663SMark.Logan@Sun.COM 
605*9663SMark.Logan@Sun.COM         wipe_line ();
606*9663SMark.Logan@Sun.COM 
607*9663SMark.Logan@Sun.COM         if (ex->type == PED_EXCEPTION_BUG) {
608*9663SMark.Logan@Sun.COM                 printf (bug_msg, VERSION);
609*9663SMark.Logan@Sun.COM                 text = str_list_create ("\n", ex->message, "\n\n", NULL);
610*9663SMark.Logan@Sun.COM         } else {
611*9663SMark.Logan@Sun.COM                 text = str_list_create (
612*9663SMark.Logan@Sun.COM                            _(ped_exception_get_type_string (ex->type)),
613*9663SMark.Logan@Sun.COM                            ": ", ex->message, "\n", NULL);
614*9663SMark.Logan@Sun.COM         }
615*9663SMark.Logan@Sun.COM 
616*9663SMark.Logan@Sun.COM         str_list_print_wrap (text, screen_width (), 0, 0);
617*9663SMark.Logan@Sun.COM         str_list_destroy (text);
618*9663SMark.Logan@Sun.COM }
619*9663SMark.Logan@Sun.COM 
620*9663SMark.Logan@Sun.COM static PedExceptionOption
exception_handler(PedException * ex)621*9663SMark.Logan@Sun.COM exception_handler (PedException* ex)
622*9663SMark.Logan@Sun.COM {
623*9663SMark.Logan@Sun.COM         PedExceptionOption    opt;
624*9663SMark.Logan@Sun.COM 
625*9663SMark.Logan@Sun.COM         _print_exception_text (ex);
626*9663SMark.Logan@Sun.COM 
627*9663SMark.Logan@Sun.COM         /* only one choice?  Take it ;-) */
628*9663SMark.Logan@Sun.COM         opt = option_get_next (ex->options, 0);
629*9663SMark.Logan@Sun.COM         if (!option_get_next (ex->options, opt))
630*9663SMark.Logan@Sun.COM                 return opt;
631*9663SMark.Logan@Sun.COM 
632*9663SMark.Logan@Sun.COM         /* script-mode: don't handle the exception */
633*9663SMark.Logan@Sun.COM         if (opt_script_mode || (!isatty (0) && !pretend_input_tty))
634*9663SMark.Logan@Sun.COM                 return PED_EXCEPTION_UNHANDLED;
635*9663SMark.Logan@Sun.COM 
636*9663SMark.Logan@Sun.COM         got_ctrl_c = 0;
637*9663SMark.Logan@Sun.COM 
638*9663SMark.Logan@Sun.COM         do {
639*9663SMark.Logan@Sun.COM                 opt = command_line_get_ex_opt ("", ex->options);
640*9663SMark.Logan@Sun.COM         } while (opt == PED_EXCEPTION_UNHANDLED
641*9663SMark.Logan@Sun.COM                  && (isatty (0) || pretend_input_tty) && !got_ctrl_c);
642*9663SMark.Logan@Sun.COM 
643*9663SMark.Logan@Sun.COM         if (got_ctrl_c) {
644*9663SMark.Logan@Sun.COM                 got_ctrl_c = 0;
645*9663SMark.Logan@Sun.COM                 opt = PED_EXCEPTION_UNHANDLED;
646*9663SMark.Logan@Sun.COM         }
647*9663SMark.Logan@Sun.COM 
648*9663SMark.Logan@Sun.COM         return opt;
649*9663SMark.Logan@Sun.COM }
650*9663SMark.Logan@Sun.COM 
651*9663SMark.Logan@Sun.COM void
command_line_push_word(const char * word)652*9663SMark.Logan@Sun.COM command_line_push_word (const char* word)
653*9663SMark.Logan@Sun.COM {
654*9663SMark.Logan@Sun.COM         command_line = str_list_append (command_line, word);
655*9663SMark.Logan@Sun.COM }
656*9663SMark.Logan@Sun.COM 
657*9663SMark.Logan@Sun.COM char*
command_line_pop_word()658*9663SMark.Logan@Sun.COM command_line_pop_word ()
659*9663SMark.Logan@Sun.COM {
660*9663SMark.Logan@Sun.COM         char*       result;
661*9663SMark.Logan@Sun.COM         StrList*    next;
662*9663SMark.Logan@Sun.COM 
663*9663SMark.Logan@Sun.COM         PED_ASSERT (command_line != NULL, return NULL);
664*9663SMark.Logan@Sun.COM 
665*9663SMark.Logan@Sun.COM         result = str_list_convert_node (command_line);
666*9663SMark.Logan@Sun.COM         next = command_line->next;
667*9663SMark.Logan@Sun.COM 
668*9663SMark.Logan@Sun.COM         str_list_destroy_node (command_line);
669*9663SMark.Logan@Sun.COM         command_line = next;
670*9663SMark.Logan@Sun.COM         return result;
671*9663SMark.Logan@Sun.COM }
672*9663SMark.Logan@Sun.COM 
673*9663SMark.Logan@Sun.COM void
command_line_flush()674*9663SMark.Logan@Sun.COM command_line_flush ()
675*9663SMark.Logan@Sun.COM {
676*9663SMark.Logan@Sun.COM         str_list_destroy (command_line);
677*9663SMark.Logan@Sun.COM         command_line = NULL;
678*9663SMark.Logan@Sun.COM }
679*9663SMark.Logan@Sun.COM 
680*9663SMark.Logan@Sun.COM char*
command_line_peek_word()681*9663SMark.Logan@Sun.COM command_line_peek_word ()
682*9663SMark.Logan@Sun.COM {
683*9663SMark.Logan@Sun.COM         if (command_line)
684*9663SMark.Logan@Sun.COM                 return str_list_convert_node (command_line);
685*9663SMark.Logan@Sun.COM         else
686*9663SMark.Logan@Sun.COM                 return NULL;
687*9663SMark.Logan@Sun.COM }
688*9663SMark.Logan@Sun.COM 
689*9663SMark.Logan@Sun.COM int
command_line_get_word_count()690*9663SMark.Logan@Sun.COM command_line_get_word_count ()
691*9663SMark.Logan@Sun.COM {
692*9663SMark.Logan@Sun.COM         return str_list_length (command_line);
693*9663SMark.Logan@Sun.COM }
694*9663SMark.Logan@Sun.COM 
695*9663SMark.Logan@Sun.COM static int
_str_is_spaces(const char * str)696*9663SMark.Logan@Sun.COM _str_is_spaces (const char* str)
697*9663SMark.Logan@Sun.COM {
698*9663SMark.Logan@Sun.COM         while (isspace (*str))
699*9663SMark.Logan@Sun.COM                 str++;
700*9663SMark.Logan@Sun.COM 
701*9663SMark.Logan@Sun.COM         return *str == 0;
702*9663SMark.Logan@Sun.COM }
703*9663SMark.Logan@Sun.COM 
704*9663SMark.Logan@Sun.COM /* "multi_word mode" is the "normal" mode... many words can be typed,
705*9663SMark.Logan@Sun.COM  * delimited by spaces, etc.
706*9663SMark.Logan@Sun.COM  *         In single-word mode, only one word is parsed per line.
707*9663SMark.Logan@Sun.COM  * Leading and trailing spaces are removed.  For example: " a b c "
708*9663SMark.Logan@Sun.COM  * is a single word "a b c".  The motivation for this mode is partition
709*9663SMark.Logan@Sun.COM  * names, etc.  In single-word mode, the empty string is a word.
710*9663SMark.Logan@Sun.COM  * (but not in multi-word mode).
711*9663SMark.Logan@Sun.COM  */
712*9663SMark.Logan@Sun.COM void
command_line_push_line(const char * line,int multi_word)713*9663SMark.Logan@Sun.COM command_line_push_line (const char* line, int multi_word)
714*9663SMark.Logan@Sun.COM {
715*9663SMark.Logan@Sun.COM         int     quoted = 0;
716*9663SMark.Logan@Sun.COM         char    quote_char = 0;
717*9663SMark.Logan@Sun.COM         char    this_word [256];
718*9663SMark.Logan@Sun.COM         int     i;
719*9663SMark.Logan@Sun.COM 
720*9663SMark.Logan@Sun.COM         do {
721*9663SMark.Logan@Sun.COM                 while (*line == ' ')
722*9663SMark.Logan@Sun.COM                         line++;
723*9663SMark.Logan@Sun.COM 
724*9663SMark.Logan@Sun.COM                 i = 0;
725*9663SMark.Logan@Sun.COM                 for (; *line; line++) {
726*9663SMark.Logan@Sun.COM                         if (*line == ' ' && !quoted) {
727*9663SMark.Logan@Sun.COM                                 if (multi_word)
728*9663SMark.Logan@Sun.COM                                         break;
729*9663SMark.Logan@Sun.COM 
730*9663SMark.Logan@Sun.COM                         /* single word: check for trailing spaces + eol */
731*9663SMark.Logan@Sun.COM                                 if (_str_is_spaces (line))
732*9663SMark.Logan@Sun.COM                                         break;
733*9663SMark.Logan@Sun.COM                         }
734*9663SMark.Logan@Sun.COM 
735*9663SMark.Logan@Sun.COM                         if (!quoted && strchr ("'\"", *line)) {
736*9663SMark.Logan@Sun.COM                                 quoted = 1;
737*9663SMark.Logan@Sun.COM                                 quote_char = *line;
738*9663SMark.Logan@Sun.COM                                 continue;
739*9663SMark.Logan@Sun.COM                         }
740*9663SMark.Logan@Sun.COM 
741*9663SMark.Logan@Sun.COM                         if (quoted && *line == quote_char) {
742*9663SMark.Logan@Sun.COM                                 quoted = 0;
743*9663SMark.Logan@Sun.COM                                 continue;
744*9663SMark.Logan@Sun.COM                         }
745*9663SMark.Logan@Sun.COM 
746*9663SMark.Logan@Sun.COM                         /* hack: escape characters */
747*9663SMark.Logan@Sun.COM                         if (quoted && line[0] == '\\' && line[1])
748*9663SMark.Logan@Sun.COM                                 line++;
749*9663SMark.Logan@Sun.COM 
750*9663SMark.Logan@Sun.COM                         this_word [i++] = *line;
751*9663SMark.Logan@Sun.COM                 }
752*9663SMark.Logan@Sun.COM                 if (i || !multi_word) {
753*9663SMark.Logan@Sun.COM                         this_word [i] = 0;
754*9663SMark.Logan@Sun.COM                         command_line_push_word (this_word);
755*9663SMark.Logan@Sun.COM                 }
756*9663SMark.Logan@Sun.COM         } while (*line && multi_word);
757*9663SMark.Logan@Sun.COM }
758*9663SMark.Logan@Sun.COM 
759*9663SMark.Logan@Sun.COM static char*
realloc_and_cat(char * str,const char * append)760*9663SMark.Logan@Sun.COM realloc_and_cat (char* str, const char* append)
761*9663SMark.Logan@Sun.COM {
762*9663SMark.Logan@Sun.COM         int      length = strlen (str) + strlen (append) + 1;
763*9663SMark.Logan@Sun.COM         char*    new_str = realloc (str, length);
764*9663SMark.Logan@Sun.COM 
765*9663SMark.Logan@Sun.COM         strcat (new_str, append);
766*9663SMark.Logan@Sun.COM         return new_str;
767*9663SMark.Logan@Sun.COM }
768*9663SMark.Logan@Sun.COM 
769*9663SMark.Logan@Sun.COM static char*
_construct_prompt(const char * head,const char * def,const StrList * possibilities)770*9663SMark.Logan@Sun.COM _construct_prompt (const char* head, const char* def,
771*9663SMark.Logan@Sun.COM                    const StrList* possibilities)
772*9663SMark.Logan@Sun.COM {
773*9663SMark.Logan@Sun.COM         char*    prompt = strdup (head);
774*9663SMark.Logan@Sun.COM 
775*9663SMark.Logan@Sun.COM         if (def && possibilities)
776*9663SMark.Logan@Sun.COM                 PED_ASSERT (str_list_match_any (possibilities, def),
777*9663SMark.Logan@Sun.COM                             return NULL);
778*9663SMark.Logan@Sun.COM 
779*9663SMark.Logan@Sun.COM         if (possibilities && str_list_length (possibilities) < 8) {
780*9663SMark.Logan@Sun.COM                 const StrList*    walk;
781*9663SMark.Logan@Sun.COM 
782*9663SMark.Logan@Sun.COM                 if (strlen (prompt))
783*9663SMark.Logan@Sun.COM                         prompt = realloc_and_cat (prompt, "  ");
784*9663SMark.Logan@Sun.COM 
785*9663SMark.Logan@Sun.COM                 for (walk = possibilities; walk; walk = walk->next) {
786*9663SMark.Logan@Sun.COM                         if (walk != possibilities)
787*9663SMark.Logan@Sun.COM                                 prompt = realloc_and_cat (prompt, "/");
788*9663SMark.Logan@Sun.COM 
789*9663SMark.Logan@Sun.COM                         if (def && str_list_match_node (walk, def) == 2) {
790*9663SMark.Logan@Sun.COM                                 prompt = realloc_and_cat (prompt, "[");
791*9663SMark.Logan@Sun.COM                                 prompt = realloc_and_cat (prompt, def);
792*9663SMark.Logan@Sun.COM                                 prompt = realloc_and_cat (prompt, "]");
793*9663SMark.Logan@Sun.COM                         } else {
794*9663SMark.Logan@Sun.COM                                 char*    text = str_list_convert_node (walk);
795*9663SMark.Logan@Sun.COM                                 prompt = realloc_and_cat (prompt, text);
796*9663SMark.Logan@Sun.COM                                 free (text);
797*9663SMark.Logan@Sun.COM                         }
798*9663SMark.Logan@Sun.COM                 }
799*9663SMark.Logan@Sun.COM                 prompt = realloc_and_cat (prompt, "? ");
800*9663SMark.Logan@Sun.COM         } else if (def) {
801*9663SMark.Logan@Sun.COM                 if (strlen (prompt))
802*9663SMark.Logan@Sun.COM                         prompt = realloc_and_cat (prompt, "  ");
803*9663SMark.Logan@Sun.COM                 prompt = realloc_and_cat (prompt, "[");
804*9663SMark.Logan@Sun.COM                 prompt = realloc_and_cat (prompt, def);
805*9663SMark.Logan@Sun.COM                 prompt = realloc_and_cat (prompt, "]? ");
806*9663SMark.Logan@Sun.COM         } else {
807*9663SMark.Logan@Sun.COM                 if (strlen (prompt))
808*9663SMark.Logan@Sun.COM                         prompt = realloc_and_cat (prompt, " ");
809*9663SMark.Logan@Sun.COM         }
810*9663SMark.Logan@Sun.COM 
811*9663SMark.Logan@Sun.COM         return prompt;
812*9663SMark.Logan@Sun.COM }
813*9663SMark.Logan@Sun.COM 
814*9663SMark.Logan@Sun.COM void
command_line_prompt_words(const char * prompt,const char * def,const StrList * possibilities,int multi_word)815*9663SMark.Logan@Sun.COM command_line_prompt_words (const char* prompt, const char* def,
816*9663SMark.Logan@Sun.COM                            const StrList* possibilities, int multi_word)
817*9663SMark.Logan@Sun.COM {
818*9663SMark.Logan@Sun.COM         char*    line;
819*9663SMark.Logan@Sun.COM         char*    real_prompt;
820*9663SMark.Logan@Sun.COM         char*    _def = (char*) def;
821*9663SMark.Logan@Sun.COM         int      _def_needs_free = 0;
822*9663SMark.Logan@Sun.COM 
823*9663SMark.Logan@Sun.COM         if (!def && str_list_length (possibilities) == 1) {
824*9663SMark.Logan@Sun.COM                 _def = str_list_convert_node (possibilities);
825*9663SMark.Logan@Sun.COM                 _def_needs_free = 1;
826*9663SMark.Logan@Sun.COM         }
827*9663SMark.Logan@Sun.COM 
828*9663SMark.Logan@Sun.COM         if (opt_script_mode) {
829*9663SMark.Logan@Sun.COM                 if (_def)
830*9663SMark.Logan@Sun.COM                         command_line_push_line (_def, 0);
831*9663SMark.Logan@Sun.COM                 return;
832*9663SMark.Logan@Sun.COM         }
833*9663SMark.Logan@Sun.COM 
834*9663SMark.Logan@Sun.COM         do {
835*9663SMark.Logan@Sun.COM                 real_prompt = _construct_prompt (prompt, _def, possibilities);
836*9663SMark.Logan@Sun.COM                 line = _readline (real_prompt, possibilities);
837*9663SMark.Logan@Sun.COM                 free (real_prompt);
838*9663SMark.Logan@Sun.COM                 if (!line)
839*9663SMark.Logan@Sun.COM                         break;
840*9663SMark.Logan@Sun.COM 
841*9663SMark.Logan@Sun.COM                 if (!strlen (line)) {
842*9663SMark.Logan@Sun.COM                         if (_def)
843*9663SMark.Logan@Sun.COM                                 command_line_push_line (_def, 0);
844*9663SMark.Logan@Sun.COM                 } else {
845*9663SMark.Logan@Sun.COM                         command_line_push_line (line, multi_word);
846*9663SMark.Logan@Sun.COM                 }
847*9663SMark.Logan@Sun.COM                 free (line);
848*9663SMark.Logan@Sun.COM         } while (!command_line_get_word_count () && !_def);
849*9663SMark.Logan@Sun.COM 
850*9663SMark.Logan@Sun.COM         if (_def_needs_free)
851*9663SMark.Logan@Sun.COM                 free (_def);
852*9663SMark.Logan@Sun.COM }
853*9663SMark.Logan@Sun.COM 
854*9663SMark.Logan@Sun.COM /**
855*9663SMark.Logan@Sun.COM  * Get a word from command line.
856*9663SMark.Logan@Sun.COM  *
857*9663SMark.Logan@Sun.COM  * \param possibilities a StrList of valid strings, NULL if all are valid.
858*9663SMark.Logan@Sun.COM  * \param multi_word whether multiple words are allowed.
859*9663SMark.Logan@Sun.COM  *
860*9663SMark.Logan@Sun.COM  * \return The word(s), or NULL if empty.
861*9663SMark.Logan@Sun.COM  */
862*9663SMark.Logan@Sun.COM char*
command_line_get_word(const char * prompt,const char * def,const StrList * possibilities,int multi_word)863*9663SMark.Logan@Sun.COM command_line_get_word (const char* prompt, const char* def,
864*9663SMark.Logan@Sun.COM                        const StrList* possibilities, int multi_word)
865*9663SMark.Logan@Sun.COM {
866*9663SMark.Logan@Sun.COM         do {
867*9663SMark.Logan@Sun.COM                 if (command_line_get_word_count ()) {
868*9663SMark.Logan@Sun.COM                         char*       result = command_line_pop_word ();
869*9663SMark.Logan@Sun.COM                         StrList*    result_node;
870*9663SMark.Logan@Sun.COM 
871*9663SMark.Logan@Sun.COM                         if (!possibilities)
872*9663SMark.Logan@Sun.COM                                 return result;
873*9663SMark.Logan@Sun.COM 
874*9663SMark.Logan@Sun.COM                         result_node = str_list_match (possibilities, result);
875*9663SMark.Logan@Sun.COM                         if (result_node == NULL)
876*9663SMark.Logan@Sun.COM                                 error (0, 0, _("invalid token: %s"), result);
877*9663SMark.Logan@Sun.COM                         free (result);
878*9663SMark.Logan@Sun.COM                         if (result_node)
879*9663SMark.Logan@Sun.COM                                 return str_list_convert_node (result_node);
880*9663SMark.Logan@Sun.COM 
881*9663SMark.Logan@Sun.COM                         command_line_flush ();
882*9663SMark.Logan@Sun.COM                         if (opt_script_mode)
883*9663SMark.Logan@Sun.COM                                 return NULL;
884*9663SMark.Logan@Sun.COM                 }
885*9663SMark.Logan@Sun.COM 
886*9663SMark.Logan@Sun.COM                 command_line_prompt_words (prompt, def, possibilities,
887*9663SMark.Logan@Sun.COM                                            multi_word);
888*9663SMark.Logan@Sun.COM         } while (command_line_get_word_count ());
889*9663SMark.Logan@Sun.COM 
890*9663SMark.Logan@Sun.COM         return NULL;
891*9663SMark.Logan@Sun.COM }
892*9663SMark.Logan@Sun.COM 
893*9663SMark.Logan@Sun.COM int
command_line_get_integer(const char * prompt,int * value)894*9663SMark.Logan@Sun.COM command_line_get_integer (const char* prompt, int* value)
895*9663SMark.Logan@Sun.COM {
896*9663SMark.Logan@Sun.COM         char     def_str [10];
897*9663SMark.Logan@Sun.COM         char*    input;
898*9663SMark.Logan@Sun.COM         int      valid;
899*9663SMark.Logan@Sun.COM 
900*9663SMark.Logan@Sun.COM         snprintf (def_str, 10, "%d", *value);
901*9663SMark.Logan@Sun.COM         input = command_line_get_word (prompt, *value ? def_str : NULL,
902*9663SMark.Logan@Sun.COM                                        NULL, 1);
903*9663SMark.Logan@Sun.COM         if (!input)
904*9663SMark.Logan@Sun.COM                 return 0;
905*9663SMark.Logan@Sun.COM         valid = sscanf (input, "%d", value);
906*9663SMark.Logan@Sun.COM         free (input);
907*9663SMark.Logan@Sun.COM         return valid;
908*9663SMark.Logan@Sun.COM }
909*9663SMark.Logan@Sun.COM 
910*9663SMark.Logan@Sun.COM int
command_line_get_sector(const char * prompt,PedDevice * dev,PedSector * value,PedGeometry ** range)911*9663SMark.Logan@Sun.COM command_line_get_sector (const char* prompt, PedDevice* dev, PedSector* value,
912*9663SMark.Logan@Sun.COM                          PedGeometry** range)
913*9663SMark.Logan@Sun.COM {
914*9663SMark.Logan@Sun.COM         char*    def_str;
915*9663SMark.Logan@Sun.COM         char*    input;
916*9663SMark.Logan@Sun.COM         int      valid;
917*9663SMark.Logan@Sun.COM 
918*9663SMark.Logan@Sun.COM         def_str = ped_unit_format (dev, *value);
919*9663SMark.Logan@Sun.COM         input = command_line_get_word (prompt, *value ? def_str : NULL,
920*9663SMark.Logan@Sun.COM                                        NULL, 1);
921*9663SMark.Logan@Sun.COM 
922*9663SMark.Logan@Sun.COM         /* def_str might have rounded *value a little bit.  If the user picked
923*9663SMark.Logan@Sun.COM          * the default, make sure the selected sector is identical to the
924*9663SMark.Logan@Sun.COM          * default.
925*9663SMark.Logan@Sun.COM          */
926*9663SMark.Logan@Sun.COM         if (input && *value && !strcmp (input, def_str)) {
927*9663SMark.Logan@Sun.COM                 if (range) {
928*9663SMark.Logan@Sun.COM                         *range = ped_geometry_new (dev, *value, 1);
929*9663SMark.Logan@Sun.COM                         ped_free (def_str);
930*9663SMark.Logan@Sun.COM                         return *range != NULL;
931*9663SMark.Logan@Sun.COM                 }
932*9663SMark.Logan@Sun.COM 
933*9663SMark.Logan@Sun.COM                 ped_free (def_str);
934*9663SMark.Logan@Sun.COM                 return 1;
935*9663SMark.Logan@Sun.COM         }
936*9663SMark.Logan@Sun.COM 
937*9663SMark.Logan@Sun.COM         ped_free (def_str);
938*9663SMark.Logan@Sun.COM         if (!input) {
939*9663SMark.Logan@Sun.COM                 *value = 0;
940*9663SMark.Logan@Sun.COM                 if (range)
941*9663SMark.Logan@Sun.COM                         *range = NULL;
942*9663SMark.Logan@Sun.COM                 return 0;
943*9663SMark.Logan@Sun.COM         }
944*9663SMark.Logan@Sun.COM 
945*9663SMark.Logan@Sun.COM         valid = ped_unit_parse (input, dev, value, range);
946*9663SMark.Logan@Sun.COM 
947*9663SMark.Logan@Sun.COM         free (input);
948*9663SMark.Logan@Sun.COM         return valid;
949*9663SMark.Logan@Sun.COM }
950*9663SMark.Logan@Sun.COM 
951*9663SMark.Logan@Sun.COM int
command_line_get_state(const char * prompt,int * value)952*9663SMark.Logan@Sun.COM command_line_get_state (const char* prompt, int* value)
953*9663SMark.Logan@Sun.COM {
954*9663SMark.Logan@Sun.COM         char*    def_word;
955*9663SMark.Logan@Sun.COM         char*    input;
956*9663SMark.Logan@Sun.COM 
957*9663SMark.Logan@Sun.COM         if (*value)
958*9663SMark.Logan@Sun.COM                 def_word = str_list_convert_node (on_list);
959*9663SMark.Logan@Sun.COM         else
960*9663SMark.Logan@Sun.COM                 def_word = str_list_convert_node (off_list);
961*9663SMark.Logan@Sun.COM         input = command_line_get_word (prompt, def_word, on_off_list, 1);
962*9663SMark.Logan@Sun.COM         free (def_word);
963*9663SMark.Logan@Sun.COM         if (!input)
964*9663SMark.Logan@Sun.COM                 return 0;
965*9663SMark.Logan@Sun.COM         if (str_list_match_any (on_list, input))
966*9663SMark.Logan@Sun.COM                 *value = 1;
967*9663SMark.Logan@Sun.COM         else
968*9663SMark.Logan@Sun.COM                 *value = 0;
969*9663SMark.Logan@Sun.COM         free (input);
970*9663SMark.Logan@Sun.COM         return 1;
971*9663SMark.Logan@Sun.COM }
972*9663SMark.Logan@Sun.COM 
973*9663SMark.Logan@Sun.COM int
command_line_get_device(const char * prompt,PedDevice ** value)974*9663SMark.Logan@Sun.COM command_line_get_device (const char* prompt, PedDevice** value)
975*9663SMark.Logan@Sun.COM {
976*9663SMark.Logan@Sun.COM         char*         def_dev_name = *value ? (*value)->path : NULL;
977*9663SMark.Logan@Sun.COM         char*         dev_name;
978*9663SMark.Logan@Sun.COM         PedDevice*    dev;
979*9663SMark.Logan@Sun.COM 
980*9663SMark.Logan@Sun.COM         dev_name = command_line_get_word (prompt, def_dev_name, NULL, 1);
981*9663SMark.Logan@Sun.COM         if (!dev_name)
982*9663SMark.Logan@Sun.COM                 return 0;
983*9663SMark.Logan@Sun.COM 
984*9663SMark.Logan@Sun.COM         dev = ped_device_get (dev_name);
985*9663SMark.Logan@Sun.COM         free (dev_name);
986*9663SMark.Logan@Sun.COM         if (!dev)
987*9663SMark.Logan@Sun.COM                 return 0;
988*9663SMark.Logan@Sun.COM 
989*9663SMark.Logan@Sun.COM         *value = dev;
990*9663SMark.Logan@Sun.COM         return 1;
991*9663SMark.Logan@Sun.COM }
992*9663SMark.Logan@Sun.COM 
993*9663SMark.Logan@Sun.COM int
command_line_get_disk(const char * prompt,PedDisk ** value)994*9663SMark.Logan@Sun.COM command_line_get_disk (const char* prompt, PedDisk** value)
995*9663SMark.Logan@Sun.COM {
996*9663SMark.Logan@Sun.COM         PedDevice*    dev = *value ? (*value)->dev : NULL;
997*9663SMark.Logan@Sun.COM 
998*9663SMark.Logan@Sun.COM         if (!command_line_get_device (prompt, &dev))
999*9663SMark.Logan@Sun.COM                 return 0;
1000*9663SMark.Logan@Sun.COM 
1001*9663SMark.Logan@Sun.COM         if (dev != (*value)->dev) {
1002*9663SMark.Logan@Sun.COM                 PedDisk*    new_disk = ped_disk_new (dev);
1003*9663SMark.Logan@Sun.COM                 if (!new_disk)
1004*9663SMark.Logan@Sun.COM                         return 0;
1005*9663SMark.Logan@Sun.COM                 *value = new_disk;
1006*9663SMark.Logan@Sun.COM         }
1007*9663SMark.Logan@Sun.COM         return 1;
1008*9663SMark.Logan@Sun.COM }
1009*9663SMark.Logan@Sun.COM 
1010*9663SMark.Logan@Sun.COM int
command_line_get_partition(const char * prompt,PedDisk * disk,PedPartition ** value)1011*9663SMark.Logan@Sun.COM command_line_get_partition (const char* prompt, PedDisk* disk,
1012*9663SMark.Logan@Sun.COM                             PedPartition** value)
1013*9663SMark.Logan@Sun.COM {
1014*9663SMark.Logan@Sun.COM         PedPartition*    part;
1015*9663SMark.Logan@Sun.COM 
1016*9663SMark.Logan@Sun.COM         /* Flawed logic, doesn't seem to work?!
1017*9663SMark.Logan@Sun.COM         check = ped_disk_next_partition (disk, part);
1018*9663SMark.Logan@Sun.COM         part  = ped_disk_next_partition (disk, check);
1019*9663SMark.Logan@Sun.COM 
1020*9663SMark.Logan@Sun.COM         if (part == NULL) {
1021*9663SMark.Logan@Sun.COM 
1022*9663SMark.Logan@Sun.COM         *value = check;
1023*9663SMark.Logan@Sun.COM         printf (_("The (only) primary partition has "
1024*9663SMark.Logan@Sun.COM                   "been automatically selected\n"));
1025*9663SMark.Logan@Sun.COM         return 1;
1026*9663SMark.Logan@Sun.COM 
1027*9663SMark.Logan@Sun.COM         } else {
1028*9663SMark.Logan@Sun.COM         */
1029*9663SMark.Logan@Sun.COM         int num = (*value) ? (*value)->num : 0;
1030*9663SMark.Logan@Sun.COM 
1031*9663SMark.Logan@Sun.COM         if (!command_line_get_integer (prompt, &num)) {
1032*9663SMark.Logan@Sun.COM                 ped_exception_throw (PED_EXCEPTION_ERROR,
1033*9663SMark.Logan@Sun.COM                                      PED_EXCEPTION_CANCEL,
1034*9663SMark.Logan@Sun.COM                                      _("Expecting a partition number."));
1035*9663SMark.Logan@Sun.COM                 return 0;
1036*9663SMark.Logan@Sun.COM         }
1037*9663SMark.Logan@Sun.COM 
1038*9663SMark.Logan@Sun.COM         part = ped_disk_get_partition (disk, num);
1039*9663SMark.Logan@Sun.COM 
1040*9663SMark.Logan@Sun.COM         if (!part) {
1041*9663SMark.Logan@Sun.COM                 ped_exception_throw (PED_EXCEPTION_ERROR,
1042*9663SMark.Logan@Sun.COM                                      PED_EXCEPTION_CANCEL,
1043*9663SMark.Logan@Sun.COM                                      _("Partition doesn't exist."));
1044*9663SMark.Logan@Sun.COM             return 0;
1045*9663SMark.Logan@Sun.COM         }
1046*9663SMark.Logan@Sun.COM 
1047*9663SMark.Logan@Sun.COM         *value = part;
1048*9663SMark.Logan@Sun.COM         return 1;
1049*9663SMark.Logan@Sun.COM         //}
1050*9663SMark.Logan@Sun.COM }
1051*9663SMark.Logan@Sun.COM 
1052*9663SMark.Logan@Sun.COM int
command_line_get_fs_type(const char * prompt,const PedFileSystemType * (* value))1053*9663SMark.Logan@Sun.COM command_line_get_fs_type (const char* prompt, const PedFileSystemType*(* value))
1054*9663SMark.Logan@Sun.COM {
1055*9663SMark.Logan@Sun.COM         char*                 fs_type_name;
1056*9663SMark.Logan@Sun.COM         PedFileSystemType*    fs_type;
1057*9663SMark.Logan@Sun.COM 
1058*9663SMark.Logan@Sun.COM         fs_type_name = command_line_get_word (prompt,
1059*9663SMark.Logan@Sun.COM                                               *value ? (*value)->name : NULL,
1060*9663SMark.Logan@Sun.COM                                                      fs_type_list, 1);
1061*9663SMark.Logan@Sun.COM         if (!fs_type_name) {
1062*9663SMark.Logan@Sun.COM                 ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1063*9663SMark.Logan@Sun.COM                                      _("Expecting a file system type."));
1064*9663SMark.Logan@Sun.COM                 return 0;
1065*9663SMark.Logan@Sun.COM         }
1066*9663SMark.Logan@Sun.COM 
1067*9663SMark.Logan@Sun.COM         fs_type = ped_file_system_type_get (fs_type_name);
1068*9663SMark.Logan@Sun.COM         if (!fs_type) {
1069*9663SMark.Logan@Sun.COM                 ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1070*9663SMark.Logan@Sun.COM                                      _("Unknown file system type \"%s\"."),
1071*9663SMark.Logan@Sun.COM                                      fs_type_name);
1072*9663SMark.Logan@Sun.COM                 return 0;
1073*9663SMark.Logan@Sun.COM         }
1074*9663SMark.Logan@Sun.COM 
1075*9663SMark.Logan@Sun.COM         free (fs_type_name);
1076*9663SMark.Logan@Sun.COM         *value = fs_type;
1077*9663SMark.Logan@Sun.COM         return 1;
1078*9663SMark.Logan@Sun.COM }
1079*9663SMark.Logan@Sun.COM 
1080*9663SMark.Logan@Sun.COM int
command_line_get_disk_type(const char * prompt,const PedDiskType * (* value))1081*9663SMark.Logan@Sun.COM command_line_get_disk_type (const char* prompt, const PedDiskType*(* value))
1082*9663SMark.Logan@Sun.COM {
1083*9663SMark.Logan@Sun.COM         char*    disk_type_name;
1084*9663SMark.Logan@Sun.COM 
1085*9663SMark.Logan@Sun.COM         disk_type_name = command_line_get_word (prompt,
1086*9663SMark.Logan@Sun.COM                                                 *value ? (*value)->name : NULL,
1087*9663SMark.Logan@Sun.COM                                                 disk_type_list, 1);
1088*9663SMark.Logan@Sun.COM         if (!disk_type_name) {
1089*9663SMark.Logan@Sun.COM                 ped_exception_throw (PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1090*9663SMark.Logan@Sun.COM                                      _("Expecting a disk label type."));
1091*9663SMark.Logan@Sun.COM                 return 0;
1092*9663SMark.Logan@Sun.COM         }
1093*9663SMark.Logan@Sun.COM 
1094*9663SMark.Logan@Sun.COM         *value = ped_disk_type_get (disk_type_name);
1095*9663SMark.Logan@Sun.COM         free (disk_type_name);
1096*9663SMark.Logan@Sun.COM         PED_ASSERT (*value != NULL, return 0);
1097*9663SMark.Logan@Sun.COM         return 1;
1098*9663SMark.Logan@Sun.COM }
1099*9663SMark.Logan@Sun.COM 
1100*9663SMark.Logan@Sun.COM int
command_line_get_part_flag(const char * prompt,const PedPartition * part,PedPartitionFlag * flag)1101*9663SMark.Logan@Sun.COM command_line_get_part_flag (const char* prompt, const PedPartition* part,
1102*9663SMark.Logan@Sun.COM                             PedPartitionFlag* flag)
1103*9663SMark.Logan@Sun.COM {
1104*9663SMark.Logan@Sun.COM         StrList*            opts = NULL;
1105*9663SMark.Logan@Sun.COM         PedPartitionFlag    walk = 0;
1106*9663SMark.Logan@Sun.COM         char*               flag_name;
1107*9663SMark.Logan@Sun.COM 
1108*9663SMark.Logan@Sun.COM         while ( (walk = ped_partition_flag_next (walk)) ) {
1109*9663SMark.Logan@Sun.COM                 if (ped_partition_is_flag_available (part, walk)) {
1110*9663SMark.Logan@Sun.COM                         const char*        walk_name;
1111*9663SMark.Logan@Sun.COM 
1112*9663SMark.Logan@Sun.COM                         walk_name = ped_partition_flag_get_name (walk);
1113*9663SMark.Logan@Sun.COM                         opts = str_list_append (opts, walk_name);
1114*9663SMark.Logan@Sun.COM                         opts = str_list_append_unique (opts, _(walk_name));
1115*9663SMark.Logan@Sun.COM                 }
1116*9663SMark.Logan@Sun.COM         }
1117*9663SMark.Logan@Sun.COM 
1118*9663SMark.Logan@Sun.COM         flag_name = command_line_get_word (prompt, NULL, opts, 1);
1119*9663SMark.Logan@Sun.COM         str_list_destroy (opts);
1120*9663SMark.Logan@Sun.COM 
1121*9663SMark.Logan@Sun.COM         if (flag_name) {
1122*9663SMark.Logan@Sun.COM                 *flag = ped_partition_flag_get_by_name (flag_name);
1123*9663SMark.Logan@Sun.COM                 ped_free (flag_name);
1124*9663SMark.Logan@Sun.COM                 return 1;
1125*9663SMark.Logan@Sun.COM         } else
1126*9663SMark.Logan@Sun.COM                 return 0;
1127*9663SMark.Logan@Sun.COM }
1128*9663SMark.Logan@Sun.COM 
1129*9663SMark.Logan@Sun.COM static int
_can_create_primary(const PedDisk * disk)1130*9663SMark.Logan@Sun.COM _can_create_primary (const PedDisk* disk)
1131*9663SMark.Logan@Sun.COM {
1132*9663SMark.Logan@Sun.COM         int    i;
1133*9663SMark.Logan@Sun.COM 
1134*9663SMark.Logan@Sun.COM         for (i = 1; i <= ped_disk_get_max_primary_partition_count (disk); i++) {
1135*9663SMark.Logan@Sun.COM                 if (!ped_disk_get_partition (disk, i))
1136*9663SMark.Logan@Sun.COM                         return 1;
1137*9663SMark.Logan@Sun.COM         }
1138*9663SMark.Logan@Sun.COM 
1139*9663SMark.Logan@Sun.COM         return 0;
1140*9663SMark.Logan@Sun.COM }
1141*9663SMark.Logan@Sun.COM 
1142*9663SMark.Logan@Sun.COM static int
_can_create_extended(const PedDisk * disk)1143*9663SMark.Logan@Sun.COM _can_create_extended (const PedDisk* disk)
1144*9663SMark.Logan@Sun.COM {
1145*9663SMark.Logan@Sun.COM         if (!_can_create_primary (disk))
1146*9663SMark.Logan@Sun.COM                 return 0;
1147*9663SMark.Logan@Sun.COM 
1148*9663SMark.Logan@Sun.COM         if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1149*9663SMark.Logan@Sun.COM                 return 0;
1150*9663SMark.Logan@Sun.COM 
1151*9663SMark.Logan@Sun.COM         if (ped_disk_extended_partition (disk))
1152*9663SMark.Logan@Sun.COM                 return 0;
1153*9663SMark.Logan@Sun.COM 
1154*9663SMark.Logan@Sun.COM         return 1;
1155*9663SMark.Logan@Sun.COM }
1156*9663SMark.Logan@Sun.COM 
1157*9663SMark.Logan@Sun.COM static int
_can_create_logical(const PedDisk * disk)1158*9663SMark.Logan@Sun.COM _can_create_logical (const PedDisk* disk)
1159*9663SMark.Logan@Sun.COM {
1160*9663SMark.Logan@Sun.COM         if (!ped_disk_type_check_feature (disk->type, PED_DISK_TYPE_EXTENDED))
1161*9663SMark.Logan@Sun.COM                 return 0;
1162*9663SMark.Logan@Sun.COM 
1163*9663SMark.Logan@Sun.COM         return ped_disk_extended_partition (disk) != 0;
1164*9663SMark.Logan@Sun.COM }
1165*9663SMark.Logan@Sun.COM 
1166*9663SMark.Logan@Sun.COM int
command_line_get_part_type(const char * prompt,const PedDisk * disk,PedPartitionType * type)1167*9663SMark.Logan@Sun.COM command_line_get_part_type (const char* prompt, const PedDisk* disk,
1168*9663SMark.Logan@Sun.COM                                    PedPartitionType* type)
1169*9663SMark.Logan@Sun.COM {
1170*9663SMark.Logan@Sun.COM         StrList*    opts = NULL;
1171*9663SMark.Logan@Sun.COM         char*       type_name;
1172*9663SMark.Logan@Sun.COM 
1173*9663SMark.Logan@Sun.COM         if (_can_create_primary (disk)) {
1174*9663SMark.Logan@Sun.COM                 opts = str_list_append_unique (opts, "primary");
1175*9663SMark.Logan@Sun.COM                 opts = str_list_append_unique (opts, _("primary"));
1176*9663SMark.Logan@Sun.COM         }
1177*9663SMark.Logan@Sun.COM         if (_can_create_extended (disk)) {
1178*9663SMark.Logan@Sun.COM                 opts = str_list_append_unique (opts, "extended");
1179*9663SMark.Logan@Sun.COM                 opts = str_list_append_unique (opts, _("extended"));
1180*9663SMark.Logan@Sun.COM         }
1181*9663SMark.Logan@Sun.COM         if (_can_create_logical (disk)) {
1182*9663SMark.Logan@Sun.COM                 opts = str_list_append_unique (opts, "logical");
1183*9663SMark.Logan@Sun.COM                 opts = str_list_append_unique (opts, _("logical"));
1184*9663SMark.Logan@Sun.COM         }
1185*9663SMark.Logan@Sun.COM         if (!opts) {
1186*9663SMark.Logan@Sun.COM                 ped_exception_throw (
1187*9663SMark.Logan@Sun.COM                         PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1188*9663SMark.Logan@Sun.COM                         _("Can't create any more partitions."));
1189*9663SMark.Logan@Sun.COM                 return 0;
1190*9663SMark.Logan@Sun.COM         }
1191*9663SMark.Logan@Sun.COM 
1192*9663SMark.Logan@Sun.COM         type_name = command_line_get_word (prompt, NULL, opts, 1);
1193*9663SMark.Logan@Sun.COM         str_list_destroy (opts);
1194*9663SMark.Logan@Sun.COM 
1195*9663SMark.Logan@Sun.COM         if (!type_name) {
1196*9663SMark.Logan@Sun.COM                 ped_exception_throw (
1197*9663SMark.Logan@Sun.COM                         PED_EXCEPTION_ERROR, PED_EXCEPTION_CANCEL,
1198*9663SMark.Logan@Sun.COM                         _("Expecting a partition type."));
1199*9663SMark.Logan@Sun.COM                 return 0;
1200*9663SMark.Logan@Sun.COM         }
1201*9663SMark.Logan@Sun.COM 
1202*9663SMark.Logan@Sun.COM         if (!strcmp (type_name, "primary")
1203*9663SMark.Logan@Sun.COM                         || !strcmp (type_name, _("primary"))) {
1204*9663SMark.Logan@Sun.COM                 *type = 0;
1205*9663SMark.Logan@Sun.COM         }
1206*9663SMark.Logan@Sun.COM         if (!strcmp (type_name, "extended")
1207*9663SMark.Logan@Sun.COM                         || !strcmp (type_name, _("extended"))) {
1208*9663SMark.Logan@Sun.COM                 *type = PED_PARTITION_EXTENDED;
1209*9663SMark.Logan@Sun.COM         }
1210*9663SMark.Logan@Sun.COM         if (!strcmp (type_name, "logical")
1211*9663SMark.Logan@Sun.COM                         || !strcmp (type_name, _("logical"))) {
1212*9663SMark.Logan@Sun.COM                 *type = PED_PARTITION_LOGICAL;
1213*9663SMark.Logan@Sun.COM         }
1214*9663SMark.Logan@Sun.COM 
1215*9663SMark.Logan@Sun.COM         free (type_name);
1216*9663SMark.Logan@Sun.COM         return 1;
1217*9663SMark.Logan@Sun.COM }
1218*9663SMark.Logan@Sun.COM 
1219*9663SMark.Logan@Sun.COM PedExceptionOption
command_line_get_ex_opt(const char * prompt,PedExceptionOption options)1220*9663SMark.Logan@Sun.COM command_line_get_ex_opt (const char* prompt, PedExceptionOption options)
1221*9663SMark.Logan@Sun.COM {
1222*9663SMark.Logan@Sun.COM         StrList*              options_strlist = NULL;
1223*9663SMark.Logan@Sun.COM         PedExceptionOption    opt;
1224*9663SMark.Logan@Sun.COM         char*                 opt_name;
1225*9663SMark.Logan@Sun.COM 
1226*9663SMark.Logan@Sun.COM         for (opt = option_get_next (options, 0); opt;
1227*9663SMark.Logan@Sun.COM              opt = option_get_next (options, opt)) {
1228*9663SMark.Logan@Sun.COM                 options_strlist = str_list_append_unique (options_strlist,
1229*9663SMark.Logan@Sun.COM                                      _(ped_exception_get_option_string (opt)));
1230*9663SMark.Logan@Sun.COM                 options_strlist = str_list_append_unique (options_strlist,
1231*9663SMark.Logan@Sun.COM                                      ped_exception_get_option_string (opt));
1232*9663SMark.Logan@Sun.COM         }
1233*9663SMark.Logan@Sun.COM 
1234*9663SMark.Logan@Sun.COM         opt_name = command_line_get_word (prompt, NULL, options_strlist, 1);
1235*9663SMark.Logan@Sun.COM         if (!opt_name)
1236*9663SMark.Logan@Sun.COM                 return PED_EXCEPTION_UNHANDLED;
1237*9663SMark.Logan@Sun.COM         str_list_destroy (options_strlist);
1238*9663SMark.Logan@Sun.COM 
1239*9663SMark.Logan@Sun.COM         opt = PED_EXCEPTION_OPTION_FIRST;
1240*9663SMark.Logan@Sun.COM         while (1) {
1241*9663SMark.Logan@Sun.COM                 if (strcmp (opt_name,
1242*9663SMark.Logan@Sun.COM                             ped_exception_get_option_string (opt)) == 0)
1243*9663SMark.Logan@Sun.COM                         break;
1244*9663SMark.Logan@Sun.COM                 if (strcmp (opt_name,
1245*9663SMark.Logan@Sun.COM                             _(ped_exception_get_option_string (opt))) == 0)
1246*9663SMark.Logan@Sun.COM                         break;
1247*9663SMark.Logan@Sun.COM                 opt = option_get_next (options, opt);
1248*9663SMark.Logan@Sun.COM         }
1249*9663SMark.Logan@Sun.COM         free (opt_name);
1250*9663SMark.Logan@Sun.COM         return opt;
1251*9663SMark.Logan@Sun.COM }
1252*9663SMark.Logan@Sun.COM 
1253*9663SMark.Logan@Sun.COM int
command_line_get_unit(const char * prompt,PedUnit * unit)1254*9663SMark.Logan@Sun.COM command_line_get_unit (const char* prompt, PedUnit* unit)
1255*9663SMark.Logan@Sun.COM {
1256*9663SMark.Logan@Sun.COM         StrList*       opts = NULL;
1257*9663SMark.Logan@Sun.COM         PedUnit        walk;
1258*9663SMark.Logan@Sun.COM         char*          unit_name;
1259*9663SMark.Logan@Sun.COM         const char*    default_unit_name;
1260*9663SMark.Logan@Sun.COM 
1261*9663SMark.Logan@Sun.COM         for (walk = PED_UNIT_FIRST; walk <= PED_UNIT_LAST; walk++)
1262*9663SMark.Logan@Sun.COM                 opts = str_list_append (opts, ped_unit_get_name (walk));
1263*9663SMark.Logan@Sun.COM 
1264*9663SMark.Logan@Sun.COM         default_unit_name = ped_unit_get_name (ped_unit_get_default ());
1265*9663SMark.Logan@Sun.COM         unit_name = command_line_get_word (prompt, default_unit_name, opts, 1);
1266*9663SMark.Logan@Sun.COM         str_list_destroy (opts);
1267*9663SMark.Logan@Sun.COM 
1268*9663SMark.Logan@Sun.COM         if (unit_name) {
1269*9663SMark.Logan@Sun.COM                 *unit = ped_unit_get_by_name (unit_name);
1270*9663SMark.Logan@Sun.COM                 free (unit_name);
1271*9663SMark.Logan@Sun.COM                 return 1;
1272*9663SMark.Logan@Sun.COM         } else
1273*9663SMark.Logan@Sun.COM                 return 0;
1274*9663SMark.Logan@Sun.COM }
1275*9663SMark.Logan@Sun.COM 
1276*9663SMark.Logan@Sun.COM int
command_line_is_integer()1277*9663SMark.Logan@Sun.COM command_line_is_integer ()
1278*9663SMark.Logan@Sun.COM {
1279*9663SMark.Logan@Sun.COM         char*    word;
1280*9663SMark.Logan@Sun.COM         int      is_integer;
1281*9663SMark.Logan@Sun.COM         int      scratch;
1282*9663SMark.Logan@Sun.COM 
1283*9663SMark.Logan@Sun.COM         word = command_line_peek_word ();
1284*9663SMark.Logan@Sun.COM         if (!word)
1285*9663SMark.Logan@Sun.COM                 return 0;
1286*9663SMark.Logan@Sun.COM 
1287*9663SMark.Logan@Sun.COM         is_integer = sscanf (word, "%d", &scratch);
1288*9663SMark.Logan@Sun.COM         free (word);
1289*9663SMark.Logan@Sun.COM         return is_integer;
1290*9663SMark.Logan@Sun.COM }
1291*9663SMark.Logan@Sun.COM 
1292*9663SMark.Logan@Sun.COM static int
init_ex_opt_str()1293*9663SMark.Logan@Sun.COM init_ex_opt_str ()
1294*9663SMark.Logan@Sun.COM {
1295*9663SMark.Logan@Sun.COM         int                   i;
1296*9663SMark.Logan@Sun.COM         PedExceptionOption    opt;
1297*9663SMark.Logan@Sun.COM 
1298*9663SMark.Logan@Sun.COM         for (i = 0; (1 << i) <= PED_EXCEPTION_OPTION_LAST; i++) {
1299*9663SMark.Logan@Sun.COM                 opt = (1 << i);
1300*9663SMark.Logan@Sun.COM                 ex_opt_str [i]
1301*9663SMark.Logan@Sun.COM                         = str_list_create (
1302*9663SMark.Logan@Sun.COM                                 ped_exception_get_option_string (opt),
1303*9663SMark.Logan@Sun.COM                                 _(ped_exception_get_option_string (opt)),
1304*9663SMark.Logan@Sun.COM                                 NULL);
1305*9663SMark.Logan@Sun.COM                 if (!ex_opt_str [i])
1306*9663SMark.Logan@Sun.COM                         return 0;
1307*9663SMark.Logan@Sun.COM         }
1308*9663SMark.Logan@Sun.COM 
1309*9663SMark.Logan@Sun.COM         ex_opt_str [i] = NULL;
1310*9663SMark.Logan@Sun.COM         return 1;
1311*9663SMark.Logan@Sun.COM }
1312*9663SMark.Logan@Sun.COM 
1313*9663SMark.Logan@Sun.COM static void
done_ex_opt_str()1314*9663SMark.Logan@Sun.COM done_ex_opt_str ()
1315*9663SMark.Logan@Sun.COM {
1316*9663SMark.Logan@Sun.COM         int    i;
1317*9663SMark.Logan@Sun.COM 
1318*9663SMark.Logan@Sun.COM         for (i=0; ex_opt_str [i]; i++)
1319*9663SMark.Logan@Sun.COM                 str_list_destroy (ex_opt_str [i]);
1320*9663SMark.Logan@Sun.COM }
1321*9663SMark.Logan@Sun.COM 
1322*9663SMark.Logan@Sun.COM static int
init_state_str()1323*9663SMark.Logan@Sun.COM init_state_str ()
1324*9663SMark.Logan@Sun.COM {
1325*9663SMark.Logan@Sun.COM         on_list = str_list_create_unique (_("on"), "on", NULL);
1326*9663SMark.Logan@Sun.COM         off_list = str_list_create_unique (_("off"), "off", NULL);
1327*9663SMark.Logan@Sun.COM         on_off_list = str_list_join (str_list_duplicate (on_list),
1328*9663SMark.Logan@Sun.COM                                      str_list_duplicate (off_list));
1329*9663SMark.Logan@Sun.COM         return 1;
1330*9663SMark.Logan@Sun.COM }
1331*9663SMark.Logan@Sun.COM 
1332*9663SMark.Logan@Sun.COM static void
done_state_str()1333*9663SMark.Logan@Sun.COM done_state_str ()
1334*9663SMark.Logan@Sun.COM {
1335*9663SMark.Logan@Sun.COM         str_list_destroy (on_list);
1336*9663SMark.Logan@Sun.COM         str_list_destroy (off_list);
1337*9663SMark.Logan@Sun.COM         str_list_destroy (on_off_list);
1338*9663SMark.Logan@Sun.COM }
1339*9663SMark.Logan@Sun.COM 
1340*9663SMark.Logan@Sun.COM static int
init_fs_type_str()1341*9663SMark.Logan@Sun.COM init_fs_type_str ()
1342*9663SMark.Logan@Sun.COM {
1343*9663SMark.Logan@Sun.COM         PedFileSystemType*    walk;
1344*9663SMark.Logan@Sun.COM 
1345*9663SMark.Logan@Sun.COM         fs_type_list = NULL;
1346*9663SMark.Logan@Sun.COM 
1347*9663SMark.Logan@Sun.COM         for (walk = ped_file_system_type_get_next (NULL); walk;
1348*9663SMark.Logan@Sun.COM              walk = ped_file_system_type_get_next (walk))
1349*9663SMark.Logan@Sun.COM         {
1350*9663SMark.Logan@Sun.COM                 fs_type_list = str_list_insert (fs_type_list, walk->name);
1351*9663SMark.Logan@Sun.COM                 if (!fs_type_list)
1352*9663SMark.Logan@Sun.COM                         return 0;
1353*9663SMark.Logan@Sun.COM         }
1354*9663SMark.Logan@Sun.COM 
1355*9663SMark.Logan@Sun.COM         return 1;
1356*9663SMark.Logan@Sun.COM }
1357*9663SMark.Logan@Sun.COM 
1358*9663SMark.Logan@Sun.COM static int
init_disk_type_str()1359*9663SMark.Logan@Sun.COM init_disk_type_str ()
1360*9663SMark.Logan@Sun.COM {
1361*9663SMark.Logan@Sun.COM         PedDiskType*    walk;
1362*9663SMark.Logan@Sun.COM 
1363*9663SMark.Logan@Sun.COM         disk_type_list = NULL;
1364*9663SMark.Logan@Sun.COM 
1365*9663SMark.Logan@Sun.COM         for (walk = ped_disk_type_get_next (NULL); walk;
1366*9663SMark.Logan@Sun.COM              walk = ped_disk_type_get_next (walk))
1367*9663SMark.Logan@Sun.COM         {
1368*9663SMark.Logan@Sun.COM                 disk_type_list = str_list_insert (disk_type_list, walk->name);
1369*9663SMark.Logan@Sun.COM                 if (!disk_type_list)
1370*9663SMark.Logan@Sun.COM                         return 0;
1371*9663SMark.Logan@Sun.COM         }
1372*9663SMark.Logan@Sun.COM 
1373*9663SMark.Logan@Sun.COM         return 1;
1374*9663SMark.Logan@Sun.COM }
1375*9663SMark.Logan@Sun.COM 
1376*9663SMark.Logan@Sun.COM int
init_ui()1377*9663SMark.Logan@Sun.COM init_ui ()
1378*9663SMark.Logan@Sun.COM {
1379*9663SMark.Logan@Sun.COM         if (!init_ex_opt_str ()
1380*9663SMark.Logan@Sun.COM             || !init_state_str ()
1381*9663SMark.Logan@Sun.COM             || !init_fs_type_str ()
1382*9663SMark.Logan@Sun.COM             || !init_disk_type_str ())
1383*9663SMark.Logan@Sun.COM                 return 0;
1384*9663SMark.Logan@Sun.COM         ped_exception_set_handler (exception_handler);
1385*9663SMark.Logan@Sun.COM 
1386*9663SMark.Logan@Sun.COM #ifdef HAVE_LIBREADLINE
1387*9663SMark.Logan@Sun.COM         rl_initialize ();
1388*9663SMark.Logan@Sun.COM         rl_attempted_completion_function = (CPPFunction*) complete_function;
1389*9663SMark.Logan@Sun.COM         readline_state.in_readline = 0;
1390*9663SMark.Logan@Sun.COM #endif
1391*9663SMark.Logan@Sun.COM 
1392*9663SMark.Logan@Sun.COM #ifdef SA_SIGINFO
1393*9663SMark.Logan@Sun.COM         sigset_t curr;
1394*9663SMark.Logan@Sun.COM         sigfillset (&curr);
1395*9663SMark.Logan@Sun.COM 
1396*9663SMark.Logan@Sun.COM         sig_segv.sa_sigaction = &sa_sigsegv_handler;
1397*9663SMark.Logan@Sun.COM         sig_int.sa_sigaction = &sa_sigint_handler;
1398*9663SMark.Logan@Sun.COM         sig_fpe.sa_sigaction = &sa_sigfpe_handler;
1399*9663SMark.Logan@Sun.COM         sig_ill.sa_sigaction = &sa_sigill_handler;
1400*9663SMark.Logan@Sun.COM 
1401*9663SMark.Logan@Sun.COM         sig_segv.sa_mask =
1402*9663SMark.Logan@Sun.COM                 sig_int.sa_mask =
1403*9663SMark.Logan@Sun.COM                         sig_fpe.sa_mask =
1404*9663SMark.Logan@Sun.COM                                 sig_ill.sa_mask = curr;
1405*9663SMark.Logan@Sun.COM 
1406*9663SMark.Logan@Sun.COM         sig_segv.sa_flags =
1407*9663SMark.Logan@Sun.COM                 sig_int.sa_flags =
1408*9663SMark.Logan@Sun.COM                         sig_fpe.sa_flags =
1409*9663SMark.Logan@Sun.COM                                 sig_ill.sa_flags = SA_SIGINFO;
1410*9663SMark.Logan@Sun.COM 
1411*9663SMark.Logan@Sun.COM         sigaction (SIGSEGV, &sig_segv, NULL);
1412*9663SMark.Logan@Sun.COM         sigaction (SIGINT, &sig_int, NULL);
1413*9663SMark.Logan@Sun.COM         sigaction (SIGFPE, &sig_fpe, NULL);
1414*9663SMark.Logan@Sun.COM         sigaction (SIGILL, &sig_ill, NULL);
1415*9663SMark.Logan@Sun.COM #else
1416*9663SMark.Logan@Sun.COM         signal (SIGSEGV, s_sigsegv_handler);
1417*9663SMark.Logan@Sun.COM         signal (SIGINT, s_sigint_handler);
1418*9663SMark.Logan@Sun.COM         signal (SIGFPE, s_sigfpe_handler);
1419*9663SMark.Logan@Sun.COM         signal (SIGILL, s_sigill_handler);
1420*9663SMark.Logan@Sun.COM #endif /* SA_SIGINFO */
1421*9663SMark.Logan@Sun.COM 
1422*9663SMark.Logan@Sun.COM         return 1;
1423*9663SMark.Logan@Sun.COM }
1424*9663SMark.Logan@Sun.COM 
1425*9663SMark.Logan@Sun.COM void
done_ui()1426*9663SMark.Logan@Sun.COM done_ui ()
1427*9663SMark.Logan@Sun.COM {
1428*9663SMark.Logan@Sun.COM         ped_exception_set_handler (NULL);
1429*9663SMark.Logan@Sun.COM         done_ex_opt_str ();
1430*9663SMark.Logan@Sun.COM         done_state_str ();
1431*9663SMark.Logan@Sun.COM         str_list_destroy (fs_type_list);
1432*9663SMark.Logan@Sun.COM         str_list_destroy (disk_type_list);
1433*9663SMark.Logan@Sun.COM }
1434*9663SMark.Logan@Sun.COM 
1435*9663SMark.Logan@Sun.COM void
help_msg()1436*9663SMark.Logan@Sun.COM help_msg ()
1437*9663SMark.Logan@Sun.COM {
1438*9663SMark.Logan@Sun.COM         fputs (_(usage_msg), stdout);
1439*9663SMark.Logan@Sun.COM 
1440*9663SMark.Logan@Sun.COM         putchar ('\n');
1441*9663SMark.Logan@Sun.COM         fputs (_("OPTIONs:"), stdout);
1442*9663SMark.Logan@Sun.COM         putchar ('\n');
1443*9663SMark.Logan@Sun.COM         print_options_help ();
1444*9663SMark.Logan@Sun.COM 
1445*9663SMark.Logan@Sun.COM         putchar ('\n');
1446*9663SMark.Logan@Sun.COM         fputs (_("COMMANDs:"), stdout);
1447*9663SMark.Logan@Sun.COM         putchar ('\n');
1448*9663SMark.Logan@Sun.COM         print_commands_help ();
1449*9663SMark.Logan@Sun.COM         exit (0);
1450*9663SMark.Logan@Sun.COM }
1451*9663SMark.Logan@Sun.COM 
1452*9663SMark.Logan@Sun.COM void
print_using_dev(PedDevice * dev)1453*9663SMark.Logan@Sun.COM print_using_dev (PedDevice* dev)
1454*9663SMark.Logan@Sun.COM {
1455*9663SMark.Logan@Sun.COM         printf (_("Using %s\n"), dev->path);
1456*9663SMark.Logan@Sun.COM }
1457*9663SMark.Logan@Sun.COM 
1458*9663SMark.Logan@Sun.COM int
interactive_mode(PedDevice ** dev,Command * cmd_list[])1459*9663SMark.Logan@Sun.COM interactive_mode (PedDevice** dev, Command* cmd_list[])
1460*9663SMark.Logan@Sun.COM {
1461*9663SMark.Logan@Sun.COM         StrList*    list;
1462*9663SMark.Logan@Sun.COM         StrList*    command_names = command_get_names (cmd_list);
1463*9663SMark.Logan@Sun.COM 
1464*9663SMark.Logan@Sun.COM         commands = cmd_list;    /* FIXME yucky, nasty, evil hack */
1465*9663SMark.Logan@Sun.COM 
1466*9663SMark.Logan@Sun.COM         fputs (prog_name, stdout);
1467*9663SMark.Logan@Sun.COM 
1468*9663SMark.Logan@Sun.COM         print_using_dev (*dev);
1469*9663SMark.Logan@Sun.COM 
1470*9663SMark.Logan@Sun.COM         list = str_list_create (_(banner_msg), NULL);
1471*9663SMark.Logan@Sun.COM         str_list_print_wrap (list, screen_width (), 0, 0);
1472*9663SMark.Logan@Sun.COM         str_list_destroy (list);
1473*9663SMark.Logan@Sun.COM 
1474*9663SMark.Logan@Sun.COM         while (1) {
1475*9663SMark.Logan@Sun.COM                 char*       word;
1476*9663SMark.Logan@Sun.COM                 Command*    cmd;
1477*9663SMark.Logan@Sun.COM 
1478*9663SMark.Logan@Sun.COM                 while (!command_line_get_word_count ()) {
1479*9663SMark.Logan@Sun.COM                         if (feof (stdin)) {
1480*9663SMark.Logan@Sun.COM                                 putchar ('\n');
1481*9663SMark.Logan@Sun.COM                                 return 1;
1482*9663SMark.Logan@Sun.COM                         }
1483*9663SMark.Logan@Sun.COM                         command_line_prompt_words ("(parted)", NULL,
1484*9663SMark.Logan@Sun.COM                                                    command_names, 1);
1485*9663SMark.Logan@Sun.COM                 }
1486*9663SMark.Logan@Sun.COM 
1487*9663SMark.Logan@Sun.COM                 word = command_line_pop_word ();
1488*9663SMark.Logan@Sun.COM                 if (word) {
1489*9663SMark.Logan@Sun.COM                         cmd = command_get (commands, word);
1490*9663SMark.Logan@Sun.COM                         free (word);
1491*9663SMark.Logan@Sun.COM                         if (cmd) {
1492*9663SMark.Logan@Sun.COM                                 if (!command_run (cmd, dev))
1493*9663SMark.Logan@Sun.COM                                         command_line_flush ();
1494*9663SMark.Logan@Sun.COM                         } else
1495*9663SMark.Logan@Sun.COM                                 print_commands_help ();
1496*9663SMark.Logan@Sun.COM                 }
1497*9663SMark.Logan@Sun.COM         }
1498*9663SMark.Logan@Sun.COM 
1499*9663SMark.Logan@Sun.COM         return 1;
1500*9663SMark.Logan@Sun.COM }
1501*9663SMark.Logan@Sun.COM 
1502*9663SMark.Logan@Sun.COM 
1503*9663SMark.Logan@Sun.COM int
non_interactive_mode(PedDevice ** dev,Command * cmd_list[],int argc,char * argv[])1504*9663SMark.Logan@Sun.COM non_interactive_mode (PedDevice** dev, Command* cmd_list[],
1505*9663SMark.Logan@Sun.COM                       int argc, char* argv[])
1506*9663SMark.Logan@Sun.COM {
1507*9663SMark.Logan@Sun.COM         int         i;
1508*9663SMark.Logan@Sun.COM         Command*    cmd;
1509*9663SMark.Logan@Sun.COM 
1510*9663SMark.Logan@Sun.COM         commands = cmd_list;    /* FIXME yucky, nasty, evil hack */
1511*9663SMark.Logan@Sun.COM 
1512*9663SMark.Logan@Sun.COM         for (i = 0; i < argc; i++)
1513*9663SMark.Logan@Sun.COM                 command_line_push_line (argv [i], 1);
1514*9663SMark.Logan@Sun.COM 
1515*9663SMark.Logan@Sun.COM         while (command_line_get_word_count ()) {
1516*9663SMark.Logan@Sun.COM                 char*    word;
1517*9663SMark.Logan@Sun.COM 
1518*9663SMark.Logan@Sun.COM                 word = command_line_pop_word ();
1519*9663SMark.Logan@Sun.COM                 if (!word)
1520*9663SMark.Logan@Sun.COM                         break;
1521*9663SMark.Logan@Sun.COM 
1522*9663SMark.Logan@Sun.COM                 cmd = command_get (commands, word);
1523*9663SMark.Logan@Sun.COM                 free (word);
1524*9663SMark.Logan@Sun.COM                 if (!cmd) {
1525*9663SMark.Logan@Sun.COM                         help_msg ();
1526*9663SMark.Logan@Sun.COM                         goto error;
1527*9663SMark.Logan@Sun.COM                 }
1528*9663SMark.Logan@Sun.COM                 if (!(cmd->non_interactive)) {
1529*9663SMark.Logan@Sun.COM                         fputs(_("This command does not make sense in "
1530*9663SMark.Logan@Sun.COM                                 "non-interactive mode.\n"), stdout);
1531*9663SMark.Logan@Sun.COM                         exit(1);
1532*9663SMark.Logan@Sun.COM                         goto error;
1533*9663SMark.Logan@Sun.COM                 }
1534*9663SMark.Logan@Sun.COM 
1535*9663SMark.Logan@Sun.COM                 if (!command_run (cmd, dev))
1536*9663SMark.Logan@Sun.COM                         goto error;
1537*9663SMark.Logan@Sun.COM         }
1538*9663SMark.Logan@Sun.COM         return 1;
1539*9663SMark.Logan@Sun.COM 
1540*9663SMark.Logan@Sun.COM error:
1541*9663SMark.Logan@Sun.COM         return 0;
1542*9663SMark.Logan@Sun.COM }
1543