From 2d04cacc5322951f187bb17e017c12920ac8ebe2 Mon Sep 17 00:00:00 2001 From: Mark Zbikowski Date: Thu, 25 Apr 2024 21:24:10 +0100 Subject: MZ is back! --- v4.0/src/CMD/SUBST/MAKEFILE | 81 +++++ v4.0/src/CMD/SUBST/SUBST.C | 719 +++++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/SUBST/SUBST.LNK | 12 + v4.0/src/CMD/SUBST/SUBST.SKL | 22 ++ v4.0/src/CMD/SUBST/SUBSTPAR.H | 155 +++++++++ v4.0/src/CMD/SUBST/_MSGRET.ASM | 250 ++++++++++++++ v4.0/src/CMD/SUBST/_PARSE.ASM | 121 +++++++ 7 files changed, 1360 insertions(+) create mode 100644 v4.0/src/CMD/SUBST/MAKEFILE create mode 100644 v4.0/src/CMD/SUBST/SUBST.C create mode 100644 v4.0/src/CMD/SUBST/SUBST.LNK create mode 100644 v4.0/src/CMD/SUBST/SUBST.SKL create mode 100644 v4.0/src/CMD/SUBST/SUBSTPAR.H create mode 100644 v4.0/src/CMD/SUBST/_MSGRET.ASM create mode 100644 v4.0/src/CMD/SUBST/_PARSE.ASM (limited to 'v4.0/src/CMD/SUBST') diff --git a/v4.0/src/CMD/SUBST/MAKEFILE b/v4.0/src/CMD/SUBST/MAKEFILE new file mode 100644 index 0000000..9ad2e7b --- /dev/null +++ b/v4.0/src/CMD/SUBST/MAKEFILE @@ -0,0 +1,81 @@ +#************************ makefile for cmd\subst ************************* + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h +map =..\..\mapper +here =..\cmd\subst # This is the path from INC or MAP dir's to here. +make =nmake -i + +# +####################### dependencies begin here. ######################### +# + +all: subst.exe + +$(inc)\errtst.obj: + cd $(inc) + $(make) + cd $(here) + +$(inc)\sysvar.obj: + cd $(inc) + $(make) + cd $(here) + +$(inc)\cds.obj: + cd $(inc) + $(make) + cd $(here) + +$(inc)\dpb.obj: + cd $(inc) + $(make) + cd $(here) + +$(inc)\comsubs.lib: + cd $(inc) + $(make) + cd $(here) + +$(map)\mapper.lib: + cd $(map) + $(make) + cd $(here) + +subst.ctl: subst.skl \ + $(msg)\$(COUNTRY).msg \ + makefile + +_msgret.obj: _msgret.asm \ + $(inc)\msgserv.asm \ + $(inc)\sysmsg.inc \ + subst.ctl \ + subst.cla \ + subst.cl1 \ + subst.cl2 \ + subst.skl + +_parse.obj: _parse.asm \ + $(inc)\parse.asm \ + $(inc)\psdata.inc + +subst.obj: subst.c \ + makefile \ + substpar.h \ + $(hinc)\cds.h \ + $(hinc)\jointype.h \ + $(hinc)\sysvar.h + +subst.exe: subst.obj \ + $(inc)\cds.obj \ + $(inc)\dpb.obj \ + $(inc)\errtst.obj \ + $(inc)\sysvar.obj \ + $(map)\mapper.lib \ + $(inc)\comsubs.lib \ + _msgret.obj \ + _parse.obj \ + subst.lnk + link @subst.lnk diff --git a/v4.0/src/CMD/SUBST/SUBST.C b/v4.0/src/CMD/SUBST/SUBST.C new file mode 100644 index 0000000..c873e42 --- /dev/null +++ b/v4.0/src/CMD/SUBST/SUBST.C @@ -0,0 +1,719 @@ +/*  */ +/**************************************************************************/ +/* */ +/* UTILITY NAME: Subst */ +/* */ +/* SOURCE FILE NAME: Subst.C */ +/* */ +/* STATUS: Subst Utility, DOS Version 4.0 */ +/* */ +/* FUNCTIONAL DESCRIPTION: This utility allows the substitution of a */ +/* physical drive for a pathname on another drive such that operations */ +/* performed using the physical drive as an argument take place on the */ +/* pathname. */ +/* */ +/* SYNTAX: [d:][path]SUBST or */ +/* [d:][path]SUBST d: d:path or */ +/* [d:][path]SUBST d: /D */ +/* where: */ +/* [d:][path] to specify the drive and path that */ +/* contains the SUBST command file */ +/* */ +/* d: specifies the drive letter that you want */ +/* to use to refer to another drive or path. */ +/* */ +/* d:path to specify the drive or path that you */ +/* want to refer to with a nickname. */ +/* */ +/* /D to delete a substitution. You must specify */ +/* the letter of the drive whose substitution */ +/* you want to delete. */ +/* */ +/* LINKS: */ +/* CDS.C - Functions to get/set DOS CDS structures */ +/* DPB.C - Functions to get DOS DPB structures */ +/* ERRTST.C - Drive and path validity testing functions */ +/* SYSVAR.C - Functions to get/set DOS System Variable structures */ +/* COMSUBS.LIB - DOS DBCS function calls */ +/* MAPPER.LIB - DOS function calls */ +/* SLIBC3.LIB - C library functions */ +/* _MSGRET.SAL - Assembler interface for common DOS message services */ +/* _PARSE.SAL - Assembler interface for common DOS parser */ +/* */ +/* ERROR HANDLING: Error message displayed and utility is terminated. */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* */ +/* MODIFICATIONS: */ +/* */ +/* Converted to CMERGE 03/26/85 */ +/* */ +/* M000 June 5/85 */ +/* Changed low version check for specific 320. */ +/* */ +/* M001 June 12/85 */ +/* The original IBM version of SUBST allowed the delete switch "/D" */ +/* immediately after the drive specification. The argument parsing code */ +/* has been Revised to allow this combination. */ +/* */ +/* M002 July 3/85 */ +/* When there are only two operand make sure that there are no additional*/ +/* switch characters. */ +/* */ +/* M003 July 9/85 */ +/* Altered pathname verification tests to so that the same error message */ +/* will result. */ +/* */ +/* M004 July 29/85 */ +/* Only allow 2 characters in the drive name specifier for delete (used */ +/* to be three). */ +/* */ +/* May /87 */ +/* Deletion of source code dealing with parsing and displaying messages */ +/* and addition of SYSLOADMSG, SYSDISPMSG, SYSPARSE in order to conform */ +/* to DOS Version 4.0 specifications to utilize common DOS parser and */ +/* message service routines. */ +/* */ +/* AC000: Changed code for DOS Version 4.0 5/87 */ +/* */ +/* AN000: New code for DOS Version 4.0 5/87 */ +/* AN000;M = message services */ +/* AN000;P = parser service */ +/* */ +/* Ax001: Changed code req'd - PTM0003920 3/88 */ +/* Incorrect message response */ +/* */ +/* Ax002: Changed code req'd - PTM0004045 3/88 */ +/* Incomplete message response */ +/* */ +/**************************************************************************/ + +#include "cds.h" +#include "dos.h" +#include "fcntl.h" +#include "jointype.h" +#include "string.h" +#include "substpar.h" /* ;AN000; Parser structures */ +#include "sysvar.h" + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PARSE EQUATES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +#define ASCII_DRIVE 'A'-1 /* ;AN000;P Convert to Ascii drive */ +#define CAPRESULT 0x0001 /* ;AN000;P Cap result by file table */ +#define DRVONLY_OPT 0x0101 /* ;AN000;P Drive only & optional */ +#define ERRORLEVEL1 1 /* ;AN000;P Parsing error occurred */ +#define FALSE 0 +#define FILESPEC_OPT 0x0201 /* ;AN000;P File spec & optional */ +#define MAX 256 /* ;AN000;P Define a limit */ +#define MAXPOSITION 2 /* ;AN000;P Max positionals in cmdline */ +#define MINPOSITION 0 /* ;AN000;P Min positionals in cmdline */ +#define NOCAPPING 0x0000 /* ;AN000;P Do not cap result */ +#define NULL 0 +#define SWITCH_OPT 0x0000 /* ;AN000;P Optional switch */ + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MESSAGE EQUATES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +#define MSG_PARMNUM 1 /* ;AN000;M Incorrect Num of Parms */ +#define MSG_BADPATH 2 /* ;AN000;M Path not Found */ +#define MSG_NOMEM 3 /* ;AN000;M Insufficient memory */ +#define MSG_BADPARM 4 /* ;AN000;M Invalid parameter */ +#define MSG_NETERR 5 /* ;AN000;M Cannot %1 a network drv */ +#define MSG_INVSWTCH 6 /* ;AN000;M Invalid switch */ + +#define BLNK ' ' /* ;AN000;M For sublist.pad_char */ +#define CARRY 0x0001 /* ;AN000;M To test carry from msg hndlr */ +#define D_SWITCH "/D" /* ;AN000;M For switch id */ +#define EXT_ERR_CLASS 0x01 /* ;AN000;M DOS Extended error class */ +#define MAXWIDTH 0 /* ;AN000;M 0 ensures no padding */ +#define MINWIDTH 1 /* ;AN000;M At least 1 char in parm */ +#define NO_INPUT 0x00 /* ;AN000;M No input characters */ +#define PARSE_ERR_CLASS 0x02 /* ;AN000;M Parse error class */ +#define RESERVED 0 /* ;AN000;M Reserved byte field */ +#define STDERR 0x0002 /* ;AN000;M Standard error device handle */ +#define STDOUT 0x0001 /* ;AN000;M Std output device handle */ +#define STR_INPUT 16 /* ;AN000;M Byte def for sublist.flags */ +#define SUB_ID0 0 /* ;AN000;M 0 for error substitution */ +#define SUB_ID1 1 /* ;AN000;M Only 1 replaceable parameter */ +#define SUBCNT0 0 /* ;AN000;M 0 substitutions in message */ +#define SUBCNT1 1 /* ;AN000;M 1 substitution in message */ +#define SUBLIST_LENGTH 11 /* ;AN000;M Length of sublist structure */ +#define UTILITY_CLASS 0x0ff /* ;AN000;M Utility message class */ + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MISCELLANEOUS ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +extern long GetDPB() ; +extern char fDelete() ; /* SM '87 compiler required extern */ +extern char *malloc() ; /* SM '87 compiler required extern */ +extern char *strbscan() ; /* SM '87 compiler required extern */ + +char cmdln_drive[64] = {0} ; /* ;AN002; Save user's input in */ +char cmdln_flspec[64] = {0} ; /* ;AN002; order to pass to error */ +char cmdln_invalid[64] = {0} ; /* ;AN002; */ +char cmdln_switch[64] = {0} ; /* ;AN002; message, if needed */ +char fix_es_reg[1] ; /* ;AN000;P Corrects es reg after type-"far" */ +char p_drive[3] ; /* ;AN000;P Recvs drive ltr from parser */ +char p_filespec[64] ; /* ;AN000;P Recvs filespec from parser */ +char replparm_SUBST[] = "SUBST" ; /* ;AN000;P Cannot SUBST a network drv */ + +unsigned char source[MAX] = {0} ; /* ;AN000;P buffer for string manipulation */ + +int index ; /* ;AN000;P Used in creating cmdline string */ + +struct sysVarsType SysVars ; + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ PARSE STRUCTURES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +struct p_parms p_p ; /* ;AN000;P # of extras & pts to descrptn */ +struct p_parmsx p_px ; /* ;AN000;P min/max parms & pts to controls */ +struct p_control_blk p_con1 ; /* ;AN000;P 1st posit parm in cmd str */ +struct p_control_blk p_con2 ; /* ;AN000;P 2nd posit parm in cmd str */ +struct p_switch_blk p_swi1 ; /* ;AN000;P /D switch in cmd str */ +struct p_result_blk rslt1 ; /* ;AN000;P Result blk rtrnd from parser */ +struct p_fresult_blk rslt2 ; /* ;AN000;P Result blk rtrnd from parser */ +struct p_result_blk rslt3 ; /* ;AN000;P Result blk rtrnd from parser */ +struct noval novals = {0} ; /* ;AN000;P Value list not used */ + +union REGS inregs, outregs ; /* ;AN000;P Define register variables */ + +/**************************************************************************/ +/* */ +/* SUBROUTINE NAME: main (program entry point) */ +/* */ +/* SUBROUTINE FUNCTION: Preload message file */ +/* Get the command line parameters */ +/* Parse the command line by calling SYSPARSE */ +/* Verify the correctness of the parameters */ +/* Check for deletion switch */ +/* Check source path and destination not same */ +/* Determine if source or destination is network */ +/* Determine if currently spliced */ +/* Print messages by calling SYSDISPMSG */ +/* */ +/* EXTERNAL ROUTINES: SYSLOADMSG */ +/* SYSDISPMSG */ +/* SYSPARSE */ +/* */ +/* INTERNAL ROUTINES: BackFix Load_Msg */ +/* fDelete Display_Msg */ +/* Insert Parser_Prep */ +/* Display dispmsg_terminate */ +/* */ +/**************************************************************************/ + +main(c, v) +int c ; +char *v[] ; +{ + char far * fptr ; /* ;AN000;P Pointer to parser's buffer */ + + int delflag = FALSE ; /* Deletion specified M001 */ + int fchar = 0 ; /* ;AN000;P Parser filespec chars */ + int more_to_parse = TRUE ; /* ;AN000;P While parsing cmdline */ + int pdrive_flg = FALSE ; /* ;AN000;P Is there a drive letter? */ + int pflspec_flg = FALSE ; /* ;AN000;P Is there a filespec? */ + +/************************ BEGIN ***********************************************/ + + load_msg() ; /* ;AN000;M Point to msgs & chk DOS ver */ + + for (index = 1; index <= c; index++) /* ;AN000;P Loop through end of cmd line */ + { /* ;AN000;P */ + strcat(source,v[index]) ; /* ;AN000;P Add the argument */ + strcat(source," ") ; /* ;AN000;P Separate with a space */ + } /* ;AN000;P */ + Parser_Prep(source) ; /* ;AN000;P Initialization for the parser */ + + while (more_to_parse) /* ;AN000;P test the flag */ + { /* ;AN000;P */ + index = 0 ; /* ;AN002; Init array index */ + parse(&inregs,&outregs) ; /* ;AN000;P call the parser */ + if (outregs.x.ax == P_No_Error) /* ;AN000;P if no error */ + { /* ;AN000;P */ + if (outregs.x.dx == (unsigned short)&rslt1) /* ;AN000;P if result is drv ltr */ + { /* ;AN000;P */ + p_drive[0] = *(rslt1.p_result_buff) ; /* ;AN000;P save the drive letter */ + p_drive[0] += (char)ASCII_DRIVE ; /* ;AN000;P */ + p_drive[1] = COLON ; /* ;AN000;P */ + pdrive_flg = TRUE ; /* ;AN000;P and set the flag */ + for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */ + { /* ;AN002; parser just parsed */ + cmdln_drive[index] = *(char *)inregs.x.si ; /* ;AN002; */ + index++ ; /* ;AN002; */ + } /* ;AN002; */ + } /* ;AN000;P */ + else /* ;AN000;P */ + if (outregs.x.dx == (unsigned short)&rslt2) /* ;AN000;P if result is filespec */ + { /* ;AN000;P */ + for (fptr = rslt2.fp_result_buff; (char)*fptr != NULL; fptr++) /* ;AN000;P From beg of buf til nul */ + { /* ;AN000;P */ + p_filespec[fchar] = (char)*fptr ; /* ;AN000;P copy from rslt field buf */ + fchar++ ; /* ;AN000;P */ + } /* ;AN000;P */ + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + pflspec_flg = TRUE ; /* ;AN000;P and set the flag */ + for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */ + { /* ;AN002; parser just parsed */ + cmdln_flspec[index] = *(char *)inregs.x.si ; /* ;AN002; */ + index++ ; /* ;AN002; */ + } /* ;AN002; */ + } /* ;AN000;P */ + else /* ;AN000;P */ + { /* ;AN000;P */ + for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */ + { /* ;AN002; parser just parsed */ + cmdln_switch[index] = *(char *)inregs.x.si ; /* ;AN002; */ + index++ ; /* ;AN002; */ + } /* ;AN002; */ + if (!delflag) /* ;AN000;P Check for dup switch */ + delflag = TRUE ; /* ;AN000;P it's /D switch */ + else /* ;AN000;P else it's a duplicate switch */ + dispmsg_terminate(MSG_INVSWTCH,cmdln_switch) ; /* ;AN000;P display err msg & exit util */ + } /* ;AN000;P */ + } /* ;AN000;P */ + else /* ;AN000;P */ + if (outregs.x.ax != P_RC_EOL) /* ;AN000;P there must be an error */ + { /* ;AN000;P */ + for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN002; Copy whatever */ + { /* ;AN002; parser just parsed */ + cmdln_invalid[index] = *(char *)inregs.x.si ; /* ;AN002; */ + index++ ; /* ;AN002; */ + } /* ;AN002; */ + switch (outregs.x.ax) /* ;AN000;P See what error the */ + { /* ;AN000;P parser may have found */ + case P_Too_Many : dispmsg_terminate(MSG_PARMNUM,cmdln_invalid) ; /* ;AN000;P incorrect syntax */ + break ; /* ;AN000;P more_to_parse = FALSE */ + case P_Not_In_SW : dispmsg_terminate(MSG_INVSWTCH,cmdln_invalid) ; /* ;AN000;P Invalid switch */ + break ; /* ;AN000;P more_to_parse = FALSE */ + case P_Op_Missing : /* ;AN000;P Required operand missing */ + case P_Not_In_Key : /* ;AN000;P Not in kywrd list provided */ + case P_Out_Of_Range : /* ;AN000;P Out of range specified */ + case P_Not_In_Val : /* ;AN000;P Not in val list provided */ + case P_Not_In_Str : /* ;AN000;P Not in strg list provided */ + case P_Syntax : dispmsg_terminate(MSG_BADPARM,cmdln_invalid) ; /* ;AN000;P incorrect syntax */ + break ; /* ;AN000;P more_to_parse = FALSE */ + default : display_msg(MSG_BADPARM,cmdln_invalid) ; /* ;AN000;P */ + exit(ERRORLEVEL1) ; /* ;AN000;P Something's wrong */ + } /* ;AN000;P */ + } /* ;AN000;P */ + else /* ;AN000;P End of the cmdline */ + more_to_parse = FALSE ; /* ;AN000;P */ + inregs.x.cx = outregs.x.cx ; /* ;AN000;P Move the count */ + inregs.x.si = outregs.x.si ; /* ;AN000;P Move the pointer */ + } /* ;AN000;P */ + + if (pdrive_flg && !(pflspec_flg || delflag)) /* ;AN000;P drive & no flspec or delete ? */ + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AN000;P display error msg & exit utility */ + + if (pflspec_flg && !pdrive_flg) /* ;AN000;P filespec & no drive ? */ + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AN000;P display error msg & exit utility */ + + if (delflag && !pdrive_flg) /* ;AN000;P delete & no drive ? */ + dispmsg_terminate(MSG_BADPARM,cmdln_switch) ; /* ;AN000;P display error msg & exit utility */ + + if (pdrive_flg && pflspec_flg && delflag) /* ;AN000;P drive, filespec & /D ? */ + dispmsg_terminate(MSG_PARMNUM,cmdln_switch) ; /* ;AN000;P display error msg & exit utility */ + + GetVars(&SysVars) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + + if (c == 1) /* display all tree aliases */ + Display() ; + else + if (delflag) /* ;AC000;P Are we to delete a subst? */ + { + if (!fDelete(p_drive)) + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* :AC002; */ + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + } + else + Insert(p_drive,p_filespec) ; /* ;AC000;P */ + + exit(0) ; +} +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +char *BackFix(p) +char *p ; +{ + char *p1 ; + char *p2 ; + + p2 = p-1 ; + while (*(p2 = strbscan(p1 = p2+1,"\\")) != NULL) ; + + /* p1 points to char after last path sep. */ + /* If this is a NULL, p already has a trailing path sep. */ + + if (*p1 != NULL) + if ((p1 = malloc(strlen(p)+2)) == NULL) + dispmsg_terminate(MSG_NOMEM) ; /* ;AN000;M */ + else + { + strcpy(p1, p) ; + strcat(p1, "\\") ; + p = p1 ; + } + return(p) ; +} +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +char fDelete(v) +char *v ; +{ + struct CDSType CDS ; + int drive ; + + /* M004 Only 2 characters in the drive specifier */ + /* (and move before the call to BackFix) */ + + if (strlen(v) != 2 || v[1] != ':') + return(FALSE) ; + + v = BackFix(v) ; + drive = *v - 'A' ; + + if (!fGetCDS(drive, &CDS) || /* If CDS doesn't exist or */ + !TESTFLAG(CDS.flags,CDSLOCAL) || /* was not substed or */ + drive == getdrv()) /* is the current drive */ + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M */ + + strcpy(CDS.text, "A:\\") ; /* Set-up text of curr directory */ + CDS.text[0] += drive ; + CDS.cbEnd = 2 ; /* Set backup limit */ + + /* If physical, then mark as inuse and set-up DPB pointer */ + + CDS.flags = drive >= SysVars.cDrv ? FALSE : CDSINUSE ; + CDS.pDPB = drive >= SysVars.cDrv ? 0L : GetDPB(drive) ; + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + fPutCDS(drive, &CDS) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + return(TRUE) ; +} +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Insert(s, d) +char *s, *d ; +{ + struct CDSType CDS ; + int drives, drived ; + char buf[MAXPATHLEN] ; + + rootpath(d, buf) ; + + if (strlen(d) == 2 && d[1] == ':') + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000;M Insure dest not just a drive */ + + if (strlen(buf) == 3) /* Dest must exist, try root 1st */ + if (buf[1] != ':' || (buf[2]) != PathChr) + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000;M */ + + /* M003 - path verification was treated as an ELSE condition */ + /* else Must be subdir... make sure */ + + if (open(buf,O_BINARY) != -1) + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000;M */ + else + if (access(buf,NULL) == -1) + dispmsg_terminate(MSG_BADPATH,cmdln_flspec) ; /* ;AC000;M */ + + s = BackFix(s) ; + d = BackFix(buf) ; + drives = *s - 'A' ; + drived = *d - 'A' ; + + if (fNet(drives)) /* Src can't be net drive, is reuse of CDS */ + dispmsg_terminate(MSG_NETERR) ; /* ;AC000;M */ + + strcpy(fix_es_reg,NULL); /* ;AN000;P (Set es reg correct) */ + if (fNet(drived)) /* Dest can't be a net drive either */ + dispmsg_terminate(MSG_NETERR) ; /* ;AC000;M */ + + /* If src or dest invalid; or dest too long; or drives the same; or can't */ + /* get CDS for source; or source is current drive; or drive is net, */ + /* splices or substed already; or destination is not physical */ + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + if (drives < 0 || drives >= SysVars.cCDS || + drives == drived || + !fGetCDS(drives, &CDS) || + drives == getdrv() || + TESTFLAG(CDS.flags,CDSNET|CDSSPLICE|CDSLOCAL)) + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M */ + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + if (drived < 0 || drived >= SysVars.cCDS || + strlen(d) >= DIRSTRLEN || + !fPhysical(drived)) + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000;M */ + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + if (strlen(d) != 3) /* Chop trailing \ if not at root */ + d[strlen(d)-1] = 0 ; + + strcpy(CDS.text, d) ; + CDS.cbEnd = strlen(CDS.text) ; + if (CDS.cbEnd == 3) + CDS.cbEnd-- ; + CDS.flags = CDSINUSE|CDSLOCAL ; + if ((CDS.pDPB = GetDPB(drived)) == -1L) + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000;M */ + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + CDS.ID = -1L ; + fPutCDS(drives, &CDS) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + return ; /* ;AN000; */ +} +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Display() /* Display current list of substs */ +{ + struct CDSType CDS ; + int i ; + + for (i=0 ; fGetCDS(i, &CDS) ; i++) + if (TESTFLAG(CDS.flags,CDSLOCAL)) + { + if (CDS.cbEnd == 2) + CDS.cbEnd ++ ; + CDS.text[CDS.cbEnd] = 0 ; + printf("%c: => %s\n", i+'A', CDS.text) ; + } + return ; /* ;AN000; */ +} +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/**************************************************************************/ +/* */ +/* SUBROUTINE NAME: load_msg */ +/* */ +/* SUBROUTINE FUNCTION: Load the set of SUBST Utility messages to */ +/* become available for display_msg call. */ +/* */ +/* ERROR EXIT: Utility will be terminated by sysloadmsg if */ +/* version check is incorrect. */ +/* */ +/* EXTERNAL REF: SYSLOADMSG */ +/* */ +/**************************************************************************/ + +load_msg() /* ;AN000;M */ +{ /* ;AN000;M */ + sysloadmsg(&inregs,&outregs) ; /* ;AN000;M Load utility messages */ + if (outregs.x.cflag & CARRY) /* ;AN000;M If problem loading msgs */ + { /* ;AN000;M */ + sysdispmsg(&outregs,&outregs) ; /* ;AN000;M then display the err msg */ + exit(ERRORLEVEL1) ; /* ;AN000;M */ + } /* ;AN000;M */ + return ; /* ;AN000;M */ +} /* ;AN000;M */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/**************************************************************************/ +/* */ +/* SUBROUTINE NAME: display_msg */ +/* */ +/* SUBROUTINE FUNCTION: The correct message called by main is displayed */ +/* to standard out. */ +/* */ +/* INPUT: msg_num (message number to display) */ +/* outline (substitution parameter) */ +/* */ +/* OUTPUT: none */ +/* */ +/* ERROR EXIT: Display error message corresponding to number */ +/* returned in AX. */ +/* */ +/* EXTERNAL REF: SYSDISPMSG */ +/* */ +/**************************************************************************/ + +display_msg(msg_num,outline) /* ;AN000;M */ +int msg_num ; /* ;AN000;M Message number #define'd */ +char *outline ; /* ;AN001; Substitution parameter */ +{ /* ;AN000;M */ + unsigned char function ; /* ;AN000;M Y/N response or press key? */ + unsigned int message, /* ;AN000;M Message number to display */ + msg_class, /* ;AN000;M Which class of messages? */ + sub_cnt, /* ;AN000;M Number of substitutions? */ + handle ; /* ;AN000;M Display where? */ + + struct sublist /* ;AN000;M */ + { /* ;AN000;M */ + unsigned char size ; /* ;AN000;M Points to next sublist */ + unsigned char reserved ; /* ;AN000;M Required for sysdispmsg */ + unsigned far *value ; /* ;AN000;M Data pointer */ + unsigned char id ; /* ;AN000;M Id of substitution parm (%1) */ + unsigned char flags ; /* ;AN000;M Format of data - (a0sstttt) */ + unsigned char max_width ; /* ;AN000;M Maximum field width */ + unsigned char min_width ; /* ;AN000;M Minimum field width */ + unsigned char pad_char ; /* ;AN000;M char to pad field */ + } sublist ; /* ;AN000;M */ + + switch (msg_num) /* ;AN000;M Which msg to display? */ + { /* ;AN000;M */ + case MSG_PARMNUM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */ + message = 2 ; /* ;AN000;M Message number to display */ + msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */ + sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */ + handle = STDERR ; /* ;AN000;M Display where? */ + break ; /* ;AN000;M */ + case MSG_BADPATH : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */ + message = 3 ; /* ;AN000;M Message number to display */ + msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */ + sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */ + handle = STDERR ; /* ;AN000;M Display where? */ + break ; /* ;AN000;M */ + case MSG_NOMEM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */ + message = 8 ; /* ;AN000;M Message number to display */ + msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */ + sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */ + handle = STDERR ; /* ;AN000;M Display where? */ + break ; /* ;AN000;M */ + case MSG_BADPARM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */ + message = 10 ; /* ;AN000;M Message number to display */ + msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */ + sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */ + handle = STDERR ; /* ;AN000;M Display where? */ + break ; /* ;AN000;M */ + case MSG_NETERR : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */ + message = 12 ; /* ;AN000;M Message number to display */ + msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */ + sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */ + handle = STDERR ; /* ;AN000;M Display where? */ + break ; /* ;AN000;M */ + case MSG_INVSWTCH: function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */ + message = 3 ; /* ;AN000;M Message number to display */ + msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */ + sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */ + handle = STDERR ; /* ;AN000;M Display where? */ + break ; /* ;AN000;M */ + default : exit(ERRORLEVEL1) ; /* ;AN000;M */ + break ; /* ;AN000;M */ + } /* ;AN000;M */ + + switch (msg_num) /* ;AN000;M */ + { /* ;AN000;M */ + case MSG_NOMEM : inregs.x.ax = message ; /* ;AN000;M Insufficient memory */ + inregs.x.bx = handle ; /* ;AN000;M STDERR */ + inregs.x.cx = sub_cnt ; /* ;AN000;M SUBCNT0 */ + inregs.h.dl = function ; /* ;AN000;M NO_INPUT */ + inregs.h.dh = msg_class ; /* ;AN000;M Extended, Parse or Utility */ + sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call common msg service */ + break ; /* ;AN000;M */ + case MSG_INVSWTCH: /* ;AN000;M Invalid switch */ + case MSG_PARMNUM : /* ;AN000;M Incorrect num of parms */ + case MSG_BADPARM : /* ;AN000;M Invalid parameter */ + case MSG_BADPATH : sublist.value = (unsigned far *)outline ; /* ;AN000;M Path not found */ + sublist.reserved = RESERVED ; /* ;AN000;M */ + sublist.id = SUB_ID0 ; /* ;AN000;M */ + sublist.flags = STR_INPUT ; /* ;AN000;M */ + sublist.max_width = MAXWIDTH ; /* ;AN000;M */ + sublist.min_width = MINWIDTH ; /* ;AN000;M */ + sublist.pad_char = (unsigned char)BLNK ; /* ;AN000;M */ + inregs.x.ax = message ; /* ;AN000;M Cannot SUBST a network drive */ + inregs.x.bx = handle ; /* ;AN000;M STDERR */ + inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M Point to the sub buffer */ + inregs.x.cx = sub_cnt ; /* ;AN000;M SUBCNT1 */ + inregs.h.dl = function ; /* ;AN000;M STR_INPUT */ + inregs.h.dh = msg_class ; /* ;AN000;M Extended, Parse or Utility */ + sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call common msg service */ + break ; /* ;AN000;M */ + case MSG_NETERR : sublist.value = (unsigned far *)replparm_SUBST ; /* ;AN000;M Cannot SUBST a network drive */ + sublist.reserved = RESERVED ; /* ;AN000;M */ + sublist.id = SUB_ID1 ; /* ;AN000;M */ + sublist.flags = STR_INPUT ; /* ;AN000;M */ + sublist.max_width = MAXWIDTH ; /* ;AN000;M */ + sublist.min_width = MINWIDTH ; /* ;AN000;M */ + sublist.pad_char = (unsigned char)BLNK ; /* ;AN000;M */ + inregs.x.ax = message ; /* ;AN000;M Cannot SUBST a network drive */ + inregs.x.bx = handle ; /* ;AN000;M STDERR */ + inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M Point to the sub buffer */ + inregs.x.cx = sub_cnt ; /* ;AN000;M SUBCNT1 */ + inregs.h.dl = function ; /* ;AN000;M STR_INPUT */ + inregs.h.dh = msg_class ; /* ;AN000;M Extended, Parse or Utility */ + sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call common msg service */ + break ; /* ;AN000;M */ + default : exit(ERRORLEVEL1) ; /* ;AN000;M */ + break ; /* ;AN000;M */ + } /* ;AN000;M */ + + if (outregs.x.cflag & CARRY) /* ;AN000;M Is the carry flag set? */ + { /* ;AN000;M Then setup regs for extd-err */ + inregs.x.bx = STDERR ; /* ;AN000;M */ + inregs.x.cx = SUBCNT0 ; /* ;AN000;M */ + inregs.h.dl = NO_INPUT ; /* ;AN000;M */ + inregs.h.dh = EXT_ERR_CLASS ; /* ;AN000;M */ + sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call to display ext_err msg */ + exit(ERRORLEVEL1) ; /* ;AN000;M */ + } /* ;AN000;M */ + return ; /* ;AN000;M */ +} /* ;AN000;M */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/**************************************************************************/ +/* */ +/* SUBROUTINE NAME: dispmsg_terminate */ +/* */ +/* SUBROUTINE FUNCTION: Display the message, then terminate the utility.*/ +/* */ +/* INPUT: msg_num (#define'd message to display) */ +/* outline (substitution parameter) */ +/* */ +/**************************************************************************/ + +dispmsg_terminate(msg_num,outline) /* ;AN000;P */ +int msg_num ; /* ;AN000;P Message number #define'd */ +char *outline ; /* ;AN001; Substitution parameter */ +{ /* ;AN000;P */ + display_msg(msg_num,outline) ; /* ;AN000;P First, display the msg */ + exit(ERRORLEVEL1) ; /* ;AN000;P Then, terminate utility */ +} /* ;AN000;P */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/**************************************************************************/ +/* */ +/* SUBROUTINE NAME: Parser_Prep */ +/* */ +/* SUBROUTINE FUNCTION: Initialize all structures for the parser. */ +/* */ +/* INPUT: source (command line string) */ +/* */ +/* OUTPUT: none */ +/* */ +/* EXTERNAL REF: parse */ +/* */ +/**************************************************************************/ + +Parser_Prep(source) /* ;AN000;P */ +char *source ; /* ;AN000;P Commandline */ +{ /* ;AN000;P */ + p_p.p_parmsx_address = &p_px ; /* ;AN000;P Address of extended parm list */ + p_p.p_num_extra = 0 ; /* ;AN000;P No extra declarations */ + + p_px.p_minp = MINPOSITION ; /* ;AN000;P */ + p_px.p_maxp = MAXPOSITION ; /* ;AN000;P */ + p_px.p_control1 = &p_con1 ; /* ;AN000;P Point to 1st control blk */ + p_px.p_control2 = &p_con2 ; /* ;AN000;P Point to 2nd control blk */ + p_px.p_maxs = 1 ; /* ;AN000;P Specify # of switches */ + p_px.p_switch = &p_swi1 ; /* ;AN000;P Point to the switch blk */ + p_px.p_maxk = 0 ; /* ;AN000;P Specify # of keywords */ + + p_con1.p_match_flag = DRVONLY_OPT ; /* ;AN000;P Drive only & optional */ + p_con1.p_function_flag = NOCAPPING ; /* ;AN000;P Cap result by file table */ + p_con1.p_result_buf = (unsigned int)&rslt1 ; /* ;AN000;P Point to result blk */ + p_con1.p_value_list = (unsigned int)&novals ; /* ;AN000;P Point to no value list */ + p_con1.p_nid = 0 ; /* ;AN000;P Not a switch id */ + + p_con2.p_match_flag = FILESPEC_OPT ; /* ;AN000;P File spec & optional */ + p_con2.p_function_flag = CAPRESULT ; /* ;AN000;P Cap result by file table */ + p_con2.p_result_buf = (unsigned int)&rslt2 ; /* ;AN000;P Point to result blk */ + p_con2.p_value_list = (unsigned int)&novals ; /* ;AN000;P Point to no value list */ + p_con2.p_nid = 0 ; /* ;AN000;P Not a switch id */ + + p_swi1.sp_match_flag = SWITCH_OPT ; /* ;AN000;P Optional (switch) */ + p_swi1.sp_function_flag = NOCAPPING ; /* ;AN000;P Cap result by file table */ + p_swi1.sp_result_buf = (unsigned int)&rslt3 ; /* ;AN000;P Point to result blk */ + p_swi1.sp_value_list = (unsigned int)&novals ; /* ;AN000;P Point to no value list */ + p_swi1.sp_nid = 1 ; /* ;AN000;P One switch allowed */ + strcpy(p_swi1.sp_keyorsw,D_SWITCH) ; /* ;AN000;P Identify the switch */ + + inregs.x.cx = 0 ; /* ;AN000;P Operand ordinal */ + inregs.x.di = (unsigned int)&p_p ; /* ;AN000;P Address of parm list */ + inregs.x.si = (unsigned int)source ; /* ;AN000;P Make DS:SI point to source */ + return ; /* ;AN000; */ +} /* ;AN000;P */ diff --git a/v4.0/src/CMD/SUBST/SUBST.LNK b/v4.0/src/CMD/SUBST/SUBST.LNK new file mode 100644 index 0000000..f0a8493 --- /dev/null +++ b/v4.0/src/CMD/SUBST/SUBST.LNK @@ -0,0 +1,12 @@ +SUBST.OBJ+ +..\..\inc\ERRTST.OBJ+ +..\..\inc\SYSVAR.OBJ+ +..\..\inc\CDS.OBJ+ +..\..\inc\DPB.OBJ+ +_MSGRET.OBJ+ +_PARSE.OBJ +SUBST +NUL +..\..\inc\comsubs.lib+ +..\..\mapper\mapper.lib; + \ No newline at end of file diff --git a/v4.0/src/CMD/SUBST/SUBST.SKL b/v4.0/src/CMD/SUBST/SUBST.SKL new file mode 100644 index 0000000..fa33102 --- /dev/null +++ b/v4.0/src/CMD/SUBST/SUBST.SKL @@ -0,0 +1,22 @@ +;SUBST Utility ;AN000; +;Message Service Routine ;AN000; + +:util SUBST ;BEGIN UTIL ;AN000; + +:class 1 ;EXTENDED ERRORS ;AN000; +;------- --------------- +;:use EXTEND3 ;Path not found +;:use EXTEND8 ;Insufficient memory + +:class 2 ;PARSE ERRORS ;AN000; +;------- ------------ +;:use PARSE3 ;Invalid switch +;:use PARSE10 ;Invalid parameter ;AN000; + +:class A ;COMMON & DEFINED MSGS ;AN000; +;------- ------------ +:use 1 COMMON1 ;Incorrect DOS version ;AN000; +:def 2 "Incorrect number of parameters",CR,LF ;AN000; +:use 12 COMMON12 ;Cannot %1 a network drive ;AN000; + +:end ;END UTIL ;AN000; diff --git a/v4.0/src/CMD/SUBST/SUBSTPAR.H b/v4.0/src/CMD/SUBST/SUBSTPAR.H new file mode 100644 index 0000000..2f985d5 --- /dev/null +++ b/v4.0/src/CMD/SUBST/SUBSTPAR.H @@ -0,0 +1,155 @@ +/*  */ +/*----------------------------------------------------------------------+ +| | +| This file contains the structures and defines that are needed to use | +| the parser from a C program. | +| ** customized for the JOIN and SUBST utilities ** | +| | +| Date: 5-21-87 | +| | ++----------------------------------------------------------------------*/ + + +struct p_parms + { + struct p_parmsx *p_parmsx_address; /* address of p_parmsx */ + unsigned char p_num_extra; /* number of extra stuff */ + }; + +struct p_parmsx + { + unsigned char p_minp; /* Minimum positional number */ + unsigned char p_maxp; /* Maximum positional number */ + struct p_control_blk *p_control1; /* Address of the 1st CONTROL block */ + struct p_control_blk *p_control2; /* Address of the 2nd CONTROL block */ + unsigned char p_maxs; /* Maximun switches */ + struct p_switch_blk *p_switch; /* Address of the SWITCH block */ + unsigned char p_maxk; /* Maximum keywords */ + }; + + +struct p_control_blk + { + unsigned int p_match_flag; /* Controls type matched */ + unsigned int p_function_flag; /* Function should be taken */ + unsigned int p_result_buf; /* Result buffer address */ + unsigned int p_value_list; /* Value list address */ + unsigned char p_nid; /* # of keyword/SW synonyms */ + }; + +struct p_switch_blk + { + unsigned int sp_match_flag; /* Controls type matched */ + unsigned int sp_function_flag; /* Function should be taken */ + unsigned int sp_result_buf; /* Result buffer address */ + unsigned int sp_value_list; /* Value list address */ + unsigned char sp_nid; /* # of keyword/SW synonyms */ + unsigned char sp_keyorsw[3]; /* keyword or sw */ + }; + +/* Match_Flags */ + +#define P_Num_Val 0x8000 /* Numeric Value */ +#define P_SNum_Val 0x4000 /* Signed numeric value */ +#define P_Simple_S 0x2000 /* Simple string */ +#define P_Date_S 0x1000 /* Date string */ +#define P_Time_S 0x0800 /* Time string */ +#define P_Cmpx_S 0x0400 /* Complex string */ +#define P_File_Spc 0x0200 /* File Spec */ +#define P_Drv_Only 0x0100 /* Drive Only */ +#define P_Qu_String 0x0080 /* Quoted string */ +#define P_Ig_Colon 0x0010 /* Ignore colon at end in match */ +#define P_Repeat 0x0002 /* Repeat allowed */ +#define P_Optional 0x0001 /* Optional */ + +/*----------------------------------------------------------------------+ +| | +| Function flags | +| | ++----------------------------------------------------------------------*/ + +#define P_CAP_File 0x0001 /* CAP result by file table */ +#define P_CAP_Char 0x0002 /* CAP result by character table */ +#define P_Rm_Colon 0x0010 /* Remove ":" at the end */ + + + +#define P_nval_None 0 /* no value list ID */ +#define P_nval_Range 1 /* range list ID */ +#define P_nval_Value 2 /* value list ID */ +#define P_nval_String 3 /* string list ID */ +#define P_Len_Range 9 /* Length of a range choice(two DD plus one DB) */ +#define P_Len_Value 5 /* Length of a value choice(one DD plus one DB) */ +#define P_Len_String 3 /* Length of a string choice(one DW plus one DB) */ + + +/*----------------------------------------------------------------------+ +| | +| Result block structure | +| | ++----------------------------------------------------------------------*/ + +struct p_result_blk + { + unsigned char P_Type; /* Type returned */ + unsigned char P_Item_Tag; /* Matched item tag */ + unsigned int P_SYNONYM_Ptr; /* pointer to Synonym list returned */ + unsigned int p_result_buff[2]; /* result value */ + }; + +struct p_fresult_blk + { + unsigned char fP_Type; /* Type returned */ + unsigned char fP_Item_Tag; /* Matched item tag */ + unsigned int fP_SYNONYM_Ptr; /* pointer to Synonym list returned */ + char far * fp_result_buff; /* result value */ + }; + +/*----------------------------------------------------------------------+ +| | +| type | +| | ++----------------------------------------------------------------------*/ + +#define P_EOL 0 /* End of line */ +#define P_Number 1 /* Number */ +#define P_List_Idx 2 /* List Index */ +#define P_String 3 /* String */ +#define P_Complex 4 /* Complex */ +#define P_File_Spec 5 /* File Spec */ +#define P_Drive 6 /* Drive */ +#define P_Date_F 7 /* Date */ +#define P_Time_F 8 /* Time */ +#define P_Quoted_String 9 /* Quoted String */ + +#define P_No_Tag 0x0FF /* No ITEM_TAG found */ + +/*----------------------------------------------------------------------+ +| | +| Value list structure | +| | ++----------------------------------------------------------------------*/ + +struct noval + { + unsigned char null; + }; + +/*----------------------------------------------------------------------+ +| | +| following return code will be returned in the AX register. | +| | ++----------------------------------------------------------------------*/ + +#define P_No_Error 0 /* No error */ +#define P_Too_Many 1 /* Too many operands */ +#define P_Op_Missing 2 /* Required operand missing */ +#define P_Not_In_SW 3 /* Not in switch list provided */ +#define P_Not_In_Key 4 /* Not in keyword list provided */ +#define P_Out_Of_Range 6 /* Out of range specified */ +#define P_Not_In_Val 7 /* Not in value list provided */ +#define P_Not_In_Str 8 /* Not in string list provided */ +#define P_Syntax 9 /* Syntax error */ +#define P_RC_EOL 0x0ffff /* End of command line */ + + diff --git a/v4.0/src/CMD/SUBST/_MSGRET.ASM b/v4.0/src/CMD/SUBST/_MSGRET.ASM new file mode 100644 index 0000000..cded0ff --- /dev/null +++ b/v4.0/src/CMD/SUBST/_MSGRET.ASM @@ -0,0 +1,250 @@ +page 60,132 +name _msgret +title C to Message Retriever +;------------------------------------------------------------------- +; +; MODULE: _msgret +; +; PURPOSE: Supplies an interface between C programs and +; the DOS 3.3 message retriever +; +; CALLING FORMAT: +; sysloadmsg(&inregs,&outregs); +; sysgetmsg(&inregs,&outregs); +; sysdispmsg(&inregs,&outregs); +; +; DATE: 5-21-87 +; +;------------------------------------------------------------------- + + INCLUDE SYSMSG.INC ;PERMIT SYSTEM MESSAGE HANDLER DEFINITION;AN000; + + MSG_UTILNAME ;IDENTIFY THE COMPONENT ;AN000; + + .8087 ;AN000; +_TEXT SEGMENT BYTE PUBLIC 'CODE' ;AN000; +_TEXT ENDS ;AN000; +_DATA SEGMENT WORD PUBLIC 'DATA' ;AN000; +_DATA ENDS ;AN000; +CONST SEGMENT WORD PUBLIC 'CONST' ;AN000; +CONST ENDS ;AN000; +_BSS SEGMENT WORD PUBLIC 'BSS' ;AN000; +_BSS ENDS ;AN000; +DGROUP GROUP CONST, _BSS, _DATA ;AN000; + ASSUME CS: _TEXT, DS: _TEXT, SS: DGROUP, ES: DGROUP ;AN000; + + + public _sysloadmsg ;AN000; + public _sysgetmsg ;AN000; + public _sysdispmsg ;AN000; + +;------------------------------------------------------------------- +;------------------------------------------------------------------- + +_DATA segment ;AN000; +.XLIST ;AN000; +.XCREF ;AN000; + MSG_SERVICES ;DATA AREA FOR THE MESSAGE HANDLER ;AN000; +.LIST ;AN000; +.CREF ;AN000; +_DATA ends ;AN000; + + +_TEXT segment ;AN000; + +;------------------------------------------------------------------- + +; = = = = = = = = = = = = + + ;DEFAULT=CHECK DOS VERSION ;AN000; + ;DEFAULT=NEARmsg ;AN000; + ;DEFAULT=INPUTmsg ;AN000; + ;DEFAULT=NUMmsg ;AN000; + ;DEFAULT=NO TIMEmsg ;AN000; + ;DEFAULT=NO DATEmsg ;AN000; +; MSG_SERVICES ;AN000; +; MSG_SERVICES ;MSG TEXT ;AN000; +.XLIST ;AN000; +.XCREF ;AN000; +; MSG_SERVICES ;DATA AREA FOR THE MESSAGE HANDLER ;AN000; + MSG_SERVICES ;AN000; + MSG_SERVICES ;MSG TEXT ;AN000; +.LIST ;AN000; +.CREF ;AN000; +;------------------------------------------------------------------- + +_sysloadmsg proc near ;AN000; + + push bp ; save user's base pointer ;AN000; + mov bp,sp ; set bp to current sp ;AN000; + push di ; save some registers ;AN000; + push si ;AN000; + +; copy C inregs into proper registers + + mov di,[bp+4] ; fix di (arg 0) ;AN000; + +;------------------------------------------------------------------- + + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack;AN000; + + mov ax,[di+00] ; get inregs.x.ax ;AN000; + mov bx,[di+02] ; get inregs.x.bx ;AN000; + mov cx,[di+04] ; get inregs.x.cx ;AN000; + mov dx,[di+06] ; get inregs.x.dx ;AN000; + mov si,[di+08] ; get inregs.x.si ;AN000; + pop di ; get inregs.x.di from stack ;AN000; + + push bp ; save base pointer ;AN000; + +;------------------------------------------------------------------- + call sysloadmsg ; call the message retriever ;AN000; +;------------------------------------------------------------------- + + pop bp ; restore base pointer ;AN000; + push di ; the di value from call is now on stack;AN000; + mov di,[bp+6] ; fix di (arg 1) ;AN000; + + mov [di+00],ax ; load outregs.x.ax ;AN000; + mov [di+02],bx ; load outregs.x.bx ;AN000; + mov [di+04],cx ; load outregs.x.cx ;AN000; + mov [di+06],dx ; load outregs.x.dx ;AN000; + mov [di+08],si ; load outregs.x.si ;AN000; + + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; + + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; + +;------------------------------------------------------------------- + + pop si ; restore registers ;AN000; + pop di ;AN000; + mov sp,bp ; restore sp ;AN000; + pop bp ; restore user's bp ;AN000; + ret ;AN000; + +_sysloadmsg endp ;AN000; + + +_sysgetmsg proc near ;AN000; + + push bp ; save user's base pointer ;AN000; + mov bp,sp ; set bp to current sp ;AN000; + push di ; save some registers ;AN000; + push si ;AN000; + ;AN000; +; copy C inregs into proper registers + + mov di,[bp+4] ; fix di (arg 0) ;AN000; + +;------------------------------------------------------------------- + + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack;AN000; + + mov ax,[di+00] ; get inregs.x.ax ;AN000; + mov bx,[di+02] ; get inregs.x.bx ;AN000; + mov cx,[di+04] ; get inregs.x.cx ;AN000; + mov dx,[di+06] ; get inregs.x.dx ;AN000; + mov si,[di+08] ; get inregs.x.si ;AN000; + pop di ; get inregs.x.di from stack ;AN000; + + push bp ; save base pointer ;AN000; + +;------------------------------------------------------------------- + call sysgetmsg ; call the message retriever ;AN000; +;------------------------------------------------------------------- + + pop bp ; restore base pointer ;AN000; + push di ; the di value from call is now on stack;AN000; + mov di,[bp+6] ; fix di (arg 1) ;AN000; + + mov [di+00],ax ; load outregs.x.ax ;AN000; + mov [di+02],bx ; load outregs.x.bx ;AN000; + mov [di+04],cx ; load outregs.x.cx ;AN000; + mov [di+06],dx ; load outregs.x.dx ;AN000; + mov [di+08],si ; load outregs.x.si ;AN000; + + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; + + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; + +;------------------------------------------------------------------- + + pop si ; restore registers ;AN000; + pop di ;AN000; + mov sp,bp ; restore sp ;AN000; + pop bp ; restore user's bp ;AN000; + ret ;AN000; + +_sysgetmsg endp ;AN000; + +_sysdispmsg proc near ;AN000; + + push bp ; save user's base pointer ;AN000; + mov bp,sp ; set bp to current sp ;AN000; + push di ; save some registers ;AN000; + push si ;AN000; + +; copy C inregs into proper registers + + mov di,[bp+4] ; fix di (arg 0) ;AN000; + +;------------------------------------------------------------------- + + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack;AN000; + + mov ax,[di+00] ; get inregs.x.ax ;AN000; + mov bx,[di+02] ; get inregs.x.bx ;AN000; + mov cx,[di+04] ; get inregs.x.cx ;AN000; + mov dx,[di+06] ; get inregs.x.dx ;AN000; + mov si,[di+08] ; get inregs.x.si ;AN000; + pop di ; get inregs.x.di from stack ;AN000; + + push bp ; save base pointer ;AN000; + +;------------------------------------------------------------------- + call sysdispmsg ; call the message retriever ;AN000; +;------------------------------------------------------------------- + + pop bp ; restore base pointer ;AN000; + push di ; the di value from call is now on stack;AN000; + mov di,[bp+6] ; fix di (arg 1) ;AN000; + + mov [di+00],ax ; load outregs.x.ax ;AN000; + mov [di+02],bx ; load outregs.x.bx ;AN000; + mov [di+04],cx ; load outregs.x.cx ;AN000; + mov [di+06],dx ; load outregs.x.dx ;AN000; + mov [di+08],si ; load outregs.x.si ;AN000; + + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; + + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; + +;------------------------------------------------------------------- + + pop si ; restore registers ;AN000; + pop di ;AN000; + mov sp,bp ; restore sp ;AN000; + pop bp ; restore user's bp ;AN000; + ret ;AN000; + +_sysdispmsg endp ;AN000; + +include msgdcl.inc + +_TEXT ends ; end code segment ;AN000; + end ;AN000; + + \ No newline at end of file diff --git a/v4.0/src/CMD/SUBST/_PARSE.ASM b/v4.0/src/CMD/SUBST/_PARSE.ASM new file mode 100644 index 0000000..8c44df5 --- /dev/null +++ b/v4.0/src/CMD/SUBST/_PARSE.ASM @@ -0,0 +1,121 @@ +page 60,132 +name _parse +title C to PARSER interface +;------------------------------------------------------------------- +; +; MODULE: _parse +; +; PURPOSE: Supplies an interface between C programs and +; the DOS 3.3 parser +; +; **(Customized for the SUBST utility) +; +; CALLING FORMAT: +; parse(&inregs,&outregs); +; +; DATE: 5-21-87 +; +;------------------------------------------------------------------- + +; extrn sysparse:far + + public _parse ;AN000; + +;------------------------------------------------------------------- + +; set for SUBST +; ------------- + +FarSW equ 0 ; make sysparse be a NEAR proc ;AN000; +TimeSW equ 0 ; Check time format ;AN000; +FileSW equ 1 ; Check file specification ;AN000; +CAPSW equ 1 ; Perform CAPS if specified ;AN000; +CmpxSW equ 0 ; Check complex list ;AN000; +NumSW equ 0 ; Check numeric value ;AN000; +KeySW equ 0 ; Support keywords ;AN000; +SwSW equ 1 ; Support switches ;AN000; +Val1SW equ 0 ; Support value definition 1 ;AN000; +Val2SW equ 0 ; Support value definition 2 ;AN000; +Val3SW equ 0 ; Support value definition 3 ;AN000; +DrvSW equ 1 ; Support drive only format ;AN000; +QusSW equ 0 ; Support quoted string format ;AN000; +;------------------------------------------------------------------- + +DGROUP GROUP _DATA +PGROUP GROUP _TEXT + +_DATA segment byte public 'DATA' ;AN000; +BASESW = 1 ;SPECIFY, PSDATA POINTED TO BY "DS" +INCSW = 0 ;PSDATA.INC IS ALREADY INCLUDED + INCLUDE PSDATA.INC ;PARSER'S WORK SPACE +_DATA ends ;AN000; + +_TEXT segment byte public 'CODE' ;AN000; + + ASSUME CS: PGROUP ;AN000; + ASSUME DS: DGROUP ;AN000; + +;------------------------------------------------------------------- +include parse.asm ; include the parser ;AN000; +;------------------------------------------------------------------- + +_parse proc near ;AN000; + + push bp ; save user's base pointer ;AN000; + mov bp,sp ; set bp to current sp ;AN000; + push di ; save some registers ;AN000; + push si ;AN000; + +; copy C inregs into proper registers + + mov di,[bp+4] ; fix di (arg 0) ;AN000; + +;------------------------------------------------------------------- + + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack;AN000; + + mov ax,[di+00] ; get inregs.x.ax ;AN000; + mov bx,[di+02] ; get inregs.x.bx ;AN000; + mov cx,[di+04] ; get inregs.x.cx ;AN000; + mov dx,[di+06] ; get inregs.x.dx ;AN000; + mov si,[di+08] ; get inregs.x.si ;AN000; + pop di ; get inregs.x.di from stack ;AN000; + + push bp ; save base pointer ;AN000; + +;------------------------------------------------------------------- + call sysparse ; call the parser ;AN000; +;------------------------------------------------------------------- + + pop bp ; restore base pointer ;AN000; + push di ; the di value from call is now on stack;AN000; + mov di,[bp+6] ; fix di (arg 1) ;AN000; + + mov [di+00],ax ; load outregs.x.ax ;AN000; + mov [di+02],bx ; load outregs.x.bx ;AN000; + mov [di+04],cx ; load outregs.x.cx ;AN000; + mov [di+06],dx ; load outregs.x.dx ;AN000; + mov [di+08],si ; load outregs.x.si ;AN000; + + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; + + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; + +;------------------------------------------------------------------- + + pop si ; restore registers ;AN000; + pop di ;AN000; + mov sp,bp ; restore sp ;AN000; + pop bp ; restore user's bp ;AN000; + ret ;AN000; + +_parse endp ;AN000; + +_TEXT ends ; end code segment ;AN000; + end ;AN000; + + \ No newline at end of file -- cgit v1.2.3