/* 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;*/ }