Subversion Repositories DevTools

Rev

Rev 303 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 303 Rev 5659
Line 42... Line 42...
42
 *    WIN32 support
42
 *    WIN32 support
43
 *
43
 *
44
 *    Revision 1.1.1.1  1999/12/02 01:11:12  gordonh
44
 *    Revision 1.1.1.1  1999/12/02 01:11:12  gordonh
45
 *    UTIL
45
 *    UTIL
46
 *
46
 *
47
 *	Revision 2.19  1994/08/25  20:49:11  istewart
47
 *      Revision 2.19  1994/08/25  20:49:11  istewart
48
 *	MS Shell 2.3 Release
48
 *      MS Shell 2.3 Release
49
 *
49
 *
50
 *	Revision 2.18  1994/02/23  09:23:38  istewart
50
 *      Revision 2.18  1994/02/23  09:23:38  istewart
51
 *	Beta 233 updates
51
 *      Beta 233 updates
52
 *
52
 *
53
 *	Revision 2.17  1994/02/01  10:25:20  istewart
53
 *      Revision 2.17  1994/02/01  10:25:20  istewart
54
 *	Release 2.3 Beta 2, including first NT port
54
 *      Release 2.3 Beta 2, including first NT port
55
 *
55
 *
56
 *	Revision 2.16  1994/01/20  14:51:43  istewart
56
 *      Revision 2.16  1994/01/20  14:51:43  istewart
57
 *	Release 2.3 Beta 1
57
 *      Release 2.3 Beta 1
58
 *
58
 *
59
 *	Revision 2.15  1994/01/11  17:55:25  istewart
59
 *      Revision 2.15  1994/01/11  17:55:25  istewart
60
 *	Release 2.3 Beta 0 patches
60
 *      Release 2.3 Beta 0 patches
61
 *
61
 *
62
 *	Revision 2.14  1993/12/01  11:58:34  istewart
62
 *      Revision 2.14  1993/12/01  11:58:34  istewart
63
 *	Release 226 beta
63
 *      Release 226 beta
64
 *
64
 *
65
 *	Revision 2.13  1993/11/09  10:39:49  istewart
65
 *      Revision 2.13  1993/11/09  10:39:49  istewart
66
 *	Beta 226 checking
66
 *      Beta 226 checking
67
 *
67
 *
68
 *	Revision 2.12  1993/08/25  16:03:57  istewart
68
 *      Revision 2.12  1993/08/25  16:03:57  istewart
69
 *	Beta 225 - see Notes file
69
 *      Beta 225 - see Notes file
70
 *
70
 *
71
 *	Revision 2.11  1993/07/02  10:21:35  istewart
71
 *      Revision 2.11  1993/07/02  10:21:35  istewart
72
 *	224 Beta fixes
72
 *      224 Beta fixes
73
 *
73
 *
74
 *	Revision 2.10  1993/06/16  12:55:49  istewart
74
 *      Revision 2.10  1993/06/16  12:55:49  istewart
75
 *	Fix the -s and -t options so they work
75
 *      Fix the -s and -t options so they work
76
 *
76
 *
77
 *	Revision 2.9  1993/06/14  11:00:12  istewart
77
 *      Revision 2.9  1993/06/14  11:00:12  istewart
78
 *	More changes for 223 beta
78
 *      More changes for 223 beta
79
 *
79
 *
80
 *	Revision 2.8  1993/06/02  09:52:35  istewart
80
 *      Revision 2.8  1993/06/02  09:52:35  istewart
81
 *	Beta 223 Updates - see Notes file
81
 *      Beta 223 Updates - see Notes file
82
 *
82
 *
83
 *	Revision 2.7  1993/02/16  16:03:15  istewart
83
 *      Revision 2.7  1993/02/16  16:03:15  istewart
84
 *	Beta 2.22 Release
84
 *      Beta 2.22 Release
85
 *
85
 *
86
 *	Revision 2.6  1993/01/26  18:35:09  istewart
86
 *      Revision 2.6  1993/01/26  18:35:09  istewart
87
 *	Release 2.2 beta 0
87
 *      Release 2.2 beta 0
88
 *
88
 *
89
 *	Revision 2.5  1992/12/14  10:54:56  istewart
89
 *      Revision 2.5  1992/12/14  10:54:56  istewart
90
 *	BETA 215 Fixes and 2.1 Release
90
 *      BETA 215 Fixes and 2.1 Release
91
 *
91
 *
92
 *	Revision 2.4  1992/11/06  10:03:44  istewart
92
 *      Revision 2.4  1992/11/06  10:03:44  istewart
93
 *	214 Beta test updates
93
 *      214 Beta test updates
94
 *
94
 *
95
 *	Revision 2.3  1992/09/03  18:54:45  istewart
95
 *      Revision 2.3  1992/09/03  18:54:45  istewart
96
 *	Beta 213 Updates
96
 *      Beta 213 Updates
97
 *
97
 *
98
 *	Revision 2.2  1992/07/16  14:33:34  istewart
98
 *      Revision 2.2  1992/07/16  14:33:34  istewart
99
 *	Beta 212 Baseline
99
 *      Beta 212 Baseline
100
 *
100
 *
101
 *	Revision 2.1  1992/07/10  10:52:48  istewart
101
 *      Revision 2.1  1992/07/10  10:52:48  istewart
102
 *	211 Beta updates
102
 *      211 Beta updates
103
 *
103
 *
104
 *	Revision 2.0  1992/04/13  17:39:09  Ian_Stewartson
104
 *      Revision 2.0  1992/04/13  17:39:09  Ian_Stewartson
105
 *     MS-Shell 2.0 Baseline release
105
 *     MS-Shell 2.0 Baseline release
106
 */
106
 */
107
 
107
 
108
#include <sys/types.h>
108
#include <sys/types.h>
109
#include <sys/stat.h>
109
#include <sys/stat.h>
Line 124... Line 124...
124
 
124
 
125
/* OS2 or DOS, DEBUG MEMORY or normal malloc */
125
/* OS2 or DOS, DEBUG MEMORY or normal malloc */
126
 
126
 
127
#ifdef OS2_DOSALLOC
127
#ifdef OS2_DOSALLOC
128
#  ifdef DEBUG_MEMORY
128
#  ifdef DEBUG_MEMORY
129
#    define RELEASE_MEMORY(x)	if (DosFreeSeg (SELECTOROF ((x))))	\
129
#    define RELEASE_MEMORY(x)   if (DosFreeSeg (SELECTOROF ((x))))      \
130
				    fprintf(stderr, "Memory Release error\n");
130
                                    fprintf(stderr, "Memory Release error\n");
131
#  else
131
#  else
132
#    define RELEASE_MEMORY(x)	DosFreeSeg (SELECTOROF ((x)))
132
#    define RELEASE_MEMORY(x)   DosFreeSeg (SELECTOROF ((x)))
133
#  endif
133
#  endif
134
 
134
 
135
#else
135
#else
136
#  define RELEASE_MEMORY(x)     free ((x))
136
#  define RELEASE_MEMORY(x)     free ((x))
137
#endif
137
#endif
Line 140... Line 140...
140
 * Structure of Malloced space to allow release of space nolonger required
140
 * Structure of Malloced space to allow release of space nolonger required
141
 * without having to know about it.
141
 * without having to know about it.
142
 */
142
 */
143
 
143
 
144
typedef struct region {
144
typedef struct region {
145
    struct region	*next;
145
    struct region       *next;
146
    size_t		nbytes;
146
    size_t              nbytes;
147
    int			area;
147
    int                 area;
148
} s_region;
148
} s_region;
149
 
149
 
150
static struct region	*MemoryAreaHeader = (s_region *)NULL;
150
static struct region    *MemoryAreaHeader = (s_region *)NULL;
151
 
151
 
152
/*
152
/*
153
 * default shell, search rules
153
 * default shell, search rules
154
 */
154
 */
155
 
155
 
156
#if (OS_TYPE == OS_UNIX)
156
#if (OS_TYPE == OS_UNIX)
157
static char		*shellname = "/bin/pksh";
157
static char             *shellname = "/bin/pksh";
158
static char		search[] = ":/bin:/usr/bin";
158
static char             search[] = ":/bin:/usr/bin";
159
 
159
 
160
extern char		**environ;
160
extern char             **environ;
161
#else
161
#else
162
static char		*shellname = "c:/bin/sh.exe";
162
static char             *shellname = "c:/bin/sh.exe";
163
static char		search[] = ";c:/bin;c:/usr/bin";
163
static char             search[] = ";c:/bin;c:/usr/bin";
164
#endif
164
#endif
165
static char		*ymail = "You have mail";
165
static char             *ymail = "You have mail";
166
static char		*ShellNameLiteral = "sh";
166
static char             *ShellNameLiteral = "sh";
167
static char		*ShellOptions = "D:MPRX:abc:defghijklmnopqrtsuvwxyz0";
167
static char             *ShellOptions = "D:MPRX:abc:defghijklmnopqrtsuvwxyz0";
168
 
168
 
169
#if (OS_TYPE != OS_DOS)
169
#if (OS_TYPE != OS_DOS)
170
static char		DefaultWinTitle[] = "MS Shell";
170
static char             DefaultWinTitle[] = "MS Shell";
171
#endif
171
#endif
172
 
172
 
173
#if (OS_TYPE == OS_OS2)
173
#if (OS_TYPE == OS_OS2)
174
#  if (OS_SIZE == OS_32)
174
#  if (OS_SIZE == OS_32)
175
static HEV		SessionQueueSema = 0;
175
static HEV              SessionQueueSema = 0;
176
static HQUEUE		SessionQueueHandler = 0;
176
static HQUEUE           SessionQueueHandler = 0;
177
#  else
177
#  else
178
static HSEM		SessionQueueSema = 0;
178
static HSEM             SessionQueueSema = 0;
179
static HQUEUE		SessionQueueHandler = 0;
179
static HQUEUE           SessionQueueHandler = 0;
180
#  endif
180
#  endif
181
#endif
181
#endif
182
 
182
 
183
static char		*tilde = "~";
183
static char             *tilde = "~";
184
static char		LIT_OSmode[] = "OSMODE";
184
static char             LIT_OSmode[] = "OSMODE";
185
static char		LIT_SHmode[] = "SHMODE";
185
static char             LIT_SHmode[] = "SHMODE";
186
static char		LIT_Dollar[] = "$";
186
static char             LIT_Dollar[] = "$";
187
#if (OS_TYPE == OS_DOS)
187
#if (OS_TYPE == OS_DOS)
188
static char            *NOExit = "sh: ignoring attempt to leave lowest level shell";
188
static char            *NOExit = "sh: ignoring attempt to leave lowest level shell";
189
#endif
189
#endif
190
static bool		ProcessingDEBUGTrap = FALSE;
190
static bool             ProcessingDEBUGTrap = FALSE;
191
static bool		ProcessingERRORTrap = FALSE;
191
static bool             ProcessingERRORTrap = FALSE;
192
static unsigned int	ATOE_GFlags;	/* Twalk GLOBAL flags		*/
192
static unsigned int     ATOE_GFlags;    /* Twalk GLOBAL flags           */
193
static unsigned int	ATNE_Function;	/* Twalk GLOBAL flags		*/
193
static unsigned int     ATNE_Function;  /* Twalk GLOBAL flags           */
194
 
194
 
195
/*
195
/*
196
 * Count value for counting the number entries in an array
196
 * Count value for counting the number entries in an array
197
 */
197
 */
198
 
198
 
199
static int		Count_Array;	/* Array size			*/
199
static int              Count_Array;    /* Array size                   */
200
static char		*Count_Name;	/* Array name			*/
200
static char             *Count_Name;    /* Array name                   */
201
 
201
 
202
/* Integer Variables */
202
/* Integer Variables */
203
 
203
 
204
static struct ShellVariablesInit {
204
static struct ShellVariablesInit {
205
    char       *Name;                   /* Name of variable             */
205
    char       *Name;                   /* Name of variable             */
206
    int		Status;			/* Initial status		*/
206
    int         Status;                 /* Initial status               */
207
    char       *CValue;
207
    char       *CValue;
208
} InitialiseShellVariables[] = {
208
} InitialiseShellVariables[] = {
209
    { LIT_COLUMNS,		STATUS_INTEGER,		"80"		},
209
    { LIT_COLUMNS,              STATUS_INTEGER,         "80"            },
210
    { HistorySizeVariable,	STATUS_INTEGER,		"100"		},
210
    { HistorySizeVariable,      STATUS_INTEGER,         "100"           },
211
    { LineCountVariable,	STATUS_INTEGER,		"1"		},
211
    { LineCountVariable,        STATUS_INTEGER,         "1"             },
212
    { LIT_LINES,		STATUS_INTEGER,		"25"		},
212
    { LIT_LINES,                STATUS_INTEGER,         "25"            },
213
    { OptIndVariable,		STATUS_INTEGER,		"1"		},
213
    { OptIndVariable,           STATUS_INTEGER,         "1"             },
214
    { StatusVariable,		STATUS_INTEGER,		"0"		},
214
    { StatusVariable,           STATUS_INTEGER,         "0"             },
215
    { RandomVariable,		(STATUS_EXPORT | STATUS_INTEGER),
215
    { RandomVariable,           (STATUS_EXPORT | STATUS_INTEGER),
216
							null		},
216
                                                        null            },
217
    { SecondsVariable,		(STATUS_EXPORT | STATUS_INTEGER),
217
    { SecondsVariable,          (STATUS_EXPORT | STATUS_INTEGER),
218
							null		},
218
                                                        null            },
219
    { LIT_OSmode,		(STATUS_EXPORT | STATUS_CANNOT_UNSET |
219
    { LIT_OSmode,               (STATUS_EXPORT | STATUS_CANNOT_UNSET |
220
				 STATUS_INTEGER),	null		},
220
                                 STATUS_INTEGER),       null            },
221
    { LIT_SHmode,		(STATUS_EXPORT | STATUS_CANNOT_UNSET |
221
    { LIT_SHmode,               (STATUS_EXPORT | STATUS_CANNOT_UNSET |
222
				 STATUS_INTEGER),	null		},
222
                                 STATUS_INTEGER),       null            },
223
    { LIT_Dollar,		(STATUS_CANNOT_UNSET | STATUS_INTEGER),
223
    { LIT_Dollar,               (STATUS_CANNOT_UNSET | STATUS_INTEGER),
224
							null		},
224
                                                        null            },
225
 
225
 
226
    { LastWordVariable,		STATUS_EXPORT,		null		},
226
    { LastWordVariable,         STATUS_EXPORT,          null            },
227
    { PathLiteral,		(STATUS_EXPORT | STATUS_CANNOT_UNSET | STATUS_CONVERT_MSDOS),
227
    { PathLiteral,              (STATUS_EXPORT | STATUS_CANNOT_UNSET | STATUS_CONVERT_MSDOS),
228
							search		},
228
                                                        search          },
229
    { IFS,			(STATUS_EXPORT | STATUS_CANNOT_UNSET),
229
    { IFS,                      (STATUS_EXPORT | STATUS_CANNOT_UNSET),
230
							" \t\n"		},
230
                                                        " \t\n"         },
231
    { PS1,			(STATUS_EXPORT | STATUS_CANNOT_UNSET),
231
    { PS1,                      (STATUS_EXPORT | STATUS_CANNOT_UNSET),
232
							"%e$ "		},
232
                                                        "%e$ "          },
233
    { PS2,			(STATUS_EXPORT | STATUS_CANNOT_UNSET),
233
    { PS2,                      (STATUS_EXPORT | STATUS_CANNOT_UNSET),
234
							"> "		},
234
                                                        "> "            },
235
    { PS3,			STATUS_EXPORT,		"#? "		},
235
    { PS3,                      STATUS_EXPORT,          "#? "           },
236
    { PS4,			STATUS_EXPORT,		"+ "		},
236
    { PS4,                      STATUS_EXPORT,          "+ "            },
237
    { HomeVariableName,		STATUS_EXPORT,		null		},
237
    { HomeVariableName,         STATUS_EXPORT,          null            },
238
    { ShellVariableName,	STATUS_EXPORT,		null		},
238
    { ShellVariableName,        STATUS_EXPORT,          null            },
239
 
239
 
240
#if (OS_TYPE != OS_DOS)
240
#if (OS_TYPE != OS_DOS)
241
    { WinTitleVariable, 	0,			DefaultWinTitle	},
241
    { WinTitleVariable,         0,                      DefaultWinTitle },
242
#endif
242
#endif
243
 
243
 
244
    { (char *)NULL,		0 }
244
    { (char *)NULL,             0 }
245
};
245
};
246
 
246
 
247
/*
247
/*
248
 * List of Editor variables
248
 * List of Editor variables
249
 */
249
 */
250
 
250
 
251
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
251
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
252
static char		*EditorVariables[] = {
252
static char             *EditorVariables[] = {
253
    FCEditVariable, EditorVariable, VisualVariable, (char *)NULL
253
    FCEditVariable, EditorVariable, VisualVariable, (char *)NULL
254
};
254
};
255
#endif
255
#endif
256
 
256
 
257
					/* Entry directory		*/
257
                                        /* Entry directory              */
258
static char	Start_directory[PATH_MAX + 6] = { 0 };
258
static char     Start_directory[PATH_MAX + 6] = { 0 };
259
static time_t	ShellStartTime = 0;	/* Load time of shell		*/
259
static time_t   ShellStartTime = 0;     /* Load time of shell           */
260
					/* Original Interrupt 24 address */
260
                                        /* Original Interrupt 24 address */
261
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
261
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
262
#if defined (__WATCOMC__)
262
#if defined (__WATCOMC__)
263
#    define INTERRUPT_TYPE		__interrupt __far
263
#    define INTERRUPT_TYPE              __interrupt __far
264
#  else
264
#  else
265
#    define INTERRUPT_TYPE		interrupt far
265
#    define INTERRUPT_TYPE              interrupt far
266
#  endif
266
#  endif
267
static void	(INTERRUPT_TYPE *Orig_I24_V) (void);
267
static void     (INTERRUPT_TYPE *Orig_I24_V) (void);
268
#endif
268
#endif
269
 
269
 
270
#ifdef SIGQUIT
270
#ifdef SIGQUIT
271
static void     (_SIGDECL *qflag)(int) = SIG_IGN;
271
static void     (_SIGDECL *qflag)(int) = SIG_IGN;
272
#endif
272
#endif
273
 
273
 
274
/* Functions */
274
/* Functions */
275
 
275
 
276
static int F_LOCAL	RunCommands (Source *);
276
static int F_LOCAL      RunCommands (Source *);
277
static unsigned char * F_LOCAL  CheckClassExpression (unsigned char *, int, bool);
277
static unsigned char * F_LOCAL  CheckClassExpression (unsigned char *, int, bool);
278
static bool F_LOCAL	Initialise (int, char **);
278
static bool F_LOCAL     Initialise (int, char **);
279
static void F_LOCAL	CheckForMailArriving (void);
279
static void F_LOCAL     CheckForMailArriving (void);
280
static void F_LOCAL	LoadGlobalVariableList (void);
280
static void F_LOCAL     LoadGlobalVariableList (void);
281
static void F_LOCAL	LoadTheProfileFiles (void);
281
static void F_LOCAL     LoadTheProfileFiles (void);
282
static void F_LOCAL	ConvertUnixPathToMSDOS (char *);
282
static void F_LOCAL     ConvertUnixPathToMSDOS (char *);
283
static void F_LOCAL	ClearUserPrompts (void);
283
static void F_LOCAL     ClearUserPrompts (void);
284
static void F_LOCAL	SecondAndRandomEV (char *, long);
284
static void F_LOCAL     SecondAndRandomEV (char *, long);
285
static void F_LOCAL	SetUpParameterEV (int, char **, char *);
285
static void F_LOCAL     SetUpParameterEV (int, char **, char *);
286
static bool F_LOCAL	AllowedToSetVariable (VariableList *);
286
static bool F_LOCAL     AllowedToSetVariable (VariableList *);
287
static void F_LOCAL	SetUpANumericValue (VariableList *, long, int);
287
static void F_LOCAL     SetUpANumericValue (VariableList *, long, int);
288
static void F_LOCAL	ProcessErrorExit (char *, va_list);
288
static void F_LOCAL     ProcessErrorExit (char *, va_list);
289
static char * F_LOCAL	SuppressSpacesZeros (VariableList *, char *);
289
static char * F_LOCAL   SuppressSpacesZeros (VariableList *, char *);
290
static void		AddToNewEnvironment (const void *, VISIT, int);
290
static void             AddToNewEnvironment (const void *, VISIT, int);
291
static void		AddToOldEnvironment (const void *, VISIT, int);
291
static void             AddToOldEnvironment (const void *, VISIT, int);
292
static void		DeleteEnvironment (const void *, VISIT, int);
292
static void             DeleteEnvironment (const void *, VISIT, int);
293
static void F_LOCAL	CheckOPTIND (char *, long);
293
static void F_LOCAL     CheckOPTIND (char *, long);
294
static void F_LOCAL	CreateIntegerVariables (void);
294
static void F_LOCAL     CreateIntegerVariables (void);
295
static bool F_LOCAL	ExecuteShellScript (char *);
295
static bool F_LOCAL     ExecuteShellScript (char *);
296
static void 		CountEnvironment (const void *, VISIT, int);
296
static void             CountEnvironment (const void *, VISIT, int);
297
 
297
 
298
/*
298
/*
299
 * Process termination
299
 * Process termination
300
 */
300
 */
301
 
301
 
302
#if (OS_TYPE != OS_DOS)
302
#if (OS_TYPE != OS_DOS)
303
static void F_LOCAL	CheckForTerminatedProcess (void);
303
static void F_LOCAL     CheckForTerminatedProcess (void);
304
 
304
 
305
#  if (OS_TYPE == OS_NT)
305
#  if (OS_TYPE == OS_NT)
306
static void		LookUpJobs (const void *, VISIT, int);
306
static void             LookUpJobs (const void *, VISIT, int);
307
#  endif
307
#  endif
308
 
308
 
309
#else
309
#else
310
#  define CheckForTerminatedProcess()
310
#  define CheckForTerminatedProcess()
311
#endif
311
#endif
Line 315... Line 315...
315
 */
315
 */
316
 
316
 
317
#if (OS_TYPE == OS_UNIX)
317
#if (OS_TYPE == OS_UNIX)
318
#define Pre_Process_Argv(a,b)
318
#define Pre_Process_Argv(a,b)
319
#else
319
#else
320
static void F_LOCAL	Pre_Process_Argv (char **, int *);
320
static void F_LOCAL     Pre_Process_Argv (char **, int *);
321
#endif
321
#endif
322
 
322
 
323
/*
323
/*
324
 * OS/2 Session Queues
324
 * OS/2 Session Queues
325
 */
325
 */
326
 
326
 
327
#if (OS_TYPE == OS_OS2)
327
#if (OS_TYPE == OS_OS2)
328
static void F_LOCAL	CheckForSessionEnd (void);
328
static void F_LOCAL     CheckForSessionEnd (void);
329
static void F_LOCAL	CreateTerminationQueues (void);
329
static void F_LOCAL     CreateTerminationQueues (void);
330
#else
330
#else
331
#  define CheckForSessionEnd()
331
#  define CheckForSessionEnd()
332
#  define CreateTerminationQueues()
332
#  define CreateTerminationQueues()
333
#endif
333
#endif
334
 
334
 
335
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
335
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
336
static void F_LOCAL	SetEditorMode (char *);
336
static void F_LOCAL     SetEditorMode (char *);
337
#endif
337
#endif
338
 
338
 
339
/*
339
/*
340
 * The Program Name and Command Line, set up by stdargv.c
340
 * The Program Name and Command Line, set up by stdargv.c
341
 */
341
 */
342
 
342
 
343
#if (OS_TYPE != OS_UNIX)
343
#if (OS_TYPE != OS_UNIX)
344
extern char 		*_APgmName;
344
extern char             *_APgmName;
345
extern char		*_ACmdLine;
345
extern char             *_ACmdLine;
346
#endif
346
#endif
347
 
347
 
348
/*
348
/*
349
**  Debug level
349
**  Debug level
350
*/
350
*/
Line 357... Line 357...
357
void __cdecl main(int argc, char **argv, char **envp)
357
void __cdecl main(int argc, char **argv, char **envp)
358
#else
358
#else
359
void main(int argc, char **argv)
359
void main(int argc, char **argv)
360
#endif
360
#endif
361
{
361
{
362
    int			cflag = 0;
362
    int                 cflag = 0;
363
    int			sc;
363
    int                 sc;
364
    char                *name;
364
    char                *name;
365
					/* Load up various parts of the	*/
365
                                        /* Load up various parts of the */
366
					/* system			*/
366
                                        /* system                       */
367
    bool                OptionsRflag;
367
    bool                OptionsRflag;
368
    bool		OptionsXflag = FALSE;	/* -x option from	*/
368
    bool                OptionsXflag = FALSE;   /* -x option from       */
369
						/* command line		*/
369
                                                /* command line         */
370
    bool		Level0Shell = FALSE;	/* Level 0 (read profile)*/
370
    bool                Level0Shell = FALSE;    /* Level 0 (read profile)*/
371
    jmp_buf		ReturnPoint;
371
    jmp_buf             ReturnPoint;
372
    char		*cp;
372
    char                *cp;
373
    Source		*s;
373
    Source              *s;
374
    int			fid;
374
    int                 fid;
375
    bool		TTYInput;
375
    bool                TTYInput;
376
    bool		PIPEInput;
376
    bool                PIPEInput;
377
    bool		RootShell = FALSE;
377
    bool                RootShell = FALSE;
378
 
378
 
379
    (void) envp;
379
    (void) envp;
380
 
380
 
381
    name = *argv;
381
    name = *argv;
382
    OptionsRflag = Initialise(argc, argv);
382
    OptionsRflag = Initialise(argc, argv);
Line 403... Line 403...
403
 
403
 
404
    S_getcwd (Start_directory, 0);
404
    S_getcwd (Start_directory, 0);
405
 
405
 
406
/* Force Shell Globals as DOS */
406
/* Force Shell Globals as DOS */
407
#if (OS_TYPE == OS_NT) ||(OS_TYPE == OS_DOS)
407
#if (OS_TYPE == OS_NT) ||(OS_TYPE == OS_DOS)
408
	ShellGlobalFlags |= FLAGS_MSDOS_FORMAT;
408
        ShellGlobalFlags |= FLAGS_MSDOS_FORMAT;
409
#endif
409
#endif
410
 
410
 
411
/* Process the options */
411
/* Process the options */
412
 
412
 
413
    while ((sc = GetOptions (argc, argv, ShellOptions, GETOPT_MESSAGE)) != EOF)
413
    while ((sc = GetOptions (argc, argv, ShellOptions, GETOPT_MESSAGE)) != EOF)
414
    {
414
    {
415
	switch (sc)
415
        switch (sc)
416
	{
416
        {
417
	    case '?':
417
            case '?':
418
		FinalExitCleanUp (1);
418
                FinalExitCleanUp (1);
419
 
419
 
420
	    case '0':				/* Level 0 flag for DOS	*/
420
            case '0':                           /* Level 0 flag for DOS */
421
		Level0Shell = TRUE;
421
                Level0Shell = TRUE;
422
		break;
422
                break;
423
 
423
 
424
	    case 'r':				/* Restricted		*/
424
            case 'r':                           /* Restricted           */
425
		OptionsRflag = TRUE;
425
                OptionsRflag = TRUE;
426
		break;
426
                break;
427
 
427
 
428
	    case 'c':				/* Command on line	*/
428
            case 'c':                           /* Command on line      */
429
		ClearUserPrompts ();
429
                ClearUserPrompts ();
430
		cflag = 1;
430
                cflag = 1;
431
		s->type = SSTRING;
431
                s->type = SSTRING;
432
		s->str = OptionArgument;
432
                s->str = OptionArgument;
433
		SetVariableFromString ("_cString", OptionArgument);
433
                SetVariableFromString ("_cString", OptionArgument);
434
		break;
434
                break;
435
 
435
 
436
	    case 'q':				/* No quit ints		*/
436
            case 'q':                           /* No quit ints         */
437
#ifdef SIGQUIT
437
#ifdef SIGQUIT
438
		qflag = SIG_DFL;
438
                qflag = SIG_DFL;
439
#endif
439
#endif
440
		break;
440
                break;
441
 
441
 
442
 
442
 
443
	    case 'X':
443
            case 'X':
444
		if (!GotoDirectory (OptionArgument, GetCurrentDrive ()))
444
                if (!GotoDirectory (OptionArgument, GetCurrentDrive ()))
445
		{
445
                {
446
		    PrintErrorMessage ("%s: bad directory", OptionArgument);
446
                    PrintErrorMessage ("%s: bad directory", OptionArgument);
447
		    FinalExitCleanUp (1);
447
                    FinalExitCleanUp (1);
448
		}
448
                }
449
 
449
 
450
		break;
450
                break;
451
 
451
 
452
	    case 'x':
452
            case 'x':
453
		OptionsXflag = TRUE;
453
                OptionsXflag = TRUE;
-
 
454
                break;
-
 
455
 
-
 
456
            case 'M':
-
 
457
                ShellGlobalFlags |= FLAGS_MSDOS_FORMAT;
-
 
458
                break;
-
 
459
 
-
 
460
            case 'D':
-
 
461
                AssignVariableFromString (OptionArgument, (int *)NULL);
-
 
462
                break;
-
 
463
 
-
 
464
            case 'R':
-
 
465
                RootShell = TRUE;
-
 
466
                ChangeInitLoad = TRUE;  /* Change load .ini pt.         */
454
		break;
467
                break;
455
 
468
 
456
	    case 'M':
469
#if (OS_TYPE != OS_DOS)
-
 
470
            case 'P':                           /* Use real pipes       */
457
		ShellGlobalFlags |= FLAGS_MSDOS_FORMAT;
471
                ShellGlobalFlags |= FLAGS_REALPIPES;
458
	        break;
472
                break;
-
 
473
#endif
459
 
474
 
460
	    case 'D':
-
 
461
		AssignVariableFromString (OptionArgument, (int *)NULL);
475
            case 's':                           /* standard input       */
462
	        break;
476
                if (cflag)
-
 
477
                    PrintErrorMessage ("cannot use -s and -c together");
463
 
478
 
464
	    case 'R':
479
            case 'i':                           /* Set interactive      */
465
		RootShell = TRUE;
480
                InteractiveFlag = TRUE;
466
		ChangeInitLoad = TRUE;	/* Change load .ini pt.		*/
-
 
467
		break;
-
 
468
 
481
 
469
#if (OS_TYPE != OS_DOS)
-
 
470
	    case 'P':				/* Use real pipes	*/
-
 
471
    		ShellGlobalFlags |= FLAGS_REALPIPES;
-
 
472
    		break;
-
 
473
#endif
-
 
474
 
-
 
475
	    case 's':				/* standard input	*/
-
 
476
	    	if (cflag)
-
 
477
		    PrintErrorMessage ("cannot use -s and -c together");
-
 
478
 
-
 
479
	    case 'i':				/* Set interactive	*/
-
 
480
		InteractiveFlag = TRUE;
-
 
481
 
-
 
482
	    default:
482
            default:
483
		if (islower (sc))
483
                if (islower (sc))
484
		    FL_SET (sc);
484
                    FL_SET (sc);
485
	}
485
        }
486
 
486
 
487
/* If -s, set the argv to point to -s so that the rest of the parameters
487
/* If -s, set the argv to point to -s so that the rest of the parameters
488
 * get used as parameters ($digit) values.
488
 * get used as parameters ($digit) values.
489
 */
489
 */
490
 
490
 
491
        if (FL_TEST (FLAG_POSITION))
491
        if (FL_TEST (FLAG_POSITION))
492
	{
492
        {
493
	    OptionIndex--;
493
            OptionIndex--;
494
	    break;
494
            break;
495
	}
495
        }
496
    }
496
    }
497
 
497
 
498
/* Under UNIX, check for login shell */
498
/* Under UNIX, check for login shell */
499
 
499
 
500
#if (OS_TYPE == OS_UNIX)
500
#if (OS_TYPE == OS_UNIX)
501
    if (*argv[0] == '-')
501
    if (*argv[0] == '-')
502
	Level0Shell = TRUE;
502
        Level0Shell = TRUE;
503
#endif
503
#endif
504
 
504
 
505
    argv += OptionIndex;
505
    argv += OptionIndex;
506
    argc -= OptionIndex;
506
    argc -= OptionIndex;
507
 
507
 
Line 553... Line 553...
553
 */
553
 */
554
 
554
 
555
    if ((s->type == SFILE) && (argc > 0) && !InteractiveFlag)
555
    if ((s->type == SFILE) && (argc > 0) && !InteractiveFlag)
556
    {
556
    {
557
        ClearUserPrompts ();
557
        ClearUserPrompts ();
558
	name = *argv;
558
        name = *argv;
559
 
559
 
560
	if (((fid = S_open (FALSE, s->file = name, O_RMASK)) < 0) ||
560
        if (((fid = S_open (FALSE, s->file = name, O_RMASK)) < 0) ||
561
	    ((s->u.file = ReOpenFile (ReMapIOHandler (fid), sOpenReadMode))
561
            ((s->u.file = ReOpenFile (ReMapIOHandler (fid), sOpenReadMode))
562
	                == (FILE *)NULL))
562
                        == (FILE *)NULL))
563
	{
563
        {
564
	    PrintErrorMessage (LIT_Emsg, "cannot open script", name,
564
            PrintErrorMessage (LIT_Emsg, "cannot open script", name,
565
			       strerror (errno));
565
                               strerror (errno));
566
	    FinalExitCleanUp (1);
566
            FinalExitCleanUp (1);
567
	}
567
        }
568
 
568
 
569
/* Un-map this file descriptor from the current environment so it does not
569
/* Un-map this file descriptor from the current environment so it does not
570
 * get closed at the wrong times
570
 * get closed at the wrong times
571
 */
571
 */
572
        ChangeFileDescriptorStatus (fileno (s->u.file), FALSE);
572
        ChangeFileDescriptorStatus (fileno (s->u.file), FALSE);
Line 632... Line 632...
632
 * profiles have been executed.
632
 * profiles have been executed.
633
 */
633
 */
634
 
634
 
635
    if ( debug_level & DEBUG_EXEC_ALL )
635
    if ( debug_level & DEBUG_EXEC_ALL )
636
    {
636
    {
637
    	FL_SET (FLAG_DEBUG_EXECUTE);
637
        FL_SET (FLAG_DEBUG_EXECUTE);
638
     	FL_CLEAR (FLAG_WARNING);
638
        FL_CLEAR (FLAG_WARNING);
639
    }
639
    }
640
    if (OptionsXflag)
640
    if (OptionsXflag)
641
    {
641
    {
642
        FL_SET (FLAG_PRINT_EXECUTE);
642
        FL_SET (FLAG_PRINT_EXECUTE);
643
    }
643
    }
644
 
644
 
645
    if (OptionsRflag)
645
    if (OptionsRflag)
646
    {
646
    {
647
	FL_SET (FLAG_READONLY_SHELL);
647
        FL_SET (FLAG_READONLY_SHELL);
648
	RestrictedShellFlag = TRUE;
648
        RestrictedShellFlag = TRUE;
649
    }
649
    }
650
 
650
 
651
/*
651
/*
652
 * Execute $ENV
652
 * Execute $ENV
653
 *
653
 *
Line 661... Line 661...
661
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
661
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
662
    if (InteractiveFlag)
662
    if (InteractiveFlag)
663
    {
663
    {
664
        char    **rep = EditorVariables;
664
        char    **rep = EditorVariables;
665
 
665
 
666
	while (*rep != (char *)NULL)
666
        while (*rep != (char *)NULL)
667
	{
667
        {
668
	    if ((cp = GetVariableAsString (*(rep++), FALSE)) != null)
668
            if ((cp = GetVariableAsString (*(rep++), FALSE)) != null)
669
	    {
669
            {
670
                SetEditorMode (cp);
670
                SetEditorMode (cp);
671
		break;
671
                break;
672
	    }
672
            }
673
	}
673
        }
674
    }
674
    }
675
#endif
675
#endif
676
 
676
 
677
/*
677
/*
678
 * Execute what ever we have to do!!
678
 * Execute what ever we have to do!!
679
 */
679
 */
680
 
680
 
681
//  while (TRUE)
681
//  while (TRUE)
682
    for (;;)
682
    for (;;)
683
    {
683
    {
684
	switch (SetErrorPoint (ReturnPoint))
684
        switch (SetErrorPoint (ReturnPoint))
685
	{
685
        {
686
	    case TERMINATE_POINT_SET:
686
            case TERMINATE_POINT_SET:
687
		RunCommands (s);		/* Drop to exit		*/
687
                RunCommands (s);                /* Drop to exit         */
688
 
688
 
689
	    case TERMINATE_COMMAND:
689
            case TERMINATE_COMMAND:
690
	    default:
690
            default:
691
		ExitTheShell (FALSE);
691
                ExitTheShell (FALSE);
692
 
692
 
693
/* Re-set TTY input.  If we reach this point, the shell is a root shell and
693
/* Re-set TTY input.  If we reach this point, the shell is a root shell and
694
 * the no exit message has been displayed.  Reset the shell for input from the
694
 * the no exit message has been displayed.  Reset the shell for input from the
695
 * TTY.
695
 * TTY.
696
 */
696
 */
697
 
697
 
698
	    case TERMINATE_SHELL:
698
            case TERMINATE_SHELL:
699
		s->type = STTY;
699
                s->type = STTY;
700
		break;
700
                break;
701
	}
701
        }
702
    }
702
    }
703
}
703
}
704
 
704
 
705
 
705
 
706
/*
706
/*
707
 * Process a script file
707
 * Process a script file
708
 */
708
 */
709
 
709
 
710
static bool F_LOCAL ExecuteShellScript (char *name)
710
static bool F_LOCAL ExecuteShellScript (char *name)
711
{
711
{
712
    FILE	*f = stdin;
712
    FILE        *f = stdin;
713
    int		fp;
713
    int         fp;
714
    Source	*s;
714
    Source      *s;
715
 
715
 
716
    if (strcmp (name, "-") != 0)
716
    if (strcmp (name, "-") != 0)
717
    {
717
    {
718
	if ((fp = OpenForExecution (name, (char **)NULL, (int *)NULL)) < 0)
718
        if ((fp = OpenForExecution (name, (char **)NULL, (int *)NULL)) < 0)
719
	    return FALSE;
719
            return FALSE;
720
 
720
 
721
	if ((f = ReOpenFile (fp = ReMapIOHandler (fp),
721
        if ((f = ReOpenFile (fp = ReMapIOHandler (fp),
722
			     sOpenReadMode)) == (FILE *)NULL)
722
                             sOpenReadMode)) == (FILE *)NULL)
723
	    return FALSE;
723
            return FALSE;
724
    }
724
    }
725
 
725
 
726
    (s = pushs (SFILE))->u.file = f;
726
    (s = pushs (SFILE))->u.file = f;
727
    s->file = name;
727
    s->file = name;
728
 
728
 
729
    RunCommands (s);
729
    RunCommands (s);
730
 
730
 
731
    if (f != stdin)
731
    if (f != stdin)
732
	CloseFile (f);
732
        CloseFile (f);
733
 
733
 
734
    return TRUE;
734
    return TRUE;
735
}
735
}
736
 
736
 
737
 
737
 
Line 739... Line 739...
739
 * run the commands from the input source, returning status.
739
 * run the commands from the input source, returning status.
740
 */
740
 */
741
 
741
 
742
static int F_LOCAL RunCommands (Source *src)
742
static int F_LOCAL RunCommands (Source *src)
743
{
743
{
744
    int		i;
744
    int         i;
745
    jmp_buf	ReturnPoint;
745
    jmp_buf     ReturnPoint;
746
    C_Op	*t = (C_Op *)NULL;
746
    C_Op        *t = (C_Op *)NULL;
747
    bool	wastty;
747
    bool        wastty;
748
    int		EntryMemoryLevel = MemoryAreaLevel + 1;
748
    int         EntryMemoryLevel = MemoryAreaLevel + 1;
749
 
749
 
750
    CreateNewEnvironment ();
750
    CreateNewEnvironment ();
751
    e.ErrorReturnPoint = (ErrorPoint)NULL;
751
    e.ErrorReturnPoint = (ErrorPoint)NULL;
752
    e.line = GetAllocatedSpace (LINE_MAX);
752
    e.line = GetAllocatedSpace (LINE_MAX);
753
 
753
 
Line 759... Line 759...
759
    for (;;)
759
    for (;;)
760
    {
760
    {
761
 
761
 
762
/* Initialise space */
762
/* Initialise space */
763
 
763
 
764
	MemoryAreaLevel = EntryMemoryLevel;
764
        MemoryAreaLevel = EntryMemoryLevel;
765
	ReleaseMemoryArea (MemoryAreaLevel);
765
        ReleaseMemoryArea (MemoryAreaLevel);
766
	SW_intr = 0;
766
        SW_intr = 0;
767
	ProcessingEXECCommand = FALSE;
767
        ProcessingEXECCommand = FALSE;
768
 
768
 
769
	if (src->next == NULL)
769
        if (src->next == NULL)
770
	    src->echo = C2bool (FL_TEST (FLAG_ECHO_INPUT));
770
            src->echo = C2bool (FL_TEST (FLAG_ECHO_INPUT));
771
 
771
 
772
/*
772
/*
773
 * Set up a few things for console input - cursor, mail prompt etc
773
 * Set up a few things for console input - cursor, mail prompt etc
774
 */
774
 */
775
 
775
 
776
	if ((wastty = C2bool (src->type == STTY)) != FALSE)
776
        if ((wastty = C2bool (src->type == STTY)) != FALSE)
777
	{
777
        {
778
	    PositionCursorInColumnZero ();
778
            PositionCursorInColumnZero ();
779
	    CheckForMailArriving ();
779
            CheckForMailArriving ();
780
	    CheckForTerminatedProcess ();
780
            CheckForTerminatedProcess ();
781
	    CloseAllHandlers ();	/* Clean up any open shell files */
781
            CloseAllHandlers ();        /* Clean up any open shell files */
782
	}
782
        }
783
 
783
 
784
	LastUserPrompt = PS1;
784
        LastUserPrompt = PS1;
785
	FlushStreams ();			/* Clear output */
785
        FlushStreams ();                        /* Clear output */
786
 
786
 
787
/* Set execute function recursive level and the SubShell count to zero */
787
/* Set execute function recursive level and the SubShell count to zero */
788
 
788
 
789
	Execute_stack_depth = 0;
789
        Execute_stack_depth = 0;
790
 
790
 
791
/* Set up Redirection IO (Saved) array and SubShell Environment information */
791
/* Set up Redirection IO (Saved) array and SubShell Environment information */
792
 
792
 
793
	NSave_IO_E = 0;		/* Number of entries		*/
793
        NSave_IO_E = 0;         /* Number of entries            */
794
	MSave_IO_E = 0;		/* Max Number of entries	*/
794
        MSave_IO_E = 0;         /* Max Number of entries        */
795
	NSubShells = 0;		/* Number of entries		*/
795
        NSubShells = 0;         /* Number of entries            */
796
	MSubShells = 0;		/* Max Number of entries	*/
796
        MSubShells = 0;         /* Max Number of entries        */
797
	CurrentFunction = (FunctionList *)NULL;
797
        CurrentFunction = (FunctionList *)NULL;
798
	CurrentFunction = (FunctionList *)NULL;
798
        CurrentFunction = (FunctionList *)NULL;
799
	ProcessingDEBUGTrap = FALSE;
799
        ProcessingDEBUGTrap = FALSE;
800
	ProcessingERRORTrap = FALSE;
800
        ProcessingERRORTrap = FALSE;
801
	Break_List = (Break_C *)NULL;
801
        Break_List = (Break_C *)NULL;
802
	Return_List = (Break_C *)NULL;
802
        Return_List = (Break_C *)NULL;
803
	SShell_List = (Break_C *)NULL;
803
        SShell_List = (Break_C *)NULL;
804
	ProcessingEXECCommand = FALSE;
804
        ProcessingEXECCommand = FALSE;
805
 
805
 
806
/* Get the line and process it */
806
/* Get the line and process it */
807
 
807
 
808
	if (SetErrorPoint (ReturnPoint) ||
808
        if (SetErrorPoint (ReturnPoint) ||
809
	    ((t = BuildParseTree (src)) == (C_Op *)NULL) || SW_intr)
809
            ((t = BuildParseTree (src)) == (C_Op *)NULL) || SW_intr)
810
	{
810
        {
811
	    ScrapHereList ();
811
            ScrapHereList ();
812
 
812
 
813
	    if ((!InteractiveFlag && SW_intr) || FL_TEST (FLAG_ONE_COMMAND))
813
            if ((!InteractiveFlag && SW_intr) || FL_TEST (FLAG_ONE_COMMAND))
814
		ExitTheShell (FALSE);
814
                ExitTheShell (FALSE);
815
 
815
 
816
/* Go round again */
816
/* Go round again */
817
 
817
 
818
	    src->str = null;
818
            src->str = null;
819
	    SW_intr = 0;
819
            SW_intr = 0;
820
	    continue;
820
            continue;
821
	}
821
        }
822
 
822
 
823
/* Ok - reset some variables and then execute the command tree */
823
/* Ok - reset some variables and then execute the command tree */
824
 
824
 
825
	SW_intr = 0;
825
        SW_intr = 0;
826
	ProcessingEXECCommand = FALSE;
826
        ProcessingEXECCommand = FALSE;
827
	FlushHistoryBuffer ();		/* Save history			*/
827
        FlushHistoryBuffer ();          /* Save history                 */
828
 
828
 
829
/* Check for exit */
829
/* Check for exit */
830
 
830
 
831
	if ((t != NULL) && (t->type == TEOF))
831
        if ((t != NULL) && (t->type == TEOF))
832
	{
832
        {
833
	    if (wastty && (ShellGlobalFlags & FLAGS_IGNOREEOF))
833
            if (wastty && (ShellGlobalFlags & FLAGS_IGNOREEOF))
834
	    {
834
            {
835
		PrintWarningMessage ("Use `exit'");
835
                PrintWarningMessage ("Use `exit'");
836
		src->type = STTY;
836
                src->type = STTY;
837
		continue;
837
                continue;
838
	    }
838
            }
839
 
839
 
840
	    else
840
            else
841
		break;
841
                break;
842
	}
842
        }
843
 
843
 
844
/* Execute the parse tree */
844
/* Execute the parse tree */
845
 
845
 
846
	if ((SetErrorPoint (ReturnPoint) == 0) &&
846
        if ((SetErrorPoint (ReturnPoint) == 0) &&
847
	    ((!FL_TEST (FLAG_NO_EXECUTE)) || (src->type == STTY)))
847
            ((!FL_TEST (FLAG_NO_EXECUTE)) || (src->type == STTY)))
848
	    ExecuteParseTree (t, NOPIPE, NOPIPE, 0);
848
            ExecuteParseTree (t, NOPIPE, NOPIPE, 0);
849
 
849
 
850
/* Make sure the I/O and environment are back at level 0 and then clear them */
850
/* Make sure the I/O and environment are back at level 0 and then clear them */
851
 
851
 
852
	e.ErrorReturnPoint = (ErrorPoint)NULL;
852
        e.ErrorReturnPoint = (ErrorPoint)NULL;
853
	Execute_stack_depth = 0;
853
        Execute_stack_depth = 0;
854
	ClearExtendedLineFile ();
854
        ClearExtendedLineFile ();
855
 
855
 
856
	if (NSubShells != 0)
856
        if (NSubShells != 0)
857
	    DeleteGlobalVariableList ();
857
            DeleteGlobalVariableList ();
858
 
858
 
859
	if (NSave_IO_E)
859
        if (NSave_IO_E)
860
	    RestoreStandardIO (0, TRUE);
860
            RestoreStandardIO (0, TRUE);
861
 
861
 
862
	if (MSubShells)
862
        if (MSubShells)
863
	    ReleaseMemoryCell ((void *)SubShells);
863
            ReleaseMemoryCell ((void *)SubShells);
864
 
864
 
865
	if (MSave_IO_E)
865
        if (MSave_IO_E)
866
	    ReleaseMemoryCell ((void *)SSave_IO);
866
            ReleaseMemoryCell ((void *)SSave_IO);
867
 
867
 
868
    /* Check for interrupts */
868
    /* Check for interrupts */
869
 
869
 
870
	if ((!InteractiveFlag && SW_intr) || FL_TEST (FLAG_ONE_COMMAND))
870
        if ((!InteractiveFlag && SW_intr) || FL_TEST (FLAG_ONE_COMMAND))
871
	{
871
        {
872
	    ProcessingEXECCommand = FALSE;
872
            ProcessingEXECCommand = FALSE;
873
	    ExitTheShell (FALSE);
873
            ExitTheShell (FALSE);
874
	}
874
        }
875
 
875
 
876
/* Run any traps that are required */
876
/* Run any traps that are required */
877
 
877
 
878
	if ((i = InterruptTrapPending) != 0)
878
        if ((i = InterruptTrapPending) != 0)
879
	{
879
        {
880
	    InterruptTrapPending = 0;
880
            InterruptTrapPending = 0;
881
	    RunTrapCommand (i);
881
            RunTrapCommand (i);
882
	}
882
        }
883
    }
883
    }
884
 
884
 
885
/*
885
/*
886
 * Terminate the current environment
886
 * Terminate the current environment
887
 */
887
 */
Line 895... Line 895...
895
 * Set up the value of $-
895
 * Set up the value of $-
896
 */
896
 */
897
 
897
 
898
void SetShellSwitches (void)
898
void SetShellSwitches (void)
899
{
899
{
900
    char	*cp, c;
900
    char        *cp, c;
901
    char	m['z' - 'a' + 2];
901
    char        m['z' - 'a' + 2];
902
 
902
 
903
    for (cp = m, c = 'a'; c <= 'z'; ++c)
903
    for (cp = m, c = 'a'; c <= 'z'; ++c)
904
    {
904
    {
905
	if (FL_TEST (c))
905
        if (FL_TEST (c))
906
	    *(cp++) = c;
906
            *(cp++) = c;
907
    }
907
    }
908
 
908
 
909
    if (ShellGlobalFlags & FLAGS_MSDOS_FORMAT)
909
    if (ShellGlobalFlags & FLAGS_MSDOS_FORMAT)
910
	*(cp++) = 'M';
910
        *(cp++) = 'M';
911
 
911
 
912
    *cp = 0;
912
    *cp = 0;
913
    SetVariableFromString (ShellOptionsVariable, m);
913
    SetVariableFromString (ShellOptionsVariable, m);
914
}
914
}
915
 
915
 
Line 918... Line 918...
918
 * Terminate current environment with an error
918
 * Terminate current environment with an error
919
 */
919
 */
920
 
920
 
921
void TerminateCurrentEnvironment (int TValue)
921
void TerminateCurrentEnvironment (int TValue)
922
{
922
{
923
    FlushStreams ();			/* Clear output */
923
    FlushStreams ();                    /* Clear output */
924
 
924
 
925
    if (e.ErrorReturnPoint != (ErrorPoint)NULL)
925
    if (e.ErrorReturnPoint != (ErrorPoint)NULL)
926
	ExitErrorPoint (TValue);
926
        ExitErrorPoint (TValue);
927
 
927
 
928
    /* NOTREACHED */
928
    /* NOTREACHED */
929
}
929
}
930
 
930
 
931
 
931
 
Line 933... Line 933...
933
 * Exit the shell
933
 * Exit the shell
934
 */
934
 */
935
 
935
 
936
void ExitTheShell (bool ReturnRequired)
936
void ExitTheShell (bool ReturnRequired)
937
{
937
{
938
    FlushStreams ();			/* Clear output */
938
    FlushStreams ();                    /* Clear output */
939
 
939
 
940
    if (ProcessingEXECCommand)
940
    if (ProcessingEXECCommand)
941
	TerminateCurrentEnvironment (TERMINATE_COMMAND);
941
        TerminateCurrentEnvironment (TERMINATE_COMMAND);
942
 
942
 
943
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
943
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
944
    if (Orig_I24_V == (void (INTERRUPT_TYPE *)())NULL)
944
    if (Orig_I24_V == (void (INTERRUPT_TYPE *)())NULL)
945
    {
945
    {
946
	feputs (NOExit);
946
        feputs (NOExit);
947
 
947
 
948
	if (!ReturnRequired)
948
        if (!ReturnRequired)
949
	    TerminateCurrentEnvironment (TERMINATE_SHELL);
949
            TerminateCurrentEnvironment (TERMINATE_SHELL);
950
    }
950
    }
951
#else
951
#else
952
    (void) ReturnRequired;
952
    (void) ReturnRequired;
953
#endif
953
#endif
954
 
954
 
Line 970... Line 970...
970
/* If this is a command only - restore the directory because DOS doesn't
970
/* If this is a command only - restore the directory because DOS doesn't
971
 * and the user might expect it
971
 * and the user might expect it
972
 */
972
 */
973
 
973
 
974
    if (*Start_directory)
974
    if (*Start_directory)
975
	RestoreCurrentDirectory (Start_directory);
975
        RestoreCurrentDirectory (Start_directory);
976
 
976
 
977
/* If this happens during startup - we restart */
977
/* If this happens during startup - we restart */
978
 
978
 
979
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
979
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
980
    if (Orig_I24_V == (void (INTERRUPT_TYPE *)())NULL)
980
    if (Orig_I24_V == (void (INTERRUPT_TYPE *)())NULL)
981
	return;
981
        return;
982
#endif
982
#endif
983
 
983
 
984
/*
984
/*
985
 * Clean up any Here Document files left in the function tree
985
 * Clean up any Here Document files left in the function tree
986
 */
986
 */
Line 999... Line 999...
999
 * Output warning message
999
 * Output warning message
1000
 */
1000
 */
1001
 
1001
 
1002
int PrintWarningMessage (char *fmt, ...)
1002
int PrintWarningMessage (char *fmt, ...)
1003
{
1003
{
1004
    va_list	ap;
1004
    va_list     ap;
1005
 
1005
 
1006
    va_start (ap, fmt);
1006
    va_start (ap, fmt);
1007
    vfprintf (stderr, fmt, ap);
1007
    vfprintf (stderr, fmt, ap);
1008
    feputc (CHAR_NEW_LINE);
1008
    feputc (CHAR_NEW_LINE);
1009
    ExitStatus = -1;
1009
    ExitStatus = -1;
1010
 
1010
 
1011
/* If leave on error - exit */
1011
/* If leave on error - exit */
1012
 
1012
 
1013
    if (FL_TEST (FLAG_EXIT_ON_ERROR))
1013
    if (FL_TEST (FLAG_EXIT_ON_ERROR))
1014
	ExitTheShell (FALSE);
1014
        ExitTheShell (FALSE);
1015
 
1015
 
1016
    va_end (ap);
1016
    va_end (ap);
1017
    return 1;
1017
    return 1;
1018
}
1018
}
1019
 
1019
 
Line 1022... Line 1022...
1022
 * Shell error message
1022
 * Shell error message
1023
 */
1023
 */
1024
 
1024
 
1025
void ShellErrorMessage (char *fmt, ...)
1025
void ShellErrorMessage (char *fmt, ...)
1026
{
1026
{
1027
    va_list	ap;
1027
    va_list     ap;
1028
 
1028
 
1029
/* Error message processing */
1029
/* Error message processing */
1030
 
1030
 
1031
    if (source->file == (char *)NULL)
1031
    if (source->file == (char *)NULL)
1032
	feputs ("sh: ");
1032
        feputs ("sh: ");
1033
 
1033
 
1034
    else
1034
    else
1035
	fprintf (stderr, "%s: at line %d, ", source->file, source->line);
1035
        fprintf (stderr, "%s: at line %d, ", source->file, source->line);
1036
 
1036
 
1037
    va_start (ap, fmt);
1037
    va_start (ap, fmt);
1038
    ProcessErrorExit (fmt, ap);
1038
    ProcessErrorExit (fmt, ap);
1039
    va_end (ap);
1039
    va_end (ap);
1040
}
1040
}
Line 1044... Line 1044...
1044
 * Output error message
1044
 * Output error message
1045
 */
1045
 */
1046
 
1046
 
1047
void PrintErrorMessage (char *fmt, ...)
1047
void PrintErrorMessage (char *fmt, ...)
1048
{
1048
{
1049
    va_list	ap;
1049
    va_list     ap;
1050
 
1050
 
1051
/* Error message processing */
1051
/* Error message processing */
1052
 
1052
 
1053
    va_start (ap, fmt);
1053
    va_start (ap, fmt);
1054
    ProcessErrorExit (fmt, ap);
1054
    ProcessErrorExit (fmt, ap);
Line 1065... Line 1065...
1065
    feputc (CHAR_NEW_LINE);
1065
    feputc (CHAR_NEW_LINE);
1066
 
1066
 
1067
    ExitStatus = -1;
1067
    ExitStatus = -1;
1068
 
1068
 
1069
    if (FL_TEST (FLAG_EXIT_ON_ERROR))
1069
    if (FL_TEST (FLAG_EXIT_ON_ERROR))
1070
	ExitTheShell (FALSE);
1070
        ExitTheShell (FALSE);
1071
 
1071
 
1072
/* Error processing */
1072
/* Error processing */
1073
 
1073
 
1074
    if (FL_TEST (FLAG_NO_EXECUTE))
1074
    if (FL_TEST (FLAG_NO_EXECUTE))
1075
	return;
1075
        return;
1076
 
1076
 
1077
/* If not interactive - exit */
1077
/* If not interactive - exit */
1078
 
1078
 
1079
    if (!InteractiveFlag)
1079
    if (!InteractiveFlag)
1080
	ExitTheShell (FALSE);
1080
        ExitTheShell (FALSE);
1081
 
1081
 
1082
    if (e.ErrorReturnPoint != (ErrorPoint)NULL)
1082
    if (e.ErrorReturnPoint != (ErrorPoint)NULL)
1083
	ExitErrorPoint (TERMINATE_COMMAND);
1083
        ExitErrorPoint (TERMINATE_COMMAND);
1084
 
1084
 
1085
/* CloseAllHandlers (); Removed - caused problems.  There may be problems
1085
/* CloseAllHandlers (); Removed - caused problems.  There may be problems
1086
 * remaining with files left open?
1086
 * remaining with files left open?
1087
 */
1087
 */
1088
}
1088
}
Line 1092... Line 1092...
1092
 * Create or delete a new environment.  If f is set, delete the environment
1092
 * Create or delete a new environment.  If f is set, delete the environment
1093
 */
1093
 */
1094
 
1094
 
1095
void CreateNewEnvironment (void)
1095
void CreateNewEnvironment (void)
1096
{
1096
{
1097
    ShellFileEnvironment	*ep;
1097
    ShellFileEnvironment        *ep;
1098
 
1098
 
1099
/* Create a new environment */
1099
/* Create a new environment */
1100
 
1100
 
1101
    if ((ep = (ShellFileEnvironment *)
1101
    if ((ep = (ShellFileEnvironment *)
1102
		GetAllocatedSpace (sizeof (ShellFileEnvironment)))
1102
                GetAllocatedSpace (sizeof (ShellFileEnvironment)))
1103
		== (ShellFileEnvironment *)NULL)
1103
                == (ShellFileEnvironment *)NULL)
1104
    {
1104
    {
1105
	while (e.PreviousEnvironment)
1105
        while (e.PreviousEnvironment)
1106
	    QuitCurrentEnvironment ();
1106
            QuitCurrentEnvironment ();
1107
 
1107
 
1108
	TerminateCurrentEnvironment (TERMINATE_COMMAND);
1108
        TerminateCurrentEnvironment (TERMINATE_COMMAND);
1109
    }
1109
    }
1110
 
1110
 
1111
    *ep = e;
1111
    *ep = e;
1112
    e.PreviousEnvironment = ep;
1112
    e.PreviousEnvironment = ep;
1113
    e.IOMap = 0L;
1113
    e.IOMap = 0L;
Line 1119... Line 1119...
1119
 * Exit the current environment successfully
1119
 * Exit the current environment successfully
1120
 */
1120
 */
1121
 
1121
 
1122
void QuitCurrentEnvironment (void)
1122
void QuitCurrentEnvironment (void)
1123
{
1123
{
1124
    ShellFileEnvironment	*ep;
1124
    ShellFileEnvironment        *ep;
1125
    unsigned long		FdMap;
1125
    unsigned long               FdMap;
1126
    Word_B			*wb;
1126
    Word_B                      *wb;
1127
    int				NEntries;
1127
    int                         NEntries;
1128
    int				i;
1128
    int                         i;
1129
 
1129
 
1130
/* Restore old environment, delete the space and close any files opened in
1130
/* Restore old environment, delete the space and close any files opened in
1131
 * this environment
1131
 * this environment
1132
 */
1132
 */
1133
 
1133
 
1134
    if ((ep = e.PreviousEnvironment) != (ShellFileEnvironment *)NULL)
1134
    if ((ep = e.PreviousEnvironment) != (ShellFileEnvironment *)NULL)
1135
    {
1135
    {
1136
 
1136
 
1137
/* Close opened streams */
1137
/* Close opened streams */
1138
 
1138
 
1139
	wb = e.OpenStreams;
1139
        wb = e.OpenStreams;
1140
	NEntries = WordBlockSize (wb);
1140
        NEntries = WordBlockSize (wb);
1141
 
1141
 
1142
	for (i = 0; i < NEntries; i++)
1142
        for (i = 0; i < NEntries; i++)
1143
	{
1143
        {
1144
	    if (wb->w_words[i] != (char *)NULL)
1144
            if (wb->w_words[i] != (char *)NULL)
1145
		fclose ((FILE *)wb->w_words[i]);
1145
                fclose ((FILE *)wb->w_words[i]);
1146
	}
1146
        }
1147
 
1147
 
1148
/* Get the files used in this environment to close */
1148
/* Get the files used in this environment to close */
1149
 
1149
 
1150
	FdMap = e.IOMap;
1150
        FdMap = e.IOMap;
1151
	e = *ep;
1151
        e = *ep;
1152
 
1152
 
1153
	ReleaseMemoryCell ((void *)ep);
1153
        ReleaseMemoryCell ((void *)ep);
1154
 
1154
 
1155
	for (i = 0; i < 32; i++)
1155
        for (i = 0; i < 32; i++)
1156
	{
1156
        {
1157
	    if (FdMap & (1L << i))
1157
            if (FdMap & (1L << i))
1158
		S_close (i + FDBASE, TRUE);
1158
                S_close (i + FDBASE, TRUE);
1159
	}
1159
        }
1160
    }
1160
    }
1161
}
1161
}
1162
 
1162
 
1163
/*
1163
/*
1164
 * Convert binary to ascii
1164
 * Convert binary to ascii
1165
 */
1165
 */
1166
 
1166
 
1167
char *IntegerToString (int n)
1167
char *IntegerToString (int n)
1168
{
1168
{
1169
    static char		nt[10];
1169
    static char         nt[10];
1170
 
1170
 
1171
    sprintf (nt, "%u", n);
1171
    sprintf (nt, "%u", n);
1172
    return nt;
1172
    return nt;
1173
}
1173
}
1174
 
1174
 
Line 1199... Line 1199...
1199
    SW_intr = 1;
1199
    SW_intr = 1;
1200
 
1200
 
1201
/* Are we talking to the user?  Yes - Abandon processing */
1201
/* Are we talking to the user?  Yes - Abandon processing */
1202
 
1202
 
1203
    if (InteractiveFlag)
1203
    if (InteractiveFlag)
1204
	TerminateCurrentEnvironment (TERMINATE_COMMAND);
1204
        TerminateCurrentEnvironment (TERMINATE_COMMAND);
1205
 
1205
 
1206
/* No - exit */
1206
/* No - exit */
1207
 
1207
 
1208
    else
1208
    else
1209
    {
1209
    {
1210
	ProcessingEXECCommand = FALSE;
1210
        ProcessingEXECCommand = FALSE;
1211
	ExitStatus = 1;
1211
        ExitStatus = 1;
1212
	ExitTheShell (FALSE);
1212
        ExitTheShell (FALSE);
1213
    }
1213
    }
1214
}
1214
}
1215
 
1215
 
1216
/*
1216
/*
1217
 * Grap some space and check for an error
1217
 * Grap some space and check for an error
1218
 */
1218
 */
1219
 
1219
 
1220
void *GetAllocatedSpace (size_t n)
1220
void *GetAllocatedSpace (size_t n)
1221
{
1221
{
1222
    void	*cp;
1222
    void        *cp;
1223
 
1223
 
1224
    if ((cp = AllocateMemoryCell (n)) == (void *)NULL)
1224
    if ((cp = AllocateMemoryCell (n)) == (void *)NULL)
1225
	PrintErrorMessage (BasicErrorMessage, ShellNameLiteral, Outofmemory1);
1225
        PrintErrorMessage (BasicErrorMessage, ShellNameLiteral, Outofmemory1);
1226
 
1226
 
1227
    return cp;
1227
    return cp;
1228
}
1228
}
1229
 
1229
 
1230
/*
1230
/*
1231
 * Re-allocate some space
1231
 * Re-allocate some space
1232
 */
1232
 */
1233
 
1233
 
1234
void *ReAllocateSpace (void *OldSpace, size_t NewSize)
1234
void *ReAllocateSpace (void *OldSpace, size_t NewSize)
1235
{
1235
{
1236
    void	*NewSpace;
1236
    void        *NewSpace;
1237
 
1237
 
1238
    if ((NewSpace = GetAllocatedSpace (NewSize)) == (void *)NULL)
1238
    if ((NewSpace = GetAllocatedSpace (NewSize)) == (void *)NULL)
1239
        return NewSpace;
1239
        return NewSpace;
1240
 
1240
 
1241
    if (OldSpace != (void *)NULL)
1241
    if (OldSpace != (void *)NULL)
1242
    {
1242
    {
1243
	size_t	OldSize = ((s_region *)((char *)OldSpace -
1243
        size_t  OldSize = ((s_region *)((char *)OldSpace -
1244
					sizeof (s_region)))->nbytes;
1244
                                        sizeof (s_region)))->nbytes;
1245
 
1245
 
1246
	SetMemoryAreaNumber (NewSpace, GetMemoryAreaNumber (OldSpace));
1246
        SetMemoryAreaNumber (NewSpace, GetMemoryAreaNumber (OldSpace));
1247
	memcpy (NewSpace, OldSpace, OldSize);
1247
        memcpy (NewSpace, OldSpace, OldSize);
1248
	ReleaseMemoryCell (OldSpace);
1248
        ReleaseMemoryCell (OldSpace);
1249
    }
1249
    }
1250
 
1250
 
1251
    return NewSpace;
1251
    return NewSpace;
1252
}
1252
}
1253
 
1253
 
Line 1256... Line 1256...
1256
 * Duplicate a memory Area
1256
 * Duplicate a memory Area
1257
 */
1257
 */
1258
 
1258
 
1259
void *DuplicateMemoryCell (void *cell)
1259
void *DuplicateMemoryCell (void *cell)
1260
{
1260
{
1261
    void	*new;
1261
    void        *new;
1262
    size_t	len = ((s_region *)((char *)cell - sizeof (s_region)))->nbytes;
1262
    size_t      len = ((s_region *)((char *)cell - sizeof (s_region)))->nbytes;
1263
 
1263
 
1264
    if ((new = AllocateMemoryCell (len)) == (void *)NULL)
1264
    if ((new = AllocateMemoryCell (len)) == (void *)NULL)
1265
	PrintErrorMessage (BasicErrorMessage, ShellNameLiteral, Outofmemory1);
1265
        PrintErrorMessage (BasicErrorMessage, ShellNameLiteral, Outofmemory1);
1266
 
1266
 
1267
    else
1267
    else
1268
	memcpy (new, cell, len);
1268
        memcpy (new, cell, len);
1269
 
1269
 
1270
    return new;
1270
    return new;
1271
}
1271
}
1272
 
1272
 
1273
 
1273
 
Line 1284... Line 1284...
1284
 * Save a string in a given area
1284
 * Save a string in a given area
1285
 */
1285
 */
1286
 
1286
 
1287
char *StringSave (char *s)
1287
char *StringSave (char *s)
1288
{
1288
{
1289
    char	*cp;
1289
    char        *cp;
1290
 
1290
 
1291
    if ((cp = GetAllocatedSpace (strlen (s) + 1)) != (char *)NULL)
1291
    if ((cp = GetAllocatedSpace (strlen (s) + 1)) != (char *)NULL)
1292
    {
1292
    {
1293
	SetMemoryAreaNumber ((void *)cp, 0);
1293
        SetMemoryAreaNumber ((void *)cp, 0);
1294
	return strcpy (cp, s);
1294
        return strcpy (cp, s);
1295
    }
1295
    }
1296
 
1296
 
1297
    return null;
1297
    return null;
1298
}
1298
}
1299
 
1299
 
Line 1301... Line 1301...
1301
 * Duplicate at current Memory level
1301
 * Duplicate at current Memory level
1302
 */
1302
 */
1303
 
1303
 
1304
char *StringCopy (char *s)
1304
char *StringCopy (char *s)
1305
{
1305
{
1306
    char	*cp;
1306
    char        *cp;
1307
 
1307
 
1308
    if ((cp = GetAllocatedSpace (strlen (s) + 1)) != (char *)NULL)
1308
    if ((cp = GetAllocatedSpace (strlen (s) + 1)) != (char *)NULL)
1309
	return strcpy (cp, s);
1309
        return strcpy (cp, s);
1310
 
1310
 
1311
    return null;
1311
    return null;
1312
}
1312
}
1313
 
1313
 
1314
/*
1314
/*
1315
 * trap handling - Save signal number and restore signal processing
1315
 * trap handling - Save signal number and restore signal processing
1316
 */
1316
 */
1317
 
1317
 
1318
void _SIGDECL TerminateSignalled (int i)
1318
void _SIGDECL TerminateSignalled (int i)
1319
{
1319
{
1320
    if (i == SIGINT)		/* Need this because swapper sets it	*/
1320
    if (i == SIGINT)            /* Need this because swapper sets it    */
1321
    {
1321
    {
1322
	SW_intr = 0;
1322
        SW_intr = 0;
1323
    }
1323
    }
1324
 
1324
 
1325
    InterruptTrapPending = i;
1325
    InterruptTrapPending = i;
1326
    signal (i, TerminateSignalled);
1326
    signal (i, TerminateSignalled);
1327
}
1327
}
Line 1334... Line 1334...
1334
 * -2 - Error Trap
1334
 * -2 - Error Trap
1335
 */
1335
 */
1336
 
1336
 
1337
void RunTrapCommand (int i)
1337
void RunTrapCommand (int i)
1338
{
1338
{
1339
    Source	*s;
1339
    Source      *s;
1340
    char	*trapstr;
1340
    char        *trapstr;
1341
    char	tval[10];
1341
    char        tval[10];
1342
    char	*tvalp = tval;
1342
    char        *tvalp = tval;
1343
 
1343
 
1344
/* Check for special values and recursion */
1344
/* Check for special values and recursion */
1345
 
1345
 
1346
    if (i == -1)
1346
    if (i == -1)
1347
    {
1347
    {
1348
	tvalp = Trap_DEBUG;
1348
        tvalp = Trap_DEBUG;
1349
 
1349
 
1350
	if (ProcessingDEBUGTrap)
1350
        if (ProcessingDEBUGTrap)
1351
	    return;
1351
            return;
1352
 
1352
 
1353
	ProcessingDEBUGTrap = TRUE;
1353
        ProcessingDEBUGTrap = TRUE;
1354
    }
1354
    }
1355
 
1355
 
1356
/* Error trap */
1356
/* Error trap */
1357
 
1357
 
1358
    else if (i == -2)
1358
    else if (i == -2)
1359
    {
1359
    {
1360
	tvalp = Trap_ERR;
1360
        tvalp = Trap_ERR;
1361
 
1361
 
1362
	if (ProcessingERRORTrap)
1362
        if (ProcessingERRORTrap)
1363
	    return;
1363
            return;
1364
 
1364
 
1365
	ProcessingERRORTrap = TRUE;
1365
        ProcessingERRORTrap = TRUE;
1366
    }
1366
    }
1367
 
1367
 
1368
    else
1368
    else
1369
	sprintf (tval, "~%d", i);
1369
        sprintf (tval, "~%d", i);
1370
 
1370
 
1371
    if ((trapstr = GetVariableAsString (tvalp, FALSE)) == null)
1371
    if ((trapstr = GetVariableAsString (tvalp, FALSE)) == null)
1372
	return;
1372
        return;
1373
 
1373
 
1374
/* If signal zero, save a copy of the trap value and then delete the trap */
1374
/* If signal zero, save a copy of the trap value and then delete the trap */
1375
 
1375
 
1376
    if (i == 0)
1376
    if (i == 0)
1377
    {
1377
    {
1378
	trapstr = StringCopy (trapstr);
1378
        trapstr = StringCopy (trapstr);
1379
	UnSetVariable (tval, -1, TRUE);
1379
        UnSetVariable (tval, -1, TRUE);
1380
    }
1380
    }
1381
 
1381
 
1382
    (s = pushs (SSTRING))->str = trapstr;
1382
    (s = pushs (SSTRING))->str = trapstr;
1383
    RunACommand (s, (char **)NULL);
1383
    RunACommand (s, (char **)NULL);
1384
 
1384
 
Line 1390... Line 1390...
1390
 * Find the given name in the dictionary and return its value.  If the name was
1390
 * Find the given name in the dictionary and return its value.  If the name was
1391
 * not previously there, enter it now and return a null value.
1391
 * not previously there, enter it now and return a null value.
1392
 */
1392
 */
1393
 
1393
 
1394
VariableList    *LookUpVariable (char *name,    /* Variable name        */
1394
VariableList    *LookUpVariable (char *name,    /* Variable name        */
1395
				 int  Index,	/* Array Index		*/
1395
                                 int  Index,    /* Array Index          */
1396
				 bool cflag)	/* Create flag		*/
1396
                                 bool cflag)    /* Create flag          */
1397
{
1397
{
1398
    VariableList		*vp;
1398
    VariableList                *vp;
1399
    VariableList		**vpp;
1399
    VariableList                **vpp;
1400
    int				c;
1400
    int                         c;
1401
    static VariableList		dummy;
1401
    static VariableList         dummy;
1402
    void                        (_SIGDECL *save_signal)(int);
1402
    void                        (_SIGDECL *save_signal)(int);
1403
 
1403
 
1404
/* Set up the dummy variable */
1404
/* Set up the dummy variable */
1405
 
1405
 
1406
    memset (&dummy, 0, sizeof (VariableList));
1406
    memset (&dummy, 0, sizeof (VariableList));
Line 1410... Line 1410...
1410
 
1410
 
1411
/* If digit string - use the dummy to return the value */
1411
/* If digit string - use the dummy to return the value */
1412
 
1412
 
1413
    if (isdigit (*name))
1413
    if (isdigit (*name))
1414
    {
1414
    {
1415
	for (c = 0; isdigit (*name) && (c < 1000); name++)
1415
        for (c = 0; isdigit (*name) && (c < 1000); name++)
1416
	    c = c * 10 + *name - '0';
1416
            c = c * 10 + *name - '0';
1417
 
1417
 
1418
	c += Index;
1418
        c += Index;
1419
	dummy.value = (c <= ParameterCount) ? ParameterArray[c] : null;
1419
        dummy.value = (c <= ParameterCount) ? ParameterArray[c] : null;
1420
	return &dummy;
1420
        return &dummy;
1421
    }
1421
    }
1422
 
1422
 
1423
/* Look up in list */
1423
/* Look up in list */
1424
 
1424
 
1425
    dummy.index = Index;
1425
    dummy.index = Index;
Line 1431... Line 1431...
1431
    {
1431
    {
1432
        vp = *vpp;
1432
        vp = *vpp;
1433
 
1433
 
1434
/* Special processing for SECONDS and RANDOM */
1434
/* Special processing for SECONDS and RANDOM */
1435
 
1435
 
1436
	if (!strcmp (name, SecondsVariable) &&
1436
        if (!strcmp (name, SecondsVariable) &&
1437
	    !(DisabledVariables & DISABLE_SECONDS))
1437
            !(DisabledVariables & DISABLE_SECONDS))
1438
	    SetUpANumericValue (vp, time ((time_t *)NULL) - ShellStartTime, 10);
1438
            SetUpANumericValue (vp, time ((time_t *)NULL) - ShellStartTime, 10);
1439
 
1439
 
1440
	else if (!strcmp (name, RandomVariable) &&
1440
        else if (!strcmp (name, RandomVariable) &&
1441
		 !(DisabledVariables & DISABLE_RANDOM))
1441
                 !(DisabledVariables & DISABLE_RANDOM))
1442
	    SetUpANumericValue (vp, (long)rand(), 10);
1442
            SetUpANumericValue (vp, (long)rand(), 10);
1443
 
1443
 
1444
	return vp;
1444
        return vp;
1445
    }
1445
    }
1446
 
1446
 
1447
/* If we don't want to create it, return a dummy */
1447
/* If we don't want to create it, return a dummy */
1448
 
1448
 
1449
    dummy.status |= STATUS_NOEXISTANT;
1449
    dummy.status |= STATUS_NOEXISTANT;
1450
 
1450
 
1451
    if (!cflag)
1451
    if (!cflag)
1452
	return &dummy;
1452
        return &dummy;
1453
 
1453
 
1454
/* Create a new variable.  If no memory, use the dummy */
1454
/* Create a new variable.  If no memory, use the dummy */
1455
 
1455
 
1456
    dummy.name = null;
1456
    dummy.name = null;
1457
 
1457
 
1458
    if ((vp = (VariableList *)GetAllocatedSpace (sizeof (VariableList)))
1458
    if ((vp = (VariableList *)GetAllocatedSpace (sizeof (VariableList)))
1459
		== (VariableList *)NULL)
1459
                == (VariableList *)NULL)
1460
	return &dummy;
1460
        return &dummy;
1461
 
1461
 
1462
    if ((vp->name = StringCopy (name)) == null)
1462
    if ((vp->name = StringCopy (name)) == null)
1463
    {
1463
    {
1464
	ReleaseMemoryCell ((void *)vp);
1464
        ReleaseMemoryCell ((void *)vp);
1465
	return &dummy;
1465
        return &dummy;
1466
    }
1466
    }
1467
 
1467
 
1468
/* Set values */
1468
/* Set values */
1469
 
1469
 
1470
    vp->value = null;
1470
    vp->value = null;
Line 1477... Line 1477...
1477
 
1477
 
1478
/* Add to the tree */
1478
/* Add to the tree */
1479
 
1479
 
1480
    if (tsearch (vp, &VariableTree, SearchVariable) == (void *)NULL)
1480
    if (tsearch (vp, &VariableTree, SearchVariable) == (void *)NULL)
1481
    {
1481
    {
1482
	ReleaseMemoryCell ((void *)vp->name);
1482
        ReleaseMemoryCell ((void *)vp->name);
1483
	ReleaseMemoryCell ((void *)vp);
1483
        ReleaseMemoryCell ((void *)vp);
1484
        vp = &dummy;
1484
        vp = &dummy;
1485
    }
1485
    }
1486
 
1486
 
1487
/* OK Added OK - set up memory */
1487
/* OK Added OK - set up memory */
1488
 
1488
 
1489
    else
1489
    else
1490
    {
1490
    {
1491
	SetMemoryAreaNumber ((void *)vp, 0);
1491
        SetMemoryAreaNumber ((void *)vp, 0);
1492
	SetMemoryAreaNumber ((void *)vp->name, 0);
1492
        SetMemoryAreaNumber ((void *)vp->name, 0);
1493
    }
1493
    }
1494
 
1494
 
1495
/* Restore signals */
1495
/* Restore signals */
1496
 
1496
 
1497
    signal (SIGINT, save_signal);
1497
    signal (SIGINT, save_signal);
Line 1504... Line 1504...
1504
 */
1504
 */
1505
 
1505
 
1506
int     CountVariableArraySize (char *name)
1506
int     CountVariableArraySize (char *name)
1507
{
1507
{
1508
    if (isdigit (*name))
1508
    if (isdigit (*name))
1509
	return ParameterCount;
1509
        return ParameterCount;
1510
 
1510
 
1511
    Count_Array = 0;
1511
    Count_Array = 0;
1512
    Count_Name = name;
1512
    Count_Name = name;
1513
    twalk (VariableTree, CountEnvironment);
1513
    twalk (VariableTree, CountEnvironment);
1514
    return Count_Array;
1514
    return Count_Array;
Line 1522... Line 1522...
1522
{
1522
{
1523
    (void) level;
1523
    (void) level;
1524
 
1524
 
1525
    if (((visit == postorder) || (visit == leaf)) &&
1525
    if (((visit == postorder) || (visit == leaf)) &&
1526
       (strcmp (Count_Name, (*(VariableList **)key)->name) == 0))
1526
       (strcmp (Count_Name, (*(VariableList **)key)->name) == 0))
1527
	Count_Array++;
1527
        Count_Array++;
1528
}
1528
}
1529
 
1529
 
1530
/*
1530
/*
1531
 * TFIND & TSEARCH - Search the VARIABLE TREE for an entry
1531
 * TFIND & TSEARCH - Search the VARIABLE TREE for an entry
1532
 */
1532
 */
1533
 
1533
 
1534
int	SearchVariable (const void *key1, const void *key2)
1534
int     SearchVariable (const void *key1, const void *key2)
1535
{
1535
{
1536
    int			diff;
1536
    int                 diff;
1537
 
1537
 
1538
    if ((diff = strcmp (((VariableList *)key1)->name,
1538
    if ((diff = strcmp (((VariableList *)key1)->name,
1539
			((VariableList *)key2)->name)) != 0)
1539
                        ((VariableList *)key2)->name)) != 0)
1540
	return diff;
1540
        return diff;
1541
 
1541
 
1542
    return ((VariableList *)key1)->index - ((VariableList *)key2)->index;
1542
    return ((VariableList *)key1)->index - ((VariableList *)key2)->index;
1543
}
1543
}
1544
 
1544
 
1545
/*
1545
/*
Line 1550... Line 1550...
1550
 */
1550
 */
1551
 
1551
 
1552
bool    AssignVariableFromString (char *String, /* assignment string       */
1552
bool    AssignVariableFromString (char *String, /* assignment string       */
1553
                                  int  *Index)  /* Index value returned    */
1553
                                  int  *Index)  /* Index value returned    */
1554
{
1554
{
1555
    char	*cp;
1555
    char        *cp;
1556
    long	value = 0;
1556
    long        value = 0;
1557
 
1557
 
1558
/* Ignore if not valid environment variable - check alpha and equals */
1558
/* Ignore if not valid environment variable - check alpha and equals */
1559
 
1559
 
1560
    if (!GetVariableName (String, &value, &cp, (bool*)NULL) ||
1560
    if (!GetVariableName (String, &value, &cp, (bool*)NULL) ||
1561
	(*cp != CHAR_ASSIGN))
1561
        (*cp != CHAR_ASSIGN))
1562
    {
1562
    {
1563
	if (value == -1)
1563
        if (value == -1)
1564
	    PrintErrorMessage (LIT_BadArray, String);
1564
            PrintErrorMessage (LIT_BadArray, String);
1565
 
1565
 
1566
	return FALSE;
1566
        return FALSE;
1567
    }
1567
    }
1568
 
1568
 
1569
/* Change the = to a end of string */
1569
/* Change the = to a end of string */
1570
 
1570
 
1571
    *(cp++) = 0;
1571
    *(cp++) = 0;
Line 1575... Line 1575...
1575
    SetVariableArrayFromString (String, (int)value, cp);
1575
    SetVariableArrayFromString (String, (int)value, cp);
1576
 
1576
 
1577
/* Return the index */
1577
/* Return the index */
1578
 
1578
 
1579
    if (Index != (int *)NULL)
1579
    if (Index != (int *)NULL)
1580
	*Index = (int)value;
1580
        *Index = (int)value;
1581
 
1581
 
1582
    return TRUE;
1582
    return TRUE;
1583
}
1583
}
1584
 
1584
 
1585
/*
1585
/*
Line 1587... Line 1587...
1587
 *
1587
 *
1588
 * String either ends in a null or assignment
1588
 * String either ends in a null or assignment
1589
 */
1589
 */
1590
 
1590
 
1591
bool    GetVariableName (char *String,  /* The original string          */
1591
bool    GetVariableName (char *String,  /* The original string          */
1592
			 long *Index,	/* Array index value found	*/
1592
                         long *Index,   /* Array index value found      */
1593
			 char **Value,	/* Pointer to the value		*/
1593
                         char **Value,  /* Pointer to the value         */
1594
			 bool *Array)	/* Array detected flag		*/
1594
                         bool *Array)   /* Array detected flag          */
1595
{
1595
{
1596
    char        *cp, *sp;
1596
    char        *cp, *sp;
1597
    char	EndName;
1597
    char        EndName;
1598
 
1598
 
1599
    *Index = 0;
1599
    *Index = 0;
1600
 
1600
 
1601
/* Ignore if not valid environment variable - check alpha and equals */
1601
/* Ignore if not valid environment variable - check alpha and equals */
1602
 
1602
 
1603
    if (((EndName = IsValidVariableName (String)) != CHAR_ASSIGN) &&
1603
    if (((EndName = IsValidVariableName (String)) != CHAR_ASSIGN) &&
1604
	(EndName != CHAR_OPEN_BRACKETS) && EndName)
1604
        (EndName != CHAR_OPEN_BRACKETS) && EndName)
1605
	return FALSE;
1605
        return FALSE;
1606
 
1606
 
1607
    if ((cp = strchr (String, CHAR_ASSIGN)) == (char *)NULL)
1607
    if ((cp = strchr (String, CHAR_ASSIGN)) == (char *)NULL)
1608
	cp = &String[strlen (String)];
1608
        cp = &String[strlen (String)];
1609
 
1609
 
1610
    if (Array != (bool *)NULL)
1610
    if (Array != (bool *)NULL)
1611
	*Array = C2bool (EndName == CHAR_OPEN_BRACKETS);
1611
        *Array = C2bool (EndName == CHAR_OPEN_BRACKETS);
1612
 
1612
 
1613
/* Check for valid array */
1613
/* Check for valid array */
1614
 
1614
 
1615
    if (EndName == CHAR_OPEN_BRACKETS)
1615
    if (EndName == CHAR_OPEN_BRACKETS)
1616
    {
1616
    {
1617
	if ((Index == (long *)NULL) || (*(cp - 1) != CHAR_CLOSE_BRACKETS))
1617
        if ((Index == (long *)NULL) || (*(cp - 1) != CHAR_CLOSE_BRACKETS))
1618
	    return FALSE;
1618
            return FALSE;
1619
 
1619
 
1620
/* Terminate the name and remove the trailing bracket */
1620
/* Terminate the name and remove the trailing bracket */
1621
 
1621
 
1622
	*(sp = strchr (String, CHAR_OPEN_BRACKETS)) = 0;
1622
        *(sp = strchr (String, CHAR_OPEN_BRACKETS)) = 0;
1623
	*(cp - 1) = 0;
1623
        *(cp - 1) = 0;
1624
 
1624
 
1625
	if ((!ConvertNumericValue (sp + 1, Index, 10)) ||
1625
        if ((!ConvertNumericValue (sp + 1, Index, 10)) ||
1626
	    (*Index < 0) || (*Index > INT_MAX))
1626
            (*Index < 0) || (*Index > INT_MAX))
1627
	{
1627
        {
1628
	    *Index = -1;
1628
            *Index = -1;
1629
	    return FALSE;
1629
            return FALSE;
1630
	}
1630
        }
1631
    }
1631
    }
1632
 
1632
 
1633
/* Return pointer to null or assignment */
1633
/* Return pointer to null or assignment */
1634
 
1634
 
1635
    *Value = cp;
1635
    *Value = cp;
Line 1642... Line 1642...
1642
 * Create a new Var_list environment for a Sub Shell
1642
 * Create a new Var_list environment for a Sub Shell
1643
 */
1643
 */
1644
 
1644
 
1645
int CreateGlobalVariableList (unsigned int Function)
1645
int CreateGlobalVariableList (unsigned int Function)
1646
{
1646
{
1647
    int			i;
1647
    int                 i;
1648
    S_SubShell		*sp;
1648
    S_SubShell          *sp;
1649
 
1649
 
1650
    for (sp = SubShells, i = 0; (i < NSubShells) &&
1650
    for (sp = SubShells, i = 0; (i < NSubShells) &&
1651
			       (SubShells[i].depth < Execute_stack_depth);
1651
                               (SubShells[i].depth < Execute_stack_depth);
1652
	 i++);
1652
         i++);
1653
 
1653
 
1654
/* If depth is greater or equal to the Execute_stack_depth - we should panic
1654
/* If depth is greater or equal to the Execute_stack_depth - we should panic
1655
 * as this should not happen.  However, for the moment, I'll ignore it
1655
 * as this should not happen.  However, for the moment, I'll ignore it
1656
 */
1656
 */
1657
 
1657
 
1658
    if (NSubShells == MSubShells)
1658
    if (NSubShells == MSubShells)
1659
    {
1659
    {
1660
	sp = (S_SubShell *)ReAllocateSpace ((MSubShells == 0) ? (void *)NULL
1660
        sp = (S_SubShell *)ReAllocateSpace ((MSubShells == 0) ? (void *)NULL
1661
							      : SubShells,
1661
                                                              : SubShells,
1662
					    (MSubShells + SSAVE_IO_SIZE) *
1662
                                            (MSubShells + SSAVE_IO_SIZE) *
1663
						sizeof (S_SubShell));
1663
                                                sizeof (S_SubShell));
1664
/* Check for error */
1664
/* Check for error */
1665
 
1665
 
1666
	if (sp == (S_SubShell *)NULL)
1666
        if (sp == (S_SubShell *)NULL)
1667
	    return -1;
1667
            return -1;
1668
 
1668
 
1669
	SetMemoryAreaNumber ((void *)sp, 0);
1669
        SetMemoryAreaNumber ((void *)sp, 0);
1670
	SubShells = sp;
1670
        SubShells = sp;
1671
	MSubShells += SSAVE_IO_SIZE;
1671
        MSubShells += SSAVE_IO_SIZE;
1672
    }
1672
    }
1673
 
1673
 
1674
/* Save the depth and the old Variable Tree value */
1674
/* Save the depth and the old Variable Tree value */
1675
 
1675
 
1676
    sp = &SubShells[NSubShells++];
1676
    sp = &SubShells[NSubShells++];
Line 1695... Line 1695...
1695
 * TWALK - add to new environment
1695
 * TWALK - add to new environment
1696
 */
1696
 */
1697
 
1697
 
1698
static void AddToNewEnvironment (const void *key, VISIT visit, int level)
1698
static void AddToNewEnvironment (const void *key, VISIT visit, int level)
1699
{
1699
{
1700
    VariableList	*vp = *(VariableList **)key;
1700
    VariableList        *vp = *(VariableList **)key;
1701
    VariableList	*vp1;
1701
    VariableList        *vp1;
1702
 
1702
 
1703
    (void) level;
1703
    (void) level;
1704
 
1704
 
1705
    if ((visit == postorder) || (visit == leaf))
1705
    if ((visit == postorder) || (visit == leaf))
1706
    {
1706
    {
1707
 
1707
 
1708
/* For functions, do not copy the traps */
1708
/* For functions, do not copy the traps */
1709
 
1709
 
1710
	if (ATNE_Function && (*vp->name == CHAR_TILDE) && vp->name[1])
1710
        if (ATNE_Function && (*vp->name == CHAR_TILDE) && vp->name[1])
1711
	    return;
1711
            return;
1712
 
1712
 
1713
/* Create a new entry */
1713
/* Create a new entry */
1714
 
1714
 
1715
	vp1 = LookUpVariable (vp->name, vp->index, TRUE);
1715
        vp1 = LookUpVariable (vp->name, vp->index, TRUE);
1716
 
1716
 
1717
	if ((!(vp->status & STATUS_INTEGER)) && (vp->value != null))
1717
        if ((!(vp->status & STATUS_INTEGER)) && (vp->value != null))
1718
	    vp1->value = StringSave (vp->value);
1718
            vp1->value = StringSave (vp->value);
1719
 
1719
 
1720
/* Copy some flags */
1720
/* Copy some flags */
1721
 
1721
 
1722
	vp1->status = vp->status;
1722
        vp1->status = vp->status;
1723
	vp1->nvalue = vp->nvalue;
1723
        vp1->nvalue = vp->nvalue;
1724
	vp1->base = vp->base;
1724
        vp1->base = vp->base;
1725
	vp1->width = vp->width;
1725
        vp1->width = vp->width;
1726
    }
1726
    }
1727
}
1727
}
1728
 
1728
 
1729
/*
1729
/*
1730
 * Delete a SubShell environment and restore the original
1730
 * Delete a SubShell environment and restore the original
1731
 */
1731
 */
1732
 
1732
 
1733
void DeleteGlobalVariableList (void)
1733
void DeleteGlobalVariableList (void)
1734
{
1734
{
1735
    int			j;
1735
    int                 j;
1736
    S_SubShell		*sp;
1736
    S_SubShell          *sp;
1737
    VariableList	*vp;
1737
    VariableList        *vp;
1738
    void                (_SIGDECL *save_signal)(int);
1738
    void                (_SIGDECL *save_signal)(int);
1739
 
1739
 
1740
    for (j = NSubShells; j > 0; j--)
1740
    for (j = NSubShells; j > 0; j--)
1741
    {
1741
    {
1742
       sp = &SubShells[j - 1];
1742
       sp = &SubShells[j - 1];
1743
 
1743
 
1744
       if (sp->depth < Execute_stack_depth)
1744
       if (sp->depth < Execute_stack_depth)
1745
	   break;
1745
           break;
1746
 
1746
 
1747
/* Reduce number of entries */
1747
/* Reduce number of entries */
1748
 
1748
 
1749
	--NSubShells;
1749
        --NSubShells;
1750
 
1750
 
1751
/* Disable signals */
1751
/* Disable signals */
1752
 
1752
 
1753
	save_signal = signal (SIGINT, SIG_IGN);
1753
        save_signal = signal (SIGINT, SIG_IGN);
1754
 
1754
 
1755
/* Restore the previous level information */
1755
/* Restore the previous level information */
1756
 
1756
 
1757
	vp = VariableTree;
1757
        vp = VariableTree;
1758
	VariableTree = sp->OldVariableTree;
1758
        VariableTree = sp->OldVariableTree;
1759
	ShellGlobalFlags = (unsigned int)(sp->GFlags & ~FLAGS_FUNCTION);
1759
        ShellGlobalFlags = (unsigned int)(sp->GFlags & ~FLAGS_FUNCTION);
1760
	flags = sp->Eflags;
1760
        flags = sp->Eflags;
1761
 
1761
 
1762
/* Release the space */
1762
/* Release the space */
1763
 
1763
 
1764
	ATOE_GFlags = sp->GFlags;
1764
        ATOE_GFlags = sp->GFlags;
1765
 
1765
 
1766
	twalk (vp, AddToOldEnvironment);
1766
        twalk (vp, AddToOldEnvironment);
1767
	twalk (vp, DeleteEnvironment);
1767
        twalk (vp, DeleteEnvironment);
1768
 
1768
 
1769
/* Restore signals */
1769
/* Restore signals */
1770
 
1770
 
1771
	signal (SIGINT, save_signal);
1771
        signal (SIGINT, save_signal);
1772
 
1772
 
1773
	LoadGlobalVariableList ();
1773
        LoadGlobalVariableList ();
1774
    }
1774
    }
1775
}
1775
}
1776
 
1776
 
1777
/*
1777
/*
1778
 * TWALK - delete old environment tree
1778
 * TWALK - delete old environment tree
1779
 */
1779
 */
1780
 
1780
 
1781
static void DeleteEnvironment (const void *key, VISIT visit, int level)
1781
static void DeleteEnvironment (const void *key, VISIT visit, int level)
1782
{
1782
{
1783
    VariableList	*vp = *(VariableList **)key;
1783
    VariableList        *vp = *(VariableList **)key;
1784
 
1784
 
1785
    (void) level;
1785
    (void) level;
1786
 
1786
 
1787
    if ((visit == endorder) || (visit == leaf))
1787
    if ((visit == endorder) || (visit == leaf))
1788
    {
1788
    {
Line 1798... Line 1798...
1798
 * TWALK - Transfer Current Environment to the Old one
1798
 * TWALK - Transfer Current Environment to the Old one
1799
 */
1799
 */
1800
 
1800
 
1801
static void AddToOldEnvironment (const void *key, VISIT visit, int level)
1801
static void AddToOldEnvironment (const void *key, VISIT visit, int level)
1802
{
1802
{
1803
    VariableList	*vp = *(VariableList **)key;
1803
    VariableList        *vp = *(VariableList **)key;
1804
    VariableList	*vp1;
1804
    VariableList        *vp1;
1805
 
1805
 
1806
    (void) level;
1806
    (void) level;
1807
 
1807
 
1808
    if ((visit == postorder) || (visit == leaf))
1808
    if ((visit == postorder) || (visit == leaf))
1809
    {
1809
    {
1810
 
1810
 
1811
/* Skip local variables and traps */
1811
/* Skip local variables and traps */
1812
 
1812
 
1813
	if ((ATOE_GFlags & FLAGS_FUNCTION) && (!(vp->status & STATUS_LOCAL)) &&
1813
        if ((ATOE_GFlags & FLAGS_FUNCTION) && (!(vp->status & STATUS_LOCAL)) &&
1814
	    (((*vp->name != CHAR_TILDE) || !vp->name[1])))
1814
            (((*vp->name != CHAR_TILDE) || !vp->name[1])))
1815
	{
1815
        {
1816
 
1816
 
1817
/* Get the entry in the old variable list and update it with the new
1817
/* Get the entry in the old variable list and update it with the new
1818
 * parameters
1818
 * parameters
1819
 */
1819
 */
1820
	    vp1 = LookUpVariable (vp->name, vp->index, TRUE);
1820
            vp1 = LookUpVariable (vp->name, vp->index, TRUE);
1821
 
1821
 
1822
	    if (vp1->value != null)
1822
            if (vp1->value != null)
1823
		ReleaseMemoryCell ((void *)vp1->value);
1823
                ReleaseMemoryCell ((void *)vp1->value);
1824
 
1824
 
1825
	    vp1->value = vp->value;
1825
            vp1->value = vp->value;
1826
	    vp->value = null;		/* Stop releaseing this as its tx */
1826
            vp->value = null;           /* Stop releaseing this as its tx */
1827
 
1827
 
1828
	    vp1->status = vp->status;
1828
            vp1->status = vp->status;
1829
	    vp1->nvalue = vp->nvalue;
1829
            vp1->nvalue = vp->nvalue;
1830
	    vp1->base   = vp->base;
1830
            vp1->base   = vp->base;
1831
	    vp1->width  = vp->width;
1831
            vp1->width  = vp->width;
1832
	}
1832
        }
1833
    }
1833
    }
1834
}
1834
}
1835
 
1835
 
1836
/*
1836
/*
1837
 * Load GLobal Var List values
1837
 * Load GLobal Var List values
1838
 */
1838
 */
1839
 
1839
 
1840
static void F_LOCAL LoadGlobalVariableList (void)
1840
static void F_LOCAL LoadGlobalVariableList (void)
1841
{
1841
{
1842
    VariableList	*cifs = LookUpVariable (IFS, 0, TRUE);
1842
    VariableList        *cifs = LookUpVariable (IFS, 0, TRUE);
1843
 
1843
 
1844
    CurrentDirectory = LookUpVariable (tilde, 0, TRUE);
1844
    CurrentDirectory = LookUpVariable (tilde, 0, TRUE);
1845
    RestoreCurrentDirectory (CurrentDirectory->value);
1845
    RestoreCurrentDirectory (CurrentDirectory->value);
1846
    SetCharacterTypes (cifs->value, C_IFS);
1846
    SetCharacterTypes (cifs->value, C_IFS);
1847
}
1847
}
Line 1854... Line 1854...
1854
 * mode - mode for match processing - see GM_ flags in sh.h
1854
 * mode - mode for match processing - see GM_ flags in sh.h
1855
 *
1855
 *
1856
 * pattern character are prefixed with MAGIC by expand.
1856
 * pattern character are prefixed with MAGIC by expand.
1857
 */
1857
 */
1858
 
1858
 
1859
bool GeneralPatternMatch (char		*string,	/* String	*/
1859
bool GeneralPatternMatch (char          *string,        /* String       */
1860
			  unsigned char *pattern,	/* Pattern	*/
1860
                          unsigned char *pattern,       /* Pattern      */
1861
			  bool		IgnoreCase,	/* Ignorecase	*/
1861
                          bool          IgnoreCase,     /* Ignorecase   */
1862
			  char		**end,		/* End of match	*/
1862
                          char          **end,          /* End of match */
1863
			  int		mode)		/* Mode		*/
1863
                          int           mode)           /* Mode         */
1864
{
1864
{
1865
    int		string_c, pattern_c;
1865
    int         string_c, pattern_c;
1866
    char	*save_end;
1866
    char        *save_end;
1867
 
1867
 
1868
    if ((string == (char *)NULL) || (pattern == (unsigned char *)NULL))
1868
    if ((string == (char *)NULL) || (pattern == (unsigned char *)NULL))
1869
	return FALSE;
1869
        return FALSE;
1870
 
1870
 
1871
    while ((pattern_c = *(pattern++)) != 0)
1871
    while ((pattern_c = *(pattern++)) != 0)
1872
    {
1872
    {
1873
	string_c = *(string++);
1873
        string_c = *(string++);
1874
 
1874
 
1875
	if (pattern_c != CHAR_MAGIC)
1875
        if (pattern_c != CHAR_MAGIC)
1876
	{
1876
        {
1877
	    if (IgnoreCase)
1877
            if (IgnoreCase)
1878
	    {
1878
            {
1879
		string_c = tolower (string_c);
1879
                string_c = tolower (string_c);
1880
		pattern_c = tolower (pattern_c);
1880
                pattern_c = tolower (pattern_c);
1881
	    }
1881
            }
1882
 
1882
 
1883
	    if (string_c != pattern_c)
1883
            if (string_c != pattern_c)
1884
		return FALSE;
1884
                return FALSE;
1885
 
1885
 
1886
	    continue;
1886
            continue;
1887
	}
1887
        }
1888
 
1888
 
1889
/* Magic characters */
1889
/* Magic characters */
1890
 
1890
 
1891
	switch (*(pattern++))
1891
        switch (*(pattern++))
1892
	{
1892
        {
1893
	    case CHAR_OPEN_BRACKETS:	/* Class expression		*/
1893
            case CHAR_OPEN_BRACKETS:    /* Class expression             */
1894
		if ((!string_c) ||
1894
                if ((!string_c) ||
1895
		    ((pattern = CheckClassExpression (pattern, string_c,
1895
                    ((pattern = CheckClassExpression (pattern, string_c,
1896
						     IgnoreCase)) ==
1896
                                                     IgnoreCase)) ==
1897
				(unsigned char *)NULL))
1897
                                (unsigned char *)NULL))
1898
		    return FALSE;
1898
                    return FALSE;
1899
 
1899
 
1900
		break;
1900
                break;
1901
 
1901
 
1902
	    case CHAR_MATCH_ANY:	/* Match any character		*/
1902
            case CHAR_MATCH_ANY:        /* Match any character          */
1903
		if (string_c == 0)
1903
                if (string_c == 0)
1904
		    return FALSE;
1904
                    return FALSE;
1905
 
1905
 
1906
		break;
1906
                break;
1907
 
1907
 
1908
	    case CHAR_MATCH_ALL:	/* Match as many as possible	*/
1908
            case CHAR_MATCH_ALL:        /* Match as many as possible    */
1909
		--string;
1909
                --string;
1910
		save_end = (char *)NULL;
1910
                save_end = (char *)NULL;
1911
 
1911
 
1912
		do
1912
                do
1913
		{
1913
                {
1914
		    if (!*pattern ||
1914
                    if (!*pattern ||
1915
			GeneralPatternMatch (string, pattern, IgnoreCase, end,
1915
                        GeneralPatternMatch (string, pattern, IgnoreCase, end,
1916
					     mode))
1916
                                             mode))
1917
		    {
1917
                    {
1918
			if (mode == GM_LONGEST)
1918
                        if (mode == GM_LONGEST)
1919
			    save_end = *end;
1919
                            save_end = *end;
1920
 
1920
 
1921
			else
1921
                        else
1922
			    return TRUE;
1922
                            return TRUE;
1923
		    }
1923
                    }
1924
 
1924
 
1925
		} while (*(string++));
1925
                } while (*(string++));
1926
 
1926
 
1927
		if (end != (char **)NULL)
1927
                if (end != (char **)NULL)
1928
		    *end = save_end;
1928
                    *end = save_end;
1929
 
1929
 
1930
		return C2bool (save_end != (char *)NULL);
1930
                return C2bool (save_end != (char *)NULL);
1931
 
-
 
1932
	    default:		/* Match				*/
-
 
1933
		if ((unsigned)string_c != pattern[-1])
-
 
1934
		    return FALSE;
-
 
1935
 
1931
 
-
 
1932
            default:            /* Match                                */
-
 
1933
                if ((unsigned)string_c != pattern[-1])
1936
		break;
1934
                    return FALSE;
1937
	}
1935
 
-
 
1936
                break;
-
 
1937
        }
1938
    }
1938
    }
1939
 
1939
 
1940
    if (end != (char **)NULL)
1940
    if (end != (char **)NULL)
1941
    {
1941
    {
1942
	*end = string;
1942
        *end = string;
1943
	return TRUE;
1943
        return TRUE;
1944
    }
1944
    }
1945
 
1945
 
1946
    return C2bool (*string == 0);
1946
    return C2bool (*string == 0);
1947
}
1947
}
1948
 
1948
 
1949
/*
1949
/*
1950
 * Process a class expression - []
1950
 * Process a class expression - []
1951
 */
1951
 */
1952
 
1952
 
1953
static unsigned char * F_LOCAL CheckClassExpression (
1953
static unsigned char * F_LOCAL CheckClassExpression (
1954
				unsigned char	*pattern,
1954
                                unsigned char   *pattern,
1955
				int		string_c, /* Match char*/
1955
                                int             string_c, /* Match char*/
1956
				bool		IgnoreCase)/* Ic flag	*/
1956
                                bool            IgnoreCase)/* Ic flag   */
1957
{
1957
{
1958
    int		llimit_c, ulimit_c;
1958
    int         llimit_c, ulimit_c;
1959
    bool	not = FALSE;
1959
    bool        not = FALSE;
1960
    bool	found;
1960
    bool        found;
1961
 
1961
 
1962
/* Exclusive or inclusive class */
1962
/* Exclusive or inclusive class */
1963
 
1963
 
1964
    if ((*pattern == CHAR_MAGIC) &&
1964
    if ((*pattern == CHAR_MAGIC) &&
1965
	((*(pattern + 1) == CHAR_NOT) || (*(pattern + 1) == '!')))
1965
        ((*(pattern + 1) == CHAR_NOT) || (*(pattern + 1) == '!')))
1966
    {
1966
    {
1967
	pattern += 2;
1967
        pattern += 2;
1968
	not = TRUE;
1968
        not = TRUE;
1969
    }
1969
    }
1970
 
1970
 
1971
    found = not;
1971
    found = not;
1972
 
1972
 
1973
/* Process the pattern */
1973
/* Process the pattern */
1974
 
1974
 
1975
    do
1975
    do
1976
    {
1976
    {
1977
	if (*pattern == CHAR_MAGIC)
1977
        if (*pattern == CHAR_MAGIC)
1978
	    pattern++;
1978
            pattern++;
1979
 
1979
 
1980
	if (!*pattern)
1980
        if (!*pattern)
1981
	    return (unsigned char *)NULL;
1981
            return (unsigned char *)NULL;
1982
 
1982
 
1983
/* Get the next character in class, converting to lower case if necessary */
1983
/* Get the next character in class, converting to lower case if necessary */
1984
 
1984
 
1985
	llimit_c = IgnoreCase ? tolower (*pattern) : *pattern;
1985
        llimit_c = IgnoreCase ? tolower (*pattern) : *pattern;
1986
 
1986
 
1987
/* If this is a range, get the end of range character */
1987
/* If this is a range, get the end of range character */
1988
 
1988
 
1989
	if ((*(pattern + 1) == CHAR_MATCH_RANGE) &&
1989
        if ((*(pattern + 1) == CHAR_MATCH_RANGE) &&
1990
	    (*(pattern + 2) != CHAR_CLOSE_BRACKETS))
1990
            (*(pattern + 2) != CHAR_CLOSE_BRACKETS))
1991
	{
1991
        {
1992
	    ulimit_c = IgnoreCase ? tolower (*(pattern + 2)) : *(pattern + 2);
1992
            ulimit_c = IgnoreCase ? tolower (*(pattern + 2)) : *(pattern + 2);
1993
	    pattern++;
1993
            pattern++;
1994
	}
1994
        }
1995
 
1995
 
1996
	else
1996
        else
1997
	    ulimit_c = llimit_c;
1997
            ulimit_c = llimit_c;
1998
 
1998
 
1999
/* Is the current character in the class? */
1999
/* Is the current character in the class? */
2000
 
2000
 
2001
	if ((llimit_c <= string_c) && (string_c <= ulimit_c))
2001
        if ((llimit_c <= string_c) && (string_c <= ulimit_c))
2002
	    found = C2bool (!not);
2002
            found = C2bool (!not);
2003
 
2003
 
2004
    } while (*(++pattern) != CHAR_CLOSE_BRACKETS);
2004
    } while (*(++pattern) != CHAR_CLOSE_BRACKETS);
2005
 
2005
 
2006
    return found ? pattern + 1 : (unsigned char *)NULL;
2006
    return found ? pattern + 1 : (unsigned char *)NULL;
2007
}
2007
}
2008
 
2008
 
2009
/*
2009
/*
2010
 * Suffix processing - find the longest/shortest suffix.
2010
 * Suffix processing - find the longest/shortest suffix.
2011
 */
2011
 */
2012
 
2012
 
2013
bool SuffixPatternMatch (char *string,	/* String to match		*/
2013
bool SuffixPatternMatch (char *string,  /* String to match              */
2014
			 char *pattern, /* Pattern to match against	*/
2014
                         char *pattern, /* Pattern to match against     */
2015
			 char **start,	/* Start position		*/
2015
                         char **start,  /* Start position               */
2016
			 int  mode)	/* Match mode			*/
2016
                         int  mode)     /* Match mode                   */
2017
{
2017
{
2018
    char	*save_start = (char *)NULL;
2018
    char        *save_start = (char *)NULL;
2019
 
2019
 
2020
/* Scan the string, looking for a match to the end */
2020
/* Scan the string, looking for a match to the end */
2021
 
2021
 
2022
    while (*string)
2022
    while (*string)
2023
    {
2023
    {
2024
	if (GeneralPatternMatch (string, (unsigned char *)pattern, FALSE,
2024
        if (GeneralPatternMatch (string, (unsigned char *)pattern, FALSE,
2025
				 (char **)NULL, GM_ALL))
2025
                                 (char **)NULL, GM_ALL))
2026
	{
2026
        {
2027
 
2027
 
2028
/* If longest, stop here */
2028
/* If longest, stop here */
2029
 
2029
 
2030
	    if (mode == GM_LONGEST)
2030
            if (mode == GM_LONGEST)
2031
	    {
2031
            {
2032
		*start = string;
2032
                *start = string;
2033
		return TRUE;
2033
                return TRUE;
2034
	    }
2034
            }
2035
 
2035
 
2036
/* Save the start of the shortest string so far and continue */
2036
/* Save the start of the shortest string so far and continue */
2037
 
2037
 
2038
	    save_start = string;
2038
            save_start = string;
2039
	}
2039
        }
2040
 
2040
 
2041
	++string;
2041
        ++string;
2042
    }
2042
    }
2043
 
2043
 
2044
    return C2bool ((*start = save_start) != (char *)NULL);
2044
    return C2bool ((*start = save_start) != (char *)NULL);
2045
}
2045
}
2046
 
2046
 
Line 2048... Line 2048...
2048
 * Get a string in a malloced area
2048
 * Get a string in a malloced area
2049
 */
2049
 */
2050
 
2050
 
2051
char *AllocateMemoryCell (size_t nbytes)
2051
char *AllocateMemoryCell (size_t nbytes)
2052
{
2052
{
2053
    s_region		*np;
2053
    s_region            *np;
2054
    void                (_SIGDECL *save_signal)(int);
2054
    void                (_SIGDECL *save_signal)(int);
2055
#ifdef OS2_DOSALLOC
2055
#ifdef OS2_DOSALLOC
2056
    SEL			sel;
2056
    SEL                 sel;
2057
#endif
2057
#endif
2058
 
2058
 
2059
    if (nbytes == 0)
2059
    if (nbytes == 0)
2060
	abort ();	/* silly and defeats the algorithm */
2060
        abort ();       /* silly and defeats the algorithm */
2061
 
2061
 
2062
/* Grab some space */
2062
/* Grab some space */
2063
 
2063
 
2064
#ifdef OS2_DOSALLOC
2064
#ifdef OS2_DOSALLOC
2065
    if (DosAllocSeg (nbytes + sizeof (s_region), &sel, SEG_NONSHARED))
2065
    if (DosAllocSeg (nbytes + sizeof (s_region), &sel, SEG_NONSHARED))
2066
    {
2066
    {
2067
	errno = ENOMEM;
2067
        errno = ENOMEM;
2068
	return (char *)NULL;
2068
        return (char *)NULL;
2069
    }
2069
    }
2070
 
2070
 
2071
    np = (s_region *)MAKEP (sel, 0);
2071
    np = (s_region *)MAKEP (sel, 0);
2072
    memset (np, 0, nbytes + sizeof (s_region));
2072
    memset (np, 0, nbytes + sizeof (s_region));
2073
 
2073
 
2074
#else
2074
#else
2075
    if ((np = (s_region *)calloc (nbytes + sizeof (s_region), 1))
2075
    if ((np = (s_region *)calloc (nbytes + sizeof (s_region), 1))
2076
		== (s_region *)NULL)
2076
                == (s_region *)NULL)
2077
    {
2077
    {
2078
	errno = ENOMEM;
2078
        errno = ENOMEM;
2079
        return (char *)NULL;
2079
        return (char *)NULL;
2080
    }
2080
    }
2081
#endif
2081
#endif
2082
 
2082
 
2083
/* Disable signals */
2083
/* Disable signals */
Line 2101... Line 2101...
2101
 
2101
 
2102
/*
2102
/*
2103
 * Release a array of strings
2103
 * Release a array of strings
2104
 */
2104
 */
2105
 
2105
 
2106
void	ReleaseAList (char **list)
2106
void    ReleaseAList (char **list)
2107
{
2107
{
2108
    char	**ap = list;
2108
    char        **ap = list;
2109
 
2109
 
2110
    while (*ap != (char *)NULL)
2110
    while (*ap != (char *)NULL)
2111
	ReleaseMemoryCell (*(ap++));
2111
        ReleaseMemoryCell (*(ap++));
2112
 
2112
 
2113
    ReleaseMemoryCell (list);
2113
    ReleaseMemoryCell (list);
2114
 
2114
 
2115
}
2115
}
2116
 
2116
 
Line 2118... Line 2118...
2118
 * Free a string in a malloced area
2118
 * Free a string in a malloced area
2119
 */
2119
 */
2120
 
2120
 
2121
void ReleaseMemoryCell (void *s)
2121
void ReleaseMemoryCell (void *s)
2122
{
2122
{
2123
    s_region		*cp = MemoryAreaHeader;
2123
    s_region            *cp = MemoryAreaHeader;
2124
    s_region		*lp = (s_region *)NULL;
2124
    s_region            *lp = (s_region *)NULL;
2125
    s_region		*sp = (s_region *)((char *)s - sizeof (s_region));
2125
    s_region            *sp = (s_region *)((char *)s - sizeof (s_region));
2126
    void                (_SIGDECL *save_signal)(int);
2126
    void                (_SIGDECL *save_signal)(int);
2127
 
2127
 
2128
/* Disable signals */
2128
/* Disable signals */
2129
 
2129
 
2130
    save_signal = signal (SIGINT, SIG_IGN);
2130
    save_signal = signal (SIGINT, SIG_IGN);
2131
 
2131
 
2132
/* Find the string in the chain */
2132
/* Find the string in the chain */
2133
 
2133
 
2134
    if (s != (char *)NULL)
2134
    if (s != (char *)NULL)
2135
    {
2135
    {
2136
	while (cp != (s_region *)NULL)
2136
        while (cp != (s_region *)NULL)
2137
	{
2137
        {
2138
	    if (cp != sp)
2138
            if (cp != sp)
2139
	    {
2139
            {
2140
		lp = cp;
2140
                lp = cp;
2141
		cp = cp->next;
2141
                cp = cp->next;
2142
		continue;
2142
                continue;
2143
	    }
2143
            }
2144
 
2144
 
2145
/* First in chain ? */
2145
/* First in chain ? */
2146
 
2146
 
2147
	    else if (lp == (s_region *)NULL)
2147
            else if (lp == (s_region *)NULL)
2148
		MemoryAreaHeader = cp->next;
2148
                MemoryAreaHeader = cp->next;
2149
 
2149
 
2150
/* Delete the current entry and relink */
2150
/* Delete the current entry and relink */
2151
 
2151
 
2152
	    else
2152
            else
2153
		lp->next = cp->next;
2153
                lp->next = cp->next;
2154
 
2154
 
2155
	    RELEASE_MEMORY (cp);
2155
            RELEASE_MEMORY (cp);
2156
	    break;
2156
            break;
2157
	}
2157
        }
2158
    }
2158
    }
2159
 
2159
 
2160
/* Restore signals */
2160
/* Restore signals */
2161
 
2161
 
2162
    signal (SIGINT, save_signal);
2162
    signal (SIGINT, save_signal);
Line 2167... Line 2167...
2167
 */
2167
 */
2168
 
2168
 
2169
#ifdef DEBUG_MEMORY
2169
#ifdef DEBUG_MEMORY
2170
void DumpMemoryCells (int status)
2170
void DumpMemoryCells (int status)
2171
{
2171
{
2172
    s_region		*cp = MemoryAreaHeader;
2172
    s_region            *cp = MemoryAreaHeader;
2173
    size_t		i;
2173
    size_t              i;
2174
    char		buffer[17];
2174
    char                buffer[17];
2175
    char		*sp;
2175
    char                *sp;
2176
 
2176
 
2177
/* Find the string in the chain */
2177
/* Find the string in the chain */
2178
 
2178
 
2179
    while (cp != (s_region *)NULL)
2179
    while (cp != (s_region *)NULL)
2180
    {
2180
    {
2181
	fprintf (stderr, "Segment 0x%.8lx Area %5d Length %5d Link 0x%.8lx\n",
2181
        fprintf (stderr, "Segment 0x%.8lx Area %5d Length %5d Link 0x%.8lx\n",
2182
		 cp, cp->area, cp->nbytes, cp->next);
2182
                 cp, cp->area, cp->nbytes, cp->next);
2183
 
2183
 
2184
	memset (buffer, CHAR_SPACE, 17);
2184
        memset (buffer, CHAR_SPACE, 17);
2185
	buffer[16] = 0;
2185
        buffer[16] = 0;
2186
 
2186
 
2187
	sp = ((char *)cp) + sizeof (s_region);
2187
        sp = ((char *)cp) + sizeof (s_region);
2188
 
2188
 
2189
	for (i = 0; i < (((cp->nbytes - 1)/16) + 1) * 16; i++)
2189
        for (i = 0; i < (((cp->nbytes - 1)/16) + 1) * 16; i++)
2190
	{
2190
        {
2191
	    if (i >= cp->nbytes)
2191
            if (i >= cp->nbytes)
2192
	    {
2192
            {
2193
		feputs ("   ");
2193
                feputs ("   ");
2194
		buffer [i % 16] = CHAR_SPACE;
2194
                buffer [i % 16] = CHAR_SPACE;
2195
	    }
2195
            }
2196
 
2196
 
2197
	    else
2197
            else
2198
	    {
2198
            {
2199
		fprintf (stderr, "%.2x ", *sp & 0x0ff);
2199
                fprintf (stderr, "%.2x ", *sp & 0x0ff);
2200
		buffer [i % 16] = (char)(isprint (*sp) ? *sp : CHAR_PERIOD);
2200
                buffer [i % 16] = (char)(isprint (*sp) ? *sp : CHAR_PERIOD);
2201
	    }
2201
            }
2202
 
2202
 
2203
	    if (i % 16 == 15)
2203
            if (i % 16 == 15)
2204
		fprintf (stderr, "    [%s]\n", buffer);
2204
                fprintf (stderr, "    [%s]\n", buffer);
2205
 
2205
 
2206
	    sp++;
2206
            sp++;
2207
	}
2207
        }
2208
 
2208
 
2209
	feputc (CHAR_NEW_LINE);
2209
        feputc (CHAR_NEW_LINE);
2210
	cp = cp->next;
2210
        cp = cp->next;
2211
    }
2211
    }
2212
#undef exit
2212
#undef exit
2213
    exit (status);
2213
    exit (status);
2214
#define exit(x)		DumpMemoryCells (x)
2214
#define exit(x)         DumpMemoryCells (x)
2215
}
2215
}
2216
#endif
2216
#endif
2217
 
2217
 
2218
/*
2218
/*
2219
 * Autodelete space nolonger required.  Ie. Free all the strings in a malloced
2219
 * Autodelete space nolonger required.  Ie. Free all the strings in a malloced
2220
 * area
2220
 * area
2221
 */
2221
 */
2222
 
2222
 
2223
void ReleaseMemoryArea (int a)
2223
void ReleaseMemoryArea (int a)
2224
{
2224
{
2225
    s_region		*cp = MemoryAreaHeader;
2225
    s_region            *cp = MemoryAreaHeader;
2226
    s_region		*lp = (s_region *)NULL;
2226
    s_region            *lp = (s_region *)NULL;
2227
    void                (_SIGDECL *save_signal)(int);
2227
    void                (_SIGDECL *save_signal)(int);
2228
 
2228
 
2229
/* Release the Here documents first */
2229
/* Release the Here documents first */
2230
 
2230
 
2231
    FreeAllHereDocuments (a);
2231
    FreeAllHereDocuments (a);
Line 2237... Line 2237...
2237
    while (cp != (s_region *)NULL)
2237
    while (cp != (s_region *)NULL)
2238
    {
2238
    {
2239
 
2239
 
2240
/* Is the area number less than that specified - yes, continue */
2240
/* Is the area number less than that specified - yes, continue */
2241
 
2241
 
2242
	if (cp->area < a)
2242
        if (cp->area < a)
2243
	{
2243
        {
2244
	    lp = cp;
2244
            lp = cp;
2245
	    cp = cp->next;
2245
            cp = cp->next;
2246
	}
2246
        }
2247
 
2247
 
2248
/* OK - delete the area.  Is it the first in chain ?  Yes, delete, relink
2248
/* OK - delete the area.  Is it the first in chain ?  Yes, delete, relink
2249
 * and update start location
2249
 * and update start location
2250
 */
2250
 */
2251
 
2251
 
2252
	else if (lp == (s_region *)NULL)
2252
        else if (lp == (s_region *)NULL)
2253
	{
2253
        {
2254
	    lp = cp;
2254
            lp = cp;
2255
	    cp = cp->next;
2255
            cp = cp->next;
2256
	    MemoryAreaHeader = cp;
2256
            MemoryAreaHeader = cp;
2257
 
2257
 
2258
	    RELEASE_MEMORY (lp);
2258
            RELEASE_MEMORY (lp);
2259
	    lp = (s_region *)NULL;
2259
            lp = (s_region *)NULL;
2260
	}
2260
        }
2261
 
2261
 
2262
/* Not first, delete the current entry and relink */
2262
/* Not first, delete the current entry and relink */
2263
 
2263
 
2264
	else
2264
        else
2265
	{
2265
        {
2266
	    lp->next = cp->next;
2266
            lp->next = cp->next;
2267
	    RELEASE_MEMORY (cp);
2267
            RELEASE_MEMORY (cp);
2268
	    cp = lp->next;
2268
            cp = lp->next;
2269
	}
2269
        }
2270
    }
2270
    }
2271
 
2271
 
2272
/* Restore signals */
2272
/* Restore signals */
2273
 
2273
 
2274
    signal (SIGINT, save_signal);
2274
    signal (SIGINT, save_signal);
Line 2279... Line 2279...
2279
 * space that is nolonger required.
2279
 * space that is nolonger required.
2280
 */
2280
 */
2281
 
2281
 
2282
void SetMemoryAreaNumber (void *cp, int a)
2282
void SetMemoryAreaNumber (void *cp, int a)
2283
{
2283
{
2284
    s_region	*sp = (s_region *)((char *)cp - sizeof (s_region));
2284
    s_region    *sp = (s_region *)((char *)cp - sizeof (s_region));
2285
 
2285
 
2286
    if (cp != (void *)NULL)
2286
    if (cp != (void *)NULL)
2287
	sp->area = a;
2287
        sp->area = a;
2288
}
2288
}
2289
 
2289
 
2290
/*
2290
/*
2291
 * Get the area number for a malloced string
2291
 * Get the area number for a malloced string
2292
 */
2292
 */
2293
 
2293
 
2294
int GetMemoryAreaNumber (void *cp)
2294
int GetMemoryAreaNumber (void *cp)
2295
{
2295
{
2296
    s_region	*sp = (s_region *)((char *)cp - sizeof (s_region));
2296
    s_region    *sp = (s_region *)((char *)cp - sizeof (s_region));
2297
 
2297
 
2298
    return sp->area;
2298
    return sp->area;
2299
}
2299
}
2300
 
2300
 
2301
/* Output one of the Prompt.  We save the prompt for the history part of
2301
/* Output one of the Prompt.  We save the prompt for the history part of
2302
 * the program
2302
 * the program
2303
 */
2303
 */
2304
 
2304
 
2305
void OutputUserPrompt (char *s)
2305
void OutputUserPrompt (char *s)
2306
{
2306
{
2307
    struct tm		*tm;
2307
    struct tm           *tm;
2308
    time_t		xtime = time ((time_t *)NULL);
2308
    time_t              xtime = time ((time_t *)NULL);
2309
    int			i;
2309
    int                 i;
2310
    char		buf[PATH_MAX + 4];
2310
    char                buf[PATH_MAX + 4];
2311
 
2311
 
2312
    if (LastUserPrompt != (char *)NULL)
2312
    if (LastUserPrompt != (char *)NULL)
2313
    {
2313
    {
2314
	LastUserPrompt = s;		/* Save the Last prompt id	*/
2314
        LastUserPrompt = s;             /* Save the Last prompt id      */
2315
	s = GetVariableAsString (s, TRUE); /* Get the string value	*/
2315
        s = GetVariableAsString (s, TRUE); /* Get the string value      */
2316
 
2316
 
2317
	if (LastUserPrompt == PS1)
2317
        if (LastUserPrompt == PS1)
2318
	    s = substitute (s, 0);
2318
            s = substitute (s, 0);
2319
    }
2319
    }
2320
 
2320
 
2321
    else
2321
    else
2322
	s = LastUserPrompt1;
2322
        s = LastUserPrompt1;
2323
 
2323
 
2324
    tm = localtime (&xtime);
2324
    tm = localtime (&xtime);
2325
 
2325
 
2326
    while (*s)
2326
    while (*s)
2327
    {
2327
    {
2328
 
2328
 
2329
/* If a format character, process it */
2329
/* If a format character, process it */
2330
 
2330
 
2331
	if (*s == CHAR_FORMAT)
2331
        if (*s == CHAR_FORMAT)
2332
	{
2332
        {
2333
	    s++;
2333
            s++;
2334
	    *s = (char)tolower(*s);
2334
            *s = (char)tolower(*s);
2335
 
2335
 
2336
	    if (*s == CHAR_FORMAT)
2336
            if (*s == CHAR_FORMAT)
2337
		fputchar (CHAR_FORMAT);
2337
                fputchar (CHAR_FORMAT);
2338
 
-
 
2339
	    else
-
 
2340
	    {
-
 
2341
		*buf = 0;
-
 
2342
 
-
 
2343
		switch (*(s++))
-
 
2344
		{
-
 
2345
		    case 'e':		    /* Current event number */
-
 
2346
			if (HistoryEnabled)
-
 
2347
			    sprintf (buf, "%d", Current_Event + 1);
-
 
2348
 
-
 
2349
			break;
-
 
2350
 
-
 
2351
		    case 't':		    /* time	    */
-
 
2352
			sprintf (buf,"%.2d:%.2d", tm->tm_hour, tm->tm_min);
-
 
2353
			break;
-
 
2354
 
-
 
2355
		    case 'd':		    /* date	    */
-
 
2356
			sprintf (buf, "%.3s %.2d-%.2d-%.2d",
-
 
2357
				 &"SunMonTueWedThuFriSat"[tm->tm_wday * 3],
-
 
2358
				 tm->tm_mday, tm->tm_mon + 1,
-
 
2359
				 tm->tm_year % 100);
-
 
2360
			break;
-
 
2361
 
-
 
2362
		    case 'p':		    /* directory    */
-
 
2363
		    case 'n':		    /* default drive */
-
 
2364
			strcpy (buf, CurrentDirectory->value);
-
 
2365
 
2338
 
-
 
2339
            else
-
 
2340
            {
2366
			if (*(s - 1) == 'n')
2341
                *buf = 0;
-
 
2342
 
-
 
2343
                switch (*(s++))
2367
			    buf[1] = 0;
2344
                {
-
 
2345
                    case 'e':               /* Current event number */
-
 
2346
                        if (HistoryEnabled)
-
 
2347
                            sprintf (buf, "%d", Current_Event + 1);
-
 
2348
 
-
 
2349
                        break;
-
 
2350
 
-
 
2351
                    case 't':               /* time         */
-
 
2352
                        sprintf (buf,"%.2d:%.2d", tm->tm_hour, tm->tm_min);
-
 
2353
                        break;
-
 
2354
 
-
 
2355
                    case 'd':               /* date         */
-
 
2356
                        sprintf (buf, "%.3s %.2d-%.2d-%.2d",
-
 
2357
                                 &"SunMonTueWedThuFriSat"[tm->tm_wday * 3],
-
 
2358
                                 tm->tm_mday, tm->tm_mon + 1,
-
 
2359
                                 tm->tm_year % 100);
-
 
2360
                        break;
-
 
2361
 
-
 
2362
                    case 'p':               /* directory    */
-
 
2363
                    case 'n':               /* default drive */
-
 
2364
                        strcpy (buf, CurrentDirectory->value);
-
 
2365
 
-
 
2366
                        if (*(s - 1) == 'n')
-
 
2367
                            buf[1] = 0;
2368
 
2368
 
2369
			break;
2369
                        break;
2370
 
2370
 
2371
#if (OS_TYPE != OS_UNIX)
2371
#if (OS_TYPE != OS_UNIX)
2372
		    case 'v':		    /* version	    */
2372
                    case 'v':               /* version      */
2373
			sprintf (buf, "%s %.2d:%.2d", LIT_OSname,
2373
                        sprintf (buf, "%s %.2d:%.2d", LIT_OSname,
2374
                                OS_VERS_N, OS_VERS_M);
2374
                                OS_VERS_N, OS_VERS_M);
2375
			break;
2375
                        break;
2376
#endif
2376
#endif
2377
		}
2377
                }
2378
 
2378
 
2379
/* Output the string */
2379
/* Output the string */
2380
 
2380
 
2381
		foputs (buf);
2381
                foputs (buf);
2382
	    }
2382
            }
2383
	}
2383
        }
2384
 
2384
 
2385
/* Escaped character ? */
2385
/* Escaped character ? */
2386
 
2386
 
2387
	else if (*s == CHAR_META)
2387
        else if (*s == CHAR_META)
2388
	{
2388
        {
2389
	    ++s;
2389
            ++s;
2390
	    if ((i = ProcessOutputMetaCharacters (&s)) == -1)
2390
            if ((i = ProcessOutputMetaCharacters (&s)) == -1)
2391
		i = 0;
2391
                i = 0;
2392
 
2392
 
2393
	    fputchar ((char)i);
2393
            fputchar ((char)i);
2394
	}
2394
        }
2395
 
2395
 
2396
	else
2396
        else
2397
	    fputchar (*(s++));
2397
            fputchar (*(s++));
2398
    }
2398
    }
2399
 
2399
 
2400
    FlushStreams ();			/* Clear output */
2400
    FlushStreams ();                    /* Clear output */
2401
}
2401
}
2402
 
2402
 
2403
/*
2403
/*
2404
 * Get the current path in UNIX format and save it in the environment
2404
 * Get the current path in UNIX format and save it in the environment
2405
 * variable $~
2405
 * variable $~
2406
 */
2406
 */
2407
 
2407
 
2408
void GetCurrentDirectoryPath (void)
2408
void GetCurrentDirectoryPath (void)
2409
{
2409
{
2410
    char	ldir[PATH_MAX + 6];
2410
    char        ldir[PATH_MAX + 6];
2411
    char	*CurrentPWDValue;		/* Current directory	*/
2411
    char        *CurrentPWDValue;               /* Current directory    */
2412
 
2412
 
2413
    S_getcwd (ldir, 0);
2413
    S_getcwd (ldir, 0);
2414
 
2414
 
2415
/* Save in environment */
2415
/* Save in environment */
2416
 
2416
 
Line 2418... Line 2418...
2418
    CurrentDirectory = LookUpVariable (tilde, 0, TRUE);
2418
    CurrentDirectory = LookUpVariable (tilde, 0, TRUE);
2419
 
2419
 
2420
/* If we have changed directory, set PWD and OLDPWD */
2420
/* If we have changed directory, set PWD and OLDPWD */
2421
 
2421
 
2422
    if (strcmp (CurrentPWDValue = GetVariableAsString (PWDVariable, FALSE),
2422
    if (strcmp (CurrentPWDValue = GetVariableAsString (PWDVariable, FALSE),
2423
		ldir))
2423
                ldir))
2424
    {
2424
    {
2425
	SetVariableFromString (OldPWDVariable, CurrentPWDValue);
2425
        SetVariableFromString (OldPWDVariable, CurrentPWDValue);
2426
	SetVariableFromString (PWDVariable, ldir);
2426
        SetVariableFromString (PWDVariable, ldir);
2427
    }
2427
    }
2428
}
2428
}
2429
 
2429
 
2430
/*
2430
/*
2431
 * Initialise the shell and Patch up various parts of the system for the
2431
 * Initialise the shell and Patch up various parts of the system for the
Line 2457... Line 2457...
2457
}
2457
}
2458
#endif
2458
#endif
2459
 
2459
 
2460
static bool F_LOCAL Initialise (int argc, char **argv)
2460
static bool F_LOCAL Initialise (int argc, char **argv)
2461
{
2461
{
2462
    char	*s, *s1;
2462
    char        *s, *s1;
2463
    char	**ap;
2463
    char        **ap;
2464
    char	*name = *argv;
2464
    char        *name = *argv;
2465
    bool	OptionsRflag = FALSE;
2465
    bool        OptionsRflag = FALSE;
2466
#if (OS_TYPE == OS_NT)
2466
#if (OS_TYPE == OS_NT)
2467
    bool	Level0 = FALSE;
2467
    bool        Level0 = FALSE;
2468
    int		sc;
2468
    int         sc;
2469
#endif
2469
#endif
2470
 
2470
 
2471
/*
2471
/*
2472
 * Determine the base OS if we can!
2472
 * Determine the base OS if we can!
2473
 */
2473
 */
2474
 
2474
 
2475
#if (OS_TYPE == OS_NT)
2475
#if (OS_TYPE == OS_NT)
2476
    BaseOS = BASE_OS_NT;	/* Default to NT - no other */
2476
    BaseOS = BASE_OS_NT;        /* Default to NT - no other */
2477
#elif (OS_TYPE == OS_UNIX)
2477
#elif (OS_TYPE == OS_UNIX)
2478
    BaseOS = BASE_OS_UNIX;	/* Default to UNIX - no other */
2478
    BaseOS = BASE_OS_UNIX;      /* Default to UNIX - no other */
2479
#elif (OS_TYPE == OS_OS2)
2479
#elif (OS_TYPE == OS_OS2)
2480
    BaseOS = BASE_OS_OS2;	/* Default to OS2 - no other */
2480
    BaseOS = BASE_OS_OS2;       /* Default to OS2 - no other */
2481
#elif (OS_TYPE == OS_DOS)
2481
#elif (OS_TYPE == OS_DOS)
2482
 
2482
 
2483
    BaseOS = BASE_OS_DOS;	/* Default to DOS */
2483
    BaseOS = BASE_OS_DOS;       /* Default to DOS */
2484
 
2484
 
2485
    if (_osmajor > 10)          /* Rather crude check */
2485
    if (_osmajor > 10)          /* Rather crude check */
2486
	BaseOS = BASE_OS_OS2;
2486
        BaseOS = BASE_OS_OS2;
2487
 
2487
 
2488
/* Know to stop NT ? */
2488
/* Know to stop NT ? */
2489
 
2489
 
2490
    else
2490
    else
2491
    {
2491
    {
2492
        union REGS	r;
2492
        union REGS      r;
2493
	r.h.ah = 0x16;
2493
        r.h.ah = 0x16;
2494
	r.h.al = 0;
2494
        r.h.al = 0;
2495
 
2495
 
2496
	SystemInterrupt (0x2f, &r, &r);
2496
        SystemInterrupt (0x2f, &r, &r);
2497
 
2497
 
2498
	if (r.h.al > 0)
2498
        if (r.h.al > 0)
2499
	    BaseOS = BASE_OS_WIN;
2499
            BaseOS = BASE_OS_WIN;
2500
 
2500
 
2501
	else
2501
        else
2502
	{
2502
        {
2503
	    r.x.REG_AX = 0x3306;
2503
            r.x.REG_AX = 0x3306;
2504
	    SystemInterrupt (0x21, &r, &r);
2504
            SystemInterrupt (0x21, &r, &r);
2505
 
2505
 
2506
	    if ((r.x.REG_AX == 0x3306) && (r.x.REG_BX == 0x3205))
2506
            if ((r.x.REG_AX == 0x3306) && (r.x.REG_BX == 0x3205))
2507
		BaseOS = BASE_OS_NT;
2507
                BaseOS = BASE_OS_NT;
2508
	}
2508
        }
2509
    }
2509
    }
2510
#endif
2510
#endif
2511
 
2511
 
2512
/*
2512
/*
2513
 * For MSDOS: Get original interrupt 24 address and set up our new interrupt
2513
 * For MSDOS: Get original interrupt 24 address and set up our new interrupt
2514
 *	      24 address.
2514
 *            24 address.
2515
 * For OS/2 : Set noignore interrupts.
2515
 * For OS/2 : Set noignore interrupts.
2516
 */
2516
 */
2517
 
2517
 
2518
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
2518
#if (OS_TYPE == OS_DOS) && !defined (__EMX__)
2519
    Orig_I24_V = GetInterruptVector (0x24);
2519
    Orig_I24_V = GetInterruptVector (0x24);
Line 2551... Line 2551...
2551
 */
2551
 */
2552
 
2552
 
2553
#if (OS_TYPE == OS_NT)
2553
#if (OS_TYPE == OS_NT)
2554
    while ((sc = GetOptions (argc, argv, ShellOptions, 0)) != EOF)
2554
    while ((sc = GetOptions (argc, argv, ShellOptions, 0)) != EOF)
2555
    {
2555
    {
2556
	if (sc == '0')
2556
        if (sc == '0')
2557
	{
2557
        {
2558
	    Level0 = TRUE;
2558
            Level0 = TRUE;
2559
	    break;
2559
            break;
2560
	}
2560
        }
2561
    }
2561
    }
2562
 
2562
 
2563
    ResetGetOptions ();
2563
    ResetGetOptions ();
2564
#endif
2564
#endif
2565
 
2565
 
Line 2570... Line 2570...
2570
#if (OS_TYPE == OS_NT)
2570
#if (OS_TYPE == OS_NT)
2571
        const char *paths[PATHSMAX];
2571
        const char *paths[PATHSMAX];
2572
        int pathcnt = 0;
2572
        int pathcnt = 0;
2573
#endif
2573
#endif
2574
 
2574
 
2575
	for (ap = environ; *ap != (char *)NULL; ap++)
2575
        for (ap = environ; *ap != (char *)NULL; ap++)
2576
	{
2576
        {
2577
 
2577
 
2578
/* Set up any variables.  Note there is an assumption that
2578
/* Set up any variables.  Note there is an assumption that
2579
 * AssignVariableFromString sets the equals sign to 0, hiding the value;
2579
 * AssignVariableFromString sets the equals sign to 0, hiding the value;
2580
 */
2580
 */
2581
	    if (!strncmp ("SECONDS=", *ap, 8))
2581
            if (!strncmp ("SECONDS=", *ap, 8))
2582
		continue;
2582
                continue;
2583
 
2583
 
2584
/* NT is case in-sensitive - what a PAIN! */
2584
/* NT is case in-sensitive - what a PAIN! */
2585
 
2585
 
2586
#if (OS_TYPE == OS_NT)
2586
#if (OS_TYPE == OS_NT)
2587
                                                /* special PATH handling */
2587
                                                /* special PATH handling */
Line 2590... Line 2590...
2590
                if (pathcnt < PATHSMAX)
2590
                if (pathcnt < PATHSMAX)
2591
                    paths[ pathcnt++ ] = *ap;
2591
                    paths[ pathcnt++ ] = *ap;
2592
                continue;                       /* next -- process on exit */
2592
                continue;                       /* next -- process on exit */
2593
            }
2593
            }
2594
 
2594
 
2595
	    if (Level0)
2595
            if (Level0)
2596
            {
2596
            {
2597
		s = *ap;
2597
                s = *ap;
2598
 
2598
 
2599
		while (*s && (*s != CHAR_ASSIGN))
2599
                while (*s && (*s != CHAR_ASSIGN))
2600
		{                               /* convert to upper case */
2600
                {                               /* convert to upper case */
2601
		    *s = (char)toupper (*s);
2601
                    *s = (char)toupper (*s);
2602
		    s++;
2602
                    s++;
2603
		}
2603
                }
2604
	    }
2604
            }
2605
#endif
2605
#endif
2606
	    if (AssignVariableFromString (*ap, (int *)NULL))
2606
            if (AssignVariableFromString (*ap, (int *)NULL))
2607
		SetVariableStatus (*ap, STATUS_EXPORT);
2607
                SetVariableStatus (*ap, STATUS_EXPORT);
2608
	}
2608
        }
2609
 
2609
 
2610
    /*
2610
    /*
2611
    **  Can not access varibales from the environment
2611
    **  Can not access varibales from the environment
2612
    **  Set up debug level
2612
    **  Set up debug level
2613
    */
2613
    */
Line 2653... Line 2653...
2653
                        {                       /* .. different */
2653
                        {                       /* .. different */
2654
                            if (dbg) {
2654
                            if (dbg) {
2655
                                fprintf ( stderr, " .. different!\n" );
2655
                                fprintf ( stderr, " .. different!\n" );
2656
                            }
2656
                            }
2657
 
2657
 
2658
	                    if (!FL_TEST (FLAG_WARNING)) {
2658
                            if (!FL_TEST (FLAG_WARNING)) {
2659
                                if (err++ == 0)
2659
                                if (err++ == 0)
2660
                                    PrintWarningMessage ( "sh: %d path definitions encountered.", pathcnt );
2660
                                    PrintWarningMessage ( "sh: %d path definitions encountered.", pathcnt );
2661
                                PrintWarningMessage ( "sh: ignoring differing alternative '%.4s'\n %s", paths[i], paths[i] );
2661
                                PrintWarningMessage ( "sh: ignoring differing alternative '%.4s'\n %s", paths[i], paths[i] );
2662
                            }
2662
                            }
2663
 
2663
 
Line 2743... Line 2743...
2743
 * save it as the Shell name.  Under OS/2, make sure we use .exe
2743
 * save it as the Shell name.  Under OS/2, make sure we use .exe
2744
 */
2744
 */
2745
    if (GetVariableAsString (ShellVariableName, FALSE) == null)
2745
    if (GetVariableAsString (ShellVariableName, FALSE) == null)
2746
    {
2746
    {
2747
#if (OS_TYPE == OS_OS2) || (OS_TYPE == OS_NT)
2747
#if (OS_TYPE == OS_OS2) || (OS_TYPE == OS_NT)
2748
	if ((s1 = strrchr (name, CHAR_PERIOD)) == (char *)NULL)
2748
        if ((s1 = strrchr (name, CHAR_PERIOD)) == (char *)NULL)
2749
	    strcat (name, EXEExtension);
2749
            strcat (name, EXEExtension);
2750
 
2750
 
2751
	SetVariableFromString (ShellVariableName, name);
2751
        SetVariableFromString (ShellVariableName, name);
2752
 
2752
 
2753
	ReleaseMemoryCell (name);
2753
        ReleaseMemoryCell (name);
2754
#elif (OS_TYPE == OS_DOS)
2754
#elif (OS_TYPE == OS_DOS)
2755
	if (((s1 = strrchr (name, CHAR_PERIOD)) != (char *)NULL) &&
2755
        if (((s1 = strrchr (name, CHAR_PERIOD)) != (char *)NULL) &&
2756
	    (stricmp (s1 + 1, EXEExtension + 1) == 0))
2756
            (stricmp (s1 + 1, EXEExtension + 1) == 0))
2757
	    SetVariableFromString (ShellVariableName, PATH_TO_UNIX (name));
2757
            SetVariableFromString (ShellVariableName, PATH_TO_UNIX (name));
2758
#elif (OS_TYPE == OS_UNIX)
2758
#elif (OS_TYPE == OS_UNIX)
2759
	SetVariableFromString (ShellVariableName,
2759
        SetVariableFromString (ShellVariableName,
2760
				(*name == '-') ? name + 1 : name);
2760
                                (*name == '-') ? name + 1 : name);
2761
#endif
2761
#endif
2762
    }
2762
    }
2763
 
2763
 
2764
/* Default if necessary */
2764
/* Default if necessary */
2765
 
2765
 
2766
    if (GetVariableAsString (ShellVariableName, FALSE) == null)
2766
    if (GetVariableAsString (ShellVariableName, FALSE) == null)
2767
	SetVariableFromString (ShellVariableName, shellname);
2767
        SetVariableFromString (ShellVariableName, shellname);
2768
 
2768
 
2769
    PATH_TO_UNIX (s1 = GetVariableAsString (ShellVariableName, FALSE));
2769
    PATH_TO_UNIX (s1 = GetVariableAsString (ShellVariableName, FALSE));
2770
 
2770
 
2771
/* Check for restricted shell */
2771
/* Check for restricted shell */
2772
 
2772
 
2773
    if ((s = FindLastPathCharacter (s1)) == (char *)NULL)
2773
    if ((s = FindLastPathCharacter (s1)) == (char *)NULL)
2774
	s = s1;
2774
        s = s1;
2775
 
2775
 
2776
    else
2776
    else
2777
	s++;
2777
        s++;
2778
 
2778
 
2779
    if (*s == 'r')
2779
    if (*s == 'r')
2780
	OptionsRflag = TRUE;
2780
        OptionsRflag = TRUE;
2781
 
2781
 
2782
/* Set up home directory */
2782
/* Set up home directory */
2783
 
2783
 
2784
    if (GetVariableAsString (HomeVariableName, FALSE) == null)
2784
    if (GetVariableAsString (HomeVariableName, FALSE) == null)
2785
    {
2785
    {
2786
        if ((s = GetVariableAsString ("INIT", FALSE)) == null)
2786
        if ((s = GetVariableAsString ("INIT", FALSE)) == null)
2787
            s = CurrentDirectory->value;
2787
            s = CurrentDirectory->value;
2788
 
2788
 
2789
	SetVariableFromString (HomeVariableName, s);
2789
        SetVariableFromString (HomeVariableName, s);
2790
    }
2790
    }
2791
 
2791
 
2792
/* Set up OS Mode */
2792
/* Set up OS Mode */
2793
 
2793
 
2794
#if (OS_TYPE == OS_UNIX) || defined(WIN32)
2794
#if (OS_TYPE == OS_UNIX) || defined(WIN32)
Line 2826... Line 2826...
2826
 * to display if the file has changed.
2826
 * to display if the file has changed.
2827
 */
2827
 */
2828
 
2828
 
2829
static void F_LOCAL CheckForMailArriving (void)
2829
static void F_LOCAL CheckForMailArriving (void)
2830
{
2830
{
2831
    int			delay = (int)GetVariableAsNumeric (MailCheckVariable);
2831
    int                 delay = (int)GetVariableAsNumeric (MailCheckVariable);
2832
    char		*mail = GetVariableAsString ("MAIL", FALSE);
2832
    char                *mail = GetVariableAsString ("MAIL", FALSE);
2833
    char		*mailp = GetVariableAsString ("MAILPATH", FALSE);
2833
    char                *mailp = GetVariableAsString ("MAILPATH", FALSE);
2834
    static time_t	last = 0L;
2834
    static time_t       last = 0L;
2835
    time_t		current = time ((time_t *)NULL);
2835
    time_t              current = time ((time_t *)NULL);
2836
    struct stat		st;
2836
    struct stat         st;
2837
    char		*cp, *sp, *ap;
2837
    char                *cp, *sp, *ap;
2838
 
2838
 
2839
/* Have we waited long enough */
2839
/* Have we waited long enough */
2840
 
2840
 
2841
    if (((current - last) < delay) || (DisabledVariables & DISABLE_MAILCHECK))
2841
    if (((current - last) < delay) || (DisabledVariables & DISABLE_MAILCHECK))
2842
	return;
2842
        return;
2843
 
2843
 
2844
/* Yes - Check $MAILPATH.  If it is defined, process it.  Otherwise, use
2844
/* Yes - Check $MAILPATH.  If it is defined, process it.  Otherwise, use
2845
 * $MAIL
2845
 * $MAIL
2846
 */
2846
 */
2847
 
2847
 
2848
    if (mailp != null)
2848
    if (mailp != null)
2849
    {
2849
    {
2850
 
2850
 
2851
/* Check MAILPATH */
2851
/* Check MAILPATH */
2852
 
2852
 
2853
	sp = mailp;
2853
        sp = mailp;
2854
 
2854
 
2855
/* Look for the next separator */
2855
/* Look for the next separator */
2856
 
2856
 
2857
	while ((cp = strchr (sp, CHAR_PATH_SEPARATOR)) != (char *)NULL)
2857
        while ((cp = strchr (sp, CHAR_PATH_SEPARATOR)) != (char *)NULL)
2858
	{
2858
        {
2859
	    *cp = 0;
2859
            *cp = 0;
2860
 
2860
 
2861
/* % in string ? */
2861
/* % in string ? */
2862
 
2862
 
2863
	    if ((ap = strchr (sp, CHAR_FORMAT)) != (char *)NULL)
2863
            if ((ap = strchr (sp, CHAR_FORMAT)) != (char *)NULL)
2864
		*ap = 0;
2864
                *ap = 0;
2865
 
2865
 
2866
/* Check the file name */
2866
/* Check the file name */
2867
 
2867
 
2868
	    if ((S_stat (sp, &st)) && (st.st_mtime > last) && st.st_size)
2868
            if ((S_stat (sp, &st)) && (st.st_mtime > last) && st.st_size)
2869
	    {
2869
            {
2870
		feputs ((ap != (char *)NULL) ? ap + 1 : ymail);
2870
                feputs ((ap != (char *)NULL) ? ap + 1 : ymail);
2871
		feputc (CHAR_NEW_LINE);
2871
                feputc (CHAR_NEW_LINE);
2872
	    }
2872
            }
2873
 
2873
 
2874
/* Restore the % */
2874
/* Restore the % */
2875
 
2875
 
2876
	    if (ap != (char *)NULL)
2876
            if (ap != (char *)NULL)
2877
		*ap = CHAR_FORMAT;
2877
                *ap = CHAR_FORMAT;
2878
 
2878
 
2879
/* Restore the semi-colon and find the next one */
2879
/* Restore the semi-colon and find the next one */
2880
 
2880
 
2881
	    *cp = CHAR_PATH_SEPARATOR;
2881
            *cp = CHAR_PATH_SEPARATOR;
2882
	    sp = cp + 1;
2882
            sp = cp + 1;
2883
	}
2883
        }
2884
    }
2884
    }
2885
 
2885
 
2886
/* Just check MAIL */
2886
/* Just check MAIL */
2887
 
2887
 
2888
    else if ((mail != null) && (S_stat (mail, &st)) &&
2888
    else if ((mail != null) && (S_stat (mail, &st)) &&
2889
	     (st.st_mtime > last) && st.st_size)
2889
             (st.st_mtime > last) && st.st_size)
2890
    {
2890
    {
2891
	feputs (ymail);
2891
        feputs (ymail);
2892
	feputc (CHAR_NEW_LINE);
2892
        feputc (CHAR_NEW_LINE);
2893
    }
2893
    }
2894
 
2894
 
2895
/* Save the last check time */
2895
/* Save the last check time */
2896
 
2896
 
2897
    last = current;
2897
    last = current;
Line 2907... Line 2907...
2907
 */
2907
 */
2908
 
2908
 
2909
#if (OS_TYPE != OS_UNIX)
2909
#if (OS_TYPE != OS_UNIX)
2910
static void F_LOCAL Pre_Process_Argv (char **argv, int *argc1)
2910
static void F_LOCAL Pre_Process_Argv (char **argv, int *argc1)
2911
{
2911
{
2912
    int		argc = 1;
2912
    int         argc = 1;
2913
    char	*ocl = _ACmdLine;
2913
    char        *ocl = _ACmdLine;
2914
    int		i;
2914
    int         i;
2915
 
2915
 
2916
/* Check for these options */
2916
/* Check for these options */
2917
 
2917
 
2918
    while ((*++argv != (char *)NULL) && (strlen (*argv) == 2) &&
2918
    while ((*++argv != (char *)NULL) && (strlen (*argv) == 2) &&
2919
	   (**argv == '/'))
2919
           (**argv == '/'))
2920
    {
2920
    {
2921
	argc++;
2921
        argc++;
2922
	*strlwr (*argv) = CHAR_SWITCH;
2922
        *strlwr (*argv) = CHAR_SWITCH;
2923
 
2923
 
2924
/* Get the original information from the command line */
2924
/* Get the original information from the command line */
2925
 
2925
 
2926
	if ((*argv)[1] == 'c')
2926
        if ((*argv)[1] == 'c')
2927
	{
2927
        {
2928
 
2928
 
2929
/*
2929
/*
2930
 * In some case under OS/2, we get /c, but with EMX style.  So all we need
2930
 * In some case under OS/2, we get /c, but with EMX style.  So all we need
2931
 * to do is change the / to a - and return.
2931
 * to do is change the / to a - and return.
2932
 */
2932
 */
2933
 
2933
 
2934
#  if (OS_TYPE == OS_OS2)
2934
#  if (OS_TYPE == OS_OS2)
2935
	    if (EMXStyleParameters)
2935
            if (EMXStyleParameters)
2936
	        return;
2936
                return;
2937
#  endif
2937
#  endif
2938
 
2938
 
2939
/*
2939
/*
2940
 * Otherwise, parse the command line again, looking for the /c
2940
 * Otherwise, parse the command line again, looking for the /c
2941
 */
2941
 */
2942
 
2942
 
2943
	    while ((*ocl != '/') && (*(ocl + 1) != 'c') &&
2943
            while ((*ocl != '/') && (*(ocl + 1) != 'c') &&
2944
		   (*ocl) && (*ocl != CHAR_RETURN))
2944
                   (*ocl) && (*ocl != CHAR_RETURN))
2945
		++ocl;
2945
                ++ocl;
2946
 
2946
 
2947
	    if (*ocl != '/')
2947
            if (*ocl != '/')
2948
		continue;
2948
                continue;
2949
 
2949
 
2950
/* Find the start of the string */
2950
/* Find the start of the string */
2951
 
2951
 
2952
	    ocl += 2;
2952
            ocl += 2;
2953
 
2953
 
2954
	    while (isspace (*ocl) && (*ocl != CHAR_RETURN))
2954
            while (isspace (*ocl) && (*ocl != CHAR_RETURN))
2955
		++ocl;
2955
                ++ocl;
2956
 
2956
 
2957
	    if (*ocl == CHAR_RETURN)
2957
            if (*ocl == CHAR_RETURN)
2958
		continue;
2958
                continue;
2959
 
2959
 
2960
/* Found the start.  Set up next parameter and ignore the rest */
2960
/* Found the start.  Set up next parameter and ignore the rest */
2961
 
2961
 
2962
	    if (*(argv + 1) == (char *)NULL)
2962
            if (*(argv + 1) == (char *)NULL)
2963
		continue;
2963
                continue;
2964
 
2964
 
2965
	    argc++;
2965
            argc++;
2966
 
2966
 
2967
/* Remove quotes from string, if they are there */
2967
/* Remove quotes from string, if they are there */
2968
 
2968
 
2969
	    if ((*ocl == CHAR_DOUBLE_QUOTE) &&
2969
            if ((*ocl == CHAR_DOUBLE_QUOTE) &&
2970
		(ocl[i = (strlen (ocl) - 1)] == CHAR_DOUBLE_QUOTE))
2970
                (ocl[i = (strlen (ocl) - 1)] == CHAR_DOUBLE_QUOTE))
2971
	    {
2971
            {
2972
		ocl[i] = 0;
2972
                ocl[i] = 0;
2973
		ocl++;
2973
                ocl++;
2974
	    }
2974
            }
2975
 
2975
 
2976
/* Set up new argument array */
2976
/* Set up new argument array */
2977
 
2977
 
2978
	    *(argv + 1) = ocl;
2978
            *(argv + 1) = ocl;
2979
	    *(argv + 2) = (char *)NULL;
2979
            *(argv + 2) = (char *)NULL;
2980
	    *argc1 = argc;
2980
            *argc1 = argc;
2981
 
2981
 
2982
	    if ((ocl = strchr (ocl, CHAR_RETURN)) != (char *)NULL)
2982
            if ((ocl = strchr (ocl, CHAR_RETURN)) != (char *)NULL)
2983
		*ocl = 0;
2983
                *ocl = 0;
2984
 
2984
 
2985
	    return;
2985
            return;
2986
	}
2986
        }
2987
    }
2987
    }
2988
}
2988
}
2989
#endif
2989
#endif
2990
 
2990
 
2991
/*
2991
/*
Line 2995... Line 2995...
2995
char *ConvertPathToFormat (char *path, char in, char out)
2995
char *ConvertPathToFormat (char *path, char in, char out)
2996
{
2996
{
2997
#if (OS_TYPE == OS_UNIX)
2997
#if (OS_TYPE == OS_UNIX)
2998
    return path;
2998
    return path;
2999
#else
2999
#else
3000
    char	*s = path;
3000
    char        *s = path;
3001
 
3001
 
3002
    while ((path = strchr (path, in)) != (char *)NULL)
3002
    while ((path = strchr (path, in)) != (char *)NULL)
3003
	*path = out;
3003
        *path = out;
3004
 
3004
 
3005
    return s;
3005
    return s;
3006
#endif
3006
#endif
3007
}
3007
}
3008
 
3008
 
3009
/* Load profiles onto I/O Stack */
3009
/* Load profiles onto I/O Stack */
3010
 
3010
 
3011
static void F_LOCAL LoadTheProfileFiles (void)
3011
static void F_LOCAL LoadTheProfileFiles (void)
3012
{
3012
{
3013
    char	*name;
3013
    char        *name;
3014
    char	*Pname;
3014
    char        *Pname;
3015
 
3015
 
3016
    if ((Pname = GetVariableAsString ("ETCPROFILE", FALSE)) == null)
3016
    if ((Pname = GetVariableAsString ("ETCPROFILE", FALSE)) == null)
3017
    {
3017
    {
3018
	Pname = "x:/etc/profile";
3018
        char PnameDefault[] = "x:/etc/profile";
-
 
3019
        Pname = PnameDefault; 
3019
	*Pname = GetDriveLetter (GetRootDiskDrive ());
3020
        *Pname = GetDriveLetter (GetRootDiskDrive ());
3020
    }
3021
    }
3021
 
3022
 
3022
    InteractiveFlag = TRUE;
3023
    InteractiveFlag = TRUE;
3023
    ExecuteShellScript (Pname);
3024
    ExecuteShellScript (Pname);
3024
 
3025
 
3025
/*
3026
/*
3026
 * Check $HOME format.  If in DOS format, mark and convert to UNIX
3027
 * Check $HOME format.  If in DOS format, mark and convert to UNIX
3027
 */
3028
 */
3028
 
3029
 
3029
    if (strchr (name = GetVariableAsString (HomeVariableName, FALSE),
3030
    if (strchr (name = GetVariableAsString (HomeVariableName, FALSE),
3030
		CHAR_DOS_PATH) != (char *)NULL)
3031
                CHAR_DOS_PATH) != (char *)NULL)
3031
    {
3032
    {
3032
	PATH_TO_UNIX (name);
3033
        PATH_TO_UNIX (name);
3033
	SetVariableStatus (HomeVariableName, STATUS_CONVERT_MSDOS);
3034
        SetVariableStatus (HomeVariableName, STATUS_CONVERT_MSDOS);
3034
    }
3035
    }
3035
 
3036
 
3036
    name = BuildFileName ("profile"); 	/* Set up home profile */
3037
    name = BuildFileName ("profile");   /* Set up home profile */
3037
    ExecuteShellScript (name);
3038
    ExecuteShellScript (name);
3038
    ReleaseMemoryCell ((void *)name);
3039
    ReleaseMemoryCell ((void *)name);
3039
}
3040
}
3040
 
3041
 
3041
/*
3042
/*
3042
 * Convert Unix PATH to MSDOS PATH
3043
 * Convert Unix PATH to MSDOS PATH
3043
 */
3044
 */
3044
 
3045
 
3045
static void F_LOCAL ConvertUnixPathToMSDOS (char *cp)
3046
static void F_LOCAL ConvertUnixPathToMSDOS (char *cp)
3046
{
3047
{
3047
    char	*scp = cp;
3048
    char        *scp = cp;
3048
    int		colon = 0;
3049
    int         colon = 0;
3049
 
3050
 
3050
/* If there is a semi-colon or a backslash, we assume this is a DOS format
3051
/* If there is a semi-colon or a backslash, we assume this is a DOS format
3051
 * path
3052
 * path
3052
 */
3053
 */
3053
 
3054
 
3054
    if ((strchr (cp, CHAR_PATH_SEPARATOR) != (char *)NULL) ||
3055
    if ((strchr (cp, CHAR_PATH_SEPARATOR) != (char *)NULL) ||
3055
	(strchr (cp, CHAR_DOS_PATH) != (char *)NULL))
3056
        (strchr (cp, CHAR_DOS_PATH) != (char *)NULL))
3056
	return;
3057
        return;
3057
 
3058
 
3058
/* Count the number of colons */
3059
/* Count the number of colons */
3059
 
3060
 
3060
    while ((cp = strchr (cp, CHAR_COLON)) != (char *)NULL)
3061
    while ((cp = strchr (cp, CHAR_COLON)) != (char *)NULL)
3061
    {
3062
    {
3062
	++colon;
3063
        ++colon;
3063
	++cp;
3064
        ++cp;
3064
    }
3065
    }
3065
 
3066
 
3066
/* If there are no colons or there is one colon as the second character, it
3067
/* If there are no colons or there is one colon as the second character, it
3067
 * is probably an MSDOS path
3068
 * is probably an MSDOS path
3068
 */
3069
 */
3069
 
3070
 
3070
    cp = scp;
3071
    cp = scp;
3071
    if ((colon == 0) || ((colon == 1) && (*(cp + 1) == CHAR_COLON)))
3072
    if ((colon == 0) || ((colon == 1) && (*(cp + 1) == CHAR_COLON)))
3072
	return;
3073
        return;
3073
 
3074
 
3074
/* Otherwise, convert all colons to semis */
3075
/* Otherwise, convert all colons to semis */
3075
 
3076
 
3076
    while ((cp = strchr (cp, CHAR_COLON)) != (char *)NULL)
3077
    while ((cp = strchr (cp, CHAR_COLON)) != (char *)NULL)
3077
	*(cp++) = CHAR_PATH_SEPARATOR;
3078
        *(cp++) = CHAR_PATH_SEPARATOR;
3078
}
3079
}
3079
 
3080
 
3080
/* Generate a file name from a directory and name.  Return null if an error
3081
/* Generate a file name from a directory and name.  Return null if an error
3081
 * occurs or some malloced space containing the file name otherwise
3082
 * occurs or some malloced space containing the file name otherwise
3082
 */
3083
 */
3083
 
3084
 
3084
char *BuildFileName (char *name)
3085
char *BuildFileName (char *name)
3085
{
3086
{
3086
    char	*dir = GetVariableAsString (HomeVariableName, FALSE);
3087
    char        *dir = GetVariableAsString (HomeVariableName, FALSE);
3087
    char	*cp;
3088
    char        *cp;
3088
 
3089
 
3089
/* Get some space */
3090
/* Get some space */
3090
 
3091
 
3091
    if ((cp = AllocateMemoryCell (strlen (dir) + strlen (name) + 2))
3092
    if ((cp = AllocateMemoryCell (strlen (dir) + strlen (name) + 2))
3092
		== (char *)NULL)
3093
                == (char *)NULL)
3093
	return null;
3094
        return null;
3094
 
3095
 
3095
/* Addend the directory and a / if the directory does not end in one */
3096
/* Addend the directory and a / if the directory does not end in one */
3096
 
3097
 
3097
    strcpy (cp, dir);
3098
    strcpy (cp, dir);
3098
 
3099
 
3099
    if (!IsPathCharacter (cp[strlen (cp) - 1]))
3100
    if (!IsPathCharacter (cp[strlen (cp) - 1]))
3100
	strcat (cp, DirectorySeparator);
3101
        strcat (cp, DirectorySeparator);
3101
 
3102
 
3102
/* Append the file name */
3103
/* Append the file name */
3103
 
3104
 
3104
    return strcat (cp, name);
3105
    return strcat (cp, name);
3105
}
3106
}
Line 3119... Line 3120...
3119
/* Process setting of SECONDS and RANDOM environment variables */
3120
/* Process setting of SECONDS and RANDOM environment variables */
3120
 
3121
 
3121
static void F_LOCAL SecondAndRandomEV (char *name, long val)
3122
static void F_LOCAL SecondAndRandomEV (char *name, long val)
3122
{
3123
{
3123
    if (!strcmp (name, SecondsVariable) &&
3124
    if (!strcmp (name, SecondsVariable) &&
3124
	!(DisabledVariables & DISABLE_SECONDS))
3125
        !(DisabledVariables & DISABLE_SECONDS))
3125
	ShellStartTime = time ((time_t *)NULL) - val;
3126
        ShellStartTime = time ((time_t *)NULL) - val;
3126
 
3127
 
3127
    else if (!strcmp (name, RandomVariable) &&
3128
    else if (!strcmp (name, RandomVariable) &&
3128
	     !(DisabledVariables & DISABLE_RANDOM))
3129
             !(DisabledVariables & DISABLE_RANDOM))
3129
	srand ((int)val);
3130
        srand ((int)val);
3130
}
3131
}
3131
 
3132
 
3132
/*
3133
/*
3133
 * Set up the Window name.  Give up if it does not work.
3134
 * Set up the Window name.  Give up if it does not work.
3134
 */
3135
 */
3135
 
3136
 
3136
#if (OS_TYPE == OS_OS2)
3137
#if (OS_TYPE == OS_OS2)
3137
void	SetWindowName (char *title)
3138
void    SetWindowName (char *title)
3138
{
3139
{
3139
    HSWITCH		hswitch;
3140
    HSWITCH             hswitch;
3140
    SWCNTRL		swctl;
3141
    SWCNTRL             swctl;
3141
    char		*cp;
3142
    char                *cp;
3142
 
3143
 
3143
    if ((!(hswitch = WinQuerySwitchHandle (0, getpid ()))) ||
3144
    if ((!(hswitch = WinQuerySwitchHandle (0, getpid ()))) ||
3144
	(WinQuerySwitchEntry (hswitch, &swctl)))
3145
        (WinQuerySwitchEntry (hswitch, &swctl)))
3145
	return;
3146
        return;
3146
 
3147
 
3147
    if (title != (char *)NULL)
3148
    if (title != (char *)NULL)
3148
        cp = title;
3149
        cp = title;
3149
 
3150
 
3150
    else if ((DisabledVariables & DISABLE_WINTITLE) ||
3151
    else if ((DisabledVariables & DISABLE_WINTITLE) ||
3151
	     ((cp = GetVariableAsString (WinTitleVariable, FALSE)) == null))
3152
             ((cp = GetVariableAsString (WinTitleVariable, FALSE)) == null))
3152
	cp = DefaultWinTitle;
3153
        cp = DefaultWinTitle;
3153
 
3154
 
3154
    strncpy (swctl.szSwtitle, cp, sizeof (swctl.szSwtitle));
3155
    strncpy (swctl.szSwtitle, cp, sizeof (swctl.szSwtitle));
3155
    swctl.szSwtitle[sizeof (swctl.szSwtitle) - 1] = 0;
3156
    swctl.szSwtitle[sizeof (swctl.szSwtitle) - 1] = 0;
3156
    WinChangeSwitchEntry (hswitch, &swctl);
3157
    WinChangeSwitchEntry (hswitch, &swctl);
3157
}
3158
}
3158
#endif
3159
#endif
3159
 
3160
 
3160
/* NT Version */
3161
/* NT Version */
3161
 
3162
 
3162
#if (OS_TYPE == OS_NT)
3163
#if (OS_TYPE == OS_NT)
3163
void	SetWindowName (char *title)
3164
void    SetWindowName (char *title)
3164
{
3165
{
3165
    char		*cp;
3166
    char                *cp;
3166
 
3167
 
3167
    if (title != (char *)NULL)
3168
    if (title != (char *)NULL)
3168
        cp = title;
3169
        cp = title;
3169
 
3170
 
3170
    else if ((DisabledVariables & DISABLE_WINTITLE) ||
3171
    else if ((DisabledVariables & DISABLE_WINTITLE) ||
3171
	     ((cp = GetVariableAsString (WinTitleVariable, FALSE)) == null))
3172
             ((cp = GetVariableAsString (WinTitleVariable, FALSE)) == null))
3172
	cp = DefaultWinTitle;
3173
        cp = DefaultWinTitle;
3173
 
3174
 
3174
    SetConsoleTitle (cp);
3175
    SetConsoleTitle (cp);
3175
}
3176
}
3176
#endif
3177
#endif
3177
 
3178
 
Line 3180... Line 3181...
3180
 */
3181
 */
3181
 
3182
 
3182
#if (OS_TYPE == OS_OS2)
3183
#if (OS_TYPE == OS_OS2)
3183
static void F_LOCAL CheckForTerminatedProcess (void)
3184
static void F_LOCAL CheckForTerminatedProcess (void)
3184
{
3185
{
3185
    RESULTCODES		rescResults;
3186
    RESULTCODES         rescResults;
3186
    PID			pidProcess;
3187
    PID                 pidProcess;
3187
    char		*s;
3188
    char                *s;
3188
    OSCALL_RET		rc;
3189
    OSCALL_RET          rc;
3189
 
3190
 
3190
#  if (OS_TYPE == OS_OS2)
3191
#  if (OS_TYPE == OS_OS2)
3191
   CheckForSessionEnd ();
3192
   CheckForSessionEnd ();
3192
#  endif
3193
#  endif
3193
 
3194
 
3194
/* Check for tasks terminating */
3195
/* Check for tasks terminating */
3195
 
3196
 
3196
    while (TRUE)
3197
    while (TRUE)
3197
    {
3198
    {
3198
	while ((rc = DosCwait (DCWA_PROCESSTREE, DCWW_NOWAIT, &rescResults,
3199
        while ((rc = DosCwait (DCWA_PROCESSTREE, DCWW_NOWAIT, &rescResults,
3199
			       &pidProcess, 0)) == ERROR_INTERRUPT)
3200
                               &pidProcess, 0)) == ERROR_INTERRUPT)
3200
	    continue;
3201
            continue;
3201
 
3202
 
3202
/* Ignore errors */
3203
/* Ignore errors */
3203
 
3204
 
3204
	if (rc)
3205
        if (rc)
3205
	    return;
3206
            return;
3206
 
3207
 
3207
/* Remove the job */
3208
/* Remove the job */
3208
 
3209
 
3209
	DeleteJob (pidProcess);
3210
        DeleteJob (pidProcess);
3210
 
3211
 
3211
	switch (rescResults.codeTerminate)
3212
        switch (rescResults.codeTerminate)
3212
	{
3213
        {
3213
	    case TC_EXIT:
3214
            case TC_EXIT:
3214
		s = "Normal Exit";
3215
                s = "Normal Exit";
3215
		break;
3216
                break;
3216
 
3217
 
3217
	    case TC_HARDERROR:
3218
            case TC_HARDERROR:
3218
		s = "Hard error";
3219
                s = "Hard error";
3219
		break;
3220
                break;
3220
 
3221
 
3221
	    case TC_TRAP:
3222
            case TC_TRAP:
3222
		s = "Trapped";
3223
                s = "Trapped";
3223
		break;
3224
                break;
3224
 
3225
 
3225
	    case TC_KILLPROCESS:
3226
            case TC_KILLPROCESS:
3226
		s = "Killed";
3227
                s = "Killed";
3227
		break;
3228
                break;
3228
 
3229
 
3229
	    default:
3230
            default:
3230
		s = "Unknown";
3231
                s = "Unknown";
3231
		break;
3232
                break;
3232
 
3233
 
3233
	}
3234
        }
3234
 
3235
 
3235
	fprintf (stderr, "Process %d terminated - %s (%d)\n", pidProcess, s,
3236
        fprintf (stderr, "Process %d terminated - %s (%d)\n", pidProcess, s,
3236
		 rescResults.codeTerminate);
3237
                 rescResults.codeTerminate);
3237
    }
3238
    }
3238
}
3239
}
3239
#endif
3240
#endif
3240
 
3241
 
3241
 
3242
 
Line 3252... Line 3253...
3252
 * Walk the NT job tree looking for terminated processes
3253
 * Walk the NT job tree looking for terminated processes
3253
 */
3254
 */
3254
 
3255
 
3255
static void LookUpJobs (const void *key, VISIT visit, int level)
3256
static void LookUpJobs (const void *key, VISIT visit, int level)
3256
{
3257
{
3257
    JobList	*job = *(JobList **)key;
3258
    JobList     *job = *(JobList **)key;
3258
    HANDLE	hp;
3259
    HANDLE      hp;
3259
    DWORD	res;
3260
    DWORD       res;
3260
    DWORD	ExitCode;
3261
    DWORD       ExitCode;
3261
 
3262
 
3262
    (void) level;
3263
    (void) level;
3263
 
3264
 
3264
    if ((visit == postorder) || (visit == leaf))
3265
    if ((visit == postorder) || (visit == leaf))
3265
    {
3266
    {
3266
	if ((hp = OpenProcess (PROCESS_ALL_ACCESS, (BOOL)TRUE,
3267
        if ((hp = OpenProcess (PROCESS_ALL_ACCESS, (BOOL)TRUE,
3267
			       job->pid)) == NULL)
3268
                               job->pid)) == NULL)
3268
	{
3269
        {
3269
	    PrintWarningMessage ("sh: Cannot open process %d\n%s", job->pid,
3270
            PrintWarningMessage ("sh: Cannot open process %d\n%s", job->pid,
3270
				 GetOSSystemErrorMessage (GetLastError ()));
3271
                                 GetOSSystemErrorMessage (GetLastError ()));
3271
	    DeleteJob (job->pid);
3272
            DeleteJob (job->pid);
3272
	}
3273
        }
3273
 
3274
 
3274
/* Wait for the object to exit */
3275
/* Wait for the object to exit */
3275
 
3276
 
3276
	else if ((res = WaitForSingleObject (hp, 0)) == WAIT_OBJECT_0)
3277
        else if ((res = WaitForSingleObject (hp, 0)) == WAIT_OBJECT_0)
3277
	{
3278
        {
3278
	    DeleteJob (job->pid);
3279
            DeleteJob (job->pid);
3279
 
3280
 
3280
	    if (!GetExitCodeProcess (hp, &ExitCode))
3281
            if (!GetExitCodeProcess (hp, &ExitCode))
3281
		PrintWarningMessage (
3282
                PrintWarningMessage (
3282
			"sh: Cannot get termination code for process %d\n%s",
3283
                        "sh: Cannot get termination code for process %d\n%s",
3283
			job->pid, GetOSSystemErrorMessage (GetLastError ()));
3284
                        job->pid, GetOSSystemErrorMessage (GetLastError ()));
3284
	    else
3285
            else
3285
		fprintf (stderr, "Process %d terminated (%ld)\n", job->pid,
3286
                fprintf (stderr, "Process %d terminated (%ld)\n", job->pid,
3286
			 ExitCode);
3287
                         ExitCode);
3287
	}
3288
        }
3288
 
3289
 
3289
/* Failed?  - error */
3290
/* Failed?  - error */
3290
 
3291
 
3291
	else if (res == WAIT_FAILED)
3292
        else if (res == WAIT_FAILED)
3292
	{
3293
        {
3293
	    PrintWarningMessage ("sh: Cannot wait for process %d\n%s",
3294
            PrintWarningMessage ("sh: Cannot wait for process %d\n%s",
3294
				 job->pid,
3295
                                 job->pid,
3295
				 GetOSSystemErrorMessage (GetLastError ()));
3296
                                 GetOSSystemErrorMessage (GetLastError ()));
3296
 
3297
 
3297
	    DeleteJob (job->pid);
3298
            DeleteJob (job->pid);
3298
	}
3299
        }
3299
 
3300
 
3300
	CloseHandle (hp);
3301
        CloseHandle (hp);
3301
    }
3302
    }
3302
}
3303
}
3303
#endif
3304
#endif
3304
 
3305
 
3305
 
3306
 
Line 3316... Line 3317...
3316
/*
3317
/*
3317
 * Check for end of a Session
3318
 * Check for end of a Session
3318
 */
3319
 */
3319
 
3320
 
3320
#if (OS_TYPE == OS_OS2)
3321
#if (OS_TYPE == OS_OS2)
3321
static void F_LOCAL	CheckForSessionEnd (void)
3322
static void F_LOCAL     CheckForSessionEnd (void)
3322
{
3323
{
3323
    OSCALL_PARAM	DataLength;
3324
    OSCALL_PARAM        DataLength;
3324
    OSCALL_RET		rc;
3325
    OSCALL_RET          rc;
3325
    BYTE		bElemPriority;
3326
    BYTE                bElemPriority;
3326
    struct SessionEnd
3327
    struct SessionEnd
3327
    {
3328
    {
3328
        unsigned short	SessionId;
3329
        unsigned short  SessionId;
3329
	unsigned short	ExitCode;
3330
        unsigned short  ExitCode;
3330
    }			*DataAddress;
3331
    }                   *DataAddress;
3331
 
3332
 
3332
#  if (OS_SIZE == OS_32)
3333
#  if (OS_SIZE == OS_32)
3333
    REQUESTDATA		Request;
3334
    REQUESTDATA         Request;
3334
#  else
3335
#  else
3335
    QUEUERESULT		Request;
3336
    QUEUERESULT         Request;
3336
#  endif
3337
#  endif
3337
 
3338
 
3338
/* Check for sessions terminating */
3339
/* Check for sessions terminating */
3339
 
3340
 
3340
    while ((rc = DosReadQueue (SessionQueueHandler, &Request, &DataLength,
3341
    while ((rc = DosReadQueue (SessionQueueHandler, &Request, &DataLength,
3341
    		       	       (PVOID *)&DataAddress,
3342
                               (PVOID *)&DataAddress,
3342
    		       	       0, DCWW_NOWAIT, &bElemPriority,
3343
                               0, DCWW_NOWAIT, &bElemPriority,
3343
			       SessionQueueSema)) == NO_ERROR)
3344
                               SessionQueueSema)) == NO_ERROR)
3344
    {
3345
    {
3345
	DeleteJobBySession (DataAddress->SessionId);
3346
        DeleteJobBySession (DataAddress->SessionId);
3346
 
3347
 
3347
	fprintf (stderr, "Session %d terminated - Normal Exit (%d)\n",
3348
        fprintf (stderr, "Session %d terminated - Normal Exit (%d)\n",
3348
		 DataAddress->SessionId, DataAddress->ExitCode);
3349
                 DataAddress->SessionId, DataAddress->ExitCode);
3349
 
3350
 
3350
#  if (OS_SIZE == OS_32)
3351
#  if (OS_SIZE == OS_32)
3351
	DosFreeMem (DataAddress);
3352
        DosFreeMem (DataAddress);
3352
#  else
3353
#  else
3353
	DosFreeSeg (SELECTOROF ((DataAddress)));
3354
        DosFreeSeg (SELECTOROF ((DataAddress)));
3354
#  endif
3355
#  endif
3355
    }
3356
    }
3356
}
3357
}
3357
#endif
3358
#endif
3358
 
3359
 
Line 3360... Line 3361...
3360
 * Set up the Parameter Environment variables
3361
 * Set up the Parameter Environment variables
3361
 */
3362
 */
3362
 
3363
 
3363
static void F_LOCAL SetUpParameterEV (int argc, char **argv, char *name)
3364
static void F_LOCAL SetUpParameterEV (int argc, char **argv, char *name)
3364
{
3365
{
3365
    Word_B	*wb = (Word_B *)NULL;
3366
    Word_B      *wb = (Word_B *)NULL;
3366
    char	*Value;
3367
    char        *Value;
3367
    int		i;
3368
    int         i;
3368
 
3369
 
3369
    if ((Value = StringSave (name)) == null)
3370
    if ((Value = StringSave (name)) == null)
3370
    {
3371
    {
3371
	fprintf (stderr, BasicErrorMessage, ShellNameLiteral, Outofmemory1);
3372
        fprintf (stderr, BasicErrorMessage, ShellNameLiteral, Outofmemory1);
3372
	return;
3373
        return;
3373
    }
3374
    }
3374
 
3375
 
3375
    wb = AddParameter (Value, wb, ShellNameLiteral);
3376
    wb = AddParameter (Value, wb, ShellNameLiteral);
3376
 
3377
 
3377
    for (i = 1; i < argc; ++i)
3378
    for (i = 1; i < argc; ++i)
3378
    {
3379
    {
3379
	if ((!AssignVariableFromString (argv[i], (int *)NULL)) &&
3380
        if ((!AssignVariableFromString (argv[i], (int *)NULL)) &&
3380
	    (wb != (Word_B *)NULL))
3381
            (wb != (Word_B *)NULL))
3381
	{
3382
        {
3382
	    if ((Value = StringSave (argv[i])) != null)
3383
            if ((Value = StringSave (argv[i])) != null)
3383
		wb = AddParameter (Value, wb, ShellNameLiteral);
3384
                wb = AddParameter (Value, wb, ShellNameLiteral);
3384
 
3385
 
3385
	    else
3386
            else
3386
	    {
3387
            {
3387
		fprintf (stderr, BasicErrorMessage, ShellNameLiteral,
3388
                fprintf (stderr, BasicErrorMessage, ShellNameLiteral,
3388
			 Outofmemory1);
3389
                         Outofmemory1);
3389
		return;
3390
                return;
3390
	    }
3391
            }
3391
	}
3392
        }
3392
    }
3393
    }
3393
 
3394
 
3394
    if (wb != (Word_B *)NULL)
3395
    if (wb != (Word_B *)NULL)
3395
	wb = AddParameter ((char *)NULL, wb, ShellNameLiteral);
3396
        wb = AddParameter ((char *)NULL, wb, ShellNameLiteral);
3396
}
3397
}
3397
 
3398
 
3398
/*
3399
/*
3399
 * Update the Seconds and Random variables
3400
 * Update the Seconds and Random variables
3400
 */
3401
 */
3401
 
3402
 
3402
void HandleSECONDandRANDOM (void)
3403
void HandleSECONDandRANDOM (void)
3403
{
3404
{
3404
    if (!(DisabledVariables & DISABLE_SECONDS))
3405
    if (!(DisabledVariables & DISABLE_SECONDS))
3405
	LookUpVariable (SecondsVariable, 0, TRUE);
3406
        LookUpVariable (SecondsVariable, 0, TRUE);
3406
 
3407
 
3407
    if (!(DisabledVariables & DISABLE_RANDOM))
3408
    if (!(DisabledVariables & DISABLE_RANDOM))
3408
	LookUpVariable (RandomVariable, 0, TRUE);
3409
        LookUpVariable (RandomVariable, 0, TRUE);
3409
}
3410
}
3410
 
3411
 
3411
/*
3412
/*
3412
 * Set the status of an environment variable
3413
 * Set the status of an environment variable
3413
 */
3414
 */
3414
 
3415
 
3415
void SetVariableStatus (char *name,             /* Variable name        */
3416
void SetVariableStatus (char *name,             /* Variable name        */
3416
			int  flag)		/* New status		*/
3417
                        int  flag)              /* New status           */
3417
{
3418
{
3418
    VariableList	*vp = LookUpVariable (name, 0, TRUE);
3419
    VariableList        *vp = LookUpVariable (name, 0, TRUE);
3419
 
3420
 
3420
    if (IS_VariableFC ((int)*vp->name))	/* not an internal symbol ($# etc) */
3421
    if (IS_VariableFC ((int)*vp->name)) /* not an internal symbol ($# etc) */
3421
	vp->status |= flag;
3422
        vp->status |= flag;
3422
}
3423
}
3423
 
3424
 
3424
/*
3425
/*
3425
 * Array version - only 0 is exported
3426
 * Array version - only 0 is exported
3426
 */
3427
 */
3427
 
3428
 
3428
void SetVariableArrayStatus (char *name,	/* Variable name	*/
3429
void SetVariableArrayStatus (char *name,        /* Variable name        */
3429
			     int  index,	/* Array index		*/
3430
                             int  index,        /* Array index          */
3430
			     int  flag)		/* New status		*/
3431
                             int  flag)         /* New status           */
3431
{
3432
{
3432
    VariableList	*vp = LookUpVariable (name, index, TRUE);
3433
    VariableList        *vp = LookUpVariable (name, index, TRUE);
3433
 
3434
 
3434
    if (IS_VariableFC ((int)*vp->name))	/* not an internal symbol ($# etc) */
3435
    if (IS_VariableFC ((int)*vp->name)) /* not an internal symbol ($# etc) */
3435
    {
3436
    {
3436
	vp->status |= flag;
3437
        vp->status |= flag;
3437
 
3438
 
3438
	if (index)
3439
        if (index)
3439
	    vp->status &= ~STATUS_EXPORT;
3440
            vp->status &= ~STATUS_EXPORT;
3440
    }
3441
    }
3441
}
3442
}
3442
 
3443
 
3443
/*
3444
/*
3444
 * Set the status of an environment variable
3445
 * Set the status of an environment variable
3445
 */
3446
 */
3446
 
3447
 
3447
void ClearVariableStatus (char *name, int flag)
3448
void ClearVariableStatus (char *name, int flag)
3448
{
3449
{
3449
    VariableList	*vp = LookUpVariable (name, 0, TRUE);
3450
    VariableList        *vp = LookUpVariable (name, 0, TRUE);
3450
 
3451
 
3451
    if (IS_VariableFC ((int)*vp->name))	/* not an internal symbol ($# etc) */
3452
    if (IS_VariableFC ((int)*vp->name)) /* not an internal symbol ($# etc) */
3452
	vp->status &= ~flag;
3453
        vp->status &= ~flag;
3453
}
3454
}
3454
 
3455
 
3455
/*
3456
/*
3456
 * Check allowed to set variable
3457
 * Check allowed to set variable
3457
 */
3458
 */
3458
 
3459
 
3459
static bool F_LOCAL AllowedToSetVariable (VariableList *vp)
3460
static bool F_LOCAL AllowedToSetVariable (VariableList *vp)
3460
{
3461
{
3461
    if (vp->status & STATUS_READONLY)
3462
    if (vp->status & STATUS_READONLY)
3462
    {
3463
    {
3463
	ShellErrorMessage (LIT_2Strings, vp->name, LIT_IsReadonly);
3464
        ShellErrorMessage (LIT_2Strings, vp->name, LIT_IsReadonly);
3464
	return FALSE;
3465
        return FALSE;
3465
    }
3466
    }
3466
 
3467
 
3467
/* Check for $PATH, $SHELL or $ENV reset in restricted shell */
3468
/* Check for $PATH, $SHELL or $ENV reset in restricted shell */
3468
 
3469
 
3469
    if ((!strcmp (vp->name, PathLiteral) || !strcmp (vp->name, ENVVariable) ||
3470
    if ((!strcmp (vp->name, PathLiteral) || !strcmp (vp->name, ENVVariable) ||
3470
	 !strcmp (vp->name, ShellVariableName)) &&
3471
         !strcmp (vp->name, ShellVariableName)) &&
3471
	CheckForRestrictedShell (PathLiteral))
3472
        CheckForRestrictedShell (PathLiteral))
3472
	return FALSE;
3473
        return FALSE;
3473
 
3474
 
3474
    return TRUE;
3475
    return TRUE;
3475
}
3476
}
3476
 
3477
 
3477
/*
3478
/*
Line 3487... Line 3488...
3487
 * Array index version
3488
 * Array index version
3488
 */
3489
 */
3489
 
3490
 
3490
void SetVariableArrayFromString (char *name, int Index, char *val)
3491
void SetVariableArrayFromString (char *name, int Index, char *val)
3491
{
3492
{
3492
    VariableList	*vp = LookUpVariable (name, Index, TRUE);
3493
    VariableList        *vp = LookUpVariable (name, Index, TRUE);
3493
    char		*xp = null;
3494
    char                *xp = null;
3494
    long		nval;
3495
    long                nval;
3495
 
3496
 
3496
/* Check if allowed to set variable */
3497
/* Check if allowed to set variable */
3497
 
3498
 
3498
    if (!AllowedToSetVariable (vp))
3499
    if (!AllowedToSetVariable (vp))
3499
	return;
3500
        return;
3500
 
3501
 
3501
/* If we change the PATH to a new value, we need to untrack some aliases */
3502
/* If we change the PATH to a new value, we need to untrack some aliases */
3502
 
3503
 
3503
    if (!strcmp (name, PathLiteral) && strcmp (vp->value, val))
3504
    if (!strcmp (name, PathLiteral) && strcmp (vp->value, val))
3504
	UnTrackAllAliases ();
3505
        UnTrackAllAliases ();
3505
 
3506
 
3506
    CheckOPTIND (name, atol (val));
3507
    CheckOPTIND (name, atol (val));
3507
 
3508
 
3508
/* Save the new value */
3509
/* Save the new value */
3509
 
3510
 
3510
    if ((!(vp->status & STATUS_INTEGER)) && (val != null) && strlen (val) &&
3511
    if ((!(vp->status & STATUS_INTEGER)) && (val != null) && strlen (val) &&
3511
	((xp = StringSave (val = SuppressSpacesZeros (vp, val))) == null))
3512
        ((xp = StringSave (val = SuppressSpacesZeros (vp, val))) == null))
3512
	    return;
3513
            return;
3513
 
3514
 
3514
/* Free the old value if appropriate */
3515
/* Free the old value if appropriate */
3515
 
3516
 
3516
    if (vp->value != null)
3517
    if (vp->value != null)
3517
	ReleaseMemoryCell ((void *)vp->value);
3518
        ReleaseMemoryCell ((void *)vp->value);
3518
 
3519
 
3519
    vp->value = null;
3520
    vp->value = null;
3520
 
3521
 
3521
/* String value? */
3522
/* String value? */
3522
 
3523
 
3523
    if (!(vp->status & STATUS_INTEGER))
3524
    if (!(vp->status & STATUS_INTEGER))
3524
    {
3525
    {
3525
	vp->value = xp;
3526
        vp->value = xp;
3526
 
3527
 
3527
	if (!vp->width)
3528
        if (!vp->width)
3528
	    vp->width = strlen (val);
3529
            vp->width = strlen (val);
3529
    }
3530
    }
3530
 
3531
 
3531
/* No - Number value */
3532
/* No - Number value */
3532
 
3533
 
3533
    else if (!ValidMathsExpression (val, &nval))
3534
    else if (!ValidMathsExpression (val, &nval))
3534
    {
3535
    {
3535
	SecondAndRandomEV (name, nval);
3536
        SecondAndRandomEV (name, nval);
3536
	SetUpANumericValue (vp, nval, -1);
3537
        SetUpANumericValue (vp, nval, -1);
3537
    }
3538
    }
3538
 
3539
 
3539
 
3540
 
3540
/* Check to see if it should be exported */
3541
/* Check to see if it should be exported */
3541
 
3542
 
3542
    if (FL_TEST (FLAG_ALL_EXPORT))
3543
    if (FL_TEST (FLAG_ALL_EXPORT))
3543
	vp->status |= STATUS_EXPORT;
3544
        vp->status |= STATUS_EXPORT;
3544
 
3545
 
3545
/* Convert UNIX to DOS for PATH variable */
3546
/* Convert UNIX to DOS for PATH variable */
3546
 
3547
 
3547
    if (!strcmp (name, PathLiteral))
3548
    if (!strcmp (name, PathLiteral))
3548
	ConvertUnixPathToMSDOS (GetVariableAsString (PathLiteral, FALSE));
3549
        ConvertUnixPathToMSDOS (GetVariableAsString (PathLiteral, FALSE));
3549
 
3550
 
3550
    else if (!strcmp (name, CDPathLiteral))
3551
    else if (!strcmp (name, CDPathLiteral))
3551
	ConvertUnixPathToMSDOS (GetVariableAsString (CDPathLiteral, FALSE));
3552
        ConvertUnixPathToMSDOS (GetVariableAsString (CDPathLiteral, FALSE));
3552
 
3553
 
3553
    else if (!strcmp (name, PathExtsLiteral))
3554
    else if (!strcmp (name, PathExtsLiteral))
3554
	BuildExtensionLists ();
3555
        BuildExtensionLists ();
3555
 
3556
 
3556
/* Set up IFS characters */
3557
/* Set up IFS characters */
3557
 
3558
 
3558
    else if (!strcmp (name, IFS))
3559
    else if (!strcmp (name, IFS))
3559
	SetCharacterTypes (val, C_IFS);
3560
        SetCharacterTypes (val, C_IFS);
3560
 
3561
 
3561
/* Check for title change */
3562
/* Check for title change */
3562
 
3563
 
3563
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
3564
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
3564
    else if (!strcmp (name, FCEditVariable))
3565
    else if (!strcmp (name, FCEditVariable))
3565
	SetEditorMode (val);
3566
        SetEditorMode (val);
3566
 
3567
 
3567
    else if (!strcmp (name, EditorVariable))
3568
    else if (!strcmp (name, EditorVariable))
3568
	SetEditorMode (val);
3569
        SetEditorMode (val);
3569
 
3570
 
3570
    else if (!strcmp (name, VisualVariable))
3571
    else if (!strcmp (name, VisualVariable))
3571
	SetEditorMode (val);
3572
        SetEditorMode (val);
3572
#endif
3573
#endif
3573
 
3574
 
3574
#if (OS_TYPE != OS_DOS)
3575
#if (OS_TYPE != OS_DOS)
3575
    else if ((!(DisabledVariables & DISABLE_WINTITLE)) &&
3576
    else if ((!(DisabledVariables & DISABLE_WINTITLE)) &&
3576
	     (!strcmp (name, WinTitleVariable)))
3577
             (!strcmp (name, WinTitleVariable)))
3577
	SetWindowName ((char *)NULL);
3578
        SetWindowName ((char *)NULL);
3578
#endif
3579
#endif
3579
}
3580
}
3580
 
3581
 
3581
 
3582
 
3582
/*
3583
/*
Line 3591... Line 3592...
3591
 
3592
 
3592
/* Array version */
3593
/* Array version */
3593
 
3594
 
3594
void SetVariableArrayFromNumeric (char *name, int Index, long value)
3595
void SetVariableArrayFromNumeric (char *name, int Index, long value)
3595
{
3596
{
3596
    VariableList	*vp = LookUpVariable (name, Index, TRUE);
3597
    VariableList        *vp = LookUpVariable (name, Index, TRUE);
3597
    char		NumericBuffer[20];
3598
    char                NumericBuffer[20];
3598
 
3599
 
3599
/* Check if allowed to set variable */
3600
/* Check if allowed to set variable */
3600
 
3601
 
3601
    if (!AllowedToSetVariable (vp))
3602
    if (!AllowedToSetVariable (vp))
3602
	return;
3603
        return;
3603
 
3604
 
3604
    CheckOPTIND (name, value);
3605
    CheckOPTIND (name, value);
3605
 
3606
 
3606
    if (!(vp->status & STATUS_INTEGER))
3607
    if (!(vp->status & STATUS_INTEGER))
3607
    {
3608
    {
3608
	sprintf (NumericBuffer, "%ld", value);
3609
        sprintf (NumericBuffer, "%ld", value);
3609
	SetVariableFromString (name, NumericBuffer);
3610
        SetVariableFromString (name, NumericBuffer);
3610
    }
3611
    }
3611
 
3612
 
3612
/* Save the integer value */
3613
/* Save the integer value */
3613
 
3614
 
3614
    else
3615
    else
3615
	SetUpANumericValue (vp, value, -1);
3616
        SetUpANumericValue (vp, value, -1);
3616
 
3617
 
3617
    SecondAndRandomEV (name, value);
3618
    SecondAndRandomEV (name, value);
3618
}
3619
}
3619
 
3620
 
3620
 
3621
 
Line 3630... Line 3631...
3630
 
3631
 
3631
/* Array version */
3632
/* Array version */
3632
 
3633
 
3633
long GetVariableArrayAsNumeric (char *name, int Index)
3634
long GetVariableArrayAsNumeric (char *name, int Index)
3634
{
3635
{
3635
    VariableList	*vp = LookUpVariable (name, Index, FALSE);
3636
    VariableList        *vp = LookUpVariable (name, Index, FALSE);
3636
 
3637
 
3637
    if (vp->status & STATUS_INTEGER)
3638
    if (vp->status & STATUS_INTEGER)
3638
	return vp->nvalue;
3639
        return vp->nvalue;
3639
 
3640
 
3640
    else
3641
    else
3641
	return atol (vp->value);
3642
        return atol (vp->value);
3642
}
3643
}
3643
 
3644
 
3644
 
3645
 
3645
/*
3646
/*
3646
 * Get variable as a formatted string
3647
 * Get variable as a formatted string
Line 3656... Line 3657...
3656
 * Indexed version
3657
 * Indexed version
3657
 */
3658
 */
3658
 
3659
 
3659
char *GetVariableArrayAsString (char *name, int Index, bool Format)
3660
char *GetVariableArrayAsString (char *name, int Index, bool Format)
3660
{
3661
{
3661
    VariableList	*vp = LookUpVariable (name, Index, FALSE);
3662
    VariableList        *vp = LookUpVariable (name, Index, FALSE);
3662
    char		*Value = vp->value;
3663
    char                *Value = vp->value;
3663
    char		*xp;
3664
    char                *xp;
3664
    size_t		len;
3665
    size_t              len;
3665
    char		*NumericBuffer;
3666
    char                *NumericBuffer;
3666
 
3667
 
3667
    if (vp->status & STATUS_INTEGER)
3668
    if (vp->status & STATUS_INTEGER)
3668
    {
3669
    {
3669
	if ((NumericBuffer = GetAllocatedSpace (40)) == (char *)NULL)
3670
        if ((NumericBuffer = GetAllocatedSpace (40)) == (char *)NULL)
3670
	    return null;
3671
            return null;
3671
 
3672
 
3672
	if (vp->base != 10)
3673
        if (vp->base != 10)
3673
	{
3674
        {
3674
	    sprintf (NumericBuffer, LIT_BNumber, vp->base);
3675
            sprintf (NumericBuffer, LIT_BNumber, vp->base);
3675
	    xp = NumericBuffer + strlen (NumericBuffer);
3676
            xp = NumericBuffer + strlen (NumericBuffer);
3676
	}
3677
        }
3677
 
3678
 
3678
	else
3679
        else
3679
	    xp = NumericBuffer;
3680
            xp = NumericBuffer;
3680
 
3681
 
3681
        ltoa (vp->nvalue, xp, vp->base);
3682
        ltoa (vp->nvalue, xp, vp->base);
3682
	return NumericBuffer;
3683
        return NumericBuffer;
3683
    }
3684
    }
3684
 
3685
 
3685
/* Handle a string variable, if no formating required, return it */
3686
/* Handle a string variable, if no formating required, return it */
3686
 
3687
 
3687
    if (!Format)
3688
    if (!Format)
3688
	return vp->value;
3689
        return vp->value;
3689
 
3690
 
3690
/* Left justify ? */
3691
/* Left justify ? */
3691
 
3692
 
3692
    if (vp->status & STATUS_LEFT_JUSTIFY)
3693
    if (vp->status & STATUS_LEFT_JUSTIFY)
3693
    {
3694
    {
3694
	xp = SuppressSpacesZeros (vp, Value);
3695
        xp = SuppressSpacesZeros (vp, Value);
3695
 
3696
 
3696
	if ((Value = GetAllocatedSpace (vp->width + 1)) == (char *)NULL)
3697
        if ((Value = GetAllocatedSpace (vp->width + 1)) == (char *)NULL)
3697
	    return null;
3698
            return null;
3698
 
3699
 
3699
	memset (Value, CHAR_SPACE, vp->width);
3700
        memset (Value, CHAR_SPACE, vp->width);
3700
	Value[vp->width] = 0;
3701
        Value[vp->width] = 0;
3701
 
3702
 
3702
	if ((len = strlen (xp)) > vp->width)
3703
        if ((len = strlen (xp)) > vp->width)
3703
	    len = vp->width;
3704
            len = vp->width;
3704
 
3705
 
3705
	memcpy (Value, xp, len);
3706
        memcpy (Value, xp, len);
3706
    }
3707
    }
3707
 
3708
 
3708
/* Right justify ? */
3709
/* Right justify ? */
3709
 
3710
 
3710
    else if (vp->status & (STATUS_RIGHT_JUSTIFY | STATUS_ZERO_FILL))
3711
    else if (vp->status & (STATUS_RIGHT_JUSTIFY | STATUS_ZERO_FILL))
3711
    {
3712
    {
3712
	if ((xp = GetAllocatedSpace (vp->width + 1)) == (char *)NULL)
3713
        if ((xp = GetAllocatedSpace (vp->width + 1)) == (char *)NULL)
3713
	    return null;
3714
            return null;
3714
 
3715
 
3715
	if ((len = strlen (Value)) < vp->width)
3716
        if ((len = strlen (Value)) < vp->width)
3716
	{
3717
        {
3717
	    memset (xp, ((vp->status & STATUS_ZERO_FILL) &&
3718
            memset (xp, ((vp->status & STATUS_ZERO_FILL) &&
3718
			 (isdigit (*Value))) ? '0' : CHAR_SPACE, vp->width);
3719
                         (isdigit (*Value))) ? '0' : CHAR_SPACE, vp->width);
3719
 
3720
 
3720
	    memcpy (xp + (vp->width - len), Value, len);
3721
            memcpy (xp + (vp->width - len), Value, len);
3721
	}
3722
        }
3722
 
3723
 
3723
	else
3724
        else
3724
	    memcpy (xp, Value + vp->width - len, vp->width);
3725
            memcpy (xp, Value + vp->width - len, vp->width);
3725
 
3726
 
3726
	*(xp + vp->width) = 0;
3727
        *(xp + vp->width) = 0;
3727
	Value = xp;
3728
        Value = xp;
3728
    }
3729
    }
3729
 
3730
 
3730
/* Handle upper and lower case conversions */
3731
/* Handle upper and lower case conversions */
3731
 
3732
 
3732
    if (vp->status & STATUS_LOWER_CASE)
3733
    if (vp->status & STATUS_LOWER_CASE)
3733
	Value = strlwr (StringCopy (Value));
3734
        Value = strlwr (StringCopy (Value));
3734
 
3735
 
3735
    if (vp->status & STATUS_UPPER_CASE)
3736
    if (vp->status & STATUS_UPPER_CASE)
3736
	Value = strupr (StringCopy (Value));
3737
        Value = strupr (StringCopy (Value));
3737
 
3738
 
3738
    return Value;
3739
    return Value;
3739
}
3740
}
3740
 
3741
 
3741
 
3742
 
Line 3747... Line 3748...
3747
{
3748
{
3748
    vp->nvalue = value;
3749
    vp->nvalue = value;
3749
    vp->status |= STATUS_INTEGER;
3750
    vp->status |= STATUS_INTEGER;
3750
 
3751
 
3751
    if (vp->base == 0)
3752
    if (vp->base == 0)
3752
	vp->base = (base > 1) ? base
3753
        vp->base = (base > 1) ? base
3753
			      : ((LastNumberBase != -1) ? LastNumberBase
3754
                              : ((LastNumberBase != -1) ? LastNumberBase
3754
							: 10);
3755
                                                        : 10);
3755
 
3756
 
3756
    if (vp->value != null)
3757
    if (vp->value != null)
3757
	ReleaseMemoryCell ((void *)vp->value);
3758
        ReleaseMemoryCell ((void *)vp->value);
3758
 
3759
 
3759
    vp->value = null;
3760
    vp->value = null;
3760
}
3761
}
3761
 
3762
 
3762
 
3763
 
Line 3766... Line 3767...
3766
 
3767
 
3767
static char * F_LOCAL SuppressSpacesZeros (VariableList *vp, char *value)
3768
static char * F_LOCAL SuppressSpacesZeros (VariableList *vp, char *value)
3768
{
3769
{
3769
    if (vp->status & STATUS_LEFT_JUSTIFY)
3770
    if (vp->status & STATUS_LEFT_JUSTIFY)
3770
    {
3771
    {
3771
	while (*value == CHAR_SPACE)
3772
        while (*value == CHAR_SPACE)
3772
	    value++;
3773
            value++;
3773
 
3774
 
3774
	if (vp->status & STATUS_ZERO_FILL)
3775
        if (vp->status & STATUS_ZERO_FILL)
3775
	{
3776
        {
3776
	    while (*value == '0')
3777
            while (*value == '0')
3777
		value++;
3778
                value++;
3778
	}
3779
        }
3779
    }
3780
    }
3780
 
3781
 
3781
    return value;
3782
    return value;
3782
}
3783
}
3783
 
3784
 
Line 3787... Line 3788...
3787
 */
3788
 */
3788
 
3789
 
3789
static void F_LOCAL CheckOPTIND (char *name, long value)
3790
static void F_LOCAL CheckOPTIND (char *name, long value)
3790
{
3791
{
3791
    if ((value == 1) && (!(DisabledVariables & DISABLE_OPTIND)) &&
3792
    if ((value == 1) && (!(DisabledVariables & DISABLE_OPTIND)) &&
3792
	(strcmp (OptIndVariable, name) == 0))
3793
        (strcmp (OptIndVariable, name) == 0))
3793
	ResetGetoptsValues (FALSE);
3794
        ResetGetoptsValues (FALSE);
3794
}
3795
}
3795
 
3796
 
3796
 
3797
 
3797
/*
3798
/*
3798
 * Initialise the Integer variables by creating them
3799
 * Initialise the Integer variables by creating them
3799
 */
3800
 */
3800
 
3801
 
3801
static void F_LOCAL CreateIntegerVariables (void)
3802
static void F_LOCAL CreateIntegerVariables (void)
3802
{
3803
{
3803
    struct ShellVariablesInit	*wp = InitialiseShellVariables;
3804
    struct ShellVariablesInit   *wp = InitialiseShellVariables;
3804
 
3805
 
3805
    while  (wp->Name != (char *)NULL)
3806
    while  (wp->Name != (char *)NULL)
3806
    {
3807
    {
3807
	SetVariableStatus (wp->Name, wp->Status);
3808
        SetVariableStatus (wp->Name, wp->Status);
3808
 
3809
 
3809
	if (wp->CValue != null)
3810
        if (wp->CValue != null)
3810
	    SetVariableFromString (wp->Name, wp->CValue);
3811
            SetVariableFromString (wp->Name, wp->CValue);
3811
 
3812
 
3812
	wp++;
3813
        wp++;
3813
    }
3814
    }
3814
}
3815
}
3815
 
3816
 
3816
 
3817
 
3817
/*
3818
/*
Line 3840... Line 3841...
3840
 */
3841
 */
3841
 
3842
 
3842
#if (OS_TYPE == OS_OS2)
3843
#if (OS_TYPE == OS_OS2)
3843
static void F_LOCAL CreateTerminationQueues (void)
3844
static void F_LOCAL CreateTerminationQueues (void)
3844
{
3845
{
3845
    int			count = 0;
3846
    int                 count = 0;
3846
    static char		Name[25];
3847
    static char         Name[25];
3847
    OSCALL_RET		rc;
3848
    OSCALL_RET          rc;
3848
#  if (OS_SIZE == OS_32)
3849
#  if (OS_SIZE == OS_32)
3849
    LONG		ReqCount = 0;		/* Increment		*/
3850
    LONG                ReqCount = 0;           /* Increment            */
3850
    ULONG		CurMaxFH;		/* Available File handlers */
3851
    ULONG               CurMaxFH;               /* Available File handlers */
3851
 
3852
 
3852
    DosSetRelMaxFH (&ReqCount, &CurMaxFH);
3853
    DosSetRelMaxFH (&ReqCount, &CurMaxFH);
3853
    MaxNumberofFDs = min (CurMaxFH, 32 + FDBASE);
3854
    MaxNumberofFDs = min (CurMaxFH, 32 + FDBASE);
3854
#  endif
3855
#  endif
3855
 
3856
 
Line 3862... Line 3863...
3862
#  else
3863
#  else
3863
        sprintf (Name, "\\SEM\\SHELL\\%.5d", count++);
3864
        sprintf (Name, "\\SEM\\SHELL\\%.5d", count++);
3864
#  endif
3865
#  endif
3865
 
3866
 
3866
#  if (OS_SIZE == OS_32)
3867
#  if (OS_SIZE == OS_32)
3867
	if ((rc = DosCreateEventSem (Name, &SessionQueueSema,
3868
        if ((rc = DosCreateEventSem (Name, &SessionQueueSema,
3868
				     DC_SEM_SHARED, TRUE)) == NO_ERROR)
3869
                                     DC_SEM_SHARED, TRUE)) == NO_ERROR)
3869
	    break;
3870
            break;
3870
#  else
3871
#  else
3871
	if ((rc = DosCreateSem (CSEM_PUBLIC, &SessionQueueSema,
3872
        if ((rc = DosCreateSem (CSEM_PUBLIC, &SessionQueueSema,
3872
				Name)) == NO_ERROR)
3873
                                Name)) == NO_ERROR)
3873
	{
3874
        {
3874
	    DosSemClear (SessionQueueSema);
3875
            DosSemClear (SessionQueueSema);
3875
	    break;
3876
            break;
3876
	}
3877
        }
3877
#  endif
3878
#  endif
3878
 
3879
 
3879
/* Check for error */
3880
/* Check for error */
3880
 
3881
 
3881
#  if (OS_SIZE == OS_32)
3882
#  if (OS_SIZE == OS_32)
3882
	if (rc != ERROR_DUPLICATE_NAME)
3883
        if (rc != ERROR_DUPLICATE_NAME)
3883
#  else
3884
#  else
3884
	if (rc != ERROR_ALREADY_EXISTS)
3885
        if (rc != ERROR_ALREADY_EXISTS)
3885
#  endif
3886
#  endif
3886
	{
3887
        {
3887
	    SessionQueueSema = 0;
3888
            SessionQueueSema = 0;
3888
	    PrintErrorMessage ("DosCreateSem: Cannot create semaphore\n%s",
3889
            PrintErrorMessage ("DosCreateSem: Cannot create semaphore\n%s",
3889
	    		       GetOSSystemErrorMessage (rc));
3890
                               GetOSSystemErrorMessage (rc));
3890
	}
3891
        }
3891
    }
3892
    }
3892
 
3893
 
3893
/* Create the queue */
3894
/* Create the queue */
3894
 
3895
 
3895
    count = 0;
3896
    count = 0;
Line 3900... Line 3901...
3900
        sprintf (Name, "\\QUEUES\\SHELL\\%.5d", count++);
3901
        sprintf (Name, "\\QUEUES\\SHELL\\%.5d", count++);
3901
#  else
3902
#  else
3902
        sprintf (Name, "\\QUEUES\\SHQ%.5d", count++);
3903
        sprintf (Name, "\\QUEUES\\SHQ%.5d", count++);
3903
#  endif
3904
#  endif
3904
 
3905
 
3905
	if ((rc = DosCreateQueue (&SessionQueueHandler,
3906
        if ((rc = DosCreateQueue (&SessionQueueHandler,
3906
#ifdef QUE_CONVERT_ADDRESS
3907
#ifdef QUE_CONVERT_ADDRESS
3907
				  QUE_FIFO | QUE_CONVERT_ADDRESS,
3908
                                  QUE_FIFO | QUE_CONVERT_ADDRESS,
3908
#else
3909
#else
3909
				  QUE_FIFO,
3910
                                  QUE_FIFO,
3910
#endif
3911
#endif
3911
 
3912
 
3912
				  Name)) == NO_ERROR)
3913
                                  Name)) == NO_ERROR)
3913
	    break;
3914
            break;
3914
 
3915
 
3915
/* Check for error */
3916
/* Check for error */
3916
 
3917
 
3917
	if (rc != ERROR_QUE_DUPLICATE)
3918
        if (rc != ERROR_QUE_DUPLICATE)
3918
	{
3919
        {
3919
	    SessionQueueHandler = 0;
3920
            SessionQueueHandler = 0;
3920
	    PrintErrorMessage ("DosCreateQueue: Cannot create queue\n%s",
3921
            PrintErrorMessage ("DosCreateQueue: Cannot create queue\n%s",
3921
	    		       GetOSSystemErrorMessage (rc));
3922
                               GetOSSystemErrorMessage (rc));
3922
	}
3923
        }
3923
    }
3924
    }
3924
 
3925
 
3925
    SessionEndQName = Name;
3926
    SessionEndQName = Name;
3926
}
3927
}
3927
#endif
3928
#endif
Line 3931... Line 3932...
3931
 */
3932
 */
3932
 
3933
 
3933
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
3934
#if defined (FLAGS_EMACS) || defined (FLAGS_VI) || defined (FLAGS_GMACS)
3934
static void F_LOCAL SetEditorMode (char *ed)
3935
static void F_LOCAL SetEditorMode (char *ed)
3935
{
3936
{
3936
    char	*rcp;
3937
    char        *rcp;
3937
 
3938
 
3938
    if ((rcp = strrchr (ed, '/')) != (char *)NULL)
3939
    if ((rcp = strrchr (ed, '/')) != (char *)NULL)
3939
	ed = rcp + 1;
3940
        ed = rcp + 1;
3940
 
3941
 
3941
#  ifdef FLAGS_EMACS
3942
#  ifdef FLAGS_EMACS
3942
    if (strstr (ed, "emacs"))
3943
    if (strstr (ed, "emacs"))
3943
    {
3944
    {
3944
	ShellGlobalFlags &= ~FLAGS_EDITORS;
3945
        ShellGlobalFlags &= ~FLAGS_EDITORS;
3945
	ShellGlobalFlags |= FLAGS_EMACS;
3946
        ShellGlobalFlags |= FLAGS_EMACS;
3946
    }
3947
    }
3947
#  endif
3948
#  endif
3948
 
3949
 
3949
#  ifdef FLAGS_VI
3950
#  ifdef FLAGS_VI
3950
    if (strstr (ed, "vi"))
3951
    if (strstr (ed, "vi"))
3951
    {
3952
    {
3952
	ShellGlobalFlags &= ~FLAGS_EDITORS;
3953
        ShellGlobalFlags &= ~FLAGS_EDITORS;
3953
	ShellGlobalFlags |= FLAGS_VI;
3954
        ShellGlobalFlags |= FLAGS_VI;
3954
    }
3955
    }
3955
#  endif
3956
#  endif
3956
 
3957
 
3957
#  ifdef FLAGS_GMACS
3958
#  ifdef FLAGS_GMACS
3958
    if (strstr (ed, "gmacs"))
3959
    if (strstr (ed, "gmacs"))
3959
    {
3960
    {
3960
	ShellGlobalFlags &= ~FLAGS_EDITORS;
3961
        ShellGlobalFlags &= ~FLAGS_EDITORS;
3961
	ShellGlobalFlags |= FLAGS_GMACS;
3962
        ShellGlobalFlags |= FLAGS_GMACS;
3962
    }
3963
    }
3963
#  endif
3964
#  endif
3964
}
3965
}
3965
#endif
3966
#endif
-
 
3967
 
-
 
3968
/*----------------------------------------------------------------------------
-
 
3969
** FUNCTION           : localRealloc
-
 
3970
**
-
 
3971
** DESCRIPTION        : A local replacement for realloc, except it avoids
-
 
3972
**                      compiler warnings
-
 
3973
**
-
 
3974
**
-
 
3975
** INPUTS             : ptr     - ref to current memory
-
 
3976
**                      size    - new size required
-
 
3977
**
-
 
3978
** RETURNS            : Ref to new memory or NULL on error
-
 
3979
**
-
 
3980
----------------------------------------------------------------------------*/
-
 
3981
 
-
 
3982
void *localRealloc(void *ptr, size_t size)
-
 
3983
{
-
 
3984
    void *rv = realloc(ptr, size);
-
 
3985
    if (! rv)
-
 
3986
    {
-
 
3987
        free( ptr);
-
 
3988
        return 0;
-
 
3989
    }
-
 
3990
 
-
 
3991
    return rv;
-
 
3992
}