From pa.dec.com!shlump.nac.dec.com!news.crl.dec.com!deccrl!bloom-beacon!snorkelwacker.mit.edu!apple!agate!ucbvax!unisoft!uunet!sparky!kent Sat Feb 2 14:36:39 PST 1991 Article: 2024 of comp.sources.misc Path: pa.dec.com!shlump.nac.dec.com!news.crl.dec.com!deccrl!bloom-beacon!snorkelwacker.mit.edu!apple!agate!ucbvax!unisoft!uunet!sparky!kent From: istewart@datlog.co.uk (Ian Stewartson) Newsgroups: comp.sources.misc Subject: v16i078: MSDOS Shell (sh) Implementation 1.6.4, Patch01/02 Message-ID: <1991Jan16.195036.11473@sparky.IMD.Sterling.COM> Date: 16 Jan 91 19:50:36 GMT Sender: kent@sparky.IMD.Sterling.COM (Kent Landfield) Organization: Sterling Software, IMD Lines: 1453 Approved: kent@sparky.imd.sterling.com X-Checksum-Snefru: 73adc354 f7a3fd6f c609dbbb 9f096918 Submitted-by: istewart@datlog.co.uk (Ian Stewartson) Posting-number: Volume 16, Issue 78 Archive-name: ms_sh-1.6/patch01 Patch-To: ms_sh-1.6: Volume 12, Issue 19-26 1.6.4 of the MSDOS Shell. Unfortunately, I'm tied up with real work at the moment, so this is likely to be the last upgrade for a couple of months. It fixes one or two bugs and provides some new feature from the Korn/POSIX shell (see release notes). Regards, Ian Stewartson Data Logic ------- #!/bin/sh # This is a shell archive (shar 3.46) # made 12/24/1990 18:01 UTC by istewart@dlvax2 # Source directory /usr/proj1/ssd/istewart/src/shell # # existing files will NOT be overwritten unless -c is specified # # This is part 1 of a multipart archive # do not concatenate these parts, unpack them in order with /bin/sh # # This shar contains: # length mode name # ------ ---------- ------------------------------------------ # 63614 -rw-r--r-- Patch1.6.4 # if test -r _shar_seq_.tmp; then echo 'Must unpack archives in sequence!' echo Please unpack part `cat _shar_seq_.tmp` next exit 1 fi # ============= Patch1.6.4 ============== if test -f 'Patch1.6.4' -a X"$1" != X"-c"; then echo 'x - skipping Patch1.6.4 (File already exists)' rm -f _shar_wnt_.tmp else > _shar_wnt_.tmp echo 'x - extracting Patch1.6.4 (Text)' sed 's/^X//' << 'SHAR_EOF' > 'Patch1.6.4' && Index: Notes1.6 *** ../sh16.3/Notes1.6 Fri Aug 17 21:29:59 1990 --- Notes1.6 Tue Nov 6 20:47:31 1990 *************** *** 1,4 **** ! Version 1.6.3 Release Notes: X X Note: Release 1.6.1 did occur to comp.ibm.pc.binaries. However, the X transmission was corrupt and by the time I was notified (the moderator having --- 1,4 ---- ! Version 1.6.4 Release Notes: X X Note: Release 1.6.1 did occur to comp.ibm.pc.binaries. However, the X transmission was corrupt and by the time I was notified (the moderator having *************** *** 41,47 **** X The code has been fixed to cope with DOS 4. X 21. A bug in the processing of functions has been fixed which caused X the shell to crash or hang has been fixed. ! X The following enhancements have been made: X X 1. /dev/tty and /dev/null are mapped to /dev/con and /dev/nul internally --- 41,48 ---- X The code has been fixed to cope with DOS 4. X 21. A bug in the processing of functions has been fixed which caused X the shell to crash or hang has been fixed. ! 22. A bug in the function code that caused case functions to hang ! has been fixed. X The following enhancements have been made: X X 1. /dev/tty and /dev/null are mapped to /dev/con and /dev/nul internally *************** *** 78,83 **** --- 79,87 ---- X 20. The POSIX variable substitution command ${#name} to give the X string length has been implemented. X 21. The POSIX I/O option <> has been implemented. + 22. The POSIX I/O options ${#*%} and ~ have been implemented. + 23. The builtin command command has been implemented. + 24. The source for stdargv.c has been modified to work under OS/2 X X The following enhancements/bugs remain outstanding: X *************** *** 93,98 **** --- 97,108 ---- X processing of escape characters. The shell uses the 8-bit to X mark escaped characters (Release 1.7). X + 3. Interrupting a disk swap at the wrong time may cause the shell to + hang. I've tried disabling Control-Break during disk read/writes + but this only causes the shell to hang on re-load every time in + some environments. In the next release, I'm going to put in some + checks and issue re-read/writes when necessary. + X Thanks are due to X X Greg Yachuk *************** *** 101,106 **** --- 111,117 ---- X John B Thiel X Harry McGavran X Bill Davidsen + Richard J Reiner X X for their comments, fixes, tolerance etc in testing release 1.6 X Index: lib/stdargv.c *** ../sh16.3/lib/stdargv.c Fri Mar 2 11:34:58 1990 --- lib/stdargv.c Tue Nov 6 20:52:05 1990 *************** *** 18,25 **** X * This function replaces the standard MS-DOS command X * line processing function (_setargv in stdargv.obj). X * ! * CALLING SEQUENCE: The following calling sequences are used: X * X * void _setargv (); X * X * ERROR MESSAGES: Out of memory --- 18,27 ---- X * This function replaces the standard MS-DOS command X * line processing function (_setargv in stdargv.obj). X * ! * Support for OS2 added. Compile with -DOS2 X * + * CALLING SEQUENCE: The following calling sequences are used: + * X * void _setargv (); X * X * ERROR MESSAGES: Out of memory *************** *** 32,45 **** X #include /* Standard I/O delarations */ X #include /* Standard library functions */ X #include /* Error number declarations */ X #include /* DOS functions declarations */ X #include /* BIOS functions declarations */ X #include /* Character type declarations */ X #include /* String library functions */ X #include /* String library functions */ X #include /* File Control Declarations */ - #include /* Input/Output Declarations */ X #include /* Direction I/O functions */ X X /* X * DATA DEFINITIONS: --- 34,51 ---- X #include /* Standard I/O delarations */ X #include /* Standard library functions */ X #include /* Error number declarations */ + #ifdef OS2 + #include /* OS2 functions declarations */ + #else X #include /* DOS functions declarations */ X #include /* BIOS functions declarations */ + #endif X #include /* Character type declarations */ X #include /* String library functions */ X #include /* String library functions */ X #include /* File Control Declarations */ X #include /* Direction I/O functions */ + #include X X /* X * DATA DEFINITIONS: *************** *** 65,76 **** --- 71,90 ---- X static void ex_fatal (int, char *, char *); /* Fatal error processing*/ X static char *ex_environment (char *); /* Process environment */ X static char *_ex_multi_drive (char *); /* Check for multidrive */ + static int N_floppy_disks (void); X static char *ex_nomem = "%s: %s\n"; X X extern char far *_pgmptr; /* Program name */ X extern char **__argv; /* Current argument address */ X extern int __argc; /* Current argument count */ X + #ifdef OS2 + static void _dos_setdrive (unsigned int, unsigned int *); + static void _dos_getdrive (unsigned int *); + extern ushort _aenvseg; /* Environment seg */ + extern ushort _acmdln; /* Command line offset */ + #endif + X /* X * MODULE ABSTRACT: _setargv X * *************** *** 79,92 **** X X void _setargv () X { X /* Set up pointer to command line */ X char far *argvp = (char far *)((((long)_psp) << 16) + 0x081L); X unsigned int envs = *(int far *)((((long)_psp) << 16) + 0x02cL); X char far *s; /* Temporary string pointer */ ! #ifndef M_I86LM X char buf[MAX_LINE]; /* Temporary space */ X char *cp; ! #endif X X /* Command line can be null or 0x0d terminated - convert to null */ X --- 93,131 ---- X X void _setargv () X { + #ifdef OS2 + char far *argvp = (char far *)((((long)_aenvseg) << 16)); + ushort off = _acmdln; + + while (--off) + { + if (argvp[off - 1] == 0) + break; + } + + /* Add program name */ + + _pgmptr = &argvp[off]; + + if (argvp[_acmdln] == 0) + ex_add_arg (ex_tounix (_pgmptr)); /* Add the program name */ + + else + { + argvp += _acmdln; + ex_add_arg (ex_tounix (argvp)); /* Add the program name */ + argvp += strlen (argvp) + 1; + exp_line (argvp); + } + #else X /* Set up pointer to command line */ X char far *argvp = (char far *)((((long)_psp) << 16) + 0x081L); X unsigned int envs = *(int far *)((((long)_psp) << 16) + 0x02cL); X char far *s; /* Temporary string pointer */ ! # ifndef M_I86LM X char buf[MAX_LINE]; /* Temporary space */ X char *cp; ! # endif X X /* Command line can be null or 0x0d terminated - convert to null */ X *************** *** 123,129 **** X X _pgmptr = s; X ! #ifndef M_I86LM X cp = buf; X while (*(cp++) = *(s++)); X --- 162,168 ---- X X _pgmptr = s; X ! # ifndef M_I86LM X cp = buf; X while (*(cp++) = *(s++)); X *************** *** 134,142 **** X while (*(cp++) = *(s++)); X X exp_line (buf); ! #else X ex_add_arg (ex_tounix (s)); /* Add the program name */ X exp_line (argvp); X #endif X X ex_add_arg ((char *)NULL); --- 173,182 ---- X while (*(cp++) = *(s++)); X X exp_line (buf); ! # else X ex_add_arg (ex_tounix (s)); /* Add the program name */ X exp_line (argvp); + # endif X #endif X X ex_add_arg ((char *)NULL); *************** *** 262,268 **** X X /* Check to see if the second diskette drive is really there */ X ! if (((_bios_equiplist () & 0x00c0) == 0x0000) && (s_drive == 2)) X continue; X X /* If the drive exists and is in our list - process it */ --- 302,308 ---- X X /* Check to see if the second diskette drive is really there */ X ! if ((N_floppy_disks () < 2) && (s_drive == 2)) X continue; X X /* If the drive exists and is in our list - process it */ *************** *** 619,623 **** --- 659,703 ---- X } X X return (*prefix && (*(prefix + 1) == ':')) ? prefix + 1 : (char *)NULL; + } + + /* Some OS/2 functions to emulate the DOS functions */ + + #ifdef OS2 + static void _dos_getdrive (cdp) + unsigned int *cdp; + { + USHORT cdr; + ULONG ndr; + + DosQCurDisk((PUSHORT)&cdr, (PULONG) &ndr); + *cdp = (unsigned int)cdr; + } + + static void _dos_setdrive (cdr, ndp) + unsigned int cdr; + unsigned int *ndp; + { + USHORT dummy; + ULONG ndr; + + DosQCurDisk((PUSHORT)&dummy, (PULONG) &ndr); + *ndp = (unsigned int)ndr; + + DosSelectDisk ((USHORT)cdr); + } + #endif + + /* Return the number of floppy disks */ + + static int N_floppy_disks () + { + #ifdef OS2 + BYTE nflop = 1; + DosDevConfig (&nflop, 2, 0); + return nflop; + #else + return ((_bios_equiplist () & 0x00c0) >> 6) + 1; + #endif X } X #endif Index: sh.1 Prereq: 1.11 *** ../sh16.3/sh.1 Fri Aug 17 21:31:41 1990 --- sh.1 Tue Nov 6 20:11:17 1990 *************** *** 14,22 **** X .\" 2. The sources (or parts thereof) or objects generated from the sources X .\" (or parts of sources) cannot be sold under any circumstances. X .\" ! .\" $Header: C:/SRC/SHELL/RCS/sh.1 1.11 90/08/14 23:17:25 Ian_Stewartson Exp $ X .\" X .\" $Log: sh.1 $ X .\" Revision 1.11 90/08/14 23:17:25 Ian_Stewartson X .\" Add IO read/write open X .\" --- 14,26 ---- X .\" 2. The sources (or parts thereof) or objects generated from the sources X .\" (or parts of sources) cannot be sold under any circumstances. X .\" ! .\" $Header: D:/SRC/SHELL/RCS/sh.1 1.12 90/11/06 20:08:46 Ian_Stewartson Exp $ X .\" X .\" $Log: sh.1 $ + .\" Revision 1.12 90/11/06 20:08:46 Ian_Stewartson + .\" Add POSIX options {#%*} and ~ + .\" Add builtin command + .\" X .\" Revision 1.11 90/08/14 23:17:25 Ian_Stewartson X .\" Add IO read/write open X .\" *************** *** 163,172 **** X .SS Comments X A word beginning with \fB#\fR causes that word and all the following X characters up to a new-line to be ignored. X .SS Command Substitution ! The standard output from a command enclosed in a pair of grave accents ! (\fB\(ga\(ga\fR) may be used as part or all of a word; trailing new-lines ! are removed. X .SS Parameter Substitution X The character \fB$\fR is used to introduce substitutable \fIparameters\fR. X There are two types of parameters, positional and keyword. If \fIparameter\fR --- 167,179 ---- X .SS Comments X A word beginning with \fB#\fR causes that word and all the following X characters up to a new-line to be ignored. + .SS Tilde Substitution + Each word is checked to see if it begins with an unquoted\fB~\fR. If it is, + the \fB~\fR is replaced by the value of the \fBHOME\fR parameter. X .SS Command Substitution ! The standard output from a command enclosed in parenthesis preceded by a ! dollar sign (\fB$()\fR), or in a pair of grave accents (\fB\(ga\(ga\fR) may ! be used as part or all of a word; trailing new-lines are removed. X .SS Parameter Substitution X The character \fB$\fR is used to introduce substitutable \fIparameters\fR. X There are two types of parameters, positional and keyword. If \fIparameter\fR *************** *** 184,196 **** X .PD 0 X .TP X \fB${\fIparameter\fB}\fR ! The value, if any, of the parameter is substituted. The braces are required ! only when \fIparameter\fR is followed by a letter, digit, or underscore that ! is not to be interpreted as part of its name. If \fIparameter\fR is ! \fB*\fR or \fB@\fR, all the positional parameters, starting with \fB$1\fR, ! are substituted (separated by spaces). Parameter \fB$0\fR is set from argument ! zero when the shell is invoked. X .TP X \fB${\fIparameter\fB:-\fIword\fB}\fR X If \fIparameter\fR is set and is non-null, substitute its value; otherwise X substitute \fIword\fR. --- 191,208 ---- X .PD 0 X .TP X \fB${\fIparameter\fB}\fR ! The value, if any, of the \fIparameter\fR is substituted. The braces are ! required only when \fIparameter\fR is followed by a letter, digit, or ! underscore that is not to be interpreted as part of its name. If ! \fIparameter\fR is \fB*\fR or \fB@\fR, all the positional parameters, starting ! with \fB$1\fR, are substituted (separated by spaces). Parameter \fB$0\fR is ! set from argument zero when the shell is invoked. X .TP + \fB${#\fIparameter\fB}\fR + If \fIparameter\fR is \fB*\fR or \fB@\fR, the number of positional parameters + is substituted. Otherwise, the length of the value of the \fIparameter\fR is + substituted. + .TP X \fB${\fIparameter\fB:-\fIword\fB}\fR X If \fIparameter\fR is set and is non-null, substitute its value; otherwise X substitute \fIword\fR. *************** *** 208,213 **** --- 220,242 ---- X \fB${\fIparameter\fB:+\fIword\fB}\fR X If \fIparameter\fR is set and is non-null, substitute \fIword\fR; otherwise X substitute nothing. + .TP + \fB${\fIparameter\fB#\fIpattern\fB}\fR + \fB${\fIparameter\fB##\fIpattern\fB}\fR + If the Shell \fIpattern\fR matches the beginning of the value of + \fIparameter\fR, then the value of this substitution is the value of the + \fIparameter\fR with the matched portion deleted; otherwise the value of + this \fIparameter\fR is substituted. In the first form the smallest matching + \fIpattern\fR is deleted and in the latter form the largest matching + \fIpattern\fR is deleted. + .TP + \fB${\fIparameter\fB%\fIpattern\fB}\fR + \fB${\fIparameter\fB%%\fIpattern\fB}\fR + If the Shell \fIpattern\fR matches the end of the value of \fIparameter\fR, + then the value of this substitution is the value of the \fIparameter\fR with + the matched portion deleted; otherwise the value of this \fIparameter\fR is + substituted. In the first form the smallest matching \fIpattern\fR is deleted + and in the latter form the largest matching \fIpattern\fR is deleted. X .PD X .PP X In the above, \fIword\fR is not evaluated unless it is to be used as the *************** *** 830,835 **** --- 859,886 ---- X Exit from the enclosing \fBfor\fR or \fBwhile\fR loop, if any. If \fIn\fR is X specified, break \fIn\fR levels. X .TP + \fBbuiltin\fR \*(OK \fIargs\fR ... \*(CK + Force the selection of the \fBbuiltin\fR version of a command. The builtin + shell command selected by the first \fIargs\fR value is executed with the + parameters defined by the remaining \fIargs\fRs. If no arguments are given, + a list of all \fIbuiltin\fR commands is printed. + .sp + If the first argument is one of the following, the processing of the + builtin command in the following arguments are changed as indicated: + .RS + .TP + \fB-a\fR + Set the following builtin commands to use builtin version in preference to + any function or external versions. + .TP + \fB-d\fR + Set the following builtin commands to use the function or external version + in preference to the builtin version. + .TP + \fB-s\fR + Display the current status of the following builtin commands. + .RE + .TP X \fBcontinue\fR \*(OK \fIn\fR \*(CK X Resume the next iteration of the enclosing \fBfor\fR or \fBwhile\fR loop. If X \fIn\fR is specified, resume at the \fIn\fR-th enclosing loop. *************** *** 986,992 **** X \fBmsdos\fR \*(OK \fIname\fR ... \*(CK X The given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag X is set, the values of the these \fIname\fRs are exported to child processes ! with any slashes in the value replaced by backslashes. X .TP X \fBpwd\fR X Print the current working directory. --- 1037,1044 ---- X \fBmsdos\fR \*(OK \fIname\fR ... \*(CK X The given \fIname\fRs are marked \fImsdos\fR format and if the \fB-m\fR flag X is set, the values of the these \fIname\fRs are exported to child processes ! with any slashes in the value replaced by backslashes. If no arguments are ! given, a list of all \fImsdos\fR names is printed. X .TP X \fBpwd\fR X Print the current working directory. Index: shell/sh.h Prereq: 1.21 *** ../sh16.3/shell/sh.h Fri Aug 17 21:33:20 1990 --- shell/sh.h Tue Nov 6 19:18:37 1990 *************** *** 13,21 **** X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * ! * $Header: C:/SRC/SHELL/RCS/sh.h 1.21 90/08/14 23:54:44 MS_user Exp $ X * X * $Log: sh.h $ X * Revision 1.21 90/08/14 23:54:44 MS_user X * Add addition value to env structure X * Add some new publics --- 13,27 ---- X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * ! * $Header: D:/SRC/SHELL/RCS/sh.h 1.23 90/09/19 15:29:54 Ian_Stewartson Exp $ X * X * $Log: sh.h $ + * Revision 1.23 90/09/19 15:29:54 Ian_Stewartson + * Allow builtin commands to selected/de-selected + * + * Revision 1.22 90/08/24 21:53:13 Ian_Stewartson + * Add support for POSIX macro command {x#y} and {x%y} + * X * Revision 1.21 90/08/14 23:54:44 MS_user X * Add addition value to env structure X * Add some new publics *************** *** 85,91 **** X * X */ X ! #define PATCHLEVEL 7 X #define LINE_MAX 1000 /* Command line length */ X #define HISTORY_MAX 100 /* History array length */ X /* Space for full file name */ --- 91,97 ---- X * X */ X ! #define PATCHLEVEL 8 X #define LINE_MAX 1000 /* Command line length */ X #define HISTORY_MAX 100 /* History array length */ X /* Space for full file name */ *************** *** 168,179 **** X struct builtin { X char *command; X int (*fn)(C_Op *); X }; X X /* ! * actions determining the environment of a process X */ X X #define FEXEC 0x0001 /* execute without forking */ X X /* MSDOS Memory Control Block chain structure */ --- 174,193 ---- X struct builtin { X char *command; X int (*fn)(C_Op *); + int mode; X }; X X /* ! * Valid values of mode X */ X + #define BLT_ALWAYS 0x0001 /* Always use builtin version */ + #define BLT_CURRENT 0x0002 /* Currently use builtin version */ + + /* + * actions determining the environment of a process + */ + X #define FEXEC 0x0001 /* execute without forking */ X X /* MSDOS Memory Control Block chain structure */ *************** *** 376,384 **** X /* depth */ X X /* ! * Variable list X */ X X typedef struct var { X char *value; /* Value */ X char *name; /* Name */ --- 390,407 ---- X /* depth */ X X /* ! * Mode values for new gmatch X */ X + #define GM_ALL 0 /* Match full string */ + #define GM_SHORTEST 1 /* Shortest prefix/suffix */ + #define GM_LONGEST 2 /* Longest prefix/suffix */ + + /* + /* + * Variable list + */ + X typedef struct var { X char *value; /* Value */ X char *name; /* Name */ *************** *** 531,537 **** X extern void s_vstatus (Var_List *, int); X extern bool isassign (char *); X extern bool assign (char *, int); ! extern bool gmatch (char *, char *, bool); X extern char *getcell (unsigned int); X extern void freecell (char *); X extern void freearea (int); --- 554,561 ---- X extern void s_vstatus (Var_List *, int); X extern bool isassign (char *); X extern bool assign (char *, int); ! extern bool gmatch (char *, char *, bool, char **, int); ! extern bool gmatch_suffix (char *, char *, bool, char **, int); X extern char *getcell (unsigned int); X extern void freecell (char *); X extern void freearea (int); *************** *** 574,580 **** X extern void put_prompt (char *); X extern bool eqname (char *, char *); X extern bool any (char, char *); ! extern int (*inbuilt (char *))(); X extern char *path_append (char *, char *, char *); X extern void unset (char *, bool); X extern int S_open (bool, char *, int, ...); --- 598,604 ---- X extern void put_prompt (char *); X extern bool eqname (char *, char *); X extern bool any (char, char *); ! extern int (*inbuilt (char *, bool *))(); X extern char *path_append (char *, char *, char *); X extern void unset (char *, bool); X extern int S_open (bool, char *, int, ...); Index: shell/sh0.asm Prereq: 1.10 *** ../sh16.3/shell/sh0.asm Fri Aug 17 21:33:41 1990 --- shell/sh0.asm Tue Nov 6 19:19:30 1990 *************** *** 16,22 **** X ; 2. The sources (or parts thereof) or objects generated from the sources X ; (or parts of sources) cannot be sold under any circumstances. X ; ! ; $Header: C:/SRC/SHELL/RCS/sh0.asm 1.10 90/05/31 17:46:31 MS_user Exp $ X ; X ; $Log: sh0.asm $ X ; Revision 1.10 90/05/31 17:46:31 MS_user --- 16,22 ---- X ; 2. The sources (or parts thereof) or objects generated from the sources X ; (or parts of sources) cannot be sold under any circumstances. X ; ! ; $Header: D:/SRC/SHELL/RCS/sh0.asm 1.10 90/05/31 17:46:31 MS_user Exp $ X ; X ; $Log: sh0.asm $ X ; Revision 1.10 90/05/31 17:46:31 MS_user Index: shell/sh1.c Prereq: 1.17 *** ../sh16.3/shell/sh1.c Fri Aug 17 21:32:33 1990 --- shell/sh1.c Tue Nov 6 19:20:30 1990 *************** *** 13,77 **** X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * ! * $Header: C:/SRC/SHELL/RCS/sh1.c 1.17 90/08/14 23:32:53 MS_user Exp $ X * X * $Log: sh1.c $ X * Revision 1.17 90/08/14 23:32:53 MS_user X * Fix memory bugs - Add malloc checking functions for debug X * Make Convert_Backslashes public ! * X * Revision 1.16 90/05/31 09:48:06 MS_user X * Implement partial write when swapping to disk X * Add some signal lockouts to prevent corruption ! * X * Revision 1.15 90/05/15 21:08:59 MS_user X * Restore original directory on exit ! * X * Revision 1.14 90/04/25 22:33:28 MS_user X * Fix rsh check for PATH ! * X * Revision 1.13 90/04/25 09:18:12 MS_user X * Change version message processing ! * X * Revision 1.12 90/04/04 11:32:12 MS_user X * Change MAILPATH to use a semi-colon and not a colon for DOS ! * X * Revision 1.11 90/04/03 17:58:35 MS_user X * Stop shell exit from lowest level CLI ! * X * Revision 1.10 90/03/27 20:24:49 MS_user X * Fix problem with Interrupts not restoring std??? and clearing extended file ! * X * Revision 1.9 90/03/26 20:56:13 MS_user X * Change I/O restore so that "exec >filename" works ! * X * Revision 1.8 90/03/26 04:30:14 MS_user X * Remove original Interrupt 24 save address ! * X * Revision 1.7 90/03/12 20:16:22 MS_user X * Save program name for Initialisation file processing ! * X * Revision 1.6 90/03/09 16:05:33 MS_user X * Add build file name function and change the profile check to use it ! * X * Revision 1.5 90/03/06 16:49:14 MS_user X * Add disable history option ! * X * Revision 1.4 90/03/06 15:09:27 MS_user X * Add Unix PATH variable conversion ! * X * Revision 1.3 90/03/05 13:47:45 MS_user X * Get /etc/profile and profile order rigth X * Use $HOME/profile and not profile X * Check cursor position before outputing prompt X * Move some of processing in main to sub-routines ! * X * Revision 1.2 90/02/14 04:46:20 MS_user X * Add Interrupt 24 processing ! * X * Revision 1.1 90/01/25 13:40:39 MS_user X * Initial revision ! * X */ X X #include --- 13,83 ---- X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * ! * $Header: D:/SRC/SHELL/RCS/sh1.c 1.19 90/11/06 19:13:39 Ian_Stewartson Exp $ X * X * $Log: sh1.c $ + * Revision 1.19 90/11/06 19:13:39 Ian_Stewartson + * Add deletion of swap file on interrupt + * + * Revision 1.18 90/08/24 21:54:05 Ian_Stewartson + * Add support for POSIX macro command {x#y} and {x%y} + * X * Revision 1.17 90/08/14 23:32:53 MS_user X * Fix memory bugs - Add malloc checking functions for debug X * Make Convert_Backslashes public ! * X * Revision 1.16 90/05/31 09:48:06 MS_user X * Implement partial write when swapping to disk X * Add some signal lockouts to prevent corruption ! * X * Revision 1.15 90/05/15 21:08:59 MS_user X * Restore original directory on exit ! * X * Revision 1.14 90/04/25 22:33:28 MS_user X * Fix rsh check for PATH ! * X * Revision 1.13 90/04/25 09:18:12 MS_user X * Change version message processing ! * X * Revision 1.12 90/04/04 11:32:12 MS_user X * Change MAILPATH to use a semi-colon and not a colon for DOS ! * X * Revision 1.11 90/04/03 17:58:35 MS_user X * Stop shell exit from lowest level CLI ! * X * Revision 1.10 90/03/27 20:24:49 MS_user X * Fix problem with Interrupts not restoring std??? and clearing extended file ! * X * Revision 1.9 90/03/26 20:56:13 MS_user X * Change I/O restore so that "exec >filename" works ! * X * Revision 1.8 90/03/26 04:30:14 MS_user X * Remove original Interrupt 24 save address ! * X * Revision 1.7 90/03/12 20:16:22 MS_user X * Save program name for Initialisation file processing ! * X * Revision 1.6 90/03/09 16:05:33 MS_user X * Add build file name function and change the profile check to use it ! * X * Revision 1.5 90/03/06 16:49:14 MS_user X * Add disable history option ! * X * Revision 1.4 90/03/06 15:09:27 MS_user X * Add Unix PATH variable conversion ! * X * Revision 1.3 90/03/05 13:47:45 MS_user X * Get /etc/profile and profile order rigth X * Use $HOME/profile and not profile X * Check cursor position before outputing prompt X * Move some of processing in main to sub-routines ! * X * Revision 1.2 90/02/14 04:46:20 MS_user X * Add Interrupt 24 processing ! * X * Revision 1.1 90/01/25 13:40:39 MS_user X * Initial revision ! * X */ X X #include *************** *** 528,534 **** X X Clear_Swap_File (); X ! /* If this is a command only - restore the directory because DOS doesn't X * and the user might expect it X */ X --- 534,540 ---- X X Clear_Swap_File (); X ! /* If this is a command only - restore the directory because DOS doesn't X * and the user might expect it X */ X *************** *** 713,720 **** X signal (SIGINT, onintr); X SW_intr = 1; X ! /* Are we talking to the user? Yes - check in parser */ X X if (talking) X { X if (inparse) --- 719,731 ---- X signal (SIGINT, onintr); X SW_intr = 1; X ! /* Zap the swap file, just in case it got corrupted */ X + S_close (SW_fp, TRUE); + Clear_Swap_File (); + + /* Are we talking to the user? Yes - check in parser */ + X if (talking) X { X if (inparse) *************** *** 775,782 **** --- 786,800 ---- X register int i; X { X if (i == SIGINT) /* Need this because swapper sets it */ + { X SW_intr = 0; X + /* Zap the swap file, just in case it got corrupted */ + + S_close (SW_fp, TRUE); + Clear_Swap_File (); + } + X trapset = i; X signal (i, sig); X } *************** *** 1185,1298 **** X } X X /* ! * Match a pattern as in sh(1). X */ X ! bool gmatch (s, p, IgnoreCase) ! register char *s, *p; X bool IgnoreCase; X { ! register int sc, pc; X ! if ((s == (char *)NULL) || (p == (char *)NULL)) X return FALSE; X ! while ((pc = *(p++) & CMASK) != '\0') X { ! sc = *(s++) & QMASK; X ! switch (pc) X { X case '[': /* Class expression */ ! if ((p = cclass (p, sc, IgnoreCase)) == (char *)NULL) X return FALSE; X X break; X X case '?': /* Match any character */ ! if (sc == 0) X return FALSE; X X break; X X case '*': /* Match as many as possible */ ! s--; X do X { ! if (!*p || gmatch (s, p, IgnoreCase)) ! return TRUE; X ! } while (*(s++)); X ! return FALSE; X X default: X if (IgnoreCase) X { ! sc = tolower (sc); ! pc = tolower ((pc & ~QUOTE)); X } X ! if (sc != (pc & ~QUOTE)) X return FALSE; X } X } X ! return (*s == 0) ? TRUE : FALSE; ! } X X /* X * Process a class expression - [] X */ X ! static char *cclass (p, sub, IgnoreCase) ! register char *p; ! register int sub; X bool IgnoreCase; X { ! register int c, d, not, found; X X /* Exclusive or inclusive class */ X ! if ((not = *p == NOT) != 0) ! p++; X X found = not; X X do X { ! if (!*p) X return (char *)NULL; X X /* Get the next character in class, converting to lower case if necessary */ X ! c = IgnoreCase ? tolower ((*p & CMASK)) : (*p & CMASK); X X /* If this is a range, get the end of range character */ X ! if ((*(p + 1) == '-') && (*(p + 2) != ']')) X { ! d = IgnoreCase ? tolower ((*(p + 2) & CMASK)) : (*(p + 2) & CMASK); ! p++; X } X X else ! d = c; X X /* Is the current character in the class? */ X ! if ((c <= sub) && (sub <= d)) X found = !not; X ! } while (*(++p) != ']'); X ! return found ? p + 1 : (char *)NULL; X } X X /* ! * Get a string in a malloced area X */ X X char *getcell (nbytes) X unsigned int nbytes; X { --- 1203,1381 ---- X } X X /* ! * Match a pattern as in sh(1). Enhancement to handle prefix processing ! * ! * IgnoreCase - ignore case on comparisions. ! * end - end of match in 'string'. ! * mode - mode for match processing - see GM_ flags in sh.h X */ X ! bool gmatch (string, pattern, IgnoreCase, end, mode) ! register char *string, *pattern; X bool IgnoreCase; + char **end; + int mode; X { ! register int string_c, pattern_c; ! char *save_end; X ! if ((string == (char *)NULL) || (pattern == (char *)NULL)) X return FALSE; X ! while ((pattern_c = *(pattern++) & CMASK) != '\0') X { ! string_c = *(string++) & QMASK; X ! switch (pattern_c) X { X case '[': /* Class expression */ ! if ((pattern = cclass (pattern, string_c, IgnoreCase)) == (char *)NULL) X return FALSE; X X break; X X case '?': /* Match any character */ ! if (string_c == 0) X return FALSE; X X break; X X case '*': /* Match as many as possible */ ! --string; ! save_end = (char *)NULL; ! X do X { ! if (!*pattern || ! gmatch (string, pattern, IgnoreCase, end, mode)) ! { ! if (mode == GM_LONGEST) ! save_end = *end; X ! else ! return TRUE; ! } X ! } while (*(string++)); X + if (end != (char **)NULL) + *end = save_end; + + return (save_end == (char *)NULL) ? FALSE : TRUE; + X default: X if (IgnoreCase) X { ! string_c = tolower (string_c); ! pattern_c = tolower ((pattern_c & ~QUOTE)); X } X ! if (string_c != (pattern_c & ~QUOTE)) X return FALSE; X } X } X ! if (end != (char **)NULL) ! { ! *end = string; ! return TRUE; ! } X + return (*string == 0) ? TRUE : FALSE; + } + X /* X * Process a class expression - [] X */ X ! static char *cclass (pattern, string_c, IgnoreCase) ! register char *pattern; ! register int string_c; X bool IgnoreCase; X { ! register int llimit_c, ulimit_c, not, found; X X /* Exclusive or inclusive class */ X ! if ((not = *pattern == NOT) != 0) ! pattern++; X X found = not; X X do X { ! if (!*pattern) X return (char *)NULL; X X /* Get the next character in class, converting to lower case if necessary */ X ! llimit_c = IgnoreCase ? tolower ((*pattern & CMASK)) ! : (*pattern & CMASK); X X /* If this is a range, get the end of range character */ X ! if ((*(pattern + 1) == '-') && (*(pattern + 2) != ']')) X { ! ulimit_c = IgnoreCase ? tolower ((*(pattern + 2) & CMASK)) ! : (*(pattern + 2) & CMASK); ! pattern++; X } X X else ! ulimit_c = llimit_c; X X /* Is the current character in the class? */ X ! if ((llimit_c <= string_c) && (string_c <= ulimit_c)) X found = !not; X ! } while (*(++pattern) != ']'); X ! return found ? pattern + 1 : (char *)NULL; X } X X /* ! * Suffix processing - find the longest/shortest suffix. X */ X + bool gmatch_suffix (string, pattern, IgnoreCase, start, mode) + register char *string, *pattern; + bool IgnoreCase; + char **start; + int mode; + { + char *save_start = (char *)NULL; + + /* Scan the string, looking for a match to the end */ + + while (*string) + { + if (gmatch (string, pattern, IgnoreCase, (char **)NULL, GM_ALL)) + { + + /* If longest, stop here */ + + if (mode == GM_LONGEST) + { + *start = string; + return TRUE; + } + + /* Save the start of the shortest string so far and continue */ + + save_start = string; + } + + ++string; + } + + return ((*start = save_start) == (char *)NULL) ? FALSE : TRUE; + } + + /* + * Get a string in a malloced area + */ + X char *getcell (nbytes) X unsigned int nbytes; X { *************** *** 1323,1329 **** X print_warn ("Malloc access to bad segment\n"); X return (char *)NULL; X } ! X np->magic1 = MAGIC1; X np->len = nbytes; X rp = (char *)(np + 1); --- 1406,1412 ---- X print_warn ("Malloc access to bad segment\n"); X return (char *)NULL; X } ! X np->magic1 = MAGIC1; X np->len = nbytes; X rp = (char *)(np + 1); *************** *** 1362,1370 **** X /* Disable signals */ X X save_signal = signal (SIGINT, SIG_IGN); - - /* Find the string in the chain */ X X if (s != (char *)NULL) X { X while (cp != (s_region *)NULL) --- 1445,1453 ---- X /* Disable signals */ X X save_signal = signal (SIGINT, SIG_IGN); X + /* Find the string in the chain */ + X if (s != (char *)NULL) X { X while (cp != (s_region *)NULL) *************** *** 2012,2018 **** X str1++; X str2++; X } ! X return rtn; X } X --- 2095,2101 ---- X str1++; X str2++; X } ! X return rtn; X } X *************** *** 2064,2074 **** X X while (--len >= 0) X { ! if ((*(str1++) = *(str2++)) == 0) X { X while (--len >= 0) X *(str1++) = 0; ! X break; X } X } --- 2147,2157 ---- X X while (--len >= 0) X { ! if ((*(str1++) = *(str2++)) == 0) X { X while (--len >= 0) X *(str1++) = 0; ! X break; X } X } Index: shell/sh3.c Prereq: 1.24 *** ../sh16.3/shell/sh3.c Fri Aug 17 21:34:34 1990 --- shell/sh3.c Tue Nov 6 19:21:26 1990 *************** *** 13,21 **** X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * ! * $Header: C:/SRC/SHELL/RCS/sh3.c 1.24 90/08/16 10:28:47 Ian_Stewartson Exp $ X * X * $Log: sh3.c $ X * Revision 1.24 90/08/16 10:28:47 Ian_Stewartson X * Find setting of switch character for DOS4 for batch files X * --- 13,32 ---- X * 2. The sources (or parts thereof) or objects generated from the sources X * (or parts of sources) cannot be sold under any circumstances. X * ! * $Header: C:/SRC/SHELL/RCS/sh3.c 1.27 90/09/19 15:30:31 Ian_Stewartson Exp $ X * X * $Log: sh3.c $ + * Revision 1.27 90/09/19 15:30:31 Ian_Stewartson + * Allow builtin commands to selected/de-selected + * + * Revision 1.26 90/09/11 20:06:11 Ian_Stewartson + * Add support for buitlin command, including the alway builtin functions + * Change search order to match POSIX + * + * Revision 1.25 90/08/24 21:55:00 Ian_Stewartson + * Change processing order (function, external, internal) to conform to + * POSIX. Update to gmatch for macro command changes + * X * Revision 1.24 90/08/16 10:28:47 Ian_Stewartson X * Find setting of switch character for DOS4 for batch files X * *************** *** 144,149 **** --- 155,161 ---- X static char *AE2big = "arg/env list too big"; X static char *EMS_emsg = "Warning: EMS Error (%x)\n"; X static char *XMS_emsg = "Warning: XMS Error (%x)\n"; + static char *EF_msg = "%s: %s\n"; X /* Extended Command line processing file name */ X static char *Extend_file = (char *)NULL; X static char *Swap_File = (char *)NULL; /* Swap file */ *************** *** 475,481 **** --- 487,495 ---- X void (*sig_int)(); X char **owp = wp; X bool spawn = FALSE; + bool builtin = FALSE; X Fun_Ops *fop; + int i; X X if (t->type == TCOM) X { *************** *** 510,522 **** X /* Check for built in commands */ X X else if (cp != (char *)NULL) ! shcom = inbuilt (cp); X } X X /* Unix fork simulation? */ X X t->words = wp; ! if (shcom == NULL && (act & FEXEC) == 0) X { X spawn = TRUE; X --- 524,536 ---- X /* Check for built in commands */ X X else if (cp != (char *)NULL) ! shcom = inbuilt (cp, &builtin); X } X X /* Unix fork simulation? */ X X t->words = wp; ! if ((act & FEXEC) == 0) X { X spawn = TRUE; X *************** *** 534,540 **** X X while (((cp = *owp++) != (char *)NULL) && assign (cp, COPYV)) X { ! if (shcom == NULL) X s_vstatus (lookup (cp, TRUE), EXPORT); X } X --- 548,554 ---- X X while (((cp = *owp++) != (char *)NULL) && assign (cp, COPYV)) X { ! if (shcom == (int (*)())NULL) X s_vstatus (lookup (cp, TRUE), EXPORT); X } X *************** *** 565,572 **** X } X } X - if (shcom) - return restore_std (setstatus ((*shcom)(t)), TRUE); X X /* All fids above 10 are autoclosed in the exec file because we have used X * the O_NOINHERIT flag. Note I patched open.obj to pass this flag to the --- 579,584 ---- *************** *** 598,604 **** X * in some processing for return. X */ X ! if ((fop = Fun_Search (wp[0])) != (Fun_Ops *)NULL) X { X char **s_dolv = dolv; X int s_dolc = dolc; --- 610,616 ---- X * in some processing for return. X */ X ! if (!builtin && (fop = Fun_Search (wp[0])) != (Fun_Ops *)NULL) X { X char **s_dolv = dolv; X int s_dolc = dolc; *************** *** 651,659 **** X X /* Ok - execute the program */ X ! return restore_std (rexecve (wp[0], wp, makenv (), spawn), TRUE); ! } X X /* X * Restore Local Environment X */ --- 663,685 ---- X X /* Ok - execute the program */ X ! if (!builtin) ! rv = rexecve (wp[0], wp, makenv (), spawn); X + /* If we didn't find it, check for internal command */ + + if (builtin || ((rv == -1) && (errno == ENOENT))) + { + if (shcom != (int (*)())NULL) + rv = setstatus ((*shcom)(t)); + + else + print_warn (EF_msg, wp[0], "not found"); + } + + return restore_std (rv, TRUE); + } + X /* X * Restore Local Environment X */ *************** *** 835,841 **** X X for (wp = t1->words; *wp != (char *)NULL;) SHAR_EOF true || echo 'restore of Patch1.6.4 failed' fi echo 'End of part 1' echo 'File Patch1.6.4 is continued in part 2' echo 2 > _shar_seq_.tmp exit 0 exit 0 # Just in case... -- Kent Landfield INTERNET: kent@sparky.IMD.Sterling.COM Sterling Software, IMD UUCP: uunet!sparky!kent Phone: (402) 291-8300 FAX: (402) 291-4362 Please send comp.sources.misc-related mail to kent@uunet.uu.net.