📄 com.c
字号:
/* File : $Workfile: COM.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$
* COM.C 1.2 97/03/21 14:41:21
* Added /n option to disable critical error handler
* COM.C 1.59 94/12/01 10:05:21
* Removed closing handles 5 and 6 in error_code() in order to be able
* to continue with a batch file if the user wants to. JBEULICH
* Enabled UNC filenames
* COM.C 1.58 94/08/10 14:49:22
* After first run through looking for a file to execute, now strips the D:
* off the path, if only a drive and not a directory is specified. So, if you
* type D:TEST, it will look for TEST on the current directory of drive D:, then
* continue to search the path. It will only skip searching the path if a
* specific directory is specified.
* COM.C 1.57 94/03/29 16:12:11
* docmd_int2f in CSTART.ASM returns 1 if it has been accepted.
* In this case, we don't want it, so docmd_offer returns TRUE.
* All cases of docmd_offer return if TRUE, so we don't process
* the line ourselves.
* COM.C 1.56 94/02/08 11:50:17
* Fixed a problem where typing COMMAND DIR A: after giving the correct error
* message for DIR being an incorrect loadpath, tries to access A: and crashes
* under /MULTI.
* Break added after error message to fix crashing problem.
* Variable lferror added so that after an incorrect loadpath, it does not use
* the next bit (ie. A:) as keyboard input.
* COM.C 1.54 93/12/09 18:07:04
* Fixed a bug which screwed the upper memory link if you entered c:lh dir
* COM.C 1.53 93/12/01 23:14:02
* Fix parsing bug "<infile >outfile command" would fail
* COM.C 1.49 93/12/01 11:32:08
* Now do a flush cache call before displaying prompt.
* COM.C 1.48 93/12/01 00:17:17
* docmd_offer() will do an int 2F/AE (2 if external) within batch files
* SPR: 811218, shouldn't access drive whatever the prompt
* COM.C 1.45 93/11/19 21:08:14
* Put code to report "Syntax Error" for "| command" and "command |" back to
* it's original state.
* COM.C 1.43 93/11/08 23:59:19
* F8 key now only affects autoexec, not 1st batch file
* COM.C 1.42 93/11/05 13:03:00
* Fix problem with /P /MH (missing break;....)
* COM.C 1.41 93/11/05 00:44:07
* /MU option only valid with /P option. The problem is if you "exit" with upper
* memory unlinked the resident portion isn't freed, and you eat upper memory.
* COM.C 1.40 93/10/29 17:05:51
* Add PROMPT=$P$G and PATH=d:\NWDOS to default env
* COM.C 1.39 93/10/22 11:51:30
* Changed Beta string from 3 to 4
* COM.C 1.36 93/09/15 18:56:39
* FOR command now allows any char in brackets. eg for %%v in (+ -) do...
* COM.C 1.34 93/08/26 09:39:05
* Now use PSP for stack during func 4b exec. There's some debug
* code in case things screw up.
* COM.C 1.30 93/07/05 08:32:57
* Memory allocation strategy now restored if ctrl-c pressed during a hiload.
* COM.C 1.25 93/05/24 11:34:43
* psp now points to itself when /P isn't specified.
* COM.C 1.24 93/05/17 11:22:28
* Added support for F5 and F8 being pressed during boot-up.
* COM.C 1.23 93/04/22 14:51:10
* Now close handles 5-19 after an exec.
* echoflg is now correctly preserved when batch files are chained. See
* echoflg_save2.
* COM.C 1.19 93/01/21 14:29:44
* Now do INT 21 ah=29 when changing default drive.
* COM.C 1.16 92/11/25 09:30:15
* Password support enabled/disabled by #if defined(PASSWORD) statements.
* HOMEDIR support disabled.
* COM.C 1.12 92/09/25 19:48:56
* Removed .cmd from search order if DOSPLUS defined.
* Fixed bug when ;; appears in path.
* COM.C 1.11 92/09/17 11:30:14
* Piping a batch file through MORE no longer stops with Syntax Error
* displayed.
* COM.C 1.10 92/09/11 10:43:41
* COMMAND /P: disables time and date prompt and copyright message.
* COMMAND ? no longer hangs.
* ENDLOG
*/
#include "defines.h"
#if 0
#if defined(DLS)
#define MSG_VER 111 /* required message file version No. */
#else
#define MSG_VER msg_ver111 /* required message file version No. */
extern char *MSG_VER;
#endif
#endif
#include <setjmp.h>
#include <string.h>
#if defined(MWC) && defined(strlen)
#undef strcmp /* These are defined as macros in string.h */
#undef strcpy /* which are expaneded in line under */
#undef strlen /* Metaware C. These undefs avoid this. */
#endif
#include <portab.h>
#include <mserror.h>
#if !defined(DOSPLUS)
#include <ccpm.h>
#include <sysdat.h>
#endif
#include "command.h" /* Command Definitions */
#include "support.h" /* Support routines */
#include "dos.h" /* MSDOS function definitions */
#include "dosif.h" /* DOS interface definitions */
#include "toupper.h"
#include "global.h" /* Global Variables */
/* RG-00- */
#define PATH_LEN 65 /* max path length (null terminated) */
#if !defined(NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
#include <pd.h>
#include "security.h"
#include "login.h"
#endif
/* RG-00- end */
MLOCAL BYTE valid_sepchar[] = ":.;,=+";
#if defined(DOSPLUS) /* we now define initial */
MLOCAL BYTE PATH_DIR[] = "A:\\OPENDOS";
MLOCAL BYTE SET_PATH[] = "PATH=%s";
MLOCAL BYTE SET_PROMPT[] = "PROMPT=$P$G";
MLOCAL BYTE SET_OS[] = "OS=OPENDOS"; /* environment in COMMAND */
MLOCAL BYTE SET_VER[] = "VER=7"; /* not in BIOSINIT */
#if !defined(FINAL)
MLOCAL BYTE SET_BETA[] = "BETA=Beta 4";
#endif
#endif
GLOBAL jmp_buf break_env;
#if defined(DOSPLUS)
EXTERN UWORD _psp;
EXTERN VOID *batchptr_off;
EXTERN VOID *batchflg_off;
EXTERN VOID *echoflg_off;
EXTERN UWORD FAR *batch_seg_ptr;
#endif
/*RG-03*/
EXTERN BOOLEAN if_context; /* BATCH.C */
/*RG-03-end*/
#if defined(DOSPLUS)
EXTERN VOID CDECL show_help(WORD); /* CSTART.ASM */
EXTERN VOID CDECL put_resident_high(WORD); /* CSTART.ASM */
EXTERN BYTE FAR * CDECL get_config_env(VOID); /* CTSART.ASM */
EXTERN UWORD CDECL get_original_envsize(VOID);
EXTERN VOID CDECL copy_crit_msgs(VOID); /* CSUP.ASM */
EXTERN VOID CDECL copy_rld_msgs(VOID); /* CSUP.ASM */
EXTERN WORD CDECL dos_parse_filename(BYTE *);
EXTERN UWORD CDECL docmd_int2f(BYTE *, BYTE *, UWORD);
#endif
EXTERN void CDECL flush_cache(void);
EXTERN BYTE *kbdptr;
EXTERN BYTE msg_patheq[]; /* Static Environ String "PATH=" */
EXTERN S_CMD cmd_list[]; /* CMDLIST.C */
#if defined(DOSPLUS)
EXTERN VOID inherit_parent_state();
#endif
EXTERN WORD echoflg_save2;
EXTERN VOID batch_start(BYTE *, BYTE *, BYTE *);
EXTERN VOID batch_end(VOID); /* BATCH.C */
EXTERN VOID batch_endall(VOID); /* BATCH.C */
EXTERN VOID batch_close(VOID); /* BATCH.C */
EXTERN VOID for_end(VOID); /* BATCH.C */
EXTERN BOOLEAN getcmd(BYTE *); /* BATCH.C */
#if !defined(CDOSTMP)
EXTERN VOID int2e_start(); /* BATCH.C */
EXTERN VOID int2e_finish(); /* BATCH.C */
#endif
EXTERN VOID CDECL cmd_cd(BYTE *); /* COMINT.C */
EXTERN VOID CDECL cmd_ver(); /* COMINT.C */
EXTERN VOID CDECL cmd_set(BYTE *); /* COMINT.C */
GLOBAL VOID docmd(BYTE *, BOOLEAN); /* COM.C */
MLOCAL VOID cmd_loop (BYTE *); /* COM.C */
MLOCAL VOID error_code(UWORD); /* COM.C */
MLOCAL VOID cmd_cleantp(VOID); /* COM.C */
GLOBAL BOOLEAN parse(BYTE *); /* COM.C */
MLOCAL VOID init(BYTE *); /* COM.C */
MLOCAL BOOLEAN doexec(BYTE *, BYTE *, UWORD, BYTE *);
#if !defined(CDOSTMP)
MLOCAL BYTE msg_comspec[] = "COMSPEC=";
/*EXTERN BYTE *reload_file; CSTART.ASM */
EXTERN VOID CDECL get_reload_file(VOID); /* CSUP.ASM */
EXTERN VOID CDECL set_reload_file(VOID); /* CSUP.ASM */
EXTERN VOID CDECL get_out_pipe(VOID); /* CSUP.ASM */
EXTERN VOID CDECL install_perm(VOID); /* CSTART.ASM */
EXTERN VOID CDECL master_env(UWORD); /* CSTART.ASM */
GLOBAL WORD CDECL findfile(BYTE *, UWORD *); /* COM.C for MS-DOS */
MLOCAL WORD checkfile(BYTE *, UWORD *, BYTE *, BYTE *, BYTE *, BYTE *);
EXTERN BYTE cbreak_ok; /* control break handler initialised */
#else
EXTERN WORD CDECL findfile(BYTE *, UWORD *); /* DOSIF.A86 (P_PATH) */
EXTERN VOID network_init(VOID); /* NETWORK.C */
EXTERN PD FAR * CDECL pd; /* Far pointer to Current PD */
MLOCAL BOOLEAN system_init = TRUE;
#endif
EXTERN BYTE FAR * CDECL farptr(BYTE *);
EXTERN BYTE FAR * CDECL cgroupptr(BYTE *);
#if defined(CPM)
EXTERN UWORD CDECL cpm_init(VOID); /* CP/M Init Routine */
#endif
#if !defined(NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
/* global VC data */
UWORD vc_base; /* first vc number for this station */
UWORD num_of_vcs; /* number of vcs on this station */
#endif
#if !defined(CDOSTMP)
BYTE autoexec_name[13] = "autoexec.bat";
#endif
#if defined(DOSPLUS)
UWORD boot_key_scan_code = 0;
#endif
#if !defined(FINAL)
void save_psp(void);
void check_psp(void);
WORD psp_xsum;
#endif
VOID FAR CDECL _main(cmd)
BYTE *cmd;
{
BYTE cmd_buf[128];
#if defined(CDOSTMP) /* Insure the NETWORK_INIT */
network_init(); /* function is called before */
#endif /* any disk activity so that */
/* Diskless DRNET systems can*/
/* be generated. */
#if !defined(NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
/* get the VC data and make global */
vc_data(&vc_base, &num_of_vcs, &station);
#endif
#if defined(DOSPLUS) && defined(DLS)
copy_crit_msgs();
copy_rld_msgs();
#endif
init(cmd); /* Initialize COMMAND.??? */
#if defined(CPM)
if(cpm_init()) { /* If this is the CP/M Media */
eprintf(MSG_SINGLECPM); /* Access program then call */
ms_x_exit(1); /* the CPM_INIT function */
}
#endif
ms_drv_set(drive); /* try to set default drive */
FOREVER {
error_code(setjmp(break_env)); /* Initialize Error Handler */
#if !defined(CDOSTMP)
cbreak_ok = TRUE; /* we can handle break now */
#endif
#if !defined(NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
#if defined(CDOSTMP)
ms_drv_set(drive); /* try to set default drive */
/* Ensure we are the foreground process on the Virtual Console */
/* before displaying login prompt. */
if(login_enabled()) {
disable_vc_switch(); /* stop user switching to another console */
/* if 1st time through on VC 0 then run system autoexec */
if (system_init) {
login_save_initial_state();
if (pd->P_CNS==0) {
/* log this event */
logevent("",LOG_POWERON);
/* process system Autoexec.bat */
while (*kbdptr || batchflg)
cmd_loop (cmd_buf);
}
system_init = FALSE;
}
if(waiting_on_login() && !background_proc())
login_station(); /* login station */
login_consoles(); /* initialise all VCs */
enable_vc_switch();
}
#endif
FOREVER {
error_code(setjmp(break_env)); /* Initialize Error Handler */
if (login_enabled()) {
if(!logged_in()) /* keep going until logged out */
break;
}
#endif
cmd_loop (cmd_buf);
#if !defined(NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
}
if(login_enabled()) {
/* kill off any remaining batch processes still running */
while (batchflg)
cmd_exit("");
#if defined(CDOSTMP)
/* the logout event */
if(!background_proc())
logout();
#else
return; /* CDOS.COM just dies when logout happens */
#endif
}
#endif
}
}
/*MLOCAL*/ VOID cmd_loop (cmd)
BYTE *cmd;
{
WORD echoing;
REG BYTE *cmdline;
BYTE first_ch;
cmd_cleanup(); /* Cleanup after the command */
cmdline = cmd;
if (!batchflg) flush_cache();
echoing = getcmd(cmdline); /* do not echo Labels */
first_ch = *deblank(cmdline);
if((pipe_out && !batchflg && !*deblank(kbdptr)) ||
/* if "|<nul command>" */
(pipe_in && (first_ch == 0 || first_ch == ':'))) {
/* or "<null command>|" */
eprintf(MSG_SYNTAX); /* report syntax error */
pipe_out = NO; /* forget about pipes */
pipe_in = NO;
if (!batchflg)
*kbdptr = '\0'; /* discard rest of line */
crlfflg = YES; /* remember to do a LF */
return; /* stop now before echo */
}
if(echoing && first_ch != ':') {
/* Echo command line if ECHO */
puts(cmdline); /* ON and source not keyboard*/
crlf(); /* and not a label */
}
crlfflg = NO; /* NO CR/LF req'd */
cmdline = deblank(cmdline); /* remove leading spaces */
if(*cmdline && *cmdline != ':') /* Check for a command */
{ /* not a LABEL */
if (!strnicmp(cmdline,"IF",2)) docmd(cmdline,YES);
else {
if(!parse(cmdline)) { /* If the Parse succeeds then*/
docmd(cmdline, YES); /* execute the command. */
}
}
}
}
/*.pa*/
/*
*
*/
#define COMMAND_P (cflag & 1) /* Permanent Flag */
#define COMMAND_C (cflag & 2) /* One Command Option */
#define COMMAND_T (cflag & 4) /* CDOS TSR option */
MLOCAL VOID init(cmd)
BYTE *cmd;
{
UBYTE console = 1; /* Concurrent Console No. +1 */
SYSDATE date; /* System Date Structure */
WORD ret; /* General Variable */
UWORD cflag;
BYTE *s;
#if defined(CDOSTMP)
UWORD vc_base, vc_num, pc_num; /* Virtual Console Data */
#else
BYTE buf[MAX_ENVLEN], c;
UWORD envsize = 256;
#endif
#if defined(DOSPLUS)
BOOLEAN no_timedate = FALSE;
WORD prh_function = 0;
UWORD FAR *p_batch_seg;
#endif
BYTE lferror = 0;
strcpy(kbdptr, ""); /* start with no commands */
#if 0
#if defined(DLS)
dls_msg_ver(MSG_VER); /* check message file version*/
#else
s = MSG_VER; /* ensure label is referenced */
#endif
#endif
#if defined(CDOS)
ret = ioctl_ver();
if(ret < 0x1450 || ret > 0x1499) { /* Get the CDOS BDOS Version */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -