BATCH.C
资源名称:drdossrc.zip [点击查看]
上传用户:xiaogehua
上传日期:2007-01-08
资源大小:1183k
文件大小:70k
源码类别:
操作系统开发
开发平台:
Asm
- /*
- ; File : $Workfile: BATCH.C$
- ;
- ; Description :
- ;
- ; Original Author : DIGITAL RESEARCH
- ;
- ; Last Edited By : $CALDERA$
- ;
- ;-----------------------------------------------------------------------;
- ; Copyright Work of Caldera, Inc. All Rights Reserved.
- ;
- ; THIS WORK IS A COPYRIGHT WORK AND CONTAINS CONFIDENTIAL,
- ; PROPRIETARY AND TRADE SECRET INFORMATION OF CALDERA, INC.
- ; ACCESS TO THIS WORK IS RESTRICTED TO (I) CALDERA, INC. EMPLOYEES
- ; WHO HAVE A NEED TO KNOW TO PERFORM TASKS WITHIN THE SCOPE OF
- ; THEIR ASSIGNMENTS AND (II) ENTITIES OTHER THAN CALDERA, INC. WHO
- ; HAVE ACCEPTED THE CALDERA OPENDOS SOURCE LICENSE OR OTHER CALDERA LICENSE
- ; AGREEMENTS. EXCEPT UNDER THE EXPRESS TERMS OF THE CALDERA LICENSE
- ; AGREEMENT NO PART OF THIS WORK MAY BE USED, PRACTICED, PERFORMED,
- ; COPIED, DISTRIBUTED, REVISED, MODIFIED, TRANSLATED, ABRIDGED,
- ; CONDENSED, EXPANDED, COLLECTED, COMPILED, LINKED, RECAST,
- ; TRANSFORMED OR ADAPTED WITHOUT THE PRIOR WRITTEN CONSENT OF
- ; CALDERA, INC. ANY USE OR EXPLOITATION OF THIS WORK WITHOUT
- ; AUTHORIZATION COULD SUBJECT THE PERPETRATOR TO CRIMINAL AND
- ; CIVIL LIABILITY.
- ;-----------------------------------------------------------------------;
- ;
- ; *** Current Edit History ***
- ; *** End of Current Edit History ***
- ;
- ; $Log$
- ; ENDLOG
- */
- /*
- * 27 Oct 87 Improve GOTO command to ignore trailing white space, only
- * match on the first 8 characters and only allow valid
- * filename characters.
- * 28 Oct 87 Correct duplicate prompt display when a batch file label
- * is read and the echo flag is ON.
- * 9 Nov 87 Change Batch file termination so that Output Redirection is
- * correctly handled.
- * 13 Jan 88 If prompt display is aborted because of a critical error
- * the following prompt will be forced to "$n$g".
- * 25 Jan 88 Support redirection on the FOR command correctly
- * 24 Feb 88 Generate batch file parameter %0 correctly as WS200 install
- * requires that the drive specifier be present. Garry Silvey
- * 5 May 88 Batch paramater %0 is now a copied from the invoking command
- * line.
- * 18 May 88 Support the ESC_CHAR in the command line.
- * 20 May 88 Disable MULTI_CHAR support in DOSPLUS when the user enters the
- * first command.
- * 26 May 88 Added STACK switch and support $q in prompt.
- * 27 May 88 Added string undefs.
- * 6 Jun 88 Call resident portion to do readline (SideKick+ problem)
- * 23 Jun 88 Support CR only delimited batch files and if errorlevel ==
- * syntax used in installation files.
- * 6 Jul 88 Support the FOR ... CALL syntax correctly. (IMS)
- * 17 Aug 88 Jump to labels followed by comments (Ashton Tate By-Line)
- * 21 Sep 88 Use KEYIN_FLG to allow the default ECHO state to be ON.
- * 16 Nov 88 Disable BACK_CHAR in Concurrent DOS.
- * 21 Dec 88 Allow leading whitespace before labels
- * 5 Jan 89 Support Quoted strings in Batch files.
- * 18 Apr 89 Support Quoted strings in IF command
- * 19 Apr 89 Quotes in IF command: "x == "x" parses, "x=x" == "x.. doesn't
- * 24 Apr 89 Increase MAX_LINE to 128 for pctools ver 5
- * 19 May 89 Take out support for quoted strings in IF command
- * 05 Jun 89 Do not echo command or display the prompt during FOR command.
- * Restore support for batch files with long lines.
- * 02 Nov 89 batch_line bodge which substitutes 0xFF for 0x00 changed - we
- * now substitute 'rn', then throw away rest of the line.
- * 01 Dec 89 batch_line - trailing % at end of line is discarded
- * 15 Dec 89 "if errorlevel -1" allowed
- * 30 Jan 90 Added int2e_start and int2e_finish to save and restore
- * important batch file variables to allow novell menu program
- * to use int 2e to invoke batch files.
- * 30 Jan 90 Forced batch data structures to appear on segment boundaries;
- * Added dummy memory descriptor before batch structure;
- * Put segment address of batch structure in batch_seg_ptr;
- * All so novell can find and patch the drive letter of
- * autoexec.bat during a remote boot.
- * 6-Mar-90 Watcom C v 7.0
- * 7-Mar-90 allow ESC_CHAR through unless followed by MULTI/BACK_CHAR
- * 14-Mar-90 Reduce batch_buf to 32 bytes like wot dos is
- * 20-Mar-90 Batch structures allocated by mem_alloc (ie. MS_M_ALLOC)
- * rather than on heap. Batch file nesting no longer heap limited.
- * 27-Mar-90 Allow "=", "==", "===" etc in "if errorlevel==n"
- * 10-Apr-90 Make errorlevel 999 same as errorlevel 231 (mod 256)
- * 8-May-90 Don't echo getcmd unless batch file (eg. "dir|more" shouldn't
- * echo "C:>more")
- * 23-May-90 batch_read no longer repeatedly deblanks line (which leads
- * to the buffer happily wandering up memory).
- * 30-May-90 "if ab de==ef" form doesn't generate syntax error
- * 13-Jun-90 batch_line rejects unmatched "|" as syntax error
- * 20-Sep-90 is_filechar() and is_pathchar() now take pointer instead of byte
- * Changed batch_char() to return pointer instead of byte,
- * renamed to batch_ptr().
- * Amended make_label(), batch_start() and cmd_for() to check for
- * DBCS lead bytes.
- * 24-Sep-90 Add $m and $u option to PROMPT to display status of mail
- and user name respectively
- * 27-Sep-90 Add IF USERID <userid> COMMAND
- IF LOGINNAME <loginname> COMMAND
- IF GROUPNAME <groupname> COMMAND
- IF ASK ["string"] <char> COMMAND
- .. AND .. OR .. to IF processing
- INPUT ["string"] <environment-variable>
- INPUTC ["string"] <environment-variable>
- * 10-Oct-90 inherit batch files from TMP when TSR auto-loads CDOS.COM
- (a bodge for Stellar)
- * 25-Oct-90 inherit echoflg from TMP when TSR auto-loads CDOS.COM
- * 31-Oct-90 change IF ASK command to IF KEY command
- DRDOS BUXTON
- ------------
- * 25-Apr-91 '!' is now ignored during COMMAND /C processing.
- * 28-May-91 leading white space is now ignored before labels.
- * 09-Jun-91 Added GOSUB, RETURN and SWITCH commands.
- * 24-Jul-91 if batch_seg_ptr is poked to zero all batch processing is
- terminated.
- * 26-Jul-91 batch files are now read into a far buffer. This avoids
- reading directly to seg FFFF if we happen to be there and so
- solves some NOVELL problems.
- * 18-Jun-92 Support ? in batch files as in config.sys.
- * 23-Jun-92 $u in prompt causes LOGINNAME in environment to be displayed.
- * 07-Jul-92 IF EXIST now finds hidden files.
- */
- #include "defines.h"
- #include <string.h>
- #if defined(MWC) && defined(strlen)
- #undef strcmp /* These are defined as macros in string.h */
- #undef strcpy /* which are expanded in line under */
- #undef strlen /* Metaware C. These undefs avoid this. */
- #endif
- #include <portab.h>
- #if !defined(DOSPLUS)
- #include <ccpm.h>
- #endif
- #include "command.h"
- #include "toupper.h"
- #include "support.h"
- #include "dosif.h"
- #include "global.h"
- #include "dos.h"
- #include <setjmp.h>
- /*RG-01*/
- #if defined(CDOSTMP) || defined(CDOS)
- #include <pd.h>
- #define PATH_LEN 65 /* max path length (null terminated) */
- EXTERN PD FAR * CDECL pd; /* Far pointer to Current PD */
- EXTERN VOID CDECL cmd_set(BYTE *); /* COMINT.C */
- #if !defined (NOSECURITY)
- #include "security.h"
- #include "login.h"
- #endif
- #endif
- /*RG-01-end*/
- EXTERN VOID CDECL cmd_pause();
- EXTERN BOOLEAN parse(BYTE *);
- EXTERN UWORD boot_key_scan_code; /* in COM.C */
- /*RG-03*/
- BOOLEAN if_context=FALSE;
- BOOLEAN ifcond=FALSE;
- /*RG-03-end*/
- EXTERN jmp_buf break_env;
- #define MAX_LINE 128 /* Maximum No of Chars in input line */
- #if defined(CPM)
- EXTERN UWORD user; /* USER Number variable for CPM.EXE */
- #endif
- EXTERN BYTE msg_prmeq[]; /* Static Environ String "PROMPT=" */
- #if 0
- #define FCONTROL struct fcc
- MLOCAL FCONTROL {
- BOOLEAN sflg; /* FOR File Search Flag */
- DTA search; /* FOR Search structure */
- BYTE *files; /* FOR File list */
- BYTE *cmd; /* FOR Command Line */
- BYTE forvar; /* FOR variable char */
- };
- #endif
- MLOCAL FCONTROL *forptr;
- #if 0
- #define BCONTROL struct bcc
- GLOBAL BCONTROL {
- BCONTROL FAR *bcontrol; /* Previous Batch Control Structure */
- BOOLEAN eof; /* End of File Flag */
- LONG offset; /* Offset in BATCH file */
- LONG ret_offset[4]; /* return offset from gosub */
- BYTE *batcmd; /* Batch File Input parameters */
- UWORD batshift; /* Shift Offset */
- BYTE batfile[MAX_PATHLEN]; /* Batch File Name */
- UWORD stream; /* Stream for this Batch File */
- FCONTROL *fcontrol; /* Pointer to previous FOR command */
- BYTE *heap_start; /* Heap pointer before extra bytes */
- WORD heap_size; /* are added to shift to segment */
- BYTE save_area[1]; /* boundary. - EJH */
- } FAR *batch, FAR *batch_save; /* Master Batch Control Stucture */
- #endif
- /* Handle 255 is closed */
- #define CLOSED 0xff
- /* Keyboard Variables */
- GLOBAL BYTE kbdbuf[MAX_LINE+2]= {0};/* Keyboard Input Buffer */
- GLOBAL BYTE *kbdptr = kbdbuf+2; /* Keyboard Buffer Pointer */
- MLOCAL BOOLEAN keyin_flg = FALSE; /* This flag is set to TRUE when the */
- /* initial command line buffer setup */
- /* by INIT() has been exhausted. */
- MLOCAL WORD batchflg_save; /* Used during INT 2E handling. */
- MLOCAL WORD echoflg_save; /* ditto above */
- GLOBAL WORD echoflg_save2; /* saves echo state when batch file */
- /* execed. */
- /*
- * Batch file buffering control structures.
- */
- MLOCAL LONG batch_off; /* Offset of buffered data in File */
- MLOCAL WORD batch_cnt = 0; /* Number of bytes in buffer */
- MLOCAL BYTE batch_buf[32];
- MLOCAL BYTE batch_eof[] = "x1a"; /* End of file string */
- MLOCAL BYTE batch_sep[] = "t ;,="; /* Batch Command line option delimiters */
- EXTERN VOID CDECL cmd_ver(BYTE *); /* COMINT.C Display Version */
- EXTERN VOID docmd(BYTE *, BOOLEAN); /* COM.C */
- EXTERN VOID CDECL int_break(VOID); /* COM.C */
- GLOBAL BOOLEAN getcmd(BYTE *);
- GLOBAL VOID for_end();
- GLOBAL VOID batch_start(BYTE *, BYTE *, BYTE *);
- GLOBAL VOID batch_end(VOID);
- GLOBAL VOID batch_close(VOID);
- MLOCAL VOID for_in(BYTE *);
- MLOCAL WORD batch_open(VOID);
- MLOCAL VOID batch_read(BYTE *, BOOLEAN);
- MLOCAL VOID batch_line(BYTE *, BOOLEAN);
- MLOCAL BYTE *batch_ptr(VOID);
- MLOCAL VOID prompt(VOID);
- MLOCAL BOOLEAN novell_extension(BYTE *, BYTE *);
- #if !defined(CDOSTMP)
- EXTERN UWORD FAR *batch_seg_ptr; /* For novell remote boot. see CSTART.ASM */
- #endif
- #if defined(CDOS) || defined(CDOSTMP)
- #define TmpPspEchoFlgPtr 0x58 /* Magic location to keep echo flag */
- #define TmpPspDataSeg 0x5a /* Magic location to keep Data Seg */
- #define TmpPspBatchSeg 0x5c /* Magic location to keep Batch Ptr */
- #define TmpPspMpad 0x5e /* Magic location to keep unlinked MPAD */
- #endif
- #if defined(CDOS)
- typedef struct _mpad
- {
- UWORD link; /* address of next MPAD */
- UWORD start; /* seg of allocation unit */
- UWORD length; /* length in paras */
- UWORD res0x06; /* reserved */
- UWORD xios; /* Process id */
- } MPAD;
- GLOBAL VOID inherit_TMP_state(VOID);
- #endif
- /*.pa*/
- GLOBAL BOOLEAN getcmd(line) /* read command line */
- BYTE *line;
- {
- BYTE *s;
- BOOLEAN quote = FALSE;
- BOOLEAN cancel_prompt = FALSE;
- #if defined(DOSPLUS)
- WORD i;
- BYTE cmd_name[16];
- #endif
- back_flag = FALSE; /* Disable BackGround Processing*/
- *line = ' ';
- FOREVER {
- if(for_flag) { /* If Processing a FOR command */
- for_in(line); /* then call then use the FOR_IN*/
- return NO; /* routine to fill the keyboard */
- } /* buffer and then return */
- if(!batchflg) /* If no batch processing then */
- break; /* skip further tests */
- batch_restart:
- #if defined(DOSPLUS)
- if (!*batch_seg_ptr) { /* if batch_seg_ptr has been set to */
- batch_endall(); /* zero terminate all batch files */
- return NO;
- }
- #endif
- if(batchflg && batch->eof) { /* Close the batch file if at */
- batch_end(); /* the end of the file. */
- if(batchflg == 0) /* BREAK if batch processing */
- return NO; /* is complete. */
- continue;
- }
- if(!batch_open()) /* Open the file and read a line*/
- return YES; /* from the file */
- batch_read(line, NO); /* Read Line */
- if(batch->eof) /* If the end of the batch file */
- batch_close(); /* has been detected then close */
- /* the file. */
- if (*line == '?' || boot_key_scan_code == 0x4200) {
- optional_line(line);
- }
- if(*line == '@') { /* If first character in the */
- strcpy(line, line+1); /* command line is '@' donot */
- return NO; /* echo the command and move the*/
- } /* string down 1 character. */
- if (!cancel_prompt) {
- if(crlfflg && echoflg)
- crlf();
- prompt();
- }
- return echoflg;
- }
- if(!*kbdptr) { /* Set the Keyboard Input flag */
- keyin_flg = TRUE; /* after a initial command line */
- /* buffer has been exhausted */
- #if 1
- if (c_option) { /* insert an EXIT command if we */
- kbdptr = &kbdbuf[2]; /* are processing a /C command */
- strcpy(&kbdbuf[2],"exit");
- }
- #endif
- }
- if (!*kbdptr) { /* Check for existing line */
- /* NEIL */
- if(crlfflg && echoflg)
- crlf();
- /* NEIL end */
- prompt(); /* issue command line prompt */
- allow_pexec = FALSE;
- /* $x in prompt string may cause batchflg to be set. */
- /* If so we must jump to batch processing code. */
- if (batchflg) {
- cancel_prompt = TRUE;
- goto batch_restart;
- }
- kbdptr = ""; /* Force KBDPTR to point to ' '*/
- /* in case we get ABORTED and */
- /* drop through here again. */
- kbdbuf[0] = MAX_LINE; /* set max. input length */
- kbdbuf[kbdbuf[1]+2] = 'r'; /* Terminate current line. */
- #if defined(CDOSTMP)
- system(C_READSTR, kbdbuf); /* read a line */
- #else
- readline(kbdbuf);
- #endif
- crlf();
- kbdbuf[kbdbuf[1] + 2]=' '; /* terminate input */
- kbdptr = kbdbuf + 2;
- }
- s = kbdptr;
- while(*s) {
- if(*s == '"') /* Check for a " character and */
- quote = !quote; /* update the flag correctly */
- #if !defined(DOSPLUS)
- if(*s == ESC_CHAR && /* If the Escape character has */
- !quote && /* been specified then do not */
- ((*(s+1) == MULTI_CHAR) || (*(s+1) == BACK_CHAR))) {
- *line++ = *++s; /* process the following char. */
- s++;
- continue;
- }
- #endif
- #if defined(DOSPLUS) /* Disable MULTI_CHAR support */
- if(!(keyin_flg||c_option||k_option))
- /* after the init command line */
- #endif /* has been exhausted. */
- if(*s == MULTI_CHAR && /* If a Multiple command char */
- !quote) { /* and the QUOTE flag is FALSE */
- s++; /* then break the command here */
- break; /* and save the rest of the line*/
- } /* for next time. */
- #if FALSE /* defined(CDOSTMP) */
- if(*s == BACK_CHAR && /* If a Back Ground processing */
- !quote) { /* and the QUOTE flag is FALSE */
- s++; /* then treat as for MULTI_CHAR */
- back_flag = TRUE; /* except that the current */
- break; /* command is executed in the */
- } /* background. */
- #endif
- if(*s == PIPE_CHAR && /* If a Pipe enable character */
- !quote) { /* and the QUOTE flag is FALSE */
- s++; /* then break the command here */
- pipe_out = YES; /* and save the rest of the line*/
- break; /* for next time. */
- }
- copy_char(&line, &s); /* Just save the character */
- }
- *line = ' '; /* Terminate the Buffer */
- kbdptr = deblank(s); /* Copy the possibly null length*/
- return NO; /* string to KBDBUF for next */
- /* next invocation and save CCP */
- }
- MLOCAL VOID for_in(line) /* A FOR command is currently */
- BYTE *line; /* executing so build the line */
- { /* from the internal FOR data */
- BYTE *s,*t; /* initialized by CMD_FOR */
- BYTE *bp1, *fp;
- WORD i;
- FOREVER {
- fp = forptr->files; /* Get the next string and stop */
- if(strlen(fp) == 0) { /* if its the zero length string */
- *line = ' '; /* which marks the end of the FOR */
- crlfflg = YES; /* search list. */
- for_end();
- return;
- }
- if(!iswild(fp)) { /* If not an ambiguous file */
- forptr->sflg = NO; /* then update the FOR */
- forptr->files += strlen(fp)+1; /* pointer to the next file */
- break; /* in the search list. */
- }
- if(forptr->sflg) /* Search for the next file */
- i = ms_x_next(&forptr->search); /* file on the disk if */
- else /* FOR_SFLG otherwise get first */
- i = ms_x_first(fp, ATTR_RO, &forptr->search);
- if(i < 0) { /* If the search failed */
- forptr->sflg = NO; /* then update the FOR */
- forptr->files += strlen(fp)+1; /* pointer to the next file */
- continue; /* in the search list. */
- } /* and get the next entry */
- fp = (BYTE *) heap();
- strip_path(forptr->files, fp); /* Extract the Path */
- strcat(fp, forptr->search.fname); /* and then add the matching */
- forptr->sflg = YES; /* filename and update the */
- strupr(fp); /* variables. */
- break; /* Force name to uppercase */
- }
- s = forptr->cmd;
- t = line;
- while (*s && (t - line) < MAX_LINE) { /* Copy the command */
- if(*s == '%' && *(s+1) == forptr->forvar) { /* line looking for */
- s += 2; /* the imbedded %c and insert*/
- bp1 = fp; /* the current substition */
- while(*bp1 && (t - line) < MAX_LINE) /* string pointed at by FP */
- copy_char(&t, &bp1);
- continue;
- }
- copy_char(&t, &s);
- }
- *t = ' '; /* and terminate the string */
- }
- /*.pa*/
- /*
- * BATCH FILE CONTROL ROUTINES
- * ===========================
- *
- * The following routines provide the interface from COMMAND.COM to
- * a batch file. BATCH_START sets up all the local variables to enable
- * batch processing while BATCH_END terminates batch processing. BATCH_READ
- * reads a line of data from the batch file and expands it to contain the
- * command line variables and variables from the environment.
- */
- GLOBAL VOID batch_start(argv0, path, tail)
- BYTE *argv0; /* Invoking Command */
- BYTE *path; /* Complete filename */
- BYTE *tail; /* Command Line Options */
- {
- BYTE *s2;
- BYTE dirbuf[MAX_PATHLEN];
- WORD i;
- if(batchflg) /* If a batch file is currently */
- batch_close(); /* close it. So minimum number */
- /* of handles are used. */
- s2 = path; /* Save the original Path */
- if((path = d_check(path)) == NULL) /* Check that the file */
- return; /* exists. */
- batch_new(); /* new incarnation of batch */
- forptr = (FCONTROL *) NULL; /* Disable current FOR control */
- for_flag = NO; /* and Global FOR flag */
- /*
- * Generate the full path specification for the batch file
- * and store in the batch control information. If the user
- * has specified the full path use it otherwise determine the
- * full path using ms_x_curdir.
- */
- if (ddrive != -1 && *path != *pathchar) {
- ms_x_curdir(ddrive+1, dirbuf);
- sprintf(heap(), "%c:%s%s%s%s", ddrive + 'A',
- pathchar,
- dirbuf,
- (*dirbuf ? pathchar : ""),
- path);
- }
- else if (ddrive != -1)
- sprintf(heap(), "%c:%s", ddrive + 'A', path);
- else
- ms_x_expand(heap(), path);
- for (i=0; i<MAX_PATHLEN; i++) /* save the batch pathname */
- batch->batfile[i] = heap()[i];
- batch->batfile[MAX_PATHLEN-1] = 0;
- /*
- * Copy the invoking command and the individual elements
- * of the command line into a buffer ready for processing
- */
- batch->batcmd = (BYTE *)heap(); /* Initialize Parameter Buffer */
- strcpy(heap(), argv0); /* Copy the invoking command */
- heap_get(strlen(heap())+1); /* and protect the buffer */
- while(*tail) { /* While there are command line */
- s2 = (BYTE *)heap(); /* parameters copy them */
- while(*tail && strchr(batch_sep, *tail))
- tail = skip_char(tail);
- while(*tail && !strchr(batch_sep, *tail))
- copy_char(&s2, &tail);
- *s2++ = ' ';
- heap_get(strlen(heap()) + 1);
- }
- *(WORD *)heap_get(2) = 0; /* Double NULL is a terminator */
- /* for command line params */
- if(in_flag & REDIR_ACTIVE) /* If Input redirection has been */
- in_flag |= REDIR_BATCH; /* enabled for this command force*/
- /* it on for the complete command*/
- if(out_flag & REDIR_ACTIVE) /* If Output redirection has been*/
- out_flag |= REDIR_BATCH; /* enabled for this command force*/
- /* it on for the complete command*/
- batchflg++; /* increment batch flag */
- crlfflg = YES; /* print CR/LF after this */
- }
- GLOBAL VOID batch_endall() /* This terminates BATCH */
- { /* processing by closing ALL */
- while(batchflg) { /* active batch files */
- batch_end();
- }
- }
- GLOBAL VOID batch_end() /* This function is called for */
- { /* both NORMAL and ABNORMAL */
- if(batchflg == 0) /* termination of batch file */
- return; /* processing */
- boot_key_scan_code = 0;
- batch_close(); /* Close the Batch file */
- for_end(); /* Terminate Any FOR command */
- batch_old(); /* Restore the previous batch */
- /* control structures to heap */
- if(--batchflg == 0) {
- *batch_seg_ptr = 0;
- echoflg = echoflg_save2; /* Restore the original ECHO */
- crlfflg = YES; /* flag and set CR/LF flag when */
- } /* returning to the keyboard. */
- }
- MLOCAL BOOLEAN batch_open()
- {
- WORD h, i;
- BYTE *name;
- if(batch->eof) { /* If the End of the batch file */
- batch_end(); /* was discovered last time then*/
- return FALSE; /* End Batch file input and exit*/
- }
- if(batch->stream != CLOSED)
- return batch->stream;
- name = heap();
- for (i=0; i<MAX_PATHLEN; i++)
- name[i] = batch->batfile[i];
- while ((h = ms_x_open(name, OPEN_READ)) < 0) {
- err_flag = TRUE;
- eprintf(MSG_BATMISS, name); /* prompt for batch file */
- heap_get(strlen(name)+1);
- cmd_pause("");
- heap_set(name);
- }
- err_flag = FALSE;
- batch->stream = h;
- return TRUE;
- }
- GLOBAL VOID batch_close()
- {
- if(batchflg != 0 &&
- batch->stream != CLOSED) { /* Check if the batch file */
- batch_cnt = 0; /* currently open if YES */
- ms_x_close(batch->stream); /* then flush the internal */
- batch->stream = CLOSED; /* buffer and close file. */
- }
- }
- #if defined(DOSPLUS)
- GLOBAL VOID inherit_batch_file(bc)
- BCONTROL FAR *bc;
- {
- WORD i;
- BYTE FAR *p_heap;
- BYTE *l_heap;
- /* inherit any parent batch file first */
- if (bc->bcontrol) inherit_batch_file(bc->bcontrol);
- /* create a new batch structure */
- batch_new();
- batch->offset = bc->offset; /* continue at same offset */
- for (i=0;i<4;i++) batch->ret_offset[i] = bc->ret_offset[i];
- batch->batshift = bc->batshift;
- for (i=0; i<MAX_PATHLEN; i++) /* get the batch pathname */
- batch->batfile[i] = bc->batfile[i];
- batch->batfile[MAX_PATHLEN-1] = 0;
- /* get command line */
- p_heap = MK_FP(*parent_psp+16,bc->batcmd);
- l_heap = heap();
- while (1) {
- while(*p_heap) *l_heap++ = *p_heap++;
- *l_heap++ = *p_heap++;
- if (*p_heap == 0) {
- *l_heap = 0;
- break;
- }
- }
- heap_get(l_heap-heap());
- batchflg++;
- }
- GLOBAL VOID inherit_parent_state()
- {
- UWORD FAR *p;
- BCONTROL FAR *bc;
- UWORD root_psp;
- root_psp = *parent_psp;
- while(1) {
- p = MK_FP(root_psp-1,8);
- if (p[0] == 0x4F43 && p[1] == 0x4D4D &&
- p[2] == 0x4E41 && p[3] == 0x0044) break;
- p = MK_FP(root_psp,0x16);
- root_psp = *p;
- }
- p = MK_FP(root_psp+16,batch_seg_ptr);
- #if 0
- printf("batch_seg_ptr = %04X:%04Xn",p);
- printf("parent batch_seg_ptr = %04Xn",*p);
- #endif
- if (*p == 0 || *p == 0xFFFF) return;
- bc = MK_FP(*p,0);
- inherit_batch_file(bc);
- *p = 0;
- p = MK_FP(root_psp+16,&echoflg);
- echoflg = *p;
- }
- #endif
- GLOBAL VOID batch_new()
- /* save current batch file heap contexts to high memory */
- {
- BYTE *hp_start;
- WORD hp_size;
- UWORD i;
- BCONTROL FAR *bc;
- #if defined(CDOSTMP)
- UWORD FAR *ptr;
- #endif
- if (batchflg != 0)
- hp_start = batch->heap_start;
- else
- hp_start = heap();
- hp_size = heap() - hp_start;
- i = (sizeof(BCONTROL) + hp_size + 15)/16;
- mem_alloc(&bc, &i, i, i); /* allocate new batch structure */
- if (i == 0) { /* if we can't allocate one */
- longjmp(break_env, IA_HEAP);/* then pretend heap has run out*/
- } /* to force termination. */
- bc->bcontrol = batch; /* Link to Previous Structure */
- batch = bc; /* make this current batch struc*/
- batch->eof = NO; /* Have not found the EOF yet */
- batch->offset = 0L; /* start at beginning of File */
- for (i=0;i<4;i++) batch->ret_offset[i] = 0L;
- batch->batshift = 0; /* No Shift Factor */
- batch->stream = CLOSED; /* Batch file is not open */
- batch->fcontrol = forptr; /* Save current FOR control */
- batch->heap_start = hp_start; /* Save original heap */
- batch->heap_size = hp_size;
- for (i=0; i < hp_size; i++) {
- batch->save_area[i] = hp_start[i];
- }
- heap_set(hp_start); /* free up heap used by old batch */
- #if defined(CDOSTMP)
- ptr = MK_FP(pd->P_PSP, TmpPspEchoFlgPtr);
- *ptr = (UWORD)&echoflg;
- ptr = (UWORD FAR *) &ptr; /* coerce a FAR * to local data */
- i = FP_SEG(ptr); /* so we can get local data segment */
- ptr = MK_FP(pd->P_PSP, TmpPspDataSeg);
- *ptr = i; /* save local data segment */
- ptr = MK_FP(pd->P_PSP, TmpPspBatchSeg);
- *ptr = (UWORD)(((ULONG)batch) >> 16);
- #else
- /* Get segment address of batch and put it where novell */
- /* can find it. */
- *batch_seg_ptr = (UWORD)(((ULONG)batch) >> 16);
- #endif
- }
- MLOCAL VOID batch_old()
- /* restore current batch file heap contents from high memory */
- {
- BCONTROL FAR *bc;
- UWORD i;
- #if defined(CDOSTMP)
- UWORD FAR *ptr;
- #endif
- heap_set(batch->heap_start+batch->heap_size);
- for (i=0; i<batch->heap_size; i++) {
- batch->heap_start[i] = batch->save_area[i];
- }
- bc = batch;
- forptr = batch->fcontrol; /* Restore the previous for */
- for_flag = (BOOLEAN) forptr; /* control structures */
- batch = batch->bcontrol; /* restore ptr to previous batch */
- mem_free(&bc); /* free up batch memory */
- #if defined(CDOSTMP)
- ptr = MK_FP(pd->P_PSP, TmpPspBatchSeg);
- *ptr = (UWORD)(((ULONG)batch) >> 16);
- #endif
- }
- /*
- * Read lines repeatedly from the batch file until a line in
- * the correct format is read from the batch file or the EOF
- * has been reached.
- */
- MLOCAL VOID batch_read(line, goto_flg)
- BYTE *line; /* Command Line Buffer */
- BOOLEAN goto_flg; /* Goto Command Flag */
- {
- BYTE *l; /* we need to deblank line */
- do {
- batch_line(line, goto_flg); /* Read the next line from */
- l = deblank(line); /* the batch file and return*/
- if(*l != ';') {
- if(goto_flg && *l == ':') /* a line in the correct */
- return; /* format. */
- if(!goto_flg && *l != ':')
- return;
- }
- } while(!batch->eof);
- }
- /*
- * Read one line from the batch file and place the expanded data into
- * the buffer LINE.
- */
- MLOCAL VOID batch_line(line, goto_flg)
- BYTE *line; /* Command Line Buffer */
- BOOLEAN goto_flg; /* Goto Command Flag */
- {
- REG WORD i;
- REG BYTE *s;
- WORD n, env_start;
- BYTE c, *bp;
- BYTE env_str[128];
- BOOLEAN quote = FALSE;
- LONG old_offset;
- int j;
- env_start = NULL; /* Copy the environment into a */
- #if 0
- /* 'eject any line starting with 'rem' */
- old_offset = batch->offset;
- i=0;
- do{
- switch(c=*batch_ptr()){
- case 0x1a:
- batch->eof = YES; /* We have come to the end */
- c = 'r'; /* of the batch file so set */
- break; /* flag and mark end of line*/
- default:
- if (i < MAX_LINE)
- line[i++] = c;
- if (dbcs_lead(c)) {
- if ((c = *batch_ptr()) >= ' ' && i < MAX_LINE)
- line[i++] = c;
- }
- }/*switch*/
- }while(c!='r');
- if (*batch_ptr() != 'n') batch->offset--;
- line[i]=0;
- j=0;
- while(line[j]){
- if (line[j] != ' ')
- break;
- j++;
- }
- if (( strlwr(line[j]) == 'r') &&
- ( strlwr(line[j+1]) == 'e') &&
- ( strlwr(line[j+2]) == 'm') &&
- ( strlwr(line[j+3]) == ' ')){
- if (echoflg)
- printf("%sn",line);
- line[0]=' ';
- return;
- }
- batch->offset = old_offset;
- batch->eof = NO;
- #endif
- /*rbf-end*/
- /* process line */
- i = 0;
- do {
- switch(c = *batch_ptr()) {
- case ' ': /* In OS/2 install.bat file */
- #if 0
- if (i < MAX_LINE) /* "ECHO