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

📄 com.c

📁 一个dos操作系统DRDOS的源码
💻 C
📖 第 1 页 / 共 4 页
字号:
	BYTE	sppath[MAX_PATHLEN];		/* Buffer for the optional  */
						/* load path.		    */
	BYTE	fname[8+1+3+1+8+1];		/* Buffer for the filename */
						/* optional extension and   */
						/* password		    */
	BYTE	*path;				/* Environment Load path    */
	BYTE	*ftype; 			/* Optional file type	    */
	BYTE	*pwd;				/* Optional Password	    */
	BYTE	*envpath;			/* current PATH= in env     */
	WORD	i, ret;
#if !STACK
	BYTE	pathbuf[MAX_ENVLEN];		/* temporary path buffer    */
#endif

	strip_path(loadpath, sppath);		/* isolate the optional path*/
	ftype = loadpath+strlen(sppath);	/* get the Filename Address */

	if(strlen(ftype) < sizeof(fname))	/* If the filename is not   */
	    strcpy(fname, ftype);		/* too long then copy to an */
	else					/* internal buffer otherwise*/
	    longjmp(break_env, IA_FILENAME);	/* break with FILENAME error*/

	if((ftype = strchr(fname, '.')) != 0) {	/* then extract the optional*/
	    *ftype++ = '\0';			/* file type from the name  */
	    pwd = ftype;
	}
	else {					/* If no type has been	    */
	    ftype = NULLPTR;			/* specified then make it   */
	    pwd = fname;			/* file type a NULL pointer */
	}

	if ((ret = ms_x_open (fname, 0)) > 0) {	/* don't exec a device in   */
	    i = isdev (ret);			/* any shape or form	    */
	    ms_x_close (ret);
	    if (i)
		return (ED_FILE);
	}

#if defined(PASSWORD)
	if((pwd = strchr(pwd, *pwdchar)) != 0)  /* Finally extract the      */
	    *pwd++ = '\0';			/* optional password if none*/
	else					/* exists then default to a */
	    pwd = NULLPTR;			/* NULL pointer.	    */
#endif

	if(ftype) {				/* If a file type has been  */
	    for(i=0; ftypes[i]; i++)		/* specified then check that*/
		if(!strcmp(ftype, ftypes[i]))	/* is legal and return an   */
		    break;			/* error if not.	    */

	    if(!ftypes[i])			/* If an illegal filetype   */
		return ED_FILE; 		/* has been given then	    */
	}					/* return FAILURE	    */

	*loadtype = i;				/* Save the Load File Type  */

	/*
	 *	Check if a path is currently defined if YES then get
	 *	a copy of the path and save locally on the heap. Protecting
	 *	it against being overwritten.
	 */

	if(!env_scan(msg_patheq, heap())) {
	    envpath = heap();
	    while (*envpath) {			/* process path in env	 */
		if(dbcs_lead(*envpath))		/* so delimiters are the */
		    envpath++;			/* pathchar we expect	 */
		else
		    if((*envpath == '/') || (*envpath == '\\'))
			*envpath = *pathchar;
		envpath++;
	    }
#if STACK
	    envpath = stack(strlen(heap()) + 1);
#else
	    envpath = &pathbuf[0];
#endif
	    strcpy(envpath, heap());
	}
	else
	    envpath = "";

	/*
	 *	First attempt to load the file from the default/specified
	 *	path and then if no path was specified attempt to load the
	 *	file from all the entries in the search path defined in the
	 *	environment.
	 */

	if(*sppath)
	    path = sppath;
	else
	    path = "";

	do {
	    i = checkfile(loadpath, loadtype, path, fname, ftype, pwd);

	    switch (i)
	    {
	      case SUCCESS:
		strupr(loadpath);
		return SUCCESS;
	      case ED_FAIL:
	      case ED_DRIVE:			/* if bad drive in search  */
		if ((!*sppath) && (*path))	/* path, print msg & carry on*/
		{
		    eprintf(MSG_PATHDRV);
		    i = ED_FILE;
		    break;
		}
	      default:
		break;				/* get next search path	   */
	    }

	    path = envpath;			/* Set PATH to the next     */
	    if((s=strchr(envpath, ';')) != 0) {	/* element in the search path*/
		while (*s == ';') {		/* Skip over extra semicolons*/
		    *s = 0;
		    s++;
		}
		envpath = s;
	    }
	    else
		envpath = "";			/* path exhausted, -> null */

	    /* If you type FILENAME.EXE, it will search the current drive then */
	    /* the path. If you type C:\DIR\FILENAME.EXE, it will search */
	    /* C:\DIR. Now, if you type C:FILENAME.EXE, it will search the */
	    /* current directory on C:, then path. This is done by resetting */
	    /* sppath after the first run through, if it is just D:	*/
	    if((strlen(sppath) == 2) && (sppath[1] == ':'))
		sppath[0] = '\0';

	} while(!*sppath && *path);

	return i;
}

/*
 *	CHECKFILE generates the full path of the load file and
 *	attempts to open the file. If the file is located and
 *	can successfully be opened return SUCCESS with the full
 *	path in LOADPATH and the LOADTYPE initialised.
 *
 *	If no file extension has been specified then use the standard
 *	search order.
 *
 *	ATTR_SEARCH specifies the attributes used to locate the file
 *	to be loaded.
 */

#define	ATTR_SEARCH ATTR_STD + ATTR_HID

MLOCAL WORD checkfile(loadpath, loadtype, path, fname, ftype, pwd)
BYTE	*loadpath;
UWORD	*loadtype;
BYTE	*path, *fname, *ftype, *pwd;
{
	UWORD	type;
	WORD	ret;
	DTA	search;
	BYTE	curpath[MAX_PATHLEN+1];

	if((path = d_check(path)) == NULL)	/* Remove the drive specifier*/
	    return ED_DRIVE;			/* and return on Error.	     */
/*	get path starting from root. n.b. don't use ms_x_expand (func 60h)   */
/*	as it upsets Novell						     */

	if (ddrive != -1)
	{
	    sprintf(loadpath, "%c:%c", ddrive + 'A', *pathchar);
	    if((*path == '\\') || (*path == '/'))  /* If path is absolute then */
		strcpy(loadpath+2, path);	   /* just append to drive	    */
	    else {				   /* Otherwise append the     */
		ms_x_curdir(ddrive+1, loadpath+3); /* path to the drive and    */
		if(*fptr(loadpath))		   /* current subdirectory.    */
		    append_slash(loadpath);
		strcat(loadpath, path);
	    }
	}
	else
	    ms_x_expand(loadpath,path);


	if(*fptr(loadpath))
	    append_slash(loadpath);

	strcat(loadpath, fname);		/* Add the FileName	     */
	strcat(loadpath, ".");
	path = loadpath + strlen(loadpath);	/* Save the Extension Offset */

#if defined(PCDOS)
/*
 *	If running under PCDOS the check if any extension has been specified
 *	if not then search first for filename.* and return if no match occurs
 *	This will be quicker than opening each file in turn.
 */
	if(!ftype) {
	    strcat(path, "*");
	    if((ret = ms_x_first(loadpath, ATTR_SEARCH, &search)) < 0) {
		if( ret == ED_FILE ||	    /* Abort if an error occurs     */
		    ret == ED_ROOM ||	    /* but ignore File not Found    */
		    ret == ED_PATH)	    /* and invalid path errors	    */
		    return ED_FILE;
		else
		    return e_check(ret);
	    }
	}
#endif

	if (ftype == 0)
	    type = COM_FILETYPE;	/* Initialize the Type Index	*/
	else				/* correctly depending on the	*/
	    type = *loadtype;		/* initial file type.		*/

	do {
	    strcpy(path, ftypes[type]);	/* Add the first file type  */

#if defined(PASSWORD)
	    if(pwd) {			/* followed by the optional */
		strcat(path, pwdchar);	/* password and attempt to  */
		strcat(path, pwd);	/* open the file.	    */
	    }
#endif

	    if((ret = ms_x_first(loadpath, ATTR_SEARCH, &search)) < 0) {
		if(ret == ED_PATH)	/* Stop scanning this	   */
		    return ED_FILE;	/* element of the path if  */
					/* it is invalid.	   */
#if 0
		if(ret != ED_FILE && ret != ED_ROOM)
		    return ret;
#endif
	    }
	    else {
		*loadtype = type;	/* Set the correct loadtype */
		return SUCCESS;		/* and return SUCCESS	    */
	    }
	    if (++type > BAT_FILETYPE)
#if defined(DOSPLUS) || defined(NETWARE)
		type = COM_FILETYPE;
#else
		type = CMD_FILETYPE;
#endif
	} while(!ftype && (type != COM_FILETYPE));
	return ED_FILE;
}
#endif

MLOCAL BOOLEAN doexec(argv0, loadpath, loadtype, tail)
BYTE	*argv0;			/* Invoking Command		*/
BYTE	*loadpath;		/* Fully expanded filename	*/
UWORD	loadtype;		/* File Type .BAT, .EXE etc.	*/
BYTE	*tail;			/* Command line options		*/
{
	WORD	ret;
	WORD	i;
	BYTE	*s;
#if !STACK
	BYTE	tailbuf[128];
#endif

#if 0
printf("DOEXEC Load File \"%s\" Command Line \"%s\"\n",
				loadpath, (tail ? tail : ""));
#endif


	if(loadtype == BAT_FILETYPE) {	    /* if Batch file then:-	     */
	    
	    if (batchflg == 0) echoflg_save2 = echoflg;
	    
	    ret = echoflg;		    /* Save the Current ECHO State   */
	    batch_end();		    /* Close any Existing Batch file */
	    echoflg = ret;		    /* restore the ECHO status	     */
	    batch_start(argv0, loadpath, tail); /* and initialize the new batch  */
	    return YES; 		    /* use "CALL" to nest batches.   */
	}
					/* if CMD, COM or EXE		     */
	if(batchflg)			/* close the BATCH file if OPEN cos  */
	    batch_close();		/* some programs update the running  */
					/* batch file.			     */

	s = deblank(tail);		/* No SPACE before options   */
	if(!*s)				/* if this is a blank line   */
	    tail = s;

#if defined(CDOSTMP)
	ret = exec(loadpath, loadtype, tail, back_flag);
#else
	ms_set_break(break_flag);
#if STACK
	s = stack(strlen(tail)+2)+1;
#else
	s = &tailbuf[1];
#endif
	tail = strcpy(s, tail) - 1;
	*tail = (UBYTE) strlen(tail+1);
	strcat(tail+1, "\r");
#if !defined(FINAL)
	save_psp();
#endif
	ret = exec(loadpath, loadtype, tail, back_flag);
#if !defined(FINAL)
	check_psp();
#endif
	init_switchar();		/* switch character may have changed */
	break_flag = ms_set_break(YES);
#endif

	/*
	 *	Novell use the MS_DRV_GET function to detect abnormal
	 *	program termination. They assume this function is only
	 *	called by the command processor when a child has terminated.
	 *	They close all Remote Handles when the parent command
	 *	processor calls this function.
	 */
	drive = ms_drv_get();	 		/* get default drive.	     */

	for (i=5;i<20;i++) ms_x_close(i);	/* Close all handles */

	if(ret < 0) {			/* Get the returned Error Code	*/
#if defined(CDOS) || defined(CDOSTMP)
	    if(ret == ED_ENVIRON)	/* Check for an Environment	*/
		ret = (-255);		/* error this is really 	*/
#endif					/* a resource unavailable.	*/

					/* Print a message if the exec	*/
	    e_check(ret);		/* went wrong otherwise get the */
					/* completion status and return */
	    return FAILURE;
	}

	err_ret = ms_x_wait();
	return YES;
}

#if !defined(CDOSTMP)
VOID	FAR CDECL	int2e_handler (cmd)
BYTE	*cmd;
{
BYTE	*p;
jmp_buf save_jmpbuf;

/*	save the normal setjmp environment and reset it to ourselves	*/
/*	so that the int2e caller does not get aborted on criterr or	*/
/*	Control break							*/

    memmove (&save_jmpbuf, &break_env, sizeof (jmp_buf));

    if (setjmp (break_env) == 0) {

	if ((p = strchr (cmd, 0xd)) != NULL)
	    *p = '\0'; 

	int2e_start();
	
	docmd (deblank (cmd), TRUE);

/*	if int2e is executing a batch file, do not return until all	*/
/*	batch file commands have been processed. Loop round as in main	*/
/*	loop								*/

	while (batchflg > 0)
	{
	    cmd_loop (cmd);
	}
	
	int2e_finish();
    }
    memmove (&break_env, &save_jmpbuf, sizeof (jmp_buf));
}


MLOCAL VOID init_switchar()
{
	*switchar = ms_switchar();		/* get switch character      */
	if (*switchar == '/')			/* if not UNIX path char     */
	    *pathchar = '\\';			/*   then be compatible      */
	else
	    *pathchar = '/';
}

#endif

#if defined(DOSPLUS)

GLOBAL VOID process_config_env()
{
	BYTE FAR *config_env;
	WORD i;
	BYTE buff[128];
	BYTE *s;

	config_env = get_config_env();
	if (config_env) {
		FOREVER {		
			i = 0;
			while ((*config_env) && (*config_env!=0x1A) && 
			       (i < 127)) {
				
				buff[i++] = *config_env++;
			}
			if (i == 0) {
			   while (*config_env != 0x1A) config_env++;
			   config_env++;
			   boot_key_scan_code = * ((UWORD far *) config_env);
			   break;
			}
			buff[i] = 0;
			cmd_set(buff);    
		    	while (*config_env) config_env++;
			config_env++;
		}
#if 0
		s = heap();
		if (!env_scan("HOMEDIR=",s)) {
			if (s[1] == ':') ms_drv_set(toupper(*s)-'A');
			ms_x_chdir(s);
		}
#endif
	}
}
#endif

#if !defined(FINAL)
void	save_psp()
{
	BYTE far *fp;
	WORD	i;
	
	fp = MK_FP(_psp,0);

	psp_xsum = 0;
	for  (i=64;i<128;i++) psp_xsum += fp[i];
}

void	check_psp()
{
	BYTE far *fp;
	WORD	xsum;
	WORD	i;

	fp = MK_FP(_psp,0);
	
	xsum = 0;
	for (i=64;i<128;i++) xsum += fp[i];
	
	if (xsum != psp_xsum) {
	    printf("BETA DEBUG ERROR: Need more stack!\n");
	    printf("Press a key to continue.\n");
	    getch();
	}
}
#endif

⌨️ 快捷键说明

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