Initial original import from: fuse-2.4.2-2.fc4
[captive.git] / src / client / cmdline / cmd_shell.c
1 /* $Id$
2  * client cmdline interface command "shell" for libcaptive
3  * Copyright (C) 2003 Jan Kratochvil <project-captive@jankratochvil.net>
4  * 
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; exactly version 2 of June 1991 is required
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17  */
18
19
20 #include "config.h"
21
22 #include <glib/gmessages.h>
23 #include <glib/gerror.h>
24 #include <popt.h>
25 #include <stdlib.h>
26 #include <glib/gstrfuncs.h>
27 #include <glib/gmem.h>
28 #include <string.h>
29
30 #ifdef HAVE_LIBREADLINE
31 #include <readline/readline.h>
32 #ifdef HAVE_READLINE_HISTORY_H
33 #include <readline/history.h>
34 #endif /* HAVE_READLINE_HISTORY_H */
35 #endif /* HAVE_LIBREADLINE */
36
37 #include "cmd_shell.h"  /* self */
38 #include "cmd_quit.h"   /* for cmd_quit() */
39 #include "main.h"       /* for invoke_cmd() */
40 #include "cmd_cd.h"
41
42
43 /* Config: */
44 #define PROMPT_STRING "%s$ "    /* %s == 'cmdline_cwd' */
45
46
47 GQuark cmdline_cmd_shell_error_quark(void)
48 {
49 GQuark r=0;
50
51         if (!r)
52                 r=g_quark_from_static_string("cmdline-cmd-shell");
53
54         return r;
55 }
56
57
58 const struct poptOption cmd_shell_table[]={
59                 CMDLINE_POPT_AUTOHELP
60                 POPT_TABLEEND
61                 };
62
63
64 /* Function mostly stolen from the project Partition Surprise.
65  */
66 void cmd_shell(const char **cmd_argv,GError **errp)
67 {
68 char *line;
69 #ifndef HAVE_LIBREADLINE
70 char linebuf[1024],*s;
71 #endif /* HAVE_LIBREADLINE */
72 int errint,line_argc;
73 const char **line_argv=NULL;
74 gchar *prompt;
75 const char *cmd_cd_args[]={NULL};
76
77         g_return_if_fail(!errp || !*errp);
78
79 #ifndef HAVE_LIBREADLINE
80         puts(_("Line editing not available, please recompile with readline library installed"));
81 #endif /* HAVE_LIBREADLINE */
82
83         cmd_cd(cmd_cd_args,errp);       /* Show current directory. */
84         if (errp && *errp)
85                 return;
86
87         for (;;) {
88                 prompt=g_strdup_printf(PROMPT_STRING,cmdline_cwd);
89 #ifdef HAVE_LIBREADLINE
90                 line=readline(prompt);
91 #ifdef HAVE_ADD_HISTORY
92                 if (line && *line)
93                         add_history(line);
94 #endif /* HAVE_ADD_HISTORY */
95 #else /* HAVE_LIBREADLINE */
96                 fputs(prompt,stdout); fflush(stdout);
97                 line=fgets(linebuf,sizeof(linebuf),stdin);
98 #endif /* HAVE_LIBREADLINE */
99                 g_free(prompt);
100                 if (!line) {
101                         cmd_quit(
102                                         NULL,   /* cmd_argv */
103                                         errp);  /* errp */
104                         g_assert_not_reached();
105                         }
106 #ifndef HAVE_LIBREADLINE
107                 if (line && (s=strchr(line,'\n')))
108                         *s='\0';
109 #endif /* HAVE_LIBREADLINE */
110
111                 line_argv=NULL;
112                 errint=poptParseArgvString(line,&line_argc,&line_argv);
113 #ifdef HAVE_LIBREADLINE
114                 free(line);
115 #endif /* HAVE_LIBREADLINE */
116                 if (errint!=0) {
117                         free(line_argv);
118                         g_set_error(errp,CMDLINE_CMD_SHELL_ERROR,CMDLINE_CMD_SHELL_ERROR_LINE_PARSE_ARGUMENTS,
119                                         _("Error '%s' parsing arguments of text line: %s"),poptStrerror(errint),line);
120                         err_cleanup(errp);
121                         continue;
122                         }
123
124                 invoke_cmd(line_argc,line_argv);        /* errors catched inside */
125                 free(line_argv);
126                 }
127 }