⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 batch.c

📁 一个dos操作系统DRDOS的源码
💻 C
📖 第 1 页 / 共 5 页
字号:
/*
;    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 '\r\n', 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 = '\0';

	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 '\0'*/
					/* 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]='\0'; /* 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 = '\0';			/* 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 = '\0';		/* 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.	     */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -