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

📄 com.c

📁 一个dos操作系统DRDOS的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
		pipe_in = YES; pipe_out = NO;
		old_pipe = heap_get(strlen(out_pipe)+1);
		strcpy(old_pipe,out_pipe);
	    }

	    out_flag = NULL;
	}

	country.code = ms_s_country(&country);	/* re-init the Country data  */
#if 0
#if defined(DLS)
	dls_msg_crit();				/* re-init crit error msgs   */
#endif
#endif
}

/*.pa*/
/*
 *	ERROR_INIT is the "CRITICAL" error handler which will initialize
 *	the error handling code, displays error messages and clean-up the
 *	environment after an error has occurred.
 */
/*RG-00*/
/*MLOCAL VOID error_code(error)*/
VOID error_code(error)
/*RG-00-end*/
UWORD error;
{
	switch(error) {
	    case 0:				/* Setting JMPBUF. Enable    */
#if !defined(CDOSTMP)				/* break checking in case    */
		ms_set_break(YES);		/* this is the first time    */
#endif						/* through the command proc. */
 		return;

	    case IA_BREAK:
		putc('\r');			/* A CR here makes SideKick+ */
						/* look good when it	     */
						/* deinstalls itself	     */
/* The following two function calls close the batch file during an INT 23
   thus disallowing to continue with a batch file if the user chooses to
   do so after being prompted. However, there migh have been a reason why
   this has been inserted before which I don't know of. JBM */
/*		ms_x_close(5);			 ##jc## Close Unused Handles*/
/*		ms_x_close(6);			 ##jc## Close Unused Handles*/
		mem_free(&bufaddr);		/* Free External Copy Buffer */
#if defined(CDOSTMP)				/* On Concurrent DOS and     */
		bdos(DRV_RESET, 0xFFFF);	/* DOSPLUS reset the disk    */
		crlf();				/* when we get a Control-C.  */
#endif
		break;

	    case IA_STACK:			/* Stack Overflow Error      */
	    case IA_HEAP:			/* Heap Overflow Error	     */
		batch_endall(); 		/* Out of memory error	     */
		eprintf(MSG_BATNEST);		/* probably caused by nesting*/
		break;				/* batch files TOO deep.     */
		
	    case IA_FILENAME:			/* FileName Error	     */
		eprintf(ERR_FILE);		/* display an error message  */
		break;				/* and terminate the command */

	    default:
		eprintf(MSG_LONGJMP, error);
		break;
	}

	crlfflg = NO;				/* Reset CR/LF Flag	    */
}

/*
 *	This function is invoked after a CONTROL-BREAK or Critical Error
 *	during the execution of an internal function. Any BREAK specific
 *	cleanup is executed here. The break handler then restarts normal
 *	code execution by executing a LONGJMP.
 */
GLOBAL VOID CDECL int_break()
{
int	i;

	if (show_file_buf) mem_free(&show_file_buf);

	if (global_in_hiload) {
	    /* if ctrl-c pressed during a hiload, restore memory */
	    /* allocation strategy.				 */

	    for(i=1;i<10;i++) {		/* free up any UMB's we have */
		if (hidden_umb[i]) {
		    free_region(hidden_umb[i]);
		    hidden_umb[i] = 0;
		}
	    }
	    set_upper_memory_link(global_link);
	    set_alloc_strategy(global_strat);
	    global_in_hiload = 0;
	}

	err_ret = BREAK_EXIT;		/* Update the Global Error Return */
	longjmp(break_env, IA_BREAK);	/* Either Control-C or Critical   */
					/* Error Process Termination.	  */
}

/*.pa*/
/*
 *	This function parses the command line and extracts all unquoted
 *	>>, > and < character sequences and their corresponding filenames.
 *	The last redirection specification of the same type is used all
 *	previous references will be removed. Redirection will only be 
 *	enabled if no redirection of the same type is already active.
 *	ie. If redirection is enabled on a batch file all redirection
 *	commands of the same type inside the file are ignored.
 */
GLOBAL BOOLEAN parse(s)		   	/* Parse the command line looking    */
BYTE *s;				/* for Redirection commands	     */
{
REG BYTE *bps;
BYTE *bpi, *bpo;
BYTE infile[MAX_FILELEN];		/* Input Redirection FileName	    */
BYTE outfile[MAX_FILELEN];		/* Output Redirection FileName	    */
BYTE cmdbuf[128];			/* Command buffer for Aborted Pipe  */
WORD h;
BOOLEAN quote = NO;			/* Check for Quoted Statements	     */
BOOLEAN append; 			/* Out Redirection Append	     */

	crlfflg = YES;			/* Force a CRLF in case an error     */
					/* occurs in the command line parsing*/

	for(bpi = NULL, bpo = NULL; *s; s++) {

	    if(*s == '"') {			/* Maintain the correct    */
		quote = !quote; 		/* Status of the QUOTE flag*/
		continue;
	    }

	    if(quote)				/* If the QUOTE flag is     */
		continue;			/* then skip the following  */

	    if(*s == '>') {			/* Found Output redirection  */
		bpo = outfile;			/* Character extract the Path*/
		bps = s+1; append = FALSE;	/*  and save locally	     */

		if(*(bps) == '>') {		/* Check for append mode     */
		    append = TRUE;
		    bps++;
		}

		bps = get_filename(bpo, deblank(bps), NO);
						/* Extract the FileName	     */
		bps = deblank(bps);
		strcpy(s--, bps);		/* Then remove data from Line*/
		continue;			/* S decrement to force new  */
	    }					/* next character to be read */

	    if(*s == '<') {			/* Found Input redirection   */
		bpi = infile;			/* Character extract the Path*/
		bps = get_filename(bpi, deblank(s+1), NO);
						/* Extract the FileName	     */
		bps = deblank(bps);
		strcpy(s--, bps);		/* Then remove data from Line*/
	    }					/* S decrement to force new  */
	}					/* next character to be read */


#if defined(DOSPLUS)
	/* only redirect if not already redirected */
	if ((pipe_in || bpi) && (!(in_flag & REDIR_ACTIVE))) {
#else
	if(pipe_in || bpi) {			/* Check for any redirection */
	    if(in_flag & REDIR_ACTIVE) {	/* If Standard Input has been*/
		eprintf(MSG_INACTIVE);		/* redirected then fail      */
		return FAILURE;
	    }
#endif

	    bpi = pipe_in ? out_pipe : infile;	/* BPI points to the filename*/

	    h = ms_x_open(bpi, OPEN_READ);
	    if(h < 0) {
						/* Attempt to Open the file  */
		e_check(h);			/* || device specified and   */
		return FAILURE; 		/* print an error message if */
	    }					/* we fail.		     */
		
	    psp_poke(STDIN, psp_poke(h, 0xFF));	/* Force New input file onto */
	    					/* Standard Input and close  */
	    in_flag = REDIR_ACTIVE;		/* the returned handle	     */
	}
		
#if defined(DOSPLUS)
	/* only redirect if not already redirected */
	if ((pipe_out || bpo) && (!(out_flag & REDIR_ACTIVE))) {
#else
	if(pipe_out || bpo) {			/* Check for any redirection */
	    if(out_flag & REDIR_ACTIVE) {	/* If Standard Output has been*/
		eprintf(MSG_OUTACTIVE);		/* redirected then fail      */
		return FAILURE;
	    }
#endif

	    if(pipe_out) {
#if defined(CDOSTMP)
		out_pipe[0] = *SYSDATB(TEMPDISK)+'A';	/* Initialise the DRIVE */
		out_pipe[3] = '\0';			/* Terminate String	*/
#else
		if (!env_scan("TEMP=",out_pipe)) {
		    
		    /* if TEMP != "d:\" check its a valid directory */
		    if ((strlen(out_pipe) > 3) || (out_pipe[1] !=':')) {

		    	h = ms_x_chmod(out_pipe,ATTR_ALL,0);
			if ((h<0) || !(h&0x10)) goto assume_root;	
		    }
		    append_slash(out_pipe);
		}
		else {
assume_root:
		    get_out_pipe();		/* get string from low_seg */
		    out_pipe[0] = drive+'A';	/* Initialise the DRIVE */
		    out_pipe[3] = '\0';		/* Terminate String	*/
		}
#endif
		bpo = out_pipe;
		h = ms_x_unique(out_pipe, ATTR_SYS);

	    }
	    else {				/* Create the output file if */
		bpo = outfile;			/* not Appending or the OPEN */
						/* on the file fails.	     */
		if(!append || (h = ms_x_open(bpo, OPEN_WRITE)) < 0)
		    h = ms_x_creat(bpo, 0);
	    }

	    if(e_check(h) < 0) {		/* Display any error message */
	    	if(pipe_out) {			/* Pipe'ed command then     */
		    pipe_out = NO;		/* absorb the second command*/
		    getcmd(cmdbuf); 		/* return FAILURE on error   */
		    crlfflg = YES;
		}
		return FAILURE;
	    }

	    if(append)				/* If in APPEND mode then    */
		ms_x_lseek(h, 0L, 2);		/* seek to the end.	     */

	    psp_poke(STDOUT, psp_poke(h, 0xFF));/* Force New input file onto */
	    					/* Standard Ouput and close  */
	    out_flag = REDIR_ACTIVE;		/* the returned handle	     */

	    if(pipe_out)
		out_flag |= REDIR_PIPE;
	}

	crlfflg = NO;
	return SUCCESS;
}


MLOCAL	BOOLEAN docmd_offer(BYTE *cp, BYTE *command, UWORD internal_flag)
{
BYTE	*lcp;
int	i;
UWORD	int2f_gotit = 0;

	lcp = heap();

	lcp[0] = 0x80;		/* copy command line to buffer	*/
	lcp[1] = strlen(cp);	/*   with "readline" format	*/
	for (i=0;i<lcp[1];i++)
	    lcp[i+2]=cp[i];
	lcp[i+2] = '\r';

				/* offer command line to interested parties */
	if(int2f_gotit = docmd_int2f(lcp,command,internal_flag))
	    return 1;		/* if they want it, docmd_offer = TRUE 	    */
				

	for(i=command[0];i<8;command[1+(i++)]=' ');
				/* if length is altered, space fill */

	for(i=0;i<lcp[1];i++)
	    cp[i] = lcp[i+2];	/* copy it back in case it was changed */
	cp[i] = 0;		/* null terminate it */
	return 0;		/* docmd_offer = FALSE, cos the int2f didn't want it */
}

GLOBAL VOID docmd(cp, internal)
REG BYTE  *cp;			/* Command Line To be Parsed	*/
BOOLEAN   internal;		/* Search for INTERNAL Commands */
{
	REG S_CMD FAR *s_cmd_p;
	WORD	  i;
	BYTE FAR  *cpf;
	BYTE 	  loadfile[MAX_FILELEN];
	BYTE	  *cp1, *lcp;
	UWORD	  loadtype;
	BYTE	  argv0[MAX_FILELEN];

	heap_get(0);				/* check for stack overflow */
	lcp = cp;				/* in case 1st parse fails.. */
        crlfflg = YES;

	for(i=0;i<12;loadfile[i++]=' ');	/* initialise with blanks */
	ms_f_parse(loadfile, cp, 1);		/* parse for internal cmd */
	for(i=7;(i>=0) && (loadfile[i+1] == ' '); i--);
	loadfile[0] = i+1;			/* set length of cmd */
	
	for(;strchr(valid_sepchar,*cp);cp++);	/* ignore leading separators */
	for(;is_filechar(cp);cp++);		/* skip the command itself */
						/* offer command line to */
						/* interested parties */
	if(docmd_offer(lcp,loadfile,0xFF00+strlen(cp)))	/* If they want it */
		return;					/* we don't */
	
	cp = lcp;
	if ((cp[0] != 0) && (cp[1] == ':')) cp+=2;
	for(;strchr(valid_sepchar,*cp);cp++);
	for(;is_filechar(cp);cp++);		/* skip the command itself */

	cp1 = cp;
	i = 0;
	while (*cp1 != '\0') {
	    if (*cp1 == '"')
		i ^= 1;
	    if (is_blank(cp1) == 2 && !i)	/* replace each KANJI space */
		*cp1 = *(cp1 + 1) = ' ';	/* with one ASCII space */
	    cp1 = skip_char(cp1);
	}

	s_cmd_p = (S_CMD FAR *)farptr((BYTE *)&cmd_list[0]);
	while(internal && s_cmd_p->cmnd) {	/* while more builtins	*/
	    cpf = cgroupptr(s_cmd_p->cmnd);
	    for(i=0;cpf[i];i++)			/* make upper case copy */
	    	argv0[i]=toupper(cpf[i]);
	    for(;i<8;argv0[i++]=' ');		/* space fill it to 8 */

	    if(!strncmp(argv0,loadfile+1,8)) {	/* Is this a match ? */

#if !defined(NOHELP)
		/* Handle  /H or /? in command */
		strcpy(heap(),deblank(cp));
		if(!strnicmp(heap(),"/h",2)||!strnicmp(heap(),"/?",2)) {
		    if (s_cmd_p->help_index != -1)
		    	show_help(s_cmd_p->help_index);
		    crlf();
		    return;
		}
#endif

		/* check for embedded commands in IF that only have meaning in
                		that context */
		if(s_cmd_p->needparm==PARAM_IFCONTEXT) {
		    if(if_context==FALSE) break;
		}

		cp1 = deblank(cp);		/* Remove Blanks from Options*/

		if(s_cmd_p->needparm!=PARAM_NONE /* if a parameter is needed */
		   && !*cp1) {			/* but none is supplied      */

		    switch ((UWORD)s_cmd_p->needparm)	/* display an error message  */
		    {
		    case PARAM_NEEDFILE: eprintf(MSG_NEEDFILE); break;
		    case PARAM_NEEDPATH: eprintf(MSG_NEEDPATH); break;
		    case PARAM_NEEDDEV:	 eprintf(MSG_NEEDDEV);  break;
		    default:		 eprintf(MSG_SYNTAX);   break;
		    }
		    eprintf("\n");
		    return;			/* ignore the command	     */
		}
		
		page_len = get_lines_page();    /* so /P works in 43 and 50 */
						/* line modes */
		(*s_cmd_p->func)(cp1, cp);	/* Just Invoke builtin	     */
		return;
	    }
	    s_cmd_p ++; 			/* compare with next command */
	}

	/* it's not an internal command - could it be help ? */
        if ((!strnicmp(lcp,"/h",2))||(!strncmp(lcp,"/?",2))) {
            show_help(0);
	    s_cmd_p = (S_CMD FAR *)farptr((BYTE *)&cmd_list[0]);
	    while(s_cmd_p->cmnd) {
	        cpf = cgroupptr(s_cmd_p->cmnd);
                printf("%s\t",cpf);
	        s_cmd_p++;
	    }
	    crlf();
	    return;
	}

	/* command is not builtin, must be disk based so determine path ... */
	if(docmd_offer(lcp,loadfile,strlen(cp)))	/* offer command line to */
		return;				/* interested parties */
		/* If they want it, we don't */

	cp = get_filename(loadfile, lcp, NO);
	strcpy(argv0, loadfile);		/* the original command name */
	strlwr(loadfile);

	if((loadfile[strlen(loadfile)-1] == '\\') ||
	   ((strlen(loadfile) == 2) && (loadfile[1] == ':'))) {
	    if(!dos_parse_filename(loadfile) && d_check(loadfile)) {
		if (ddrive != -1)
		{
		    ms_drv_set(ddrive);		/* then check the requested */
		    drive = ddrive;		/* drive and make it the    */
		    crlfflg = NO;		/* default if OK.	    */
		}
	    }
	    else {
		eprintf(ERR15);
		crlf();
	    }
	    return;
	}

	if (strcmp(loadfile,"________") == 0) {
		ms_x_first("________.???",ATTR_HID+ATTR_STD,(DTA *) heap());
		strcpy(loadfile,"C:\\________.COM");
	}
	else if((i = findfile(loadfile, &loadtype)) < 0) {
	    if(i == ED_FILE ||		/* Determine the full	*/
	       i == ED_ROOM || 		/* path and type of the */
	       i == ED_PATH)	{	/* command and return if*/
		    eprintf(MSG_BADCMD); /* file or command cannot be located */
	    }
	    else {
		e_check(i);
	    }
	    return;
	}


	if(!env_scan(msg_comspec, heap()))	/* If COMSPEC is defined   */
	    set_reload_file();			/* then update RELOAD_FILE */

	doexec(argv0, loadfile, loadtype, cp);	/* Load the file	*/
	allow_pexec = TRUE;
}


/*
 *	FindFile searches the file system copying the actions of the 
 *	Concurrent DOS P_PATH function. If this is TMP for Concurrent 
 *	DOS then use the system call otherwise use the C function.
 *
 *	If no extension is specified then check the file types in
 *	the following order .CMD, .COM, .EXE, .BAT
 *
 *	If a Path is specified then just check that location otherwise
 *	check the current directory and then all entries in the path.
 */
#if !defined(CDOSTMP)
GLOBAL WORD CDECL findfile(loadpath, loadtype)
BYTE	*loadpath;		/* Command Name expanded to full path	*/
UWORD	*loadtype;		/* Command file Type			*/
{
	REG BYTE *s;

⌨️ 快捷键说明

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