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

📄 cmd.c

📁 DOS操作系统源代码,研究操作系统用. 包括了dos的所有源文件
💻 C
📖 第 1 页 / 共 2 页
字号:
			}
			DosSeek(Handle, 2, 0l);
		}
		else
			Handle = DosCreat((BYTE FAR *)Output, D_NORMAL | D_ARCHIVE);

		if((Handle < 0) || (!DosForceDupHandle(Handle, STDOUT, (COUNT FAR *)&ErrorCode)))
		{
			RestoreIO(-1, OldStdout);
			error_message(INTERNAL_ERR);
			return;
		}
		DosClose(Handle);
	}

	for(argc = 0; argc < 16; argc++)
	{
		argv[argc] = (BYTE *)0;
		args[argc][0] = '\0';
	}
	lp = scanspl(cmd_line, args[0], '/');

	if(args[0][0] == '@')
	{
		at_FLAG = TRUE;
		index++;
	}
	else
		at_FLAG = FALSE;

	/* If preceeded by a @, swallow it, it was taken care of	*/
	/* elsewhere.  Also, change case so that our command verb is	*/
	/* case sensitive.						*/
	while(args[0][index] != '\0')
	{

		if(at_FLAG)
			args[0][index-1] = tolower(args[0][index]);
		else
			args[0][index] = tolower(args[0][index]);
		index++;
	}
	if(at_FLAG)
		args[0][index-1] = '\0';

	argv[0] = args[0];
	/* this kludge is for an MS-DOS wart emulation */
	tail = skipwh(lp);

	for(argc = 1; argc < NPARAMS; argc++)
	{
		lp = scan(lp, args[argc]);
		if(*args[argc] == '\0')
			break;
		else
			argv[argc] = args[argc];
	}

	if(*argv[0] != '\0')
	{
		/* Look for just a drive change command, and execute	*/
		/* it if found.						*/
		if(argv[0][1] == ':' && argv[0][2] == NULL)
		{
			BYTE c = argv[0][0];

			if(c >= 'a' && c <= 'z')
				c = c - 'a' + 'A';
			if(c >= 'A' && c <= 'Z')
				DosSetDrive(c - 'A');
		}

		/* It may be a help command request.			*/
		else if((argv[1][0] == switchchar) &&
			 (argv[1][1] == '?'))
		{
			strcpy(tail, " ");
			strcat(tail, argv[0]);
			strcat(tail, "\r\n");
			argc = 2;
			argv[1] = argv[0];
			argv[0] = "help";
			argv[2] = 0;
			ExecCmd(argc, argv);
			if(IORedirected)
				RestoreIO(OldStdin, OldStdout);
		}
		/* do a normal command execution			*/
		else
		{
			p = lookup(commands, argv[0]);
			(*(p -> func))(argc, argv);
			if(IORedirected)
				RestoreIO(OldStdin, OldStdout);
		}
	}
}


BOOL prompt(argc, argv)
WORD argc;
BYTE *argv[];
{
	BYTE *p;
	BYTE *cmd = "PROMPT";

	if(argc == 1)
	{
		p = EnvLookup(cmd);
		if(p != (BYTE *)0)
			scopy(p, prompt_string);
		else
		{
			scopy(dflt_pr_string, prompt_string);
			EnvClearVar(cmd);
		}
	}
	else
	{
		/* Trim trailing newline				*/
		for(p = tail; (*p != '\r') && (*p != '\n'); p++)
			;
		*p = '\0';

		/* should be scopy(argv[1], &pr_string[1]); but to	*/
		/* emulate an MS-DOS wart, is				*/
		scopy(tail, prompt_string);

		/* Now set the environment variable for all children to	*/
		/* see.							*/
		EnvSetVar(cmd, prompt_string);
	}
	return TRUE;
}


struct table *lookup(p, token)
struct table *p;
BYTE *token;
{
	while(*(p -> entry) != '\0')
	{
		if(strcmp(p -> entry, token) == 0)
			break;
		else
			++p;
	}
	return p;
}


VOID RestoreIO(DupStdin, DupStdout)
{
	COUNT ErrorCode;

	if(DupStdin >= 0)
	{
		if(!DosForceDupHandle(DupStdin, STDIN, (COUNT FAR *)&ErrorCode))
			error_message(INTERNAL_ERR);
		DosClose(DupStdin);
	}

	if(DupStdout >= 0)
	{
		if(!DosForceDupHandle(DupStdout, STDOUT, (COUNT FAR *)&ErrorCode))
			error_message(INTERNAL_ERR);
		DosClose(DupStdout);
	}
}


BOOL ExecCmd(argc, argv)
COUNT argc;
BYTE *argv[];
{
	exec_blk exb;
	COUNT err;
	BYTE tmppath[64];
	COUNT idx;
	BOOL ext = FALSE;
	BYTE *extp;
	COUNT len;
	BYTE *lp;
	CommandTail CmdTail;
	fcb fcb1, fcb2;
	static BYTE *extns[2] =
	{
		".com",
		".exe"
	};
	static BYTE *batfile = ".bat";
	BYTE PathString[MAX_CMDLINE];
	BYTE Path[MAX_CMDLINE], *pPath;

	/* Build the path string and create the full string that	*/
	/* includes ".\" so that the current directory is searched	*/
	/* first.  Note that Path is initialized outside the loop.	*/
	strcpy(Path, ".\\");
	strcpy(PathString, EnvLookup("PATH"));
	pPath = PathString;

	do
	{
		/* Build a path to the command.				*/
		if(*pPath == ';')
			++pPath;
		strcpy(tmppath, Path);
		if(*tmppath != '\0' && !((tmppath[strlen(tmppath) - 1] != '\\') == 0))
			strcat(tmppath, "\\");
		strcat(tmppath, argv[0]);

		/* batch processing					*/
		/* search for an extension in the specification		*/
		for(idx = len = strlen(argv[0]) ; idx > 0 && idx > (len - FEXT_SIZE - 2); --idx)
		{
			if(argv[0][idx] == '.')
			{
				ext = TRUE;
				extp = &argv[0][idx];
				break;
			}
		}

		/* If no extension was found, the entire path was	*/
		/* specified and we do not append an extension.		*/
		if(!ext)
		{
			strcat(tmppath, batfile);
			extp = batfile;
		}

		/* if it ends with a '.bat' (either user supplied or	*/
		/* previously added), try to run as a batch.		*/
		if((strcmp(extp, batfile) == 0) && batch(tmppath, tail))
		{
			if(pflag && bootup)
				bootup = FALSE;
			return TRUE;
		}

		/* tail comes in as a string with trailing newline. 	*/
		/* Convert it to a return only and put it into CmdTail	*/
		/* format						*/
		CmdTail.ctCount = (argc > 1) ? strlen(tail) : 1;
		strcpy(CmdTail.ctBuffer, " ");
		strcpy(&CmdTail.ctBuffer[1], (argc > 1) ? tail : "");
		CmdTail.ctBuffer[CmdTail.ctCount] = '\0';
		if(CmdTail.ctCount < LINESIZE)
			CmdTail.ctBuffer[CmdTail.ctCount] = '\0';
		rtn_errlvl = 0;
		exb.exec.env_seg = FP_SEG(lpEnviron);
		exb.exec.cmd_line = (CommandTail FAR *)&CmdTail;

#if 0
		if(argc > 1)
		{
			DosParseFilename((BYTE FAR *)argv[1], (fcb FAR *)&fcb1, 0);
			exb.exec.fcb_1 = (fcb FAR *)&fcb1;
		}
		else
			exb.exec.fcb_1 = (fcb FAR *)0;
		if(argc > 2)
		{
			exb.exec.fcb_2 = (fcb FAR *)&fcb2;
			DosParseFilename((BYTE FAR *)argv[2], (fcb FAR *)&fcb2, 0);
		}
		else
			exb.exec.fcb_2 = (fcb FAR *)0;
#else
		exb.exec.fcb_1 = (fcb FAR *)0;
		exb.exec.fcb_2 = (fcb FAR *)0;
#endif

		for(idx = 0; idx < 2; idx++)
		{
			strcpy(tmppath, Path);
			if(*tmppath != '\0' && !((tmppath[strlen(tmppath) - 1] != '\\') == 0))
				strcat(tmppath, "\\");
			strcat(tmppath, argv[0]);
			if(!ext)
			{
				strcat(tmppath, extns[idx]);
				extp = extns[idx];
			}
			if(!(strcmp(extp, extns[idx]) == 0))
				continue;
			if((rtn_errlvl = err = DosExec((BYTE FAR *)tmppath, (exec_blk FAR *)&exb)) != SUCCESS)
			{
				switch(err)
				{
				case DE_FILENOTFND:
					continue;

				case DE_INVLDFUNC:
					rtn_errlvl = INV_FUNCTION_PARAM;
					goto errmsg;

				case DE_PATHNOTFND:
					rtn_errlvl = PATH_NOT_FOUND;
					goto errmsg;

				case DE_TOOMANY:
					rtn_errlvl = TOO_FILES_OPEN;
					goto errmsg;

				case DE_ACCESS:
					rtn_errlvl = ACCESS_DENIED;
					goto errmsg;

				case DE_NOMEM:
					rtn_errlvl = INSUFF_MEM;
					goto errmsg;

				default:
					rtn_errlvl = EXEC_ERR;
				errmsg:
					error_message(rtn_errlvl);
					return FALSE;
				}
			}
			else
			{
				rtn_errlvl = DosRtnValue() & 0xff;
				return TRUE;
			}
		}
		if(err < 0 || idx == 2)
		{
			if(!(err == DE_FILENOTFND || idx == 2))
			{
				error_message(EXEC_FAIL);
				return FALSE;
			}
			continue;
		}
	}
	while(*Path = '\0', pPath = scanspl(pPath, Path, ';'), *Path != '\0');
	error_message(BAD_CMD_FILE_NAME);
	return FALSE;
}


BOOL cmd_exit(argc, argv)
COUNT argc;
BYTE FAR *argv[];
{
#ifndef DEBUG
	/* Don't exit from a permanent shell				*/
	if(pflag)
		return TRUE;
#endif

	/* If no values passed, return errorvalue = 0			*/
	if(argc == 1)
		DosExit(0);

	/* otherwise return what the user asked for			*/
	else
	{
		COUNT ret_val;
		static BYTE nums[] = "0123456789";
		BYTE FAR *p;

		for(ret_val = 0, p = argv[1]; isdigit(*p); p++)
		{
			COUNT j;

			for(j = 0; j < 10; j++)
				if(nums[j] == *p)
					break;
			ret_val += j;
		}
		DosExit(ret_val);
	}
        return TRUE;
}


VOID sto(c)
COUNT c;
{
	BYTE ch[1];

	*ch = c;
	DosWrite(STDOUT, (BYTE FAR *)ch, 1);
}

⌨️ 快捷键说明

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