📄 comint.c
字号:
/*
; File : $Workfile: COMINT.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$
;
; ENDLOG
*/
#include "defines.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 <pd.h>
#include <ccpm.h>
#include <sysdat.h>
#endif
#include "command.h" /* COMMAND Definitions */
#include "dos.h" /* MSDOS Functions */
#include "dosif.h" /* DOS interface definitions */
#include "toupper.h"
#include "support.h" /* Support routines */
#include "global.h"
/*RG-00-*/
#if !defined(NOXBATCH)
#if !defined(NOSECURITY) && (defined(CDOSTMP) || defined(CDOS))
#define PATH_LEN 65 /* max path length (null terminated) */
#include "security.h"
#include "login.h"
#include "txlogin.h"
#endif
#endif /*NOXBATCH*/
/*RG-00-end*/
EXTERN VOID CDECL restore_error_mode();
EXTERN VOID batch_start(BYTE *, BYTE *, BYTE *);
EXTERN VOID batch_end(VOID); /* BATCH.C */
EXTERN VOID batch_close(VOID); /* BATCH.C */
MLOCAL VOID erase(BYTE *, BOOLEAN); /* COMINT.C */
MLOCAL BYTE * date_format(UWORD); /* COMINT.C */
MLOCAL BOOLEAN check_date(BYTE *); /* COMINT.C */
MLOCAL BOOLEAN check_time(BYTE *); /* COMINT.C */
MLOCAL VOID show_crlf(BOOLEAN); /* COMINT.C */
/*RG-02-*/
#if !defined(NOXBATCH)
GLOBAL VOID CDECL cmd_pauseerr(BYTE *); /* COMINT.C */
/*RG-02-end*/
#endif
GLOBAL VOID CDECL cmd_pause(BYTE *); /* COMINT.C */
GLOBAL VOID CDECL cmd_set(BYTE *); /* COMINT.C */
GLOBAL VOID CDECL cmd_vol(BYTE *); /* COMINT.C */
EXTERN WORD CDECL findfile(BYTE *, UWORD *); /* DOSIF.A86 || COM.C */
EXTERN VOID CDECL int_break(VOID); /* COM.C */
EXTERN VOID docmd(BYTE *, BOOLEAN); /* COM.C */
#if defined(CPM)
EXTERN UWORD CDECL cpm_de_init(VOID); /* CP/M Clean-Up Routine*/
#endif
MLOCAL WORD linesleft; /* Remaining lines on Screen */
MLOCAL WORD ret; /* general BDOS return code */
#if defined(CDOSTMP) || defined(CDOS)
/*.pa*/
/*
* USER BEWARE
*
* A process descriptor exists in both DOS Plus and Concurrent
* DOS. But is an internal Structure in DOS Plus and should only
* be used with the upmost care.
*/
EXTERN PD FAR * CDECL pd; /* Far pointer to Current PD */
/*
* The following command will enable APPEND processing and set
* path searched by the BDOS on every OPEN function call.
*
* APPEND[=][d:]path[[;[d:]path]..] | [;] [/X|/E]
*
* APPEND without any command line options will display the current
* search path while APPEND ; will remove the Search Path and disable
* the APPEND facility.
*
* /E Forces the search path to be saved in the environment under
* Concurrent DOS this is always true and this flag is ignored.
*
* /X Forces APPEND to be active for the SEARCH FIRST(0x11),
* FIND FIRST(0x4E) and EXEC(0x4B) functions. In addition
* to the normal functions FCB OPEN(0x0F), FCB FileSize(0x23)
* and OPEN(0x3D).
* /B Forces APPEND to provide batch command compatible output
* that when redirected to a file, can be used to regenerate a
* given append state.
*/
MLOCAL BYTE msg_appeq [] = "APPEND="; /* Static Environment String */
/*RG-03*/
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
#define APPEND_BAT (flags & 4) /* /B Append Option */
#endif
/*RG-03-end*/
#define APPEND_X (flags & 2) /* /X Append Option */
#define APPEND_E (flags & 1) /* /E Append Option */
GLOBAL VOID CDECL cmd_append(path)
REG BYTE *path;
{
REG BYTE *s;
UWORD flags; /* Command Flags */
#if !STACK
BYTE sbuf[MAX_ENVLEN];
#endif
#if defined(CDOS) || defined(CDOSTMP)
if (f_check (path, "exb", &flags, NO)) /* Check for valid Flags */
#else
if (f_check (path, "ex", &flags, NO)) /* Check for valid Flags */
#endif
return;
zap_spaces(path); /* Remove White Space */
if(!*path && !APPEND_X) {
if(env_scan(msg_appeq, s = (BYTE *)heap())) /* look for current value */
s = NULLPTR;
if(s && (pd->P_SFLAG & PSF_APPEND)) { /* If a path exists and the */
printf(msg_appeq); /* Append bit is set in the */
puts(s);
}
/*RG-03*/
else { /* PD then display path */
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
if (APPEND_BAT)
printf("APPEND=");
else
#endif
printf(MSG_APPEND);
}
/*RG-03-end*/
crlfflg = YES;
return;
}
pd->P_SFLAG |= APPEND_X ? PSF_XAPPEND : 0;
if(*path == '=' || *path == ';')/* Skip Leading '=' or ';' chars */
path++; /* and disable the APPEND command */
/* if no path is specified. */
if(*path) { /* Assign APPEND Path */
pd->P_SFLAG |= PSF_APPEND; /* Set the APPEND and XAPPEND Bits */
#if STACK
s = stack(strlen(msg_appeq) + strlen(path) + 1);
#else
s = &sbuf[0];
#endif
strcpy(s, msg_appeq); /* build command line for "SET" */
strcat(s, strupr(path)); /* Force Path to UPPER case */
cmd_set(s); /* set new path using "SET" */
}
else if(!APPEND_X) { /* Disable APPEND Processing */
pd->P_SFLAG &= ~(PSF_APPEND | PSF_XAPPEND);
cmd_set(msg_appeq);
}
}
#endif
#if !defined(EXT_SUBST)
/*.pa*/
/************************************************************************/
/* */
/* ASSIGN (x [=] y ...) [/a][/b] */
/* */
/* This command forces future references to the X: to physically */
/* reference the Y: drive. */
/* */
/* When no command line parameters are given then all assignments */
/* are removed. If the /A option is used the current drive */
/* assignments are displayed. For the purpose of the display and */
/* remove functions an "ASSIGNed" drives is any physical drive */
/* which does not reference itself. */
/* */
/************************************************************************/
/*
* ASSIGN_DRV returns TRUE if the drive pointed to by BP
* is a valid physical drive.
*/
MLOCAL BOOLEAN assign_drv(bp)
BYTE *bp;
{
if(!d_check(bp))
return FALSE;
if(physical_drvs() & (1L << ddrive))
return TRUE;
e_check(ED_DRIVE);
return FALSE;
}
/*RG-03*/
#define ASSIGN_BAT (flags & 2) /* Display Current Assignments in batch form */
/*RG-03-end*/
#define ASSIGN_ALL (flags & 1) /* Display Current Assignments */
GLOBAL VOID CDECL cmd_assign(s)
REG BYTE *s;
{
BYTE temp[7]; /* Temporary Command Buffer */
BYTE path[MAX_PATHLEN];
BYTE src, dst;
ULONG vec,pvec,lvec,nvec;
UWORD drv;
UWORD flags; /* Command Flags */
WORD ret; /* General purpose variable */
if (f_check (s, "ab", &flags, NO)) /* Check for Flags if any are */
return; /* invalid then don't do it */
pvec = physical_drvs();
lvec = logical_drvs();
/*
* Display the current drive assignments.
*/
/*RG-03*/
if((ASSIGN_ALL)||(ASSIGN_BAT))
{
vec = 1L;
drv = 0;
while(drv < 26) {
if((lvec & vec) && (pdrive(drv) != drv)) {
if (ASSIGN_BAT)
printf("ASSIGN %c = %c\n", drv+'A', pdrive(drv)+'A');
else
/*RG-03-end*/
printf("%c: => %c:\n", drv+'A', pdrive(drv)+'A');
}
vec <<= 1;
drv++;
}
return;
}
/*
* Remove ALL drive assignments.
*/
s = deblank(s); /* If no command line options */
if(!*s) { /* are given then remove the */
/* current assignments. */
vec = 1L;
drv = 0;
while(drv < 26) {
if((lvec & vec) && (pdrive(drv) != drv)) {
sprintf(temp, "%c:=%c:", drv+'A', drv+'A');
ms_x_chdir(temp);
}
vec <<= 1;
drv++;
}
return;
}
/*
* Scan the command line and make all the drive assignments
* specified by the user.
*/
do {
dst = *s++; /* Get the Destinaion */
s = deblank(s);
if(*s == '=') /* Skip the optional '=' */
s = deblank(s+1); /* character and get the source */
if(!*s) { /* if no second drive has been */
syntax(); /* specified the return error */
return;
}
src = *s++;
sprintf(temp, "%c:=%c:", dst, src);
#if defined(DOSPLUS)
nvec = network_drvs();
if ((nvec & (1L << (toupper(src)-'A')))
|| (nvec & (1L << (toupper(dst)-'A')))) {
eprintf(MSG_NETASSIGN); /* if either is remote */
return; /* complain and exit */
}
#endif
if(assign_drv(temp) && assign_drv(temp+3)) {
ret = ms_x_chdir(temp);
if (ret) {
e_check(ret);
return;
}
}
else
return;
sprintf (path, "%c:%c", dst, *pathchar);
ms_x_curdir (tolower(src) - 'a'+1, path+3);
/* set dst drive to cur path on */
/* source */
ms_x_chdir (path);
s = deblank(s); /* Deblank the renmainder of */
} while(*s); /* command line and repeat */
}
#endif
/*
* The CALL command accepts the name of a batch file with an
* optional parameter list. Any current batch processing is
* halted and the new batch file is used until the EOF is reached
* or an EXIT command is executed. Control then passes back to
* the original Batch file.
*/
EXTERN UWORD CDECL heap_size(VOID);
GLOBAL VOID CDECL cmd_call(line)
REG BYTE *line;
{
BYTE path[MAX_FILELEN];
UWORD loadtype;
BYTE argv0[MAX_FILELEN];
BYTE *s;
heap_get(0); /* check for stack overflow */
s = get_filename(path, deblank(line), NO);
strcpy(argv0, path);
strlwr(path);
if((ret = findfile(path, &loadtype)) >= 0) {
if(loadtype == BAT_FILETYPE) { /* treat .BAT differently */
batch_start(argv0, path, s); /* nested batch files */
return;
}
}
line = deblank(line);
docmd(line,YES); /* call normal code */
}
/*
* Display the current directory assignment of a logical drive
* Currently the Absolute path is specified with the physical drive
*/
/*RG-03*/
#define CHDIR_BAT (flags & 2) /* Display dir in command line compatible form */
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
MLOCAL VOID display_cd(drv,flags)
#else
MLOCAL VOID display_cd(drv)
#endif
REG WORD drv;
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
UWORD flags; /* Command Flags */
#endif
{
BYTE dispbuf[MAX_PATHLEN];
WORD ret;
dispbuf[0] = (BYTE) (drv + 'A'); /* Display the path of the */
dispbuf[1] = ':'; /* requested drive */
dispbuf[2] = *pathchar;
ret = ms_x_curdir(drv+1, dispbuf+3);
if (ret < 0) return;
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
if (CHDIR_BAT)
printf ("CHDIR %s\n", dispbuf);
else
#endif
printf ("%s\n", dispbuf);
}
/*RG-03-end*/
#define CHDIR_ALL (flags & 1) /* Display Current Assignments */
GLOBAL VOID CDECL cmd_cd(s)
REG BYTE *s;
{
BYTE *cp;
ULONG login; /* Login Vector */
WORD ret; /* General purpose variable */
UWORD flags; /* Command Flags */
/*rbf remove trailing spaces from string 's'*/
char *p = s;
while ( (*p!=' ') && *p)
p++;
*p=0;
/*rbf-end*/
#if defined(CDOS) || defined(CDOSTMP)
if (f_check (s, "ab", &flags, NO)) /* Check for valid Flags */
#else
if (f_check (s, "a", &flags, NO)) /* Check for valid Flags */
#endif
return; /* invalid then don't do it */
if(CHDIR_ALL) { /* Display the current drive */
for(ret = 0; ret < 26; ret++)
/*RG-03*/
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
display_cd(ret,flags);
#else
display_cd(ret);
#endif
/*RG-03-end*/
return;
}
cp = s = deblank(strlwr(s)); /* Deblank after the Flag Check */
if(*(s+1) == ':') { /* check for a drive specifier */
ddrive = *s - 'a'; /* Get the drive letter and check */
s = deblank(s+2); /* that it is a valid drive and */
/* is not the LOAD Drive. */
if(INVALID_DRV(ddrive)) {
e_check(ED_DRIVE);
return;
}
}
else
ddrive = drive; /* Use the default drive */
if(*s == '=') { /* Floating Drive Assignment */
if(*++s) { /* Check source drive if spec. */
if((s = d_check(s)) == 0)/* Abort if an illegal drive is */
return; /* selected. */
if(!*s) /* If the command is of the form */
strcpy(s, "."); /* x:=y: then append a "." */
}
}
else if(!*s) { /* Display the selected drives */
if(d_check(cp)) /* current sub-directory. */
/*RG-03-*/
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
display_cd(ddrive,flags);
#else
display_cd(ddrive);
#endif
/*RG-03-end*/
return;
}
if (*cp == '.') {
while (cp[1] == 32) {
ret = 1;
while (cp[ret]) {
cp[ret] = cp[ret+1];
ret++;
}
}
}
/* Make the drive Assignment */
if (!d_check(cp)) ddrive = -1;
e_check(ddrive != -1 ? ms_x_chdir(cp) : ED_DRIVE);
}
#if !defined(EXT_SUBST)
/*.pa*/
#define SUBST_DEL (flags & 1)
/*RG-03-*/
#if !defined(NOXBATCH) && (defined(CDOS) || defined(CDOSTMP))
#define SUBST_BAT (flags & 2)
#endif
/*RG-03-end*/
GLOBAL VOID CDECL cmd_subst(s)
BYTE *s;
{
BYTE cp[MAX_FILELEN+3]; /* CHDIR Path Buffer */
BYTE root[4];
ULONG login; /* Logical Drive Vector */
UWORD flags; /* Command Flags */
UWORD drv;
WORD i;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -