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

📄 batch.c

📁 DOS源码
💻 C
📖 第 1 页 / 共 5 页
字号:
	    }

	    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 = '\0';	 			/* 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++ = '\0';
	    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:%04X\n",p);
	printf("parent batch_seg_ptr = %04X\n",*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("%s\n",line);
		line[0]='\0';  
		return;
		}

	batch->offset = old_offset;
	batch->eof    = NO;

#endif
/*rbf-end*/
	
/* process line */
	i = 0;
	do {
 	    switch(c = *batch_ptr()) {
		case '\0':			/* In OS/2 install.bat file  */
#if 0
		    if (i < MAX_LINE)		/* "ECHO \0" displays blank  */
			line[i++] = '\r';	/* line - so we insert a CR  */
		    while (c != '\r') {		/* then swallow rest of line */
			c = *batch_ptr();	/* read next character - if  */
			if (c == 0x1a)		/* it's an EOF mark then use */
			    goto end_of_file;	/* end-of-file code else end */
		    }				/* up falling into '\r' code */
#else
		    c = *batch_ptr();
		    if ((c == '\r') && (i < MAX_LINE))
			line[i++] = '\r';
#endif

⌨️ 快捷键说明

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