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/JOIN/JOIN.C | 669 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 669 insertions(+) create mode 100644 v4.0/src/CMD/JOIN/JOIN.C (limited to 'v4.0/src/CMD/JOIN/JOIN.C') diff --git a/v4.0/src/CMD/JOIN/JOIN.C b/v4.0/src/CMD/JOIN/JOIN.C new file mode 100644 index 0000000..b0e13d8 --- /dev/null +++ b/v4.0/src/CMD/JOIN/JOIN.C @@ -0,0 +1,669 @@ +/*  */ +/**************************************************************************/ +/* */ +/* UTILITY NAME: Join */ +/* */ +/* SOURCE FILE NAME: Join.C */ +/* */ +/* STATUS: Join Utility, DOS Version 4.0 */ +/* */ +/* FUNCTIONAL DESCRIPTION: This utility allows the splicing of a */ +/* physical drive to a pathname on another physical drive such that */ +/* operations performed using the pathname as an argument take place */ +/* on the physical drive. */ +/* */ +/* SYNTAX: [d:][path]JOIN or */ +/* [d:][path]JOIN d: d:\directory or */ +/* [d:][path]JOIN d: /D */ +/* where: */ +/* [d:][path] to specify the drive and path that */ +/* contains the JOIN command file, if it is not */ +/* in the current directory of the default drive. */ +/* */ +/* d: to specify the drive to be connected to a */ +/* directory on another drive. */ +/* */ +/* d:\directory to specify the directory that */ +/* you will join a drive under. The directory */ +/* must be at the root and only one level deep. */ +/* */ +/* /D to disconnect a join. You must specify the */ +/* drive letter of the drive whose join 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 by GregT */ +/* */ +/* M000 May 23/85 Barrys */ +/* Disallow splicing similar drives. */ +/* */ +/* M001 May 24/85 Barrys */ +/* The original IBM version of JOIN allowed the delete splice switch */ +/* "/D" immediately after the drive specification. The argument parsing */ +/* code has been Revised to allow this combination. */ +/* */ +/* M002 June 5/85 Barrys */ +/* Changed low version check for specific 320. */ +/* */ +/* M003 July 15/85 Barrys */ +/* Checked for any possible switch characters in the other operands. */ +/* */ +/* M004 July 15/85 Barrys */ +/* Moved check for physical drive before check for NET and SHARED tests. */ +/* */ +/* 33D0016 July 16/86 RosemarieG */ +/* Put SHARED test on an equal basis with physical drive check. */ +/* Last fix (M004) erroneously allowed joining physical or local shared */ +/* drives. This is because it only performed the SHARED test if the */ +/* drive failed the physical test. */ +/* */ +/* May /87 SusanM */ +/* 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 S.M 5/87 */ +/* */ +/* AN000: New code for DOS Version 4.0 S.M 5/87 */ +/* AN000;M = message services */ +/* AN000;P = parser service */ +/* */ +/* Ax001: Changed code req'd - PTM0003919 S.M 3/88 */ +/* Incorrect message response */ +/* */ +/* Ax002: Changed code req'd - PTM0004046 S.M 3/88 */ +/* Incomplete message response */ +/* */ +/**************************************************************************/ + +#include "cds.h" +#include "ctype.h" +#include "dos.h" +#include "joinpars.h" /* ;AN000;P Parser structures */ +#include "jointype.h" +#include "stdio.h" +#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 FILESPEC_OPT 0x0201 /* ;AN000;P File spec & optional */ +#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 SWITCH_OPT 0x0000 /* ;AN000;P Optional switch */ + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ MESSAGE EQUATES ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +#define MSG_NOMEM 1 /* ;AN000;M Insufficient memory */ +#define MSG_PARMNUM 2 /* ;AN000;M Too many parameters */ +#define MSG_DIRNEMP 3 /* ;AN000;M Directory not empty */ +#define MSG_BADPARM 4 /* ;AN000;M Invalid parameter */ +#define MSG_NETERR 5 /* ;AN000;M Cannot %1 a network drive */ +#define MSG_INVSWTCH 6 /* ;AN000;M Invalid switch */ + +#define BLNK ' ' /* ;AN000;M For sublist.pad_char */ +#define CARRY 0x0001 /* ;AN000;M Check carry flag */ +#define D_SWITCH "/D" /* ;AN000;M Only 1 switch */ +#define EXT_ERR_CLASS 0x01 /* ;AN000;M DOS Extended error class */ +#define FALSE 0 +#define MAX 256 +#define MAXWIDTH 0 /* ;AN000;M 0 ensures no padding */ +#define MINWIDTH 1 /* ;AN000;M At least 1 char in parm */ +#define NO_HANDLE 0xffff /* ;AN000;M No handle specified */ +#define NO_INPUT 0x00 /* ;AN000;M No input characters */ +#define NO_REPLACE 0x00 /* ;AN000;M No replacable parameters */ +#define NULL 0 +#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_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 char *strchr() ; /* M003 */ +extern char *strbscan() ; /* SM extern'd */ + +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] = {0} ; /* ;AN000;P Recvs drive ltr from parser */ +char p_filespec[64] = {0} ; /* ;AN000;P Recvs filespec from parser */ +char replparm_JOIN[] = "JOIN" ; /* ;AN000;P Cannot JOIN a network drv */ + +unsigned char source[MAX] = {0} ; /* ;AN000;P buffer for string manipulation */ + +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 SYSPARSEC */ +/* Verify the correctness of the parameters */ +/* Check for splice deletion switch */ +/* Determine if directory not empty */ +/* Check source and destination drives not same */ +/* Determine if network or shared drive */ +/* Determine if currently spliced */ +/* Determine if existing dir or can't mkdir */ +/* Print messages by calling SYSDISPMSG */ +/* */ +/* EXTERNAL ROUTINES: SYSLOADMSG */ +/* SYSDISPMSG */ +/* SYSPARSE */ +/* */ +/* INTERNAL ROUTINES: DoList Parser_Prep */ +/* Load_Msg dispmsg_terminate */ +/* Display_Msg */ +/* */ +/**************************************************************************/ + +main(c, v) +int c ; +char *v[] ; +{ + struct findType findbuf ; + struct CDSType CDS ; + + char path [MAXPATHLEN],*p ; + char far * fptr ; /* ;AN000;P Pointer to parser's buffer */ + + int delflag = FALSE ; /* M001 delete splice flag */ + int dstdrv ; /* M000 dest. drive number */ + int fchar = 0 ; /* ;AN000;P Parser filespec chars */ + int i ; + int index ; /* ;AN000;P Used in creating cmdline string */ + int more_toparse = 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 & chks 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_toparse) /* ;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 Point to parser's buffer */ + { /* ;AN000;P */ + p_filespec[fchar] = (char)*fptr ; /* ;AN000;P Copy char */ + 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 dup switch */ + dispmsg_terminate(MSG_INVSWTCH,cmdln_switch) ; /* ;AN000;P display msg & end */ + } /* ;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) ; /* ;AN002; Too many parameters */ + break ; /* ;AN000;P more_toparse = FALSE */ + case P_Not_In_SW : dispmsg_terminate(MSG_INVSWTCH,cmdln_invalid) ;/* ;AN002; Invalid switch */ + break ; /* ;AN000;P more_toparse = 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_toparse = FALSE */ + default : dispmsg_terminate(MSG_BADPARM,cmdln_invalid) ; /* ;AN000;P */ + break ; /* ;AN000;P more_toparse = FALSE */ + } /* ;AN000;P */ + } /* ;AN000;P */ + else /* ;AN000;P */ + more_toparse = FALSE ; /* ;AN000;P End of the cmdline */ + 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) ; /* Access to DOS data structures */ + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + + if (c == 1) + DoList() ; /* list splices */ + else + { + i = p_drive[0] - 'A' ; /* ;AC000;P Convert to drv # */ + if (!fGetCDS(i, &CDS)) + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M display error msg & exit utility */ + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + if (delflag == TRUE) /* Deassigning perhaps? */ + { + if (!TESTFLAG(CDS.flags, CDSSPLICE)) + dispmsg_terminate(MSG_BADPARM,cmdln_switch) ; /* ;AC000;M If NOT spliced */ + + if (fPathErr(CDS.text)) + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M If prefix of curdir */ + + CDS.text[0] = i + 'A' ; + CDS.text[1] = ':' ; + CDS.text[2] = '\\' ; + CDS.text[3] = 0 ; + CDS.cbEnd = 2 ; + + if (i >= SysVars.cDrv) + CDS.flags = FALSE ; + else + CDS.flags = CDSINUSE ; + GetVars(&SysVars) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + SysVars.fSplice-- ; + PutVars(&SysVars) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + fPutCDS(i, &CDS) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + } + else + { + if (TESTFLAG(CDS.flags,CDSSPLICE)) + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000; If now spliced */ + + rootpath(p_filespec,path) ; /* Get root path */ + + if (i == getdrv() || /* M004 Start */ /* Can't mov curdrv */ + !fPhysical(i) || /* ;AC000; */ + fShared(i)) /* 33D0016 RG */ + { /* Determine if it was a NET error */ + if (fNet(i) || fShared(i)) + dispmsg_terminate(MSG_NETERR) ; /* ;AC000;M display error msg & exit utility */ + dispmsg_terminate(MSG_BADPARM,cmdln_drive) ; /* ;AC000;M display error msg & exit utility */ + } + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + if (fPathErr(path) || *strbscan(path+3, "/\\") != 0) /* or curdir prefix */ + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000; */ + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + if (fNet(path[0] - 'A') || fShared(path[0] - 'A')) + dispmsg_terminate(MSG_NETERR) ; /* ;AC000;M display error msg & exit utility */ + + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + dstdrv = *path - 'A' ; /* M000 Check src and dst drvs ar not same */ + if (i == dstdrv) /* M000 */ + dispmsg_terminate (MSG_BADPARM,cmdln_flspec) ; /* M000 */ /* ;AC000; */ + if (mkdir(path) == -1) /* If can't mkdir or if no dir or */ + { /* if note is file */ + if (ffirst(path, A_D, &findbuf) == -1 || + !TESTFLAG(findbuf.attr,A_D)) + dispmsg_terminate(MSG_BADPARM,cmdln_flspec) ; /* ;AC000;M display error msg & exit utility */ + + p = path + strlen(path) ; + strcat(p, "\\*.*") ; + + if (ffirst(path, 0, &findbuf) != -1) + dispmsg_terminate(MSG_DIRNEMP,cmdln_flspec) ; /* ;AC001;M If dir not empty */ + + *p = 0 ; + } + + strcpy(CDS.text, path) ; + CDS.flags = CDSINUSE | CDSSPLICE ; + fPutCDS(i, &CDS) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + GetVars(&SysVars) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + SysVars.fSplice++ ; + PutVars(&SysVars) ; + strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */ + } + } + exit(0) ; +} +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +DoList() /* Print list of cur joins */ +{ + int i ; + struct CDSType CDS ; + + for (i=0 ; fGetCDS(i, &CDS) ; i++) + { + if (TESTFLAG(CDS.flags,CDSSPLICE)) + printf("%c: => %s\n", i+'A', CDS.text) ; + } + return ; +} +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/**************************************************************************/ +/* */ +/* 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 and exit utility */ + } /* ;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 ; /* ;AN000;M 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 disp msg */ + 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_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_PARMNUM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */ + message = 1 ; /* ;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_DIRNEMP : 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_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_DIRNEMP : /* ;AN000;M Directory not empty */ + case MSG_PARMNUM : /* ;AN000;M Too many parameters */ + case MSG_BADPARM : sublist.value = (unsigned far *)outline ; /* ;AN000;M Invalid parameter */ + sublist.size = SUBLIST_LENGTH ; /* ;AN000;M */ + sublist.reserved = RESERVED ; /* ;AN000;M */ + sublist.id = 0 ; /* ;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 JOIN a network drive */ + inregs.x.bx = handle ; /* ;AN000;M STDERR */ + inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M Point to the substitution 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_JOIN ; /* ;AN000;M Cannot JOIN a network drive */ + sublist.size = SUBLIST_LENGTH ; /* ;AN000;M */ + 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 JOIN a network drive */ + inregs.x.bx = handle ; /* ;AN000;M STDERR */ + inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M Point to the substitution 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;P 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 */ -- cgit v1.2.3