mirror of
https://github.com/SEPPDROID/DR-DOS-OpenDOS.git
synced 2025-10-22 07:54:28 +00:00
575 lines
14 KiB
C
575 lines
14 KiB
C
/*
|
|
; File : $Workfile: CONFIG.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
|
|
*/
|
|
|
|
/*
|
|
* 28 Oct 87 Always decrement the MEMSIZE field by 0x0A paragraphs to
|
|
* allow for the SAT's.
|
|
* 9 Nov 87 Recheck the login vector after detemining the specified
|
|
* drive in NETDRIVE.
|
|
* 9 Dec 87 Always display Physically Remote drives as Remote.
|
|
* 28 Jan 88 Support the CTTY command for DOS Plus command interpreter
|
|
* 27 May 88 Added string undefs.
|
|
* 15 Jun 88 DBG is now permanent.
|
|
* 23 Jun 88 Use new ONOFF function for XXX [=] ON|OFF parsing
|
|
* 29 Jun 88 Check OWNER field in ?CB for valid AUX and LIST devices
|
|
* 5 Aug 88 Let L_SET and A_SET determine the validity of a Device No.
|
|
* 12 Aug 88 Enforce default AUX and PRINTER on COM1 and LPT1 mapping
|
|
* 7 Feb 89 Support the CHCP command for DR DOS
|
|
* 14 Apr 89 cmd_chcp: Print relevant msg if ED_FILE returned
|
|
* 30 Aug 89 DR Dos idle command
|
|
* 30 Oct 89 "DEBUG is" moved to message.c (ie. non-resident)
|
|
* 6-Mar-90 Watcom C v 7.0
|
|
* 20-Sep-90 is_filechar() now takes pointer instead of byte.
|
|
* 2-Oct-90 Prevent exec of XSTOP.EXE from within STOP command
|
|
* 3-Oct-90 remove 8087 command
|
|
* 4-Oct-90 Netdrive goes CCB based
|
|
* 12-Oct-90 cmd_printer/cmd_aux removed (now part of printmap)
|
|
* 12-Oct-90 NETDRIVE now says "netdrive d: /Local" to aid Richard
|
|
* (You can save and restore state in batch files)
|
|
*/
|
|
|
|
#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>
|
|
#else
|
|
#include <idle.h> /*#NOIDLE#*/
|
|
#endif
|
|
|
|
#include "command.h" /* COMMAND Definitions */
|
|
#include "support.h"
|
|
#include "dosif.h" /* DOS interface definitions */
|
|
#include "toupper.h"
|
|
#include "global.h"
|
|
|
|
/*
|
|
* 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.
|
|
*/
|
|
#if !defined(DOSPLUS)
|
|
EXTERN PD FAR * CDECL pd; /* Far pointer to Current PD */
|
|
#endif
|
|
|
|
MLOCAL VOID setflag(cmd, msg, field, flag)
|
|
BYTE *cmd; /* Pointer to the Users Command Line */
|
|
BYTE *msg; /* Status Message String */
|
|
UWORD FAR *field; /* FAR pointer to the Flags field */
|
|
UWORD flag; /* The Flag to be updated */
|
|
{
|
|
|
|
switch(onoff(cmd)) { /* Check for "=on/off" */
|
|
case YES: /* Turn Flag ON */
|
|
*field |= flag;
|
|
break;
|
|
|
|
case NO: /* Turn Flag OFF */
|
|
*field &= ~flag;
|
|
break;
|
|
|
|
default:
|
|
if(*deblank(cmd)) /* Display an error message */
|
|
printf(MSG_ONOFF); /* for a non blank commnad */
|
|
else
|
|
printf(msg, *field & flag ? MSG_ON : MSG_OFF);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*.pa*/
|
|
#if defined(CDOSTMP)
|
|
/*
|
|
* BREAK [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_break(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
setflag(cmd, MSG_BREAK, (UWORD FAR *) &pd->P_SFLAG, PSF_BREAK);
|
|
}
|
|
|
|
/*
|
|
* VERIFY [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_verify(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
setflag(cmd, MSG_VERIFY, (UWORD FAR *) &pd->P_SFLAG, PSF_VERIFY);
|
|
}
|
|
|
|
#else
|
|
/*
|
|
* BREAK [ON|OFF]
|
|
*
|
|
* The break flag is emulated during by the COMMAND processor and
|
|
* only set to the users value when a program is loaded or when
|
|
* leaving COMMAND.COM using the EXIT command.
|
|
*/
|
|
GLOBAL VOID CDECL cmd_break(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
switch(onoff(cmd)) { /* Check for "=on/off" */
|
|
case YES: /* Turn Flag ON */
|
|
break_flag = YES;
|
|
break;
|
|
|
|
case NO: /* Turn Flag OFF */
|
|
break_flag = NO;
|
|
break;
|
|
|
|
default:
|
|
if(*deblank(cmd)) /* Display an error message */
|
|
printf(MSG_ONOFF); /* for a non blank commnad */
|
|
else
|
|
printf(MSG_BREAK, break_flag ? MSG_ON : MSG_OFF);
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* VERIFY [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_verify(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
switch(onoff(cmd)) { /* Check for "=on/off" */
|
|
case YES: /* Turn Flag ON */
|
|
ms_f_verify(YES);
|
|
break;
|
|
|
|
case NO: /* Turn Flag OFF */
|
|
ms_f_verify(NO);
|
|
break;
|
|
|
|
default:
|
|
if(*deblank(cmd)) /* Display an error message */
|
|
printf(MSG_ONOFF); /* for a non blank commnad */
|
|
else
|
|
printf(MSG_VERIFY, ms_f_getverify() ? MSG_ON : MSG_OFF);
|
|
break;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if defined(DOSPLUS)
|
|
/*
|
|
* CHCP [CodePage]
|
|
*
|
|
* CHCP displays or changes the current global codepage
|
|
*
|
|
*/
|
|
GLOBAL VOID CDECL cmd_chcp(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
UWORD systemcp, globalcp;
|
|
WORD ret;
|
|
|
|
zap_spaces(cmd);
|
|
if(*cmd) {
|
|
if(check_num(cmd, 0, 999, &globalcp))
|
|
printf(INV_NUM);
|
|
else {
|
|
if((ret = ms_x_setcp(globalcp)) < 0)
|
|
if (ret == ED_FILE)
|
|
printf (MSG_CPNF);
|
|
else
|
|
printf(MSG_BADCP, globalcp);
|
|
}
|
|
}
|
|
else {
|
|
ms_x_getcp(&globalcp, &systemcp);
|
|
printf(MSG_CURCP, globalcp);
|
|
}
|
|
}
|
|
|
|
/*
|
|
* CTTY Device Name
|
|
*
|
|
* CTTY redirects all console output to the specified character
|
|
* device. Note CTTY will only allow a DEVICE to be specified.
|
|
*
|
|
*/
|
|
GLOBAL VOID CDECL cmd_ctty(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
BYTE device[MAX_FILELEN];
|
|
WORD h, j;
|
|
|
|
get_filename(device, deblank(cmd), NO); /* Extract the Device Name */
|
|
|
|
FOREVER {
|
|
if((h = ms_x_open(device, OPEN_RW)) < 0)
|
|
break;
|
|
|
|
j = ms_x_ioctl(h); /* Check the user specified a */
|
|
if((j & 0x0080) == 0) { /* device or not. If a file was */
|
|
ms_x_close(h); /* Close the handle and quit */
|
|
break;
|
|
}
|
|
|
|
j |= 0x03;
|
|
ms_x_setdev(h,j);
|
|
|
|
ms_x_fdup(STDIN, h); /* Force duplicate this handle */
|
|
ms_x_fdup(STDOUT, h); /* onto STDIN, STDOUT and */
|
|
ms_x_fdup(STDERR, h); /* STDERR. */
|
|
|
|
/*
|
|
* Update the internal variables which contain the handle
|
|
* table index to be updated with the new values. So that
|
|
* all the Command Processor error messages go to the right
|
|
* device.
|
|
*/
|
|
in_handle = out_handle = psp_poke(h, 0xFF);
|
|
psp_poke(h, in_handle);
|
|
|
|
ms_x_close(h); /* Finally close the handle and */
|
|
return; /* return to the caller. */
|
|
}
|
|
|
|
crlfflg = YES; /* Display the Device Name */
|
|
printf(MSG_NEEDDEV); /* required error message and */
|
|
return; /* Terminate. */
|
|
}
|
|
|
|
/*#if 0 #NOIDLE#*/
|
|
/*
|
|
* IDLE [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_idle(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
IDLE_STATE FAR *idle;
|
|
|
|
idle = ms_idle_ptr ();
|
|
|
|
if (idle->flags & IDLE_ENABLE) {
|
|
printf(MSG_DISABLED); /* say if idle is installed */
|
|
return;
|
|
}
|
|
|
|
switch(onoff(cmd)) { /* Check for "=on/off" */
|
|
case YES: /* Reset flag */
|
|
idle->flags &= ~IDLE_ON;
|
|
break;
|
|
|
|
case NO: /* Set flag */
|
|
idle->flags |= IDLE_ON;
|
|
break;
|
|
|
|
default:
|
|
if(*deblank(cmd)) /* Display an error message */
|
|
printf(MSG_ONOFF); /* for a non blank commnad */
|
|
else
|
|
printf(MSG_IDLE, idle->flags & IDLE_ON ? MSG_OFF : MSG_ON);
|
|
break;
|
|
}
|
|
}
|
|
/*#endif #NOIDLE#*/
|
|
#endif
|
|
|
|
#if defined(CDOSTMP) || defined(CDOS)
|
|
/*
|
|
* Enforce the current PRINTER and AUX mapping for LPT1 and COM1.
|
|
* Using the console number and the number of devices supported
|
|
* update the correct mapping byte in the table.
|
|
*/
|
|
|
|
#define INT17_PTR 0x0C46 /* List Mapping Table */
|
|
#define INT14_PTR 0x0C48 /* Aux Mapping Table */
|
|
|
|
MLOCAL VOID map_device(tbl, dev)
|
|
UWORD tbl;
|
|
UWORD dev;
|
|
{
|
|
UBYTE console;
|
|
|
|
tbl = *SYSDATW(tbl);
|
|
console = (UBYTE) bdos(C_GET, 0);
|
|
*SYSDATB(tbl + (*SYSDATB(tbl) * console) +1) = (BYTE) dev;
|
|
}
|
|
|
|
GLOBAL VOID CDECL cmd_stop(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
UWORD vc_base, vc_num, pc_num, i;
|
|
struct {
|
|
UWORD pd; /* PD address */
|
|
UWORD term; /* Process termination Code */
|
|
UWORD cns; /* Console Number and Zero field*/
|
|
BYTE name[8]; /* Process Name */
|
|
} apb;
|
|
|
|
cmd = deblank(cmd); /* Get the Process Name ABORT */
|
|
|
|
if(!*cmd) { /* If no command line options */
|
|
printf(MSG_BADSTOP); /* return with syntax error */
|
|
return; /* disk based version of STOP. */
|
|
}
|
|
|
|
memset(apb.name, ' ', 8); /* Blank fill the Name Buffer */
|
|
|
|
for(i=0; i < 8 && is_filechar(cmd); cmd++, i++)
|
|
apb.name[i] = toupper(*cmd);
|
|
|
|
if(i == 0) { /* If no valid process name was */
|
|
printf(MSG_BADSTOP); /* given then return with a */
|
|
return; /* syntax error. */
|
|
}
|
|
|
|
vc_data(&vc_base, &vc_num, &pc_num);
|
|
|
|
if(check_num(cmd, 1, vc_num, &apb.cns)) {
|
|
printf(MSG_BADSTOP);
|
|
return;
|
|
}
|
|
|
|
apb.pd = 0; /* Zero Process Descriptor Field */
|
|
apb.term = 0; /* Only Abort User Process's */
|
|
apb.cns += vc_base - 1; /* Force console number base 0 */
|
|
if(bdos(P_ABORT, &apb)) /* Abort the Process */
|
|
printf(MSG_BADSTOP);
|
|
}
|
|
|
|
|
|
/*
|
|
* BANK [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_bank(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
setflag(cmd, MSG_BANK, (UWORD FAR *) &pd->P_PCMFLAG, PIDF_BANK);
|
|
}
|
|
|
|
/*
|
|
* SUSPEND [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_suspend(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
setflag(cmd, MSG_SUSPEND, (UWORD FAR *) &pd->P_PCMFLAG, PIDF_SUSPEND);
|
|
}
|
|
|
|
/*
|
|
* IDLE [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_idle(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
setflag(cmd, MSG_IDLE, (UWORD FAR *) &pd->P_PCMFLAG, PIDF_IDLE);
|
|
}
|
|
|
|
|
|
/*
|
|
* MEMSIZE [Memory Size (Kb)]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_memsize(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
UWORD kb, mmp; /* number in kilobytes */
|
|
|
|
mmp = *SYSDATW(MMP)/64; /* Per Process Maximum in Kb */
|
|
kb = (pd->P_PCMMEM + 0x0A)/64; /* Convert to number of Kb */
|
|
|
|
zap_spaces(cmd);
|
|
if(*cmd) {
|
|
if(check_num(cmd, 0, MAX_MEMSIZE, &kb))
|
|
printf (INV_NUM);
|
|
else {
|
|
if(kb == 0 || kb > mmp) /* If MEMSIZE specified was */
|
|
kb = mmp; /* out of range or was Zero */
|
|
pd->P_PCMMEM = kb * 64 - 0x0A; /* then use the MMP */
|
|
}
|
|
}
|
|
else
|
|
printf (MSG_MEMSIZE, kb);
|
|
}
|
|
|
|
/*
|
|
* LIMSIZE [Memory Size (Kb)]
|
|
*
|
|
* This command sets the Maximum number of blocks to be allocated
|
|
* to a process using the LIM memory. The maximum field is fixed for
|
|
* Concurrent DOS XM to MAX_LIMSIZE but for Concurrent DOS 386 the
|
|
* LIMMAX field in the 386 data area is used.
|
|
*/
|
|
GLOBAL VOID CDECL cmd_limsize(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
UWORD kb, limmax; /* number in kilobytes */
|
|
|
|
kb = pd->P_LIMMEM * 16; /* get number of kilobytes */
|
|
|
|
if(*SYSDATW(V386_PTR)) { /* If this is Concurrent DOS 386 */
|
|
if (*SYSDATW(*SYSDATW(V386_PTR) + 15)!=0xff) {
|
|
printf (MSG_LIMOFF);
|
|
return;
|
|
}
|
|
else
|
|
limmax = *SYSDATW(*SYSDATW(V386_PTR) + 18) * 16;
|
|
}
|
|
else
|
|
limmax = MAX_LIMSIZE;
|
|
|
|
zap_spaces(cmd);
|
|
if(*cmd) {
|
|
if(check_num(cmd, 0, limmax, &kb))
|
|
printf (INV_NUM);
|
|
else
|
|
pd->P_LIMMEM = (kb+15)/16;
|
|
}
|
|
else
|
|
printf (MSG_LIMSIZE, kb);
|
|
}
|
|
|
|
/*
|
|
* NETDRIVE d: [/A|/R|/L]
|
|
*
|
|
* This command displays and modifies the current "network" status
|
|
* of all physical drives currently logged in.
|
|
*
|
|
* NETDRIVE d: /R Treat as Networked Media
|
|
* NETDRIVE d: /L Treat as Local Media
|
|
* NETDRIVE [d:|/A] Display Network Status
|
|
*/
|
|
|
|
#define NETDRIVE_ALL (flags == 1) /* Display ALL */
|
|
#define NETDRIVE_LOCAL (flags & 2) /* Treat as LOCAL media */
|
|
#define NETDRIVE_REMOTE (flags & 4) /* Treat as REMOTE media*/
|
|
#define CCBLIST 0x0c3e
|
|
#define CCB_NETVEC 0x0010
|
|
|
|
GLOBAL VOID CDECL cmd_netdrive(s)
|
|
REG BYTE *s;
|
|
{
|
|
BYTE *cp;
|
|
UWORD login, network; /* Login Vector */
|
|
WORD ret; /* General purpose variable */
|
|
UWORD flags; /* Command Flags */
|
|
UWORD ccbptr; /* address of CCB */
|
|
UWORD netvec; /* address pseudo-net drive vec */
|
|
|
|
|
|
/* We bodge flags to all "/Local" and "/Remote" by making "emotc" */
|
|
/* into flags as well - we are only interested in the "alr" flags */
|
|
|
|
f_check (s, "alremotc", &flags, YES);
|
|
s = deblank(s); /* Deblank after the Flag Check */
|
|
|
|
|
|
ccbptr = *SYSDATW(CCBLIST) + 2*pd->P_CNS;
|
|
netvec = *SYSDATW(ccbptr) + CCB_NETVEC;
|
|
|
|
login = network = (UWORD) network_drvs();
|
|
login |= (UWORD) physical_drvs(); /* Physical Drive Vector */
|
|
network |= *SYSDATW(netvec); /* Logically Remote Drives */
|
|
|
|
/*
|
|
* if NETDRIVE_ALL then display the network status of all the currently
|
|
* logged in physical drives.
|
|
*/
|
|
if(NETDRIVE_ALL || !*s) {
|
|
for(ret = 0; ret < 16; ret++, login >>= 1, network >>=1)
|
|
if(login & 1L) {
|
|
printf("Netdrive %c: %s\n", ret + 'A',
|
|
network & 1 ? MSG_REMOTE : MSG_LOCAL);
|
|
}
|
|
return;
|
|
}
|
|
|
|
if(nofiles(s, ATTR_ALL, NO, NO))/* Abort if an illegal drive is */
|
|
return; /* selected. */
|
|
|
|
login &= ~((UWORD) network_drvs()); /* Invalidate Remote Drives */
|
|
ret = 1 << ddrive; /* Generate Bit vector and then */
|
|
if((login & ret) == 0) { /* check that this is a logged in */
|
|
e_check(ED_DRIVE); /* physical drive */
|
|
return;
|
|
}
|
|
|
|
|
|
if(NETDRIVE_LOCAL) {
|
|
*SYSDATW(netvec) &= ~ret; /* Local Drive */
|
|
}
|
|
else if(NETDRIVE_REMOTE) {
|
|
*SYSDATW(netvec) |= ret; /* Remote Drive */
|
|
}
|
|
else {
|
|
printf("Netdrive %c: %s\n", ddrive + 'A',
|
|
network & ret ? MSG_REMOTE : MSG_LOCAL);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
#if !defined(FINAL) && !defined(DOSPLUS)
|
|
/*
|
|
* DBG [ON|OFF]
|
|
*/
|
|
GLOBAL VOID CDECL cmd_dbg(cmd)
|
|
REG BYTE *cmd;
|
|
{
|
|
setflag(cmd, MSG_DEBUG, (UWORD FAR *) &pd->P_SFLAG, PSF_DEBUG);
|
|
}
|
|
#endif
|
|
|
|
#if defined(CPM)
|
|
/*.pa*/
|
|
/*
|
|
*
|
|
*/
|
|
EXTERN UWORD user; /* Current User area */
|
|
|
|
GLOBAL VOID CDECL cmd_user(s)
|
|
REG BYTE *s;
|
|
{
|
|
if(*s && check_num(s, 0, 15, &user)) /* If command line and its not */
|
|
printf(INV_USER); /* a valid user area then invalid user */
|
|
|
|
printf(CUR_USER, user);
|
|
}
|
|
#endif
|