summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/ATTRIB
diff options
context:
space:
mode:
authorGravatar Mark Zbikowski2024-04-25 21:24:10 +0100
committerGravatar Microsoft Open Source2024-04-25 22:32:27 +0000
commit2d04cacc5322951f187bb17e017c12920ac8ebe2 (patch)
tree80ee017efa878dfd5344b44249e6a241f2a7f6e2 /v4.0/src/CMD/ATTRIB
parentMerge pull request #430 from jpbaltazar/typoptbr (diff)
downloadms-dos-main.tar.gz
ms-dos-main.tar.xz
ms-dos-main.zip
MZ is back!HEADmain
Diffstat (limited to 'v4.0/src/CMD/ATTRIB')
-rw-r--r--v4.0/src/CMD/ATTRIB/ATTRIB.C2685
-rw-r--r--v4.0/src/CMD/ATTRIB/ATTRIB.H443
-rw-r--r--v4.0/src/CMD/ATTRIB/ATTRIB.LNK7
-rw-r--r--v4.0/src/CMD/ATTRIB/ATTRIB.SKL30
-rw-r--r--v4.0/src/CMD/ATTRIB/ATTRIBA.ASM480
-rw-r--r--v4.0/src/CMD/ATTRIB/MAKEFILE46
-rw-r--r--v4.0/src/CMD/ATTRIB/MSGRET.H60
-rw-r--r--v4.0/src/CMD/ATTRIB/PARSE.H185
-rw-r--r--v4.0/src/CMD/ATTRIB/_MSGRET.ASM233
-rw-r--r--v4.0/src/CMD/ATTRIB/_PARSE.ASM107
10 files changed, 4276 insertions, 0 deletions
diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.C b/v4.0/src/CMD/ATTRIB/ATTRIB.C
new file mode 100644
index 0000000..b12a470
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/ATTRIB.C
@@ -0,0 +1,2685 @@
1/* 0 */
2/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
3/* */
4/* Utility Name: ATTRIB.EXE */
5/* */
6/* Source File Name: ATTRIB.C */
7/* */
8/* Utility Function: */
9/* */
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. */
13/* */
14/* Status: ATTRIB Utility, DOS Version 4.0 */
15/* */
16/* Entry Point: inmain(line) */
17/* */
18/* Input: line = DOS command line parameters */
19/* */
20/* Exit-normal: attribute set, or attribute printed to output device */
21/* */
22/* Exit-error: error message written to standard error device */
23/* */
24/* Internal References: */
25/* */
26/* Routines: */
27/* */
28/* External References: */
29/* */
30/* Routines: */
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) */
39/* */
40/* Notes: */
41/* Syntax (Command Line) */
42/* */
43/* ATTRIB [+R|-R] [+A|-A] [d:][path]filename[.ext] [[id]|[id=value]] [/S] */
44/* */
45/* where: */
46/* */
47/* +R = Make file ReadOnly by setting READONLY bit */
48/* -R = Reset READONLY bit */
49/* +A = Set ARCHIVE bit */
50/* -A = Reset ARCHIVE bit */
51/* */
52/* id = Set or display the extended attribute named by id. */
53/* Only one id processed per invocation. id can be *. */
54/* */
55/* /S = Process subdirectories also */
56/* */
57/* Copyright 1988 Microsoft Corporation */
58/* */
59/* Revision History: */
60/* */
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 */
67/* */
68/* NOTE: */
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. */
71/* */
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/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
76
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;*/
84
85/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
86/* Beginning of code (variables declared in attrib.h) */
87/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
88
89/*
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.
93 */
94inmain(line) /*;AN000;*/
95 char *line; /*;AN000;*/
96{ /*;AN000;*/
97 main(line); /*;AN000;*/
98} /*;AN000;*/
99
100
101/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
102/* */
103/* Subroutine Name: main() */
104/* */
105/* Subroutine Function: */
106/* Parse the command line, makes a full path-filename, does the */
107/* appropriate function */
108/* */
109/* Input: none */
110/* */
111/* Output: none */
112/* */
113/* Normal exit: */
114/* */
115/* Error exit: None */
116/* */
117/* Internal References: */
118/* None */
119/* */
120/* External References: */
121/* None */
122/* */
123/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
124
125main(line) /*;AN000;*/
126 char *line; /*;AN000;*/
127{ /*;AN000;*/
128 WORD status; /*;AN000;*/
129
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;*/
135
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;*/
144
145 /* load messages */
146 sysloadmsg(&inregs,&outregs); /*;AN000;*/
147 if (outregs.x.cflag & CARRY) { /*;AN000;*/
148 sysdispmsg(&outregs,&outregs); /*;AN000;*/
149 Dexit(11); /*;AN000;*/
150 }
151
152 Check_appendx(); /* check APPEND /X status */ /*;AN000;*/
153 Get_DBCS_vector(); /* get double byte table */ /*;AN000;*/
154
155 /* parse command line */
156 status = Parse_it(line); /*;AN000;*/
157 if (status != NOERROR) { /*;AN000;*/
158 Parse_err(status); /*;AN000;*/
159 } /*;AN000;*/
160
161 /* Do extended attribute translations here */
162 Ext_translation(); /*;AN000;*/
163
164
165 /* Initialize any variables need for next phase of program */
166 segread(&segregs); /* init segment registers for DOS calls */ /*;AN000;*/
167
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;*/
172
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;*/
179 } /*;AN000;*/
180
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;*/
185 case 0: /*;AN000;*/
186 break; /*;AN000;*/
187 case 2: /* File not found */ /*;AN000;*/
188 Error_exit(ERR_EXTENDED,2,ONEPARM); /*;AN000;*/
189 break; /*;AN000;*/
190 case 3: /* Path not found */ /*;AN000;*/
191 Error_exit(ERR_EXTENDED,3,ONEPARM); /*;AN000;*/
192 break; /*;AN000;*/
193 case 5: /* Access Denied */ /*;AN000;*/
194 Error_exit(ERR_EXTENDED,5,ONEPARM); /*;AN000;*/
195 break; /*;AN000;*/
196 case 15: /* Invalid drive specification */ /*;AN000;*/
197 Error_exit(ERR_EXTENDED,15,ONEPARM); /*;AN000;*/
198 break; /*;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;*/
203 break; /*;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;*/
208 break; /*;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;*/
213 break; /*;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;*/
218 break; /*;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;*/
223 break; /*;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;*/
228 break; /*;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;*/
233 break; /*;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;*/
238 break; /*;AN000;*/
239 default: /* Access Denied */ /*;AN000;*/
240 Error_exit(ERR_EXTENDED,5,ONEPARM); /*;AN000;*/
241 break; /*;AN000;*/
242 } /*;AN000;*/
243 Reset_appendx(); /*;AN000;*/
244
245
246
247} /* end of inmain */ /*;AN000;*/
248
249
250/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
251/* */
252/* Subroutine Name: Display_msg */
253/* */
254/* Subroutine Function: */
255/* Display the requested message to a given output device */
256/* */
257/* Input: */
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 */
263/* */
264/* Output: */
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. */
268/* */
269/* Normal exit: Message written to handle */
270/* */
271/* Error exit: None */
272/* */
273/* Internal References: */
274/* None */
275/* */
276/* External References: */
277/* Sysdispmsg (module _msgret.sal) */
278/* */
279/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
280
281Display_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;*/
287{
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;*/
295
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;*/
303 } /*;AN000;*/
304}
305
306
307/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
308/* */
309/* Subroutine Name: Ext_translation() */
310/* */
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". */
315/* */
316/* Input: none */
317/* */
318/* Output: none */
319/* */
320/* Normal exit: */
321/* */
322/* Error exit: None */
323/* */
324/* Internal References: */
325/* None */
326/* */
327/* External References: */
328/* None */
329/* */
330/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
331
332Ext_translation() /*;AN000;*/
333{ /*;AN000;*/
334 if (strcmp(ext_attr,"CODEPAGE") == 0) { /*;AN000;*/
335 strcpy(ext_attr,"CP"); /*;AN000;*/
336 } /*;AN000;*/
337} /*;AN000;*/
338
339
340/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
341/* */
342/* Subroutine Name: Get_far_str() */
343/* */
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. */
347/* */
348/* Input: none */
349/* */
350/* Output: none */
351/* */
352/* Normal exit: target = source */
353/* */
354/* Error exit: None */
355/* */
356/* Internal References: */
357/* None */
358/* */
359/* External References: */
360/* None */
361/* */
362/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
363
364Get_far_str(target,source,length) /*;AN000;*/
365 char *target; /*;AN000;*/
366 DWORD *source; /* segment = cs register */ /*;AN000;*/
367 WORD length; /*;AN000;*/
368{ /*;AN000;*/
369 char far *fptr; /*;AN000;*/
370 WORD i; /*;AN000;*/
371
372 if (length == 0) { /*;AN000;*/
373
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;*/
378 } /*;AN000;*/
379 else {
380
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;*/
385 }
386 strcpy(fix_es_reg,NUL); /* fix for es reg. after using far ptr */ /*;AN000;*/
387} /*;AN000;*/
388
389
390/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
391/* */
392/* Subroutine Name: Dexit() */
393/* */
394/* Subroutine Function: */
395/* Does a DOS terminate. */
396/* */
397/* Input: none */
398/* */
399/* Output: none */
400/* */
401/* Normal exit: target = source */
402/* */
403/* Error exit: None */
404/* */
405/* Internal References: */
406/* None */
407/* */
408/* External References: */
409/* None */
410/* */
411/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
412
413Dexit(s) /*;AN000;*/
414 WORD s; /*;AN000;*/
415{ /*;AN000;*/
416 Reset_appendx(); /* Reset APPEND /X status */ /*;AN000;*/
417
418/* inregs.h.ah = (BYTE)0x4c; /*;AN003; ;AN000;*/
419/* inregs.h.al = (BYTE)s; /*;AN003; ;AN000;*/
420/* intdos(&inregs,&outregs); /*terminate*/ /*;AN003; ;AN000;*/
421
422 /* if it didn't work - kill it */
423 exit(); /*;AN000;*/
424} /*;AN000;*/
425
426
427/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
428/* */
429/* Subroutine Name: Dallocate() */
430/* */
431/* Subroutine Function: */
432/* Does a DOS allocate of length (in paragraphs). */
433/* */
434/* Input: none */
435/* */
436/* Output: none */
437/* */
438/* Normal exit: target = source */
439/* */
440/* Error exit: None */
441/* */
442/* Internal References: */
443/* None */
444/* */
445/* External References: */
446/* None */
447/* */
448/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
449
450WORD *Dallocate(s) /*;AN000;*/
451 WORD s; /* length in bytes */ /*;AN000;*/
452{ /*;AN000;*/
453 WORD length; /*length in paragraphs */ /*;AN000;*/
454
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;*/
461 } /*;AN000;*/
462 return((WORD *)outregs.x.ax); /*;AN000;*/
463} /*;AN000;*/
464
465
466/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
467/* */
468/* Subroutine Name: Dfree() */
469/* */
470/* Subroutine Function: */
471/* Does a DOS de-allocate. */
472/* */
473/* Input: none */
474/* */
475/* Output: none */
476/* */
477/* Normal exit: target = source */
478/* */
479/* Error exit: None */
480/* */
481/* Internal References: */
482/* None */
483/* */
484/* External References: */
485/* None */
486/* */
487/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
488
489Dfree(segment) /*;AN000;*/
490 WORD segment; /*;AN000;*/
491{ /*;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;*/
497 } /*;AN000;*/
498 strcpy(fix_es_reg,NUL); /* fix for es reg. after using far ptr */ /*;AN000;*/
499} /*;AN000;*/
500
501
502/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
503/* */
504/* Subroutine Name: Copy_far_ptr() */
505/* */
506/* Subroutine Function: */
507/* Copies a far ptr declared in any form to a real far ptr variable. */
508/* */
509/* Input: none */
510/* */
511/* Output: none */
512/* */
513/* Normal exit: status = NOERROR */
514/* */
515/* Error exit: None */
516/* */
517/* Internal References: */
518/* None */
519/* */
520/* External References: */
521/* None */
522/* */
523/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
524
525Copy_far_ptr(p1_addr, p2_addr) /*;AN000;*/
526 DWORD *p1_addr; /*;AN000;*/
527 WORD *p2_addr; /*;AN000;*/
528{ /*;AN000;*/
529 WORD *dptr, *tptr; /*;AN000;*/
530
531 dptr = (WORD *)p2_addr; /*;AN000;*/
532 tptr = (WORD *)p1_addr; /*;AN000;*/
533
534 *tptr++ = *dptr++; /*;AN000;*/
535 *tptr = *dptr; /*;AN000;*/
536 strcpy(fix_es_reg,NUL); /* fix ES register */ /*;AN000;*/
537} /*;AN000;*/
538
539/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
540/* */
541/* Subroutine Name: Parse_it() */
542/* */
543/* Subroutine Function: */
544/* Parses the command line and returns error status. */
545/* */
546/* Input: line */
547/* */
548/* Output: various control variables are set */
549/* */
550/* Normal exit: status = NOERROR */
551/* */
552/* Error exit: None */
553/* */
554/* Internal References: */
555/* None */
556/* */
557/* External References: */
558/* None */
559/* */
560/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
561
562WORD Parse_it(line) /*;AN000;*/
563 char *line; /*;AN000;*/
564{ /*;AN000;*/
565 WORD i; /*;AN000;*/
566 WORD status; /*;AN000;*/
567 WORD no_value; /*;AN000;*/
568 WORD got_fn; /* got filename - required parameter */ /*;AN000;*/
569 WORD pa, /*;AN000;*/
570 ma, /*;AN000;*/
571 pr, /*;AN000;*/
572 mr; /*;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;*/
578
579 /* do setup for parser */
580 for (i=0; i<4; i++) { /*;AN000;*/
581 p_mask[i] = m_mask[i] = 0; /*;AN000;*/
582 } /*;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;*/
589
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;*/
594
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;*/
599
600 /* check for errors, continue if none */
601 if (status == p_no_error) { /*;AN000;*/
602
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;*/
607 } /*;AN000;*/
608 else { /*;AN000;*/
609 m_mask[0] |= pos1_buff.p_item_tag; /*;AN000;*/
610 } /*;AN000;*/
611 set_reg_attr = TRUE; /*;AN000;*/
612 do_reg_attr = FALSE; /*;AN000;*/
613 } /*;AN000;*/
614
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;*/
619 } /*;AN000;*/
620 else { /*;AN000;*/
621 m_mask[1] |= pos2_buff.p_item_tag; /*;AN000;*/
622 } /*;AN000;*/
623 set_reg_attr = TRUE; /*;AN000;*/
624 do_reg_attr = FALSE; /*;AN000;*/
625 } /*;AN000;*/
626
627 /* check if third positional */
628 if (outregs.x.dx == (WORD)&pos3_buff) { /*;AN000;*/
629
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;*/
633 } /*;AN000;*/
634
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;*/
639 } /*;AN000;*/
640 else { /*;AN000;*/
641 m_mask[2] |= pos4_buff.p_item_tag; /*;AN000;*/
642 } /*;AN000;*/
643 set_reg_attr = TRUE; /*;AN000;*/
644 do_reg_attr = FALSE; /*;AN000;*/
645 } /*;AN000;*/
646
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;*/
651 } /*;AN000;*/
652 else { /*;AN000;*/
653 m_mask[3] |= pos5_buff.p_item_tag; /*;AN000;*/
654 } /*;AN000;*/
655 set_reg_attr = TRUE; /*;AN000;*/
656 do_reg_attr = FALSE; /*;AN000;*/
657 } /*;AN000;*/
658
659 /* check if sixth positional */
660 if (outregs.x.dx == (WORD)&pos6_buff) { /*;AN000;*/
661
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;*/
666 } /*;AN000;*/
667
668 /* check if value of sixth positional */
669 if (outregs.x.dx == (WORD)&pos6b_buff) { /*;AN000;*/
670
671 /* parse a value that is complex (in parenthesis). */
672 if (pos6b_buff.p_type == p_complex) { /*;AN000;*/
673
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;*/
682 break; /*;AN000;*/
683 } /*;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;*/
687 } /*;AN000;*/
688 status = p_no_error; /*;AN000;*/
689 ext_attr_value_type = EAISASCII; /*;AN000;*/
690 } /*;AN000;*/
691 else /*;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;*/
697 } /*;AN000;*/
698
699 /* check for '/S' switch */
700 if (outregs.x.dx == (WORD)&sw_buff) { /*;AN000;*/
701
702 /* check if duplicate switch */
703 if (descending == TRUE) { /*;AN000;*/
704 status = p_syntax; /*;AN000;*/
705 } /*;AN000;*/
706 descending = TRUE; /*;AN000;*/
707 } /*;AN000;*/
708 } /* if no error */ /*;AN000;*/
709
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;*/
715
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;*/
722 else /*;AN000;*/
723 status = p_no_error; /*;AN000;*/
724 strcpy(fix_es_reg,NUL); /*;AN000;*/
725
726 continue; /* go back up to while loop */ /*;AN000;*/
727 } /*;AN000;*/
728
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;*/
737 } /*;AN000;*/
738
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;*/
742 } /*;AN000;*/
743 } /* while loop */ /*;AN000;*/
744
745 /* check error status and if at end of line */
746 if (status == p_rc_eol) { /*;AN000;*/
747 status = p_no_error; /*;AN000;*/
748 } /*;AN000;*/
749
750 /* Check for filename on command line */
751 if (!got_fn && status == p_no_error) { /*;AN000;*/
752 status = p_op_missing; /*;AN000;*/
753 } /*;AN000;*/
754
755 /* Check for keyword and equal sign but no value */
756 if (!no_value) { /*;AN000;*/
757 status = p_syntax; /*;AN000;*/
758 } /*;AN000;*/
759
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;*/
763 pr++; /*;AN000;*/
764 if (m_mask[i] & READONLY) /*;AN000;*/
765 mr++; /*;AN000;*/
766 if (p_mask[i] & ARCHIVE) /*;AN000;*/
767 pa++; /*;AN000;*/
768 if (m_mask[i] & ARCHIVE) /*;AN000;*/
769 ma++; /*;AN000;*/
770 } /*;AN000;*/
771 if ((pr > 1) || (mr > 1) || (pa > 1) || (ma > 1)) { /*;AN000;*/
772 status = p_syntax; /*;AN000;*/
773 } /*;AN000;*/
774 else { /*;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;*/
778 } /*;AN000;*/
779 } /*;AN000;*/
780
781 /* check for duplicate -R +R or -A +A */
782 if ((pmask & mmask & READONLY) || (pmask & mmask & ARCHIVE)) { /*;AN000;*/
783 status = p_syntax; /*;AN000;*/
784 } /*;AN000;*/
785 return(status); /*;AN000;*/
786} /*;AN000;*/
787
788
789/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
790/* */
791/* Subroutine Name: Determine_type() */
792/* */
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. */
796/* */
797/* Input: none */
798/* */
799/* Output: none */
800/* */
801/* Normal exit: target = source */
802/* */
803/* Error exit: None */
804/* */
805/* Internal References: */
806/* None */
807/* */
808/* External References: */
809/* None */
810/* */
811/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
812
813Determine_type(parser_type,result_ptr) /*;AN000;*/
814 WORD parser_type; /*;AN000;*/
815 WORD *result_ptr; /*;AN000;*/
816{ /*;AN000;*/
817 DWORD number; /*;AN000;*/
818 char string[129]; /*;AN000;*/
819
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;*/
827 } /*;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;*/
831 } /*;AN000;*/
832 else { /*;AN000;*/
833 ext_attr_value.ea_bin.length = 1; /*;AN000;*/
834 ext_attr_value.ea_bin.dword = number; /*;AN000;*/
835 } /*;AN000;*/
836 break; /*;AN000;*/
837
838 case p_complex: /*;AN000;*/
839
840 /* Taken care of in Parse_it() */
841 break; /*;AN000;*/
842
843 case p_string: /*;AN000;*/
844 case p_quoted_string: /*;AN000;*/
845 Get_far_str(string,result_ptr,0); /*;AN000;*/
846
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;*/
851 } /*;AN000;*/
852 else if (strcmp(string,"OFF") == 0) { /*;AN000;*/
853 ext_attr_value.ea_logical = FALSE; /*;AN000;*/
854 ext_attr_value_type = EAISLOGICAL; /*;AN000;*/
855 } /*;AN000;*/
856 else { /*;AN000;*/
857 strcpy(ext_attr_value.ea_ascii,string); /*;AN000;*/
858 ext_attr_value_type = EAISASCII; /*;AN000;*/
859 } /*;AN000;*/
860 break; /*;AN000;*/
861
862 default: /*;AN000;*/
863 ext_attr_value_type = EAISUNDEF; /*;AN000;*/
864 ext_attr_value.ea_undef = TRUE; /*;AN000;*/
865 break; /*;AN000;*/
866 } /*;AN000;*/
867} /*;AN000;*/
868
869
870/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
871/* */
872/* Subroutine Name: Make_fspec() */
873/* */
874/* Subroutine Function: */
875/* Makes a full path-filename from the filename & current directory */
876/* information. */
877/* */
878/* Input: none */
879/* */
880/* Output: none */
881/* */
882/* Normal exit: */
883/* */
884/* Error exit: None */
885/* */
886/* Internal References: */
887/* None */
888/* */
889/* External References: */
890/* None */
891/* */
892/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
893
894WORD Make_fspec(fspec) /*;AN000;*/
895 char *fspec; /*;AN000;*/
896{ /*;AN000;*/
897 WORD Check_DBCS(); /* forward declaration */ /*;AN000;*/
898
899 char path[256]; /*;AN000;*/
900 WORD status; /*;AN000;*/
901 WORD i,j; /*;AN000;*/
902
903 status = NOERROR; /*;AN000;*/
904
905 strcpy(path,fspec); /*;AN000;*/
906
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;*/
915 } /*;AN000;*/
916
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;*/
926
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;*/
932 } /*;AN000;*/
933 } /*;AN000;*/
934
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;*/
938 i++; /*;AN000;*/
939 j = 0; /*;AN000;*/
940 while (fspec[i+j] != '\0') { /*;AN000;*/
941 file[j] = fspec[i+j]; /*;AN000;*/
942 fspec[i+j] = '\0'; /*;AN000;*/
943 j++; /*;AN000;*/
944 } /*;AN000;*/
945 file[j] = '\0'; /*;AN000;*/
946
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;*/
953 }
954
955 return(status); /*;AN000;*/
956} /*;AN000;*/
957
958
959/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
960/* */
961/* Subroutine Name: Dta_save() */
962/* */
963/* Subroutine Function: */
964/* saves an area in the PSP, but who knows. */
965/* Input: none */
966/* */
967/* Output: none */
968/* */
969/* Normal exit: */
970/* */
971/* Error exit: None */
972/* */
973/* Internal References: */
974/* None */
975/* */
976/* External References: */
977/* None */
978/* */
979/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
980
981Dta_save(t,l)
982 char *t;
983 unsigned l;
984{
985 unsigned i;
986
987 for (i = 0; i < l; i++) *(t+i) = getpspbyte(0x80+i)
988 /* null statement */ ;
989 }
990
991
992/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
993/* */
994/* Subroutine Name: Dta_restore() */
995/* */
996/* Subroutine Function: */
997/* Restores the data that was saved in Dta_save(). */
998/* Input: none */
999/* */
1000/* Output: none */
1001/* */
1002/* Normal exit: target = source */
1003/* */
1004/* Error exit: None */
1005/* */
1006/* Internal References: */
1007/* None */
1008/* */
1009/* External References: */
1010/* None */
1011/* */
1012/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1013
1014Dta_restore(t,l)
1015 char *t;
1016 unsigned l;
1017{
1018 unsigned i;
1019
1020 for (i = 0; i < l; i++) putpspbyte(0x80+i,*(t+i))
1021 /* null statement */ ;
1022}
1023
1024
1025/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1026/* */
1027/* Subroutine Name: Find_first() */
1028/* */
1029/* Subroutine Function: */
1030/* */
1031/* Input: none */
1032/* */
1033/* Output: none */
1034/* */
1035/* Normal exit: */
1036/* */
1037/* Error exit: None */
1038/* */
1039/* Internal References: */
1040/* None */
1041/* */
1042/* External References: */
1043/* None */
1044/* */
1045/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1046
1047WORD Find_first(s,f,a)
1048 char *s;
1049 char *f;
1050 WORD *a;
1051{
1052 WORD status;
1053 WORD i;
1054 WORD o;
1055 char *t;
1056
1057 t = f;
1058 *f = '\0';
1059
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;
1065
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);
1071 status = NOERROR;
1072 }
1073 return(status);
1074}
1075
1076
1077/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1078/* */
1079/* Subroutine Name: Find_next() */
1080/* */
1081/* Subroutine Function: */
1082/* */
1083/* Input: none */
1084/* */
1085/* Output: none */
1086/* */
1087/* Normal exit: */
1088/* */
1089/* Error exit: None */
1090/* */
1091/* Internal References: */
1092/* None */
1093/* */
1094/* External References: */
1095/* None */
1096/* */
1097/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1098
1099WORD Find_next(f,a)
1100 char *f;
1101 WORD *a;
1102{
1103 WORD status;
1104 WORD i;
1105 WORD o;
1106 char *t;
1107
1108 t = f;
1109 *f = '\0';
1110
1111 inregs.x.ax = 0x4f00; /* DOS find next */
1112 intdos(&inregs,&outregs);
1113 status = outregs.x.ax;
1114
1115 if (!(outregs.x.cflag & CARRY)) {
1116 for (i = 0; i < 14; i++)
1117 *f++ = getpspbyte(0x80+30+i);
1118 *a = getpspbyte(0x80+21);
1119 status = NOERROR;
1120 }
1121 return(status);
1122}
1123
1124
1125/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1126/* */
1127/* Subroutine Name: Get_reg_attrib() */
1128/* */
1129/* Subroutine Function: */
1130/* Does a DOS get attribute byte. */
1131/* */
1132/* Input: none */
1133/* */
1134/* Output: none */
1135/* */
1136/* Normal exit: return = 0 */
1137/* */
1138/* Error exit: return = error code */
1139/* */
1140/* Internal References: */
1141/* None */
1142/* */
1143/* External References: */
1144/* None */
1145/* */
1146/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1147
1148WORD Get_reg_attrib(fspec,attr_byte) /*;AN000;*/
1149 char *fspec; /*;AN000;*/
1150 BYTE *attr_byte; /*;AN000;*/
1151{ /*;AN000;*/
1152 WORD status; /*;AN000;*/
1153
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;*/
1158
1159 /* Check for error */ /*;AN000;*/
1160 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1161 *attr_byte = (BYTE)outregs.h.cl; /*;AN000;*/
1162 status = NOERROR; /*;AN000;*/
1163 } /*;AN000;*/
1164 return(status); /*;AN000;*/
1165} /*;AN000;*/
1166
1167
1168/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1169/* */
1170/* Subroutine Name: Ext_open() */
1171/* */
1172/* Subroutine Function: */
1173/* Does a DOS extended open of a filename and returns a file handle.*/
1174/* */
1175/* Input: none */
1176/* */
1177/* Output: none */
1178/* */
1179/* Normal exit: handle = file handle, return = 0 */
1180/* */
1181/* Error exit: handle = ?; return = error code */
1182/* */
1183/* Internal References: */
1184/* None */
1185/* */
1186/* External References: */
1187/* None */
1188/* */
1189/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1190
1191WORD Ext_open(fspec,handle) /*;AN000;*/
1192 char *fspec; /*;AN000;*/
1193 WORD *handle; /*;AN000;*/
1194{ /*;AN000;*/
1195 WORD status; /*;AN000;*/
1196
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;*/
1205
1206 /* Check for error */ /*;AN000;*/
1207 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1208 *handle = outregs.x.ax; /*;AN000;*/
1209 status = NOERROR; /*;AN000;*/
1210 } /*;AN000;*/
1211 return(status); /*;AN000;*/
1212} /*;AN000;*/
1213
1214
1215/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1216/* */
1217/* Subroutine Name: Get_ext_attrib() */
1218/* */
1219/* Subroutine Function: */
1220/* Does a DOS Get extended attributes and returns far ptr to list. */
1221/* */
1222/* Input: none */
1223/* */
1224/* Output: none */
1225/* */
1226/* Normal exit: handle = file handle, return = 0 */
1227/* */
1228/* Error exit: handle = ?; return = error code */
1229/* */
1230/* Internal References: */
1231/* None */
1232/* */
1233/* External References: */
1234/* None */
1235/* */
1236/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1237
1238WORD 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;*/
1242{ /*;AN000;*/
1243 WORD status; /*;AN000;*/
1244 WORD attr_size; /*;AN000;*/
1245 WORD *list_seg; /*;AN000;*/
1246 WORD *ptr; /*;AN000;*/
1247
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;*/
1255
1256 /* if no errors then get extended attributes */
1257 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1258 attr_size = outregs.x.cx; /*;AN000;*/
1259
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;*/
1265 else /*;AN000;*/
1266 list_seg = Dallocate(MAX_ATTR_SIZE); /*;AN000;*/
1267
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;*/
1278
1279 /* if no errors then fix up far pointer to list */
1280 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1281
1282 /* convert segment returned from Dallocate to far ptr */
1283 *list_ptr = 0; /*;AN000;*/
1284 ptr = (WORD *)list_ptr; /*;AN000;*/
1285 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;*/
1290 } /*;AN000;*/
1291 } /*;AN000;*/
1292 return(status); /*;AN000;*/
1293} /*;AN000;*/
1294
1295
1296/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1297/* */
1298/* Subroutine Name: Get_ext_attr_names() */
1299/* */
1300/* Subroutine Function: */
1301/* Does a DOS Get extended attribute names and return a far ptr to */
1302/* the querylist of names. */
1303/* */
1304/* Input: none */
1305/* */
1306/* Output: none */
1307/* */
1308/* Normal exit: handle = file handle, return = 0 */
1309/* */
1310/* Error exit: handle = ?; return = error code */
1311/* */
1312/* Internal References: */
1313/* None */
1314/* */
1315/* External References: */
1316/* None */
1317/* */
1318/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1319
1320WORD 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;*/
1324{ /*;AN000;*/
1325 WORD status; /*;AN000;*/
1326 WORD attr_size; /*;AN000;*/
1327 WORD *list_seg; /*;AN000;*/
1328 WORD *ptr; /*;AN000;*/
1329
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;*/
1336
1337 /* if no errors then get extended attribute names */
1338 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1339 attr_size = outregs.x.cx; /*;AN000;*/
1340
1341 /* allocate buffer space for extended attr. list */
1342 list_seg = Dallocate(attr_size); /*;AN000;*/
1343
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;*/
1354
1355 /* if no errors then fix up far pointer to list */
1356 if (!(outregs.x.cflag & CARRY)) { /*;AN000;*/
1357
1358 /* convert segment returned from Dallocate to far ptr */
1359 *list_ptr = 0; /*;AN000;*/
1360 ptr = (WORD *)list_ptr; /*;AN000;*/
1361 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;*/
1367 } /*;AN000;*/
1368 } /*;AN000;*/
1369 return(status); /*;AN000;*/
1370} /*;AN000;*/
1371
1372
1373/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1374/* */
1375/* Subroutine Name: Set_reg_attrib() */
1376/* */
1377/* Subroutine Function: */
1378/* Sets the attribute byte of a file (not extended attributes). */
1379/* */
1380/* Input: none */
1381/* */
1382/* Output: none */
1383/* */
1384/* Normal exit: */
1385/* */
1386/* Error exit: None */
1387/* */
1388/* Internal References: */
1389/* None */
1390/* */
1391/* External References: */
1392/* None */
1393/* */
1394/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1395
1396WORD Set_reg_attrib(fspec,attr_byte) /*;AN000;*/
1397 char *fspec; /*;AN000;*/
1398 BYTE attr_byte; /*;AN000;*/
1399{ /*;AN000;*/
1400 WORD status; /*;AN000;*/
1401
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;*/
1409 /*;AN000;*/
1410 /* Check for error */
1411 if (!(outregs.x.cflag & CARRY))
1412 status = NOERROR; /*;AN000;*/
1413 return(status); /*;AN000;*/
1414} /*;AN000;*/
1415
1416
1417/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1418/* */
1419/* Subroutine Name: Set_ext_attrib() */
1420/* */
1421/* Subroutine Function: */
1422/* Set an extended attribute for a file. */
1423/* */
1424/* Input: none */
1425/* */
1426/* Output: none */
1427/* */
1428/* Normal exit: */
1429/* */
1430/* Error exit: None */
1431/* */
1432/* Internal References: */
1433/* None */
1434/* */
1435/* External References: */
1436/* None */
1437/* */
1438/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1439
1440WORD Set_ext_attrib(handle,list_ptr) /*;AN000;*/
1441 WORD handle; /*;AN000;*/
1442 WORD far *list_ptr; /*;AN000;*/
1443{ /*;AN000;*/
1444 WORD status; /*;AN000;*/
1445
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;*/
1453 /*;AN000;*/
1454 /* Check for error */
1455 if (!(outregs.x.cflag & CARRY)) /*;AN000;*/
1456 status = NOERROR; /*;AN000;*/
1457 return(status); /*;AN000;*/
1458} /*;AN000;*/
1459
1460
1461/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1462/* */
1463/* Subroutine Name: CheckYN() */
1464/* */
1465/* Subroutine Function: */
1466/* Check for a valid Yes/No answer. */
1467/* */
1468/* Input: none */
1469/* */
1470/* Output: none */
1471/* */
1472/* Normal exit: */
1473/* */
1474/* Error exit: None */
1475/* */
1476/* Internal References: */
1477/* None */
1478/* */
1479/* External References: */
1480/* None */
1481/* */
1482/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1483
1484WORD CheckYN(fspec) /*;AN000;*/
1485 char *fspec; /*;AN000;*/
1486{ /*;AN000;*/
1487 WORD answer; /*;AN000;*/
1488 WORD key; /*;AN000;*/
1489
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;*/
1500
1501 if (answer == YES || answer == NO) /*;AN000;*/
1502 break; /*;AN000;*/
1503 } /*;AN000;*/
1504 return(answer); /*;AN000;*/
1505} /*;AN000;*/
1506
1507
1508/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1509/* */
1510/* Subroutine Name: Find_ext_attrib() */
1511/* */
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. */
1516/* */
1517/* Input: none */
1518/* */
1519/* Output: none */
1520/* */
1521/* Normal exit: target = source */
1522/* */
1523/* Error exit: None */
1524/* */
1525/* Internal References: */
1526/* None */
1527/* */
1528/* External References: */
1529/* None */
1530/* */
1531/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1532
1533WORD 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;*/
1538{ /*;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;*/
1544
1545 found = FALSE; /*;AN000;*/
1546
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;*/
1549
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;*/
1556 break; /*;AN000;*/
1557 } /*;AN000;*/
1558 } /*;AN000;*/
1559 if (match) { /*;AN000;*/
1560 found = TRUE; /*;AN000;*/
1561 break; /*;AN000;*/
1562 } /*;AN000;*/
1563 } /*;AN000;*/
1564
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;*/
1569 } /*;AN000;*/
1570
1571 /* found the extended attribute wanted, pass addr back */
1572 if (found) { /*;AN000;*/
1573 *addr = ptr; /*;AN000;*/
1574 } /*;AN000;*/
1575 strcpy(fix_es_reg,NUL); /*;AN000;*/
1576 return(found); /*;AN000;*/
1577} /*;AN000;*/
1578
1579
1580/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1581/* */
1582/* Subroutine Name: Print_ext_attrib() */
1583/* */
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. */
1588/* */
1589/* Input: none */
1590/* */
1591/* Output: none */
1592/* */
1593/* Normal exit: target = source */
1594/* */
1595/* Error exit: None */
1596/* */
1597/* Internal References: */
1598/* None */
1599/* */
1600/* External References: */
1601/* None */
1602/* */
1603/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1604
1605WORD 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;*/
1611{ /*;AN000;*/
1612 WORD status; /*;AN000;*/
1613 WORD i; /*;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;*/
1620
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;*/
1626
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;*/
1633 break; /*;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;*/
1638 else /*;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;*/
1643 break; /*;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;*/
1648 } /*;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;*/
1652 } /*;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;*/
1656 } /*;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;*/
1662 break; /*;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;*/
1670 break; /*;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;*/
1677 break; /*;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;*/
1684 break; /*;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;*/
1689
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;*/
1694 } /*;AN000;*/
1695
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;*/
1700
1701 msg_str2.sub_value = (WORD)string; /*;AN000;*/
1702 Display_msg(8,STDOUT,ONEPARM,&msg_str2,NOINPUT); /*;AN000;*/
1703
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;*/
1708 } /*;AN000;*/
1709 Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
1710 Display_msg(14,STDOUT,NOSUBPTR,NOSUBCNT,NOINPUT); /*;AN000;*/
1711 break; /*;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;*/
1716 break; /*;AN000;*/
1717 } /* endswitch */ /*;AN000;*/
1718 return(status); /*;AN000;*/
1719} /*;AN000;*/
1720
1721/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1722/* */
1723/* Subroutine Name: Convert_date */
1724/* */
1725/* Subroutine Function: */
1726/* Convert date word returned by DOS to the form required by the */
1727/* message retriever. */
1728/* */
1729/* DOS returns: yyyyyyym mmmddddd */
1730/* */
1731/* y = 0-119 (1980-2099) */
1732/* m = 1-12 */
1733/* d = 1-31 */
1734/* */
1735/* Message retriever requires: yyyyyyyy yyyyyyyy mmmmmmmm dddddddd */
1736/* */
1737/* Input: */
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) */
1741/* */
1742/* Output: */
1743/* Double word result updated with date in form required by */
1744/* message retriever. */
1745/* */
1746/* Normal exit: Result word updated */
1747/* */
1748/* Error exit: None */
1749/* */
1750/* Internal References: */
1751/* None */
1752/* */
1753/* External References: */
1754/* None */
1755/* */
1756/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1757
1758Convert_date(dosdate,msgdate1,msgdate2)
1759 WORD dosdate;
1760 WORD *msgdate1;
1761 WORD *msgdate2;
1762{
1763 WORD day,month,year;
1764
1765 year = dosdate;
1766 year = ((year >> 1) & 0x7f00) + 80*256; /* DOS year + 80 */
1767 year = (year >> 8) & 0x007f; /*;AN000;*/
1768 day = dosdate;
1769 day = (day << 8) & 0x1f00;
1770 month = dosdate;
1771 month = (month >> 5) & 0x000f;
1772 *msgdate1 = year;
1773 *msgdate2 = month | day;
1774}
1775
1776
1777/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1778/* */
1779/* Subroutine Name: Convert_time */
1780/* */
1781/* Subroutine Function: */
1782/* Convert time word returned by DOS to the form required by the */
1783/* message retriever. */
1784/* */
1785/* DOS returns: hhhhhmmm mmmsssss */
1786/* */
1787/* h = hours (0-23) */
1788/* m = minutes (0-59) */
1789/* s = seconds/2 */
1790/* */
1791/* Message retriever requires: hhhhhhhh mmmmmmmm ssssssss hhhhhhhh */
1792/* */
1793/* Input: */
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) */
1797/* */
1798/* Output: */
1799/* Double word result updated with time in form required by */
1800/* message retriever. */
1801/* */
1802/* Normal exit: Result word updated */
1803/* */
1804/* Error exit: None */
1805/* */
1806/* Internal References: */
1807/* None */
1808/* */
1809/* External References: */
1810/* None */
1811/* */
1812/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1813
1814Convert_time(dostime,msgtime1,msgtime2)
1815 WORD dostime;
1816 WORD *msgtime1;
1817 WORD *msgtime2;
1818{
1819 WORD hours,minutes,seconds;
1820
1821 hours = dostime;
1822 hours = hours >> 11 & 0x001f;
1823 seconds = dostime;
1824 seconds = seconds & 0x001f * 2; /* seconds * 2 */
1825 minutes = dostime;
1826 minutes = minutes << 3 & 0x3f00;
1827 *msgtime1 = hours | minutes;
1828 *msgtime2 = seconds;
1829}
1830
1831
1832/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1833/* */
1834/* Subroutine Name: Regular_attrib() */
1835/* */
1836/* Subroutine Function: */
1837/* Handles all function for archive bit and read-only bit. */
1838/* */
1839/* Input: none */
1840/* */
1841/* Output: none */
1842/* */
1843/* Normal exit: */
1844/* */
1845/* Error exit: None */
1846/* */
1847/* Internal References: */
1848/* None */
1849/* */
1850/* External References: */
1851/* None */
1852/* */
1853/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1854
1855WORD Regular_attrib(fspec) /*;AN000;*/
1856 char *fspec; /*;AN000;*/
1857{ /*;AN000;*/
1858 WORD status; /*;AN000;*/
1859 WORD i; /*;AN000;*/
1860 char string[16]; /*;AN000;*/
1861
1862 /* get attributes */
1863 if ((status = Get_reg_attrib(fspec,&attr)) != NOERROR) { /*;AN000;*/
1864 return(status); /*;AN000;*/
1865 } /*;AN000;*/
1866
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;*/
1871 } /*;AN000;*/
1872 else { /*;AN000;*/
1873 for (i = 0; i < 8; i++) /*;AN000;*/
1874 if ((attr & bits[i]) != 0 ) /*;AN000;*/
1875 string[i] = as[i]; /*;AN000;*/
1876 else /*;AN000;*/
1877 string[i] = ' '; /*;AN000;*/
1878 for (i=8; i < 16; i++) /*;AN000;*/
1879 string[i] = ' '; /*;AN000;*/
1880 string[16] = '\0'; /*;AN000;*/
1881
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;*/
1887 } /*;AN000;*/
1888
1889 did_attrib_ok = TRUE; /*;AN000;*/
1890 return(status); /*;AN000;*/
1891} /*;AN000;*/
1892
1893
1894/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1895/* */
1896/* Subroutine Name: Special_attrib() */
1897/* */
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. */
1902/* */
1903/* Input: none */
1904/* */
1905/* Output: none */
1906/* */
1907/* Normal exit: */
1908/* */
1909/* Error exit: None */
1910/* */
1911/* Internal References: */
1912/* None */
1913/* */
1914/* External References: */
1915/* None */
1916/* */
1917/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1918
1919WORD Special_attrib(handle,fspec,id) /*;AN000;*/
1920 WORD handle; /*;AN000;*/
1921 char *fspec; /*;AN000;*/
1922 WORD id; /*;AN000;*/
1923{ /*;AN000;*/
1924 WORD status; /*;AN000;*/
1925 DWORD filesize; /*;AN000;*/
1926 long size; /*;AN000;*/
1927 long filelength(); /*;AN000;*/
1928
1929 msg_str1.sub_value_seg = segregs.ds; /*;AN000;*/
1930 msg_str1.sub_value = (WORD)fspec; /*;AN000;*/
1931
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;*/
1936
1937 /* determine which info to get by using ID */
1938 if (id == A_FILESIZE) { /* get filesize */ /*;AN000;*/
1939
1940 /* get file size, if error return error code */
1941 if ((size = filelength(handle)) == (long)-1) { /*;AN000;*/
1942 return(FILENOTFOUND); /*;AN000;*/
1943 } /*;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;*/
1948 } /*;AN000;*/
1949
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;*/
1957
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;*/
1960 } /*;AN000;*/
1961
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;*/
1969
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;*/
1972 } /*;AN000;*/
1973
1974 did_attrib_ok = TRUE; /*;AN000;*/
1975 return(NOERROR); /*;AN000;*/
1976} /*;AN000;*/
1977
1978
1979/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1980/* */
1981/* Subroutine Name: Extended_attrib() */
1982/* */
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 */
1987/* return error. */
1988/* */
1989/* Input: none */
1990/* */
1991/* Output: none */
1992/* */
1993/* Normal exit: */
1994/* */
1995/* Error exit: None */
1996/* */
1997/* Internal References: */
1998/* None */
1999/* */
2000/* External References: */
2001/* None */
2002/* */
2003/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2004
2005WORD Extended_attrib(handle,fspec) /*;AN000;*/
2006 WORD handle; /*;AN000;*/
2007 char *fspec; /*;AN000;*/
2008{ /*;AN000;*/
2009 WORD status; /*;AN000;*/
2010 WORD num; /*;AN000;*/
2011 WORD type; /*;AN000;*/
2012 WORD length; /*;AN000;*/
2013 WORD i; /*;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;*/
2021
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;*/
2025 } /*;AN000;*/
2026
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;*/
2037 } /*;AN000;*/
2038
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;*/
2042 } /*;AN000;*/
2043 else /*;AN000;*/
2044 type = ((struct name_list far *)nptr)->nl_type; /*;AN000;*/
2045
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;*/
2050 } /*;AN000;*/
2051
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;*/
2059
2060 if ((status = Get_ext_attrib(handle,&list_ptr,&qlist)) != NOERROR) { /*;AN000;*/
2061 return(status); /*;AN000;*/
2062 } /*;AN000;*/
2063
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;*/
2067 } /*;AN000;*/
2068 else { /*;AN000;*/
2069
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;*/
2075 } /*;AN000;*/
2076
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;*/
2081 } /*;AN000;*/
2082
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;*/
2088
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;*/
2097 } /*;AN000;*/
2098 } /*;AN000;*/
2099
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;*/
2104 break; /*;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;*/
2110 else /*;AN000;*/
2111 *(DWORD far *)value_ptr = (DWORD)ext_attr_value.ea_bin.dword; /*;AN000;*/
2112 break; /*;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;*/
2119 } /*;AN000;*/
2120 break; /*;AN000;*/
2121 case EAISDATE: /*;AN000;*/
2122 *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_date; /*;AN000;*/
2123 break; /*;AN000;*/
2124 case EAISTIME: /*;AN000;*/
2125 *(WORD far *)value_ptr = (WORD)ext_attr_value.ea_time; /*;AN000;*/
2126 break; /*;AN000;*/
2127 } /*;AN000;*/
2128
2129 list_ptr--; /* make list_ptr point to num entries */ /*;AN000;*/
2130 *(WORD far *)list_ptr = 1; /* num entries = 1 */ /*;AN000;*/
2131
2132 if ((status = Set_ext_attrib(handle,list_ptr)) != NOERROR) { /*;AN000;*/
2133 return(status); /*;AN000;*/
2134 } /*;AN000;*/
2135 } /*;AN000;*/
2136 did_attrib_ok = TRUE; /*;AN000;*/
2137 return(status); /*;AN000;*/
2138} /*;AN000;*/
2139
2140
2141/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2142/* */
2143/* Subroutine Name: Attrib() */
2144/* */
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 */
2149/* return error. */
2150/* */
2151/* Input: none */
2152/* */
2153/* Output: none */
2154/* */
2155/* Normal exit: */
2156/* */
2157/* Error exit: None */
2158/* */
2159/* Internal References: */
2160/* None */
2161/* */
2162/* External References: */
2163/* None */
2164/* */
2165/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2166
2167WORD Attrib(path,file) /*;AN000;*/
2168 char *path, /*;AN000;*/
2169 *file; /*;AN000;*/
2170{ /*;AN000;*/
2171 char fspec[128]; /*;AN000;*/
2172 WORD status; /*;AN000;*/
2173 WORD handle; /*;AN000;*/
2174 WORD i; /*;AN000;*/
2175 WORD found_spl; /* boolean */ /*;AN000;*/
2176 WORD id; /*;AN000;*/
2177
2178 strcpy(fspec,path); /* make full filename */ /*;AN000;*/
2179 strcat(fspec,file); /*;AN000;*/
2180
2181 /* Check for extended & special attributes */
2182 if (set_ext_attr || do_ext_attr) { /*;AN000;*/
2183
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;*/
2190 break; /*;AN000;*/
2191 } /*;AN000;*/
2192 } /*;AN000;*/
2193
2194 /* Do an extended open, if error return error code */
2195 if ((status = Ext_open(fspec,&handle)) != NOERROR) { /*;AN000;*/
2196 return(status); /*;AN000;*/
2197 } /*;AN000;*/
2198
2199 /* Special attributes */
2200 if (found_spl) { /*;AN000;*/
2201 status = Special_attrib(handle,fspec,id); /*;AN000;*/
2202 } /*;AN000;*/
2203
2204 /* Extended attributes */
2205 else { /*;AN000;*/
2206 status = Extended_attrib(handle,fspec); /*;AN000;*/
2207 } /*;AN000;*/
2208 close(handle); /*;AN000;*/
2209 } /*;AN000;*/
2210
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;*/
2215 } /*;AN000;*/
2216 } /*;AN000;*/
2217
2218 return(status); /*;AN000;*/
2219} /*;AN000;*/
2220
2221
2222/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2223/* */
2224/* Subroutine Name: Do_dir() */
2225/* */
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. */
2231/* */
2232/* Input: none */
2233/* */
2234/* Output: none */
2235/* */
2236/* Normal exit: */
2237/* */
2238/* Error exit: None */
2239/* */
2240/* Internal References: */
2241/* None */
2242/* */
2243/* External References: */
2244/* None */
2245/* */
2246/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2247
2248WORD Do_dir(path,file)
2249 char *path,
2250 *file;
2251{
2252 char dta_area[128];
2253 char subdirectory[256];
2254 char next[32];
2255 WORD status;
2256 WORD search_attrib;
2257
2258 next[0] = '\0'; /*;AN000;*/
2259 Dta_save(dta_area,128);
2260 status = NOERROR; /*;AN000;*/
2261
2262 /* first, but only if descending, scan for subdirectories */
2263 if (descending) {
2264 strcpy(subdirectory,path);
2265 strcat(subdirectory,"*.*");
2266
2267 search_attrib = SUBDIR; /* Find all except volume labels*/ /*;AN000;*/
2268 status = Find_first(subdirectory,next,&search_attrib);
2269
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);
2276 }
2277 if (status == NOERROR) {
2278 strcpy(subdirectory,path);
2279 strcat(subdirectory,"*.*");
2280
2281 search_attrib = SUBDIR; /*;AN000;*/
2282 status = Find_next(next,&search_attrib);
2283 }
2284 } /* while */
2285 } /* if descending */
2286
2287 if (status == NOMOREFILES)
2288 status = NOERROR;
2289
2290 /* now, search this directory for files that match */
2291 if (status == NOERROR) {
2292 strcpy(subdirectory,path);
2293 strcat(subdirectory,file);
2294
2295 search_attrib = SUBDIR; /*;AN000;*/
2296 status = Find_first(subdirectory,next,&search_attrib);
2297 while(status == NOERROR) {
2298
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);
2306 }
2307
2308 if (status == NOERROR) {
2309 search_attrib = SUBDIR; /*;AN000;*/
2310 status = Find_next(next,&search_attrib);
2311 }
2312 } /* while */
2313 }
2314 if (status == NOMOREFILES)
2315 status = NOERROR;
2316
2317 if (status != NOERROR) { /*;AN000;*/
2318 }
2319
2320 Dta_restore(dta_area,128);
2321 return(status);
2322}
2323
2324
2325/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2326/* */
2327/* Subroutine Name: Check_appendx() */
2328/* */
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. */
2333/* */
2334/* Input: none */
2335/* */
2336/* Output: append_active_flg */
2337/* */
2338/* Normal exit: flag set if /X active */
2339/* */
2340/* Error exit: None */
2341/* */
2342/* Internal References: */
2343/* None */
2344/* */
2345/* External References: */
2346/* None */
2347/* */
2348/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2349
2350Check_appendx() /*;AN000;*/
2351{ /*;AN000;*/
2352 void ctl_brk_handler(); /*;AN000;*/
2353 extern crit_err_handler(); /*;AN000;*/
2354 WORD *ptr; /*;AN000;*/
2355
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;*/
2365
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;*/
2370 } /*;AN000;*/
2371 } /*;AN000;*/
2372
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;*/
2379
2380 /* set crtl-c & critical error handler vector */
2381 segread(&segregs);
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;*/
2386
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;*/
2392} /*;AN000;*/
2393
2394
2395/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2396/* */
2397/* Subroutine Name: Reset_appendx() */
2398/* */
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. */
2403/* */
2404/* Input: none */
2405/* */
2406/* Output: append_active_flg */
2407/* */
2408/* Normal exit: flag set if /X active */
2409/* */
2410/* Error exit: None */
2411/* */
2412/* Internal References: */
2413/* None */
2414/* */
2415/* External References: */
2416/* None */
2417/* */
2418/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2419
2420Reset_appendx() /*;AN000;*/
2421{ /*;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;*/
2426 } /*;AN000;*/
2427} /*;AN000;*/
2428
2429
2430/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2431/* */
2432/* Subroutine Name: Check_DBCS() */
2433/* */
2434/* Subroutine Function: */
2435/* Given an array and a position in the array, check if the character */
2436/* is a non-DBCS character. */
2437/* */
2438/* Input: array, character position, character */
2439/* */
2440/* Output: TRUE - if array[position-1] != DBCS character AND */
2441/* array[position] == character. */
2442/* FALSE - otherwise */
2443/* Normal exit: none */
2444/* */
2445/* Error exit: None */
2446/* */
2447/* Internal References: */
2448/* None */
2449/* */
2450/* External References: */
2451/* None */
2452/* */
2453/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2454WORD Check_DBCS(array,position,character) /*;AN000;*/
2455 char *array; /*;AN000;*/
2456 WORD position; /*;AN000;*/
2457 char character; /*;AN000;*/
2458{ /*;AN000;*/
2459 BYTE far *ptr; /*;AN000;*/
2460 WORD i; /*;AN000;*/
2461 char c; /*;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;*/
2467
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;*/
2472
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;*/
2476
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;*/
2481 break;
2482 }
2483 } /*;AN000;*/
2484 } /*;AN000;*/
2485
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;*/
2489 } /*;AN000;*/
2490 else /*;AN000;*/
2491 return (FALSE); /*;AN000;*/
2492} /*;AN000;*/
2493
2494
2495/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2496/* */
2497/* Subroutine Name: Get_DBCS_vector() */
2498/* */
2499/* Subroutine Function: */
2500/* Gets the double-byte table vector. */
2501/* */
2502/* Input: none */
2503/* */
2504/* Output: none */
2505/* */
2506/* Normal exit: none */
2507/* */
2508/* Error exit: None */
2509/* */
2510/* Internal References: */
2511/* None */
2512/* */
2513/* External References: */
2514/* None */
2515/* */
2516/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2517Get_DBCS_vector() /*;AN000;*/
2518{ /*;AN000;*/
2519 WORD *ptr; /*;AN000;*/
2520 WORD *buffer; /*;AN000;*/
2521 DWORD far *addr_ptr; /*;AN000;*/
2522
2523 /* allocate a buffer for DBCS table vector */
2524 buffer = Dallocate(5); /* at least 5 bytes big */ /*;AN000;*/
2525
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;*/
2534
2535 outregs.x.di++; /* skip over id byte */ /*;AN000;*/
2536
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;*/
2541 ptr++; /*;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;*/
2545
2546 /* DBCS_ptr points to DBCS table */ /*;AN000;*/
2547 strcpy(fix_es_reg,NUL); /*;AN000;*/
2548} /*;AN000;*/
2549
2550
2551
2552/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2553/* */
2554/* Subroutine Name: Error_exit() */
2555/* */
2556/* Subroutine Function: */
2557/* displays an extended error message with - filename */
2558/* */
2559/* Input: error_file_name[] must contain name of file, if needed for */
2560/* message output. */
2561/* */
2562/* Output: none */
2563/* */
2564/* Normal exit: */
2565/* */
2566/* Error exit: None */
2567/* */
2568/* Internal References: */
2569/* None */
2570/* */
2571/* External References: */
2572/* None */
2573/* */
2574/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2575void Error_exit(msg_class,ext_err_num,subcnt) /*;AN000;*/
2576 /*;AN000;*/
2577 int msg_class; /*;AN000;*/
2578 int ext_err_num; /*;AN000;*/
2579 int subcnt; /*;AN000;*/
2580{ /*;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;*/
2591
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;*/
2599 } /*;AN000;*/
2600
2601 Reset_appendx(); /* Reset APPEND /X status */ /*;AN000;*/
2602 exit(1); /*;AN000;*/
2603} /*;AN000;*/
2604
2605
2606
2607/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2608/* */
2609/* Subroutine Name: Parse_err() */
2610/* */
2611/* Subroutine Function: */
2612/* displays an parser error message with - filename */
2613/* */
2614/* Input: error_file_name[] must contain name of file, if needed for */
2615/* message output. */
2616/* */
2617/* Output: none */
2618/* */
2619/* Normal exit: */
2620/* */
2621/* Error exit: None */
2622/* */
2623/* Internal References: */
2624/* None */
2625/* */
2626/* External References: */
2627/* None */
2628/* */
2629/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2630void Parse_err(error_num) /*;AN000;*/
2631
2632 WORD error_num; /*;AN000;*/
2633{ /*;AN000;*/
2634 char *cptr; /*;AN000;*/
2635 char *sptr; /*;AN000;*/
2636
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;*/
2640
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;*/
2646
2647 /* check for messages with no parameter */
2648 if (error_num == p_op_missing) /*;AN000;*/
2649 Error_exit(ERR_PARSE,error_num,NOSUBCNT); /*;AN000;*/
2650 else /*;AN000;*/
2651 Error_exit(ERR_PARSE,error_num,ONEPARM); /*;AN000;*/
2652} /*;AN000;*/
2653
2654
2655
2656
2657/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2658/* */
2659/* Subroutine Name: ctl_brk_handler */
2660/* */
2661/* Subroutine Function: */
2662/* Crtl-break interrupt handler. */
2663/* */
2664/* Input: none */
2665/* */
2666/* Output: none */
2667/* */
2668/* Normal exit: */
2669/* */
2670/* Error exit: None */
2671/* */
2672/* Internal References: */
2673/* None */
2674/* */
2675/* External References: */
2676/* None */
2677/* */
2678/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2679void ctl_brk_handler()
2680{
2681 Reset_appendx();
2682 exit(3); /*;AN000;*/
2683/* inregs.x.ax = 0x4c03; /* DOS terminate int call */ /*;AN000;*/
2684/* intdos(&inregs,&outregs); /*;AN000;*/
2685}
diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.H b/v4.0/src/CMD/ATTRIB/ATTRIB.H
new file mode 100644
index 0000000..5297d11
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/ATTRIB.H
@@ -0,0 +1,443 @@
1/* Module ATTRIB.H */
2
3/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
4/* All defines for attrib.c */
5/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
6
7#define FALSE 0 /*;AN000;*/
8#define TRUE !FALSE /*;AN000;*/
9
10#ifndef BYTE
11#define BYTE unsigned char /*;AN000;*/
12#define WORD unsigned short /*;AN000;*/
13#define DWORD unsigned long /*;AN000;*/
14#endif
15
16#define CARRY 0x0001 /*;AN000; carry flag */
17
18#define YES 1 /*;AN000; Yes return from int 21h Y/N check */
19#define NO 0 /*;AN000; NO return from int 21h Y/N check */
20
21#define NUL 0x0 /*;AN000;*/
22#define BLANK 0x20 /*;AN000;*/
23#define TAB 0x09 /*;AN000;*/
24#define CR 0x0d /*;AN000;*/
25#define LF 0x0a /*;AN000;*/
26
27/* Error_exit() parameter values */
28#define ERR_EXTENDED 1 /*;AN000;*/
29#define ERR_PARSE 2 /*;AN000;*/
30
31
32/* standard file handles */
33#define STDIN 0x00 /*;AN000; Standard Input device handle */
34#define STDOUT 0x01 /*;AN000; Standard Output device handle */
35#define STDERR 0x02 /*;AN000; Standard Error Output device handle */
36#define STDAUX 0x03 /*;AN000; Standard Auxiliary device handle */
37#define STDPRN 0x04 /*;AN000; Standard Printer device handle */
38
39/* attribute byte defines */
40#define AFILE 0x00 /*;AN000;*/
41#define READONLY 0x01 /*;AN000;*/
42#define HIDDEN 0x02 /*;AN000;*/
43#define SYSTEM 0x04 /*;AN000;*/
44#define LABEL 0x08 /*;AN000;*/
45#define SUBDIR 0x10 /*;AN000;*/
46#define ARCHIVE 0x20 /*;AN000;*/
47
48/* extended attribute type defines */
49#define EAISUNDEF 0 /*;AN000; undefined type */
50#define EAISLOGICAL 1 /*;AN000; logical (0 or 1) */
51#define EAISBINARY 2 /*;AN000; binary integer */
52#define EAISASCII 3 /*;AN000; ASCII type */
53#define EAISDATE 4 /*;AN000; DOS file date format */
54#define EAISTIME 5 /*;AN000; DOS file time format */
55
56#define EANAMES 6 /*;AN000; ext attr names ASCII */
57
58/* extended attribute flag defines */
59#define EASYSTEM 0x8000 /*;AN000; EA is system defined */
60#define EAREADONLY 0x4000 /*;AN000; EA is read only */
61#define EAHIDDEN 0x2000 /*;AN000; EA is hidden */
62#define EACREATEONLY 0x1000 /*;AN000; EA is setable only at create time */
63
64/* extended attribute failure return code defines */
65#define EARCNOERROR 0 /*;AN000; no error */
66#define EARCNOTFOUND 1 /*;AN000; name not found */
67#define EARCNOSPACE 2 /*;AN000; no space to hold name or value */
68#define EARCNOTNOW 3 /*;AN000; name can't be set on this function */
69#define EARCNOTEVER 4 /*;AN000; name can't be set */
70#define EARCUNDEF 5 /*;AN000; name known to this FS but not supported */
71#define EARCDEFBAD 6 /*;AN000; EA definition bad (TYPE,LENGTH, etc.) */
72#define EARCACCESS 7 /*;AN000; EA access denied */
73#define EARCVALBAD 8 /*;AN000; EA value not supported */
74#define EARCUNKNOWN -1 /*;AN000; undetermined cause */
75
76/* message retriever interface defines */
77#define NOSUBPTR 0 /*;AN000; no sublist pointer */
78#define NOSUBCNT 0 /*;AN000; 0 substitution count */
79#define ONEPARM 1 /*;AN000; 1 substitution count */
80#define TWOPARM 2 /*;AN000; 2 substitution count */
81#define NOINPUT 0 /*;AN000; no user input */
82#define INPUT 1 /*;AN000; ask user for Y/N input */
83
84/* misc. defines */
85#define A_FILESIZE 1 /* id of special attribute: filesize */
86#define A_DATE 2 /* id of special attribute: date */
87#define A_TIME 3 /* id of special attribute: time */
88
89#define MAX_ATTR_SIZE 160 /*;AN000; max ext attribute buffer size */
90#define MAX_KEYWORD 128 /*;AN000; max size of extended attribute keyword */
91#define MAX_SPL 3 /*;AN000; max number of special attributes */
92
93#define ATTR_SIZE 7 /*;AN000; size in bytes of attr struct */
94#define NAME_SIZE 4 /*;AN000; size in bytes of name struct */
95
96#define NOERROR 0 /*;AN000;*/
97#define NOMOREFILES 18 /*;AN000;*/
98#define FILENOTFOUND 2 /*;AN000;*/
99
100#define GET_DATE 1 /*;AN000;*/
101#define GET_TIME 2 /*;AN000;*/
102
103#define INACTIVE 0x7fff /*;AN000;*/
104/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
105/* All structures defined for attrib.c */
106/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
107
108struct p_null { /*;AN000; a null value list for parser */
109 unsigned char null; /*;AN000;*/
110 }; /*;AN000;*/
111
112struct query_list { /*;AN000; Generic attribute overlay structure */
113 WORD ql_num;
114 BYTE ql_type; /*;AN000; EA type */
115 WORD ql_flags; /*;AN000; EA flags */
116 BYTE ql_name_len; /*;AN000; name length */
117 char ql_name[MAX_KEYWORD]; /*;AN000; name */
118 }; /*;AN000;*/
119
120struct name_list { /*;AN000; Generic attribute overlay structure */
121 BYTE nl_type; /*;AN000; EA type */
122 WORD nl_flags; /*;AN000; EA flags */
123 BYTE nl_name_len; /*;AN000; name length */
124 char nl_name[MAX_KEYWORD]; /*;AN000; name */
125 }; /*;AN000;*/
126
127struct attr_list { /*;AN000; Generic attribute overlay structure */
128 BYTE at_type; /*;AN000; EA type */
129 WORD at_flags; /*;AN000; EA flags */
130 BYTE at_rc; /*;AN000; EA return code */
131 BYTE at_name_len; /*;AN000; name length */
132 WORD at_value_len; /*;AN000; value length */
133 char at_name[MAX_KEYWORD]; /*;AN000; name */
134 }; /*;AN000;*/
135
136struct parm_list { /*;AN000; Parm list for extended open DOS call */
137 DWORD pm_list; /*;AN000; extended attr. list */
138 WORD pm_num_parms; /*;AN000; number of parameters */
139 BYTE pm_id; /*;AN000; id */
140 WORD pm_iomode; /*;AN000; iomode */
141 }; /*;AN000;*/
142
143struct spl_list { /*;AN000;*/
144 char name[MAX_KEYWORD]; /*;AN000;*/
145 WORD id; /*;AN000;*/
146 }; /*;AN000;*/
147
148struct bin_struct { /*;AN000;*/
149 BYTE length; /*;AN000;*/
150 DWORD dword; /*;AN000;*/
151 }; /*;AN000;*/
152
153union eav_union { /*;AN000;*/
154 WORD ea_undef; /*;AN000;*/
155 BYTE ea_logical; /*;AN000;*/
156 struct bin_struct ea_bin; /*;AN000;*/
157 char ea_ascii[129]; /*;AN000;*/
158 DWORD ea_time; /*;AN000;*/
159 DWORD ea_date; /*;AN000;*/
160 }; /*;AN000;*/
161/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
162/* All global variables for attrib.c */
163/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
164struct spl_list specials[MAX_SPL] = { /*;AN000;*/
165 "FILESIZE", A_FILESIZE, /*;AN000;*/
166 "DATE", A_DATE, /*;AN000;*/
167 "TIME", A_TIME }; /*;AN000;*/
168
169
170/* parser structure variables */
171union eav_union ext_attr_value; /*;AN000; result value union */
172
173struct p_result_blk pos1_buff; /*;AN000; result buffer for -+A,-+R */
174struct p_result_blk pos2_buff; /*;AN000; result buffer for -+A,-+R */
175struct p_result_blk pos3_buff; /*;AN000; result buffer for filespec */
176struct p_result_blk pos4_buff; /*;AN000; result buffer for -+A,-+R */
177struct p_result_blk pos5_buff; /*;AN000; result buffer for -+A,-+R */
178struct p_result_blk pos6_buff; /*;AN000; result buffer for id */
179struct p_result_blk pos6b_buff; /*;AN000; result buffer for id */
180struct p_result_blk sw_buff; /*;AN000; result buffer for /S */
181
182char nullword[] = " "; /*;AN000; used when no word attribute */
183char nulldword[] = " "; /*;AN000; used when no double word attribute */
184char nulldate[] = " "; /*;AN000; used when no date attribute */
185char nulltime[] = " "; /*;AN000; used when no time attribute */
186
187char plusa[] = "+A"; /*;AN000; strings for match */
188char minusa[] = "-A"; /*;AN000;*/
189char plusr[] = "+R"; /*;AN000;*/
190char minusr[] = "-R"; /*;AN000;*/
191
192struct p_null noval = /*;AN000; structure for no value list */
193 { 0 }; /*;AN000;*/
194
195struct ps_valist_blk vals1 = /*;AN000; +A-A+R-R value list */
196 { p_nval_string, /*;AN000; string value list type */
197 0, /*;AN000; number of ranges */
198 0, /*;AN000; number of numbers */
199 4, /*;AN000; number of strings */
200 0x20, /*;AN000; item tag */
201 (WORD)plusa, /*;AN000; address of string */
202 0x20, /*;AN000; item tag */
203 (WORD)minusa, /*;AN000; address of string */
204 0x01, /*;AN000; item tag */
205 (WORD)plusr, /*;AN000; address of string */
206 0x01, /*;AN000; item tag */
207 (WORD)minusr }; /*;AN000; address of string */
208
209struct p_control_blk p_con1 = /*;AN000; describes +-A or +-R */
210 { 0x2001, /*;AN000; Simple string,optional */
211 0x0002, /*;AN000; Cap result by char table */
212 (WORD)&pos1_buff, /*;AN000;*/
213 (WORD)&vals1, /*;AN000;*/
214 0, /*;AN000;*/
215 0 }; /*;AN000;*/
216
217struct p_control_blk p_con2 = /*;AN000; describes +-A or +-R (2nd occurrance) */
218 { 0x2001, /*;AN000; Simple string,optional */
219 0x0002, /*;AN000; Cap result by char table */
220 (WORD)&pos2_buff, /*;AN000;*/
221 (WORD)&vals1, /*;AN000;*/
222 0, /*;AN000;*/
223 0 }; /*;AN000;*/
224
225struct p_control_blk p_con3 = /*;AN000; describes filespec */
226 { 0x0200, /*;AN000; File spec required */
227 0x0001, /*;AN000; Cap result by file table */
228 (WORD)&pos3_buff, /*;AN000;*/
229 (WORD)&noval, /*;AN000;*/
230 0, /*;AN000;*/
231 0 }; /*;AN000;*/
232
233struct p_control_blk p_con4 = /*;AN000; describes +-A or +-R */
234 { 0x2001, /*;AN000; Simple string,optional */
235 0x0002, /*;AN000; Cap result by char table */
236 (WORD)&pos4_buff, /*;AN000;*/
237 (WORD)&vals1, /*;AN000;*/
238 0, /*;AN000;*/
239 0 }; /*;AN000;*/
240
241struct p_control_blk p_con5 = /*;AN000; describes +-A or +-R (2nd occurrance) */
242 { 0x2001, /*;AN000; Simple string,optional */
243 0x0002, /*;AN000; Cap result by char table */
244 (WORD)&pos5_buff, /*;AN000;*/
245 (WORD)&vals1, /*;AN000;*/
246 0, /*;AN000;*/
247 0 }; /*;AN000;*/
248
249struct p_control_blk p_con6 = /*;AN000; describes id */
250 { 0x2001, /*;AN000; Simple string,optional */
251 0x0002, /*;AN000; Cap result by char table */
252 (WORD)&pos6_buff, /*;AN000;*/
253 (WORD)&noval, /*;AN000;*/
254 0, /*;AN000;*/
255 0 }; /*;AN000;*/
256
257struct p_control_blk p_con6a = /*;AN000; describes id */
258 { 0x2000, /*;AN000; Simple string */
259 0x0002, /*;AN000; Cap result by char table */
260 (WORD)&pos6_buff, /*;AN000;*/
261 (WORD)&noval, /*;AN000;*/
262 0, /*;AN000;*/
263 0 }; /*;AN000;*/
264
265struct p_control_blk p_con6b = /*;AN000; describes id */
266 { 0xe481, /*;AN000; Quoted string */
267 0x0002, /*;AN000;*/
268 (WORD)&pos6b_buff, /*;AN000;*/
269 (WORD)&noval, /*;AN000;*/
270 0, /*;AN000;*/
271 0 }; /*;AN000;*/
272
273struct p_control_blk p_swi1 = /*;AN000; Switch control block */
274 { 0x0001, /*;AN000; Optional (switch) */
275 0x0002, /*;AN000; Cap result by char table */
276 (WORD)&sw_buff, /*;AN000;*/
277 (WORD)&noval, /*;AN000;*/
278 1, /*;AN000; one switch allowed */
279 "/S" }; /*;AN000; /S */
280
281struct p_parmsx p_px1 = /*;AN000; Parser Control definition for Parm Block 1 */
282 { 1, /*;AN000; positionals */
283 6, /*;AN000;*/
284 &p_con1, /*;AN000;*/
285 &p_con2, /*;AN000;*/
286 &p_con3, /*;AN000;*/
287 &p_con4, /*;AN000;*/
288 &p_con5, /*;AN000;*/
289 &p_con6, /*;AN000;*/
290 1, /*;AN000; switches */
291 &p_swi1, /*;AN000;*/
292 0, /*;AN000; keywords*/
293 0, /*;AN000;*/
294 0, /*;AN000;*/
295 0 }; /*;AN000;*/
296
297struct p_parms p_p1 = /*;AN000; Parms block for line */
298 { &p_px1, /*;AN000; Address of extended parm list */
299 0, /*;AN000;*/
300 0, /*;AN000;*/
301 0 }; /*;AN000;*/
302
303struct p_parmsx p_px2 = /*;AN000; Parser Control definition for Parm Block 1 */
304 { 1, /*;AN000; positionals */
305 2, /*;AN000;*/
306 &p_con6a, /*;AN000;*/
307 &p_con6b, /*;AN000;*/
308 0, /*;AN000;*/
309 0, /*;AN000;*/
310 0, /*;AN000;*/
311 0, /*;AN000;*/
312 1, /*;AN000; switches */
313 &p_swi1, /*;AN000;*/
314 0, /*;AN000; keywords*/
315 0, /*;AN000;*/
316 0, /*;AN000;*/
317 0 }; /*;AN000;*/
318
319struct p_parms p_p2 = /*;AN000; Parms block for line */
320 { &p_px2, /*;AN000; Address of extended parm list */
321 1, /*;AN000;*/
322 1, /*;AN000;*/
323 "=" }; /*;AN000;*/
324
325/* extended open structure variables */
326struct parm_list plist = /*;AN000; Extended open parm list */
327 { -1, /*;AN000; ptr to attr. list */
328 1, /*;AN000; number of parms */
329 6, /*;AN000; id */
330 2 }; /*;AN000; iomode */
331
332/* messgages */
333struct m_sublist msg_num = /*;AN000; describes substitutions */
334 { 72, /*;AN000; for parm one of message */
335 0, /*;AN000; */
336 0, /*;AN000; */
337 0, /*;AN000; */
338 1, /*;AN000; */
339 sf_unsbin2d | sf_right, /*;AN000; unsigned binary to decimal*/
340 9, /*;AN000; */
341 9, /*;AN000; */
342 0 }; /*;AN000; */
343struct m_sublist msg_str2 = /*;AN000; describes substitutions */
344 { 60, /*;AN000; for parm one of message */
345 0, /*;AN000; */
346 0, /*;AN000; */
347 0, /*;AN000; */
348 1, /*;AN000; */
349 sf_left | sf_char | sf_asciiz, /*;AN000; string */
350 0, /*;AN000; null string */
351 0, /*;AN000; */
352 (BYTE)" " }; /*;AN000; */
353struct m_sublist msg_dword = /*;AN000; describes substitutions */
354 { 48, /*;AN000; for parm one of message */
355 0, /*;AN000; */
356 0, /*;AN000; */
357 0, /*;AN000; */
358 1, /*;AN000; */
359 sf_unsbin2d | sf_dword | sf_right, /*;AN000; unsigned binary to decimal*/
360 10, /*;AN000; */
361 9, /*;AN000; */
362 0 }; /*;AN000; */
363struct m_sublist msg_date = /*;AN000; describes substitutions */
364 { 36, /*;AN000; for parm one of message */
365 0, /*;AN000; */
366 0, /*;AN000; */
367 0, /*;AN000; */
368 1, /*;AN000; */
369 sf_date | sf_mdy2, /*;AN000; unsigned binary to decimal*/
370 9, /*;AN000; */
371 9, /*;AN000; */
372 0 }; /*;AN000; */
373struct m_sublist msg_time = /*;AN000; describes substitutions */
374 { 24, /*;AN000; for parm one of message */
375 0, /*;AN000; */
376 0, /*;AN000; */
377 0, /*;AN000; */
378 1, /*;AN000; */
379 sf_time12 | sf_hhmm | sf_right, /*;AN000; unsigned binary to decimal*/
380 9, /*;AN000; NN-NN-NNa (9 characters) */
381 9, /*;AN000; */
382 0 }; /*;AN000; */
383struct m_sublist msg_str = /*;AN000; describes substitutions */
384 { 12, /*;AN000; for parm one of message */
385 0, /*;AN000; */
386 0, /*;AN000; */
387 0, /*;AN000; */
388 1, /*;AN000; */
389 sf_left | sf_char | sf_asciiz, /*;AN000; string */
390 9, /*;AN000; null string */
391 9, /*;AN000; */
392 (BYTE)" " }; /*;AN000; */
393struct m_sublist msg_str1 = /*;AN000; describes substitutions */
394 { 12, /*;AN000; for parm two of message */
395 0, /*;AN000; */
396 0, /*;AN000; */
397 0, /*;AN000; */
398 2, /*;AN000; */
399 sf_left | sf_char | sf_asciiz, /*;AN000; string */
400 0, /*;AN000; null string */
401 0, /*;AN000; */
402 (BYTE)" " }; /*;AN000; */
403struct m_sublist msg_error = /*;AN000; describes substitutions */
404 { 12, /*;AN000; for extended error messages*/
405 0, /*;AN000; */
406 0, /*;AN000; */
407 0, /*;AN000; */
408 0, /*;AN000; */
409 sf_left | sf_char | sf_asciiz, /*;AN000; string */
410 0, /*;AN000; null string */
411 0, /*;AN000; */
412 (BYTE)" " }; /*;AN000; */
413
414/* misc. variables */
415union REGS inregs, /*;AN000; Registers */
416 outregs; /*;AN000;*/
417struct SREGS segregs; /*;AN000; Segment registers */
418
419DWORD old_int24_off; /*;AN000;*/
420
421WORD descending; /*;AN000;*/
422WORD append_x_status; /*;AN000;*/
423WORD did_attrib_ok; /*;AN000;*/
424WORD set_reg_attr, /*;AN000;*/
425 set_ext_attr; /*;AN000;*/
426WORD do_reg_attr, /*;AN000;*/
427 do_ext_attr; /*;AN000;*/
428
429BYTE far *DBCS_ptr; /*;AN000;*/
430BYTE ext_attr_value_type; /*;AN000;*/
431BYTE attr; /*;AN000;*/
432BYTE bits[8] = { 0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01 }; /*;AN000;*/
433BYTE pmask, /*;AN000;*/
434 mmask; /*;AN000;*/
435
436char as[8] = { ' ',' ','A',' ',' ',' ',' ','R' }; /*;AN000;*/
437char fix_es_reg[1]; /*;AN000;*/
438char ext_attr[MAX_KEYWORD]; /*;AN000;*/
439char error_file_name[256]; /*;AN005;*/
440char fspec[256]; /*;AN000;*/
441char file[256]; /*;AN000;*/
442char str_on[3] = {"ON"}; /*;AN000;*/
443char str_off[4] = {"OFF"}; /*;AN000;*/
diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.LNK b/v4.0/src/CMD/ATTRIB/ATTRIB.LNK
new file mode 100644
index 0000000..89de3bf
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/ATTRIB.LNK
@@ -0,0 +1,7 @@
1attriba+
2attrib+
3_parse+
4_msgret
5attrib
6nul;
7
diff --git a/v4.0/src/CMD/ATTRIB/ATTRIB.SKL b/v4.0/src/CMD/ATTRIB/ATTRIB.SKL
new file mode 100644
index 0000000..aab62fa
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/ATTRIB.SKL
@@ -0,0 +1,30 @@
1:util ATTRIB ;utility name ;AN000;
2
3:class 1 ;AN000;
4
5:class 2 ;AN000;
6
7:class A ;system messages ;AN000;
8:use 1 COMMON1 ;"Incorrect DOS version" ;AN000;
9:use 2 EXTEND8 ;"Insufficient memory" ;AN000;
10
11:class B ;AN000;
12:def 8 " %1" ;AN000;
13:def 9 "%1 %2",CR,LF ;AN000;
14:def 10 "%1",CR,LF,"%2",CR,LF ;AN000;
15:def 11 "Code page mismatch - %1",CR,LF,"Are you sure (Y/N)?" ;AN000;
16:def 12 "%1",CR,LF ;AN000;
17:def 14 CR,LF ;AN000;
18:def 15 "Invalid file type value",CR,LF ;AN000;
19
20;;; Change these extended attribute error msgs back when adding ext. attr.
21;;; function in DOS.
22;;;:def 199 "Extended attribute error",CR,LF ;AN000;
23;;;:def 201 "Extended attribute name not found",CR,LF ;AN000;
24;;;:use 202 EXTEND8 ;"Insufficient memory" ;AN000;
25;;;:def 204 "Extended attribute name can't be set",CR,LF ;AN000;
26;;;:def 205 "Extended attribute name known to this filesystem but not supported",CR,LF ;AN000;
27;;;:def 206 "Extended attribute type mismatch",CR,LF ;AN000;
28;;;:def 208 "Extended attribute value not supported",CR,LF ;AN000;
29
30:end ;AN000;
diff --git a/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM b/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM
new file mode 100644
index 0000000..4f9c312
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/ATTRIBA.ASM
@@ -0,0 +1,480 @@
1 page ,132 ;
2 title New_C.C - DOS entry to the KWC's 'C' programs
3
4;
5; This module has been modified extensively for my personal
6; use.
7;
8; name XCMAIN -- initiate execution of C program
9;
10; description This is the main module for a C program on the
11; DOS implementation. It initializes the segment
12; registers, sets up the stack, and calls the C main
13; function _main with a pointer to the remainder of
14; the command line.
15;
16; Also defined in this module is the exit entry point
17; XCEXIT.
18;
19; $salut (4,12,18,41)
20SETBLOCK EQU 4AH ;MODIFY ALLOCATED MEMORY BLOCKS
21 ;ES = SEGMENT OF THE BLOCK
22 ;BX = NEW REQUESTED BLOCK SIZE
23 ; IN PARAGRAPHS
24 ;OUTPUT: BX=MAX SIZE POSSIBLE IF CY SET
25 ;AX = ERROR CODE IF CY SET
26
27RET_CD_EXIT EQU 4CH ;EXIT TO DOS, PASSING RETURN CODE
28 ;AL=RETURN CODE
29
30RET_EXIT equ 4ch ;AN000; ;terminate
31ABORT equ 2 ;AN000; ;if >=, retry
32XABORT equ 1 ;AN000; ;errorlevel return in al
33
34
35 extrn _inmain:near ;AC000;
36 extrn _Reset_appendx:near ;AN000;
37 extrn _old_int24_off:dword ;AN000;
38
39
40psp segment at 0 ;<--emk
41psp_ret dw ? ;int 20h
42psp_memsz dw ? ;memory size
43 org 2ch
44psp_env dw ? ;segid of environment
45 org 80h
46psp_parlen db ? ;length of DOS command line parms
47psp_par db 127 dup(?) ;DOS command line parms
48psp ends
49 page
50
51;
52; The following segment serves only to force "pgroup" lower in
53; memory.
54;
55
56base segment PARA PUBLIC 'DATA'
57
58 db 00dh,00ah
59 db "----------\x0d\x0a"
60 db " DOS ATTRIB function \x0d\x0a"
61 db "--------------------\x0d\x0a"
62 db 00dh,00ah,01ah
63
64base ends
65
66
67;
68; The data segment defines locations which contain the offsets
69; of the base and top of the stack.
70;
71
72_data segment PARA public 'DATA'
73
74 irp name,<_top,_base,_cs,_ss,_psp,_env,_rax,_rbx,_rcx,_rdx,_rds,_rsi,_rbp,_res,_rdi>
75 public name
76name dw 0
77 endm
78
79_data ends
80
81;
82; The stack segment is included to prevent the warning from the
83; linker, and also to define the base (lowest address) of the stack.
84;
85
86stack segment PARA stack 'data'
87
88SBase dw 128 dup (?)
89
90stack ends
91
92null segment para public 'BEGDATA'
93null ends
94const segment word public 'CONST'
95const ends
96_bss segment word public 'BSS'
97_bss ends
98pgroup group base,_text
99dgroup group null, _data, const, _bss, stack
100
101 page
102
103;
104; The main program must set up the initial segment registers
105; and the stack pointer, and set up a far return to the DOS
106; exit point at ES:0. The command line bytes from the program
107; segment prefix are moved onto the stack, and a pointer to
108; them supplied to the C main module _main (which calls main).
109;
110
111_text segment PARA public 'CODE'
112
113 public XCMAIN
114
115 assume cs:pgroup
116 assume ds:psp ;<--emk
117 assume es:psp ;<--emk
118 assume ss:stack ;<--emk
119
120XCMAIN proc far
121
122 mov ax,dgroup
123 mov ds,ax ;initialize ds and ss
124 assume ds:dgroup
125
126 mov bx,psp_memsz ;total memory size (paragraphs)
127 sub bx,ax
128 test bx,0f000h
129; $IF Z ;branch if more than or equal 64K bytes
130 JNZ $$IF1
131
132 mov cl,4
133 shl bx,cl ;highest available byte
134; $ELSE
135 JMP SHORT $$EN1
136$$IF1:
137 mov bx,0fff0h
138; $ENDIF
139$$EN1:
140 cli ; disable interrupts while changing stack <---kwc
141 mov ss,ax ; set ss <---kwc
142 mov sp,bx ; set stack pointer <---kwc
143 sti ;enable interrupts
144 assume ss:DGroup ;<--emk
145
146 mov _ss,ss
147 mov _cs,cs
148 mov _top,bx ;save top of stack
149
150 mov ax,offset DGroup:SBase
151 mov _base,ax ;store ptr to bottom of stack
152
153; code added here to allow allocates and exec's in the c code
154; we will have to calculate the size of the code that has been loaded
155
156 mov bx,sp ; bx = length of the stack
157 shr bx,1
158 shr bx,1
159 shr bx,1
160 shr bx,1 ; bx = number of paragraphs in stack,
161 add bx,1 ; (fudge factor!)<--emk ,was 10
162 mov ax,ss
163 add bx,ax ; bx = paragraph a little past the stack
164 mov ax,es ; ax = paragraph of the psp
165 sub bx,ax ; bx = number of paragraphs in code
166 mov ah,setblock
167 int 021h
168
169; end of added code!
170
171 mov _psp,es ; save pointer to psp for setblock <---kwc
172 mov cl,psp_parlen ;get number of bytes <--emk
173 xor ch,ch ;cx = number of bytes of parms!
174 mov si,offset psp_par ;point to DOS command line parms <--emk
175
176; more modified code, picking up argv[0] from the environment!
177
178 mov ds,psp_env ;set ds to segid of environment from es:psp
179 assume ds:nothing
180
181 mov _env,ds ;remember where environment is
182
183 mov si,0 ;clear index to step thru env
184;The env has a set of keyword=operand, each one ending with a single null byte.
185;At the end of the last one is a double null. We are looking for the end of
186;all these keywords, by looking for the double null.
187; $DO COMPLEX
188 JMP SHORT $$SD4
189$$DO4:
190 inc si ;bump index to look at next byte in env
191; $STRTDO
192$$SD4:
193 cmp word ptr [si],0 ;is this a double null delimiter?
194; $ENDDO E ;ifdouble null found, exit
195 JNE $$DO4
196;At end of env is the double null and a word counter
197 add si,4 ;step over this double null delimiter
198 ; and the following word counter
199 push si ;save pointer to next field in env
200;This is the invocation statement, including the path name, even if not specified
201;but supplied by PATH.
202
203;continue stepping thru env looking for one more null byte, which indicates
204;the end of the invocation command.
205; $DO
206$$DO7:
207 lodsb ;get a byte from env to al
208 cmp al,0 ;is this a null byte?
209; $ENDDO E ;quit if null is found
210 JNE $$DO7
211
212 mov bx,si ; bx -> asciiz zero
213 pop si ; si -> first byte of agrv[0], the invocation command
214 sub bx,si ; bx = length of argv[0]
215 mov dx,bx ; (save for the copy later)
216 dec dx
217 add bx,cx ; add in the length of the rest of the parms
218 inc bx ; add one for the asciiz zero!
219 and bx,0fffeh ;force even number of bytes
220 add bx,2 ;adjust for possible rounding error
221 sub sp,bx ;allocate space on stack
222 mov di,sp ; (es:di) -> where we will put the stuff
223 push es
224 mov ax,ss
225 mov es,ax
226 xchg cx,dx ; length of argv[0] to copy, save length of parms
227 rep movsb ; (ds:si) already point to argv[0]
228 pop es
229 mov ss:byte ptr [di],' ' ;store trailing blank!
230 inc di
231 mov _rdi,di ;AN000; save start of command parms
232 xchg cx,dx ; restore length of parms
233; $IF NCXZ ;if some bytes to move,
234 JCXZ $$IF9
235
236 mov si,offset psp_par ;point to DOS command line parms in psp
237; $DO
238$$DO10:
239 mov al,es:[si] ;move bytes to stack
240 mov ss:[di],al
241 inc si
242 inc di
243; $ENDDO LOOP
244 LOOP $$DO10
245; $ENDIF ;bytes to move?
246$$IF9:
247 xor ax,ax
248 mov ss:[di],al ;store null byte
249 mov ax,ss
250 mov ds,ax ;es, ds, and ss are all equal
251 assume ds:DGroup
252
253 mov es,ax ;es, ds, and ss are all equal
254 assume es:DGroup
255
256 mov ax,_rdi ;AN000; restore offset of parms on stack
257 push ax ;ptr to command line
258
259 call _inmain ;AC000; call C main
260
261 mov ah,ret_cd_exit ;return to DOS
262 int 21h ;errorlevel ret code in al
263
264XCMAIN endp
265
266 page
267
268;
269; name XCEXIT -- terminate execution of C program
270;
271; description This function terminates execution of the current
272; program by returning to DOS. The error code
273; argument normally supplied to XCEXIT is ignored
274; in this implementation.
275;
276; input - al = binary return code for dos/ERRORLEVEL
277;
278
279 assume cs:PGroup
280 assume ds:DGroup
281 assume es:DGroup
282 assume ss:DGroup
283
284 public xcexit
285XCEXIT proc far
286
287 mov ah,ret_cd_exit ; <--- kwc
288 int 021h ; <--- kwc
289
290XCEXIT endp
291
292;--------------------------------------------------------------------------
293
294 PAGE
295
296CENTER MACRO NAMELIST
297 PUSH BP ; SAVE CURRENT BP
298 MOV BP,SP ; POINT AT STACK WITH BP
299WORKOFS = 0
300 IRP ANAME,<NAMELIST> ; FOR EACH WORKING VARIABLE
301 IFNB <&ANAME>
302WORKOFS = WORKOFS-2 ; WE WILL ALLOCATE ONE
303 DOEQU &ANAME,%WORKOFS ; WORD ON THE STACK THAT
304 ENDIF
305 ENDM ; IS UNDER SS,BP
306 ADD SP,WORKOFS
307 ENDM
308
309DOEQU MACRO NAME,VALUE
310&NAME EQU &VALUE
311 ENDM
312
313CEXIT MACRO VALUE
314 MOV SP,BP
315 POP BP
316 RET
317 ENDM
318
319 PAGE
320
321; INPUT PARAMATERS PASSED ON STACK
322
323PARMS STRUC
324
325OLD_BP DW ? ; SAVED BP
326RETADD DW ? ; RETURN ADDRESS
327PARM_1 DW ?
328PARM_2 DW ?
329PARM_3 DW ?
330PARM_4 DW ?
331PARM_5 DW ?
332PARM_6 DW ?
333PARM_7 DW ?
334PARM_8 DW ?
335
336PARMS ENDS
337
338SAVE_SS DW 0
339SAVE_SP DW 0
340
341 PAGE
342
343;************************************************************************
344; ;
345; Subroutine Name: ;
346; getpspbyte ;
347; ;
348; Subroutine Function: ;
349; get a byte from PSP ; ;
350; ;
351; Input: ;
352; SS:[BP]+PARM1 = offset in PSP ;
353; ;
354; Output: ;
355; AL = byte from PSP:offset ;
356; ;
357; C calling convention: ;
358; char = getpspbyte(offset); ;
359; ;
360;************************************************************************
361
362MOFFSET EQU PARM_1 ;AN000;
363
364 ASSUME CS:PGROUP ;AN000;
365 ASSUME DS:DGROUP ;AN000;
366 ASSUME ES:DGROUP ;AN000;
367 ASSUME SS:DGROUP ;AN000;
368
369 PUBLIC _GETPSPBYTE ;AN000;
370_GETPSPBYTE PROC NEAR ;AN000;
371
372 CENTER ;AN000;
373
374 PUSH DS ;AN000;
375
376 MOV DS,_PSP ;AN000; get save PSP segment
377 MOV SI,[BP].MOFFSET ;AN000; get offset into PSP
378 LODSB ;AN000; get PSP byte
379 MOV AH,0 ;AN000; zero high byte
380
381 POP DS ;AN000;
382
383 CEXIT ;AN000;
384
385_GETPSPBYTE ENDP
386
387
388;************************************************************************
389; ;
390; Subroutine Name: ;
391; putpspbyte ;
392; ;
393; Subroutine Function: ;
394; put a byte into PSP ; ;
395; ;
396; Input: ;
397; SS:[BP]+MVALUE = byte in AL ;
398; SS:[BP]+MOFFSET = offset in PSP ;
399; ;
400; Output: ;
401; none ;
402; ;
403; C calling convention: ;
404; putpspbyte(offset,char); ;
405; ;
406;************************************************************************
407
408
409MVALUE EQU PARM_2 ;AN000;
410MOFFSET EQU PARM_1 ;AN000;
411
412 ASSUME CS:PGROUP ;AN000;
413 ASSUME DS:DGROUP ;AN000;
414 ASSUME ES:DGROUP ;AN000;
415 ASSUME SS:DGROUP ;AN000;
416
417 PUBLIC _PUTPSPBYTE ;AN000;
418_PUTPSPBYTE PROC NEAR ;AN000;
419
420 CENTER ;AN000;
421
422 PUSH ES ;AN000;
423
424 MOV AX,[BP].MVALUE ;AN000; get byte to store in PSP
425 MOV ES,_PSP ;AN000; get saved PSP segment
426 MOV DI,[BP].MOFFSET ;AN000; get offset in PSP
427 STOSB ;AN000; store the byte
428
429 POP ES ;AN000;
430
431 CEXIT ;AN000;
432
433_PUTPSPBYTE ENDP
434
435
436;-------------------------------------------------------------------
437;
438; MODULE: crit_err_handler()
439;
440; PURPOSE: Supplies assembler exit routines for
441; critical error situations
442;
443; CALLING FORMAT:
444; crit_err_handler;
445;-------------------------------------------------------------------
446 public _crit_err_handler ;AN000;
447 public vector ;AN000;
448vector dd 0 ;AN000;
449; ;AN000;
450_crit_err_handler proc near ;AN000;
451 pushf ;AN000;
452 push ax ; save registers ;AN000;
453 push ds ;AN000;
454 mov ax,dgroup ;get C data segment ;AN000;
455 mov ds,ax ;AN000;
456 mov ax,word ptr ds:_old_int24_off ;get int24 offset ;AN000;
457 mov word ptr cs:vector,ax ;AN000;
458 mov ax,word ptr ds:_old_int24_off+2 ;get int24 segment ;AN000;
459 mov word ptr cs:vector+2,ax ;AN000;
460 pop ds ;restore registers ;AN000;
461 pop ax ;AN000;
462; ;AN000;
463 call dword ptr cs:vector ; invoke DOS err hndlr ;AN000;
464 cmp al,ABORT ; what was the user's response ;AN000;
465 jnge retry ; ;AN000;
466; ;AN000;
467 mov ax,dgroup ;get C data segment ;AN000;
468 mov ds,ax ;AN000;
469 mov es,ax ;AN000;
470 call _Reset_appendx ; restore user's orig append/x ;AN000;
471; ;AN000;
472 mov ax,(RET_EXIT shl 8)+XABORT ; return to DOS w/criterr error ;AN000;
473 int 21h ; ;AN000;
474retry: ;AN000;
475 iret ;AN000;
476; ;AN000;
477_crit_err_handler endp ;AN000;
478_text ends ;AN000;
479 end XCMAIN ;AN000;
480 \ No newline at end of file
diff --git a/v4.0/src/CMD/ATTRIB/MAKEFILE b/v4.0/src/CMD/ATTRIB/MAKEFILE
new file mode 100644
index 0000000..a9e670a
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/MAKEFILE
@@ -0,0 +1,46 @@
1#************************** makefile for cmd\append ***************************
2
3msg =..\..\messages
4dos =..\..\dos
5inc =..\..\inc
6hinc =..\..\h
7
8#
9####################### dependencies begin here. #########################
10#
11
12all: attrib.exe
13
14attrib.ctl: attrib.skl \
15 $(msg)\$(COUNTRY).msg \
16 makefile
17
18_parse.obj: _parse.asm \
19 $(inc)\parse.asm \
20 $(inc)\psdata.inc
21
22_msgret.obj: _msgret.asm \
23 $(inc)\msgserv.asm \
24 $(inc)\sysmsg.inc \
25 $(inc)\copyrigh.inc \
26 attrib.skl \
27 attrib.ctl \
28 attrib.cl1 \
29 attrib.cl2 \
30 attrib.cla \
31 attrib.clb
32
33attriba.obj: attriba.asm
34
35attrib.obj: attrib.c \
36 attrib.h \
37 parse.h \
38 msgret.h \
39 makefile
40
41attrib.exe: attrib.obj \
42 attriba.obj \
43 _parse.obj \
44 _msgret.obj \
45 attrib.lnk
46 link @attrib.lnk
diff --git a/v4.0/src/CMD/ATTRIB/MSGRET.H b/v4.0/src/CMD/ATTRIB/MSGRET.H
new file mode 100644
index 0000000..0f00329
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/MSGRET.H
@@ -0,0 +1,60 @@
1/*  */
2/*----------------------------------------------------------------------+
3| |
4| This file contains the structures and defines that are needed to use |
5| the message retriever from a C program. |
6| |
7| |
8| Date: 6-19-87 |
9| |
10+----------------------------------------------------------------------*/
11
12
13#define utility_msg_class 0xff /*;AN000; Utility message type */
14#define exterr_msg_class 0x01 /*;AN000;*/
15
16
17/* Sublist Flag Values */
18
19/* Alignment Indicator */
20#define sf_left 0x00 /*;AN000; left align */
21#define sf_right 0x80 /*;AN000; right align */
22
23/* Field Type */
24#define sf_char 0x00 /*;AN000; character */
25#define sf_unsbin2d 0x01 /*;AN000; unsigned binary to decimal */
26#define sf_sbin 0x02 /*;AN000; signed binary to decimal */
27#define sf_unsbin2h 0x03 /*;AN000; unsigned binary to hex */
28#define sf_date 0x04 /*;AN000; date */
29#define sf_time12 0x05 /*;AN000; time 12-hour */
30#define sf_time24 0x06 /*;AN000; time 24-hour */
31
32
33/* Data Variable Size */
34
35#define sf_ch 0x00 /*;AN000; single character */
36#define sf_asciiz 0x10 /*;AN000; asciiz string */
37#define sf_byte 0x10 /*;AN000; byte */
38#define sf_word 0x20 /*;AN000; word */
39#define sf_dword 0x30 /*;AN000; double word */
40
41#define sf_mdy2 0x20 /*;AN000; month,day,year (2 digits) */
42#define sf_mdy4 0x30 /*;AN000; month,day,year (4 digits) */
43
44#define sf_hhmm 0x00 /*;AN000; hh:mm */
45#define sf_hhmmss 0x10 /*;AN000; hh:mm:ss */
46#define sf_hhmmsshh 0x20 /*;AN000; hh:mm:ss:hh */
47
48
49struct m_sublist /*;AN000; */
50 { /*;AN000; */
51 BYTE sub_size; /*;AN000; */
52 BYTE sub_res; /*;AN000; */
53 WORD sub_value; /*;AN000; */
54 WORD sub_value_seg; /*;AN000; */
55 BYTE sub_id; /*;AN000; */
56 BYTE sub_flags; /*;AN000; */
57 BYTE sub_max_width; /*;AN000; */
58 BYTE sub_min_width; /*;AN000; */
59 BYTE sub_pad_char; /*;AN000; */
60 }; /*;AN000; */
diff --git a/v4.0/src/CMD/ATTRIB/PARSE.H b/v4.0/src/CMD/ATTRIB/PARSE.H
new file mode 100644
index 0000000..2421481
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/PARSE.H
@@ -0,0 +1,185 @@
1/*  */
2/*----------------------------------------------------------------------+
3| |
4| This file contains the structures and defines that are needed to use |
5| the parser from a C program. |
6| |
7| |
8| Date: 5-21-87 |
9| |
10+----------------------------------------------------------------------*/
11
12#define BYTE unsigned char /*;AN000;*/
13#define WORD unsigned short /*;AN000;*/
14#define DWORD unsigned long /*;AN000;*/
15
16#define p_len_parms 4 /* length of p_parms */ /*;AN000;*/
17#define p_i_use_default 0 /* no extra stuff specified */ /*;AN000;*/
18#define p_i_have_delim 1 /* extra delimiter specified */ /*;AN000;*/
19#define p_i_have_eol 2 /* extra EOL specified */ /*;AN000;*/
20
21struct p_parms /*;AN000;*/
22 { /*;AN000;*/
23 struct p_parmsx *p_parmsx_address; /* address of p_parmsx */ /*;AN000;*/
24 BYTE p_num_extra; /* number of extra stuff */ /*;AN000;*/
25 BYTE p_len_extra_delim; /* length of extra delimiter */ /*;AN000;*/
26 char p_extra_delim[30]; /* extra delimiters */ /*;AN000;*/
27 }; /*;AN000;*/
28
29struct p_parmsx /*;AN000;*/
30 { /*;AN000;*/
31 BYTE p_minp; /* Minimum positional number */ /*;AN000;*/
32 BYTE p_maxp; /* Maximum positional number */ /*;AN000;*/
33 struct p_control_blk *p_control1; /* Address of the 1st CONTROL block */ /*;AN000;*/
34 struct p_control_blk *p_control2; /* Address of the 2nd CONTROL block */ /*;AN000;*/
35 struct p_control_blk *p_control3; /* Address of the 3nd CONTROL block */ /*;AN000;*/
36 struct p_control_blk *p_control4; /* Address of the 4th CONTROL block */ /*;AN000;*/
37 struct p_control_blk *p_control5; /* Address of the 3nd CONTROL block */ /*;AN000;*/
38 struct p_control_blk *p_control6; /* Address of the 4th CONTROL block */ /*;AN000;*/
39 BYTE p_maxs; /*;AN000;*/
40 struct p_control_blk *p_switch; /*;AN000;*/
41 BYTE p_maxk; /*;AN000;*/
42 struct p_control_blk *p_keyword1; /*;AN000;*/
43 struct p_control_blk *p_keyword2; /*;AN000;*/
44 struct p_control_blk *p_keyword3; /*;AN000;*/
45 }; /*;AN000;*/
46
47struct p_control_blk /*;AN000;*/
48 { /*;AN000;*/
49 WORD p_match_flag; /* Controls type matched */ /*;AN000;*/
50 WORD p_function_flag; /* Function should be taken */ /*;AN000;*/
51 WORD p_result_buf; /* Result buffer address */ /*;AN000;*/
52 WORD p_value_list; /* Value list address */ /*;AN000;*/
53 BYTE p_nid; /* # of keyword/SW synonyms */ /*;AN000;*/
54 char p_keyorsw[20]; /* keyword or sw */ /*;AN000;*/
55 }; /*;AN000;*/
56
57/* Match_Flags */ /*;AN000;*/
58#define p_num_val 0x8000 /* Numeric Value */ /*;AN000;*/
59#define p_snum_val 0x4000 /* Signed numeric value */ /*;AN000;*/
60#define p_simple_s 0x2000 /* Simple string */ /*;AN000;*/
61#define p_date_s 0x1000 /* Date string */ /*;AN000;*/
62#define p_time_s 0x0800 /* Time string */ /*;AN000;*/
63#define p_cmpx_s 0x0400 /* Complex string */ /*;AN000;*/
64#define p_file_spc 0x0200 /* File Spec */ /*;AN000;*/
65#define p_drv_only 0x0100 /* Drive Only */ /*;AN000;*/
66#define p_qu_string 0x0080 /* Quoted string */ /*;AN000;*/
67#define p_ig_colon 0x0010 /* Ignore colon at end in match */ /*;AN000;*/
68#define p_repeat 0x0002 /* Repeat allowed */ /*;AN000;*/
69#define p_optional 0x0001 /* Optional */ /*;AN000;*/
70
71/*----------------------------------------------------------------------+
72| |
73| Function flags |
74| |
75+----------------------------------------------------------------------*/
76
77#define p_cap_file 0x0001 /* CAP result by file table */ /*;AN000;*/
78#define p_cap_char 0x0002 /* CAP result by character table */ /*;AN000;*/
79#define p_rm_colon 0x0010 /* Remove ":" at the end */ /*;AN000;*/
80
81#define p_nval_none 0 /* no value list ID */ /*;AN000;*/
82#define p_nval_range 1 /* range list ID */ /*;AN000;*/
83#define p_nval_value 2 /* value list ID */ /*;AN000;*/
84#define p_nval_string 3 /* string list ID */ /*;AN000;*/
85#define p_len_range 9 /* Length of a range choice(two DD plus one DB) */ /*;AN000;*/
86#define p_len_value 5 /* Length of a value choice(one DD plus one DB) */ /*;AN000;*/
87#define p_len_string 3 /* Length of a string choice(one DW plus one DB) */ /*;AN000;*/
88
89/*----------------------------------------------------------------------+
90| |
91| Result block structure |
92| |
93+----------------------------------------------------------------------*/
94
95struct p_result_blk /*;AN000;*/
96 { /*;AN000;*/
97 BYTE p_type; /* Type returned */ /*;AN000;*/
98 BYTE p_item_tag; /* Matched item tag */ /*;AN000;*/
99 WORD p_synonym_ptr; /* pointer to Synonym list returned */ /*;AN000;*/
100 WORD p_result_buff[2]; /* result value */ /*;AN000;*/
101 }; /*;AN000;*/
102
103/*----------------------------------------------------------------------+
104| |
105| type |
106| |
107+----------------------------------------------------------------------*/
108
109#define p_eol 0 /* End of line */ /*;AN000;*/
110#define p_number 1 /* Number */ /*;AN000;*/
111#define p_list_idx 2 /* List Index */ /*;AN000;*/
112#define p_string 3 /* String */ /*;AN000;*/
113#define p_complex 4 /* Complex */ /*;AN000;*/
114#define p_file_spec 5 /* File Spec */ /*;AN000;*/
115#define p_drive 6 /* Drive */ /*;AN000;*/
116#define p_date_f 7 /* Date */ /*;AN000;*/
117#define p_time_f 8 /* Time */ /*;AN000;*/
118#define p_quoted_string 9 /* Quoted String */ /*;AN000;*/
119
120#define p_no_tag 0x0FF /* No ITEM_TAG found */ /*;AN000;*/
121
122/*----------------------------------------------------------------------+
123| |
124| following return code will be returned in the AX register. |
125| |
126+----------------------------------------------------------------------*/
127
128#define p_no_error 0 /* No error */ /*;AN000;*/
129#define p_too_many 1 /* Too many operands */ /*;AN000;*/
130#define p_op_missing 2 /* Required operand missing */ /*;AN000;*/
131#define p_not_in_sw 3 /* Not in switch list provided */ /*;AN000;*/
132#define p_not_in_key 4 /* Not in keyword list provided */ /*;AN000;*/
133#define p_out_of_range 6 /* Out of range specified */ /*;AN000;*/
134#define p_not_in_val 7 /* Not in value list provided */ /*;AN000;*/
135#define p_not_in_str 8 /* Not in string list provided */ /*;AN000;*/
136#define p_syntax 9 /* Syntax error */ /*;AN000;*/
137#define p_rc_eol 0x0ffff /* End of command line */ /*;AN000;*/
138
139/*----------------------------------------------------------------------+
140| |
141| String Value List Block Structure |
142| |
143+----------------------------------------------------------------------*/
144
145struct ps_valist_blk /*;AN000;*/
146 { /*;AN000;*/
147 BYTE ps_val; /* Value type */ /*;AN000;*/
148 BYTE ps_nrng; /* Number of ranges */ /*;AN000;*/
149 BYTE ps_nnval; /* Number of numbers */ /*;AN000;*/
150 BYTE ps_nstrval; /* Number of strings */ /*;AN000;*/
151 BYTE ps_item_tag1; /* Matched item tag */ /*;AN000;*/
152 WORD ps_strings1; /* Address of strings */ /*;AN000;*/
153 BYTE ps_item_tag2; /* Matched item tag */ /*;AN000;*/
154 WORD ps_strings2; /* Address of strings */ /*;AN000;*/
155 BYTE ps_item_tag3; /* Matched item tag */ /*;AN000;*/
156 WORD ps_strings3; /* Address of strings */ /*;AN000;*/
157 BYTE ps_item_tag4; /* Matched item tag */ /*;AN000;*/
158 WORD ps_strings4; /* Address of strings */ /*;AN000;*/
159 BYTE ps_item_tag5; /* Matched item tag */ /*;AN000;*/
160 WORD ps_strings5; /* Address of strings */ /*;AN000;*/
161 BYTE ps_item_tag6; /* Matched item tag */ /*;AN000;*/
162 WORD ps_strings6; /* Address of strings */ /*;AN000;*/
163 BYTE ps_item_tag7; /* Matched item tag */ /*;AN000;*/
164 WORD ps_strings7; /* Address of strings */ /*;AN000;*/
165 BYTE ps_item_tag8; /* Matched item tag */ /*;AN000;*/
166 WORD ps_strings8; /* Address of strings */ /*;AN000;*/
167 BYTE ps_item_tag9; /* Matched item tag */ /*;AN000;*/
168 WORD ps_strings9; /* Address of strings */ /*;AN000;*/
169 BYTE ps_item_tag10; /* Matched item tag */ /*;AN000;*/
170 WORD ps_strings10; /* Address of strings */ /*;AN000;*/
171 BYTE ps_item_tag11; /* Matched item tag */ /*;AN000;*/
172 WORD ps_strings11; /* Address of strings */ /*;AN000;*/
173 BYTE ps_item_tag12; /* Matched item tag */ /*;AN000;*/
174 WORD ps_strings12; /* Address of strings */ /*;AN000;*/
175 BYTE ps_item_tag13; /* Matched item tag */ /*;AN000;*/
176 WORD ps_strings13; /* Address of strings */ /*;AN000;*/
177 BYTE ps_item_tag14; /* Matched item tag */ /*;AN000;*/
178 WORD ps_strings14; /* Address of strings */ /*;AN000;*/
179 BYTE ps_item_tag15; /* Matched item tag */ /*;AN000;*/
180 WORD ps_strings15; /* Address of strings */ /*;AN000;*/
181 BYTE ps_item_tag16; /* Matched item tag */ /*;AN000;*/
182 WORD ps_strings16; /* Address of strings */ /*;AN000;*/
183 BYTE ps_item_tag17; /* Matched item tag */ /*;AN000;*/
184 WORD ps_strings17; /* Address of strings */ /*;AN000;*/
185 }; /*;AN000;*/
diff --git a/v4.0/src/CMD/ATTRIB/_MSGRET.ASM b/v4.0/src/CMD/ATTRIB/_MSGRET.ASM
new file mode 100644
index 0000000..7acb51e
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/_MSGRET.ASM
@@ -0,0 +1,233 @@
1page 60,132 ;AN000;
2name _msgret ;AN000;
3title C to Message Retriever ;AN000;
4;------------------------------------------------------------------- ;AN000;
5; ;AN000;
6; MODULE: _msgret ;AN000;
7; ;AN000;
8; PURPOSE: Supplies an interface between C programs and ;AN000;
9; the DOS message retriever ;AN000;
10; ;AN000;
11; CALLING FORMAT: ;AN000;
12; sysloadmsg(&inregs,&outregs); ;AN000;
13; sysgetmsg(&inregs,&outregs); ;AN000;
14; sysdispmsg(&inregs,&outregs); ;AN000;
15; ;AN000;
16; ;AN000;
17; DATE: 5-21-87 ;AN000;
18; Modified: 6/18/87 ;AN000;
19; ;AN000;
20;------------------------------------------------------------------- ;AN000;
21; ;AN000;
22 INCLUDE SYSMSG.INC ;PERMIT SYSTEM MESSAGE HANDLER DEFINITION ;AN000;
23; ;AN000;
24 MSG_UTILNAME <ATTRIB> ;IDENTIFY THE COMPONENT ;AN000;
25; ;AN000;
26 .8087 ;AN000;
27_TEXT SEGMENT BYTE PUBLIC 'CODE' ;AN000;
28_TEXT ENDS ;AN000;
29_DATA SEGMENT WORD PUBLIC 'DATA' ;AN000;
30_DATA ENDS ;AN000;
31CONST SEGMENT WORD PUBLIC 'CONST' ;AN000;
32CONST ENDS ;AN000;
33_BSS SEGMENT WORD PUBLIC 'BSS' ;AN000;
34_BSS ENDS ;AN000;
35DGROUP GROUP CONST, _BSS, _DATA ;AN000;
36 ASSUME CS: _TEXT, DS: _TEXT, SS: DGROUP, ES: DGROUP ;AN000;
37; ;AN000;
38 public _sysloadmsg ;AN000;
39 public _sysgetmsg ;AN000;
40 public _sysdispmsg ;AN000;
41; ;AN000;
42;------------------------------------------------------------------- ;AN000;
43;------------------------------------------------------------------- ;AN000;
44; ;AN000;
45_DATA segment ;AN000;
46.XLIST ;AN000;
47.XCREF ;AN000;
48; MSG_SERVICES <MSGDATA> ;DATA AREA FOR THE MESSAGE HANDLER ;AN000;
49 MSG_SERVICES <MSGDATA> ;DATA AREA FOR THE MESSAGE HANDLER ;AN000;
50.LIST ;AN000;
51.CREF ;AN000;
52_DATA ends ;AN000;
53; ;AN000;
54; ;AN000;
55_TEXT segment ;AN000;
56; ;AN000;
57;------------------------------------------------------------------- ;AN000;
58; ;AN000;
59 ;DEFAULT=CHECK DOS VERSION ;AN000;
60 ;DEFAULT=NEARmsg ;AN000;
61 ;DEFAULT=INPUTmsg ;AN000;
62 ;DEFAULT=NUMmsg ;AN000;
63 ;DEFAULT=NO TIMEmsg ;AN000;
64 ;DEFAULT=NO DATEmsg ;AN000;
65; MSG_SERVICES <LOADmsg,GETmsg,DISPLAYmsg,CHARmsg,NUMmsg,INPUTmsg,FARmsg,TIMEmsg,DATEmsg> ;AN000;
66; MSG_SERVICES <ATTRIB.CLA,ATTRIB.CLB,ATTRIB.CL1,ATTRIB.CL2> ;MSG TEXT ;AN000;
67.XLIST ;AN000;
68.XCREF ;AN000;
69 MSG_SERVICES <LOADmsg,GETmsg,DISPLAYmsg,CHARmsg,NUMmsg,INPUTmsg,FARmsg,TIMEmsg,DATEmsg> ;AN000;
70 MSG_SERVICES <ATTRIB.CLA,ATTRIB.CLB,ATTRIB.CL1,ATTRIB.CL2> ;MSG TEXT ;AN000;
71.LIST ;AN000;
72.CREF ;AN000;
73; ;AN000;
74;------------------------------------------------------------------- ;AN000;
75_sysloadmsg proc near ;AN000;
76 push bp ; save user's base pointer ;AN000;
77 mov bp,sp ; set bp to current sp ;AN000;
78 push di ; save some registers ;AN000;
79 push si ;AN000;
80; ;AN000;
81; copy C inregs into proper registers ;AN000;
82; ;AN000;
83 mov di,[bp+4] ; fix di (arg 0) ;AN000;
84; ;AN000;
85 mov ax,[di+0ah] ; load di ;AN000;
86 push ax ; the di value from inregs is now on stack ;AN000;
87; ;AN000;
88 mov ax,[di+00] ; get inregs.x.ax ;AN000;
89 mov bx,[di+02] ; get inregs.x.bx ;AN000;
90 mov cx,[di+04] ; get inregs.x.cx ;AN000;
91 mov dx,[di+06] ; get inregs.x.dx ;AN000;
92 mov si,[di+08] ; get inregs.x.si ;AN000;
93 pop di ; get inregs.x.di from stack ;AN000;
94; ;AN000;
95 push bp ; save base pointer ;AN000;
96; ;AN000;
97;------------------------------------------------------------------- ;AN000;
98 call sysloadmsg ; call the message retriever ;AN000;
99;------------------------------------------------------------------- ;AN000;
100; ;AN000;
101 pop bp ; restore base pointer ;AN000;
102 push di ; the di value from call is now on stack ;AN000;
103 mov di,[bp+6] ; fix di (arg 1) ;AN000;
104; ;AN000;
105 mov [di+00],ax ; load outregs.x.ax ;AN000;
106 mov [di+02],bx ; load outregs.x.bx ;AN000;
107 mov [di+04],cx ; load outregs.x.cx ;AN000;
108 mov [di+06],dx ; load outregs.x.dx ;AN000;
109 mov [di+08],si ; load outregs.x.si ;AN000;
110; ;AN000;
111 lahf ; get flags into ax ;AN000;
112 mov al,ah ; move into low byte ;AN000;
113 mov [di+0ch],ax ; load outregs.x.cflag ;AN000;
114; ;AN000;
115 pop ax ; get di from stack ;AN000;
116 mov [di+0ah],ax ; load outregs.x.di ;AN000;
117; ;AN000;
118 pop si ; restore registers ;AN000;
119 pop di ;AN000;
120 mov sp,bp ; restore sp ;AN000;
121 pop bp ; restore user's bp ;AN000;
122 ret ;AN000;
123_sysloadmsg endp ;AN000;
124; ;AN000;
125; ;AN000;
126_sysgetmsg proc near ;AN000;
127 push bp ; save user's base pointer ;AN000;
128 mov bp,sp ; set bp to current sp ;AN000;
129 push di ; save some registers ;AN000;
130 push si ;AN000;
131; ;AN000;
132; copy C inregs into proper registers ;AN000;
133; ;AN000;
134 mov di,[bp+4] ; fix di (arg 0) ;AN000;
135; ;AN000;
136 mov ax,[di+0ah] ; load di ;AN000;
137 push ax ; the di value from inregs is now on stack ;AN000;
138; ;AN000;
139 mov ax,[di+00] ; get inregs.x.ax ;AN000;
140 mov bx,[di+02] ; get inregs.x.bx ;AN000;
141 mov cx,[di+04] ; get inregs.x.cx ;AN000;
142 mov dx,[di+06] ; get inregs.x.dx ;AN000;
143 mov si,[di+08] ; get inregs.x.si ;AN000;
144 pop di ; get inregs.x.di from stack ;AN000;
145; ;AN000;
146 push bp ; save base pointer ;AN000;
147; ;AN000;
148;------------------------------------------------------------------- ;AN000;
149 call sysgetmsg ; call the message retriever ;AN000;
150;------------------------------------------------------------------- ;AN000;
151; ;AN000;
152 pop bp ; restore base pointer ;AN000;
153 push di ; the di value from call is now on stack ;AN000;
154 mov di,[bp+6] ; fix di (arg 1) ;AN000;
155; ;AN000;
156 mov [di+00],ax ; load outregs.x.ax ;AN000;
157 mov [di+02],bx ; load outregs.x.bx ;AN000;
158 mov [di+04],cx ; load outregs.x.cx ;AN000;
159 mov [di+06],dx ; load outregs.x.dx ;AN000;
160 mov [di+08],si ; load outregs.x.si ;AN000;
161; ;AN000;
162 lahf ; get flags into ax ;AN000;
163 mov al,ah ; move into low byte ;AN000;
164 mov [di+0ch],ax ; load outregs.x.cflag ;AN000;
165; ;AN000;
166 pop ax ; get di from stack ;AN000;
167 mov [di+0ah],ax ; load outregs.x.di ;AN000;
168; ;AN000;
169 pop si ; restore registers ;AN000;
170 pop di ;AN000;
171 mov sp,bp ; restore sp ;AN000;
172 pop bp ; restore user's bp ;AN000;
173 ret ;AN000;
174_sysgetmsg endp ;AN000;
175; ;AN000;
176; ;AN000;
177_sysdispmsg proc near ;AN000;
178 push bp ; save user's base pointer ;AN000;
179 mov bp,sp ; set bp to current sp ;AN000;
180 push di ; save some registers ;AN000;
181 push si ;AN000;
182; ;AN000;
183; copy C inregs into proper registers ;AN000;
184; ;AN000;
185 mov di,[bp+4] ; fix di (arg 0) ;AN000;
186; ;AN000;
187 mov ax,[di+0ah] ; load di ;AN000;
188 push ax ; the di value from inregs is now on stack ;AN000;
189; ;AN000;
190 mov ax,[di+00] ; get inregs.x.ax ;AN000;
191 mov bx,[di+02] ; get inregs.x.bx ;AN000;
192 mov cx,[di+04] ; get inregs.x.cx ;AN000;
193 mov dx,[di+06] ; get inregs.x.dx ;AN000;
194 mov si,[di+08] ; get inregs.x.si ;AN000;
195 pop di ; get inregs.x.di from stack ;AN000;
196; ;AN000;
197 push bp ; save base pointer ;AN000;
198; ;AN000;
199;------------------------------------------------------------------- ;AN000;
200 call sysdispmsg ; call the message retriever ;AN000;
201;------------------------------------------------------------------- ;AN000;
202; ;AN000;
203 pop bp ; restore base pointer ;AN000;
204 push di ; the di value from call is now on stack ;AN000;
205 mov di,[bp+6] ; fix di (arg 1) ;AN000;
206; ;AN000;
207 mov [di+00],ax ; load outregs.x.ax ;AN000;
208 mov [di+02],bx ; load outregs.x.bx ;AN000;
209 mov [di+04],cx ; load outregs.x.cx ;AN000;
210 mov [di+06],dx ; load outregs.x.dx ;AN000;
211 mov [di+08],si ; load outregs.x.si ;AN000;
212; ;AN000;
213 lahf ; get flags into ax ;AN000;
214 mov al,ah ; move into low byte ;AN000;
215 mov [di+0ch],ax ; load outregs.x.cflag ;AN000;
216; ;AN000;
217 pop ax ; get di from stack ;AN000;
218 mov [di+0ah],ax ; load outregs.x.di ;AN000;
219; ;AN000;
220 pop si ; restore registers ;AN000;
221 pop di ;AN000;
222 mov sp,bp ; restore sp ;AN000;
223 pop bp ; restore user's bp ;AN000;
224 ret ;AN000;
225_sysdispmsg endp ;AN000;
226; ;AN000;
227; ;AN000;
228_TEXT ends ; end code segment ;AN000;
229
230 include msgdcl.inc
231
232 end ;AN000;
233 \ No newline at end of file
diff --git a/v4.0/src/CMD/ATTRIB/_PARSE.ASM b/v4.0/src/CMD/ATTRIB/_PARSE.ASM
new file mode 100644
index 0000000..9800c9e
--- /dev/null
+++ b/v4.0/src/CMD/ATTRIB/_PARSE.ASM
@@ -0,0 +1,107 @@
1page 60,132 ;AN000;
2name _parse ;AN000;
3title C to PARSER interface ;AN000;
4;------------------------------------------------------------------- ;AN000;
5; ;AN000;
6; MODULE: _parse ;AN000;
7; ;AN000;
8; PURPOSE: Supplies an interface between C programs and ;AN000;
9; the DOS parser ;AN000;
10; ;AN000;
11; CALLING FORMAT: ;AN000;
12; parse(&inregs,&outregs); ;AN000;
13; ;AN000;
14; DATE: 5-21-87 ;AN000;
15; ;AN000;
16;------------------------------------------------------------------- ;AN000;
17; ;AN000;
18; extrn sysparse:far ;AN000;
19; ;AN000;
20 public _parse ;AN000;
21; ;AN000;
22;------------------------------------------------------------------- ;AN000;
23FarSW equ 0 ; make sysparse be a NEAR proc ;AN000;
24TimeSW equ 0 ; Check time format ;AN000;
25FileSW equ 1 ; Check file specification ;AN000;
26CAPSW equ 1 ; Perform CAPS if specified ;AN000;
27CmpxSW equ 0 ; Check complex list ;AN000;
28NumSW equ 1 ; Check numeric value ;AN000;
29KeySW equ 1 ; Support keywords ;AN000;
30SwSW equ 1 ; Support switches ;AN000;
31Val1SW equ 1 ; Support value definition 1 ;AN000;
32Val2SW equ 1 ; Support value definition 2 ;AN000;
33Val3SW equ 1 ; Support value definition 3 ;AN000;
34DrvSW equ 0 ; Support drive only format ;AN000;
35QusSW equ 1 ; Support quoted string format ;AN000;
36;------------------------------------------------------------------- ;AN000;
37DGROUP GROUP _DATA
38PGROUP GROUP _TEXT
39
40_DATA segment byte public 'DATA' ;AN000;
41BASESW = 1 ;SPECIFY, PSDATA POINTED TO BY "DS"
42INCSW = 0 ;PSDATA.INC IS ALREADY INCLUDED
43 INCLUDE PSDATA.INC ;PARSER'S WORK SPACE
44_DATA ends ;AN000;
45
46_TEXT segment byte public 'CODE' ;AN000;
47
48 ASSUME CS: PGROUP ;AN000;
49 ASSUME DS: DGROUP ;AN000;
50;------------------------------------------------------------------- ;AN000;
51.xlist ;AN000;
52include parse.asm ; include the parser ;AN000;
53.list ;AN000;
54;------------------------------------------------------------------- ;AN000;
55; ;AN000;
56_parse proc near ;AN000;
57 push bp ; save user's base pointer ;AN000;
58 mov bp,sp ; set bp to current sp ;AN000;
59 push di ; save some registers ;AN000;
60 push si ;AN000;
61; ;AN000;
62; copy C inregs into proper registers ;AN000;
63; ;AN000;
64 mov di,[bp+4] ; fix di (arg 0) ;AN000;
65; ;AN000;
66 mov ax,[di+0ah] ; load di ;AN000;
67 push ax ; the di value from inregs is now on stack ;AN000;
68; ;AN000;
69 mov ax,[di+00] ; get inregs.x.ax ;AN000;
70 mov bx,[di+02] ; get inregs.x.bx ;AN000;
71 mov cx,[di+04] ; get inregs.x.cx ;AN000;
72 mov dx,[di+06] ; get inregs.x.dx ;AN000;
73 mov si,[di+08] ; get inregs.x.si ;AN000;
74 pop di ; get inregs.x.di from stack ;AN000;
75; ;AN000;
76 push bp ; save base pointer ;AN000;
77; ;AN000;
78;------------------------------------------------------------------- ;AN000;
79 call sysparse ; call the parser ;AN000;
80;------------------------------------------------------------------- ;AN000;
81; ;AN000;
82 pop bp ; restore base pointer ;AN000;
83 push di ; the di value from call is now on stack ;AN000;
84 mov di,[bp+6] ; fix di (arg 1) ;AN000;
85; ;AN000;
86 mov [di+00],ax ; load outregs.x.ax ;AN000;
87 mov [di+02],bx ; load outregs.x.bx ;AN000;
88 mov [di+04],cx ; load outregs.x.cx ;AN000;
89 mov [di+06],dx ; load outregs.x.dx ;AN000;
90 mov [di+08],si ; load outregs.x.si ;AN000;
91; ;AN000;
92 lahf ; get flags into ax ;AN000;
93 mov al,ah ; move into low byte ;AN000;
94 mov [di+0ch],ax ; load outregs.x.cflag ;AN000;
95; ;AN000;
96 pop ax ; get di from stack ;AN000;
97 mov [di+0ah],ax ; load outregs.x.di ;AN000;
98; ;AN000;
99 pop si ; restore registers ;AN000;
100 pop di ;AN000;
101 mov sp,bp ; restore sp ;AN000;
102 pop bp ; restore user's bp ;AN000;
103 ret ;AN000;
104_parse endp ;AN000;
105_TEXT ends ; end code segment ;AN000;
106 end ;AN000;
107 \ No newline at end of file