📄 com.c
字号:
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 + -