1 /*
2  * ***************************************************************************
3  * MALOC = < Minimal Abstraction Layer for Object-oriented C >
4  * Copyright (C) 1994-- Michael Holst
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19  *
20  * rcsid="$Id: vsh_p.h,v 1.12 2010/08/12 05:40:27 fetk Exp $"
21  * ***************************************************************************
22  */
23 
24 /*
25  * ***************************************************************************
26  * File:     vsh_p.h
27  *
28  * Purpose:  PRIVATE header.
29  *
30  * Author:   Michael Holst
31  * ***************************************************************************
32  */
33 
34 #ifndef _VSH_P_H_
35 #define _VSH_P_H_
36 
37 #include <maloc/vsh.h>
38 #include "maloccf.h"
39 
40 #if defined(HAVE_UNISTD_H)
41 #   include <unistd.h>
42 #endif
43 
44 #if defined(HAVE_SYS_TYPES_H)
45 #   include <sys/types.h>
46 #endif
47 
48 #if defined(HAVE_SYS_TIME_H)
49 #   include <sys/time.h>
50 #endif
51 
52 #if defined(HAVE_SYS_TIMES_H)
53 #   include <sys/times.h>
54 #endif
55 
56 #if defined(HAVE_SYS_STAT_H)
57 #   include <sys/stat.h>
58 #endif
59 
60 #if defined(HAVE_FCNTL_H)
61 #   include <fcntl.h>
62 #endif
63 
64 #if defined(HAVE_SYS_WAIT_H)
65 #   include <sys/wait.h>
66 #endif
67 
68 #if defined(HAVE_DIRECT_H)
69 #   include <direct.h>
70 #endif
71 
72 #if defined(HAVE_PROCESS_H)
73 #   include <process.h>
74 #endif
75 
76 #if defined(HAVE_READLINE_READLINE_H)
77 #   include <readline/readline.h>
78 #endif
79 
80 #if defined(HAVE_READLINE_HISTORY_H)
81 #   include <readline/history.h>
82 #endif
83 
84 #if defined(HAVE_WINSOCK_H)
85     VEXTERNC int isatty(int desc);
86 #endif
87 
88 /* macros */
89 /* define Vsh_TRACE */
90 #define VSH_INPUT(buf,result,max_size) { result = Vsh_input((buf),(max_size)); }
91 #define REVERSE_LIST(list, type) \
92     ((list && list->next) ? (type)reverse_list ((GENERIC_LIST *)list) : \
93     (type)(list))
94 
95 /*
96  * All structs which contain a `next' field should have that field
97  * as the first field in the struct.  This means that functions
98  * can be written to handle the general case for linked lists.
99  */
100 typedef struct g_list {
101     struct g_list *next;
102 } GENERIC_LIST;
103 
104 /* Instructions describing what kind of thing to do for a redirection. */
105 enum r_instruction {
106   r_output_direction, r_input_direction, r_inputa_direction,
107   r_appending_to, r_reading_until, r_duplicating_input,
108   r_duplicating_output, r_deblank_reading_until, r_close_this,
109   r_err_and_out, r_input_output, r_output_force,
110   r_duplicating_input_word, r_duplicating_output_word
111 };
112 
113 /* command types */
114 enum command_type {
115     cm_for, cm_case, cm_while, cm_if, cm_simple,
116     cm_connection, cm_function_def, cm_until, cm_group
117 };
118 
119 /* A structure which represents a word. */
120 typedef struct word_desc {
121   char *word;       /* Zero terminated string. */
122   int dollar_present;   /* Non-zero means dollar sign present. */
123   int quoted;       /* Non-zero means single, double, or back quote
124                or backslash is present. */
125   int assignment;   /* Non-zero means that this word contains an
126                assignment. */
127 } WORD_DESC;
128 
129 /* A linked list of words. */
130 typedef struct word_list {
131   struct word_list *next;
132   WORD_DESC *word;
133 } WORD_LIST;
134 
135 /* ************************************************************************ */
136 
137 /* What a redirection descriptor looks like.  If FLAGS is IS_DESCRIPTOR,
138    then we use REDIRECTEE.DEST, else we use the file specified. */
139 
140 typedef union {
141   long dest;            /* Place to redirect REDIRECTOR to, or ... */
142   WORD_DESC *filename;      /* filename to redirect to. */
143 } REDIRECTEE;
144 
145 typedef struct redirect {
146   struct redirect *next;    /* Next element, or NULL. */
147   int redirector;       /* Descriptor to be redirected. */
148   int flags;            /* Flag value for `open'. */
149   enum r_instruction  instruction; /* What to do with the information. */
150   REDIRECTEE redirectee;    /* File descriptor or filename */
151   char *here_doc_eof;       /* The word that appeared in <<foo. */
152 } REDIRECT;
153 
154 /* An element used in parsing.  A single word or a single redirection.
155    This is an ephemeral construct. */
156 typedef struct element {
157   WORD_DESC *word;
158   REDIRECT *redirect;
159 } ELEMENT;
160 
161 /* Possible values for command->flags. */
162 #define CMD_WANT_SUBSHELL  0x01 /* User wants a subshell: ( command ) */
163 #define CMD_FORCE_SUBSHELL 0x02 /* Shell needs to force a subshell. */
164 #define CMD_INVERT_RETURN  0x04 /* Invert the exit value. */
165 #define CMD_IGNORE_RETURN  0x08 /* Ignore the exit value.  For set -e. */
166 #define CMD_NO_FUNCTIONS   0x10 /* Ignore functions during command lookup. */
167 #define CMD_INHIBIT_EXPANSION 0x20 /* Do not expand the command words. */
168 #define CMD_NO_FORK    0x40 /* Don't fork; just call execve */
169 
170 /* What a command looks like. */
171 typedef struct command {
172   enum command_type type;   /* FOR CASE WHILE IF CONNECTION or SIMPLE. */
173   int flags;            /* Flags controlling execution environment. */
174   int line;         /* line number the command starts on */
175   REDIRECT *redirects;      /* Special redirects for FOR CASE, etc. */
176   union {
177     struct for_com *For;
178     struct case_com *Case;
179     struct while_com *While;
180     struct if_com *If;
181     struct connection *Connection;
182     struct simple_com *Simple;
183     struct function_def *Function_def;
184     struct group_com *Group;
185   } value;
186 } COMMAND;
187 
188 /* Structure used to represent the CONNECTION type. */
189 typedef struct connection {
190   int ignore;           /* Unused; simplifies make_command (). */
191   COMMAND *first;       /* Pointer to the first command. */
192   COMMAND *second;      /* Pointer to the second command. */
193   int connector;        /* What separates this command from others. */
194 } CONNECTION;
195 
196 /* Structures used to represent the CASE command. */
197 
198 /* Pattern/action structure for CASE_COM. */
199 typedef struct pattern_list {
200   struct pattern_list *next;    /* Clause to try in case this one failed. */
201   WORD_LIST *patterns;      /* Linked list of patterns to test. */
202   COMMAND *action;      /* Thing to execute if a pattern matches. */
203 } PATTERN_LIST;
204 
205 /* The CASE command. */
206 typedef struct case_com {
207   int flags;            /* See description of CMD flags. */
208   WORD_DESC *word;      /* The thing to test. */
209   PATTERN_LIST *clauses;    /* The clauses to test against, or NULL. */
210 } CASE_COM;
211 
212 /* FOR command. */
213 typedef struct for_com {
214   int flags;        /* See description of CMD flags. */
215   WORD_DESC *name;  /* The variable name to get mapped over. */
216   WORD_LIST *map_list;  /* The things to map over.  This is never NULL. */
217   COMMAND *action;  /* The action to execute.
218                During execution, NAME is bound to successive
219                members of MAP_LIST. */
220 } FOR_COM;
221 
222 /* IF command. */
223 typedef struct if_com {
224   int flags;            /* See description of CMD flags. */
225   COMMAND *test;        /* Thing to test. */
226   COMMAND *true_case;       /* What to do if the test returned non-zero. */
227   COMMAND *false_case;      /* What to do if the test returned zero. */
228 } IF_COM;
229 
230 /* WHILE command. */
231 typedef struct while_com {
232   int flags;            /* See description of CMD flags. */
233   COMMAND *test;        /* Thing to test. */
234   COMMAND *action;      /* Thing to do while test is non-zero. */
235 } WHILE_COM;
236 
237 /* The "simple" command.  Just a collection of words and redirects. */
238 typedef struct simple_com {
239   int flags;            /* See description of CMD flags. */
240   WORD_LIST *words;     /* The program name, the arguments,
241                    variable assignments, etc. */
242   REDIRECT *redirects;      /* Redirections to perform. */
243   int line;         /* line number the command starts on */
244 } SIMPLE_COM;
245 
246 /* The "function_def" command.  This isn't really a command, but it is
247    represented as such for now.  If the function def appears within
248    `(' `)' the parser tries to set the SUBSHELL bit of the command.  That
249    means that FUNCTION_DEF has to be run through the executor.  Maybe this
250    command should be defined in a subshell.  Who knows or cares. */
251 typedef struct function_def {
252   int ignore;           /* See description of CMD flags. */
253   WORD_DESC *name;      /* The name of the function. */
254   COMMAND *command;     /* The parsed execution tree. */
255 } FUNCTION_DEF;
256 
257 /* A command that is `grouped' allows pipes to take effect over
258    the entire command structure. */
259 typedef struct group_com {
260   int ignore;           /* See description of CMD flags. */
261   COMMAND *command;
262 } GROUP_COM;
263 
264 /* ************************************************************************ */
265 
266 /* global variables */
267 VEXTERNC int cmdKey;
268 VEXTERNC Vsh *Vsh_thee;
269 VEXTERNC COMMAND *global_command;
270 
271 /* prototypes for lex/yacc-generated functions */
272 VEXTERNC char *yytext;
273 VEXTERNC int yylex(void);
274 VEXTERNC int yyparse(void);
275 VEXTERNC void yyerror(const char *errmsg);
276 VEXTERNC int yywrap(void);
277 VEXTERNC void yyrestart(FILE *input_file);
278 
279 /* Vsh support */
280 VEXTERNC int Vsh_builtIn(Vsh *thee, int argc, char **argv);
281 VEXTERNC int Vsh_isInteractive(Vsh *thee);
282 
283 /* Vsh support */
284 VEXTERNC void Vsh_trace(char *from, char *arg);
285 VEXTERNC int Vsh_keepVariable(char *envi, char *valu);
286 VEXTERNC void Vsh_addhist(char *buf, int buflen);
287 VEXTERNC char *Vsh_readline(char *prompt, char *buf, int buflen, FILE *stream);
288 VEXTERNC int Vsh_input(char *buf, int buflen);
289 VEXTERNC void Vsh_execCmd(const char *PR, int argc, char **argv, char *inbuf);
290 
291 /* Vpars and lex/yacc support */
292 VEXTERNC void Vsh_parse(void);
293 VEXTERNC void Vsh_parseHandoff(char *buf);
294 VEXTERNC void Vsh_execute(void);
295 VEXTERNC void Vsh_yyexecute(COMMAND *cmd);
296 
297 #endif /* _VSH_P_H_ */
298 
299