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/ATTRIB/ATTRIB.C | 2685 +++++++++++++++++++++++++++++++++++++++ v4.0/src/CMD/ATTRIB/ATTRIB.H | 443 +++++++ v4.0/src/CMD/ATTRIB/ATTRIB.LNK | 7 + v4.0/src/CMD/ATTRIB/ATTRIB.SKL | 30 + v4.0/src/CMD/ATTRIB/ATTRIBA.ASM | 480 +++++++ v4.0/src/CMD/ATTRIB/MAKEFILE | 46 + v4.0/src/CMD/ATTRIB/MSGRET.H | 60 + v4.0/src/CMD/ATTRIB/PARSE.H | 185 +++ v4.0/src/CMD/ATTRIB/_MSGRET.ASM | 233 ++++ v4.0/src/CMD/ATTRIB/_PARSE.ASM | 107 ++ 10 files changed, 4276 insertions(+) create mode 100644 v4.0/src/CMD/ATTRIB/ATTRIB.C create mode 100644 v4.0/src/CMD/ATTRIB/ATTRIB.H create mode 100644 v4.0/src/CMD/ATTRIB/ATTRIB.LNK create mode 100644 v4.0/src/CMD/ATTRIB/ATTRIB.SKL create mode 100644 v4.0/src/CMD/ATTRIB/ATTRIBA.ASM create mode 100644 v4.0/src/CMD/ATTRIB/MAKEFILE create mode 100644 v4.0/src/CMD/ATTRIB/MSGRET.H create mode 100644 v4.0/src/CMD/ATTRIB/PARSE.H create mode 100644 v4.0/src/CMD/ATTRIB/_MSGRET.ASM create mode 100644 v4.0/src/CMD/ATTRIB/_PARSE.ASM (limited to 'v4.0/src/CMD/ATTRIB') diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.C b/v4.0/src/CMD/ATTRIB/ATTRIB.C new file mode 100644 index 0000000..b12a470 --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/ATTRIB.C @@ -0,0 +1,2685 @@ +/* 0 */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Utility Name: ATTRIB.EXE */ +/* */ +/* Source File Name: ATTRIB.C */ +/* */ +/* Utility Function: */ +/* */ +/* Allows you to set or reset the Archive bit, the Read-Only bit and */ +/* the Extended Attributes. Also allows you to display the current */ +/* setting of those attributes. */ +/* */ +/* Status: ATTRIB Utility, DOS Version 4.0 */ +/* */ +/* Entry Point: inmain(line) */ +/* */ +/* Input: line = DOS command line parameters */ +/* */ +/* Exit-normal: attribute set, or attribute printed to output device */ +/* */ +/* Exit-error: error message written to standard error device */ +/* */ +/* Internal References: */ +/* */ +/* Routines: */ +/* */ +/* External References: */ +/* */ +/* Routines: */ +/* parse() module=_parse.sal */ +/* sysloadmsg() module=_msgret.sal */ +/* sysdispmsg() module=_msgret.sal */ +/* getpspbyte() module=new_c.sal */ +/* putpspbyte() module=new_c.sal */ +/* segread() module=dos.h(C library) */ +/* intdosx() module=dos.h(C library) */ +/* intdos() module=dos.h(C library) */ +/* */ +/* Notes: */ +/* Syntax (Command Line) */ +/* */ +/* ATTRIB [+R|-R] [+A|-A] [d:][path]filename[.ext] [[id]|[id=value]] [/S] */ +/* */ +/* where: */ +/* */ +/* +R = Make file ReadOnly by setting READONLY bit */ +/* -R = Reset READONLY bit */ +/* +A = Set ARCHIVE bit */ +/* -A = Reset ARCHIVE bit */ +/* */ +/* id = Set or display the extended attribute named by id. */ +/* Only one id processed per invocation. id can be *. */ +/* */ +/* /S = Process subdirectories also */ +/* */ +/* Copyright 1988 Microsoft Corporation */ +/* */ +/* Revision History: */ +/* */ +/* Modified 6/22/87 v. 4.0 */ +/* Rewritten 9/28/87 v. 4.0 - AN000 */ +/* - fixed check for "." & ".." - AN001 */ +/* PTM 3195 - changed Extended attribute MSGs - AN002 */ +/* PTM 3588 - Do C exit not DOS exit. - AN003 */ +/* PTM 3783 - Fix for hang problem. - AN004 */ +/* */ +/* NOTE: */ +/* When extended attributes are added back in, make sure you change the */ +/* attrib.skl file back to the original DOS 4.0 ext. attr. error msgs. */ +/* */ +/* Also, this C program requires a special lib when linking to take care */ +/* of the fact that the c lib saves the DOS environment on the heap and */ +/* if the environment is > 32k, STACK OVERFLOW will occur. */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +#include /*;AN000;*/ +#include /*;AN000;*/ +#include /*;AN000;*/ +#include /*;AN000;*/ +#include "parse.h" /*;AN000;*/ +#include "msgret.h" /*;AN000;*/ +#include "attrib.h" /*;AN000;*/ + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* Beginning of code (variables declared in attrib.h) */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +/* + * inmain() - This routine receives control from an assembler routine and from + * here, main is called. This routine first parses the command line + * and then does the appropriate action. + */ +inmain(line) /*;AN000;*/ + char *line; /*;AN000;*/ +{ /*;AN000;*/ + main(line); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: main() */ +/* */ +/* Subroutine Function: */ +/* Parse the command line, makes a full path-filename, does the */ +/* appropriate function */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +main(line) /*;AN000;*/ + char *line; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + + WORD Parse_it(); /* forward declaration */ /*;AN000;*/ + WORD Make_fspec(); /* " " */ /*;AN000;*/ + WORD Do_dir(); /* " " */ /*;AN000;*/ + void Error_exit(); /* " " */ /*;AN000;*/ + void Parse_err(); /* " " */ /*;AN000;*/ + + /* initialize control variables */ + status = NOERROR; /*;AN000;*/ + descending = FALSE; /*;AN000;*/ + set_reg_attr = FALSE; /*;AN000;*/ + pmask = mmask = 0x0; /*;AN000;*/ + ext_attr[0] = BLANK; /*;AN000;*/ + file[0] = '\0'; /*;AN000;*/ + error_file_name[0] = '\0'; /*;AN000;*/ + + /* load messages */ + sysloadmsg(&inregs,&outregs); /*;AN000;*/ + if (outregs.x.cflag & CARRY) { /*;AN000;*/ + sysdispmsg(&outregs,&outregs); /*;AN000;*/ + Dexit(11); /*;AN000;*/ + } + + Check_appendx(); /* check APPEND /X status */ /*;AN000;*/ + Get_DBCS_vector(); /* get double byte table */ /*;AN000;*/ + + /* parse command line */ + status = Parse_it(line); /*;AN000;*/ + if (status != NOERROR) { /*;AN000;*/ + Parse_err(status); /*;AN000;*/ + } /*;AN000;*/ + + /* Do extended attribute translations here */ + Ext_translation(); /*;AN000;*/ + + + /* Initialize any variables need for next phase of program */ + segread(&segregs); /* init segment registers for DOS calls */ /*;AN000;*/ + + /* make full filespec (drive + full path + filename) */ + strcpy(error_file_name,fspec); /*;AN000;*/ + status = Make_fspec(fspec); /*;AN000;*/ + if (status == NOERROR) { /*;AN000;*/ + + /* now do the work! */ + did_attrib_ok = FALSE; /* needed if file not found and no */ /*;AN000;*/ + /* error detected in Attrib(). */ + status = Do_dir(fspec,file); /*;AN000;*/ + if (status == NOERROR && did_attrib_ok == FALSE) /*;AN000;*/ + status = FILENOTFOUND; /*;AN000;*/ + } /*;AN000;*/ + + /* determine if there was an error after attempt to do attrib function */ + /* NOTE: for ext. attr. calls, add 200 to the return code to get the */ + /* ---- error code for this switch. */ + switch(status) { /* Extended error codes */ /*;AN000;*/ + case 0: /*;AN000;*/ + break; /*;AN000;*/ + case 2: /* File not found */ /*;AN000;*/ + Error_exit(ERR_EXTENDED,2,ONEPARM); /*;AN000;*/ + break; /*;AN000;*/ + case 3: /* Path not found */ /*;AN000;*/ + Error_exit(ERR_EXTENDED,3,ONEPARM); /*;AN000;*/ + break; /*;AN000;*/ + case 5: /* Access Denied */ /*;AN000;*/ + Error_exit(ERR_EXTENDED,5,ONEPARM); /*;AN000;*/ + break; /*;AN000;*/ + case 15: /* Invalid drive specification */ /*;AN000;*/ + Error_exit(ERR_EXTENDED,15,ONEPARM); /*;AN000;*/ + break; /*;AN000;*/ + case 199: /* EA error: undetermined cause */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(199,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case 201: /* EA error: name not found */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(201,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case 202: /* EA error: no space to hold name or value */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(202,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case 203: /* EA error: name can't be set on this function */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(204,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case 204: /* EA error: name can't be set */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(204,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case 205: /* EA error: name known to this FS but not supported */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(205,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case 206: /* EA error: EA definition bad (type, length, etc.) */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(206,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case 208: /* EA error: EA value not supported */ /*;AN000;*/ + strcpy(error_file_name,ext_attr); /*;AN000;*/ + Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/ + /* Display_msg(208,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + default: /* Access Denied */ /*;AN000;*/ + Error_exit(ERR_EXTENDED,5,ONEPARM); /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ + Reset_appendx(); /*;AN000;*/ + + + +} /* end of inmain */ /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Display_msg */ +/* */ +/* Subroutine Function: */ +/* Display the requested message to a given output device */ +/* */ +/* Input: */ +/* (1) Number of the message to be displayed (see ATTRIB.SKL) */ +/* (2) Output device handle */ +/* (3) Number of substitution parameters (%1,%2) */ +/* (4) Offset of sublist control block */ +/* (5) Message Class, 0=no input, 1=input via INT 21 AH=1 */ +/* */ +/* Output: */ +/* The message is written to the given output device. If input */ +/* was requested, the character code of the key pressed is returned */ +/* in outregs.x.ax. */ +/* */ +/* Normal exit: Message written to handle */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* Sysdispmsg (module _msgret.sal) */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Display_msg(msgnum,msghan,msgparms,msgsub,msginput) /*;AN000;*/ + int msgnum; /*;AN000;*/ + int msghan; /*;AN000;*/ + int msgparms; /*;AN000;*/ + int *msgsub; /*;AN000;*/ + char msginput; /*;AN000;*/ +{ + inregs.x.ax = msgnum; /*;AN000;*/ + inregs.x.bx = msghan; /*;AN000;*/ + inregs.x.cx = msgparms; /*;AN000;*/ + inregs.h.dh = utility_msg_class; /*;AN000;*/ + inregs.h.dl = msginput; /*;AN000;*/ + inregs.x.si = (WORD)msgsub; /*;AN000;*/ + sysdispmsg(&inregs,&outregs); /*;AN000;*/ + + /* check for error printing message */ + if (outregs.x.cflag & CARRY) { /*;AN000;*/ + outregs.x.bx = (WORD) STDERR; /*;AN000;*/ + outregs.x.si = NOSUBPTR; /*;AN000;*/ + outregs.x.cx = NOSUBCNT; /*;AN000;*/ + outregs.h.dl = exterr_msg_class; /*;AN000;*/ + sysdispmsg(&outregs,&outregs); /*;AN000;*/ + } /*;AN000;*/ +} + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Ext_translation() */ +/* */ +/* Subroutine Function: */ +/* This routine does all translation of extended attribute names to */ +/* the form that will be returned by Get_ext_attr_names(). For */ +/* example, "CODEPAGE" would be translated to "CP". */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Ext_translation() /*;AN000;*/ +{ /*;AN000;*/ + if (strcmp(ext_attr,"CODEPAGE") == 0) { /*;AN000;*/ + strcpy(ext_attr,"CP"); /*;AN000;*/ + } /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Get_far_str() */ +/* */ +/* Subroutine Function: */ +/* copies a filename from source to the target. The source is offset */ +/* from the code segment instead of the data segment. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Get_far_str(target,source,length) /*;AN000;*/ + char *target; /*;AN000;*/ + DWORD *source; /* segment = cs register */ /*;AN000;*/ + WORD length; /*;AN000;*/ +{ /*;AN000;*/ + char far *fptr; /*;AN000;*/ + WORD i; /*;AN000;*/ + + if (length == 0) { /*;AN000;*/ + + /* copy string in data segment */ + for (fptr = (char far *) *((DWORD *)source);(char)*fptr != NUL;) /*;AN000;*/ + *target++ = (char) *fptr++; /*;AN000;*/ + *target = *fptr; /*EOS character */ /*;AN000;*/ + } /*;AN000;*/ + else { + + /* copy string in data segment */ + for (fptr = (char far *) *((DWORD *)source),i=0;i < length;i++) /*;AN000;*/ + *target++ = (char) *fptr++; /*;AN000;*/ + *target = 0x0; /*EOS character */ /*;AN000;*/ + } + strcpy(fix_es_reg,NUL); /* fix for es reg. after using far ptr */ /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Dexit() */ +/* */ +/* Subroutine Function: */ +/* Does a DOS terminate. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Dexit(s) /*;AN000;*/ + WORD s; /*;AN000;*/ +{ /*;AN000;*/ + Reset_appendx(); /* Reset APPEND /X status */ /*;AN000;*/ + +/* inregs.h.ah = (BYTE)0x4c; /*;AN003; ;AN000;*/ +/* inregs.h.al = (BYTE)s; /*;AN003; ;AN000;*/ +/* intdos(&inregs,&outregs); /*terminate*/ /*;AN003; ;AN000;*/ + + /* if it didn't work - kill it */ + exit(); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Dallocate() */ +/* */ +/* Subroutine Function: */ +/* Does a DOS allocate of length (in paragraphs). */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD *Dallocate(s) /*;AN000;*/ + WORD s; /* length in bytes */ /*;AN000;*/ +{ /*;AN000;*/ + WORD length; /*length in paragraphs */ /*;AN000;*/ + + length = (s / 16 + 1); /*;AN000;*/ + inregs.x.bx = length; /*;AN000;*/ + inregs.x.ax = 0x4800; /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + if (outregs.x.cflag & CARRY) { /*;AN000;*/ + Error_exit(ERR_EXTENDED,8,NOSUBCNT); /*;AN000;*/ + } /*;AN000;*/ + return((WORD *)outregs.x.ax); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Dfree() */ +/* */ +/* Subroutine Function: */ +/* Does a DOS de-allocate. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Dfree(segment) /*;AN000;*/ + WORD segment; /*;AN000;*/ +{ /*;AN000;*/ + segregs.es = segment; /*;AN000;*/ + inregs.x.ax = 0x4900; /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + if (outregs.x.cflag & CARRY) { /*;AN000;*/ + Error_exit(ERR_EXTENDED,8,NOSUBCNT); /*;AN000;*/ + } /*;AN000;*/ + strcpy(fix_es_reg,NUL); /* fix for es reg. after using far ptr */ /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Copy_far_ptr() */ +/* */ +/* Subroutine Function: */ +/* Copies a far ptr declared in any form to a real far ptr variable. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: status = NOERROR */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Copy_far_ptr(p1_addr, p2_addr) /*;AN000;*/ + DWORD *p1_addr; /*;AN000;*/ + WORD *p2_addr; /*;AN000;*/ +{ /*;AN000;*/ + WORD *dptr, *tptr; /*;AN000;*/ + + dptr = (WORD *)p2_addr; /*;AN000;*/ + tptr = (WORD *)p1_addr; /*;AN000;*/ + + *tptr++ = *dptr++; /*;AN000;*/ + *tptr = *dptr; /*;AN000;*/ + strcpy(fix_es_reg,NUL); /* fix ES register */ /*;AN000;*/ +} /*;AN000;*/ + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Parse_it() */ +/* */ +/* Subroutine Function: */ +/* Parses the command line and returns error status. */ +/* */ +/* Input: line */ +/* */ +/* Output: various control variables are set */ +/* */ +/* Normal exit: status = NOERROR */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Parse_it(line) /*;AN000;*/ + char *line; /*;AN000;*/ +{ /*;AN000;*/ + WORD i; /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD no_value; /*;AN000;*/ + WORD got_fn; /* got filename - required parameter */ /*;AN000;*/ + WORD pa, /*;AN000;*/ + ma, /*;AN000;*/ + pr, /*;AN000;*/ + mr; /*;AN000;*/ + char far *cptr; /*;AN000;*/ + char *ptr; /*;AN000;*/ + BYTE p_mask[4], /*;AN000;*/ + m_mask[4]; /*;AN000;*/ + char string[129]; /*;AN000;*/ + + /* do setup for parser */ + for (i=0; i<4; i++) { /*;AN000;*/ + p_mask[i] = m_mask[i] = 0; /*;AN000;*/ + } /*;AN000;*/ + do_reg_attr = TRUE; /*;AN000;*/ + do_ext_attr = FALSE; /*;AN000;*/ + set_reg_attr = FALSE; /*;AN000;*/ + set_ext_attr = FALSE; /*;AN000;*/ + no_value = TRUE; /* no value found for keyword */ /*;AN000;*/ + got_fn = FALSE; /* no filename yet */ /*;AN000;*/ + + inregs.x.si = (WORD)line; /* Make DS:SI point to source */ /*;AN000;*/ + inregs.x.cx = 0; /* Operand ordinal */ /*;AN000;*/ + inregs.x.di = (WORD)&p_p1; /* Address of parm list */ /*;AN000;*/ + status = p_no_error; /* Init no error condition */ /*;AN000;*/ + + /* loop until error or end_of_line */ + while (status == p_no_error) { /*;AN000;*/ + parse(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /* get error status */ /*;AN000;*/ + + /* check for errors, continue if none */ + if (status == p_no_error) { /*;AN000;*/ + + /* check if first positional */ + if (outregs.x.dx == (WORD)&pos1_buff) { /*;AN000;*/ + if (*(char *)pos1_buff.p_result_buff[0] == '+') { /*;AN000;*/ + p_mask[0] |= pos1_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + m_mask[0] |= pos1_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + set_reg_attr = TRUE; /*;AN000;*/ + do_reg_attr = FALSE; /*;AN000;*/ + } /*;AN000;*/ + + /* check if second positional */ + if (outregs.x.dx == (WORD)&pos2_buff) { /*;AN000;*/ + if (*(char *)pos2_buff.p_result_buff[0] == '+') { /*;AN000;*/ + p_mask[1] |= pos2_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + m_mask[1] |= pos2_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + set_reg_attr = TRUE; /*;AN000;*/ + do_reg_attr = FALSE; /*;AN000;*/ + } /*;AN000;*/ + + /* check if third positional */ + if (outregs.x.dx == (WORD)&pos3_buff) { /*;AN000;*/ + + /* copy filename from far string to data segment string */ + Get_far_str(fspec,pos3_buff.p_result_buff,0); /*;AN000;*/ + got_fn = TRUE; /*;AN000;*/ + } /*;AN000;*/ + + /* check if fourth positional */ + if (outregs.x.dx == (WORD)&pos4_buff) { /*;AN000;*/ + if (*(char *)pos4_buff.p_result_buff[0] == '+') { /*;AN000;*/ + p_mask[2] |= pos4_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + m_mask[2] |= pos4_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + set_reg_attr = TRUE; /*;AN000;*/ + do_reg_attr = FALSE; /*;AN000;*/ + } /*;AN000;*/ + + /* check if fifth positional */ + if (outregs.x.dx == (WORD)&pos5_buff) { /*;AN000;*/ + if (*(char *)pos5_buff.p_result_buff[0] == '+') { /*;AN000;*/ + p_mask[3] |= pos5_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + m_mask[3] |= pos5_buff.p_item_tag; /*;AN000;*/ + } /*;AN000;*/ + set_reg_attr = TRUE; /*;AN000;*/ + do_reg_attr = FALSE; /*;AN000;*/ + } /*;AN000;*/ + + /* check if sixth positional */ + if (outregs.x.dx == (WORD)&pos6_buff) { /*;AN000;*/ + + /* copy attribute name from far string to data segment string */ + Get_far_str(ext_attr,pos6_buff.p_result_buff,0); /*;AN000;*/ + do_ext_attr = TRUE; /*;AN000;*/ + do_reg_attr = FALSE; /*;AN000;*/ + } /*;AN000;*/ + + /* check if value of sixth positional */ + if (outregs.x.dx == (WORD)&pos6b_buff) { /*;AN000;*/ + + /* parse a value that is complex (in parenthesis). */ + if (pos6b_buff.p_type == p_complex) { /*;AN000;*/ + + /* Parse the complex and concatenate it together */ + inregs.x.cx = 0; /* reset ordinal count */ /*;AN000;*/ + status = p_no_error; /*;AN000;*/ + while (status != p_rc_eol) { /*;AN000;*/ + parse(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /* get error status */ /*;AN000;*/ + if (status != p_no_error) { /*;AN000;*/ + status = p_syntax; /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ + Get_far_str(string,pos6b_buff.p_result_buff,0); /*;AN000;*/ + strcat(ext_attr_value.ea_ascii,string); /*;AN000;*/ + inregs.x.si = outregs.x.si; /* update SI for parser */ /*;AN000;*/ + } /*;AN000;*/ + status = p_no_error; /*;AN000;*/ + ext_attr_value_type = EAISASCII; /*;AN000;*/ + } /*;AN000;*/ + else /*;AN000;*/ + Determine_type((WORD)pos6b_buff.p_type,pos6b_buff.p_result_buff); /*;AN000;*/ + set_ext_attr = TRUE; /*;AN000;*/ + do_reg_attr = FALSE; /*;AN000;*/ + do_ext_attr = FALSE; /*;AN000;*/ + no_value = TRUE; /* found a value for keyword */ /*;AN000;*/ + } /*;AN000;*/ + + /* check for '/S' switch */ + if (outregs.x.dx == (WORD)&sw_buff) { /*;AN000;*/ + + /* check if duplicate switch */ + if (descending == TRUE) { /*;AN000;*/ + status = p_syntax; /*;AN000;*/ + } /*;AN000;*/ + descending = TRUE; /*;AN000;*/ + } /*;AN000;*/ + } /* if no error */ /*;AN000;*/ + + /* error, check if this is first positional, if so try again */ + /* using the second positional beacause they are optional */ + else if (inregs.x.cx == 0 || inregs.x.cx == 1 || /*;AN000;*/ + inregs.x.cx == 3 || inregs.x.cx == 4) { /*;AN000;*/ + inregs.x.cx++; /* try next positional */ /*;AN000;*/ + + /* Check for a filename beginning with '+' because parser will drop */ + /* the plus sign anyways, and we need to flag it as an error */ + for(ptr=(char *)inregs.x.si; *ptr == ' '; ptr++) /*;AN000;*/ + /* NULL statement */ ; /*;AN000;*/ + if (*ptr == '+') /*;AN000;*/ + status = p_syntax; /*;AN000;*/ + else /*;AN000;*/ + status = p_no_error; /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ + + continue; /* go back up to while loop */ /*;AN000;*/ + } /*;AN000;*/ + + /* Check for keyword (an attribute name - fourth positional) */ + else if (status == p_not_in_key) { /*;AN000;*/ + inregs.x.di = (WORD)&p_p2; /* change control blocks to */ /*;AN000;*/ + /* be able to parse the keyword */ + inregs.x.cx = 0; /* reset ordinal count */ /*;AN000;*/ + status = p_no_error; /*;AN000;*/ + no_value = FALSE; /* got keyword and equal sign */ /*;AN000;*/ + continue; /*;AN000;*/ + } /*;AN000;*/ + + if (status == p_no_error) { /*;AN000;*/ + inregs.x.cx = outregs.x.cx; /* update CX for parser */ /*;AN000;*/ + inregs.x.si = outregs.x.si; /* update SI for parser */ /*;AN000;*/ + } /*;AN000;*/ + } /* while loop */ /*;AN000;*/ + + /* check error status and if at end of line */ + if (status == p_rc_eol) { /*;AN000;*/ + status = p_no_error; /*;AN000;*/ + } /*;AN000;*/ + + /* Check for filename on command line */ + if (!got_fn && status == p_no_error) { /*;AN000;*/ + status = p_op_missing; /*;AN000;*/ + } /*;AN000;*/ + + /* Check for keyword and equal sign but no value */ + if (!no_value) { /*;AN000;*/ + status = p_syntax; /*;AN000;*/ + } /*;AN000;*/ + + /* check for duplicate +R +R or +A +A or -A -A or -R -R */ + for (pr=0,mr=0,pa=0,ma=0,i=0; i<4; i++) { /*;AN000;*/ + if (p_mask[i] & READONLY) /*;AN000;*/ + pr++; /*;AN000;*/ + if (m_mask[i] & READONLY) /*;AN000;*/ + mr++; /*;AN000;*/ + if (p_mask[i] & ARCHIVE) /*;AN000;*/ + pa++; /*;AN000;*/ + if (m_mask[i] & ARCHIVE) /*;AN000;*/ + ma++; /*;AN000;*/ + } /*;AN000;*/ + if ((pr > 1) || (mr > 1) || (pa > 1) || (ma > 1)) { /*;AN000;*/ + status = p_syntax; /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + for (pmask=0,mmask=0,i=0; i<4; i++) { /*;AN000;*/ + pmask |= p_mask[i]; /* combine masks */ /*;AN000;*/ + mmask |= m_mask[i]; /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + + /* check for duplicate -R +R or -A +A */ + if ((pmask & mmask & READONLY) || (pmask & mmask & ARCHIVE)) { /*;AN000;*/ + status = p_syntax; /*;AN000;*/ + } /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Determine_type() */ +/* */ +/* Subroutine Function: */ +/* Determines the type of the new value of an attribute being set by */ +/* the user in terms of extended attribute types. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Determine_type(parser_type,result_ptr) /*;AN000;*/ + WORD parser_type; /*;AN000;*/ + WORD *result_ptr; /*;AN000;*/ +{ /*;AN000;*/ + DWORD number; /*;AN000;*/ + char string[129]; /*;AN000;*/ + + switch(parser_type) { /*;AN000;*/ + case p_number: /*;AN000;*/ + ext_attr_value_type = EAISBINARY; /*;AN000;*/ + number = (DWORD)*(DWORD *)result_ptr; /*;AN000;*/ + if (number > 0xffff) { /*;AN000;*/ + ext_attr_value.ea_bin.length = 4; /*;AN000;*/ + ext_attr_value.ea_bin.dword = number; /*;AN000;*/ + } /*;AN000;*/ + else if (number > 0xff) { /*;AN000;*/ + ext_attr_value.ea_bin.length = 2; /*;AN000;*/ + ext_attr_value.ea_bin.dword = number; /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + ext_attr_value.ea_bin.length = 1; /*;AN000;*/ + ext_attr_value.ea_bin.dword = number; /*;AN000;*/ + } /*;AN000;*/ + break; /*;AN000;*/ + + case p_complex: /*;AN000;*/ + + /* Taken care of in Parse_it() */ + break; /*;AN000;*/ + + case p_string: /*;AN000;*/ + case p_quoted_string: /*;AN000;*/ + Get_far_str(string,result_ptr,0); /*;AN000;*/ + + /* is the type EAISLOGICAL or EAISASCII */ + if (strcmp(string,"ON") == 0) { /*;AN000;*/ + ext_attr_value.ea_logical = TRUE; /*;AN000;*/ + ext_attr_value_type = EAISLOGICAL; /*;AN000;*/ + } /*;AN000;*/ + else if (strcmp(string,"OFF") == 0) { /*;AN000;*/ + ext_attr_value.ea_logical = FALSE; /*;AN000;*/ + ext_attr_value_type = EAISLOGICAL; /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + strcpy(ext_attr_value.ea_ascii,string); /*;AN000;*/ + ext_attr_value_type = EAISASCII; /*;AN000;*/ + } /*;AN000;*/ + break; /*;AN000;*/ + + default: /*;AN000;*/ + ext_attr_value_type = EAISUNDEF; /*;AN000;*/ + ext_attr_value.ea_undef = TRUE; /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Make_fspec() */ +/* */ +/* Subroutine Function: */ +/* Makes a full path-filename from the filename & current directory */ +/* information. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Make_fspec(fspec) /*;AN000;*/ + char *fspec; /*;AN000;*/ +{ /*;AN000;*/ + WORD Check_DBCS(); /* forward declaration */ /*;AN000;*/ + + char path[256]; /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD i,j; /*;AN000;*/ + + status = NOERROR; /*;AN000;*/ + + strcpy(path,fspec); /*;AN000;*/ + + /* Check if user did not enter a drive letter */ + if (fspec[1] != ':') { /*;AN000;*/ + inregs.x.ax = 0x1900; /* Get current drive */ /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + fspec[0] = 'A' + (outregs.x.ax & 0xff); /*;AN000;*/ + fspec[1] = ':'; /*;AN000;*/ + fspec[2] = NUL; /*;AN000;*/ + strcat(fspec,path); /*;AN000;*/ + } /*;AN000;*/ + + /* Check if user didn't enter a path in filename */ + if (!Check_DBCS(fspec,2,'\\')) { /*;AN000;*/ + strcpy(path,&fspec[2]); /*;AN000;*/ + fspec[2] = '\\'; /*;AN000;*/ + inregs.x.ax = 0x4700; /* Get current directory */ /*;AN000;*/ + inregs.x.si = (WORD)(&fspec[3]); /*;AN000;*/ + inregs.h.dl = fspec[0] - 'A' +1; /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + + if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/ + status = NOERROR; /*;AN000;*/ + if (!Check_DBCS(fspec,strlen(fspec)-1,'\\')) /*;AN000;*/ + strcat(fspec,"\\"); /*;AN000;*/ + strcat(fspec,path); /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + + /* seperate the file specification into path and filename */ + for (i=strlen(fspec);(i>=0) && (!Check_DBCS(fspec,i,'\\')); i--) /*;AN000;*/ + /* null statement */ ; /*;AN000;*/ + i++; /*;AN000;*/ + j = 0; /*;AN000;*/ + while (fspec[i+j] != '\0') { /*;AN000;*/ + file[j] = fspec[i+j]; /*;AN000;*/ + fspec[i+j] = '\0'; /*;AN000;*/ + j++; /*;AN000;*/ + } /*;AN000;*/ + file[j] = '\0'; /*;AN000;*/ + + /* Check for filenames of: . (current dir) .. (parent dir) */ + if (strcmp(file,".") == 0) /*;AN001;*/ + strcpy(file,"*.*"); /*;AN001;*/ + else if (strcmp(file,"..") == 0) { /*;AN001;*/ + strcat(fspec,"..\\"); /*;AN001;*/ + strcpy(file,"*.*"); /*;AN001;*/ + } + + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Dta_save() */ +/* */ +/* Subroutine Function: */ +/* saves an area in the PSP, but who knows. */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Dta_save(t,l) + char *t; + unsigned l; +{ + unsigned i; + + for (i = 0; i < l; i++) *(t+i) = getpspbyte(0x80+i) + /* null statement */ ; + } + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Dta_restore() */ +/* */ +/* Subroutine Function: */ +/* Restores the data that was saved in Dta_save(). */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Dta_restore(t,l) + char *t; + unsigned l; +{ + unsigned i; + + for (i = 0; i < l; i++) putpspbyte(0x80+i,*(t+i)) + /* null statement */ ; +} + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Find_first() */ +/* */ +/* Subroutine Function: */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Find_first(s,f,a) + char *s; + char *f; + WORD *a; +{ + WORD status; + WORD i; + WORD o; + char *t; + + t = f; + *f = '\0'; + + inregs.x.ax = 0x4e00; /* DOS find first */ + inregs.x.cx = (*a & 0x00ff ); + inregs.x.dx = (WORD)s; + intdos(&inregs,&outregs); + status = outregs.x.ax; + + /* Check for no errors */ + if (!(outregs.x.cflag & CARRY)) { + for (i = 0; i < 14; i++) + *f++ = getpspbyte(0x80+30+i); + *a = getpspbyte(0x80+21); + status = NOERROR; + } + return(status); +} + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Find_next() */ +/* */ +/* Subroutine Function: */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Find_next(f,a) + char *f; + WORD *a; +{ + WORD status; + WORD i; + WORD o; + char *t; + + t = f; + *f = '\0'; + + inregs.x.ax = 0x4f00; /* DOS find next */ + intdos(&inregs,&outregs); + status = outregs.x.ax; + + if (!(outregs.x.cflag & CARRY)) { + for (i = 0; i < 14; i++) + *f++ = getpspbyte(0x80+30+i); + *a = getpspbyte(0x80+21); + status = NOERROR; + } + return(status); +} + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Get_reg_attrib() */ +/* */ +/* Subroutine Function: */ +/* Does a DOS get attribute byte. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: return = 0 */ +/* */ +/* Error exit: return = error code */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Get_reg_attrib(fspec,attr_byte) /*;AN000;*/ + char *fspec; /*;AN000;*/ + BYTE *attr_byte; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + + inregs.x.ax = (WORD)0x4300; /*;AN000;*/ + inregs.x.dx = (WORD)fspec; /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + + /* Check for error */ /*;AN000;*/ + if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/ + *attr_byte = (BYTE)outregs.h.cl; /*;AN000;*/ + status = NOERROR; /*;AN000;*/ + } /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Ext_open() */ +/* */ +/* Subroutine Function: */ +/* Does a DOS extended open of a filename and returns a file handle.*/ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: handle = file handle, return = 0 */ +/* */ +/* Error exit: handle = ?; return = error code */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Ext_open(fspec,handle) /*;AN000;*/ + char *fspec; /*;AN000;*/ + WORD *handle; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + + inregs.x.ax = (WORD)0x6c00; /*;AN000;*/ + inregs.x.bx = (WORD)0x80; /*;AN000;*/ + inregs.x.cx = (WORD)0x0; /*;AN000;*/ + inregs.x.dx = (WORD)0x0101; /*;AN000;*/ + inregs.x.si = (WORD)fspec; /*;AN000;*/ + inregs.x.di = (WORD)&plist; /*;AN000;*//*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + + /* Check for error */ /*;AN000;*/ + if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/ + *handle = outregs.x.ax; /*;AN000;*/ + status = NOERROR; /*;AN000;*/ + } /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Get_ext_attrib() */ +/* */ +/* Subroutine Function: */ +/* Does a DOS Get extended attributes and returns far ptr to list. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: handle = file handle, return = 0 */ +/* */ +/* Error exit: handle = ?; return = error code */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Get_ext_attrib(handle,list_ptr,qlist_ptr) /*;AN000;*/ + WORD handle; /*;AN000;*/ + WORD far **list_ptr; /* ptr to far ptr to list returned */ /*;AN000;*/ + WORD *qlist_ptr; /* query list */ /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD attr_size; /*;AN000;*/ + WORD *list_seg; /*;AN000;*/ + WORD *ptr; /*;AN000;*/ + + /* get size of attribute list */ /*;AN000;*/ + inregs.x.bx = handle; /*;AN000;*/ + inregs.x.ax = 0x5702; /* Get extended attributes*/ /*;AN000;*/ + inregs.x.si = (WORD)qlist_ptr; /* query one attribute */ /*;AN000;*/ + inregs.x.cx = (WORD)0; /* just get size of return buffer */ /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + + /* if no errors then get extended attributes */ + if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/ + attr_size = outregs.x.cx; /*;AN000;*/ + + /* allocate buffer space for extended attr. list */ + /* uses MAX_ATTR_SIZE if possible so that buffer can be used */ + /* to set the largest attribute possible */ + if (attr_size > MAX_ATTR_SIZE) /*;AN000;*/ + list_seg = Dallocate(attr_size); /*;AN000;*/ + else /*;AN000;*/ + list_seg = Dallocate(MAX_ATTR_SIZE); /*;AN000;*/ + + /* get extended attributes */ + inregs.x.bx = handle; /*;AN000;*/ + inregs.x.ax = 0x5702; /* Get extended attributes */ /*;AN000;*/ + inregs.x.si = (WORD)qlist_ptr; /* query one attribute */ /*;AN000;*/ + inregs.x.di = (WORD)0x0; /* return buffer offset */ /*;AN000;*/ + inregs.x.cx = attr_size; /* size to get all attributes */ /*;AN000;*/ + segregs.es = (WORD)list_seg; /* segment of ea list to return */ /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + strcpy(fix_es_reg,NUL); /* restores original ES reg. value */ /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + + /* if no errors then fix up far pointer to list */ + if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/ + + /* convert segment returned from Dallocate to far ptr */ + *list_ptr = 0; /*;AN000;*/ + ptr = (WORD *)list_ptr; /*;AN000;*/ + ptr++; /*;AN000;*/ + *ptr = (WORD)list_seg; /*;AN000;*/ + (*list_ptr)++; /*;AN000;*/ + strcpy(fix_es_reg,NUL); /* restores ES register value */ /*;AN000;*/ + status = NOERROR; /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Get_ext_attr_names() */ +/* */ +/* Subroutine Function: */ +/* Does a DOS Get extended attribute names and return a far ptr to */ +/* the querylist of names. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: handle = file handle, return = 0 */ +/* */ +/* Error exit: handle = ?; return = error code */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Get_ext_attr_names(handle,list_ptr,num_entries) /*;AN000;*/ + WORD handle; /*;AN000;*/ + WORD far **list_ptr; /* ptr to far ptr to list returned */ /*;AN000;*/ + WORD *num_entries; /* number of entries in list */ /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD attr_size; /*;AN000;*/ + WORD *list_seg; /*;AN000;*/ + WORD *ptr; /*;AN000;*/ + + /* get size of attribute name list */ /*;AN000;*/ + inregs.x.bx = handle; /*;AN000;*/ + inregs.x.ax = 0x5703; /* Get extended attribute names */ /*;AN000;*/ + inregs.x.cx = (WORD)0; /* just get size of return buffer */ /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + + /* if no errors then get extended attribute names */ + if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/ + attr_size = outregs.x.cx; /*;AN000;*/ + + /* allocate buffer space for extended attr. list */ + list_seg = Dallocate(attr_size); /*;AN000;*/ + + /* get extended attributes */ + inregs.x.bx = handle; /*;AN000;*/ + inregs.x.ax = 0x5703; /* Get extended attributes */ /*;AN000;*/ + inregs.x.di = (WORD)0x0; /* return buffer offset */ /*;AN000;*/ + inregs.x.cx = attr_size; /* size to get all names */ /*;AN000;*/ + segregs.es = (WORD)list_seg; /* segment of ea list to return */ /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + strcpy(fix_es_reg,NUL); /* restores original ES reg. value */ /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + *num_entries = 0; /*;AN000;*/ + + /* if no errors then fix up far pointer to list */ + if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/ + + /* convert segment returned from Dallocate to far ptr */ + *list_ptr = 0; /*;AN000;*/ + ptr = (WORD *)list_ptr; /*;AN000;*/ + ptr++; /*;AN000;*/ + *ptr = (WORD)list_seg; /*;AN000;*/ + *num_entries = (WORD)*(WORD far *)*list_ptr; /*;AN000;*/ + (*list_ptr)++; /*;AN000;*/ + strcpy(fix_es_reg,NUL); /* restores ES register value */ /*;AN000;*/ + status = NOERROR; /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Set_reg_attrib() */ +/* */ +/* Subroutine Function: */ +/* Sets the attribute byte of a file (not extended attributes). */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Set_reg_attrib(fspec,attr_byte) /*;AN000;*/ + char *fspec; /*;AN000;*/ + BYTE attr_byte; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + + /* set attribute byte (archive & read-only bits) */ + inregs.x.ax = 0x4301; /* do DOS chmod call */ /*;AN000;*/ + inregs.x.dx = (WORD)fspec; /*;AN000;*/ + inregs.h.ch = 0x0; /*;AN000;*/ + inregs.h.cl = (BYTE)attr_byte; /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + /*;AN000;*/ + /* Check for error */ + if (!(outregs.x.cflag & CARRY)) + status = NOERROR; /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Set_ext_attrib() */ +/* */ +/* Subroutine Function: */ +/* Set an extended attribute for a file. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Set_ext_attrib(handle,list_ptr) /*;AN000;*/ + WORD handle; /*;AN000;*/ + WORD far *list_ptr; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + + /* set extended attribute */ + inregs.x.ax = 0x5704; /* DOS set ext. attr. */ /*;AN000;*/ + inregs.x.bx = handle; /*;AN000;*/ + inregs.x.di = 0x0; /* list offset */ /*;AN000;*/ + segregs.es = (WORD)FP_SEG(list_ptr); /* list segment */ /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + /*;AN000;*/ + /* Check for error */ + if (!(outregs.x.cflag & CARRY)) /*;AN000;*/ + status = NOERROR; /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: CheckYN() */ +/* */ +/* Subroutine Function: */ +/* Check for a valid Yes/No answer. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD CheckYN(fspec) /*;AN000;*/ + char *fspec; /*;AN000;*/ +{ /*;AN000;*/ + WORD answer; /*;AN000;*/ + WORD key; /*;AN000;*/ + + while (TRUE) { /*;AN000;*/ + msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str2.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(11,STDOUT,ONEPARM,&msg_str2,INPUT); /*;AN000;*/ + key = outregs.x.ax; /* get key from AX */ /*;AN000;*/ + inregs.x.dx = key; /* put key in DX */ /*;AN000;*/ + inregs.x.ax = 0x6523; /* check Y/N */ /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + answer = outregs.x.ax; /*;AN000;*/ + Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + + if (answer == YES || answer == NO) /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ + return(answer); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Find_ext_attrib() */ +/* */ +/* Subroutine Function: */ +/* Given an extended attribute name, search the list of attributes */ +/* for a file to find this attribute. Return either TRUE for found */ +/* or FALSE for not found. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Find_ext_attrib(lptr,attribute,num,addr) /*;AN000;*/ + WORD far *lptr; /*;AN000;*/ + char *attribute; /*;AN000;*/ + WORD num; /*;AN000;*/ + struct name_list far **addr; /*;AN000;*/ +{ /*;AN000;*/ + struct name_list far *ptr; /*;AN000;*/ + WORD i,j; /*;AN000;*/ + WORD length; /*;AN000;*/ + WORD found; /*;AN000;*/ + WORD match; /*;AN000;*/ + + found = FALSE; /*;AN000;*/ + + /* loop thru return list structure for the ext. attr. we want */ + for (ptr = (struct name_list far *)lptr,i=0;i < num; i++) { /*;AN000;*/ + + /* compare attribute name to see if this is it */ + if (ptr->nl_name_len == (length = strlen(attribute))) { /*;AN000;*/ + match = TRUE; /*;AN000;*/ + for (j=0;jnl_name[j] != attribute[j]) { /*;AN000;*/ + match = FALSE; /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + if (match) { /*;AN000;*/ + found = TRUE; /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + + /* advance ptr to next extended attr. structure */ + length = NAME_SIZE + ptr->nl_name_len; /*;AN000;*/ + ptr = (struct name_list far *)((BYTE far *)ptr + length); /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ + } /*;AN000;*/ + + /* found the extended attribute wanted, pass addr back */ + if (found) { /*;AN000;*/ + *addr = ptr; /*;AN000;*/ + } /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ + return(found); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Print_ext_attrib() */ +/* */ +/* Subroutine Function: */ +/* Given an extended attribute name, search the list of attributes */ +/* for a file to find this attribute. Return either TRUE for found */ +/* or FALSE for not found. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: target = source */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Print_ext_attrib(fspec,type,name_ptr,num,attr_ptr) /*;AN000;*/ + char *fspec; /*;AN000;*/ + WORD type; /*;AN000;*/ + struct name_list far *name_ptr; /*;AN000;*/ + WORD num; /*;AN000;*/ + struct attr_list far *attr_ptr; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD i; /*;AN000;*/ + WORD length; /*;AN000;*/ + WORD value; /*;AN000;*/ + BYTE far *value_ptr; /*;AN000;*/ + char string[129]; /*;AN000;*/ + char far *cptr; /*;AN000;*/ + struct name_list far *ptr; /*;AN000;*/ + + /* find value field in attribute list */ + length = ATTR_SIZE + attr_ptr->at_name_len; /*;AN000;*/ + value_ptr = (BYTE far *)((BYTE far *)attr_ptr + length); /*;AN000;*/ + length = attr_ptr->at_value_len; /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ + + status = NOERROR; /*;AN000;*/ + switch (type) { /*;AN000;*/ + case EAISUNDEF: /*;AN000;*/ + msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str2.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case EAISLOGICAL: /*;AN000;*/ + msg_str.sub_value_seg = segregs.ds; /*;AN000;*/ + if ((BYTE)*(BYTE far *)value_ptr == 0) /*;AN000;*/ + msg_str.sub_value = (WORD)str_off; /*;AN000;*/ + else /*;AN000;*/ + msg_str.sub_value = (WORD)str_on; /*;AN000;*/ + msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str1.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_str,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case EAISBINARY: /*;AN000;*/ + if (length == 1) { /*;AN000;*/ + msg_num.sub_flags = sf_unsbin2d | sf_byte | sf_right; /*;AN000;*/ + value = (BYTE)*(BYTE far *)value_ptr; /*;AN000;*/ + } /*;AN000;*/ + else if (length == 2) { /*;AN000;*/ + msg_num.sub_flags = sf_unsbin2d | sf_word | sf_right; /*;AN000;*/ + value = (WORD)*(WORD far *)value_ptr; /*;AN000;*/ + } /*;AN000;*/ + else if (length == 4) { /*;AN000;*/ + msg_num.sub_flags = sf_unsbin2d | sf_dword | sf_right; /*;AN000;*/ + value = (DWORD)*(DWORD far *)value_ptr; /*;AN000;*/ + } /*;AN000;*/ + msg_num.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_num.sub_value = (WORD)&value; /*;AN000;*/ + msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str1.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_num,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case EAISASCII: /*;AN000;*/ + msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str2.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/ + Get_far_str(string,&value_ptr,length); /*;AN000;*/ + msg_str2.sub_value = (WORD)string; /*;AN000;*/ + Display_msg(8,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case EAISDATE: /*;AN000;*/ + msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str1.sub_value = (WORD)fspec; /*;AN000;*/ + value = (WORD)*(WORD far *)value_ptr; /*;AN000;*/ + Convert_date(value,&msg_date.sub_value,&msg_date.sub_value_seg); /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_date,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case EAISTIME: /*;AN000;*/ + msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str1.sub_value = (WORD)fspec; /*;AN000;*/ + value = (WORD)*(WORD far *)value_ptr; /*;AN000;*/ + Convert_time(value,&msg_time.sub_value,&msg_time.sub_value_seg); /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_time,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + case EANAMES: /*;AN000;*/ + msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str2.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/ + + /* display special attribute names */ + for (i=0; i < MAX_SPL; i++) { /*;AN000;*/ + msg_str2.sub_value = (WORD)specials[i].name; /*;AN000;*/ + Display_msg(8,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/ + } /*;AN000;*/ + + /* display each attribute name */ + for (ptr = name_ptr,i=0; inl_name_len); /*;AN000;*/ + + msg_str2.sub_value = (WORD)string; /*;AN000;*/ + Display_msg(8,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/ + + /* advance ptr to next extended attr. structure */ + length = NAME_SIZE + ptr->nl_name_len; /*;AN000;*/ + ptr = (struct name_list far *)((BYTE far *)ptr + length); /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ + } /*;AN000;*/ + Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + default: /*;AN000;*/ + msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str2.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/ + break; /*;AN000;*/ + } /* endswitch */ /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Convert_date */ +/* */ +/* Subroutine Function: */ +/* Convert date word returned by DOS to the form required by the */ +/* message retriever. */ +/* */ +/* DOS returns: yyyyyyym mmmddddd */ +/* */ +/* y = 0-119 (1980-2099) */ +/* m = 1-12 */ +/* d = 1-31 */ +/* */ +/* Message retriever requires: yyyyyyyy yyyyyyyy mmmmmmmm dddddddd */ +/* */ +/* Input: */ +/* (1) Date word in form given by DOS */ +/* (2) Address of first word to place result (yyyyyyyy yyyyyyyy) */ +/* (3) Address of second word to place result (mmmmmmmm dddddddd) */ +/* */ +/* Output: */ +/* Double word result updated with date in form required by */ +/* message retriever. */ +/* */ +/* Normal exit: Result word updated */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Convert_date(dosdate,msgdate1,msgdate2) + WORD dosdate; + WORD *msgdate1; + WORD *msgdate2; +{ + WORD day,month,year; + + year = dosdate; + year = ((year >> 1) & 0x7f00) + 80*256; /* DOS year + 80 */ + year = (year >> 8) & 0x007f; /*;AN000;*/ + day = dosdate; + day = (day << 8) & 0x1f00; + month = dosdate; + month = (month >> 5) & 0x000f; + *msgdate1 = year; + *msgdate2 = month | day; +} + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Convert_time */ +/* */ +/* Subroutine Function: */ +/* Convert time word returned by DOS to the form required by the */ +/* message retriever. */ +/* */ +/* DOS returns: hhhhhmmm mmmsssss */ +/* */ +/* h = hours (0-23) */ +/* m = minutes (0-59) */ +/* s = seconds/2 */ +/* */ +/* Message retriever requires: hhhhhhhh mmmmmmmm ssssssss hhhhhhhh */ +/* */ +/* Input: */ +/* (1) Time word in form given by DOS */ +/* (2) Address of first word to place result (hhhhhhhh hhhhhhhh) */ +/* (3) Address of second word to place result (ssssssss 00000000) */ +/* */ +/* Output: */ +/* Double word result updated with time in form required by */ +/* message retriever. */ +/* */ +/* Normal exit: Result word updated */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Convert_time(dostime,msgtime1,msgtime2) + WORD dostime; + WORD *msgtime1; + WORD *msgtime2; +{ + WORD hours,minutes,seconds; + + hours = dostime; + hours = hours >> 11 & 0x001f; + seconds = dostime; + seconds = seconds & 0x001f * 2; /* seconds * 2 */ + minutes = dostime; + minutes = minutes << 3 & 0x3f00; + *msgtime1 = hours | minutes; + *msgtime2 = seconds; +} + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Regular_attrib() */ +/* */ +/* Subroutine Function: */ +/* Handles all function for archive bit and read-only bit. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Regular_attrib(fspec) /*;AN000;*/ + char *fspec; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD i; /*;AN000;*/ + char string[16]; /*;AN000;*/ + + /* get attributes */ + if ((status = Get_reg_attrib(fspec,&attr)) != NOERROR) { /*;AN000;*/ + return(status); /*;AN000;*/ + } /*;AN000;*/ + + /* Check whether to display values or set new ones */ + if (set_reg_attr) { /*;AN000;*/ + attr = (attr & (~mmask)) | pmask; /*;AN000;*/ + status = Set_reg_attrib(fspec,attr); /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + for (i = 0; i < 8; i++) /*;AN000;*/ + if ((attr & bits[i]) != 0 ) /*;AN000;*/ + string[i] = as[i]; /*;AN000;*/ + else /*;AN000;*/ + string[i] = ' '; /*;AN000;*/ + for (i=8; i < 16; i++) /*;AN000;*/ + string[i] = ' '; /*;AN000;*/ + string[16] = '\0'; /*;AN000;*/ + + msg_str.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str.sub_value = (WORD)string; /*;AN000;*/ + msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str1.sub_value = (WORD)fspec; /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_str,NOINPUT); /*;AN000;*/ + } /*;AN000;*/ + + did_attrib_ok = TRUE; /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Special_attrib() */ +/* */ +/* Subroutine Function: */ +/* Handles all function for special attributes. For example, "DATE" */ +/* is a special attribute because it is not an extended attribute, */ +/* but ATTRIB does support its function. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Special_attrib(handle,fspec,id) /*;AN000;*/ + WORD handle; /*;AN000;*/ + char *fspec; /*;AN000;*/ + WORD id; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + DWORD filesize; /*;AN000;*/ + long size; /*;AN000;*/ + long filelength(); /*;AN000;*/ + + msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_str1.sub_value = (WORD)fspec; /*;AN000;*/ + + /* check to set if user is trying to set a special attribute, if so */ + /* then return error. */ + if (set_ext_attr) /*;AN000;*/ + return(EARCNOTEVER+200); /*;AN000;*/ + + /* determine which info to get by using ID */ + if (id == A_FILESIZE) { /* get filesize */ /*;AN000;*/ + + /* get file size, if error return error code */ + if ((size = filelength(handle)) == (long)-1) { /*;AN000;*/ + return(FILENOTFOUND); /*;AN000;*/ + } /*;AN000;*/ + filesize = (DWORD)size; /*;AN000;*/ + msg_dword.sub_value = (WORD)&filesize; /*;AN000;*/ + msg_dword.sub_value_seg = (WORD)segregs.ds; /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_dword,NOINPUT); /*;AN000;*/ + } /*;AN000;*/ + + else if (id == A_DATE) { /*;AN000;*/ + inregs.x.ax = 0x5700; /* get date */ /*;AN000;*/ + inregs.x.bx = handle; /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + if (outregs.x.cflag & CARRY) /*;AN000;*/ + return(status); /*;AN000;*/ + + Convert_date(outregs.x.dx,&msg_date.sub_value,&msg_date.sub_value_seg); /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_date,NOINPUT); /*;AN000;*/ + } /*;AN000;*/ + + else if (id == A_TIME) { /*;AN000;*/ + inregs.x.ax = 0x5700; /* get time */ /*;AN000;*/ + inregs.x.bx = handle; /*;AN000;*/ + intdos(&inregs,&outregs); /*;AN000;*/ + status = outregs.x.ax; /*;AN000;*/ + if (outregs.x.cflag & CARRY) /*;AN000;*/ + return(status); /*;AN000;*/ + + Convert_time(outregs.x.cx,&msg_time.sub_value,&msg_time.sub_value_seg); /*;AN000;*/ + Display_msg(9,STDOUT,TWOPARM,&msg_time,NOINPUT); /*;AN000;*/ + } /*;AN000;*/ + + did_attrib_ok = TRUE; /*;AN000;*/ + return(NOERROR); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Extended_attrib() */ +/* */ +/* Subroutine Function: */ +/* Determine what functions the user wants and then gets the */ +/* extended attributes and regular attributes and then checks */ +/* the attributes against what the user wanted and either do it or */ +/* return error. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Extended_attrib(handle,fspec) /*;AN000;*/ + WORD handle; /*;AN000;*/ + char *fspec; /*;AN000;*/ +{ /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD num; /*;AN000;*/ + WORD type; /*;AN000;*/ + WORD length; /*;AN000;*/ + WORD i; /*;AN000;*/ + WORD far *name_ptr, /*;AN000;*/ + far *nptr; /*;AN000;*/ + WORD far *list_ptr; /*;AN000;*/ + BYTE far *value_ptr; /*;AN000;*/ + char far *cptr; /*;AN000;*/ + char *ptr; /*;AN000;*/ + struct query_list qlist; /*;AN000;*/ + + /* get extended attribute names, if error return with error code */ + if ((status = Get_ext_attr_names(handle,&name_ptr,&num)) != NOERROR) { /*;AN000;*/ + return(status); /*;AN000;*/ + } /*;AN000;*/ + + /* Check for keyword "*", print all extended attribute names */ + /* ***** this is a special piece of code */ + if (strcmp(ext_attr,"*") == 0) { /*;AN000;*/ + do_ext_attr = TRUE; /*;AN000;*/ + set_ext_attr = FALSE; /*;AN000;*/ + nptr = name_ptr; /*;AN000;*/ + type = EANAMES; /*;AN000;*/ + status = Print_ext_attrib(fspec,type,name_ptr,num,list_ptr); /*;AN004;*/ + did_attrib_ok = TRUE; /*;AN004;*/ + return(status); /*;AN004;*/ + } /*;AN000;*/ + + /* find if extended attribute name is in list */ + else if (!Find_ext_attrib(name_ptr,ext_attr,num,&nptr)) { /*;AN000;*/ + return(EARCNOTFOUND+200); /*;AN000;*/ + } /*;AN000;*/ + else /*;AN000;*/ + type = ((struct name_list far *)nptr)->nl_type; /*;AN000;*/ + + /* Check if extended attribute is hidden , if so leave */ + if (((struct name_list far *)nptr)->nl_flags & EAHIDDEN) { /*;AN000;*/ + did_attrib_ok = TRUE; /*;AN000;*/ + return(NOERROR); /*;AN000;*/ + } /*;AN000;*/ + + /* Get the extended attribute value */ + qlist.ql_num = 1; /*;AN000;*/ + qlist.ql_type = ((struct name_list far *)nptr)->nl_type; /*;AN000;*/ + qlist.ql_flags = ((struct name_list far *)nptr)->nl_flags; /*;AN000;*/ + qlist.ql_name_len = ((struct name_list far *)nptr)->nl_name_len; /*;AN000;*/ + cptr = (char far *)((BYTE far *)nptr + 4); /*;AN000;*/ + Get_far_str(qlist.ql_name,&cptr,qlist.ql_name_len); /*;AN000;*/ + + if ((status = Get_ext_attrib(handle,&list_ptr,&qlist)) != NOERROR) { /*;AN000;*/ + return(status); /*;AN000;*/ + } /*;AN000;*/ + + /* Check if doing a display or set, and go do it */ + if (do_ext_attr) { /*;AN000;*/ + status = Print_ext_attrib(fspec,type,name_ptr,num,list_ptr); /*;AN000;*/ + } /*;AN000;*/ + else { /*;AN000;*/ + + /* Check if extended attribute is read-only or create-only */ + /* or if the type is undefined. if true, display error */ + if ((qlist.ql_flags & (EAREADONLY | EACREATEONLY)) || /*;AN000;*/ + (qlist.ql_type & EAISUNDEF)) { /*;AN000;*/ + return(EARCNOTEVER+200); /* error will be displayed */ /*;AN000;*/ + } /*;AN000;*/ + + /* Check type of current attribute against the type the user */ + /* is trying to set the attribute to. If they differ, error. */ + if (qlist.ql_type != ext_attr_value_type) { /*;AN000;*/ + return(EARCDEFBAD+200); /* error will be displayed */ /*;AN000;*/ + } /*;AN000;*/ + + /* find value field in attribute list */ + length = ATTR_SIZE + qlist.ql_name_len; /*;AN000;*/ + value_ptr = (BYTE far *)((BYTE far *)list_ptr + length); /*;AN000;*/ + length = ((struct attr_list far *)list_ptr)->at_value_len; /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ + + /* CODEPAGE attrbute only - display Y/N message if changing codepage */ + /* to a new value and cp != 0, ask for confirmation. */ + if (strcmp(qlist.ql_name,"CP") == 0 && /*;AN000;*/ + (WORD)*(WORD far *)value_ptr != 0 && /*;AN000;*/ + (WORD)*(WORD far *)value_ptr != (WORD)ext_attr_value.ea_bin.dword) { /*;AN000;*/ + if (CheckYN(fspec) == NO) { /*;AN000;*/ + did_attrib_ok = TRUE; /*;AN000;*/ + return(NOERROR); /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + + /* Determine type of extended attribute and set the correct value */ + switch (ext_attr_value_type) { /*;AN000;*/ + case EAISLOGICAL: /*;AN000;*/ + *(BYTE far *)value_ptr = (BYTE)ext_attr_value.ea_logical; /*;AN000;*/ + break; /*;AN000;*/ + case EAISBINARY: /*;AN000;*/ + if (length == 1) /*;AN000;*/ + *(BYTE far *)value_ptr = (BYTE)ext_attr_value.ea_bin.dword; /*;AN000;*/ + else if (length == 2) /*;AN000;*/ + *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_bin.dword; /*;AN000;*/ + else /*;AN000;*/ + *(DWORD far *)value_ptr = (DWORD)ext_attr_value.ea_bin.dword; /*;AN000;*/ + break; /*;AN000;*/ + case EAISASCII: /*;AN000;*/ + length = strlen(ext_attr_value.ea_ascii); /* get string length */ /*;AN000;*/ + ((struct attr_list far *)list_ptr)->at_value_len = length; /*;AN000;*/ + for (ptr=ext_attr_value.ea_ascii,i=0;i < length;i++) { /*;AN000;*/ + *(char far *)value_ptr = *ptr++; /*;AN000;*/ + ((char far *)value_ptr)++; /*;AN000;*/ + } /*;AN000;*/ + break; /*;AN000;*/ + case EAISDATE: /*;AN000;*/ + *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_date; /*;AN000;*/ + break; /*;AN000;*/ + case EAISTIME: /*;AN000;*/ + *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_time; /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ + + list_ptr--; /* make list_ptr point to num entries */ /*;AN000;*/ + *(WORD far *)list_ptr = 1; /* num entries = 1 */ /*;AN000;*/ + + if ((status = Set_ext_attrib(handle,list_ptr)) != NOERROR) { /*;AN000;*/ + return(status); /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + did_attrib_ok = TRUE; /*;AN000;*/ + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Attrib() */ +/* */ +/* Subroutine Function: */ +/* Determine what functions the user wants and then gets the */ +/* extended attributes and regular attributes and then checks */ +/* the attributes against what the user wanted and either do it or */ +/* return error. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Attrib(path,file) /*;AN000;*/ + char *path, /*;AN000;*/ + *file; /*;AN000;*/ +{ /*;AN000;*/ + char fspec[128]; /*;AN000;*/ + WORD status; /*;AN000;*/ + WORD handle; /*;AN000;*/ + WORD i; /*;AN000;*/ + WORD found_spl; /* boolean */ /*;AN000;*/ + WORD id; /*;AN000;*/ + + strcpy(fspec,path); /* make full filename */ /*;AN000;*/ + strcat(fspec,file); /*;AN000;*/ + + /* Check for extended & special attributes */ + if (set_ext_attr || do_ext_attr) { /*;AN000;*/ + + /* Check for special attribute keywords */ + found_spl = FALSE; /*;AN000;*/ + for (i=0; i < MAX_SPL; i++) { /*;AN000;*/ + if (strcmp(ext_attr,specials[i].name) == 0) { /*;AN000;*/ + found_spl = TRUE; /*;AN000;*/ + id = specials[i].id; /*;AN000;*/ + break; /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + + /* Do an extended open, if error return error code */ + if ((status = Ext_open(fspec,&handle)) != NOERROR) { /*;AN000;*/ + return(status); /*;AN000;*/ + } /*;AN000;*/ + + /* Special attributes */ + if (found_spl) { /*;AN000;*/ + status = Special_attrib(handle,fspec,id); /*;AN000;*/ + } /*;AN000;*/ + + /* Extended attributes */ + else { /*;AN000;*/ + status = Extended_attrib(handle,fspec); /*;AN000;*/ + } /*;AN000;*/ + close(handle); /*;AN000;*/ + } /*;AN000;*/ + + /* Check if setting archive bit or readonly bit */ + if (set_reg_attr || do_reg_attr) { /*;AN000;*/ + if ((status = Regular_attrib(fspec)) != NOERROR) { /*;AN000;*/ + return(status); /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + + return(status); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Do_dir() */ +/* */ +/* Subroutine Function: */ +/* Given the full path-filename, determine if descending option is */ +/* set and then recursively (if option set) find all files in this */ +/* directory and all files in any subdirectories (if option set). */ +/* For each directory call Attrib() which will process a file. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +WORD Do_dir(path,file) + char *path, + *file; +{ + char dta_area[128]; + char subdirectory[256]; + char next[32]; + WORD status; + WORD search_attrib; + + next[0] = '\0'; /*;AN000;*/ + Dta_save(dta_area,128); + status = NOERROR; /*;AN000;*/ + + /* first, but only if descending, scan for subdirectories */ + if (descending) { + strcpy(subdirectory,path); + strcat(subdirectory,"*.*"); + + search_attrib = SUBDIR; /* Find all except volume labels*/ /*;AN000;*/ + status = Find_first(subdirectory,next,&search_attrib); + + while (status == NOERROR) { + if ((next[0] != '.') && ((search_attrib & SUBDIR) != 0)) { + strcpy(subdirectory,path); + strcat(subdirectory,next); + strcat(subdirectory,"\\"); + status = Do_dir(subdirectory,file); + } + if (status == NOERROR) { + strcpy(subdirectory,path); + strcat(subdirectory,"*.*"); + + search_attrib = SUBDIR; /*;AN000;*/ + status = Find_next(next,&search_attrib); + } + } /* while */ + } /* if descending */ + + if (status == NOMOREFILES) + status = NOERROR; + + /* now, search this directory for files that match */ + if (status == NOERROR) { + strcpy(subdirectory,path); + strcat(subdirectory,file); + + search_attrib = SUBDIR; /*;AN000;*/ + status = Find_first(subdirectory,next,&search_attrib); + while(status == NOERROR) { + + /* Check that this file is not a directory, system file, */ + /* or a hidden file. */ + if ( (next[0] != '.') && + ((search_attrib & SUBDIR) == 0) && + ((search_attrib & SYSTEM) == 0) && + ((search_attrib & HIDDEN) == 0) ) { + status = Attrib(path,next); + } + + if (status == NOERROR) { + search_attrib = SUBDIR; /*;AN000;*/ + status = Find_next(next,&search_attrib); + } + } /* while */ + } + if (status == NOMOREFILES) + status = NOERROR; + + if (status != NOERROR) { /*;AN000;*/ + } + + Dta_restore(dta_area,128); + return(status); +} + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Check_appendx() */ +/* */ +/* Subroutine Function: */ +/* Check APPEND /X status. If it is not active, */ +/* do nothing. If it is active, then turn it off */ +/* and set flag indicating that fact. */ +/* */ +/* Input: none */ +/* */ +/* Output: append_active_flg */ +/* */ +/* Normal exit: flag set if /X active */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Check_appendx() /*;AN000;*/ +{ /*;AN000;*/ + void ctl_brk_handler(); /*;AN000;*/ + extern crit_err_handler(); /*;AN000;*/ + WORD *ptr; /*;AN000;*/ + + inregs.x.ax = 0xb700; /* Is appendx installed ? */ /*;AN000;*/ + int86(0x2f,&inregs,&outregs); /*;AN000;*/ + if (outregs.h.al) { /*;AN000;*/ + inregs.x.ax = 0xb702; /* Get version */ /*;AN000;*/ + int86(0x2f,&inregs,&outregs); /*;AN000;*/ + if (outregs.x.ax == 0xffff) { /*;AN000;*/ + inregs.x.ax = 0xb706; /* Get /X status */ /*;AN000;*/ + int86(0x2f,&inregs,&outregs); /*;AN000;*/ + append_x_status = outregs.x.bx; /* save status to restore */ /*;AN000;*/ + + /* turn off append /x */ + inregs.x.ax = 0xb707; /* Set /X status */ /*;AN000;*/ + inregs.x.bx = append_x_status & INACTIVE; /*;AN000;*/ + int86(0x2f,&inregs,&outregs); /*;AN000;*/ + } /*;AN000;*/ + } /*;AN000;*/ + + /* get critical error handler vector for later */ + inregs.x.ax = 0x3524; /* get critical error vector */ /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + ptr = (WORD *)&old_int24_off; /*;AN000;*/ + *ptr++ = (WORD)outregs.x.bx; /*;AN000;*/ + *ptr = (WORD)segregs.es; /*;AN000;*/ + + /* set crtl-c & critical error handler vector */ + segread(&segregs); + inregs.x.ax = 0x2523; /* crtl-c - int 23 */ /*;AN000;*/ + inregs.x.dx = (WORD) ctl_brk_handler; /*;AN000;*/ + segregs.ds = (WORD) segregs.cs; /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + + inregs.x.ax = 0x2524; /* critical err - int 24 */ /*;AN000;*/ + inregs.x.dx = (WORD) crit_err_handler; /*;AN000;*/ + segregs.ds = (WORD) segregs.cs; /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + strcpy(fix_es_reg,NUL); /* restore ES register */ /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Reset_appendx() */ +/* */ +/* Subroutine Function: */ +/* Reset APPEND /X status. If it is not active, */ +/* do nothing. If it is active, then turn it on */ +/* and set flag indicating that fact. */ +/* */ +/* Input: none */ +/* */ +/* Output: append_active_flg */ +/* */ +/* Normal exit: flag set if /X active */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +Reset_appendx() /*;AN000;*/ +{ /*;AN000;*/ + if (append_x_status != 0) { /*;AN000;*/ + inregs.x.ax = 0xb707; /*;AN000;*/ + inregs.x.bx = append_x_status; /*;AN000;*/ + int86(0x2f,&inregs,&outregs); /*;AN000;*/ + } /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Check_DBCS() */ +/* */ +/* Subroutine Function: */ +/* Given an array and a position in the array, check if the character */ +/* is a non-DBCS character. */ +/* */ +/* Input: array, character position, character */ +/* */ +/* Output: TRUE - if array[position-1] != DBCS character AND */ +/* array[position] == character. */ +/* FALSE - otherwise */ +/* Normal exit: none */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +WORD Check_DBCS(array,position,character) /*;AN000;*/ + char *array; /*;AN000;*/ + WORD position; /*;AN000;*/ + char character; /*;AN000;*/ +{ /*;AN000;*/ + BYTE far *ptr; /*;AN000;*/ + WORD i; /*;AN000;*/ + char c; /*;AN000;*/ + char darray[128]; /* DBCS array, put "D" in every position*/ /*;AN000;*/ + /* that corresponds to the first byte */ + /* of a DBCS character. */ + for (i=0;i<128;i++) /*;AN000;*/ + darray[i] = ' '; /*;AN000;*/ + + /* Check each character, starting with the first in string, for DBCS */ + /* characters and mark each with a "D" in the corresponding darray. */ + for (i=0;i= *ptr && c <= *(ptr+1)) { /*;AN000;*/ + darray[i] = 'D'; /*;AN000;*/ + i++; /* skip over second byte of DBCS */ /*;AN000;*/ + break; + } + } /*;AN000;*/ + } /*;AN000;*/ + + /* if character is not DBCS then check to see if it is == to character */ + if (darray[position-1] != 'D' && character == array[position]) { /*;AN000;*/ + return (TRUE); /*;AN000;*/ + } /*;AN000;*/ + else /*;AN000;*/ + return (FALSE); /*;AN000;*/ +} /*;AN000;*/ + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Get_DBCS_vector() */ +/* */ +/* Subroutine Function: */ +/* Gets the double-byte table vector. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: none */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +Get_DBCS_vector() /*;AN000;*/ +{ /*;AN000;*/ + WORD *ptr; /*;AN000;*/ + WORD *buffer; /*;AN000;*/ + DWORD far *addr_ptr; /*;AN000;*/ + + /* allocate a buffer for DBCS table vector */ + buffer = Dallocate(5); /* at least 5 bytes big */ /*;AN000;*/ + + inregs.x.ax = 0x6507; /* get extended country info */ /*;AN000;*/ + inregs.x.bx = -1; /* use active code page */ /*;AN000;*/ + inregs.x.cx = 5; /* 5 bytes of return data */ /*;AN000;*/ + inregs.x.dx = -1; /* use default country */ /*;AN000;*/ + inregs.x.di = 0; /* buffer offset */ /*;AN000;*/ + segregs.es = (WORD)buffer; /* buffer segment */ /*;AN000;*/ + intdosx(&inregs,&outregs,&segregs); /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ + + outregs.x.di++; /* skip over id byte */ /*;AN000;*/ + + /* make a far ptr from ES:[DI] */ + addr_ptr = 0; /*;AN000;*/ + ptr = (WORD *)&addr_ptr; /*;AN000;*/ + *ptr = (WORD)outregs.x.di; /* get offset */ /*;AN000;*/ + ptr++; /*;AN000;*/ + *ptr = (WORD)segregs.es; /* get segment */ /*;AN000;*/ + DBCS_ptr = (BYTE far *)*addr_ptr; /*;AN000;*/ + DBCS_ptr += 2; /* skip over table length */ /*;AN000;*/ + + /* DBCS_ptr points to DBCS table */ /*;AN000;*/ + strcpy(fix_es_reg,NUL); /*;AN000;*/ +} /*;AN000;*/ + + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Error_exit() */ +/* */ +/* Subroutine Function: */ +/* displays an extended error message with - filename */ +/* */ +/* Input: error_file_name[] must contain name of file, if needed for */ +/* message output. */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +void Error_exit(msg_class,ext_err_num,subcnt) /*;AN000;*/ + /*;AN000;*/ + int msg_class; /*;AN000;*/ + int ext_err_num; /*;AN000;*/ + int subcnt; /*;AN000;*/ +{ /*;AN000;*/ + segread(&segregs); /*;AN000;*/ + msg_error.sub_value_seg = segregs.ds; /*;AN000;*/ + msg_error.sub_value = (WORD)error_file_name; /*;AN000;*/ + inregs.x.ax = (WORD)ext_err_num; /*;AN000;*/ + inregs.x.bx = STDERR; /*;AN000;*/ + inregs.x.cx = subcnt; /*;AN000;*/ + inregs.h.dh = (WORD)msg_class; /*;AN000;*/ + inregs.h.dl = NOINPUT; /*;AN000;*/ + inregs.x.si = (WORD)&msg_error; /*;AN000;*/ + sysdispmsg(&inregs,&outregs); /*;AN000;*/ + + /* check for error printing message */ + if (outregs.x.cflag & CARRY) { /*;AN000;*/ + outregs.x.bx = (WORD) STDERR; /*;AN000;*/ + outregs.x.si = NOSUBPTR; /*;AN000;*/ + outregs.x.cx = NOSUBCNT; /*;AN000;*/ + outregs.h.dl = exterr_msg_class; /*;AN000;*/ + sysdispmsg(&outregs,&outregs); /*;AN000;*/ + } /*;AN000;*/ + + Reset_appendx(); /* Reset APPEND /X status */ /*;AN000;*/ + exit(1); /*;AN000;*/ +} /*;AN000;*/ + + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: Parse_err() */ +/* */ +/* Subroutine Function: */ +/* displays an parser error message with - filename */ +/* */ +/* Input: error_file_name[] must contain name of file, if needed for */ +/* message output. */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +void Parse_err(error_num) /*;AN000;*/ + + WORD error_num; /*;AN000;*/ +{ /*;AN000;*/ + char *cptr; /*;AN000;*/ + char *sptr; /*;AN000;*/ + + /* take out leading spaces, point to beginning of parameter */ + for (((int)sptr) = inregs.x.si; ((int)sptr) < outregs.x.si && *sptr == BLANK; sptr++) /*;AN000;*/ + /* null statement */ ; /*;AN000;*/ + + /* find end of this parameter in command line and put end-of-string there */ + for (cptr = sptr; ((int)cptr) < outregs.x.si && *cptr != BLANK; cptr++) /*;AN000;*/ + /* null statement */ ; /*;AN000;*/ + *cptr = NUL; /*;AN000;*/ + strcpy(error_file_name,sptr); /*;AN000;*/ + + /* check for messages with no parameter */ + if (error_num == p_op_missing) /*;AN000;*/ + Error_exit(ERR_PARSE,error_num,NOSUBCNT); /*;AN000;*/ + else /*;AN000;*/ + Error_exit(ERR_PARSE,error_num,ONEPARM); /*;AN000;*/ +} /*;AN000;*/ + + + + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* */ +/* Subroutine Name: ctl_brk_handler */ +/* */ +/* Subroutine Function: */ +/* Crtl-break interrupt handler. */ +/* */ +/* Input: none */ +/* */ +/* Output: none */ +/* */ +/* Normal exit: */ +/* */ +/* Error exit: None */ +/* */ +/* Internal References: */ +/* None */ +/* */ +/* External References: */ +/* None */ +/* */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +void ctl_brk_handler() +{ + Reset_appendx(); + exit(3); /*;AN000;*/ +/* inregs.x.ax = 0x4c03; /* DOS terminate int call */ /*;AN000;*/ +/* intdos(&inregs,&outregs); /*;AN000;*/ +} diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.H b/v4.0/src/CMD/ATTRIB/ATTRIB.H new file mode 100644 index 0000000..5297d11 --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/ATTRIB.H @@ -0,0 +1,443 @@ +/* Module ATTRIB.H */ + +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* All defines for attrib.c */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +#define FALSE 0 /*;AN000;*/ +#define TRUE !FALSE /*;AN000;*/ + +#ifndef BYTE +#define BYTE unsigned char /*;AN000;*/ +#define WORD unsigned short /*;AN000;*/ +#define DWORD unsigned long /*;AN000;*/ +#endif + +#define CARRY 0x0001 /*;AN000; carry flag */ + +#define YES 1 /*;AN000; Yes return from int 21h Y/N check */ +#define NO 0 /*;AN000; NO return from int 21h Y/N check */ + +#define NUL 0x0 /*;AN000;*/ +#define BLANK 0x20 /*;AN000;*/ +#define TAB 0x09 /*;AN000;*/ +#define CR 0x0d /*;AN000;*/ +#define LF 0x0a /*;AN000;*/ + +/* Error_exit() parameter values */ +#define ERR_EXTENDED 1 /*;AN000;*/ +#define ERR_PARSE 2 /*;AN000;*/ + + +/* standard file handles */ +#define STDIN 0x00 /*;AN000; Standard Input device handle */ +#define STDOUT 0x01 /*;AN000; Standard Output device handle */ +#define STDERR 0x02 /*;AN000; Standard Error Output device handle */ +#define STDAUX 0x03 /*;AN000; Standard Auxiliary device handle */ +#define STDPRN 0x04 /*;AN000; Standard Printer device handle */ + +/* attribute byte defines */ +#define AFILE 0x00 /*;AN000;*/ +#define READONLY 0x01 /*;AN000;*/ +#define HIDDEN 0x02 /*;AN000;*/ +#define SYSTEM 0x04 /*;AN000;*/ +#define LABEL 0x08 /*;AN000;*/ +#define SUBDIR 0x10 /*;AN000;*/ +#define ARCHIVE 0x20 /*;AN000;*/ + +/* extended attribute type defines */ +#define EAISUNDEF 0 /*;AN000; undefined type */ +#define EAISLOGICAL 1 /*;AN000; logical (0 or 1) */ +#define EAISBINARY 2 /*;AN000; binary integer */ +#define EAISASCII 3 /*;AN000; ASCII type */ +#define EAISDATE 4 /*;AN000; DOS file date format */ +#define EAISTIME 5 /*;AN000; DOS file time format */ + +#define EANAMES 6 /*;AN000; ext attr names ASCII */ + +/* extended attribute flag defines */ +#define EASYSTEM 0x8000 /*;AN000; EA is system defined */ +#define EAREADONLY 0x4000 /*;AN000; EA is read only */ +#define EAHIDDEN 0x2000 /*;AN000; EA is hidden */ +#define EACREATEONLY 0x1000 /*;AN000; EA is setable only at create time */ + +/* extended attribute failure return code defines */ +#define EARCNOERROR 0 /*;AN000; no error */ +#define EARCNOTFOUND 1 /*;AN000; name not found */ +#define EARCNOSPACE 2 /*;AN000; no space to hold name or value */ +#define EARCNOTNOW 3 /*;AN000; name can't be set on this function */ +#define EARCNOTEVER 4 /*;AN000; name can't be set */ +#define EARCUNDEF 5 /*;AN000; name known to this FS but not supported */ +#define EARCDEFBAD 6 /*;AN000; EA definition bad (TYPE,LENGTH, etc.) */ +#define EARCACCESS 7 /*;AN000; EA access denied */ +#define EARCVALBAD 8 /*;AN000; EA value not supported */ +#define EARCUNKNOWN -1 /*;AN000; undetermined cause */ + +/* message retriever interface defines */ +#define NOSUBPTR 0 /*;AN000; no sublist pointer */ +#define NOSUBCNT 0 /*;AN000; 0 substitution count */ +#define ONEPARM 1 /*;AN000; 1 substitution count */ +#define TWOPARM 2 /*;AN000; 2 substitution count */ +#define NOINPUT 0 /*;AN000; no user input */ +#define INPUT 1 /*;AN000; ask user for Y/N input */ + +/* misc. defines */ +#define A_FILESIZE 1 /* id of special attribute: filesize */ +#define A_DATE 2 /* id of special attribute: date */ +#define A_TIME 3 /* id of special attribute: time */ + +#define MAX_ATTR_SIZE 160 /*;AN000; max ext attribute buffer size */ +#define MAX_KEYWORD 128 /*;AN000; max size of extended attribute keyword */ +#define MAX_SPL 3 /*;AN000; max number of special attributes */ + +#define ATTR_SIZE 7 /*;AN000; size in bytes of attr struct */ +#define NAME_SIZE 4 /*;AN000; size in bytes of name struct */ + +#define NOERROR 0 /*;AN000;*/ +#define NOMOREFILES 18 /*;AN000;*/ +#define FILENOTFOUND 2 /*;AN000;*/ + +#define GET_DATE 1 /*;AN000;*/ +#define GET_TIME 2 /*;AN000;*/ + +#define INACTIVE 0x7fff /*;AN000;*/ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* All structures defined for attrib.c */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ + +struct p_null { /*;AN000; a null value list for parser */ + unsigned char null; /*;AN000;*/ + }; /*;AN000;*/ + +struct query_list { /*;AN000; Generic attribute overlay structure */ + WORD ql_num; + BYTE ql_type; /*;AN000; EA type */ + WORD ql_flags; /*;AN000; EA flags */ + BYTE ql_name_len; /*;AN000; name length */ + char ql_name[MAX_KEYWORD]; /*;AN000; name */ + }; /*;AN000;*/ + +struct name_list { /*;AN000; Generic attribute overlay structure */ + BYTE nl_type; /*;AN000; EA type */ + WORD nl_flags; /*;AN000; EA flags */ + BYTE nl_name_len; /*;AN000; name length */ + char nl_name[MAX_KEYWORD]; /*;AN000; name */ + }; /*;AN000;*/ + +struct attr_list { /*;AN000; Generic attribute overlay structure */ + BYTE at_type; /*;AN000; EA type */ + WORD at_flags; /*;AN000; EA flags */ + BYTE at_rc; /*;AN000; EA return code */ + BYTE at_name_len; /*;AN000; name length */ + WORD at_value_len; /*;AN000; value length */ + char at_name[MAX_KEYWORD]; /*;AN000; name */ + }; /*;AN000;*/ + +struct parm_list { /*;AN000; Parm list for extended open DOS call */ + DWORD pm_list; /*;AN000; extended attr. list */ + WORD pm_num_parms; /*;AN000; number of parameters */ + BYTE pm_id; /*;AN000; id */ + WORD pm_iomode; /*;AN000; iomode */ + }; /*;AN000;*/ + +struct spl_list { /*;AN000;*/ + char name[MAX_KEYWORD]; /*;AN000;*/ + WORD id; /*;AN000;*/ + }; /*;AN000;*/ + +struct bin_struct { /*;AN000;*/ + BYTE length; /*;AN000;*/ + DWORD dword; /*;AN000;*/ + }; /*;AN000;*/ + +union eav_union { /*;AN000;*/ + WORD ea_undef; /*;AN000;*/ + BYTE ea_logical; /*;AN000;*/ + struct bin_struct ea_bin; /*;AN000;*/ + char ea_ascii[129]; /*;AN000;*/ + DWORD ea_time; /*;AN000;*/ + DWORD ea_date; /*;AN000;*/ + }; /*;AN000;*/ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +/* All global variables for attrib.c */ +/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/ +struct spl_list specials[MAX_SPL] = { /*;AN000;*/ + "FILESIZE", A_FILESIZE, /*;AN000;*/ + "DATE", A_DATE, /*;AN000;*/ + "TIME", A_TIME }; /*;AN000;*/ + + +/* parser structure variables */ +union eav_union ext_attr_value; /*;AN000; result value union */ + +struct p_result_blk pos1_buff; /*;AN000; result buffer for -+A,-+R */ +struct p_result_blk pos2_buff; /*;AN000; result buffer for -+A,-+R */ +struct p_result_blk pos3_buff; /*;AN000; result buffer for filespec */ +struct p_result_blk pos4_buff; /*;AN000; result buffer for -+A,-+R */ +struct p_result_blk pos5_buff; /*;AN000; result buffer for -+A,-+R */ +struct p_result_blk pos6_buff; /*;AN000; result buffer for id */ +struct p_result_blk pos6b_buff; /*;AN000; result buffer for id */ +struct p_result_blk sw_buff; /*;AN000; result buffer for /S */ + +char nullword[] = " "; /*;AN000; used when no word attribute */ +char nulldword[] = " "; /*;AN000; used when no double word attribute */ +char nulldate[] = " "; /*;AN000; used when no date attribute */ +char nulltime[] = " "; /*;AN000; used when no time attribute */ + +char plusa[] = "+A"; /*;AN000; strings for match */ +char minusa[] = "-A"; /*;AN000;*/ +char plusr[] = "+R"; /*;AN000;*/ +char minusr[] = "-R"; /*;AN000;*/ + +struct p_null noval = /*;AN000; structure for no value list */ + { 0 }; /*;AN000;*/ + +struct ps_valist_blk vals1 = /*;AN000; +A-A+R-R value list */ + { p_nval_string, /*;AN000; string value list type */ + 0, /*;AN000; number of ranges */ + 0, /*;AN000; number of numbers */ + 4, /*;AN000; number of strings */ + 0x20, /*;AN000; item tag */ + (WORD)plusa, /*;AN000; address of string */ + 0x20, /*;AN000; item tag */ + (WORD)minusa, /*;AN000; address of string */ + 0x01, /*;AN000; item tag */ + (WORD)plusr, /*;AN000; address of string */ + 0x01, /*;AN000; item tag */ + (WORD)minusr }; /*;AN000; address of string */ + +struct p_control_blk p_con1 = /*;AN000; describes +-A or +-R */ + { 0x2001, /*;AN000; Simple string,optional */ + 0x0002, /*;AN000; Cap result by char table */ + (WORD)&pos1_buff, /*;AN000;*/ + (WORD)&vals1, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_con2 = /*;AN000; describes +-A or +-R (2nd occurrance) */ + { 0x2001, /*;AN000; Simple string,optional */ + 0x0002, /*;AN000; Cap result by char table */ + (WORD)&pos2_buff, /*;AN000;*/ + (WORD)&vals1, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_con3 = /*;AN000; describes filespec */ + { 0x0200, /*;AN000; File spec required */ + 0x0001, /*;AN000; Cap result by file table */ + (WORD)&pos3_buff, /*;AN000;*/ + (WORD)&noval, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_con4 = /*;AN000; describes +-A or +-R */ + { 0x2001, /*;AN000; Simple string,optional */ + 0x0002, /*;AN000; Cap result by char table */ + (WORD)&pos4_buff, /*;AN000;*/ + (WORD)&vals1, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_con5 = /*;AN000; describes +-A or +-R (2nd occurrance) */ + { 0x2001, /*;AN000; Simple string,optional */ + 0x0002, /*;AN000; Cap result by char table */ + (WORD)&pos5_buff, /*;AN000;*/ + (WORD)&vals1, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_con6 = /*;AN000; describes id */ + { 0x2001, /*;AN000; Simple string,optional */ + 0x0002, /*;AN000; Cap result by char table */ + (WORD)&pos6_buff, /*;AN000;*/ + (WORD)&noval, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_con6a = /*;AN000; describes id */ + { 0x2000, /*;AN000; Simple string */ + 0x0002, /*;AN000; Cap result by char table */ + (WORD)&pos6_buff, /*;AN000;*/ + (WORD)&noval, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_con6b = /*;AN000; describes id */ + { 0xe481, /*;AN000; Quoted string */ + 0x0002, /*;AN000;*/ + (WORD)&pos6b_buff, /*;AN000;*/ + (WORD)&noval, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_control_blk p_swi1 = /*;AN000; Switch control block */ + { 0x0001, /*;AN000; Optional (switch) */ + 0x0002, /*;AN000; Cap result by char table */ + (WORD)&sw_buff, /*;AN000;*/ + (WORD)&noval, /*;AN000;*/ + 1, /*;AN000; one switch allowed */ + "/S" }; /*;AN000; /S */ + +struct p_parmsx p_px1 = /*;AN000; Parser Control definition for Parm Block 1 */ + { 1, /*;AN000; positionals */ + 6, /*;AN000;*/ + &p_con1, /*;AN000;*/ + &p_con2, /*;AN000;*/ + &p_con3, /*;AN000;*/ + &p_con4, /*;AN000;*/ + &p_con5, /*;AN000;*/ + &p_con6, /*;AN000;*/ + 1, /*;AN000; switches */ + &p_swi1, /*;AN000;*/ + 0, /*;AN000; keywords*/ + 0, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_parms p_p1 = /*;AN000; Parms block for line */ + { &p_px1, /*;AN000; Address of extended parm list */ + 0, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_parmsx p_px2 = /*;AN000; Parser Control definition for Parm Block 1 */ + { 1, /*;AN000; positionals */ + 2, /*;AN000;*/ + &p_con6a, /*;AN000;*/ + &p_con6b, /*;AN000;*/ + 0, /*;AN000;*/ + 0, /*;AN000;*/ + 0, /*;AN000;*/ + 0, /*;AN000;*/ + 1, /*;AN000; switches */ + &p_swi1, /*;AN000;*/ + 0, /*;AN000; keywords*/ + 0, /*;AN000;*/ + 0, /*;AN000;*/ + 0 }; /*;AN000;*/ + +struct p_parms p_p2 = /*;AN000; Parms block for line */ + { &p_px2, /*;AN000; Address of extended parm list */ + 1, /*;AN000;*/ + 1, /*;AN000;*/ + "=" }; /*;AN000;*/ + +/* extended open structure variables */ +struct parm_list plist = /*;AN000; Extended open parm list */ + { -1, /*;AN000; ptr to attr. list */ + 1, /*;AN000; number of parms */ + 6, /*;AN000; id */ + 2 }; /*;AN000; iomode */ + +/* messgages */ +struct m_sublist msg_num = /*;AN000; describes substitutions */ + { 72, /*;AN000; for parm one of message */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 1, /*;AN000; */ + sf_unsbin2d | sf_right, /*;AN000; unsigned binary to decimal*/ + 9, /*;AN000; */ + 9, /*;AN000; */ + 0 }; /*;AN000; */ +struct m_sublist msg_str2 = /*;AN000; describes substitutions */ + { 60, /*;AN000; for parm one of message */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 1, /*;AN000; */ + sf_left | sf_char | sf_asciiz, /*;AN000; string */ + 0, /*;AN000; null string */ + 0, /*;AN000; */ + (BYTE)" " }; /*;AN000; */ +struct m_sublist msg_dword = /*;AN000; describes substitutions */ + { 48, /*;AN000; for parm one of message */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 1, /*;AN000; */ + sf_unsbin2d | sf_dword | sf_right, /*;AN000; unsigned binary to decimal*/ + 10, /*;AN000; */ + 9, /*;AN000; */ + 0 }; /*;AN000; */ +struct m_sublist msg_date = /*;AN000; describes substitutions */ + { 36, /*;AN000; for parm one of message */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 1, /*;AN000; */ + sf_date | sf_mdy2, /*;AN000; unsigned binary to decimal*/ + 9, /*;AN000; */ + 9, /*;AN000; */ + 0 }; /*;AN000; */ +struct m_sublist msg_time = /*;AN000; describes substitutions */ + { 24, /*;AN000; for parm one of message */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 1, /*;AN000; */ + sf_time12 | sf_hhmm | sf_right, /*;AN000; unsigned binary to decimal*/ + 9, /*;AN000; NN-NN-NNa (9 characters) */ + 9, /*;AN000; */ + 0 }; /*;AN000; */ +struct m_sublist msg_str = /*;AN000; describes substitutions */ + { 12, /*;AN000; for parm one of message */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 1, /*;AN000; */ + sf_left | sf_char | sf_asciiz, /*;AN000; string */ + 9, /*;AN000; null string */ + 9, /*;AN000; */ + (BYTE)" " }; /*;AN000; */ +struct m_sublist msg_str1 = /*;AN000; describes substitutions */ + { 12, /*;AN000; for parm two of message */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 2, /*;AN000; */ + sf_left | sf_char | sf_asciiz, /*;AN000; string */ + 0, /*;AN000; null string */ + 0, /*;AN000; */ + (BYTE)" " }; /*;AN000; */ +struct m_sublist msg_error = /*;AN000; describes substitutions */ + { 12, /*;AN000; for extended error messages*/ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + 0, /*;AN000; */ + sf_left | sf_char | sf_asciiz, /*;AN000; string */ + 0, /*;AN000; null string */ + 0, /*;AN000; */ + (BYTE)" " }; /*;AN000; */ + +/* misc. variables */ +union REGS inregs, /*;AN000; Registers */ + outregs; /*;AN000;*/ +struct SREGS segregs; /*;AN000; Segment registers */ + +DWORD old_int24_off; /*;AN000;*/ + +WORD descending; /*;AN000;*/ +WORD append_x_status; /*;AN000;*/ +WORD did_attrib_ok; /*;AN000;*/ +WORD set_reg_attr, /*;AN000;*/ + set_ext_attr; /*;AN000;*/ +WORD do_reg_attr, /*;AN000;*/ + do_ext_attr; /*;AN000;*/ + +BYTE far *DBCS_ptr; /*;AN000;*/ +BYTE ext_attr_value_type; /*;AN000;*/ +BYTE attr; /*;AN000;*/ +BYTE bits[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; /*;AN000;*/ +BYTE pmask, /*;AN000;*/ + mmask; /*;AN000;*/ + +char as[8] = { ' ',' ','A',' ',' ',' ',' ','R' }; /*;AN000;*/ +char fix_es_reg[1]; /*;AN000;*/ +char ext_attr[MAX_KEYWORD]; /*;AN000;*/ +char error_file_name[256]; /*;AN005;*/ +char fspec[256]; /*;AN000;*/ +char file[256]; /*;AN000;*/ +char str_on[3] = {"ON"}; /*;AN000;*/ +char str_off[4] = {"OFF"}; /*;AN000;*/ diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.LNK b/v4.0/src/CMD/ATTRIB/ATTRIB.LNK new file mode 100644 index 0000000..89de3bf --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/ATTRIB.LNK @@ -0,0 +1,7 @@ +attriba+ +attrib+ +_parse+ +_msgret +attrib +nul; + diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.SKL b/v4.0/src/CMD/ATTRIB/ATTRIB.SKL new file mode 100644 index 0000000..aab62fa --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/ATTRIB.SKL @@ -0,0 +1,30 @@ +:util ATTRIB ;utility name ;AN000; + +:class 1 ;AN000; + +:class 2 ;AN000; + +:class A ;system messages ;AN000; +:use 1 COMMON1 ;"Incorrect DOS version" ;AN000; +:use 2 EXTEND8 ;"Insufficient memory" ;AN000; + +:class B ;AN000; +:def 8 " %1" ;AN000; +:def 9 "%1 %2",CR,LF ;AN000; +:def 10 "%1",CR,LF,"%2",CR,LF ;AN000; +:def 11 "Code page mismatch - %1",CR,LF,"Are you sure (Y/N)?" ;AN000; +:def 12 "%1",CR,LF ;AN000; +:def 14 CR,LF ;AN000; +:def 15 "Invalid file type value",CR,LF ;AN000; + +;;; Change these extended attribute error msgs back when adding ext. attr. +;;; function in DOS. +;;;:def 199 "Extended attribute error",CR,LF ;AN000; +;;;:def 201 "Extended attribute name not found",CR,LF ;AN000; +;;;:use 202 EXTEND8 ;"Insufficient memory" ;AN000; +;;;:def 204 "Extended attribute name can't be set",CR,LF ;AN000; +;;;:def 205 "Extended attribute name known to this filesystem but not supported",CR,LF ;AN000; +;;;:def 206 "Extended attribute type mismatch",CR,LF ;AN000; +;;;:def 208 "Extended attribute value not supported",CR,LF ;AN000; + +:end ;AN000; diff --git a/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM b/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM new file mode 100644 index 0000000..4f9c312 --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM @@ -0,0 +1,480 @@ + page ,132 ; + title New_C.C - DOS entry to the KWC's 'C' programs + +; +; This module has been modified extensively for my personal +; use. +; +; name XCMAIN -- initiate execution of C program +; +; description This is the main module for a C program on the +; DOS implementation. It initializes the segment +; registers, sets up the stack, and calls the C main +; function _main with a pointer to the remainder of +; the command line. +; +; Also defined in this module is the exit entry point +; XCEXIT. +; +; $salut (4,12,18,41) +SETBLOCK EQU 4AH ;MODIFY ALLOCATED MEMORY BLOCKS + ;ES = SEGMENT OF THE BLOCK + ;BX = NEW REQUESTED BLOCK SIZE + ; IN PARAGRAPHS + ;OUTPUT: BX=MAX SIZE POSSIBLE IF CY SET + ;AX = ERROR CODE IF CY SET + +RET_CD_EXIT EQU 4CH ;EXIT TO DOS, PASSING RETURN CODE + ;AL=RETURN CODE + +RET_EXIT equ 4ch ;AN000; ;terminate +ABORT equ 2 ;AN000; ;if >=, retry +XABORT equ 1 ;AN000; ;errorlevel return in al + + + extrn _inmain:near ;AC000; + extrn _Reset_appendx:near ;AN000; + extrn _old_int24_off:dword ;AN000; + + +psp segment at 0 ;<--emk +psp_ret dw ? ;int 20h +psp_memsz dw ? ;memory size + org 2ch +psp_env dw ? ;segid of environment + org 80h +psp_parlen db ? ;length of DOS command line parms +psp_par db 127 dup(?) ;DOS command line parms +psp ends + page + +; +; The following segment serves only to force "pgroup" lower in +; memory. +; + +base segment PARA PUBLIC 'DATA' + + db 00dh,00ah + db "----------\x0d\x0a" + db " DOS ATTRIB function \x0d\x0a" + db "--------------------\x0d\x0a" + db 00dh,00ah,01ah + +base ends + + +; +; The data segment defines locations which contain the offsets +; of the base and top of the stack. +; + +_data segment PARA public 'DATA' + + irp name,<_top,_base,_cs,_ss,_psp,_env,_rax,_rbx,_rcx,_rdx,_rds,_rsi,_rbp,_res,_rdi> + public name +name dw 0 + endm + +_data ends + +; +; The stack segment is included to prevent the warning from the +; linker, and also to define the base (lowest address) of the stack. +; + +stack segment PARA stack 'data' + +SBase dw 128 dup (?) + +stack ends + +null segment para public 'BEGDATA' +null ends +const segment word public 'CONST' +const ends +_bss segment word public 'BSS' +_bss ends +pgroup group base,_text +dgroup group null, _data, const, _bss, stack + + page + +; +; The main program must set up the initial segment registers +; and the stack pointer, and set up a far return to the DOS +; exit point at ES:0. The command line bytes from the program +; segment prefix are moved onto the stack, and a pointer to +; them supplied to the C main module _main (which calls main). +; + +_text segment PARA public 'CODE' + + public XCMAIN + + assume cs:pgroup + assume ds:psp ;<--emk + assume es:psp ;<--emk + assume ss:stack ;<--emk + +XCMAIN proc far + + mov ax,dgroup + mov ds,ax ;initialize ds and ss + assume ds:dgroup + + mov bx,psp_memsz ;total memory size (paragraphs) + sub bx,ax + test bx,0f000h +; $IF Z ;branch if more than or equal 64K bytes + JNZ $$IF1 + + mov cl,4 + shl bx,cl ;highest available byte +; $ELSE + JMP SHORT $$EN1 +$$IF1: + mov bx,0fff0h +; $ENDIF +$$EN1: + cli ; disable interrupts while changing stack <---kwc + mov ss,ax ; set ss <---kwc + mov sp,bx ; set stack pointer <---kwc + sti ;enable interrupts + assume ss:DGroup ;<--emk + + mov _ss,ss + mov _cs,cs + mov _top,bx ;save top of stack + + mov ax,offset DGroup:SBase + mov _base,ax ;store ptr to bottom of stack + +; code added here to allow allocates and exec's in the c code +; we will have to calculate the size of the code that has been loaded + + mov bx,sp ; bx = length of the stack + shr bx,1 + shr bx,1 + shr bx,1 + shr bx,1 ; bx = number of paragraphs in stack, + add bx,1 ; (fudge factor!)<--emk ,was 10 + mov ax,ss + add bx,ax ; bx = paragraph a little past the stack + mov ax,es ; ax = paragraph of the psp + sub bx,ax ; bx = number of paragraphs in code + mov ah,setblock + int 021h + +; end of added code! + + mov _psp,es ; save pointer to psp for setblock <---kwc + mov cl,psp_parlen ;get number of bytes <--emk + xor ch,ch ;cx = number of bytes of parms! + mov si,offset psp_par ;point to DOS command line parms <--emk + +; more modified code, picking up argv[0] from the environment! + + mov ds,psp_env ;set ds to segid of environment from es:psp + assume ds:nothing + + mov _env,ds ;remember where environment is + + mov si,0 ;clear index to step thru env +;The env has a set of keyword=operand, each one ending with a single null byte. +;At the end of the last one is a double null. We are looking for the end of +;all these keywords, by looking for the double null. +; $DO COMPLEX + JMP SHORT $$SD4 +$$DO4: + inc si ;bump index to look at next byte in env +; $STRTDO +$$SD4: + cmp word ptr [si],0 ;is this a double null delimiter? +; $ENDDO E ;ifdouble null found, exit + JNE $$DO4 +;At end of env is the double null and a word counter + add si,4 ;step over this double null delimiter + ; and the following word counter + push si ;save pointer to next field in env +;This is the invocation statement, including the path name, even if not specified +;but supplied by PATH. + +;continue stepping thru env looking for one more null byte, which indicates +;the end of the invocation command. +; $DO +$$DO7: + lodsb ;get a byte from env to al + cmp al,0 ;is this a null byte? +; $ENDDO E ;quit if null is found + JNE $$DO7 + + mov bx,si ; bx -> asciiz zero + pop si ; si -> first byte of agrv[0], the invocation command + sub bx,si ; bx = length of argv[0] + mov dx,bx ; (save for the copy later) + dec dx + add bx,cx ; add in the length of the rest of the parms + inc bx ; add one for the asciiz zero! + and bx,0fffeh ;force even number of bytes + add bx,2 ;adjust for possible rounding error + sub sp,bx ;allocate space on stack + mov di,sp ; (es:di) -> where we will put the stuff + push es + mov ax,ss + mov es,ax + xchg cx,dx ; length of argv[0] to copy, save length of parms + rep movsb ; (ds:si) already point to argv[0] + pop es + mov ss:byte ptr [di],' ' ;store trailing blank! + inc di + mov _rdi,di ;AN000; save start of command parms + xchg cx,dx ; restore length of parms +; $IF NCXZ ;if some bytes to move, + JCXZ $$IF9 + + mov si,offset psp_par ;point to DOS command line parms in psp +; $DO +$$DO10: + mov al,es:[si] ;move bytes to stack + mov ss:[di],al + inc si + inc di +; $ENDDO LOOP + LOOP $$DO10 +; $ENDIF ;bytes to move? +$$IF9: + xor ax,ax + mov ss:[di],al ;store null byte + mov ax,ss + mov ds,ax ;es, ds, and ss are all equal + assume ds:DGroup + + mov es,ax ;es, ds, and ss are all equal + assume es:DGroup + + mov ax,_rdi ;AN000; restore offset of parms on stack + push ax ;ptr to command line + + call _inmain ;AC000; call C main + + mov ah,ret_cd_exit ;return to DOS + int 21h ;errorlevel ret code in al + +XCMAIN endp + + page + +; +; name XCEXIT -- terminate execution of C program +; +; description This function terminates execution of the current +; program by returning to DOS. The error code +; argument normally supplied to XCEXIT is ignored +; in this implementation. +; +; input - al = binary return code for dos/ERRORLEVEL +; + + assume cs:PGroup + assume ds:DGroup + assume es:DGroup + assume ss:DGroup + + public xcexit +XCEXIT proc far + + mov ah,ret_cd_exit ; <--- kwc + int 021h ; <--- kwc + +XCEXIT endp + +;-------------------------------------------------------------------------- + + PAGE + +CENTER MACRO NAMELIST + PUSH BP ; SAVE CURRENT BP + MOV BP,SP ; POINT AT STACK WITH BP +WORKOFS = 0 + IRP ANAME, ; FOR EACH WORKING VARIABLE + IFNB <&ANAME> +WORKOFS = WORKOFS-2 ; WE WILL ALLOCATE ONE + DOEQU &ANAME,%WORKOFS ; WORD ON THE STACK THAT + ENDIF + ENDM ; IS UNDER SS,BP + ADD SP,WORKOFS + ENDM + +DOEQU MACRO NAME,VALUE +&NAME EQU &VALUE + ENDM + +CEXIT MACRO VALUE + MOV SP,BP + POP BP + RET + ENDM + + PAGE + +; INPUT PARAMATERS PASSED ON STACK + +PARMS STRUC + +OLD_BP DW ? ; SAVED BP +RETADD DW ? ; RETURN ADDRESS +PARM_1 DW ? +PARM_2 DW ? +PARM_3 DW ? +PARM_4 DW ? +PARM_5 DW ? +PARM_6 DW ? +PARM_7 DW ? +PARM_8 DW ? + +PARMS ENDS + +SAVE_SS DW 0 +SAVE_SP DW 0 + + PAGE + +;************************************************************************ +; ; +; Subroutine Name: ; +; getpspbyte ; +; ; +; Subroutine Function: ; +; get a byte from PSP ; ; +; ; +; Input: ; +; SS:[BP]+PARM1 = offset in PSP ; +; ; +; Output: ; +; AL = byte from PSP:offset ; +; ; +; C calling convention: ; +; char = getpspbyte(offset); ; +; ; +;************************************************************************ + +MOFFSET EQU PARM_1 ;AN000; + + ASSUME CS:PGROUP ;AN000; + ASSUME DS:DGROUP ;AN000; + ASSUME ES:DGROUP ;AN000; + ASSUME SS:DGROUP ;AN000; + + PUBLIC _GETPSPBYTE ;AN000; +_GETPSPBYTE PROC NEAR ;AN000; + + CENTER ;AN000; + + PUSH DS ;AN000; + + MOV DS,_PSP ;AN000; get save PSP segment + MOV SI,[BP].MOFFSET ;AN000; get offset into PSP + LODSB ;AN000; get PSP byte + MOV AH,0 ;AN000; zero high byte + + POP DS ;AN000; + + CEXIT ;AN000; + +_GETPSPBYTE ENDP + + +;************************************************************************ +; ; +; Subroutine Name: ; +; putpspbyte ; +; ; +; Subroutine Function: ; +; put a byte into PSP ; ; +; ; +; Input: ; +; SS:[BP]+MVALUE = byte in AL ; +; SS:[BP]+MOFFSET = offset in PSP ; +; ; +; Output: ; +; none ; +; ; +; C calling convention: ; +; putpspbyte(offset,char); ; +; ; +;************************************************************************ + + +MVALUE EQU PARM_2 ;AN000; +MOFFSET EQU PARM_1 ;AN000; + + ASSUME CS:PGROUP ;AN000; + ASSUME DS:DGROUP ;AN000; + ASSUME ES:DGROUP ;AN000; + ASSUME SS:DGROUP ;AN000; + + PUBLIC _PUTPSPBYTE ;AN000; +_PUTPSPBYTE PROC NEAR ;AN000; + + CENTER ;AN000; + + PUSH ES ;AN000; + + MOV AX,[BP].MVALUE ;AN000; get byte to store in PSP + MOV ES,_PSP ;AN000; get saved PSP segment + MOV DI,[BP].MOFFSET ;AN000; get offset in PSP + STOSB ;AN000; store the byte + + POP ES ;AN000; + + CEXIT ;AN000; + +_PUTPSPBYTE ENDP + + +;------------------------------------------------------------------- +; +; MODULE: crit_err_handler() +; +; PURPOSE: Supplies assembler exit routines for +; critical error situations +; +; CALLING FORMAT: +; crit_err_handler; +;------------------------------------------------------------------- + public _crit_err_handler ;AN000; + public vector ;AN000; +vector dd 0 ;AN000; +; ;AN000; +_crit_err_handler proc near ;AN000; + pushf ;AN000; + push ax ; save registers ;AN000; + push ds ;AN000; + mov ax,dgroup ;get C data segment ;AN000; + mov ds,ax ;AN000; + mov ax,word ptr ds:_old_int24_off ;get int24 offset ;AN000; + mov word ptr cs:vector,ax ;AN000; + mov ax,word ptr ds:_old_int24_off+2 ;get int24 segment ;AN000; + mov word ptr cs:vector+2,ax ;AN000; + pop ds ;restore registers ;AN000; + pop ax ;AN000; +; ;AN000; + call dword ptr cs:vector ; invoke DOS err hndlr ;AN000; + cmp al,ABORT ; what was the user's response ;AN000; + jnge retry ; ;AN000; +; ;AN000; + mov ax,dgroup ;get C data segment ;AN000; + mov ds,ax ;AN000; + mov es,ax ;AN000; + call _Reset_appendx ; restore user's orig append/x ;AN000; +; ;AN000; + mov ax,(RET_EXIT shl 8)+XABORT ; return to DOS w/criterr error ;AN000; + int 21h ; ;AN000; +retry: ;AN000; + iret ;AN000; +; ;AN000; +_crit_err_handler endp ;AN000; +_text ends ;AN000; + end XCMAIN ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/ATTRIB/MAKEFILE b/v4.0/src/CMD/ATTRIB/MAKEFILE new file mode 100644 index 0000000..a9e670a --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/MAKEFILE @@ -0,0 +1,46 @@ +#************************** makefile for cmd\append *************************** + +msg =..\..\messages +dos =..\..\dos +inc =..\..\inc +hinc =..\..\h + +# +####################### dependencies begin here. ######################### +# + +all: attrib.exe + +attrib.ctl: attrib.skl \ + $(msg)\$(COUNTRY).msg \ + makefile + +_parse.obj: _parse.asm \ + $(inc)\parse.asm \ + $(inc)\psdata.inc + +_msgret.obj: _msgret.asm \ + $(inc)\msgserv.asm \ + $(inc)\sysmsg.inc \ + $(inc)\copyrigh.inc \ + attrib.skl \ + attrib.ctl \ + attrib.cl1 \ + attrib.cl2 \ + attrib.cla \ + attrib.clb + +attriba.obj: attriba.asm + +attrib.obj: attrib.c \ + attrib.h \ + parse.h \ + msgret.h \ + makefile + +attrib.exe: attrib.obj \ + attriba.obj \ + _parse.obj \ + _msgret.obj \ + attrib.lnk + link @attrib.lnk diff --git a/v4.0/src/CMD/ATTRIB/MSGRET.H b/v4.0/src/CMD/ATTRIB/MSGRET.H new file mode 100644 index 0000000..0f00329 --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/MSGRET.H @@ -0,0 +1,60 @@ +/*  */ +/*----------------------------------------------------------------------+ +| | +| This file contains the structures and defines that are needed to use | +| the message retriever from a C program. | +| | +| | +| Date: 6-19-87 | +| | ++----------------------------------------------------------------------*/ + + +#define utility_msg_class 0xff /*;AN000; Utility message type */ +#define exterr_msg_class 0x01 /*;AN000;*/ + + +/* Sublist Flag Values */ + +/* Alignment Indicator */ +#define sf_left 0x00 /*;AN000; left align */ +#define sf_right 0x80 /*;AN000; right align */ + +/* Field Type */ +#define sf_char 0x00 /*;AN000; character */ +#define sf_unsbin2d 0x01 /*;AN000; unsigned binary to decimal */ +#define sf_sbin 0x02 /*;AN000; signed binary to decimal */ +#define sf_unsbin2h 0x03 /*;AN000; unsigned binary to hex */ +#define sf_date 0x04 /*;AN000; date */ +#define sf_time12 0x05 /*;AN000; time 12-hour */ +#define sf_time24 0x06 /*;AN000; time 24-hour */ + + +/* Data Variable Size */ + +#define sf_ch 0x00 /*;AN000; single character */ +#define sf_asciiz 0x10 /*;AN000; asciiz string */ +#define sf_byte 0x10 /*;AN000; byte */ +#define sf_word 0x20 /*;AN000; word */ +#define sf_dword 0x30 /*;AN000; double word */ + +#define sf_mdy2 0x20 /*;AN000; month,day,year (2 digits) */ +#define sf_mdy4 0x30 /*;AN000; month,day,year (4 digits) */ + +#define sf_hhmm 0x00 /*;AN000; hh:mm */ +#define sf_hhmmss 0x10 /*;AN000; hh:mm:ss */ +#define sf_hhmmsshh 0x20 /*;AN000; hh:mm:ss:hh */ + + +struct m_sublist /*;AN000; */ + { /*;AN000; */ + BYTE sub_size; /*;AN000; */ + BYTE sub_res; /*;AN000; */ + WORD sub_value; /*;AN000; */ + WORD sub_value_seg; /*;AN000; */ + BYTE sub_id; /*;AN000; */ + BYTE sub_flags; /*;AN000; */ + BYTE sub_max_width; /*;AN000; */ + BYTE sub_min_width; /*;AN000; */ + BYTE sub_pad_char; /*;AN000; */ + }; /*;AN000; */ diff --git a/v4.0/src/CMD/ATTRIB/PARSE.H b/v4.0/src/CMD/ATTRIB/PARSE.H new file mode 100644 index 0000000..2421481 --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/PARSE.H @@ -0,0 +1,185 @@ +/*  */ +/*----------------------------------------------------------------------+ +| | +| This file contains the structures and defines that are needed to use | +| the parser from a C program. | +| | +| | +| Date: 5-21-87 | +| | ++----------------------------------------------------------------------*/ + +#define BYTE unsigned char /*;AN000;*/ +#define WORD unsigned short /*;AN000;*/ +#define DWORD unsigned long /*;AN000;*/ + +#define p_len_parms 4 /* length of p_parms */ /*;AN000;*/ +#define p_i_use_default 0 /* no extra stuff specified */ /*;AN000;*/ +#define p_i_have_delim 1 /* extra delimiter specified */ /*;AN000;*/ +#define p_i_have_eol 2 /* extra EOL specified */ /*;AN000;*/ + +struct p_parms /*;AN000;*/ + { /*;AN000;*/ + struct p_parmsx *p_parmsx_address; /* address of p_parmsx */ /*;AN000;*/ + BYTE p_num_extra; /* number of extra stuff */ /*;AN000;*/ + BYTE p_len_extra_delim; /* length of extra delimiter */ /*;AN000;*/ + char p_extra_delim[30]; /* extra delimiters */ /*;AN000;*/ + }; /*;AN000;*/ + +struct p_parmsx /*;AN000;*/ + { /*;AN000;*/ + BYTE p_minp; /* Minimum positional number */ /*;AN000;*/ + BYTE p_maxp; /* Maximum positional number */ /*;AN000;*/ + struct p_control_blk *p_control1; /* Address of the 1st CONTROL block */ /*;AN000;*/ + struct p_control_blk *p_control2; /* Address of the 2nd CONTROL block */ /*;AN000;*/ + struct p_control_blk *p_control3; /* Address of the 3nd CONTROL block */ /*;AN000;*/ + struct p_control_blk *p_control4; /* Address of the 4th CONTROL block */ /*;AN000;*/ + struct p_control_blk *p_control5; /* Address of the 3nd CONTROL block */ /*;AN000;*/ + struct p_control_blk *p_control6; /* Address of the 4th CONTROL block */ /*;AN000;*/ + BYTE p_maxs; /*;AN000;*/ + struct p_control_blk *p_switch; /*;AN000;*/ + BYTE p_maxk; /*;AN000;*/ + struct p_control_blk *p_keyword1; /*;AN000;*/ + struct p_control_blk *p_keyword2; /*;AN000;*/ + struct p_control_blk *p_keyword3; /*;AN000;*/ + }; /*;AN000;*/ + +struct p_control_blk /*;AN000;*/ + { /*;AN000;*/ + WORD p_match_flag; /* Controls type matched */ /*;AN000;*/ + WORD p_function_flag; /* Function should be taken */ /*;AN000;*/ + WORD p_result_buf; /* Result buffer address */ /*;AN000;*/ + WORD p_value_list; /* Value list address */ /*;AN000;*/ + BYTE p_nid; /* # of keyword/SW synonyms */ /*;AN000;*/ + char p_keyorsw[20]; /* keyword or sw */ /*;AN000;*/ + }; /*;AN000;*/ + +/* Match_Flags */ /*;AN000;*/ +#define p_num_val 0x8000 /* Numeric Value */ /*;AN000;*/ +#define p_snum_val 0x4000 /* Signed numeric value */ /*;AN000;*/ +#define p_simple_s 0x2000 /* Simple string */ /*;AN000;*/ +#define p_date_s 0x1000 /* Date string */ /*;AN000;*/ +#define p_time_s 0x0800 /* Time string */ /*;AN000;*/ +#define p_cmpx_s 0x0400 /* Complex string */ /*;AN000;*/ +#define p_file_spc 0x0200 /* File Spec */ /*;AN000;*/ +#define p_drv_only 0x0100 /* Drive Only */ /*;AN000;*/ +#define p_qu_string 0x0080 /* Quoted string */ /*;AN000;*/ +#define p_ig_colon 0x0010 /* Ignore colon at end in match */ /*;AN000;*/ +#define p_repeat 0x0002 /* Repeat allowed */ /*;AN000;*/ +#define p_optional 0x0001 /* Optional */ /*;AN000;*/ + +/*----------------------------------------------------------------------+ +| | +| Function flags | +| | ++----------------------------------------------------------------------*/ + +#define p_cap_file 0x0001 /* CAP result by file table */ /*;AN000;*/ +#define p_cap_char 0x0002 /* CAP result by character table */ /*;AN000;*/ +#define p_rm_colon 0x0010 /* Remove ":" at the end */ /*;AN000;*/ + +#define p_nval_none 0 /* no value list ID */ /*;AN000;*/ +#define p_nval_range 1 /* range list ID */ /*;AN000;*/ +#define p_nval_value 2 /* value list ID */ /*;AN000;*/ +#define p_nval_string 3 /* string list ID */ /*;AN000;*/ +#define p_len_range 9 /* Length of a range choice(two DD plus one DB) */ /*;AN000;*/ +#define p_len_value 5 /* Length of a value choice(one DD plus one DB) */ /*;AN000;*/ +#define p_len_string 3 /* Length of a string choice(one DW plus one DB) */ /*;AN000;*/ + +/*----------------------------------------------------------------------+ +| | +| Result block structure | +| | ++----------------------------------------------------------------------*/ + +struct p_result_blk /*;AN000;*/ + { /*;AN000;*/ + BYTE p_type; /* Type returned */ /*;AN000;*/ + BYTE p_item_tag; /* Matched item tag */ /*;AN000;*/ + WORD p_synonym_ptr; /* pointer to Synonym list returned */ /*;AN000;*/ + WORD p_result_buff[2]; /* result value */ /*;AN000;*/ + }; /*;AN000;*/ + +/*----------------------------------------------------------------------+ +| | +| type | +| | ++----------------------------------------------------------------------*/ + +#define p_eol 0 /* End of line */ /*;AN000;*/ +#define p_number 1 /* Number */ /*;AN000;*/ +#define p_list_idx 2 /* List Index */ /*;AN000;*/ +#define p_string 3 /* String */ /*;AN000;*/ +#define p_complex 4 /* Complex */ /*;AN000;*/ +#define p_file_spec 5 /* File Spec */ /*;AN000;*/ +#define p_drive 6 /* Drive */ /*;AN000;*/ +#define p_date_f 7 /* Date */ /*;AN000;*/ +#define p_time_f 8 /* Time */ /*;AN000;*/ +#define p_quoted_string 9 /* Quoted String */ /*;AN000;*/ + +#define p_no_tag 0x0FF /* No ITEM_TAG found */ /*;AN000;*/ + +/*----------------------------------------------------------------------+ +| | +| following return code will be returned in the AX register. | +| | ++----------------------------------------------------------------------*/ + +#define p_no_error 0 /* No error */ /*;AN000;*/ +#define p_too_many 1 /* Too many operands */ /*;AN000;*/ +#define p_op_missing 2 /* Required operand missing */ /*;AN000;*/ +#define p_not_in_sw 3 /* Not in switch list provided */ /*;AN000;*/ +#define p_not_in_key 4 /* Not in keyword list provided */ /*;AN000;*/ +#define p_out_of_range 6 /* Out of range specified */ /*;AN000;*/ +#define p_not_in_val 7 /* Not in value list provided */ /*;AN000;*/ +#define p_not_in_str 8 /* Not in string list provided */ /*;AN000;*/ +#define p_syntax 9 /* Syntax error */ /*;AN000;*/ +#define p_rc_eol 0x0ffff /* End of command line */ /*;AN000;*/ + +/*----------------------------------------------------------------------+ +| | +| String Value List Block Structure | +| | ++----------------------------------------------------------------------*/ + +struct ps_valist_blk /*;AN000;*/ + { /*;AN000;*/ + BYTE ps_val; /* Value type */ /*;AN000;*/ + BYTE ps_nrng; /* Number of ranges */ /*;AN000;*/ + BYTE ps_nnval; /* Number of numbers */ /*;AN000;*/ + BYTE ps_nstrval; /* Number of strings */ /*;AN000;*/ + BYTE ps_item_tag1; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings1; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag2; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings2; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag3; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings3; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag4; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings4; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag5; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings5; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag6; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings6; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag7; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings7; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag8; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings8; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag9; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings9; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag10; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings10; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag11; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings11; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag12; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings12; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag13; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings13; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag14; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings14; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag15; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings15; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag16; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings16; /* Address of strings */ /*;AN000;*/ + BYTE ps_item_tag17; /* Matched item tag */ /*;AN000;*/ + WORD ps_strings17; /* Address of strings */ /*;AN000;*/ + }; /*;AN000;*/ diff --git a/v4.0/src/CMD/ATTRIB/_MSGRET.ASM b/v4.0/src/CMD/ATTRIB/_MSGRET.ASM new file mode 100644 index 0000000..7acb51e --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/_MSGRET.ASM @@ -0,0 +1,233 @@ +page 60,132 ;AN000; +name _msgret ;AN000; +title C to Message Retriever ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;AN000; +; MODULE: _msgret ;AN000; +; ;AN000; +; PURPOSE: Supplies an interface between C programs and ;AN000; +; the DOS message retriever ;AN000; +; ;AN000; +; CALLING FORMAT: ;AN000; +; sysloadmsg(&inregs,&outregs); ;AN000; +; sysgetmsg(&inregs,&outregs); ;AN000; +; sysdispmsg(&inregs,&outregs); ;AN000; +; ;AN000; +; ;AN000; +; DATE: 5-21-87 ;AN000; +; Modified: 6/18/87 ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;AN000; + INCLUDE SYSMSG.INC ;PERMIT SYSTEM MESSAGE HANDLER DEFINITION ;AN000; +; ;AN000; + MSG_UTILNAME ;IDENTIFY THE COMPONENT ;AN000; +; ;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; +; ;AN000; + public _sysloadmsg ;AN000; + public _sysgetmsg ;AN000; + public _sysdispmsg ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;AN000; +_DATA segment ;AN000; +.XLIST ;AN000; +.XCREF ;AN000; +; MSG_SERVICES ;DATA AREA FOR THE MESSAGE HANDLER ;AN000; + MSG_SERVICES ;DATA AREA FOR THE MESSAGE HANDLER ;AN000; +.LIST ;AN000; +.CREF ;AN000; +_DATA ends ;AN000; +; ;AN000; +; ;AN000; +_TEXT segment ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;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 ;AN000; + MSG_SERVICES ;MSG TEXT ;AN000; +.LIST ;AN000; +.CREF ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;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; +; ;AN000; +; copy C inregs into proper registers ;AN000; +; ;AN000; + mov di,[bp+4] ; fix di (arg 0) ;AN000; +; ;AN000; + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack ;AN000; +; ;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; +; ;AN000; + push bp ; save base pointer ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; + call sysloadmsg ; call the message retriever ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;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; +; ;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; +; ;AN000; + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; +; ;AN000; + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; +; ;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; +; ;AN000; +; ;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 ;AN000; +; ;AN000; + mov di,[bp+4] ; fix di (arg 0) ;AN000; +; ;AN000; + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack ;AN000; +; ;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; +; ;AN000; + push bp ; save base pointer ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; + call sysgetmsg ; call the message retriever ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;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; +; ;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; +; ;AN000; + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; +; ;AN000; + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; +; ;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; +; ;AN000; +; ;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; +; ;AN000; +; copy C inregs into proper registers ;AN000; +; ;AN000; + mov di,[bp+4] ; fix di (arg 0) ;AN000; +; ;AN000; + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack ;AN000; +; ;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; +; ;AN000; + push bp ; save base pointer ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; + call sysdispmsg ; call the message retriever ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;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; +; ;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; +; ;AN000; + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; +; ;AN000; + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; +; ;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; +; ;AN000; +; ;AN000; +_TEXT ends ; end code segment ;AN000; + + include msgdcl.inc + + end ;AN000; + \ No newline at end of file diff --git a/v4.0/src/CMD/ATTRIB/_PARSE.ASM b/v4.0/src/CMD/ATTRIB/_PARSE.ASM new file mode 100644 index 0000000..9800c9e --- /dev/null +++ b/v4.0/src/CMD/ATTRIB/_PARSE.ASM @@ -0,0 +1,107 @@ +page 60,132 ;AN000; +name _parse ;AN000; +title C to PARSER interface ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;AN000; +; MODULE: _parse ;AN000; +; ;AN000; +; PURPOSE: Supplies an interface between C programs and ;AN000; +; the DOS parser ;AN000; +; ;AN000; +; CALLING FORMAT: ;AN000; +; parse(&inregs,&outregs); ;AN000; +; ;AN000; +; DATE: 5-21-87 ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;AN000; +; extrn sysparse:far ;AN000; +; ;AN000; + public _parse ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; +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 1 ; Check numeric value ;AN000; +KeySW equ 1 ; Support keywords ;AN000; +SwSW equ 1 ; Support switches ;AN000; +Val1SW equ 1 ; Support value definition 1 ;AN000; +Val2SW equ 1 ; Support value definition 2 ;AN000; +Val3SW equ 1 ; Support value definition 3 ;AN000; +DrvSW equ 0 ; Support drive only format ;AN000; +QusSW equ 1 ; Support quoted string format ;AN000; +;------------------------------------------------------------------- ;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; +;------------------------------------------------------------------- ;AN000; +.xlist ;AN000; +include parse.asm ; include the parser ;AN000; +.list ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;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; +; ;AN000; +; copy C inregs into proper registers ;AN000; +; ;AN000; + mov di,[bp+4] ; fix di (arg 0) ;AN000; +; ;AN000; + mov ax,[di+0ah] ; load di ;AN000; + push ax ; the di value from inregs is now on stack ;AN000; +; ;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; +; ;AN000; + push bp ; save base pointer ;AN000; +; ;AN000; +;------------------------------------------------------------------- ;AN000; + call sysparse ; call the parser ;AN000; +;------------------------------------------------------------------- ;AN000; +; ;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; +; ;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; +; ;AN000; + lahf ; get flags into ax ;AN000; + mov al,ah ; move into low byte ;AN000; + mov [di+0ch],ax ; load outregs.x.cflag ;AN000; +; ;AN000; + pop ax ; get di from stack ;AN000; + mov [di+0ah],ax ; load outregs.x.di ;AN000; +; ;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