summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/REPLACE/REPLACE.C
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/REPLACE/REPLACE.C')
-rw-r--r--v4.0/src/CMD/REPLACE/REPLACE.C2047
1 files changed, 2047 insertions, 0 deletions
diff --git a/v4.0/src/CMD/REPLACE/REPLACE.C b/v4.0/src/CMD/REPLACE/REPLACE.C
new file mode 100644
index 0000000..509a9a6
--- /dev/null
+++ b/v4.0/src/CMD/REPLACE/REPLACE.C
@@ -0,0 +1,2047 @@
1/* 0 */
2/**************************************************************************/
3/* */
4/* UTILITY NAME: Replace */
5/* */
6/* SOURCE FILE NAME: Replace.C */
7/* */
8/* STATUS: Replace Utility, DOS Version 4.00 */
9/* */
10/* FUNCTIONAL DESCRIPTION: REPLACE is an external DOS utility that */
11/* allows a user to selectively replace */
12/* files on the target with files of the */
13/* same name from the source. The user can */
14/* also selectively add files from the source */
15/* to the target. */
16/* */
17/* SYNTAX: [d:][path]REPLACE[d:][path]filename[.ext] */
18/* [d:][path] [/A][/P][/R][/S][/U][/W] */
19/* where: */
20/* [d:][path] before REPLACE specifies the drive */
21/* and path that contains the REPLACE command file, */
22/* if it is not the current directory of the */
23/* default drive. */
24/* */
25/* [d:][path]filename[.ext] specifies the names of */
26/* the files on the source that are to be replaced */
27/* on the target or added to the target. The file */
28/* name can contain global file name characters. */
29/* */
30/* [d:][path] specifies the target drive and */
31/* directory. The files in this directory are */
32/* the ones that are to be replaced, if /A is */
33/* specified the source files are copied to this */
34/* directory. The default is the directory on the */
35/* current drive. */
36/* */
37/* /A copies all files specified by the source that */
38/* do not exist on the target. */
39/* */
40/* /P prompts as each file is encountered on the tar- */
41/* get, allowing selective replacing or adding. */
42/* */
43/* /R replaces files that are read-only on the target.*/
44/* */
45/* /S searches all directories of the target for */
46/* files matching the source file name. */
47/* */
48/* /U replaces updated date/time attribute source */
49/* files to the target. */
50/* */
51/* /W waits for you to insert a diskette before be- */
52/* ginning to search for source files. */
53/* */
54/* ** NOTE ** /A + /S and A/ + /U cannot be used together. */
55/* */
56/* LINKS: */
57/* COMSUBS.LIB - DOS DBCS function calls */
58/* MAPPER.LIB - DOS function calls */
59/* SLIBC3.LIB - C library functions */
60/* _MSGRET.SAL - Assembler interface for common DOS message services */
61/* _PARSE.SAL - Assembler interface for common DOS parser */
62/* _REPLACE.SAL- Assembler control break and critical error handlers */
63/* */
64/* ERROR HANDLING: Error message is displayed and utility is */
65/* then terminated (with appropriate error level). */
66/* */
67/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
68/* */
69/* MODIFICATIONS: */
70/* */
71/* RW : R. W 1986 */
72/* */
73/* ;AC000;: Changed code for DOS Version 4.00 S.M 1987 */
74/* */
75/* ;AN000;: New code for DOS Version 4.00 S.M 1987 */
76/* ;AN000;A - Append/X */
77/* ;AN000;EA- Extended Attributes */
78/* ;AN000;EC- Extended Country Info */
79/* ;AN000;M - Message handler */
80/* ;AN000;P - Parser */
81/* ;AN000;U - /U (update switch) */
82/* */
83/* ;Ax001;: New code required - PTM0000001 S.M 1987 */
84/* Set archive bit ON after replace */
85/* */
86/* ;Ax002;: Change code req'd - PTM0003154 S.M 1988 */
87/* Enable filesize update in directory */
88/* */
89/* ;Ax003;: Change code req'd - PTM0003753 S.M 1988 */
90/* Dsearchf return garbage */
91/* */
92/* ;Ax004;: Change code req'd - PTM0003891 S.M 1988 */
93/* One char subdir name not handled */
94/* */
95/* ;Ax005;: Change code req'd - PTM0003907 S.M 1988 */
96/* Incorrect message responses */
97/* */
98/* ;Ax006;: Change code req'd - PTM0004124 S.M 1988 */
99/* Incorrect message responses */
100/* */
101/**************************************************************************/
102
103#include "comsub.h" /* ;AN000;P DBCS functions */
104#include "dos.h" /* ;AN000;M Used for the REGS union */
105#include "replacep.h" /* ;AN000;P Parser structures */
106
107/* ------------- ERRORLEVEL CODES ---------------*/
108#define ERRLEVELNEG1 -1 /* ;AC000; */
109#define ERRLEVEL0 0 /* ;AC000; No error */
110#define ERRLEVEL1 1 /* ;AC000; Invalid function number */
111#define ERRLEVEL2 2 /* ;AC000; File not found */
112#define ERRLEVEL3 3 /* ;AN000; Path not found */
113#define ERRLEVEL8 8 /* ;AC000; Insufficient memory */
114#define ERRLEVEL11 11 /* ;AC000; Invalid format */
115
116/* ------------- INT 21h FUNCTIONS --------------*/
117#define GETVEC_CRITERR 0x3524 /* ;AN000;A Int 21,get vector,criterr */
118#define GETVEC_CTLBRK 0x3523 /* ;AN000;A Int 21,get vector,ctlbrk */
119#define GETX_INSTALL 0xB700 /* ;AN000;A Is Append/x installed? */
120#define GETX_STATUS 0xB706 /* ;AN000;A Get the Append/x status */
121#define GETX_VERSION 0xB702 /* ;AN000;A Is it the DOS Append/x? */
122#define SETVEC_CRITERR 0x2524 /* ;AN000;A Int 21,set vector,criterr */
123#define SETVEC_CTLBRK 0x2523 /* ;AN000;A Int 21,set vector,ctlbrk */
124#define SETX_STATUS 0xB707 /* ;AN000;A Set the Append/x status */
125
126/* ------------- INT 21h RETURN CODES -----------*/
127#define INSUFFMEM 8
128#define NOERROR 0
129#define NOMOREFILES 18
130#define TARGETFULL -1
131
132/* ------------- MESSAGE EQUATES ----------------*/
133#define BLNK ' ' /* ;AN000;M For sublist.pad_char */
134#define CARRY 0x0001 /* ;AN000;M */
135#define DEC_INPUT 161 /* ;AN000;M Byte def for sublist.flags */
136#define DOS_CON_INPUT 0xC8 /* ;AN000;M Input for Y/N response */
137#define EXT_ERR_CLASS 0x01 /* ;AN000;M DOS Extended error class */
138#define NO_INPUT 0x00 /* ;AN000;M No input characters */
139#define PARSE_ERR_CLASS 0x02 /* ;AN000;M Parse error class */
140#define RESERVED 0 /* ;AN000;M Reserved byte field */
141#define STDERR 0x0002 /* ;AN000;M Standard error device handle */
142#define STDOUT 0x0001 /* ;AN000;M Std output device handle */
143#define STR_INPUT 16 /* ;AN000;M Byte def for sublist.flags */
144#define SUBCNT0 0 /* ;AN000;M 0 substitutions in message */
145#define SUBCNT1 1 /* ;AN000;M 1 substitution in message */
146#define SUBLIST_LENGTH 11 /* ;AN000;M Length of sublist structure */
147#define UTILITY_CLASS 0x0ff /* ;AN000;M Utility message class */
148
149/* ------------- MESSAGES -----------------------*/
150#define MSG_NOMEM 1 /* ;AN000;M Insufficient memory */
151#define MSG_INCOMPAT 2 /* ;AN000;M Invalid parameter combo */
152#define MSG_NOSOURCE 3 /* ;AN000;M Source path required */
153#define MSG_NONEREPL 4 /* ;AN000;M No files replaced */
154#define MSG_NONEADDE 5 /* ;AN000;M No files added */
155#define MSG_START 6 /* ;AN000;M Press any key to continue */
156#define MSG_ERRFNF 7 /* ;AN000;M File not Found */
157#define MSG_ERRPNF 8 /* ;AN000;M Path not Found */
158#define MSG_ERRACCD 9 /* ;AN000;M Access denied */
159#define MSG_ERRDRV 10 /* ;AN000;M Invalid drive specification */
160#define MSG_BADPARM 11 /* ;AN000;M Invalid parameter */
161#define MSG_WARNSAME 12 /* ;AN000;M File cannot be copied...*/
162#define MSG_ERRDSKF 13 /* ;AN000;M Insufficient disk space */
163#define MSG_REPLACIN 14 /* ;AN000;M Replacing %1 */
164#define MSG_ADDING 15 /* ;AN000;M Adding %1 */
165#define MSG_SOMEREPL 16 /* ;AN000;M %1 file(s) replaced */
166#define MSG_SOMEADDE 17 /* ;AN000;M %1 file(s) added */
167#define MSG_NONFOUND 18 /* ;AN000;M No files found */
168#define MSG_QREPLACE 19 /* ;AN000;M Replace %1? (Y/N) */
169#define MSG_QADD 20 /* ;AN000;M Add %1? (Y/N) */
170#define MSG_XTRAPARM 21 /* ;AN005;M Too many parameters */
171#define MSG_BADSWTCH 22 /* ;AN005;M Invalid switch */
172
173/* ------------- PARSE EQUATES ------------------*/
174#define A_SW "/A" /* ;AN000;P For switch id /A */
175#define P_SW "/P" /* ;AN000;P For switch id /P */
176#define R_SW "/R" /* ;AN000;P For switch id /R */
177#define S_SW "/S" /* ;AN000;P For switch id /S */
178#define U_SW "/U" /* ;AN000;P For switch id /U */
179#define W_SW "/W" /* ;AN000;P For switch id /W */
180#define CAPRESULT 0x0001 /* ;AN000;P Cap result by file table */
181#define MAXPOSITION 2 /* ;AN000;P Max positionals allowed */
182#define MINPOSITION 1 /* ;AN000;P Min positionals allowed */
183#define NOCAPPING 0x0000 /* ;AN000;P Do not capitalize */
184#define OPT_FILESPEC 0x0201 /* ;AN000;P Filespec & optional */
185#define OPT_SWITCH 0x0001 /* ;AN000;P Optional (switch) */
186#define REQ_FILESPEC 0x0200 /* ;AN000;P Filespec required */
187
188/* ------------- MISCELLANEOUS ------------------*/
189#define ARCHIVE 0x20 /* Archive bit file attribute */
190#define BUF 512 /* ;AC000; */
191#define FALSE 0
192#define INACTIVE 0x0000 /* ;AN000;A Append/x inactive status */
193#define MAX 256 /* ;AC000; */
194#define MAXMINUS1 255 /* ;AC000; */
195#define NULL 0
196#define SATTRIB 0
197#define SUBDIR 0x10
198#define TATTRIB SUBDIR
199#define TRUE !FALSE
200#define X_INSTALLED 0xffff /* ;AN000;A Set the Append/x status */
201
202struct filedata /* ;AC000; Files used in copy operations */
203{
204 char attribute ;
205 unsigned time ;
206 unsigned date ;
207 long size ;
208 char name[15] ;
209} ;
210
211struct parm_list /* ;AN000;EA To be passed to Extd Create */
212{
213 unsigned ea_list_offset ; /* ;AN000;EA List structure (filled in) */
214 unsigned ea_list_segment ; /* ;AN000;EA */
215 unsigned number ; /* ;AN000;EA ID for iomode */
216 char format ; /* ;AN000;EA Format for iomode */
217 unsigned iomode ; /* ;AN000;EA (Mainly sequential) */
218} eaparm_list = { /* ;AN000;EA */
219 -1, /* ;AN000;EA */
220 -1, /* ;AN000;EA (will recv segment addr) */
221 1, /* ;AN000;EA */
222 6, /* ;AN000;EA */
223 2 /* ;AN000;EA */
224 } ; /* ;AN000;EA */
225
226/* ------------- PARSE STRUCTURES ---------------*/
227struct p_parms p_p ; /* ;AN000;P # of extras & pts to descrptn */
228struct p_parmsx p_px ; /* ;AN000;P min/max parms & pts to controls */
229struct p_control_blk p_con1 ; /* ;AN000;P 1st posit parm in cmd str */
230struct p_control_blk p_con2 ; /* ;AN000;P 2nd posit parm in cmd str */
231struct p_switch_blk p_swit ; /* ;AN000;P /A /P /R /S /U /W */
232struct p_fresult_blk rslt1 ; /* ;AN000;P Result blk rtrnd from parser */
233struct p_result_blk rslt2 ; /* ;AN000;P Result blk rtrnd from parser */
234struct noval novals = {0} ; /* ;AN000;P Value list not used */
235
236/* ------------- MISCELLANEOUS ------------------*/
237union REGS inregs, outregs ; /* ;AN000;P Define register variables */
238struct SREGS segregs ; /* ;AN000; Segment regs for Int21 */
239
240char append_installed = FALSE ; /* ;AN000;A ? */
241char attr_list[BUF] = {0} ; /* ;AN000;EA Buf for list of attributes */
242char cmdln_invalid[64] = {0} ; /* ;AN006; */
243char cmdln_switch[64] = {0} ; /* ;AN006; message, if needed */
244char disk_full = FALSE ; /* RW Flag - Disk full on target */
245char ea_flag = FALSE ; /* ;AN000;EA */
246char errfname[MAX] = {0} ;
247char errline[MAX] = {0} ;
248char filename[MAX] = {0} ; /* RW Save area for filename being copied */
249char fix_es_reg[2] = {0} ; /* ;AN000;P Corrects es reg after type-"far" */
250char not_valid_input = TRUE ; /* ;AN000;M Flag for Y/N message */
251char only_one_valid_file = FALSE ; /* ;AN000; Flag indicating valid filecount */
252char outline[MAX] = {0} ;
253char p_path[64] = {0} ; /* ;AN000;P Recvs path from parser */
254char p_sfilespec[64] = {0} ; /* ;AN000;P Recvs filespec from parser */
255char source[MAXMINUS1] = {0} ;
256char target[MAXMINUS1] = {0} ;
257char target_full = FALSE ; /* ;AN000; Check flag at exit */
258
259unsigned char dbcs_search[3] = {0} ; /* ;AN000; */
260
261unsigned add = FALSE ; /* /A switch */
262unsigned counted = 0 ; /* Num replaced or added */
263unsigned descending = FALSE ; /* /S switch */
264unsigned length ;
265unsigned prompt = FALSE ; /* /P switch */
266unsigned readonly = FALSE ; /* /R switch */
267unsigned segment ;
268unsigned update = FALSE ; /* ;AN000;U /U switch */
269unsigned wait = FALSE ; /* /W switch */
270unsigned x_status = 0 ; /* ;AN000;A Original append/x state */
271unsigned _psp ;
272
273long oldint24 ; /* ;AN000; Rcv cntrl from, then ret to */
274
275extern crit_err_handler() ; /* ;AN000; Assembler routine */
276extern ctl_brk_handler() ; /* ;AN000; Assembler routine */
277
278unsigned Check_Appendx_Install ();
279unsigned Check_Appendx ();
280
281/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
282
283/**************************************************************************/
284/* */
285/* SUBROUTINE NAME: main */
286/* */
287/* SUBROUTINE FUNCTION: Get addressability to msgs through SYSLOADMSG */
288/* Parse the command line by calling SYSPARSE */
289/* Allocate the data buffer to be used for copy */
290/* Make a fully qualified source path */
291/* Append current directory string */
292/* Create a list of files to be replaced */
293/* Read and write files */
294/* De-allocate data buffer */
295/* Print messages by calling SYSDISPMSG */
296/* */
297/* INPUT: Command line arguments */
298/* */
299/* EXIT-NORMAL: Information message displayed. */
300/* */
301/* EXIT-ERROR: Error message displayed, appendx restored, */
302/* errorlevel set. */
303/* */
304/* EXTERNAL ROUTINES: SYSLOADMSG */
305/* SYSDISPMSG */
306/* SYSPARSE */
307/* crit_err_handler */
308/* ctl_brk_handler */
309/* */
310/* INTERNAL ROUTINES: check_appendx dta_restore */
311/* check_appendx_install dta_save */
312/* dallocate dwrite */
313/* dchmod findfile */
314/* dclose get_ext_attr */
315/* dcompare getbyte */
316/* dcreate getdword */
317/* ddelete getword */
318/* dexit load_msg */
319/* dfree parser_prep */
320/* display_exit putbyte */
321/* display_msg putdword */
322/* doadd putword */
323/* docopy restore */
324/* dodir same */
325/* dopen set_appendx */
326/* dread setup_crit_err */
327/* dsearchf setup_ctl_brk */
328/* dsearchn */
329/* */
330/**************************************************************************/
331
332void main(argc, argv) /* ;AC000; */
333int argc ;
334char *argv[] ;
335{
336 void display_exit() ; /* ;AN000; forward declaration */
337 void display_msg() ; /* ;AN000; forward declaration */
338 void dta_restore() ; /* ;AN000; forward declaration */
339 void dta_save() ; /* ;AN000; forward declaration */
340 void load_msg() ; /* ;AN000; forward declaration */
341 void parser_prep() ; /* ;AN000; forward declaration */
342 void putbyte() ; /* ;AC000; forward declaration */
343 void putdword() ; /* ;AC000; forward declaration */
344 void putword() ; /* ;AC000; forward declaration */
345 void restore() ; /* ;AN000; forward declaration */
346 void set_appendx() ; /* ;AN000; forward declaration */
347 void setup_crit_err() ; /* ;AN000; forward declaration */
348 void setup_ctl_brk() ; /* ;AN000; forward declaration */
349
350 char *com_strchr() ; /* ;AN000; To search for DBCS "\\" */
351 char getbyte() ; /* ;AC000; forward declaration */
352
353 int same() ; /* ;AN000; forward declaration */
354
355 unsigned char *com_strrchr() ; /* ;AN000; To search for DBCS "\\" */
356
357 unsigned check_appendx() ; /* ;AN000; forward declaration */
358 unsigned check_appendx_install() ; /* ;AN000; forward declaration */
359 unsigned dallocate() ; /* ;AN000; forward declaration */
360 unsigned dchmod() ; /* ;AN000; forward declaration */
361 unsigned dclose() ; /* ;AN000; forward declaration */
362 unsigned dcompare() ; /* ;AN000; forward declaration */
363 unsigned dcreate() ; /* ;AN000; forward declaration */
364 unsigned ddelete() ; /* ;AN000; forward declaration */
365 unsigned dexit() ; /* ;AN000; forward declaration */
366 unsigned dfree() ; /* ;AN000; forward declaration */
367 unsigned doadd() ; /* ;AN000; forward declaration */
368 unsigned docopy() ; /* ;AN000; forward declaration */
369 unsigned dodir() ; /* ;AN000; forward declaration */
370 unsigned dopen() ; /* ;AN000; forward declaration */
371 unsigned dread() ; /* ;AN000; forward declaration */
372 unsigned dsearchf() ; /* ;AN000; forward declaration */
373 unsigned dsearchn() ; /* ;AN000; forward declaration */
374 unsigned dwrite() ; /* ;AN000; forward declaration */
375 unsigned findfile() ; /* ;AN000; forward declaration */
376 unsigned get_ext_attr() ; /* ;AN000; forward declaration */
377 unsigned getword() ; /* ;AC000; forward declaration */
378
379 long getdword() ; /* ;AC000; forward declaration */
380
381 struct filedata files[500] ; /* ;AC000; 256 is true limit, but */
382 /* 500 to accomodate segment wrap */
383 char save[MAXMINUS1] ;
384 char switch_buffer[3] ; /* ;AN000; Gets switch from parser */
385
386 char far * fptr ; /* ;AN000;P Pts to parser's buf for flspc */
387
388 int backslash_char = FALSE ; /* ;AN000; DBCS flag */
389 int fchar = 0 ; /* ;AN000;P Index into p_sfilespec */
390 int first_time_thru_loop = TRUE ; /* ;AN000; Flag - bypass code if > 256 files */
391 int i ;
392 int index ; /* ;AN000;P Forming string for parser */
393 int more_to_parse = TRUE ; /* ;AN000;P While parsing cmdline */
394 int need_to_reset_filecount = FALSE ; /* ;AN000; Flag - get to 0 element of array */
395 int search_more_files = TRUE ; /* ;AN000; Flag to loop > 256 files */
396
397 unsigned filecount = 0 ;
398 unsigned have_source = FALSE ; /* Flag */
399 unsigned have_target = FALSE ; /* Flag */
400 unsigned status ; /* Mostly used for carry flag */
401
402/************************ BEGIN ***********************************************/
403
404 load_msg() ; /* ;AN000;M Point to msgs & chk DOS ver */
405 for (index = 1; index <= argc; index++) /* ;AN000;P Form string for parser */
406 { /* ;AN000;P */
407 strcat(source,argv[index]) ; /* ;AN000;P Add the argument */
408 strcat(source," ") ; /* ;AN000;P Separate with a space */
409 } /* ;AN000;P */
410 parser_prep(source) ; /* ;AN000;P Initialization for the parser */
411
412 while (more_to_parse) /* ;AN000;P Test the parse loop flag */
413 { /* ;AN000;P */
414 index = 0 ; /* ;AN006; Init array index */
415 parse(&inregs,&outregs) ; /* ;AN000;P Call the parser */
416 if (outregs.x.ax == P_No_Error) /* ;AN000;P If no error */
417 if ((outregs.x.dx == (unsigned short)&rslt1) && /* ;AN000;P if result is filespec */
418 !(have_source)) /* ;AN000;P & we don't have the source */
419 { /* ;AN000;P */
420 for (fptr = rslt1.fp_result_buff; (char)*fptr != NULL; fptr++) /* ;AN000;P get the filespec from parser */
421 { /* ;AN000;P */
422 p_sfilespec[fchar] = (char)*fptr ; /* ;AN000;P get the character */
423 fchar++ ; /* ;AN000;P Move the char ptr */
424 } /* ;AN000;P */
425 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
426 have_source = TRUE ; /* ;AN000;P Set the flag */
427 fchar = 0 ; /* ;AN000;P Reset char ptr */
428 } /* ;AN000;P */
429 else /* ;AN000;P */
430 if ((outregs.x.dx == (unsigned short)&rslt1) && /* ;AN000;P if result is filespec */
431 (have_source)) /* ;AN000;P & we do have the source */
432 { /* ;AN000;P */
433 for (fptr = rslt1.fp_result_buff; (char)*fptr != NULL; fptr++) /* ;AN000;P get the filespec from parser */
434 { /* ;AN000;P */
435 p_path[fchar] = (char)*fptr ; /* ;AN000;P get the character */
436 fchar++ ; /* ;AN000;P Move the char ptr */
437 } /* ;AN000;P */
438 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
439 have_target = TRUE ; /* ;AN000;P Set the flag */
440 } /* ;AN000;P */
441 else /* ;AN000;P */
442 { /* ;AN000;P */
443 for (inregs.x.si;inregs.x.si<outregs.x.si;inregs.x.si++) /* ;AN006; Copy whatever */
444 { /* ;AN006; parser just parsed */
445 cmdln_switch[index] = *(char *)inregs.x.si ; /* ;AN006; */
446 index++ ; /* ;AN006; */
447 } /* ;AN006; */
448 strcpy(switch_buffer,rslt2.P_SYNONYM_Ptr) ; /* ;AN000;P Else copy switch into buf */
449 switch (switch_buffer[1]) /* ;AN000;P Verify which switch */
450 { /* ;AN000;P */
451 case 'A' : if (!add) /* ;AN000;P /A switch */
452 add = TRUE ; /* ;AN000;P */
453 else /* ;AN000;P */
454 display_exit(MSG_BADSWTCH,cmdln_switch,ERRLEVEL11) ;/* ;ANOO5;P It's a dup switch */
455 break ; /* ;AN000;P */
456 case 'P' : if (!prompt) /* ;AN000;P /P switch */
457 prompt = TRUE ; /* ;AN000;P */
458 else /* ;AN000;P */
459 display_exit(MSG_BADSWTCH,cmdln_switch,ERRLEVEL11) ;/* ;ANOO5;P It's a dup switch */
460 break ; /* ;AN000;P */
461 case 'R' : if (!readonly) /* ;AN000;P /R switch */
462 readonly = TRUE ; /* ;AN000;P */
463 else /* ;AN000;P */
464 display_exit(MSG_BADSWTCH,cmdln_switch,ERRLEVEL11) ;/* ;ANOO5;P It's a dup switch */
465 break ; /* ;AN000;P */
466 case 'S' : if (!descending) /* ;AN000;P /S switch */
467 descending = TRUE ; /* ;AN000;P */
468 else /* ;AN000;P */
469 display_exit(MSG_BADSWTCH,cmdln_switch,ERRLEVEL11) ;/* ;ANOO5;P It's a dup switch */
470 break ; /* ;AN000;P */
471 case 'U' : if (!update) /* ;AN000;P /U switch */
472 update = TRUE ; /* ;AN000;P */
473 else /* ;AN000;P */
474 display_exit(MSG_BADSWTCH,cmdln_switch,ERRLEVEL11) ;/* ;ANOO5;P It's a dup switch */
475 break ; /* ;AN000;P */
476 case 'W' : if (!wait) /* ;AN000;P /W switch */
477 wait = TRUE ; /* ;AN000;P */
478 else /* ;AN000;P */
479 display_exit(MSG_BADSWTCH,cmdln_switch,ERRLEVEL11) ;/* ;ANOO5;P It's a dup switch */
480 break ; /* ;AN000;P */
481 default : display_exit(MSG_BADSWTCH,cmdln_switch,ERRLEVEL11) ; /* ;AN006; */
482 break ; /* ;AN000;P */
483 } /* ;AN000;P */
484 } /* ;AN000;P */
485 else /* ;AN000;P */
486 if (outregs.x.ax != P_RC_EOL) /* ;AN000;P Is the parser */
487 { /* ;AN006; */
488 for (inregs.x.si ; inregs.x.si < outregs.x.si ; inregs.x.si++) /* ;AN006; Copy whatever */
489 { /* ;AN006; parser just parsed */
490 cmdln_invalid[index] = *(char *)inregs.x.si ; /* ;AN006; */
491 index++ ; /* ;AN006; */
492 } /* ;AN006; */
493 switch (outregs.x.ax) /* ;AN000;P returning an error? */
494 { /* ;AN000;P */
495 case P_Too_Many : display_exit(MSG_XTRAPARM,cmdln_invalid,ERRLEVEL11) ;/* ;AN005;P Too many parms */
496 break ; /* ;AN000;P More_to_parse = FALSE */
497 case P_Syntax : display_exit(MSG_BADPARM,cmdln_invalid,ERRLEVEL11) ;/* ;AN000;P Bad syntax */
498 break ; /* ;AN000;P More_to_parse = FALSE */
499 case P_Not_In_SW : display_exit(MSG_BADSWTCH,cmdln_invalid,ERRLEVEL11) ;/* ;AN005;P Invalid switch */
500 break ; /* ;AN000;P More_to_parse = FALSE */
501 case P_Op_Missing : display_msg(MSG_NOSOURCE) ; /* ;AN000;P Source required */
502 dexit(ERRLEVEL11) ; /* ;AN000;P */
503 break ; /* ;AN000;P More_to_parse = FALSE */
504 } /* ;AN000;P */
505 }
506 else /* ;AN000;P */
507 more_to_parse = FALSE ; /* ;AN000;P End of the cmdline */
508 inregs.x.cx = outregs.x.cx ; /* ;AN000;P Move the count */
509 inregs.x.si = outregs.x.si ; /* ;AN000;P Move the pointer */
510 } /* ;AN000;P */
511
512 /* Verify the correctness of the parameters */
513
514 if ((add && descending) || (add && update)) /* ;AC000;P A+S or A+U */
515 {
516 display_msg(MSG_INCOMPAT) ; /* ;AN000;P Incompatible switches */
517 dexit(ERRLEVEL11) ; /* ;AC000; */
518 }
519
520 /* Allocate the data buffer to be used during the copy operations */
521
522 length = 0x1000 ;
523 status = dallocate(length) ; /* Allocate buffer */
524 if (status == INSUFFMEM) /* Not enough mem? */
525 { /* then alloc what's available */
526 length = outregs.x.bx ; /* ;AC000; */
527 status = dallocate(length) ;
528 }
529
530 if (status != 0) /* If can't alloc at all */
531 { /* something's wrong */
532 display_msg(MSG_NOMEM) ; /* ;AC000; no space for copies */
533 dexit(ERRLEVEL8) ; /* ;AC000; */
534 }
535
536 segment = outregs.x.ax ; /* ;AC000; */
537 length = (length << 4) ; /* Convert to bytes */
538 if (length == 0) length = 0xffff ;
539
540 /* If the wait switch was on the command line, wait to continue */
541
542 if (wait)
543 {
544 display_msg(MSG_START) ; /* ;AC000; Press any key... */
545 inregs.x.ax = 0x0C08 ; /* ;AC000; */
546 intdos(&inregs,&outregs) ; /* ;AC000; */
547 status = (outregs.x.cflag & CARRY) ; /* ;AC000; */
548 if ( (status == NOERROR) && ((outregs.x.ax & 0x00ff) == 0) ) /* ;AC000; */
549 {
550 inregs.x.ax = 0x0100 ; /* ;AC000; */
551 intdos(&inregs,&outregs) ; /* ;AC000; */
552 status = (outregs.x.cflag & CARRY) ; /* ;AC000; */
553 }
554 }
555
556 /* Make a fully qualified source path */
557
558 strcpy(source,p_sfilespec) ; /* ;AN000;P Copy filespec recvd from parser */
559 strcpy(save,source) ;
560 strcpy(errfname,source) ;
561 if (source[1] != ':') /* If no drive letter entered */
562 {
563 inregs.x.ax = 0x1900 ; /* :AC000; Get current drive */
564 intdos(&inregs,&outregs) ; /* ;AC000; Int 21h */
565 if (status == NOERROR) /* If no error */
566 { /* Insert current drive letter */
567 source[0] = 'A' + (outregs.x.ax & 0xff) ; /* ;AC000; */
568 source[1] = ':' ;
569 source[2] = NULL ;
570 strcat(source,save) ;
571 }
572 }
573
574 /* Append current directory string */
575
576 strcpy(errfname,source) ;
577 if (source[2] != '\\') /* If not path from root */
578 {
579 strcpy(save,&source[2]) ;
580 strcpy(&source[3],save) ;
581 source[2] = '\\' ;
582 inregs.x.ax = 0x4700 ; /* ;AC000; Get current directory */
583 inregs.x.si = (unsigned)(&source[3]) ; /* ;AC000; */
584 inregs.x.dx = source[0] - 'A' + 1 ; /* ;AC000; */
585 intdos(&inregs,&outregs) ; /* ;AC000; */
586 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
587 status = outregs.x.ax ; /* ;AC000; get returned error */
588 else /* ;AC000; else */
589 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
590 if (status == NOERROR) /* If we got it, add it to user entered path */
591 {
592 if ((com_strrchr(source,'\\')) == NULL) /* ;AC000; DBCS function */
593 strcat(source,"\\") ;
594 else
595 if ((char *)(com_strrchr(source,'\\')) != &source[strlen(source)-1]) /* ;AN000; DBCS function */
596 strcat(source,"\\") ; /* ;AN000; */
597 strcat(source,save) ;
598 }
599 }
600
601 status = check_appendx_install() ; /* ;AN000;A Check append/x install */
602 if (status != NOERROR) /* ;AN000;A If append/x is installed */
603 { /* ;AN000;A */
604 append_installed = TRUE ; /* ;AN000;A */
605 x_status = check_appendx() ; /* ;AN000;A Get the status */
606 set_appendx(x_status & INACTIVE) ; /* ;AN000;A Set it inactive */
607 } /* ;AN000;A */
608 else /* ;AN000;A */
609 status = NOERROR ; /* ;AN000;A */
610
611 setup_ctl_brk() ; /* ;AN000; Ctl brk vec now pts to us */
612 setup_crit_err() ; /* ;AN000; Crit err vec now pts to us */
613
614 /* Create a list of the files that we might just replace */
615
616 strcpy(errfname,source) ;
617 status = dsearchf(source,&files[filecount],SATTRIB) ; /* Find the first file */
618
619 while (search_more_files) /* ;AN000; Search & replace/add */
620 {
621 while ( (filecount < MAXMINUS1) && (status == NOERROR) )
622 {
623 filecount++ ;
624 if (need_to_reset_filecount) /* ;AN000; Because of prev structure, */
625 { /* ;AN000; only way to get to 0 element */
626 filecount = 0 ; /* ;AN000; */
627 need_to_reset_filecount = FALSE ; /* ;AN000; */
628 } /* ;AN000; */
629 status = dsearchn(&files[filecount]) ;
630 }
631
632 if (status == NOMOREFILES)
633 {
634 status = NOERROR ;
635 search_more_files = FALSE ; /* ;AN000; Set for loop test */
636 if (filecount == 1) /* ;AN000; Find the true filecount */
637 only_one_valid_file = TRUE ; /* ;AN000; */
638 if (filecount > 1) /* ;AN000; Last file is no good */
639 filecount-- ; /* ;AN000; so back counter up */
640 }
641
642 if ((first_time_thru_loop) && (status == NOERROR) ) /* ;AN000; Bypassed if done already */
643 {
644 first_time_thru_loop = FALSE ; /* ;AN000; > 256 files to replace */
645 if (filecount == 0)
646 display_exit(MSG_NONFOUND,source,ERRLEVEL2) ; /* ;AC000; */
647
648 if (status == NOERROR)
649 {
650 /* fixup the source directory path so that it is useable */
651
652 for (i = strlen(source)-1; (i >= 0) && (!backslash_char) && (source[i] != ':'); i--) /* ;AC000; */
653 if ((source[i] == '\\') && (i != 0)) /* ;AN000; */
654 { /* ;AN000; */
655 dbcs_search[0] = source[i-1] ; /* ;AN000; Copy char to srch for DBCS */
656 dbcs_search[1] = source[i] ; /* ;AN000; Copy char to srch for DBCS */
657 if (com_strchr(dbcs_search,'\\') != NULL) /* ;AN000; If there is a pointer */
658 { /* ;AN000; then backslash exists */
659 backslash_char = TRUE ; /* ;AN000; */
660 i++ ; /* ;AN000; Bump up index */
661 } /* ;AN000; */
662 } /* ;AN000; */
663 else /* ;AN000; */
664 if ((source[i] == '\\') && (i == 0)) /* ;AN000; */
665 { /* ;AN000; */
666 backslash_char = TRUE ; /* ;AN000; */
667 i++ ; /* ;AN000; */
668 } /* ;AN000; */
669 if (i <= 0)
670 {
671 i = 0;
672 source[0] = NULL ;
673 }
674 dbcs_search[0] = source[i-1] ; /* ;AN000; Copy char to srch for DBCS */
675 dbcs_search[1] = source[i] ; /* ;AN000; Copy char to srch for DBCS */
676 if ( ((com_strchr(dbcs_search,'\\'))!= NULL) || (source[i] == ':') ) /* ;AN000; */
677 source[i+1] = NULL ; /* ;AN000; */
678
679 /* fixup the target path */
680
681 strcpy(target,p_path) ; /* ;AN000;P Copy path recvd from parser */
682 if (target[0] == NULL)
683 {
684 inregs.x.ax = 0x1900 ; /* ;AC000; Get current drive */
685 intdos(&inregs,&outregs) ; /* ;AC000; */
686 if (status == NOERROR)
687 {
688 target[0] = 'A' + (outregs.x.ax & 0xff) ; /* ;AC000; */
689 target[1] = ':' ;
690 target[2] = NULL ;
691 }
692 }
693
694 strcpy(errfname,target) ;
695 if ( (strlen(target) == 2) && (target[1] == ':') && (status == NOERROR) )
696 {
697 target[2] = '\\' ;
698 inregs.x.ax = 0x4700 ; /* ;AC000; Get current dir */
699 inregs.x.si = (unsigned)(&target[3]) ; /* ;AC000; */
700 inregs.x.dx = target[0] - 'A' + 1 ; /* ;AC000; */
701 intdos(&inregs,&outregs) ; /* ;AC000; */
702 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
703 status = outregs.x.ax ; /* ;AC000; get returned error */
704 else /* ;AC000; else */
705 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
706 }
707
708 strcpy(save,target) ;
709 strcpy(errfname,target) ;
710 if (target[1] != ':')
711 {
712 inregs.x.ax = 0x1900 ; /* ;AC000; Get current drive */
713 intdos(&inregs,&outregs) ; /* ;AC000; */
714 if (status == NOERROR)
715 {
716 target[0] = 'A' + (outregs.x.ax & 0xff) ; /* ;AC000; */
717 target[1] = ':' ;
718 target[2] = NULL ;
719 strcat(target,save) ;
720 }
721 }
722
723 strcpy(errfname,target) ;
724 if (target[2] != '\\') /* ;AC000; */
725 {
726 strcpy(save,&target[2]) ;
727 strcpy(&target[3],save) ; /* ;AN004; */
728 target[2] = '\\' ;
729 inregs.x.ax = 0x4700 ; /* ;AC000; Get current directory */
730 inregs.x.si = (unsigned)(&target[3]) ; /* ;AC000; */
731 inregs.x.dx = target[0] - 'A' + 1 ; /* ;AC000; */
732 intdos(&inregs,&outregs) ; /* ;AC000; */
733 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
734 status = outregs.x.ax ; /* ;AC000; get returned error */
735 else /* ;AC000; else */
736 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
737 if (status == NOERROR)
738 { /* ;AC000; */
739 if ((com_strrchr(target,'\\')) == NULL) /* ;AC004; DBCS func, if no backslash */
740 strcat(target,"\\") ; /* ;AC000; then add backslash */
741 else /* ;AC000; */
742 if ((char *)(com_strrchr(target,'\\')) != &target[strlen(target)-1]) /* ;AN000; If bkslsh not last char */
743 strcat(target,"\\") ; /* ;AN000; then add backslash */
744 if (save[0] != '.') /* ;AN004; If tgt is not cur dir */
745 strcat(target,save) ; /* ;AN004; then append subdir to path */
746 else /* ;AN004; */
747 if (save[1] == '.') /* ;AN004; If tgt is parent dir */
748 { /* ;AN004; */
749 target[strlen(target)-1] = NULL ; /* ;AN004; then delete end backslash */
750 *((unsigned char *)com_strrchr(target,'\\')+1) = NULL ; /* ;AN004; del curdir name from path */
751 } /* ;AN004; */
752 } /* ;AN004; */
753 }
754
755 strcpy(errfname,target) ;
756 dbcs_search[0] = target[strlen(target)-2] ; /* ;AN000; Copy char to srch for DBCS */
757 dbcs_search[1] = target[strlen(target)-1] ; /* ;AN000; Copy char to srch for DBCS */
758 if ( ((com_strchr(dbcs_search,'\\')) != &dbcs_search[1]) && /* ;AN004; DBCS function */
759 (status == NOERROR) ) /* ;AC000; */
760 strcat(target,"\\") ;
761 }
762 }
763
764 if ( (status == NOERROR) && (!add) )
765 status = dodir(source,target,files,filecount) ;
766
767 if ( (status == NOERROR) && (add) )
768 status = doadd(source,target,files,filecount) ;
769
770 filecount = 0 ; /* ;AN000; Reset for next loop */
771 need_to_reset_filecount = TRUE ; /* ;AN000; Get to 0 element */
772
773 if (status != NOERROR) /* ;AN000; If there was an error */
774 search_more_files = FALSE ; /* ;AN000; somewhere, drop out */
775 }
776
777 dfree(segment) ;
778
779 switch(status)
780 {
781 case 0 : break ;
782 case 2 : display_msg(MSG_ERRFNF,errfname) ; /* ;AC000; file not found */
783 break ;
784 case 3 : display_msg(MSG_ERRPNF,errfname) ; /* ;AC000; path not found */
785 break ;
786 case 5 : display_msg(MSG_ERRACCD,errfname) ; /* ;AC000; access denied */
787 break ;
788 case 15 : display_msg(MSG_ERRDRV,errfname) ; /* ;AC000; invalid drive */
789 break ;
790 default : dexit(ERRLEVEL1) ; /* ;AC000; */
791 break ;
792 }
793
794 if (add)
795 if (counted == 0)
796 display_msg(MSG_NONEADDE) ; /* ;AC000; no files added */
797 else
798 display_msg(MSG_SOMEADDE,(char *)&counted) ; /* ;AC000; %1 files added */
799 else
800 if (counted == 0)
801 display_msg(MSG_NONEREPL) ; /* ;AC000; no files replaced */
802 else
803 display_msg(MSG_SOMEREPL,(char *)&counted) ; /* ;AC000; %1 files replaced */
804
805 restore() ; /* ;AN000; Cleanup before exit */
806 dexit(status) ;
807}
808/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
809
810unsigned dodir(source,target,files,filecount) /* ;AC000; */
811char *source ;
812char *target ;
813struct filedata *files ;
814unsigned filecount ;
815{
816 char dta_area[128] ;
817 char subdirectory[MAX] ;
818 int index ;
819 unsigned status ;
820 struct filedata file ;
821
822 dta_save(dta_area,128) ;
823 strcpy(subdirectory,target) ;
824 strcat(subdirectory,"*.*") ;
825 status = dsearchf(subdirectory,&file,TATTRIB) ;
826 while (status == NOERROR)
827 {
828 if ( ((file.attribute & SUBDIR) != 0) &&
829 (descending) && (file.name[0] != '.') )
830 {
831 strcpy(subdirectory,target) ;
832 strcat(subdirectory,file.name) ;
833 strcat(subdirectory,"\\") ;
834 status = dodir(source,subdirectory,files,filecount) ; /* Call self again */
835 strcpy(subdirectory,target) ;
836 strcat(subdirectory,"*.*") ;
837 }
838 else
839 {
840 index = findfile(files,&file,filecount) ; /* if there is a file and it */
841 if ( (index >= 0) && ((file.attribute & SUBDIR) == 0) ) /* is not a subdirectory name */
842 if (update) /* ;AN000;U If updt sw set,ck dt & tm */
843 if ((files[index].date < file.date) || /* ;AN000;U If src.date < tgt.date or */
844 ((files[index].date == file.date) && /* ;AN000;U Src.dt == tgt.dt and */
845 (files[index].time <= file.time))) ; /* ;AN000;U src.tm <= tgt.tm - do nthng */
846 else /* ;AN000;U Else src is newer - do cpy */
847 status = docopy(source,target,&file,files[index].time,files[index].date) ; /* ;AN000;U */
848 else /* ;AN000;U Update switch was not set */
849 status = docopy(source,target,&file,files[index].time,files[index].date) ;
850 }
851 if (status == NOERROR)
852 status = dsearchn(&file) ;
853 }
854
855 dta_restore(dta_area,128) ;
856 if (status == NOMOREFILES)
857 status = NOERROR ;
858 return(status) ;
859}
860/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
861
862unsigned doadd(source,target,files,filecount) /* ;AC000; */
863char *source ;
864char *target ;
865struct filedata *files ;
866unsigned filecount ;
867{
868 char path[MAX] ;
869 int index ;
870 unsigned status = NOERROR ;
871 struct filedata *f ;
872 struct filedata dummy ;
873
874 if (only_one_valid_file) /* ;AN003; Eliminate extra loop */
875 filecount-- ; /* ;AN003; */
876
877 for (index = 0; (index <= filecount) && (status == NOERROR) ; index++) /* ;AC000; */
878 {
879 f = files+index ;
880 strcpy(path,target) ;
881 strcat(path,f->name) ;
882 status = dsearchf(path,&dummy,TATTRIB) ;
883 if (((status == NOMOREFILES) && (f->name[0] != NULL)) || /* ;AC000; Check for null filename */
884 ((index==filecount)&&(f->name[0]!=NULL)&&(status==NOMOREFILES))) /* ;AN004;006; Process single file */
885 status = docopy(source,target,f,f->time,f->date) ;
886 else /* ;AN000; */
887 status = NOERROR ; /* ;AN000; Skip this null file */
888 }
889 return(status) ;
890}
891/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
892
893unsigned findfile(files,file,filecount) /* ;AC000; */
894struct filedata *files ;
895struct filedata *file ;
896unsigned filecount ;
897{
898 int i ;
899
900 if (only_one_valid_file) /* ;AN003; Eliminate extra loop */
901 filecount-- ; /* ;AN003 */
902
903 for (i = 0; i <= filecount; i++) /* ;AC000; */
904 {
905 if (same(files->name,file->name)) /* ;AC000; */
906 return(i) ;
907 files++ ;
908 }
909 return(ERRLEVELNEG1) ; /* ;AC000; */
910}
911/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
912
913unsigned docopy(sdir,tdir,file,time,date) /* ;AC000; */
914char *sdir ;
915char *tdir ;
916struct filedata *file ;
917unsigned time ;
918unsigned date ;
919{
920 char *s,*t ;
921 char source[MAX] ;
922 char target[MAX] ;
923 unsigned source_handle ;
924 unsigned status ;
925 unsigned target_handle ;
926 unsigned try ;
927
928 /* create the path names and check for equivalence */
929
930 strcpy(source,sdir) ;
931 strcat(source,file->name) ;
932 strcpy(target,tdir) ;
933 strcat(target,file->name) ;
934
935 status = strcmp(source,target) ;
936 if (status == NOERROR)
937 {
938 display_msg(MSG_WARNSAME,source) ; /* ;AC000; File cannot be copied... */
939 return(status) ;
940 }
941
942 /* We can replace! if prompting, check to see */
943 /* if this file is to be replaced or not */
944
945 while ( (prompt) && (not_valid_input) ) /* ;AN000;M Flag set in dcompare */
946 {
947 if (add)
948 display_msg(MSG_QADD,target) ; /* ;AC000; Add? filename */
949 else
950 display_msg(MSG_QREPLACE,target) ; /* ;AC000; Replace? filename */
951 status = dcompare() ; /* ;AN000; */
952 }
953 not_valid_input = TRUE ; /* ;AN000; Prepare for next file in loop */
954 if (status == 2)
955 return(ERRLEVEL0) ; /* ;AC000; */
956
957 /* indicate what we are replacing */
958
959 if (add)
960 display_msg(MSG_ADDING,target) ; /* ;AC000; Adding filename */
961 else
962 display_msg(MSG_REPLACIN,target) ; /* ;AC000; Replacing filename */
963
964 /* open the input file */
965
966 status = dopen(source) ; /* ;AC000; Extended open */
967 if (status != 0)
968 {
969 strcpy(errfname,source) ;
970 return(status) ;
971 }
972
973 source_handle = outregs.x.ax ; /* ;AN000; */
974
975 get_ext_attr(source_handle,0) ; /* ;AC000;EA Get the source's extd attributes */
976 if (outregs.x.cx) /* ;AN000;EA If size is retd, attrs exist */
977 { /* ;AN000;EA */
978 ea_flag = TRUE ; /* ;AN000;EA */
979 eaparm_list.ea_list_offset = 0 ; /* ;AN000;EA Use the read/write buffer */
980 eaparm_list.ea_list_segment = segment ; /* ;AN000;EA Use the read/write buffer */
981 get_ext_attr(source_handle,outregs.x.cx) ; /* ;AN000;EA Now get the extd attributes */
982 } /* ;AN000;EA */
983
984 /* create the output file */
985 /* if we are to overwrite READONLY files, set the mode so we can */
986
987 if (!add)
988 {
989 inregs.x.cx = 0 ; /* ;AC000; */
990 status = dchmod(target,0) ;
991 if (status != 0)
992 {
993 strcpy(errfname,target) ;
994 dclose(source_handle) ;
995 return(status) ;
996 }
997 file->attribute = outregs.x.cx ; /* ;AC000; */
998 if (readonly)
999 outregs.x.cx = outregs.x.cx & 0xfffe ; /* ;AC000; */
1000 if (file->attribute != outregs.x.cx) /* ;AC000; */
1001 {
1002 status = dchmod(target,1) ;
1003 if (status != 0)
1004 {
1005 strcpy(errfname,target) ;
1006 dclose(source_handle) ;
1007 return(status) ;
1008 }
1009 }
1010 }
1011
1012 if (ea_flag) /* ;AN000;EA If extd attrs exist */
1013 status = dcreate(target,&eaparm_list) ; /* ;AN000;EA open trgt w/extd attrs */
1014 else /* ;AN000;EA */
1015 status = dcreate(target,-1) ; /* ;AC000;EA Create the target file */
1016
1017 strcpy(filename,target) ; /* Note that existing file*/
1018 if (status != 0) /* will be deleted */
1019 {
1020 strcpy(errfname,target) ;
1021 dclose(source_handle) ;
1022 return(status) ;
1023 }
1024
1025 target_handle = outregs.x.ax ; /* ;AC000; */
1026
1027 /* now, copy all of the data from the in file to the out file */
1028
1029 try = length ;
1030 while ( (try == length) && (status == NOERROR) )
1031 {
1032 status = dread(source_handle,segment,0,try) ;
1033 if (status == NOERROR)
1034 {
1035 try = outregs.x.ax ; /* ;AC000; */
1036 status = dwrite(target_handle,segment,0,try) ;
1037 if (disk_full) /* RW If the target disk fills up */
1038 {
1039 strcpy(errline,filename) ; /* ;AC000; save target filename */
1040 dclose(target_handle) ; /* RW Close target file */
1041 ddelete(filename) ; /* RW Then delete target file */
1042 display_msg(MSG_ERRDSKF,errline) ; /* ;AC000; Error disk full */
1043 status = TARGETFULL ; /* RW Tell me too */
1044 }
1045 }
1046 }
1047
1048 if (status == NOERROR)
1049 {
1050 inregs.x.ax = 0x5701 ; /* ;AC000; Set files date and time */
1051 inregs.x.bx = target_handle ; /* ;AC000; */
1052 inregs.x.cx = time ; /* ;AC000; */
1053 inregs.x.dx = date ; /* ;AC000; */
1054 intdos(&inregs,&outregs) ; /* ;AC000; */
1055 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1056 status = outregs.x.ax ; /* ;AC000; get returned error */
1057 else /* ;AC000; else */
1058 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1059 }
1060
1061 if (status == NOERROR)
1062 {
1063 status = dclose(target_handle) ; /* Close target file */
1064 if (status != NOERROR)
1065 strcpy(errfname,target) ;
1066 else
1067 {
1068 if ((file->attribute & ARCHIVE) != ARCHIVE)
1069 file->attribute += ARCHIVE ; /* ;AN001; Set archive bit ON */
1070 inregs.x.cx = file->attribute ; /* ;AC000; */
1071 if (!add)
1072 status = dchmod(target,1) ; /* Reset attributes on target */
1073 if (status != NOERROR)
1074 strcpy(errfname,target) ;
1075 counted++ ; /* Increment num files processed */
1076 }
1077 }
1078
1079 if (disk_full) /* RW If the target disk got full */
1080 {
1081 status = NOERROR ; /* RW Then we've done all we can do */
1082 disk_full = FALSE ; /* RW So forget about it */
1083 target_full = TRUE ; /* ;AN000; */
1084 }
1085
1086 dclose(source_handle) ;
1087 return(status) ;
1088}
1089/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1090
1091int same(s,t) /* ;AC000; */
1092char *s ;
1093char *t ;
1094{
1095 while ( (*s != NULL) && (*t != NULL) ) /* ;AC000; */
1096 { /* ;AC000; */
1097 if ( *s != *t ) /* ;AC000; */
1098 return(FALSE) ; /* ;AN000;Removed "casemap" */
1099 s++ ; /* ;AC000; */
1100 t++ ; /* ;AC000; */
1101 } /* ;AC000; */
1102 if ( *s != *t )
1103 return(FALSE) ; /* ;AN000;Removed "casemap" */
1104 return(TRUE) ;
1105}
1106/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1107
1108unsigned dallocate(s) /* ;AC000; */
1109unsigned s ;
1110{
1111 unsigned status ;
1112
1113 inregs.x.bx = s ; /* ;AC000; Num of paragraphs requested */
1114 inregs.x.ax = 0x4800 ; /* ;AC000; Int21 - allocate memory */
1115 intdos(&inregs,&outregs) ; /* ;AC000; */
1116 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1117 status = outregs.x.ax ; /* ;AC000; get returned error */
1118 else /* ;AC000; else */
1119 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1120 return(status) ;
1121}
1122/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1123
1124unsigned dfree(s) /* ;AC000; */
1125unsigned s ;
1126{
1127 unsigned status ;
1128
1129 segregs.es = s ; /* ;AC000; */
1130 inregs.x.ax = 0x4900 ; /* ;AC000; */
1131 intdosx(&inregs,&outregs,&segregs) ; /* ;AC000; */
1132 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1133 status = outregs.x.ax ; /* ;AC000; get returned error */
1134 else /* ;AC000; else */
1135 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1136 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1137 return(status) ;
1138}
1139/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1140
1141unsigned dcreate(n,parm_value) /* ;AC000; */
1142char *n ;
1143unsigned parm_value ;
1144{
1145 unsigned status ;
1146
1147 inregs.x.ax = 0x6c00 ; /* ;AC000;EA Extended Create */
1148 inregs.x.bx = 8321 ; /* ;AN000;EA Mode */
1149 inregs.x.cx = 0 ; /* ;AN000;EA Create attribute */
1150 inregs.x.dx = 0x12 ; /* ;AC002;EA Function flag */
1151 inregs.x.di = parm_value ; /* ;AN000;EA Parm list value */
1152 inregs.x.si = (unsigned)(n) ; /* ;AN000;EA Target file to create */
1153 intdos(&inregs,&outregs) ; /* ;AC000;EA Int 21 */
1154 if (outregs.x.cflag & CARRY) /* ;AC000;EA If the carry flag is set */
1155 status = outregs.x.ax ; /* ;AC000;EA get returned error */
1156 else /* ;AC000;EA else */
1157 status = (outregs.x.cflag & CARRY) ; /* ;AC000;EA set status to NOERROR */
1158 return(status) ;
1159}
1160/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1161
1162unsigned dopen(n) /* ;AC000; */
1163char *n ;
1164{
1165 unsigned status ;
1166
1167 inregs.x.ax = 0x6c00 ; /* ;AC000;EA Extended open */
1168 inregs.x.bx = 8320 ; /* ;AN000;EA Open mode (flags) */
1169 inregs.x.cx = 0 ; /* ;AN000;EA Create attr (ignore) */
1170 inregs.x.dx = 257 ; /* ;AN000;EA Function control (flags) */
1171 inregs.x.si = (unsigned)(n) ; /* ;AC000;EA File name to open */
1172 inregs.x.di = -1 ; /* ;AN000;EA Parm list (null) */
1173 intdos(&inregs,&outregs) ; /* ;AC000;EA Int 21 */
1174 if (outregs.x.cflag & CARRY) /* ;AC000;EA If the carry flag is set */
1175 status = outregs.x.ax ; /* ;AC000;EA get returned error */
1176 else /* ;AC000;EA else */
1177 status = (outregs.x.cflag & CARRY) ; /* ;AC000;EA set status to NOERROR */
1178 return(status) ;
1179}
1180/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1181
1182unsigned ddelete(n) /* ;AC000; */
1183char *n ; /* File to be deleted */
1184{
1185 unsigned status ;
1186
1187 inregs.x.ax = 0x4100 ; /* ;AC000; */
1188 inregs.x.dx = (unsigned)(n) ; /* ;AC000; */
1189 intdos(&inregs,&outregs) ; /* ;AC000; */
1190 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1191 status = outregs.x.ax ; /* ;AC000; get returned error */
1192 else /* ;AC000; else */
1193 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1194 return(status) ;
1195}
1196/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1197
1198unsigned dread(h,s,o,l) /* ;AC000; */
1199unsigned h ;
1200unsigned s ;
1201unsigned o ;
1202unsigned l ;
1203{
1204 unsigned status ;
1205
1206 inregs.x.ax = 0x3f00 ; /* ;AC000; Read from file or device */
1207 inregs.x.bx = h ; /* ;AC000; File handle */
1208 segregs.ds = s ; /* ;AC000; Buffer segment */
1209 inregs.x.dx = o ; /* ;AC000; Buffer offset */
1210 inregs.x.cx = l ; /* ;AC000; Num of bytes to be read */
1211 intdosx(&inregs,&outregs,&segregs) ; /* ;AC000; */
1212 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1213 status = outregs.x.ax ; /* ;AC000; get returned error */
1214 else /* ;AC000; else */
1215 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1216 return(status) ;
1217}
1218/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1219
1220unsigned dwrite(handle,segment,offset,length) /* ;AC000; */
1221unsigned handle ;
1222unsigned segment ;
1223unsigned offset ;
1224unsigned length ;
1225{
1226 unsigned status ;
1227 unsigned write_len ; /* Save area for num of bytes to write */
1228
1229 inregs.x.ax = 0x4000 ; /* ;AC000; Write to file or device */
1230 inregs.x.bx = handle ; /* ;AC000; */
1231 segregs.ds = segment ; /* ;AC000; */
1232 inregs.x.dx = offset ; /* ;AC000; */
1233 inregs.x.cx = length ; /* ;AC000; */
1234 write_len = length ; /* ;AC000; */
1235 intdosx(&inregs,&outregs,&segregs) ; /* ;AC000; */
1236 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1237 status = outregs.x.ax ; /* ;AC000; get returned error */
1238 else /* ;AC000; else */
1239 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1240 if (status == NOERROR) /* If there was not an error */
1241 if (write_len != outregs.x.ax) /* And we didn't write reqtd num bytes */
1242 disk_full = TRUE ; /* Then the disk is full. Ret error */
1243 return(status) ;
1244}
1245/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1246
1247unsigned dclose(h) /* ;AC000; */
1248unsigned h ;
1249{
1250 unsigned status ;
1251
1252 inregs.x.ax = 0x3e00 ; /* ;AC000; Close a file handle */
1253 inregs.x.bx = h ; /* ;AC000; File han ret by open/create */
1254 intdos(&inregs,&outregs) ; /* ;AC000; */
1255 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1256 status = outregs.x.ax ; /* ;AC000; get returned error */
1257 else /* ;AC000; else */
1258 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1259 return(status) ;
1260}
1261/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1262
1263unsigned dchmod(n,a) /* ;AC000; */
1264char *n ;
1265unsigned a ;
1266{
1267 unsigned status ;
1268
1269 inregs.x.ax = 0x4300 | (a & 0x00ff) ; /* ;AC000; Change file mode */
1270 inregs.x.dx = (unsigned)(n) ; /* ;AC000; Ptr to asciiz path name */
1271 intdos(&inregs,&outregs) ; /* ;AC000; */
1272 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1273 status = outregs.x.ax ; /* ;AC000; get returned error */
1274 else /* ;AC000; else */
1275 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1276 return(status) ;
1277}
1278/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1279
1280unsigned dsearchf(s,t,a) /* ;AC000; */
1281char *s ;
1282struct filedata *t ;
1283unsigned a ;
1284{
1285 unsigned i ;
1286 unsigned status ;
1287
1288 inregs.x.ax = 0x4e00 ; /* ;AC000; Find first matching file */
1289 inregs.x.cx = a ; /* ;AC000; Attrib used in search */
1290 inregs.x.dx = (unsigned)(s) ; /* ;AC000; Asciiz string ptr */
1291 intdos(&inregs,&outregs) ; /* ;AC000; */
1292 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1293 status = outregs.x.ax ; /* ;AC000; get returned error */
1294 else /* ;AC000; else */
1295 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1296 if (status == NOERROR)
1297 {
1298 t->attribute = getbyte(_psp,0x80+21) ;
1299 t->time = getword(_psp,0x80+22) ;
1300 t->date = getword(_psp,0x80+24) ;
1301 t->size = getdword(_psp,0x80+26) ;
1302 for (i = 0; i < 15; i++)
1303 t->name[i] = getbyte(_psp,0x80+30+i) ;
1304 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1305 }
1306 return(status) ;
1307}
1308/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1309
1310unsigned dsearchn(t) /* ;AC000; */
1311struct filedata *t ;
1312{
1313 unsigned i ;
1314 unsigned status ;
1315
1316 inregs.x.ax = 0x4f00 ; /* ;AC000; Find next matching file */
1317 intdos(&inregs,&outregs) ; /* ;AC000; DTA contains prev call info */
1318 if (outregs.x.cflag & CARRY) /* ;AC000; If the carry flag is set */
1319 status = outregs.x.ax ; /* ;AC000; get returned error */
1320 else /* ;AC000; else */
1321 status = (outregs.x.cflag & CARRY) ; /* ;AC000; set status to NOERROR */
1322 if (status == NOERROR)
1323 {
1324 t->attribute = getbyte(_psp,0x80+21) ;
1325 t->time = getword(_psp,0x80+22) ;
1326 t->date = getword(_psp,0x80+24) ;
1327 t->size = getdword(_psp,0x80+26) ;
1328 for (i = 0; i < 15; i++)
1329 t->name[i] = getbyte(_psp,0x80+30+i) ;
1330 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1331 }
1332 return(status) ;
1333}
1334/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1335
1336unsigned dexit(s) /* ;AC000; */
1337unsigned s ;
1338{
1339 if (target_full) /* ;AN000; If unable to copy any files */
1340 s = ERRLEVEL8 ; /* ;AN000; Insufficient memory */
1341 exit(s) ; /* ;AN000; terminate program */
1342 return ;
1343}
1344/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1345
1346void dta_save(t,l) /* ;AC000; */
1347char *t ;
1348unsigned l ;
1349{
1350 unsigned i ;
1351
1352 for (i = 0; i < l; i++)
1353 *(t+i) = getbyte(_psp,0x80+i) ;
1354 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1355 return ; /* ;AC000; */
1356}
1357/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1358
1359void dta_restore(t,l) /* ;AC000; */
1360char *t ;
1361unsigned l ;
1362{
1363 unsigned i ;
1364
1365 for (i = 0; i < l; i++)
1366 putbyte(_psp,0x80+i,*(t+i)) ;
1367 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1368 return ; /* ;AC000; */
1369}
1370/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1371
1372char getbyte(msegment,moffset) /* ;AN000; */
1373unsigned int msegment ; /* ;AN000; */
1374unsigned int moffset ; /* ;AN000; */
1375{ /* ;AN000; */
1376 char far * cPtr ; /* ;AN000; */
1377
1378 FP_SEG(cPtr) = msegment ; /* ;AN000; */
1379 FP_OFF(cPtr) = moffset ; /* ;AN000; */
1380 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1381 return(*cPtr) ; /* ;AN000; */
1382} /* ;AN000; */
1383/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1384
1385unsigned getword(msegment,moffset) /* ;AN000; */
1386unsigned int msegment ; /* ;AN000; */
1387unsigned int moffset ; /* ;AN000; */
1388{ /* ;AN000; */
1389 unsigned far * uPtr ; /* ;AN000; */
1390
1391 FP_SEG(uPtr) = msegment ; /* ;AN000; */
1392 FP_OFF(uPtr) = moffset ; /* ;AN000; */
1393 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1394 return(*uPtr) ; /* ;AN000; */
1395} /* ;AN000; */
1396/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1397
1398long getdword(msegment,moffset) /* ;AN000; */
1399unsigned int msegment ; /* ;AN000; */
1400unsigned int moffset ; /* ;AN000; */
1401{ /* ;AN000; */
1402 long far * lPtr ; /* ;AN000; */
1403
1404 FP_SEG(lPtr) = msegment ; /* ;AN000; */
1405 FP_OFF(lPtr) = moffset ; /* ;AN000; */
1406 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1407 return(*lPtr) ; /* ;AN000; */
1408} /* ;AN000; */
1409/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1410
1411void putbyte(msegment,moffset,value) /* ;AN000; */
1412unsigned int msegment ; /* ;AN000; */
1413unsigned int moffset ; /* ;AN000; */
1414char value ; /* ;AN000; */
1415{ /* ;AN000; */
1416 char far * cPtr ; /* ;AN000; */
1417
1418 FP_SEG(cPtr) = msegment ; /* ;AN000; */
1419 FP_OFF(cPtr) = moffset ; /* ;AN000; */
1420 *cPtr = value ; /* ;AN000; */
1421 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1422 return ; /* ;AN000; */
1423} /* ;AN000; */
1424/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1425
1426void putword(msegment,moffset,value) /* ;AN000; */
1427unsigned int msegment ; /* ;AN000; */
1428unsigned int moffset ; /* ;AN000; */
1429unsigned value ; /* ;AN000; */
1430{ /* ;AN000; */
1431 unsigned far * uPtr ; /* ;AN000; */
1432
1433 FP_SEG(uPtr) = msegment ; /* ;AN000; */
1434 FP_OFF(uPtr) = moffset ; /* ;AN000; */
1435 *uPtr = value ; /* ;AN000; */
1436 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1437 return ; /* ;AN000; */
1438} /* ;AN000; */
1439/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1440
1441void putdword(msegment,moffset,value) /* ;AN000; */
1442unsigned int msegment ; /* ;AN000; */
1443unsigned int moffset ; /* ;AN000; */
1444long value ; /* ;AN000; */
1445{ /* ;AN000; */
1446 long far * lPtr ; /* ;AN000; */
1447
1448 FP_SEG(lPtr) = msegment ; /* ;AN000; */
1449 FP_OFF(lPtr) = moffset ; /* ;AN000; */
1450 *lPtr = value ; /* ;AN000; */
1451 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1452 return ; /* ;AN000; */
1453} /* ;AN000; */
1454/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1455/**************************************************************************/
1456/* */
1457/* SUBROUTINE NAME: load_msg */
1458/* */
1459/* SUBROUTINE FUNCTION: Load the set of REPLACE Utility messages to */
1460/* become available for display_msg call. */
1461/* */
1462/* ERROR EXIT: Utility will be terminated by sysloadmsg if */
1463/* version check is incorrect. */
1464/* */
1465/* EXTERNAL REF: SYSLOADMSG */
1466/* */
1467/**************************************************************************/
1468
1469void load_msg() /* ;AN000;M */
1470{ /* ;AN000;M */
1471 sysloadmsg(&inregs,&outregs) ; /* ;AN000;M Load utility messages */
1472 if (outregs.x.cflag & CARRY) /* ;AN000;M */
1473 { /* ;AN000;M */
1474 sysdispmsg(&outregs,&outregs) ; /* ;AN000;M If load error, display err msg */
1475 dexit(ERRLEVEL1) ; /* ;AN000;M */
1476 } /* ;AN000;M */
1477 return ; /* ;AN000;M Return with no error */
1478} /* ;AN000;M */
1479/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1480/**************************************************************************/
1481/* */
1482/* SUBROUTINE NAME: dcompare */
1483/* */
1484/* SUBROUTINE FUNCTION: Check a Y/N response using an Int21 Get */
1485/* Extended Country information. */
1486/* */
1487/* INPUT: function (character to check) (global) */
1488/* */
1489/* OUTPUT: status (carry flag if set or response) */
1490/* */
1491/* NORMAL EXIT: AX=0=No (status = 2) */
1492/* AX=1=Yes (status = 1) */
1493/* */
1494/**************************************************************************/
1495
1496unsigned dcompare() /* ;AN000;EC */
1497{ /* ;AN000;EC */
1498 unsigned status ; /* ;AN000;EC Receives error cond or Y/N */
1499
1500 inregs.x.dx = outregs.x.ax ; /* ;AN000;EC Char rec'd by msg hndlr to be ckd */
1501 inregs.x.ax = 0x6523 ; /* ;AN000;EC 65=Get-Ext-Cty 23=Y/N chk */
1502 intdos(&inregs,&outregs) ; /* ;AN000;EC Int21 call */
1503 if ((outregs.x.cflag & CARRY) || /* ;AN000;EC If the carry flag is set */
1504 (outregs.x.ax > 1)) /* ;AN000;EC or invalid return code */
1505 not_valid_input = TRUE ; /* ;AN000;EC then input is not valid */
1506 else /* ;AN000;EC else */
1507 { /* ;AN000;EC */
1508 not_valid_input = FALSE ; /* ;AN000;EC input is valid */
1509 if (outregs.x.ax == 0) /* ;AC000;EC */
1510 status = 2 ; /* ;AN000;EC 2 = No */
1511 else /* ;AC000;EC */
1512 status = 1 ; /* ;AN000;EC 1 = Yes */
1513 } /* ;AN000;EC */
1514 return(status) ; /* ;AN000;EC */
1515} /* ;AN000;EC */
1516/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1517/**************************************************************************/
1518/* */
1519/* SUBROUTINE NAME: display_msg */
1520/* */
1521/* SUBROUTINE FUNCTION: The correct message called by main is displayed */
1522/* to standard out or standard error. */
1523/* */
1524/* INPUT: msg_num (message number to display) */
1525/* outline (string for replacement parm) */
1526/* */
1527/* OUTPUT: none */
1528/* */
1529/* NORMAL EXIT: The correct message called will be displayed to */
1530/* standard out or standard error. */
1531/* */
1532/* ERROR EXIT: Display error message corresponding to number */
1533/* returned in AX. */
1534/* */
1535/* EXTERNAL REF: SYSDISPMSG */
1536/* */
1537/**************************************************************************/
1538
1539void display_msg(msg_num,outline) /* ;AN000;M */
1540int msg_num ; /* ;AN000;M Message number #define'd */
1541char *outline ; /* ;AN000;M String for replacemnt parm */
1542{ /* ;AN000;M */
1543 unsigned status ; /* ;AN000;M Receives carry flag if set */
1544 unsigned char function ; /* ;AN000;M Y/N response or press key? */
1545 unsigned int message, /* ;AN000;M Message number to display */
1546 msg_class, /* ;AN000;M Which class of messages? */
1547 sub_cnt, /* ;AN000;M Number of substitutions? */
1548 handle ; /* ;AN000;M Display where? */
1549
1550 struct sublist /* ;AN000;M */
1551 { /* ;AN000;M */
1552 unsigned char size ; /* ;AN000;M Points to next sublist */
1553 unsigned char reserved ; /* ;AN000;M Required for syddispmsg */
1554 unsigned far *value ; /* ;AN000;M Data pointer */
1555 unsigned char id ; /* ;AN000;M Id of substitution parm (%1) */
1556 unsigned char flags ; /* ;AN000;M Format of data - (a0sstttt) */
1557 unsigned char max_width ; /* ;AN000;M Maximum field width */
1558 unsigned char min_width ; /* ;AN000;M Minimum field width */
1559 unsigned char pad_char ; /* ;AN000;M char to pad field */
1560 } sublist ; /* ;AN000;M */
1561
1562 switch (msg_num) /* ;AN000;M Which msg to display? */
1563 { /* ;AN000;M */
1564 case MSG_NOMEM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1565 message = 8 ; /* ;AN000;M Message number to display */
1566 msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1567 sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */
1568 handle = STDERR ; /* ;AN000;M Display where? */
1569 break ; /* ;AN000;M */
1570 case MSG_INCOMPAT : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1571 message = 11 ; /* ;AN000;M Message number to display */
1572 msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1573 sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */
1574 handle = STDERR ; /* ;AN000;M Display where? */
1575 break ; /* ;AN000;M */
1576 case MSG_NOSOURCE : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1577 message = 2 ; /* ;AN000;M Message number to display */
1578 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1579 sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */
1580 handle = STDERR ; /* ;AN000;M Display where? */
1581 break ; /* ;AN000;M */
1582 case MSG_NONEREPL : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1583 message = 3 ; /* ;AN000;M Message number to display */
1584 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1585 sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */
1586 handle = STDOUT ; /* ;AN000;M Display where? */
1587 break ; /* ;AN000;M */
1588 case MSG_NONEADDE : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1589 message = 4 ; /* ;AN000;M Message number to display */
1590 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1591 sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */
1592 handle = STDOUT ; /* ;AN000;M Display where? */
1593 break ; /* ;AN000;M */
1594 case MSG_START : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1595 message = 21 ; /* ;AN000;M Message number to display */
1596 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1597 sub_cnt = SUBCNT0 ; /* ;AN000;M Number of substitutions? */
1598 handle = STDERR ; /* ;AN000;M Display where? */
1599 break ; /* ;AN000;M */
1600 case MSG_ERRFNF : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1601 message = 2 ; /* ;AN000;M Message number to display */
1602 msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1603 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1604 handle = STDOUT ; /* ;AN000;M Display where? */
1605 break ; /* ;AN000;M */
1606 case MSG_ERRPNF : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1607 message = 3 ; /* ;AN000;M Message number to display */
1608 msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1609 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1610 handle = STDOUT ; /* ;AN000;M Display where? */
1611 break ; /* ;AN000;M */
1612 case MSG_ERRACCD : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1613 message = 5 ; /* ;AN000;M Message number to display */
1614 msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1615 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1616 handle = STDOUT ; /* ;AN000;M Display where? */
1617 break ; /* ;AN000;M */
1618 case MSG_ERRDRV : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1619 message = 15 ; /* ;AN000;M Message number to display */
1620 msg_class = EXT_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1621 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1622 handle = STDERR ; /* ;AN000;M Display where? */
1623 break ; /* ;AN000;M */
1624 case MSG_BADPARM : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1625 message = 10 ; /* ;AN000;M Message number to display */
1626 msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1627 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1628 handle = STDERR ; /* ;AN000;M Display where? */
1629 break ; /* ;AN000;M */
1630 case MSG_WARNSAME : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1631 message = 11 ; /* ;AN000;M Message number to display */
1632 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1633 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1634 handle = STDERR ; /* ;AN000;M Display where? */
1635 break ; /* ;AN000;M */
1636 case MSG_ERRDSKF : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1637 message = 12 ; /* ;AN000;M Message number to display */
1638 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1639 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1640 handle = STDERR ; /* ;AN000;M Display where? */
1641 break ; /* ;AN000;M */
1642 case MSG_REPLACIN : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1643 message = 13 ; /* ;AN000;M Message number to display */
1644 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1645 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1646 handle = STDOUT ; /* ;AN000;M Display where? */
1647 break ; /* ;AN000;M */
1648 case MSG_ADDING : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1649 message = 14 ; /* ;AN000;M Message number to display */
1650 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1651 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1652 handle = STDOUT ; /* ;AN000;M Display where? */
1653 break ; /* ;AN000;M */
1654 case MSG_SOMEREPL : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1655 message = 15 ; /* ;AN000;M Message number to display */
1656 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1657 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1658 handle = STDOUT ; /* ;AN000;M Display where? */
1659 break ; /* ;AN000;M */
1660 case MSG_SOMEADDE : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1661 message = 16 ; /* ;AN000;M Message number to display */
1662 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1663 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1664 handle = STDOUT ; /* ;AN000;M Display where? */
1665 break ; /* ;AN000;M */
1666 case MSG_NONFOUND : function = NO_INPUT ; /* ;AN000;M Y/N response or press key? */
1667 message = 17 ; /* ;AN000;M Message number to display */
1668 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1669 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1670 handle = STDOUT ; /* ;AN000;M Display where? */
1671 break ; /* ;AN000;M */
1672 case MSG_QREPLACE : function = DOS_CON_INPUT ; /* ;AN000;M Y/N response or press key? */
1673 message = 22 ; /* ;AN000;M Message number to display */
1674 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1675 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1676 handle = STDERR ; /* ;AN000;M Display where? */
1677 break ; /* ;AN000;M */
1678 case MSG_QADD : function = DOS_CON_INPUT ; /* ;AN000;M Y/N response or press key? */
1679 message = 23 ; /* ;AN000;M Message number to display */
1680 msg_class = UTILITY_CLASS ; /* ;AN000;M Which class of messages? */
1681 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1682 handle = STDERR ; /* ;AN000;M Display where? */
1683 break ; /* ;AN000;M */
1684 case MSG_XTRAPARM : function = NO_INPUT ; /* ;AN005;M Y/N response or press key? */
1685 message = 1 ; /* ;AN000;M Message number to display */
1686 msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1687 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1688 handle = STDERR ; /* ;AN000;M Display where? */
1689 break ; /* ;AN000;M */
1690 case MSG_BADSWTCH : function = NO_INPUT ; /* ;AN005;M Y/N response or press key? */
1691 message = 3 ; /* ;AN000;M Message number to display */
1692 msg_class = PARSE_ERR_CLASS ; /* ;AN000;M Which class of messages? */
1693 sub_cnt = SUBCNT1 ; /* ;AN000;M Number of substitutions? */
1694 handle = STDERR ; /* ;AN000;M Display where? */
1695 break ; /* ;AN000;M */
1696 } /* ;AN000;M */
1697
1698 switch (msg_num) /* ;AN000;M */
1699 { /* ;AN000;M */
1700 case MSG_NOMEM : /* ;AN000;M Insufficient memory */
1701 case MSG_INCOMPAT : /* ;AN000;M Invalid parameter combo */
1702 case MSG_NOSOURCE : /* ;AN000;M Source path required */
1703 case MSG_NONEREPL : /* ;AN000;M No files replaced */
1704 case MSG_NONEADDE : /* ;AN000;M No files added */
1705 case MSG_START : inregs.x.ax = message ; /* ;AN000;M Press any key... */
1706 inregs.x.bx = handle ; /* ;AN000;M STDERR or STDOUT */
1707 inregs.x.cx = sub_cnt ; /* ;AN000;M SUBCNT0 */
1708 inregs.h.dl = function ; /* ;AN000;M NO_INPUT */
1709 inregs.h.dh = msg_class ; /* ;AN000;M Extended, Parse or Utility */
1710 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call common msg service */
1711 break ; /* ;AN000;M */
1712 case MSG_BADPARM : /* ;AN000;M Invalid parameter */
1713 case MSG_XTRAPARM : /* ;AN005;M Too many parameters */
1714 case MSG_BADSWTCH : /* ;AN005;M Invalid switch */
1715 case MSG_ERRFNF : /* ;AN000;M File not found */
1716 case MSG_ERRPNF : /* ;AN000;M Path not found */
1717 case MSG_ERRACCD : /* ;AN000;M Access denied */
1718 case MSG_ERRDRV : /* ;AN000;M Invalid drive specification */
1719 case MSG_WARNSAME : /* ;AN000;M File cannot be copied... */
1720 case MSG_ERRDSKF : sublist.value = (unsigned far *)outline ; /* ;AN000;M Insufficient disk space */
1721 sublist.size = SUBLIST_LENGTH ; /* ;AN000;M */
1722 sublist.reserved = RESERVED ; /* ;AN000;M */
1723 sublist.id = 0 ; /* ;AN000;M */
1724 sublist.flags = STR_INPUT ; /* ;AN000;M */
1725 sublist.max_width = 0 ; /* ;AN000;M */
1726 sublist.min_width = 1 ; /* ;AN000;M */
1727 sublist.pad_char = BLNK ; /* ;AN000;M */
1728 inregs.x.ax = message ; /* ;AN000;M Which message? */
1729 inregs.x.bx = handle ; /* ;AN000;M STDERR or STDOUT */
1730 inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M SUBCNT0 */
1731 inregs.x.cx = sub_cnt ; /* ;AN000;M NO_INPUT */
1732 inregs.h.dl = function ; /* ;AN000;M Extended, Parse or Utility */
1733 inregs.h.dh = msg_class ; /* ;AN000;M Call common msg service */
1734 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M */
1735 break ; /* ;AN000;M */
1736 case MSG_SOMEREPL : /* ;AN000;M %1 file(s) replaced */
1737 case MSG_SOMEADDE : sublist.value = (unsigned far *)outline ; /* ;AN000;M %1 file(s) added */
1738 sublist.size = SUBLIST_LENGTH ; /* ;AN000;M */
1739 sublist.reserved = RESERVED ; /* ;AN000;M */
1740 sublist.id = 1 ; /* ;AN000;M */
1741 sublist.flags = DEC_INPUT ; /* ;AN000;M */
1742 sublist.max_width = 0 ; /* ;AN000;M */
1743 sublist.min_width = 1 ; /* ;AN000;M */
1744 sublist.pad_char = BLNK ; /* ;AN000;M */
1745 inregs.x.ax = message ; /* ;AN000;M Which message? */
1746 inregs.x.bx = handle ; /* ;AN000;M STDERR or STDOUT */
1747 inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M SUBCNT1 */
1748 inregs.x.cx = sub_cnt ; /* ;AN000;M NO_INPUT */
1749 inregs.h.dl = function ; /* ;AN000;M Extended, Parse or Utility */
1750 inregs.h.dh = msg_class ; /* ;AN000;M Call common msg service */
1751 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M */
1752 break ; /* ;AN000;M */
1753 case MSG_REPLACIN : /* ;AN000;M Replacing %1 */
1754 case MSG_ADDING : /* ;AN000;M Adding %1 */
1755 case MSG_NONFOUND : /* ;AN000;M No files found */
1756 case MSG_QREPLACE : /* ;AN000;M Replace %1? (Y/N) */
1757 case MSG_QADD : sublist.value = (unsigned far *)outline ; /* ;AN000;M Add %1? (Y/N) */
1758 sublist.size = SUBLIST_LENGTH ; /* ;AN000;M */
1759 sublist.reserved = RESERVED ; /* ;AN000;M */
1760 sublist.id = 1 ; /* ;AN000;M */
1761 sublist.flags = STR_INPUT ; /* ;AN000;M */
1762 sublist.max_width = 0 ; /* ;AN000;M */
1763 sublist.min_width = 1 ; /* ;AN000;M */
1764 sublist.pad_char = BLNK ; /* ;AN000;M */
1765 inregs.x.ax = message ; /* ;AN000;M Which message? */
1766 inregs.x.bx = handle ; /* ;AN000;M STDERR or STDOUT*/
1767 inregs.x.si = (unsigned int)&sublist ; /* ;AN000;M SUBCNT1 */
1768 inregs.x.cx = sub_cnt ; /* ;AN000;M NO_INPUT or DOS_CON_INPUT */
1769 inregs.h.dl = function ; /* ;AN000;M Extended, Parse or Utility */
1770 inregs.h.dh = msg_class ; /* ;AN000;M Call common msg service */
1771 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M */
1772 break ; /* ;AN000;M */
1773 default : restore() ; /* ;AN000;M */
1774 dexit(ERRLEVEL1) ; /* ;AN000;M */
1775 break ; /* ;AN000;M */
1776 } /* ;AN000;M */
1777
1778 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
1779 if (outregs.x.cflag & CARRY) /* ;AN000;M Is the carry flag set? */
1780 { /* ;AN000;M Setup regs for extd-err */
1781 inregs.x.bx = STDERR ; /* ;AN000;M */
1782 inregs.x.cx = SUBCNT0 ; /* ;AN000;M */
1783 inregs.h.dl = NO_INPUT ; /* ;AN000;M */
1784 inregs.h.dh = EXT_ERR_CLASS ; /* ;AN000;M */
1785 sysdispmsg(&inregs,&outregs) ; /* ;AN000;M Call to display ext_err msg */
1786 restore() ; /* ;AN000;M */
1787 dexit(ERRLEVEL1) ; /* ;AN000;M */
1788 } /* ;AN000;M */
1789 return ; /* ;AN000;M */
1790} /* ;AN000;M */
1791/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1792/**************************************************************************/
1793/* */
1794/* SUBROUTINE NAME: get_ext_attr */
1795/* */
1796/* SUBROUTINE FUNCTION: Get the Extended Attributes of the source */
1797/* file for the copy operation. */
1798/* */
1799/* INPUT: source_handle */
1800/* size_buffer (0=get size) */
1801/* */
1802/* OUTPUT: status (no extended attributes for DOS 4.00) */
1803/* */
1804/**************************************************************************/
1805
1806unsigned get_ext_attr(source_handle,size_buffer) /* ;AN000;EA */
1807unsigned source_handle ; /* ;AN000;EA */
1808unsigned size_buffer ; /* ;AN000;EA 0 or size returned */
1809{ /* ;AN000;EA */
1810 unsigned status ; /* ;AN000;EA */
1811
1812 inregs.x.ax = 0x5702 ; /* ;AN000;EA Get Ext Attr By Handle */
1813 inregs.x.bx = source_handle ; /* ;AN000;EA Source file handle */
1814 inregs.x.cx = size_buffer ; /* ;AN000;EA # of bytes or 0=get size */
1815 segregs.es = segment ; /* ;AN000;EA Use buffer "segment" */
1816 inregs.x.di = 0 ; /* ;AN000;EA Put the attrs in buffer */
1817 inregs.x.si = -1 ; /* ;AN000;EA Select all attributes */
1818 intdosx(&inregs,&outregs,&segregs) ; /* ;AN000;EA Int 21 */
1819 status = (outregs.x.cflag & CARRY) ; /* ;AN000;EA Make the call */
1820 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1821 return(status) ; /* ;AN000;EA */
1822} /* ;AN000;EA */
1823/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1824/**************************************************************************/
1825/* */
1826/* SUBROUTINE NAME: check_appendx_install */
1827/* */
1828/* SUBROUTINE FUNCTION: Determine if append and correct version is */
1829/* currently installed. */
1830/* */
1831/* INPUT: none */
1832/* */
1833/* OUTPUT: status (TRUE or FALSE) */
1834/* */
1835/**************************************************************************/
1836
1837unsigned check_appendx_install() /* ;AN000;X */
1838{ /* ;AN000;X */
1839 unsigned status = FALSE ; /* ;AN000;X */
1840
1841 inregs.x.ax = GETX_INSTALL ; /* ;AN000;X Get Append /x status */
1842 int86(0x2f,&inregs,&outregs) ; /* ;AN000;X Make the call */
1843 if (outregs.h.al) /* ;AN000;X */
1844 { /* ;AN000;X */
1845 inregs.x.ax = GETX_VERSION ; /* ;AN000;X */
1846 int86(0x2f,&inregs,&outregs) ; /* ;AN000;X */
1847 if (outregs.x.ax == X_INSTALLED) /* ;AN000;X */
1848 status = TRUE ; /* ;AN000;X */
1849 } /* ;AN000;X */
1850 return(status) ; /* ;AN000;X */
1851} /* ;AN000;X */
1852/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1853/**************************************************************************/
1854/* */
1855/* SUBROUTINE NAME: check_appendx */
1856/* */
1857/* SUBROUTINE FUNCTION: Get the append /x status. */
1858/* */
1859/* INPUT: none */
1860/* */
1861/* OUTPUT: bx (contains append bits set) */
1862/* */
1863/**************************************************************************/
1864
1865unsigned check_appendx() /* ;AN000;X */
1866{ /* ;AN000;X */
1867 inregs.x.ax = GETX_STATUS ; /* ;AN000;X Get Append /x status */
1868 int86(0x2f,&inregs,&outregs) ; /* ;AN000;X Make the call */
1869 return(outregs.x.bx) ; /* ;AN000;X */
1870} /* ;AN000;X */
1871/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1872/**************************************************************************/
1873/* */
1874/* SUBROUTINE NAME: set_appendx */
1875/* */
1876/* SUBROUTINE FUNCTION: Set the append /x status. */
1877/* */
1878/* INPUT: set_state (turn appendx bit off or reset original) */
1879/* */
1880/* OUTPUT: none */
1881/* */
1882/**************************************************************************/
1883
1884void set_appendx(set_state) /* ;AN000;X */
1885unsigned set_state ; /* ;AN000;X */
1886{ /* ;AN000;X */
1887 inregs.x.ax = SETX_STATUS ; /* ;AN000;X Set Append /x status */
1888 inregs.x.bx = set_state ; /* ;AN000;X */
1889 int86(0x2f,&inregs,&outregs) ; /* ;AN000;X */
1890 return ; /* ;AN000;X */
1891} /* ;AN000;X */
1892/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1893/**************************************************************************/
1894/* */
1895/* SUBROUTINE NAME: parser_prep */
1896/* */
1897/* SUBROUTINE FUNCTION: Initialize all structures for the parser. */
1898/* */
1899/* INPUT: source (command line string) */
1900/* */
1901/* OUTPUT: none */
1902/* */
1903/**************************************************************************/
1904
1905void parser_prep(source) /* ;AN000;P */
1906char *source ; /* ;AN000;P Commandline */
1907{ /* ;AN000;P */
1908 p_p.p_parmsx_address = &p_px ; /* ;AN000;P Address of extd parm list */
1909 p_p.p_num_extra = 0 ; /* ;AN000;P No extra declarations */
1910
1911 p_px.p_minp = MINPOSITION ; /* ;AN000;P 1 required positional */
1912 p_px.p_maxp = MAXPOSITION ; /* ;AN000;P 2 maximum positionals */
1913 p_px.p_control1 = &p_con1 ; /* ;AN000;P pointer to next control blk */
1914 p_px.p_control2 = &p_con2 ; /* ;AN000;P pointer to next control blk */
1915 p_px.p_maxs = 1 ; /* ;AN000;P Specify # of switches */
1916 p_px.p_switch = &p_swit ; /* ;AN000;P Point to the switch blk */
1917 p_px.p_maxk = 0 ; /* ;AN000;P Specify # of keywords */
1918
1919 p_con1.p_match_flag = REQ_FILESPEC ; /* ;AN000;P File spec required */
1920 p_con1.p_function_flag = CAPRESULT ; /* ;AN000;P Cap result by file table */
1921 p_con1.p_result_buf = (unsigned int)&rslt1 ; /* ;AN000;P */
1922 p_con1.p_value_list = (unsigned int)&novals ; /* ;AN000;P */
1923 p_con1.p_nid = 0 ; /* ;AN000;P */
1924
1925 p_con2.p_match_flag = OPT_FILESPEC ; /* ;AN000;P File spec & optional */
1926 p_con2.p_function_flag = CAPRESULT ; /* ;AN000;P Cap result by file table */
1927 p_con2.p_result_buf = (unsigned int)&rslt1 ; /* ;AN000;P */
1928 p_con2.p_value_list = (unsigned int)&novals ; /* ;AN000;P */
1929 p_con2.p_nid = 0 ; /* ;AN000;P */
1930
1931 p_swit.sp_match_flag = OPT_SWITCH ; /* ;AN000;P Optional (switch) */
1932 p_swit.sp_function_flag = NOCAPPING ; /* ;AN000;P Cap result by file table */
1933 p_swit.sp_result_buf = (unsigned int)&rslt2 ; /* ;AN000;P */
1934 p_swit.sp_value_list = (unsigned int)&novals ; /* ;AN000;P */
1935 p_swit.sp_nid = 6 ; /* ;AN000;P One switch allowed */
1936 strcpy(p_swit.sp_keyorsw1,A_SW) ; /* ;AN000;P Identify the switch */
1937 strcat(p_swit.sp_keyorsw2,P_SW) ; /* ;AN000;P Identify the switch */
1938 strcat(p_swit.sp_keyorsw3,R_SW) ; /* ;AN000;P Identify the switch */
1939 strcat(p_swit.sp_keyorsw4,S_SW) ; /* ;AN000;P Identify the switch */
1940 strcat(p_swit.sp_keyorsw5,U_SW) ; /* ;AN000;P Identify the switch */
1941 strcat(p_swit.sp_keyorsw6,W_SW) ; /* ;AN000;P Identify the switch */
1942
1943 inregs.x.si = (unsigned int)source ; /* ;AN000;P Make DS:SI point to source */
1944 inregs.x.cx = 0 ; /* ;AN000;P Operand ordinal */
1945 inregs.x.di = (unsigned int)&p_p ; /* ;AN000;P Address of parm list */
1946 return ; /* ;AN000;P */
1947} /* ;AN000;P */
1948/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1949/**************************************************************************/
1950/* */
1951/* SUBROUTINE NAME: display_exit */
1952/* */
1953/* SUBROUTINE FUNCTION: Display the message, then terminate the utility.*/
1954/* */
1955/* INPUT: msg_num (#define'd message to display) */
1956/* outline (sublist substitution) */
1957/* error_code (errorlevel return code) */
1958/* */
1959/* OUTPUT: none */
1960/* */
1961/**************************************************************************/
1962
1963void display_exit(msg_num,outline,error_code) /* ;AN000;M */
1964int msg_num ; /* ;AN000;M Message number #define'd */
1965char *outline ; /* ;AN000;M */
1966int error_code ; /* ;AN006; */
1967{ /* ;AN000;M */
1968 display_msg(msg_num,outline) ; /* ;AN000;M First, display the msg */
1969 restore() ; /* ;AN006; */
1970 dexit(error_code) ; /* ;AN000;M Then, terminate utility */
1971} /* ;AN000;M */
1972/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1973/**************************************************************************/
1974/* */
1975/* SUBROUTINE NAME: setup_ctl_brk */
1976/* */
1977/* SUBROUTINE FUNCTION: Change the CTL BRK vector to point to handler */
1978/* routine. */
1979/* */
1980/* INPUT: none */
1981/* */
1982/* OUTPUT: none */
1983/* */
1984/**************************************************************************/
1985
1986void setup_ctl_brk() /* ;AN000; */
1987{ /* ;AN000; */
1988 /* set the ctl brk vector to point to us */
1989 segread(&segregs) ; /* ;AN000; */
1990 inregs.x.ax = SETVEC_CTLBRK ; /* ;AN000; Set vector,ctl brk */
1991 inregs.x.dx = (unsigned)ctl_brk_handler ; /* ;AN000; Offset points to us */
1992 segregs.ds = segregs.cs ; /* ;AN000; */
1993 intdosx(&inregs,&outregs,&segregs) ; /* ;AN000; Int 21 */
1994 return ; /* ;AN000; */
1995} /* ;AN000; */
1996/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1997/**************************************************************************/
1998/* */
1999/* SUBROUTINE NAME: setup_crit_err */
2000/* */
2001/* SUBROUTINE FUNCTION: Change the critical error vector to point to */
2002/* the handler routine. */
2003/* */
2004/* INPUT: none */
2005/* */
2006/* OUTPUT: none */
2007/* */
2008/**************************************************************************/
2009
2010void setup_crit_err() /* ;AN000; */
2011{ /* ;AN000; */
2012 /* get and save original vector pointers */
2013 inregs.x.ax = GETVEC_CRITERR ; /* ;AN000; Get vector,crit err */
2014 intdosx(&inregs,&outregs,&segregs) ; /* ;AN000; Int 21 */
2015 oldint24 = outregs.x.bx ; /* ;AN000; Save orig offset */
2016 *((unsigned *)(&oldint24)+1) = segregs.es ; /* ;AN000; */
2017 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
2018
2019 /* set the crit err vector to point to us */
2020 segread(&segregs) ; /* ;AN000; */
2021 inregs.x.ax = SETVEC_CRITERR ; /* ;AN000; Set vector,crit err */
2022 inregs.x.dx = (unsigned)crit_err_handler ; /* ;AN000; Offset points to us */
2023 segregs.ds = segregs.cs ; /* ;AN000; */
2024 intdosx(&inregs,&outregs,&segregs) ; /* ;AN000; Int 21 */
2025 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
2026 return ; /* ;AN000; */
2027} /* ;AN000; */
2028/*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2029/**************************************************************************/
2030/* */
2031/* SUBROUTINE NAME: restore */
2032/* */
2033/* SUBROUTINE FUNCTION: Restore the original appendx before exiting. */
2034/* */
2035/* INPUT: none */
2036/* */
2037/* OUTPUT: none */
2038/* */
2039/**************************************************************************/
2040
2041void restore() /* ;AN000; */
2042{ /* ;AN000; */
2043 /* restore append/x status */
2044 if (append_installed) /* ;AN000;A */
2045 set_appendx(x_status) ; /* ;AN000;A Reset append/x status */
2046 return ; /* ;AN000; */
2047} /* ;AN000; */