2 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
4 /* Utility Name: ATTRIB.EXE */
6 /* Source File Name: ATTRIB.C */
8 /* Utility Function: */
10 /* Allows you to set or reset the Archive bit, the Read-Only bit and */
11 /* the Extended Attributes. Also allows you to display the current */
12 /* setting of those attributes. */
14 /* Status: ATTRIB Utility, DOS Version 4.0 */
16 /* Entry Point: inmain(line) */
18 /* Input: line = DOS command line parameters */
20 /* Exit-normal: attribute set, or attribute printed to output device */
22 /* Exit-error: error message written to standard error device */
24 /* Internal References: */
28 /* External References: */
31 /* parse() module=_parse.sal */
32 /* sysloadmsg() module=_msgret.sal */
33 /* sysdispmsg() module=_msgret.sal */
34 /* getpspbyte() module=new_c.sal */
35 /* putpspbyte() module=new_c.sal */
36 /* segread() module=dos.h(C library) */
37 /* intdosx() module=dos.h(C library) */
38 /* intdos() module=dos.h(C library) */
41 /* Syntax (Command Line) */
43 /* ATTRIB [+R|-R] [+A|-A] [d:][path]filename[.ext] [[id]|[id=value]] [/S] */
47 /* +R = Make file ReadOnly by setting READONLY bit */
48 /* -R = Reset READONLY bit */
49 /* +A = Set ARCHIVE bit */
50 /* -A = Reset ARCHIVE bit */
52 /* id = Set or display the extended attribute named by id. */
53 /* Only one id processed per invocation. id can be *. */
55 /* /S = Process subdirectories also */
57 /* Copyright 1988 Microsoft Corporation */
59 /* Revision History: */
61 /* Modified 6/22/87 v. 4.0 */
62 /* Rewritten 9/28/87 v. 4.0 - AN000 */
63 /* - fixed check for "." & ".." - AN001 */
64 /* PTM 3195 - changed Extended attribute MSGs - AN002 */
65 /* PTM 3588 - Do C exit not DOS exit. - AN003 */
66 /* PTM 3783 - Fix for hang problem. - AN004 */
69 /* When extended attributes are added back in, make sure you change the */
70 /* attrib.skl file back to the original DOS 4.0 ext. attr. error msgs. */
72 /* Also, this C program requires a special lib when linking to take care */
73 /* of the fact that the c lib saves the DOS environment on the heap and */
74 /* if the environment is > 32k, STACK OVERFLOW will occur. */
75 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
77 #include <stdio.h> /*;AN000;*/
78 #include <io.h> /*;AN000;*/
79 #include <dos.h> /*;AN000;*/
80 #include <string.h> /*;AN000;*/
81 #include "parse.h" /*;AN000;*/
82 #include "msgret.h" /*;AN000;*/
83 #include "attrib.h" /*;AN000;*/
85 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
86 /* Beginning of code (variables declared in attrib.h) */
87 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
90 * inmain() - This routine receives control from an assembler routine and from
91 * here, main is called. This routine first parses the command line
92 * and then does the appropriate action.
94 inmain(line) /*;AN000;*/
95 char *line; /*;AN000;*/
97 main(line); /*;AN000;*/
101 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
103 /* Subroutine Name: main() */
105 /* Subroutine Function: */
106 /* Parse the command line, makes a full path-filename, does the */
107 /* appropriate function */
115 /* Error exit: None */
117 /* Internal References: */
120 /* External References: */
123 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
125 main(line) /*;AN000;*/
126 char *line; /*;AN000;*/
128 WORD status; /*;AN000;*/
130 WORD Parse_it(); /* forward declaration */ /*;AN000;*/
131 WORD Make_fspec(); /* " " */ /*;AN000;*/
132 WORD Do_dir(); /* " " */ /*;AN000;*/
133 void Error_exit(); /* " " */ /*;AN000;*/
134 void Parse_err(); /* " " */ /*;AN000;*/
136 /* initialize control variables */
137 status = NOERROR; /*;AN000;*/
138 descending = FALSE; /*;AN000;*/
139 set_reg_attr = FALSE; /*;AN000;*/
140 pmask = mmask = 0x0; /*;AN000;*/
141 ext_attr[0] = BLANK; /*;AN000;*/
142 file[0] = '\0'; /*;AN000;*/
143 error_file_name[0] = '\0'; /*;AN000;*/
146 sysloadmsg(&inregs,&outregs); /*;AN000;*/
147 if (outregs.x.cflag & CARRY) { /*;AN000;*/
148 sysdispmsg(&outregs,&outregs); /*;AN000;*/
149 Dexit(11); /*;AN000;*/
152 Check_appendx(); /* check APPEND /X status */ /*;AN000;*/
153 Get_DBCS_vector(); /* get double byte table */ /*;AN000;*/
155 /* parse command line */
156 status = Parse_it(line); /*;AN000;*/
157 if (status != NOERROR) { /*;AN000;*/
158 Parse_err(status); /*;AN000;*/
161 /* Do extended attribute translations here */
162 Ext_translation(); /*;AN000;*/
165 /* Initialize any variables need for next phase of program */
166 segread(&segregs); /* init segment registers for DOS calls */ /*;AN000;*/
168 /* make full filespec (drive + full path + filename) */
169 strcpy(error_file_name,fspec); /*;AN000;*/
170 status = Make_fspec(fspec); /*;AN000;*/
171 if (status == NOERROR) { /*;AN000;*/
173 /* now do the work! */
174 did_attrib_ok = FALSE; /* needed if file not found and no */ /*;AN000;*/
175 /* error detected in Attrib(). */
176 status = Do_dir(fspec,file); /*;AN000;*/
177 if (status == NOERROR && did_attrib_ok == FALSE) /*;AN000;*/
178 status = FILENOTFOUND; /*;AN000;*/
181 /* determine if there was an error after attempt to do attrib function */
182 /* NOTE: for ext. attr. calls, add 200 to the return code to get the */
183 /* ---- error code for this switch. */
184 switch(status) { /* Extended error codes */ /*;AN000;*/
187 case 2: /* File not found */ /*;AN000;*/
188 Error_exit(ERR_EXTENDED,2,ONEPARM); /*;AN000;*/
190 case 3: /* Path not found */ /*;AN000;*/
191 Error_exit(ERR_EXTENDED,3,ONEPARM); /*;AN000;*/
193 case 5: /* Access Denied */ /*;AN000;*/
194 Error_exit(ERR_EXTENDED,5,ONEPARM); /*;AN000;*/
196 case 15: /* Invalid drive specification */ /*;AN000;*/
197 Error_exit(ERR_EXTENDED,15,ONEPARM); /*;AN000;*/
199 case 199: /* EA error: undetermined cause */ /*;AN000;*/
200 strcpy(error_file_name,ext_attr); /*;AN000;*/
201 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
202 /* Display_msg(199,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
204 case 201: /* EA error: name not found */ /*;AN000;*/
205 strcpy(error_file_name,ext_attr); /*;AN000;*/
206 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
207 /* Display_msg(201,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
209 case 202: /* EA error: no space to hold name or value */ /*;AN000;*/
210 strcpy(error_file_name,ext_attr); /*;AN000;*/
211 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
212 /* Display_msg(202,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
214 case 203: /* EA error: name can't be set on this function */ /*;AN000;*/
215 strcpy(error_file_name,ext_attr); /*;AN000;*/
216 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
217 /* Display_msg(204,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
219 case 204: /* EA error: name can't be set */ /*;AN000;*/
220 strcpy(error_file_name,ext_attr); /*;AN000;*/
221 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
222 /* Display_msg(204,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
224 case 205: /* EA error: name known to this FS but not supported */ /*;AN000;*/
225 strcpy(error_file_name,ext_attr); /*;AN000;*/
226 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
227 /* Display_msg(205,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
229 case 206: /* EA error: EA definition bad (type, length, etc.) */ /*;AN000;*/
230 strcpy(error_file_name,ext_attr); /*;AN000;*/
231 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
232 /* Display_msg(206,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
234 case 208: /* EA error: EA value not supported */ /*;AN000;*/
235 strcpy(error_file_name,ext_attr); /*;AN000;*/
236 Error_exit(ERR_EXTENDED,87,ONEPARM); /*;AN000;*/
237 /* Display_msg(208,STDERR,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
239 default: /* Access Denied */ /*;AN000;*/
240 Error_exit(ERR_EXTENDED,5,ONEPARM); /*;AN000;*/
243 Reset_appendx(); /*;AN000;*/
247 } /* end of inmain */ /*;AN000;*/
250 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
252 /* Subroutine Name: Display_msg */
254 /* Subroutine Function: */
255 /* Display the requested message to a given output device */
258 /* (1) Number of the message to be displayed (see ATTRIB.SKL) */
259 /* (2) Output device handle */
260 /* (3) Number of substitution parameters (%1,%2) */
261 /* (4) Offset of sublist control block */
262 /* (5) Message Class, 0=no input, 1=input via INT 21 AH=1 */
265 /* The message is written to the given output device. If input */
266 /* was requested, the character code of the key pressed is returned */
267 /* in outregs.x.ax. */
269 /* Normal exit: Message written to handle */
271 /* Error exit: None */
273 /* Internal References: */
276 /* External References: */
277 /* Sysdispmsg (module _msgret.sal) */
279 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
281 Display_msg(msgnum,msghan,msgparms,msgsub,msginput) /*;AN000;*/
282 int msgnum; /*;AN000;*/
283 int msghan; /*;AN000;*/
284 int msgparms; /*;AN000;*/
285 int *msgsub; /*;AN000;*/
286 char msginput; /*;AN000;*/
288 inregs.x.ax = msgnum; /*;AN000;*/
289 inregs.x.bx = msghan; /*;AN000;*/
290 inregs.x.cx = msgparms; /*;AN000;*/
291 inregs.h.dh = utility_msg_class; /*;AN000;*/
292 inregs.h.dl = msginput; /*;AN000;*/
293 inregs.x.si = (WORD)msgsub; /*;AN000;*/
294 sysdispmsg(&inregs,&outregs); /*;AN000;*/
296 /* check for error printing message */
297 if (outregs.x.cflag & CARRY) { /*;AN000;*/
298 outregs.x.bx = (WORD) STDERR; /*;AN000;*/
299 outregs.x.si = NOSUBPTR; /*;AN000;*/
300 outregs.x.cx = NOSUBCNT; /*;AN000;*/
301 outregs.h.dl = exterr_msg_class; /*;AN000;*/
302 sysdispmsg(&outregs,&outregs); /*;AN000;*/
307 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
309 /* Subroutine Name: Ext_translation() */
311 /* Subroutine Function: */
312 /* This routine does all translation of extended attribute names to */
313 /* the form that will be returned by Get_ext_attr_names(). For */
314 /* example, "CODEPAGE" would be translated to "CP". */
322 /* Error exit: None */
324 /* Internal References: */
327 /* External References: */
330 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
332 Ext_translation() /*;AN000;*/
334 if (strcmp(ext_attr,"CODEPAGE") == 0) { /*;AN000;*/
335 strcpy(ext_attr,"CP"); /*;AN000;*/
340 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
342 /* Subroutine Name: Get_far_str() */
344 /* Subroutine Function: */
345 /* copies a filename from source to the target. The source is offset */
346 /* from the code segment instead of the data segment. */
352 /* Normal exit: target = source */
354 /* Error exit: None */
356 /* Internal References: */
359 /* External References: */
362 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
364 Get_far_str(target,source,length) /*;AN000;*/
365 char *target; /*;AN000;*/
366 DWORD *source; /* segment = cs register */ /*;AN000;*/
367 WORD length; /*;AN000;*/
369 char far *fptr; /*;AN000;*/
372 if (length == 0) { /*;AN000;*/
374 /* copy string in data segment */
375 for (fptr = (char far *) *((DWORD *)source);(char)*fptr != NUL;) /*;AN000;*/
376 *target++ = (char) *fptr++; /*;AN000;*/
377 *target = *fptr; /*EOS character */ /*;AN000;*/
381 /* copy string in data segment */
382 for (fptr = (char far *) *((DWORD *)source),i=0;i < length;i++) /*;AN000;*/
383 *target++ = (char) *fptr++; /*;AN000;*/
384 *target = 0x0; /*EOS character */ /*;AN000;*/
386 strcpy(fix_es_reg,NUL); /* fix for es reg. after using far ptr */ /*;AN000;*/
390 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
392 /* Subroutine Name: Dexit() */
394 /* Subroutine Function: */
395 /* Does a DOS terminate. */
401 /* Normal exit: target = source */
403 /* Error exit: None */
405 /* Internal References: */
408 /* External References: */
411 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
416 Reset_appendx(); /* Reset APPEND /X status */ /*;AN000;*/
418 /* inregs.h.ah = (BYTE)0x4c; /*;AN003; ;AN000;*/
419 /* inregs.h.al = (BYTE)s; /*;AN003; ;AN000;*/
420 /* intdos(&inregs,&outregs); /*terminate*/ /*;AN003; ;AN000;*/
422 /* if it didn't work - kill it */
427 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
429 /* Subroutine Name: Dallocate() */
431 /* Subroutine Function: */
432 /* Does a DOS allocate of length (in paragraphs). */
438 /* Normal exit: target = source */
440 /* Error exit: None */
442 /* Internal References: */
445 /* External References: */
448 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
450 WORD *Dallocate(s) /*;AN000;*/
451 WORD s; /* length in bytes */ /*;AN000;*/
453 WORD length; /*length in paragraphs */ /*;AN000;*/
455 length = (s / 16 + 1); /*;AN000;*/
456 inregs.x.bx = length; /*;AN000;*/
457 inregs.x.ax = 0x4800; /*;AN000;*/
458 intdos(&inregs,&outregs); /*;AN000;*/
459 if (outregs.x.cflag & CARRY) { /*;AN000;*/
460 Error_exit(ERR_EXTENDED,8,NOSUBCNT); /*;AN000;*/
462 return((WORD *)outregs.x.ax); /*;AN000;*/
466 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
468 /* Subroutine Name: Dfree() */
470 /* Subroutine Function: */
471 /* Does a DOS de-allocate. */
477 /* Normal exit: target = source */
479 /* Error exit: None */
481 /* Internal References: */
484 /* External References: */
487 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
489 Dfree(segment) /*;AN000;*/
490 WORD segment; /*;AN000;*/
492 segregs.es = segment; /*;AN000;*/
493 inregs.x.ax = 0x4900; /*;AN000;*/
494 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
495 if (outregs.x.cflag & CARRY) { /*;AN000;*/
496 Error_exit(ERR_EXTENDED,8,NOSUBCNT); /*;AN000;*/
498 strcpy(fix_es_reg,NUL); /* fix for es reg. after using far ptr */ /*;AN000;*/
502 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
504 /* Subroutine Name: Copy_far_ptr() */
506 /* Subroutine Function: */
507 /* Copies a far ptr declared in any form to a real far ptr variable. */
513 /* Normal exit: status = NOERROR */
515 /* Error exit: None */
517 /* Internal References: */
520 /* External References: */
523 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
525 Copy_far_ptr(p1_addr, p2_addr) /*;AN000;*/
526 DWORD *p1_addr; /*;AN000;*/
527 WORD *p2_addr; /*;AN000;*/
529 WORD *dptr, *tptr; /*;AN000;*/
531 dptr = (WORD *)p2_addr; /*;AN000;*/
532 tptr = (WORD *)p1_addr; /*;AN000;*/
534 *tptr++ = *dptr++; /*;AN000;*/
535 *tptr = *dptr; /*;AN000;*/
536 strcpy(fix_es_reg,NUL); /* fix ES register */ /*;AN000;*/
539 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
541 /* Subroutine Name: Parse_it() */
543 /* Subroutine Function: */
544 /* Parses the command line and returns error status. */
548 /* Output: various control variables are set */
550 /* Normal exit: status = NOERROR */
552 /* Error exit: None */
554 /* Internal References: */
557 /* External References: */
560 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
562 WORD Parse_it(line) /*;AN000;*/
563 char *line; /*;AN000;*/
566 WORD status; /*;AN000;*/
567 WORD no_value; /*;AN000;*/
568 WORD got_fn; /* got filename - required parameter */ /*;AN000;*/
573 char far *cptr; /*;AN000;*/
574 char *ptr; /*;AN000;*/
575 BYTE p_mask[4], /*;AN000;*/
576 m_mask[4]; /*;AN000;*/
577 char string[129]; /*;AN000;*/
579 /* do setup for parser */
580 for (i=0; i<4; i++) { /*;AN000;*/
581 p_mask[i] = m_mask[i] = 0; /*;AN000;*/
583 do_reg_attr = TRUE; /*;AN000;*/
584 do_ext_attr = FALSE; /*;AN000;*/
585 set_reg_attr = FALSE; /*;AN000;*/
586 set_ext_attr = FALSE; /*;AN000;*/
587 no_value = TRUE; /* no value found for keyword */ /*;AN000;*/
588 got_fn = FALSE; /* no filename yet */ /*;AN000;*/
590 inregs.x.si = (WORD)line; /* Make DS:SI point to source */ /*;AN000;*/
591 inregs.x.cx = 0; /* Operand ordinal */ /*;AN000;*/
592 inregs.x.di = (WORD)&p_p1; /* Address of parm list */ /*;AN000;*/
593 status = p_no_error; /* Init no error condition */ /*;AN000;*/
595 /* loop until error or end_of_line */
596 while (status == p_no_error) { /*;AN000;*/
597 parse(&inregs,&outregs); /*;AN000;*/
598 status = outregs.x.ax; /* get error status */ /*;AN000;*/
600 /* check for errors, continue if none */
601 if (status == p_no_error) { /*;AN000;*/
603 /* check if first positional */
604 if (outregs.x.dx == (WORD)&pos1_buff) { /*;AN000;*/
605 if (*(char *)pos1_buff.p_result_buff[0] == '+') { /*;AN000;*/
606 p_mask[0] |= pos1_buff.p_item_tag; /*;AN000;*/
609 m_mask[0] |= pos1_buff.p_item_tag; /*;AN000;*/
611 set_reg_attr = TRUE; /*;AN000;*/
612 do_reg_attr = FALSE; /*;AN000;*/
615 /* check if second positional */
616 if (outregs.x.dx == (WORD)&pos2_buff) { /*;AN000;*/
617 if (*(char *)pos2_buff.p_result_buff[0] == '+') { /*;AN000;*/
618 p_mask[1] |= pos2_buff.p_item_tag; /*;AN000;*/
621 m_mask[1] |= pos2_buff.p_item_tag; /*;AN000;*/
623 set_reg_attr = TRUE; /*;AN000;*/
624 do_reg_attr = FALSE; /*;AN000;*/
627 /* check if third positional */
628 if (outregs.x.dx == (WORD)&pos3_buff) { /*;AN000;*/
630 /* copy filename from far string to data segment string */
631 Get_far_str(fspec,pos3_buff.p_result_buff,0); /*;AN000;*/
632 got_fn = TRUE; /*;AN000;*/
635 /* check if fourth positional */
636 if (outregs.x.dx == (WORD)&pos4_buff) { /*;AN000;*/
637 if (*(char *)pos4_buff.p_result_buff[0] == '+') { /*;AN000;*/
638 p_mask[2] |= pos4_buff.p_item_tag; /*;AN000;*/
641 m_mask[2] |= pos4_buff.p_item_tag; /*;AN000;*/
643 set_reg_attr = TRUE; /*;AN000;*/
644 do_reg_attr = FALSE; /*;AN000;*/
647 /* check if fifth positional */
648 if (outregs.x.dx == (WORD)&pos5_buff) { /*;AN000;*/
649 if (*(char *)pos5_buff.p_result_buff[0] == '+') { /*;AN000;*/
650 p_mask[3] |= pos5_buff.p_item_tag; /*;AN000;*/
653 m_mask[3] |= pos5_buff.p_item_tag; /*;AN000;*/
655 set_reg_attr = TRUE; /*;AN000;*/
656 do_reg_attr = FALSE; /*;AN000;*/
659 /* check if sixth positional */
660 if (outregs.x.dx == (WORD)&pos6_buff) { /*;AN000;*/
662 /* copy attribute name from far string to data segment string */
663 Get_far_str(ext_attr,pos6_buff.p_result_buff,0); /*;AN000;*/
664 do_ext_attr = TRUE; /*;AN000;*/
665 do_reg_attr = FALSE; /*;AN000;*/
668 /* check if value of sixth positional */
669 if (outregs.x.dx == (WORD)&pos6b_buff) { /*;AN000;*/
671 /* parse a value that is complex (in parenthesis). */
672 if (pos6b_buff.p_type == p_complex) { /*;AN000;*/
674 /* Parse the complex and concatenate it together */
675 inregs.x.cx = 0; /* reset ordinal count */ /*;AN000;*/
676 status = p_no_error; /*;AN000;*/
677 while (status != p_rc_eol) { /*;AN000;*/
678 parse(&inregs,&outregs); /*;AN000;*/
679 status = outregs.x.ax; /* get error status */ /*;AN000;*/
680 if (status != p_no_error) { /*;AN000;*/
681 status = p_syntax; /*;AN000;*/
684 Get_far_str(string,pos6b_buff.p_result_buff,0); /*;AN000;*/
685 strcat(ext_attr_value.ea_ascii,string); /*;AN000;*/
686 inregs.x.si = outregs.x.si; /* update SI for parser */ /*;AN000;*/
688 status = p_no_error; /*;AN000;*/
689 ext_attr_value_type = EAISASCII; /*;AN000;*/
692 Determine_type((WORD)pos6b_buff.p_type,pos6b_buff.p_result_buff); /*;AN000;*/
693 set_ext_attr = TRUE; /*;AN000;*/
694 do_reg_attr = FALSE; /*;AN000;*/
695 do_ext_attr = FALSE; /*;AN000;*/
696 no_value = TRUE; /* found a value for keyword */ /*;AN000;*/
699 /* check for '/S' switch */
700 if (outregs.x.dx == (WORD)&sw_buff) { /*;AN000;*/
702 /* check if duplicate switch */
703 if (descending == TRUE) { /*;AN000;*/
704 status = p_syntax; /*;AN000;*/
706 descending = TRUE; /*;AN000;*/
708 } /* if no error */ /*;AN000;*/
710 /* error, check if this is first positional, if so try again */
711 /* using the second positional beacause they are optional */
712 else if (inregs.x.cx == 0 || inregs.x.cx == 1 || /*;AN000;*/
713 inregs.x.cx == 3 || inregs.x.cx == 4) { /*;AN000;*/
714 inregs.x.cx++; /* try next positional */ /*;AN000;*/
716 /* Check for a filename beginning with '+' because parser will drop */
717 /* the plus sign anyways, and we need to flag it as an error */
718 for(ptr=(char *)inregs.x.si; *ptr == ' '; ptr++) /*;AN000;*/
719 /* NULL statement */ ; /*;AN000;*/
720 if (*ptr == '+') /*;AN000;*/
721 status = p_syntax; /*;AN000;*/
723 status = p_no_error; /*;AN000;*/
724 strcpy(fix_es_reg,NUL); /*;AN000;*/
726 continue; /* go back up to while loop */ /*;AN000;*/
729 /* Check for keyword (an attribute name - fourth positional) */
730 else if (status == p_not_in_key) { /*;AN000;*/
731 inregs.x.di = (WORD)&p_p2; /* change control blocks to */ /*;AN000;*/
732 /* be able to parse the keyword */
733 inregs.x.cx = 0; /* reset ordinal count */ /*;AN000;*/
734 status = p_no_error; /*;AN000;*/
735 no_value = FALSE; /* got keyword and equal sign */ /*;AN000;*/
736 continue; /*;AN000;*/
739 if (status == p_no_error) { /*;AN000;*/
740 inregs.x.cx = outregs.x.cx; /* update CX for parser */ /*;AN000;*/
741 inregs.x.si = outregs.x.si; /* update SI for parser */ /*;AN000;*/
743 } /* while loop */ /*;AN000;*/
745 /* check error status and if at end of line */
746 if (status == p_rc_eol) { /*;AN000;*/
747 status = p_no_error; /*;AN000;*/
750 /* Check for filename on command line */
751 if (!got_fn && status == p_no_error) { /*;AN000;*/
752 status = p_op_missing; /*;AN000;*/
755 /* Check for keyword and equal sign but no value */
756 if (!no_value) { /*;AN000;*/
757 status = p_syntax; /*;AN000;*/
760 /* check for duplicate +R +R or +A +A or -A -A or -R -R */
761 for (pr=0,mr=0,pa=0,ma=0,i=0; i<4; i++) { /*;AN000;*/
762 if (p_mask[i] & READONLY) /*;AN000;*/
764 if (m_mask[i] & READONLY) /*;AN000;*/
766 if (p_mask[i] & ARCHIVE) /*;AN000;*/
768 if (m_mask[i] & ARCHIVE) /*;AN000;*/
771 if ((pr > 1) || (mr > 1) || (pa > 1) || (ma > 1)) { /*;AN000;*/
772 status = p_syntax; /*;AN000;*/
775 for (pmask=0,mmask=0,i=0; i<4; i++) { /*;AN000;*/
776 pmask |= p_mask[i]; /* combine masks */ /*;AN000;*/
777 mmask |= m_mask[i]; /*;AN000;*/
781 /* check for duplicate -R +R or -A +A */
782 if ((pmask & mmask & READONLY) || (pmask & mmask & ARCHIVE)) { /*;AN000;*/
783 status = p_syntax; /*;AN000;*/
785 return(status); /*;AN000;*/
789 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
791 /* Subroutine Name: Determine_type() */
793 /* Subroutine Function: */
794 /* Determines the type of the new value of an attribute being set by */
795 /* the user in terms of extended attribute types. */
801 /* Normal exit: target = source */
803 /* Error exit: None */
805 /* Internal References: */
808 /* External References: */
811 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
813 Determine_type(parser_type,result_ptr) /*;AN000;*/
814 WORD parser_type; /*;AN000;*/
815 WORD *result_ptr; /*;AN000;*/
817 DWORD number; /*;AN000;*/
818 char string[129]; /*;AN000;*/
820 switch(parser_type) { /*;AN000;*/
821 case p_number: /*;AN000;*/
822 ext_attr_value_type = EAISBINARY; /*;AN000;*/
823 number = (DWORD)*(DWORD *)result_ptr; /*;AN000;*/
824 if (number > 0xffff) { /*;AN000;*/
825 ext_attr_value.ea_bin.length = 4; /*;AN000;*/
826 ext_attr_value.ea_bin.dword = number; /*;AN000;*/
828 else if (number > 0xff) { /*;AN000;*/
829 ext_attr_value.ea_bin.length = 2; /*;AN000;*/
830 ext_attr_value.ea_bin.dword = number; /*;AN000;*/
833 ext_attr_value.ea_bin.length = 1; /*;AN000;*/
834 ext_attr_value.ea_bin.dword = number; /*;AN000;*/
838 case p_complex: /*;AN000;*/
840 /* Taken care of in Parse_it() */
843 case p_string: /*;AN000;*/
844 case p_quoted_string: /*;AN000;*/
845 Get_far_str(string,result_ptr,0); /*;AN000;*/
847 /* is the type EAISLOGICAL or EAISASCII */
848 if (strcmp(string,"ON") == 0) { /*;AN000;*/
849 ext_attr_value.ea_logical = TRUE; /*;AN000;*/
850 ext_attr_value_type = EAISLOGICAL; /*;AN000;*/
852 else if (strcmp(string,"OFF") == 0) { /*;AN000;*/
853 ext_attr_value.ea_logical = FALSE; /*;AN000;*/
854 ext_attr_value_type = EAISLOGICAL; /*;AN000;*/
857 strcpy(ext_attr_value.ea_ascii,string); /*;AN000;*/
858 ext_attr_value_type = EAISASCII; /*;AN000;*/
863 ext_attr_value_type = EAISUNDEF; /*;AN000;*/
864 ext_attr_value.ea_undef = TRUE; /*;AN000;*/
870 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
872 /* Subroutine Name: Make_fspec() */
874 /* Subroutine Function: */
875 /* Makes a full path-filename from the filename & current directory */
884 /* Error exit: None */
886 /* Internal References: */
889 /* External References: */
892 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
894 WORD Make_fspec(fspec) /*;AN000;*/
895 char *fspec; /*;AN000;*/
897 WORD Check_DBCS(); /* forward declaration */ /*;AN000;*/
899 char path[256]; /*;AN000;*/
900 WORD status; /*;AN000;*/
901 WORD i,j; /*;AN000;*/
903 status = NOERROR; /*;AN000;*/
905 strcpy(path,fspec); /*;AN000;*/
907 /* Check if user did not enter a drive letter */
908 if (fspec[1] != ':') { /*;AN000;*/
909 inregs.x.ax = 0x1900; /* Get current drive */ /*;AN000;*/
910 intdos(&inregs,&outregs); /*;AN000;*/
911 fspec[0] = 'A' + (outregs.x.ax & 0xff); /*;AN000;*/
912 fspec[1] = ':'; /*;AN000;*/
913 fspec[2] = NUL; /*;AN000;*/
914 strcat(fspec,path); /*;AN000;*/
917 /* Check if user didn't enter a path in filename */
918 if (!Check_DBCS(fspec,2,'\\')) { /*;AN000;*/
919 strcpy(path,&fspec[2]); /*;AN000;*/
920 fspec[2] = '\\'; /*;AN000;*/
921 inregs.x.ax = 0x4700; /* Get current directory */ /*;AN000;*/
922 inregs.x.si = (WORD)(&fspec[3]); /*;AN000;*/
923 inregs.h.dl = fspec[0] - 'A' +1; /*;AN000;*/
924 intdos(&inregs,&outregs); /*;AN000;*/
925 status = outregs.x.ax; /*;AN000;*/
927 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
928 status = NOERROR; /*;AN000;*/
929 if (!Check_DBCS(fspec,strlen(fspec)-1,'\\')) /*;AN000;*/
930 strcat(fspec,"\\"); /*;AN000;*/
931 strcat(fspec,path); /*;AN000;*/
935 /* seperate the file specification into path and filename */
936 for (i=strlen(fspec);(i>=0) && (!Check_DBCS(fspec,i,'\\')); i--) /*;AN000;*/
937 /* null statement */ ; /*;AN000;*/
940 while (fspec[i+j] != '\0') { /*;AN000;*/
941 file[j] = fspec[i+j]; /*;AN000;*/
942 fspec[i+j] = '\0'; /*;AN000;*/
945 file[j] = '\0'; /*;AN000;*/
947 /* Check for filenames of: . (current dir) .. (parent dir) */
948 if (strcmp(file,".") == 0) /*;AN001;*/
949 strcpy(file,"*.*"); /*;AN001;*/
950 else if (strcmp(file,"..") == 0) { /*;AN001;*/
951 strcat(fspec,"..\\"); /*;AN001;*/
952 strcpy(file,"*.*"); /*;AN001;*/
955 return(status); /*;AN000;*/
959 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
961 /* Subroutine Name: Dta_save() */
963 /* Subroutine Function: */
964 /* saves an area in the PSP, but who knows. */
971 /* Error exit: None */
973 /* Internal References: */
976 /* External References: */
979 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
987 for (i = 0; i < l; i++) *(t+i) = getpspbyte(0x80+i)
988 /* null statement */ ;
992 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
994 /* Subroutine Name: Dta_restore() */
996 /* Subroutine Function: */
997 /* Restores the data that was saved in Dta_save(). */
1002 /* Normal exit: target = source */
1004 /* Error exit: None */
1006 /* Internal References: */
1009 /* External References: */
1012 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1020 for (i = 0; i < l; i++) putpspbyte(0x80+i,*(t+i))
1021 /* null statement */ ;
1025 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1027 /* Subroutine Name: Find_first() */
1029 /* Subroutine Function: */
1037 /* Error exit: None */
1039 /* Internal References: */
1042 /* External References: */
1045 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1047 WORD Find_first(s,f,a)
1060 inregs.x.ax = 0x4e00; /* DOS find first */
1061 inregs.x.cx = (*a & 0x00ff );
1062 inregs.x.dx = (WORD)s;
1063 intdos(&inregs,&outregs);
1064 status = outregs.x.ax;
1066 /* Check for no errors */
1067 if (!(outregs.x.cflag & CARRY)) {
1068 for (i = 0; i < 14; i++)
1069 *f++ = getpspbyte(0x80+30+i);
1070 *a = getpspbyte(0x80+21);
1077 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1079 /* Subroutine Name: Find_next() */
1081 /* Subroutine Function: */
1089 /* Error exit: None */
1091 /* Internal References: */
1094 /* External References: */
1097 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1111 inregs.x.ax = 0x4f00; /* DOS find next */
1112 intdos(&inregs,&outregs);
1113 status = outregs.x.ax;
1115 if (!(outregs.x.cflag & CARRY)) {
1116 for (i = 0; i < 14; i++)
1117 *f++ = getpspbyte(0x80+30+i);
1118 *a = getpspbyte(0x80+21);
1125 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1127 /* Subroutine Name: Get_reg_attrib() */
1129 /* Subroutine Function: */
1130 /* Does a DOS get attribute byte. */
1136 /* Normal exit: return = 0 */
1138 /* Error exit: return = error code */
1140 /* Internal References: */
1143 /* External References: */
1146 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1148 WORD Get_reg_attrib(fspec,attr_byte) /*;AN000;*/
1149 char *fspec; /*;AN000;*/
1150 BYTE *attr_byte; /*;AN000;*/
1152 WORD status; /*;AN000;*/
1154 inregs.x.ax = (WORD)0x4300; /*;AN000;*/
1155 inregs.x.dx = (WORD)fspec; /*;AN000;*/
1156 intdos(&inregs,&outregs); /*;AN000;*/
1157 status = outregs.x.ax; /*;AN000;*/
1159 /* Check for error */ /*;AN000;*/
1160 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1161 *attr_byte = (BYTE)outregs.h.cl; /*;AN000;*/
1162 status = NOERROR; /*;AN000;*/
1164 return(status); /*;AN000;*/
1168 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1170 /* Subroutine Name: Ext_open() */
1172 /* Subroutine Function: */
1173 /* Does a DOS extended open of a filename and returns a file handle.*/
1179 /* Normal exit: handle = file handle, return = 0 */
1181 /* Error exit: handle = ?; return = error code */
1183 /* Internal References: */
1186 /* External References: */
1189 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1191 WORD Ext_open(fspec,handle) /*;AN000;*/
1192 char *fspec; /*;AN000;*/
1193 WORD *handle; /*;AN000;*/
1195 WORD status; /*;AN000;*/
1197 inregs.x.ax = (WORD)0x6c00; /*;AN000;*/
1198 inregs.x.bx = (WORD)0x80; /*;AN000;*/
1199 inregs.x.cx = (WORD)0x0; /*;AN000;*/
1200 inregs.x.dx = (WORD)0x0101; /*;AN000;*/
1201 inregs.x.si = (WORD)fspec; /*;AN000;*/
1202 inregs.x.di = (WORD)&plist; /*;AN000;*//*;AN000;*/
1203 intdos(&inregs,&outregs); /*;AN000;*/
1204 status = outregs.x.ax; /*;AN000;*/
1206 /* Check for error */ /*;AN000;*/
1207 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1208 *handle = outregs.x.ax; /*;AN000;*/
1209 status = NOERROR; /*;AN000;*/
1211 return(status); /*;AN000;*/
1215 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1217 /* Subroutine Name: Get_ext_attrib() */
1219 /* Subroutine Function: */
1220 /* Does a DOS Get extended attributes and returns far ptr to list. */
1226 /* Normal exit: handle = file handle, return = 0 */
1228 /* Error exit: handle = ?; return = error code */
1230 /* Internal References: */
1233 /* External References: */
1236 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1238 WORD Get_ext_attrib(handle,list_ptr,qlist_ptr) /*;AN000;*/
1239 WORD handle; /*;AN000;*/
1240 WORD far **list_ptr; /* ptr to far ptr to list returned */ /*;AN000;*/
1241 WORD *qlist_ptr; /* query list */ /*;AN000;*/
1243 WORD status; /*;AN000;*/
1244 WORD attr_size; /*;AN000;*/
1245 WORD *list_seg; /*;AN000;*/
1246 WORD *ptr; /*;AN000;*/
1248 /* get size of attribute list */ /*;AN000;*/
1249 inregs.x.bx = handle; /*;AN000;*/
1250 inregs.x.ax = 0x5702; /* Get extended attributes*/ /*;AN000;*/
1251 inregs.x.si = (WORD)qlist_ptr; /* query one attribute */ /*;AN000;*/
1252 inregs.x.cx = (WORD)0; /* just get size of return buffer */ /*;AN000;*/
1253 intdos(&inregs,&outregs); /*;AN000;*/
1254 status = outregs.x.ax; /*;AN000;*/
1256 /* if no errors then get extended attributes */
1257 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1258 attr_size = outregs.x.cx; /*;AN000;*/
1260 /* allocate buffer space for extended attr. list */
1261 /* uses MAX_ATTR_SIZE if possible so that buffer can be used */
1262 /* to set the largest attribute possible */
1263 if (attr_size > MAX_ATTR_SIZE) /*;AN000;*/
1264 list_seg = Dallocate(attr_size); /*;AN000;*/
1266 list_seg = Dallocate(MAX_ATTR_SIZE); /*;AN000;*/
1268 /* get extended attributes */
1269 inregs.x.bx = handle; /*;AN000;*/
1270 inregs.x.ax = 0x5702; /* Get extended attributes */ /*;AN000;*/
1271 inregs.x.si = (WORD)qlist_ptr; /* query one attribute */ /*;AN000;*/
1272 inregs.x.di = (WORD)0x0; /* return buffer offset */ /*;AN000;*/
1273 inregs.x.cx = attr_size; /* size to get all attributes */ /*;AN000;*/
1274 segregs.es = (WORD)list_seg; /* segment of ea list to return */ /*;AN000;*/
1275 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
1276 strcpy(fix_es_reg,NUL); /* restores original ES reg. value */ /*;AN000;*/
1277 status = outregs.x.ax; /*;AN000;*/
1279 /* if no errors then fix up far pointer to list */
1280 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1282 /* convert segment returned from Dallocate to far ptr */
1283 *list_ptr = 0; /*;AN000;*/
1284 ptr = (WORD *)list_ptr; /*;AN000;*/
1286 *ptr = (WORD)list_seg; /*;AN000;*/
1287 (*list_ptr)++; /*;AN000;*/
1288 strcpy(fix_es_reg,NUL); /* restores ES register value */ /*;AN000;*/
1289 status = NOERROR; /*;AN000;*/
1292 return(status); /*;AN000;*/
1296 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1298 /* Subroutine Name: Get_ext_attr_names() */
1300 /* Subroutine Function: */
1301 /* Does a DOS Get extended attribute names and return a far ptr to */
1302 /* the querylist of names. */
1308 /* Normal exit: handle = file handle, return = 0 */
1310 /* Error exit: handle = ?; return = error code */
1312 /* Internal References: */
1315 /* External References: */
1318 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1320 WORD Get_ext_attr_names(handle,list_ptr,num_entries) /*;AN000;*/
1321 WORD handle; /*;AN000;*/
1322 WORD far **list_ptr; /* ptr to far ptr to list returned */ /*;AN000;*/
1323 WORD *num_entries; /* number of entries in list */ /*;AN000;*/
1325 WORD status; /*;AN000;*/
1326 WORD attr_size; /*;AN000;*/
1327 WORD *list_seg; /*;AN000;*/
1328 WORD *ptr; /*;AN000;*/
1330 /* get size of attribute name list */ /*;AN000;*/
1331 inregs.x.bx = handle; /*;AN000;*/
1332 inregs.x.ax = 0x5703; /* Get extended attribute names */ /*;AN000;*/
1333 inregs.x.cx = (WORD)0; /* just get size of return buffer */ /*;AN000;*/
1334 intdos(&inregs,&outregs); /*;AN000;*/
1335 status = outregs.x.ax; /*;AN000;*/
1337 /* if no errors then get extended attribute names */
1338 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1339 attr_size = outregs.x.cx; /*;AN000;*/
1341 /* allocate buffer space for extended attr. list */
1342 list_seg = Dallocate(attr_size); /*;AN000;*/
1344 /* get extended attributes */
1345 inregs.x.bx = handle; /*;AN000;*/
1346 inregs.x.ax = 0x5703; /* Get extended attributes */ /*;AN000;*/
1347 inregs.x.di = (WORD)0x0; /* return buffer offset */ /*;AN000;*/
1348 inregs.x.cx = attr_size; /* size to get all names */ /*;AN000;*/
1349 segregs.es = (WORD)list_seg; /* segment of ea list to return */ /*;AN000;*/
1350 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
1351 strcpy(fix_es_reg,NUL); /* restores original ES reg. value */ /*;AN000;*/
1352 status = outregs.x.ax; /*;AN000;*/
1353 *num_entries = 0; /*;AN000;*/
1355 /* if no errors then fix up far pointer to list */
1356 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1358 /* convert segment returned from Dallocate to far ptr */
1359 *list_ptr = 0; /*;AN000;*/
1360 ptr = (WORD *)list_ptr; /*;AN000;*/
1362 *ptr = (WORD)list_seg; /*;AN000;*/
1363 *num_entries = (WORD)*(WORD far *)*list_ptr; /*;AN000;*/
1364 (*list_ptr)++; /*;AN000;*/
1365 strcpy(fix_es_reg,NUL); /* restores ES register value */ /*;AN000;*/
1366 status = NOERROR; /*;AN000;*/
1369 return(status); /*;AN000;*/
1373 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1375 /* Subroutine Name: Set_reg_attrib() */
1377 /* Subroutine Function: */
1378 /* Sets the attribute byte of a file (not extended attributes). */
1386 /* Error exit: None */
1388 /* Internal References: */
1391 /* External References: */
1394 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1396 WORD Set_reg_attrib(fspec,attr_byte) /*;AN000;*/
1397 char *fspec; /*;AN000;*/
1398 BYTE attr_byte; /*;AN000;*/
1400 WORD status; /*;AN000;*/
1402 /* set attribute byte (archive & read-only bits) */
1403 inregs.x.ax = 0x4301; /* do DOS chmod call */ /*;AN000;*/
1404 inregs.x.dx = (WORD)fspec; /*;AN000;*/
1405 inregs.h.ch = 0x0; /*;AN000;*/
1406 inregs.h.cl = (BYTE)attr_byte; /*;AN000;*/
1407 intdos(&inregs,&outregs); /*;AN000;*/
1408 status = outregs.x.ax; /*;AN000;*/
1410 /* Check for error */
1411 if (!(outregs.x.cflag & CARRY))
1412 status = NOERROR; /*;AN000;*/
1413 return(status); /*;AN000;*/
1417 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1419 /* Subroutine Name: Set_ext_attrib() */
1421 /* Subroutine Function: */
1422 /* Set an extended attribute for a file. */
1430 /* Error exit: None */
1432 /* Internal References: */
1435 /* External References: */
1438 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1440 WORD Set_ext_attrib(handle,list_ptr) /*;AN000;*/
1441 WORD handle; /*;AN000;*/
1442 WORD far *list_ptr; /*;AN000;*/
1444 WORD status; /*;AN000;*/
1446 /* set extended attribute */
1447 inregs.x.ax = 0x5704; /* DOS set ext. attr. */ /*;AN000;*/
1448 inregs.x.bx = handle; /*;AN000;*/
1449 inregs.x.di = 0x0; /* list offset */ /*;AN000;*/
1450 segregs.es = (WORD)FP_SEG(list_ptr); /* list segment */ /*;AN000;*/
1451 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
1452 status = outregs.x.ax; /*;AN000;*/
1454 /* Check for error */
1455 if (!(outregs.x.cflag & CARRY)) /*;AN000;*/
1456 status = NOERROR; /*;AN000;*/
1457 return(status); /*;AN000;*/
1461 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1463 /* Subroutine Name: CheckYN() */
1465 /* Subroutine Function: */
1466 /* Check for a valid Yes/No answer. */
1474 /* Error exit: None */
1476 /* Internal References: */
1479 /* External References: */
1482 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1484 WORD CheckYN(fspec) /*;AN000;*/
1485 char *fspec; /*;AN000;*/
1487 WORD answer; /*;AN000;*/
1488 WORD key; /*;AN000;*/
1490 while (TRUE) { /*;AN000;*/
1491 msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/
1492 msg_str2.sub_value = (WORD)fspec; /*;AN000;*/
1493 Display_msg(11,STDOUT,ONEPARM,&msg_str2,INPUT); /*;AN000;*/
1494 key = outregs.x.ax; /* get key from AX */ /*;AN000;*/
1495 inregs.x.dx = key; /* put key in DX */ /*;AN000;*/
1496 inregs.x.ax = 0x6523; /* check Y/N */ /*;AN000;*/
1497 intdos(&inregs,&outregs); /*;AN000;*/
1498 answer = outregs.x.ax; /*;AN000;*/
1499 Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
1501 if (answer == YES || answer == NO) /*;AN000;*/
1504 return(answer); /*;AN000;*/
1508 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1510 /* Subroutine Name: Find_ext_attrib() */
1512 /* Subroutine Function: */
1513 /* Given an extended attribute name, search the list of attributes */
1514 /* for a file to find this attribute. Return either TRUE for found */
1515 /* or FALSE for not found. */
1521 /* Normal exit: target = source */
1523 /* Error exit: None */
1525 /* Internal References: */
1528 /* External References: */
1531 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1533 WORD Find_ext_attrib(lptr,attribute,num,addr) /*;AN000;*/
1534 WORD far *lptr; /*;AN000;*/
1535 char *attribute; /*;AN000;*/
1536 WORD num; /*;AN000;*/
1537 struct name_list far **addr; /*;AN000;*/
1539 struct name_list far *ptr; /*;AN000;*/
1540 WORD i,j; /*;AN000;*/
1541 WORD length; /*;AN000;*/
1542 WORD found; /*;AN000;*/
1543 WORD match; /*;AN000;*/
1545 found = FALSE; /*;AN000;*/
1547 /* loop thru return list structure for the ext. attr. we want */
1548 for (ptr = (struct name_list far *)lptr,i=0;i < num; i++) { /*;AN000;*/
1550 /* compare attribute name to see if this is it */
1551 if (ptr->nl_name_len == (length = strlen(attribute))) { /*;AN000;*/
1552 match = TRUE; /*;AN000;*/
1553 for (j=0;j<length ;j++) { /*;AN000;*/
1554 if (ptr->nl_name[j] != attribute[j]) { /*;AN000;*/
1555 match = FALSE; /*;AN000;*/
1559 if (match) { /*;AN000;*/
1560 found = TRUE; /*;AN000;*/
1565 /* advance ptr to next extended attr. structure */
1566 length = NAME_SIZE + ptr->nl_name_len; /*;AN000;*/
1567 ptr = (struct name_list far *)((BYTE far *)ptr + length); /*;AN000;*/
1568 strcpy(fix_es_reg,NUL); /*;AN000;*/
1571 /* found the extended attribute wanted, pass addr back */
1572 if (found) { /*;AN000;*/
1573 *addr = ptr; /*;AN000;*/
1575 strcpy(fix_es_reg,NUL); /*;AN000;*/
1576 return(found); /*;AN000;*/
1580 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1582 /* Subroutine Name: Print_ext_attrib() */
1584 /* Subroutine Function: */
1585 /* Given an extended attribute name, search the list of attributes */
1586 /* for a file to find this attribute. Return either TRUE for found */
1587 /* or FALSE for not found. */
1593 /* Normal exit: target = source */
1595 /* Error exit: None */
1597 /* Internal References: */
1600 /* External References: */
1603 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1605 WORD Print_ext_attrib(fspec,type,name_ptr,num,attr_ptr) /*;AN000;*/
1606 char *fspec; /*;AN000;*/
1607 WORD type; /*;AN000;*/
1608 struct name_list far *name_ptr; /*;AN000;*/
1609 WORD num; /*;AN000;*/
1610 struct attr_list far *attr_ptr; /*;AN000;*/
1612 WORD status; /*;AN000;*/
1614 WORD length; /*;AN000;*/
1615 WORD value; /*;AN000;*/
1616 BYTE far *value_ptr; /*;AN000;*/
1617 char string[129]; /*;AN000;*/
1618 char far *cptr; /*;AN000;*/
1619 struct name_list far *ptr; /*;AN000;*/
1621 /* find value field in attribute list */
1622 length = ATTR_SIZE + attr_ptr->at_name_len; /*;AN000;*/
1623 value_ptr = (BYTE far *)((BYTE far *)attr_ptr + length); /*;AN000;*/
1624 length = attr_ptr->at_value_len; /*;AN000;*/
1625 strcpy(fix_es_reg,NUL); /*;AN000;*/
1627 status = NOERROR; /*;AN000;*/
1628 switch (type) { /*;AN000;*/
1629 case EAISUNDEF: /*;AN000;*/
1630 msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/
1631 msg_str2.sub_value = (WORD)fspec; /*;AN000;*/
1632 Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1634 case EAISLOGICAL: /*;AN000;*/
1635 msg_str.sub_value_seg = segregs.ds; /*;AN000;*/
1636 if ((BYTE)*(BYTE far *)value_ptr == 0) /*;AN000;*/
1637 msg_str.sub_value = (WORD)str_off; /*;AN000;*/
1639 msg_str.sub_value = (WORD)str_on; /*;AN000;*/
1640 msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/
1641 msg_str1.sub_value = (WORD)fspec; /*;AN000;*/
1642 Display_msg(9,STDOUT,TWOPARM,&msg_str,NOINPUT); /*;AN000;*/
1644 case EAISBINARY: /*;AN000;*/
1645 if (length == 1) { /*;AN000;*/
1646 msg_num.sub_flags = sf_unsbin2d | sf_byte | sf_right; /*;AN000;*/
1647 value = (BYTE)*(BYTE far *)value_ptr; /*;AN000;*/
1649 else if (length == 2) { /*;AN000;*/
1650 msg_num.sub_flags = sf_unsbin2d | sf_word | sf_right; /*;AN000;*/
1651 value = (WORD)*(WORD far *)value_ptr; /*;AN000;*/
1653 else if (length == 4) { /*;AN000;*/
1654 msg_num.sub_flags = sf_unsbin2d | sf_dword | sf_right; /*;AN000;*/
1655 value = (DWORD)*(DWORD far *)value_ptr; /*;AN000;*/
1657 msg_num.sub_value_seg = segregs.ds; /*;AN000;*/
1658 msg_num.sub_value = (WORD)&value; /*;AN000;*/
1659 msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/
1660 msg_str1.sub_value = (WORD)fspec; /*;AN000;*/
1661 Display_msg(9,STDOUT,TWOPARM,&msg_num,NOINPUT); /*;AN000;*/
1663 case EAISASCII: /*;AN000;*/
1664 msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/
1665 msg_str2.sub_value = (WORD)fspec; /*;AN000;*/
1666 Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1667 Get_far_str(string,&value_ptr,length); /*;AN000;*/
1668 msg_str2.sub_value = (WORD)string; /*;AN000;*/
1669 Display_msg(8,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1671 case EAISDATE: /*;AN000;*/
1672 msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/
1673 msg_str1.sub_value = (WORD)fspec; /*;AN000;*/
1674 value = (WORD)*(WORD far *)value_ptr; /*;AN000;*/
1675 Convert_date(value,&msg_date.sub_value,&msg_date.sub_value_seg); /*;AN000;*/
1676 Display_msg(9,STDOUT,TWOPARM,&msg_date,NOINPUT); /*;AN000;*/
1678 case EAISTIME: /*;AN000;*/
1679 msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/
1680 msg_str1.sub_value = (WORD)fspec; /*;AN000;*/
1681 value = (WORD)*(WORD far *)value_ptr; /*;AN000;*/
1682 Convert_time(value,&msg_time.sub_value,&msg_time.sub_value_seg); /*;AN000;*/
1683 Display_msg(9,STDOUT,TWOPARM,&msg_time,NOINPUT); /*;AN000;*/
1685 case EANAMES: /*;AN000;*/
1686 msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/
1687 msg_str2.sub_value = (WORD)fspec; /*;AN000;*/
1688 Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1690 /* display special attribute names */
1691 for (i=0; i < MAX_SPL; i++) { /*;AN000;*/
1692 msg_str2.sub_value = (WORD)specials[i].name; /*;AN000;*/
1693 Display_msg(8,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1696 /* display each attribute name */
1697 for (ptr = name_ptr,i=0; i<num; i++) { /*;AN000;*/
1698 cptr = (char far *)((BYTE far *)ptr + 4); /*;AN000;*/
1699 Get_far_str(string,&cptr,(WORD)ptr->nl_name_len); /*;AN000;*/
1701 msg_str2.sub_value = (WORD)string; /*;AN000;*/
1702 Display_msg(8,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1704 /* advance ptr to next extended attr. structure */
1705 length = NAME_SIZE + ptr->nl_name_len; /*;AN000;*/
1706 ptr = (struct name_list far *)((BYTE far *)ptr + length); /*;AN000;*/
1707 strcpy(fix_es_reg,NUL); /*;AN000;*/
1709 Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
1710 Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
1712 default: /*;AN000;*/
1713 msg_str2.sub_value_seg = segregs.ds; /*;AN000;*/
1714 msg_str2.sub_value = (WORD)fspec; /*;AN000;*/
1715 Display_msg(12,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1717 } /* endswitch */ /*;AN000;*/
1718 return(status); /*;AN000;*/
1721 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1723 /* Subroutine Name: Convert_date */
1725 /* Subroutine Function: */
1726 /* Convert date word returned by DOS to the form required by the */
1727 /* message retriever. */
1729 /* DOS returns: yyyyyyym mmmddddd */
1731 /* y = 0-119 (1980-2099) */
1735 /* Message retriever requires: yyyyyyyy yyyyyyyy mmmmmmmm dddddddd */
1738 /* (1) Date word in form given by DOS */
1739 /* (2) Address of first word to place result (yyyyyyyy yyyyyyyy) */
1740 /* (3) Address of second word to place result (mmmmmmmm dddddddd) */
1743 /* Double word result updated with date in form required by */
1744 /* message retriever. */
1746 /* Normal exit: Result word updated */
1748 /* Error exit: None */
1750 /* Internal References: */
1753 /* External References: */
1756 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1758 Convert_date(dosdate,msgdate1,msgdate2)
1763 WORD day,month,year;
1766 year = ((year >> 1) & 0x7f00) + 80*256; /* DOS year + 80 */
1767 year = (year >> 8) & 0x007f; /*;AN000;*/
1769 day = (day << 8) & 0x1f00;
1771 month = (month >> 5) & 0x000f;
1773 *msgdate2 = month | day;
1777 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1779 /* Subroutine Name: Convert_time */
1781 /* Subroutine Function: */
1782 /* Convert time word returned by DOS to the form required by the */
1783 /* message retriever. */
1785 /* DOS returns: hhhhhmmm mmmsssss */
1787 /* h = hours (0-23) */
1788 /* m = minutes (0-59) */
1791 /* Message retriever requires: hhhhhhhh mmmmmmmm ssssssss hhhhhhhh */
1794 /* (1) Time word in form given by DOS */
1795 /* (2) Address of first word to place result (hhhhhhhh hhhhhhhh) */
1796 /* (3) Address of second word to place result (ssssssss 00000000) */
1799 /* Double word result updated with time in form required by */
1800 /* message retriever. */
1802 /* Normal exit: Result word updated */
1804 /* Error exit: None */
1806 /* Internal References: */
1809 /* External References: */
1812 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1814 Convert_time(dostime,msgtime1,msgtime2)
1819 WORD hours,minutes,seconds;
1822 hours = hours >> 11 & 0x001f;
1824 seconds = seconds & 0x001f * 2; /* seconds * 2 */
1826 minutes = minutes << 3 & 0x3f00;
1827 *msgtime1 = hours | minutes;
1828 *msgtime2 = seconds;
1832 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1834 /* Subroutine Name: Regular_attrib() */
1836 /* Subroutine Function: */
1837 /* Handles all function for archive bit and read-only bit. */
1845 /* Error exit: None */
1847 /* Internal References: */
1850 /* External References: */
1853 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1855 WORD Regular_attrib(fspec) /*;AN000;*/
1856 char *fspec; /*;AN000;*/
1858 WORD status; /*;AN000;*/
1860 char string[16]; /*;AN000;*/
1862 /* get attributes */
1863 if ((status = Get_reg_attrib(fspec,&attr)) != NOERROR) { /*;AN000;*/
1864 return(status); /*;AN000;*/
1867 /* Check whether to display values or set new ones */
1868 if (set_reg_attr) { /*;AN000;*/
1869 attr = (attr & (~mmask)) | pmask; /*;AN000;*/
1870 status = Set_reg_attrib(fspec,attr); /*;AN000;*/
1873 for (i = 0; i < 8; i++) /*;AN000;*/
1874 if ((attr & bits[i]) != 0 ) /*;AN000;*/
1875 string[i] = as[i]; /*;AN000;*/
1877 string[i] = ' '; /*;AN000;*/
1878 for (i=8; i < 16; i++) /*;AN000;*/
1879 string[i] = ' '; /*;AN000;*/
1880 string[16] = '\0'; /*;AN000;*/
1882 msg_str.sub_value_seg = segregs.ds; /*;AN000;*/
1883 msg_str.sub_value = (WORD)string; /*;AN000;*/
1884 msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/
1885 msg_str1.sub_value = (WORD)fspec; /*;AN000;*/
1886 Display_msg(9,STDOUT,TWOPARM,&msg_str,NOINPUT); /*;AN000;*/
1889 did_attrib_ok = TRUE; /*;AN000;*/
1890 return(status); /*;AN000;*/
1894 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1896 /* Subroutine Name: Special_attrib() */
1898 /* Subroutine Function: */
1899 /* Handles all function for special attributes. For example, "DATE" */
1900 /* is a special attribute because it is not an extended attribute, */
1901 /* but ATTRIB does support its function. */
1909 /* Error exit: None */
1911 /* Internal References: */
1914 /* External References: */
1917 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1919 WORD Special_attrib(handle,fspec,id) /*;AN000;*/
1920 WORD handle; /*;AN000;*/
1921 char *fspec; /*;AN000;*/
1922 WORD id; /*;AN000;*/
1924 WORD status; /*;AN000;*/
1925 DWORD filesize; /*;AN000;*/
1926 long size; /*;AN000;*/
1927 long filelength(); /*;AN000;*/
1929 msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/
1930 msg_str1.sub_value = (WORD)fspec; /*;AN000;*/
1932 /* check to set if user is trying to set a special attribute, if so */
1933 /* then return error. */
1934 if (set_ext_attr) /*;AN000;*/
1935 return(EARCNOTEVER+200); /*;AN000;*/
1937 /* determine which info to get by using ID */
1938 if (id == A_FILESIZE) { /* get filesize */ /*;AN000;*/
1940 /* get file size, if error return error code */
1941 if ((size = filelength(handle)) == (long)-1) { /*;AN000;*/
1942 return(FILENOTFOUND); /*;AN000;*/
1944 filesize = (DWORD)size; /*;AN000;*/
1945 msg_dword.sub_value = (WORD)&filesize; /*;AN000;*/
1946 msg_dword.sub_value_seg = (WORD)segregs.ds; /*;AN000;*/
1947 Display_msg(9,STDOUT,TWOPARM,&msg_dword,NOINPUT); /*;AN000;*/
1950 else if (id == A_DATE) { /*;AN000;*/
1951 inregs.x.ax = 0x5700; /* get date */ /*;AN000;*/
1952 inregs.x.bx = handle; /*;AN000;*/
1953 intdos(&inregs,&outregs); /*;AN000;*/
1954 status = outregs.x.ax; /*;AN000;*/
1955 if (outregs.x.cflag & CARRY) /*;AN000;*/
1956 return(status); /*;AN000;*/
1958 Convert_date(outregs.x.dx,&msg_date.sub_value,&msg_date.sub_value_seg); /*;AN000;*/
1959 Display_msg(9,STDOUT,TWOPARM,&msg_date,NOINPUT); /*;AN000;*/
1962 else if (id == A_TIME) { /*;AN000;*/
1963 inregs.x.ax = 0x5700; /* get time */ /*;AN000;*/
1964 inregs.x.bx = handle; /*;AN000;*/
1965 intdos(&inregs,&outregs); /*;AN000;*/
1966 status = outregs.x.ax; /*;AN000;*/
1967 if (outregs.x.cflag & CARRY) /*;AN000;*/
1968 return(status); /*;AN000;*/
1970 Convert_time(outregs.x.cx,&msg_time.sub_value,&msg_time.sub_value_seg); /*;AN000;*/
1971 Display_msg(9,STDOUT,TWOPARM,&msg_time,NOINPUT); /*;AN000;*/
1974 did_attrib_ok = TRUE; /*;AN000;*/
1975 return(NOERROR); /*;AN000;*/
1979 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1981 /* Subroutine Name: Extended_attrib() */
1983 /* Subroutine Function: */
1984 /* Determine what functions the user wants and then gets the */
1985 /* extended attributes and regular attributes and then checks */
1986 /* the attributes against what the user wanted and either do it or */
1995 /* Error exit: None */
1997 /* Internal References: */
2000 /* External References: */
2003 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2005 WORD Extended_attrib(handle,fspec) /*;AN000;*/
2006 WORD handle; /*;AN000;*/
2007 char *fspec; /*;AN000;*/
2009 WORD status; /*;AN000;*/
2010 WORD num; /*;AN000;*/
2011 WORD type; /*;AN000;*/
2012 WORD length; /*;AN000;*/
2014 WORD far *name_ptr, /*;AN000;*/
2015 far *nptr; /*;AN000;*/
2016 WORD far *list_ptr; /*;AN000;*/
2017 BYTE far *value_ptr; /*;AN000;*/
2018 char far *cptr; /*;AN000;*/
2019 char *ptr; /*;AN000;*/
2020 struct query_list qlist; /*;AN000;*/
2022 /* get extended attribute names, if error return with error code */
2023 if ((status = Get_ext_attr_names(handle,&name_ptr,&num)) != NOERROR) { /*;AN000;*/
2024 return(status); /*;AN000;*/
2027 /* Check for keyword "*", print all extended attribute names */
2028 /* ***** this is a special piece of code */
2029 if (strcmp(ext_attr,"*") == 0) { /*;AN000;*/
2030 do_ext_attr = TRUE; /*;AN000;*/
2031 set_ext_attr = FALSE; /*;AN000;*/
2032 nptr = name_ptr; /*;AN000;*/
2033 type = EANAMES; /*;AN000;*/
2034 status = Print_ext_attrib(fspec,type,name_ptr,num,list_ptr); /*;AN004;*/
2035 did_attrib_ok = TRUE; /*;AN004;*/
2036 return(status); /*;AN004;*/
2039 /* find if extended attribute name is in list */
2040 else if (!Find_ext_attrib(name_ptr,ext_attr,num,&nptr)) { /*;AN000;*/
2041 return(EARCNOTFOUND+200); /*;AN000;*/
2044 type = ((struct name_list far *)nptr)->nl_type; /*;AN000;*/
2046 /* Check if extended attribute is hidden , if so leave */
2047 if (((struct name_list far *)nptr)->nl_flags & EAHIDDEN) { /*;AN000;*/
2048 did_attrib_ok = TRUE; /*;AN000;*/
2049 return(NOERROR); /*;AN000;*/
2052 /* Get the extended attribute value */
2053 qlist.ql_num = 1; /*;AN000;*/
2054 qlist.ql_type = ((struct name_list far *)nptr)->nl_type; /*;AN000;*/
2055 qlist.ql_flags = ((struct name_list far *)nptr)->nl_flags; /*;AN000;*/
2056 qlist.ql_name_len = ((struct name_list far *)nptr)->nl_name_len; /*;AN000;*/
2057 cptr = (char far *)((BYTE far *)nptr + 4); /*;AN000;*/
2058 Get_far_str(qlist.ql_name,&cptr,qlist.ql_name_len); /*;AN000;*/
2060 if ((status = Get_ext_attrib(handle,&list_ptr,&qlist)) != NOERROR) { /*;AN000;*/
2061 return(status); /*;AN000;*/
2064 /* Check if doing a display or set, and go do it */
2065 if (do_ext_attr) { /*;AN000;*/
2066 status = Print_ext_attrib(fspec,type,name_ptr,num,list_ptr); /*;AN000;*/
2070 /* Check if extended attribute is read-only or create-only */
2071 /* or if the type is undefined. if true, display error */
2072 if ((qlist.ql_flags & (EAREADONLY | EACREATEONLY)) || /*;AN000;*/
2073 (qlist.ql_type & EAISUNDEF)) { /*;AN000;*/
2074 return(EARCNOTEVER+200); /* error will be displayed */ /*;AN000;*/
2077 /* Check type of current attribute against the type the user */
2078 /* is trying to set the attribute to. If they differ, error. */
2079 if (qlist.ql_type != ext_attr_value_type) { /*;AN000;*/
2080 return(EARCDEFBAD+200); /* error will be displayed */ /*;AN000;*/
2083 /* find value field in attribute list */
2084 length = ATTR_SIZE + qlist.ql_name_len; /*;AN000;*/
2085 value_ptr = (BYTE far *)((BYTE far *)list_ptr + length); /*;AN000;*/
2086 length = ((struct attr_list far *)list_ptr)->at_value_len; /*;AN000;*/
2087 strcpy(fix_es_reg,NUL); /*;AN000;*/
2089 /* CODEPAGE attrbute only - display Y/N message if changing codepage */
2090 /* to a new value and cp != 0, ask for confirmation. */
2091 if (strcmp(qlist.ql_name,"CP") == 0 && /*;AN000;*/
2092 (WORD)*(WORD far *)value_ptr != 0 && /*;AN000;*/
2093 (WORD)*(WORD far *)value_ptr != (WORD)ext_attr_value.ea_bin.dword) { /*;AN000;*/
2094 if (CheckYN(fspec) == NO) { /*;AN000;*/
2095 did_attrib_ok = TRUE; /*;AN000;*/
2096 return(NOERROR); /*;AN000;*/
2100 /* Determine type of extended attribute and set the correct value */
2101 switch (ext_attr_value_type) { /*;AN000;*/
2102 case EAISLOGICAL: /*;AN000;*/
2103 *(BYTE far *)value_ptr = (BYTE)ext_attr_value.ea_logical; /*;AN000;*/
2105 case EAISBINARY: /*;AN000;*/
2106 if (length == 1) /*;AN000;*/
2107 *(BYTE far *)value_ptr = (BYTE)ext_attr_value.ea_bin.dword; /*;AN000;*/
2108 else if (length == 2) /*;AN000;*/
2109 *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_bin.dword; /*;AN000;*/
2111 *(DWORD far *)value_ptr = (DWORD)ext_attr_value.ea_bin.dword; /*;AN000;*/
2113 case EAISASCII: /*;AN000;*/
2114 length = strlen(ext_attr_value.ea_ascii); /* get string length */ /*;AN000;*/
2115 ((struct attr_list far *)list_ptr)->at_value_len = length; /*;AN000;*/
2116 for (ptr=ext_attr_value.ea_ascii,i=0;i < length;i++) { /*;AN000;*/
2117 *(char far *)value_ptr = *ptr++; /*;AN000;*/
2118 ((char far *)value_ptr)++; /*;AN000;*/
2121 case EAISDATE: /*;AN000;*/
2122 *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_date; /*;AN000;*/
2124 case EAISTIME: /*;AN000;*/
2125 *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_time; /*;AN000;*/
2129 list_ptr--; /* make list_ptr point to num entries */ /*;AN000;*/
2130 *(WORD far *)list_ptr = 1; /* num entries = 1 */ /*;AN000;*/
2132 if ((status = Set_ext_attrib(handle,list_ptr)) != NOERROR) { /*;AN000;*/
2133 return(status); /*;AN000;*/
2136 did_attrib_ok = TRUE; /*;AN000;*/
2137 return(status); /*;AN000;*/
2141 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2143 /* Subroutine Name: Attrib() */
2145 /* Subroutine Function: */
2146 /* Determine what functions the user wants and then gets the */
2147 /* extended attributes and regular attributes and then checks */
2148 /* the attributes against what the user wanted and either do it or */
2157 /* Error exit: None */
2159 /* Internal References: */
2162 /* External References: */
2165 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2167 WORD Attrib(path,file) /*;AN000;*/
2168 char *path, /*;AN000;*/
2171 char fspec[128]; /*;AN000;*/
2172 WORD status; /*;AN000;*/
2173 WORD handle; /*;AN000;*/
2175 WORD found_spl; /* boolean */ /*;AN000;*/
2176 WORD id; /*;AN000;*/
2178 strcpy(fspec,path); /* make full filename */ /*;AN000;*/
2179 strcat(fspec,file); /*;AN000;*/
2181 /* Check for extended & special attributes */
2182 if (set_ext_attr || do_ext_attr) { /*;AN000;*/
2184 /* Check for special attribute keywords */
2185 found_spl = FALSE; /*;AN000;*/
2186 for (i=0; i < MAX_SPL; i++) { /*;AN000;*/
2187 if (strcmp(ext_attr,specials[i].name) == 0) { /*;AN000;*/
2188 found_spl = TRUE; /*;AN000;*/
2189 id = specials[i].id; /*;AN000;*/
2194 /* Do an extended open, if error return error code */
2195 if ((status = Ext_open(fspec,&handle)) != NOERROR) { /*;AN000;*/
2196 return(status); /*;AN000;*/
2199 /* Special attributes */
2200 if (found_spl) { /*;AN000;*/
2201 status = Special_attrib(handle,fspec,id); /*;AN000;*/
2204 /* Extended attributes */
2206 status = Extended_attrib(handle,fspec); /*;AN000;*/
2208 close(handle); /*;AN000;*/
2211 /* Check if setting archive bit or readonly bit */
2212 if (set_reg_attr || do_reg_attr) { /*;AN000;*/
2213 if ((status = Regular_attrib(fspec)) != NOERROR) { /*;AN000;*/
2214 return(status); /*;AN000;*/
2218 return(status); /*;AN000;*/
2222 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2224 /* Subroutine Name: Do_dir() */
2226 /* Subroutine Function: */
2227 /* Given the full path-filename, determine if descending option is */
2228 /* set and then recursively (if option set) find all files in this */
2229 /* directory and all files in any subdirectories (if option set). */
2230 /* For each directory call Attrib() which will process a file. */
2238 /* Error exit: None */
2240 /* Internal References: */
2243 /* External References: */
2246 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2248 WORD Do_dir(path,file)
2253 char subdirectory[256];
2258 next[0] = '\0'; /*;AN000;*/
2259 Dta_save(dta_area,128);
2260 status = NOERROR; /*;AN000;*/
2262 /* first, but only if descending, scan for subdirectories */
2264 strcpy(subdirectory,path);
2265 strcat(subdirectory,"*.*");
2267 search_attrib = SUBDIR; /* Find all except volume labels*/ /*;AN000;*/
2268 status = Find_first(subdirectory,next,&search_attrib);
2270 while (status == NOERROR) {
2271 if ((next[0] != '.') && ((search_attrib & SUBDIR) != 0)) {
2272 strcpy(subdirectory,path);
2273 strcat(subdirectory,next);
2274 strcat(subdirectory,"\\");
2275 status = Do_dir(subdirectory,file);
2277 if (status == NOERROR) {
2278 strcpy(subdirectory,path);
2279 strcat(subdirectory,"*.*");
2281 search_attrib = SUBDIR; /*;AN000;*/
2282 status = Find_next(next,&search_attrib);
2285 } /* if descending */
2287 if (status == NOMOREFILES)
2290 /* now, search this directory for files that match */
2291 if (status == NOERROR) {
2292 strcpy(subdirectory,path);
2293 strcat(subdirectory,file);
2295 search_attrib = SUBDIR; /*;AN000;*/
2296 status = Find_first(subdirectory,next,&search_attrib);
2297 while(status == NOERROR) {
2299 /* Check that this file is not a directory, system file, */
2300 /* or a hidden file. */
2301 if ( (next[0] != '.') &&
2302 ((search_attrib & SUBDIR) == 0) &&
2303 ((search_attrib & SYSTEM) == 0) &&
2304 ((search_attrib & HIDDEN) == 0) ) {
2305 status = Attrib(path,next);
2308 if (status == NOERROR) {
2309 search_attrib = SUBDIR; /*;AN000;*/
2310 status = Find_next(next,&search_attrib);
2314 if (status == NOMOREFILES)
2317 if (status != NOERROR) { /*;AN000;*/
2320 Dta_restore(dta_area,128);
2325 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2327 /* Subroutine Name: Check_appendx() */
2329 /* Subroutine Function: */
2330 /* Check APPEND /X status. If it is not active, */
2331 /* do nothing. If it is active, then turn it off */
2332 /* and set flag indicating that fact. */
2336 /* Output: append_active_flg */
2338 /* Normal exit: flag set if /X active */
2340 /* Error exit: None */
2342 /* Internal References: */
2345 /* External References: */
2348 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2350 Check_appendx() /*;AN000;*/
2352 void ctl_brk_handler(); /*;AN000;*/
2353 extern crit_err_handler(); /*;AN000;*/
2354 WORD *ptr; /*;AN000;*/
2356 inregs.x.ax = 0xb700; /* Is appendx installed ? */ /*;AN000;*/
2357 int86(0x2f,&inregs,&outregs); /*;AN000;*/
2358 if (outregs.h.al) { /*;AN000;*/
2359 inregs.x.ax = 0xb702; /* Get version */ /*;AN000;*/
2360 int86(0x2f,&inregs,&outregs); /*;AN000;*/
2361 if (outregs.x.ax == 0xffff) { /*;AN000;*/
2362 inregs.x.ax = 0xb706; /* Get /X status */ /*;AN000;*/
2363 int86(0x2f,&inregs,&outregs); /*;AN000;*/
2364 append_x_status = outregs.x.bx; /* save status to restore */ /*;AN000;*/
2366 /* turn off append /x */
2367 inregs.x.ax = 0xb707; /* Set /X status */ /*;AN000;*/
2368 inregs.x.bx = append_x_status & INACTIVE; /*;AN000;*/
2369 int86(0x2f,&inregs,&outregs); /*;AN000;*/
2373 /* get critical error handler vector for later */
2374 inregs.x.ax = 0x3524; /* get critical error vector */ /*;AN000;*/
2375 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
2376 ptr = (WORD *)&old_int24_off; /*;AN000;*/
2377 *ptr++ = (WORD)outregs.x.bx; /*;AN000;*/
2378 *ptr = (WORD)segregs.es; /*;AN000;*/
2380 /* set crtl-c & critical error handler vector */
2382 inregs.x.ax = 0x2523; /* crtl-c - int 23 */ /*;AN000;*/
2383 inregs.x.dx = (WORD) ctl_brk_handler; /*;AN000;*/
2384 segregs.ds = (WORD) segregs.cs; /*;AN000;*/
2385 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
2387 inregs.x.ax = 0x2524; /* critical err - int 24 */ /*;AN000;*/
2388 inregs.x.dx = (WORD) crit_err_handler; /*;AN000;*/
2389 segregs.ds = (WORD) segregs.cs; /*;AN000;*/
2390 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
2391 strcpy(fix_es_reg,NUL); /* restore ES register */ /*;AN000;*/
2395 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2397 /* Subroutine Name: Reset_appendx() */
2399 /* Subroutine Function: */
2400 /* Reset APPEND /X status. If it is not active, */
2401 /* do nothing. If it is active, then turn it on */
2402 /* and set flag indicating that fact. */
2406 /* Output: append_active_flg */
2408 /* Normal exit: flag set if /X active */
2410 /* Error exit: None */
2412 /* Internal References: */
2415 /* External References: */
2418 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2420 Reset_appendx() /*;AN000;*/
2422 if (append_x_status != 0) { /*;AN000;*/
2423 inregs.x.ax = 0xb707; /*;AN000;*/
2424 inregs.x.bx = append_x_status; /*;AN000;*/
2425 int86(0x2f,&inregs,&outregs); /*;AN000;*/
2430 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2432 /* Subroutine Name: Check_DBCS() */
2434 /* Subroutine Function: */
2435 /* Given an array and a position in the array, check if the character */
2436 /* is a non-DBCS character. */
2438 /* Input: array, character position, character */
2440 /* Output: TRUE - if array[position-1] != DBCS character AND */
2441 /* array[position] == character. */
2442 /* FALSE - otherwise */
2443 /* Normal exit: none */
2445 /* Error exit: None */
2447 /* Internal References: */
2450 /* External References: */
2453 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2454 WORD Check_DBCS(array,position,character) /*;AN000;*/
2455 char *array; /*;AN000;*/
2456 WORD position; /*;AN000;*/
2457 char character; /*;AN000;*/
2459 BYTE far *ptr; /*;AN000;*/
2462 char darray[128]; /* DBCS array, put "D" in every position*/ /*;AN000;*/
2463 /* that corresponds to the first byte */
2464 /* of a DBCS character. */
2465 for (i=0;i<128;i++) /*;AN000;*/
2466 darray[i] = ' '; /*;AN000;*/
2468 /* Check each character, starting with the first in string, for DBCS */
2469 /* characters and mark each with a "D" in the corresponding darray. */
2470 for (i=0;i<position;i++) { /*;AN000;*/
2471 c = array[i]; /*;AN000;*/
2473 /* look thru DBCS table to determine if character is first byte */
2474 /* of a double byte character */
2475 for (ptr=DBCS_ptr; (WORD)*(WORD far *)ptr != 0; ptr += 2) { /*;AN000;*/
2477 /* check if byte is within range values of DOS DBCS table */
2478 if (c >= *ptr && c <= *(ptr+1)) { /*;AN000;*/
2479 darray[i] = 'D'; /*;AN000;*/
2480 i++; /* skip over second byte of DBCS */ /*;AN000;*/
2486 /* if character is not DBCS then check to see if it is == to character */
2487 if (darray[position-1] != 'D' && character == array[position]) { /*;AN000;*/
2488 return (TRUE); /*;AN000;*/
2491 return (FALSE); /*;AN000;*/
2495 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2497 /* Subroutine Name: Get_DBCS_vector() */
2499 /* Subroutine Function: */
2500 /* Gets the double-byte table vector. */
2506 /* Normal exit: none */
2508 /* Error exit: None */
2510 /* Internal References: */
2513 /* External References: */
2516 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2517 Get_DBCS_vector() /*;AN000;*/
2519 WORD *ptr; /*;AN000;*/
2520 WORD *buffer; /*;AN000;*/
2521 DWORD far *addr_ptr; /*;AN000;*/
2523 /* allocate a buffer for DBCS table vector */
2524 buffer = Dallocate(5); /* at least 5 bytes big */ /*;AN000;*/
2526 inregs.x.ax = 0x6507; /* get extended country info */ /*;AN000;*/
2527 inregs.x.bx = -1; /* use active code page */ /*;AN000;*/
2528 inregs.x.cx = 5; /* 5 bytes of return data */ /*;AN000;*/
2529 inregs.x.dx = -1; /* use default country */ /*;AN000;*/
2530 inregs.x.di = 0; /* buffer offset */ /*;AN000;*/
2531 segregs.es = (WORD)buffer; /* buffer segment */ /*;AN000;*/
2532 intdosx(&inregs,&outregs,&segregs); /*;AN000;*/
2533 strcpy(fix_es_reg,NUL); /*;AN000;*/
2535 outregs.x.di++; /* skip over id byte */ /*;AN000;*/
2537 /* make a far ptr from ES:[DI] */
2538 addr_ptr = 0; /*;AN000;*/
2539 ptr = (WORD *)&addr_ptr; /*;AN000;*/
2540 *ptr = (WORD)outregs.x.di; /* get offset */ /*;AN000;*/
2542 *ptr = (WORD)segregs.es; /* get segment */ /*;AN000;*/
2543 DBCS_ptr = (BYTE far *)*addr_ptr; /*;AN000;*/
2544 DBCS_ptr += 2; /* skip over table length */ /*;AN000;*/
2546 /* DBCS_ptr points to DBCS table */ /*;AN000;*/
2547 strcpy(fix_es_reg,NUL); /*;AN000;*/
2552 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2554 /* Subroutine Name: Error_exit() */
2556 /* Subroutine Function: */
2557 /* displays an extended error message with - filename */
2559 /* Input: error_file_name[] must contain name of file, if needed for */
2560 /* message output. */
2566 /* Error exit: None */
2568 /* Internal References: */
2571 /* External References: */
2574 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2575 void Error_exit(msg_class,ext_err_num,subcnt) /*;AN000;*/
2577 int msg_class; /*;AN000;*/
2578 int ext_err_num; /*;AN000;*/
2579 int subcnt; /*;AN000;*/
2581 segread(&segregs); /*;AN000;*/
2582 msg_error.sub_value_seg = segregs.ds; /*;AN000;*/
2583 msg_error.sub_value = (WORD)error_file_name; /*;AN000;*/
2584 inregs.x.ax = (WORD)ext_err_num; /*;AN000;*/
2585 inregs.x.bx = STDERR; /*;AN000;*/
2586 inregs.x.cx = subcnt; /*;AN000;*/
2587 inregs.h.dh = (WORD)msg_class; /*;AN000;*/
2588 inregs.h.dl = NOINPUT; /*;AN000;*/
2589 inregs.x.si = (WORD)&msg_error; /*;AN000;*/
2590 sysdispmsg(&inregs,&outregs); /*;AN000;*/
2592 /* check for error printing message */
2593 if (outregs.x.cflag & CARRY) { /*;AN000;*/
2594 outregs.x.bx = (WORD) STDERR; /*;AN000;*/
2595 outregs.x.si = NOSUBPTR; /*;AN000;*/
2596 outregs.x.cx = NOSUBCNT; /*;AN000;*/
2597 outregs.h.dl = exterr_msg_class; /*;AN000;*/
2598 sysdispmsg(&outregs,&outregs); /*;AN000;*/
2601 Reset_appendx(); /* Reset APPEND /X status */ /*;AN000;*/
2602 exit(1); /*;AN000;*/
2607 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2609 /* Subroutine Name: Parse_err() */
2611 /* Subroutine Function: */
2612 /* displays an parser error message with - filename */
2614 /* Input: error_file_name[] must contain name of file, if needed for */
2615 /* message output. */
2621 /* Error exit: None */
2623 /* Internal References: */
2626 /* External References: */
2629 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2630 void Parse_err(error_num) /*;AN000;*/
2632 WORD error_num; /*;AN000;*/
2634 char *cptr; /*;AN000;*/
2635 char *sptr; /*;AN000;*/
2637 /* take out leading spaces, point to beginning of parameter */
2638 for (((int)sptr) = inregs.x.si; ((int)sptr) < outregs.x.si && *sptr == BLANK; sptr++) /*;AN000;*/
2639 /* null statement */ ; /*;AN000;*/
2641 /* find end of this parameter in command line and put end-of-string there */
2642 for (cptr = sptr; ((int)cptr) < outregs.x.si && *cptr != BLANK; cptr++) /*;AN000;*/
2643 /* null statement */ ; /*;AN000;*/
2644 *cptr = NUL; /*;AN000;*/
2645 strcpy(error_file_name,sptr); /*;AN000;*/
2647 /* check for messages with no parameter */
2648 if (error_num == p_op_missing) /*;AN000;*/
2649 Error_exit(ERR_PARSE,error_num,NOSUBCNT); /*;AN000;*/
2651 Error_exit(ERR_PARSE,error_num,ONEPARM); /*;AN000;*/
2657 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2659 /* Subroutine Name: ctl_brk_handler */
2661 /* Subroutine Function: */
2662 /* Crtl-break interrupt handler. */
2670 /* Error exit: None */
2672 /* Internal References: */
2675 /* External References: */
2678 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2679 void ctl_brk_handler()
2682 exit(3); /*;AN000;*/
2683 /* inregs.x.ax = 0x4c03; /* DOS terminate int call */ /*;AN000;*/
2684 /* intdos(&inregs,&outregs); /*;AN000;*/