2 /**************************************************************************/
4 /* UTILITY NAME: Replace */
6 /* SOURCE FILE NAME: Replace.C */
8 /* STATUS: Replace Utility, DOS Version 4.00 */
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 */
17 /* SYNTAX: [d:][path]REPLACE[d:][path]filename[.ext] */
18 /* [d:][path] [/A][/P][/R][/S][/U][/W] */
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 */
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. */
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 */
37 /* /A copies all files specified by the source that */
38 /* do not exist on the target. */
40 /* /P prompts as each file is encountered on the tar- */
41 /* get, allowing selective replacing or adding. */
43 /* /R replaces files that are read-only on the target.*/
45 /* /S searches all directories of the target for */
46 /* files matching the source file name. */
48 /* /U replaces updated date/time attribute source */
49 /* files to the target. */
51 /* /W waits for you to insert a diskette before be- */
52 /* ginning to search for source files. */
54 /* ** NOTE ** /A + /S and A/ + /U cannot be used together. */
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 */
64 /* ERROR HANDLING: Error message is displayed and utility is */
65 /* then terminated (with appropriate error level). */
67 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
73 /* ;AC000;: Changed code for DOS Version 4.00 S.M 1987 */
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) */
83 /* ;Ax001;: New code required - PTM0000001 S.M 1987 */
84 /* Set archive bit ON after replace */
86 /* ;Ax002;: Change code req'd - PTM0003154 S.M 1988 */
87 /* Enable filesize update in directory */
89 /* ;Ax003;: Change code req'd - PTM0003753 S.M 1988 */
90 /* Dsearchf return garbage */
92 /* ;Ax004;: Change code req'd - PTM0003891 S.M 1988 */
93 /* One char subdir name not handled */
95 /* ;Ax005;: Change code req'd - PTM0003907 S.M 1988 */
96 /* Incorrect message responses */
98 /* ;Ax006;: Change code req'd - PTM0004124 S.M 1988 */
99 /* Incorrect message responses */
101 /**************************************************************************/
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 */
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 */
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 */
126 /* ------------- INT 21h RETURN CODES -----------*/
129 #define NOMOREFILES 18
130 #define TARGETFULL -1
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 */
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 */
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 */
188 /* ------------- MISCELLANEOUS ------------------*/
189 #define ARCHIVE 0x20 /* Archive bit file attribute */
190 #define BUF 512 /* ;AC000; */
192 #define INACTIVE 0x0000 /* ;AN000;A Append/x inactive status */
193 #define MAX 256 /* ;AC000; */
194 #define MAXMINUS1 255 /* ;AC000; */
198 #define TATTRIB SUBDIR
200 #define X_INSTALLED 0xffff /* ;AN000;A Set the Append/x status */
202 struct filedata /* ;AC000; Files used in copy operations */
211 struct parm_list /* ;AN000;EA To be passed to Extd Create */
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 */
220 -1, /* ;AN000;EA (will recv segment addr) */
226 /* ------------- PARSE STRUCTURES ---------------*/
227 struct p_parms p_p ; /* ;AN000;P # of extras & pts to descrptn */
228 struct p_parmsx p_px ; /* ;AN000;P min/max parms & pts to controls */
229 struct p_control_blk p_con1 ; /* ;AN000;P 1st posit parm in cmd str */
230 struct p_control_blk p_con2 ; /* ;AN000;P 2nd posit parm in cmd str */
231 struct p_switch_blk p_swit ; /* ;AN000;P /A /P /R /S /U /W */
232 struct p_fresult_blk rslt1 ; /* ;AN000;P Result blk rtrnd from parser */
233 struct p_result_blk rslt2 ; /* ;AN000;P Result blk rtrnd from parser */
234 struct noval novals = {0} ; /* ;AN000;P Value list not used */
236 /* ------------- MISCELLANEOUS ------------------*/
237 union REGS inregs, outregs ; /* ;AN000;P Define register variables */
238 struct SREGS segregs ; /* ;AN000; Segment regs for Int21 */
240 char append_installed = FALSE ; /* ;AN000;A ? */
241 char attr_list[BUF] = {0} ; /* ;AN000;EA Buf for list of attributes */
242 char cmdln_invalid[64] = {0} ; /* ;AN006; */
243 char cmdln_switch[64] = {0} ; /* ;AN006; message, if needed */
244 char disk_full = FALSE ; /* RW Flag - Disk full on target */
245 char ea_flag = FALSE ; /* ;AN000;EA */
246 char errfname[MAX] = {0} ;
247 char errline[MAX] = {0} ;
248 char filename[MAX] = {0} ; /* RW Save area for filename being copied */
249 char fix_es_reg[2] = {0} ; /* ;AN000;P Corrects es reg after type-"far" */
250 char not_valid_input = TRUE ; /* ;AN000;M Flag for Y/N message */
251 char only_one_valid_file = FALSE ; /* ;AN000; Flag indicating valid filecount */
252 char outline[MAX] = {0} ;
253 char p_path[64] = {0} ; /* ;AN000;P Recvs path from parser */
254 char p_sfilespec[64] = {0} ; /* ;AN000;P Recvs filespec from parser */
255 char source[MAXMINUS1] = {0} ;
256 char target[MAXMINUS1] = {0} ;
257 char target_full = FALSE ; /* ;AN000; Check flag at exit */
259 unsigned char dbcs_search[3] = {0} ; /* ;AN000; */
261 unsigned add = FALSE ; /* /A switch */
262 unsigned counted = 0 ; /* Num replaced or added */
263 unsigned descending = FALSE ; /* /S switch */
265 unsigned prompt = FALSE ; /* /P switch */
266 unsigned readonly = FALSE ; /* /R switch */
268 unsigned update = FALSE ; /* ;AN000;U /U switch */
269 unsigned wait = FALSE ; /* /W switch */
270 unsigned x_status = 0 ; /* ;AN000;A Original append/x state */
273 long oldint24 ; /* ;AN000; Rcv cntrl from, then ret to */
275 extern crit_err_handler() ; /* ;AN000; Assembler routine */
276 extern ctl_brk_handler() ; /* ;AN000; Assembler routine */
278 unsigned Check_Appendx_Install ();
279 unsigned Check_Appendx ();
281 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
283 /**************************************************************************/
285 /* SUBROUTINE NAME: main */
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 */
297 /* INPUT: Command line arguments */
299 /* EXIT-NORMAL: Information message displayed. */
301 /* EXIT-ERROR: Error message displayed, appendx restored, */
302 /* errorlevel set. */
304 /* EXTERNAL ROUTINES: SYSLOADMSG */
307 /* crit_err_handler */
308 /* ctl_brk_handler */
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 */
319 /* dfree parser_prep */
320 /* display_exit putbyte */
321 /* display_msg putdword */
325 /* dopen set_appendx */
326 /* dread setup_crit_err */
327 /* dsearchf setup_ctl_brk */
330 /**************************************************************************/
332 void main(argc, argv) /* ;AC000; */
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 */
350 char *com_strchr() ; /* ;AN000; To search for DBCS "\\" */
351 char getbyte() ; /* ;AC000; forward declaration */
353 int same() ; /* ;AN000; forward declaration */
355 unsigned char *com_strrchr() ; /* ;AN000; To search for DBCS "\\" */
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 */
379 long getdword() ; /* ;AC000; forward declaration */
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 */
386 char far * fptr ; /* ;AN000;P Pts to parser's buf for flspc */
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 */
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 */
397 unsigned filecount = 0 ;
398 unsigned have_source = FALSE ; /* Flag */
399 unsigned have_target = FALSE ; /* Flag */
400 unsigned status ; /* Mostly used for carry flag */
402 /************************ BEGIN ***********************************************/
404 load_msg() ; /* ;AN000;M Point to msgs & chk DOS ver */
405 for (index = 1; index <= argc; index++) /* ;AN000;P Form string for parser */
407 strcat(source,argv[index]) ; /* ;AN000;P Add the argument */
408 strcat(source," ") ; /* ;AN000;P Separate with a space */
410 parser_prep(source) ; /* ;AN000;P Initialization for the parser */
412 while (more_to_parse) /* ;AN000;P Test the parse loop flag */
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 */
420 for (fptr = rslt1.fp_result_buff; (char)*fptr != NULL; fptr++) /* ;AN000;P get the filespec from parser */
422 p_sfilespec[fchar] = (char)*fptr ; /* ;AN000;P get the character */
423 fchar++ ; /* ;AN000;P Move the char ptr */
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 */
430 if ((outregs.x.dx == (unsigned short)&rslt1) && /* ;AN000;P if result is filespec */
431 (have_source)) /* ;AN000;P & we do have the source */
433 for (fptr = rslt1.fp_result_buff; (char)*fptr != NULL; fptr++) /* ;AN000;P get the filespec from parser */
435 p_path[fchar] = (char)*fptr ; /* ;AN000;P get the character */
436 fchar++ ; /* ;AN000;P Move the char ptr */
438 strcpy(fix_es_reg,NULL) ; /* ;AN000;P (Set es reg correct) */
439 have_target = TRUE ; /* ;AN000;P Set the flag */
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; */
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 */
451 case 'A' : if (!add) /* ;AN000;P /A switch */
452 add = TRUE ; /* ;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 */
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 */
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 */
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 */
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 */
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 */
486 if (outregs.x.ax != P_RC_EOL) /* ;AN000;P Is the parser */
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; */
493 switch (outregs.x.ax) /* ;AN000;P returning an error? */
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 */
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 */
512 /* Verify the correctness of the parameters */
514 if ((add && descending) || (add && update)) /* ;AC000;P A+S or A+U */
516 display_msg(MSG_INCOMPAT) ; /* ;AN000;P Incompatible switches */
517 dexit(ERRLEVEL11) ; /* ;AC000; */
520 /* Allocate the data buffer to be used during the copy operations */
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) ;
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; */
536 segment = outregs.x.ax ; /* ;AC000; */
537 length = (length << 4) ; /* Convert to bytes */
538 if (length == 0) length = 0xffff ;
540 /* If the wait switch was on the command line, wait to continue */
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; */
550 inregs.x.ax = 0x0100 ; /* ;AC000; */
551 intdos(&inregs,&outregs) ; /* ;AC000; */
552 status = (outregs.x.cflag & CARRY) ; /* ;AC000; */
556 /* Make a fully qualified source path */
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 */
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; */
570 strcat(source,save) ;
574 /* Append current directory string */
576 strcpy(errfname,source) ;
577 if (source[2] != '\\') /* If not path from root */
579 strcpy(save,&source[2]) ;
580 strcpy(&source[3],save) ;
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 */
592 if ((com_strrchr(source,'\\')) == NULL) /* ;AC000; DBCS function */
593 strcat(source,"\\") ;
595 if ((char *)(com_strrchr(source,'\\')) != &source[strlen(source)-1]) /* ;AN000; DBCS function */
596 strcat(source,"\\") ; /* ;AN000; */
597 strcat(source,save) ;
601 status = check_appendx_install() ; /* ;AN000;A Check append/x install */
602 if (status != NOERROR) /* ;AN000;A If append/x is installed */
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 */
609 status = NOERROR ; /* ;AN000;A */
611 setup_ctl_brk() ; /* ;AN000; Ctl brk vec now pts to us */
612 setup_crit_err() ; /* ;AN000; Crit err vec now pts to us */
614 /* Create a list of the files that we might just replace */
616 strcpy(errfname,source) ;
617 status = dsearchf(source,&files[filecount],SATTRIB) ; /* Find the first file */
619 while (search_more_files) /* ;AN000; Search & replace/add */
621 while ( (filecount < MAXMINUS1) && (status == NOERROR) )
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; */
629 status = dsearchn(&files[filecount]) ;
632 if (status == NOMOREFILES)
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 */
642 if ((first_time_thru_loop) && (status == NOERROR) ) /* ;AN000; Bypassed if done already */
644 first_time_thru_loop = FALSE ; /* ;AN000; > 256 files to replace */
646 display_exit(MSG_NONFOUND,source,ERRLEVEL2) ; /* ;AC000; */
648 if (status == NOERROR)
650 /* fixup the source directory path so that it is useable */
652 for (i = strlen(source)-1; (i >= 0) && (!backslash_char) && (source[i] != ':'); i--) /* ;AC000; */
653 if ((source[i] == '\\') && (i != 0)) /* ;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 */
664 if ((source[i] == '\\') && (i == 0)) /* ;AN000; */
666 backslash_char = TRUE ; /* ;AN000; */
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; */
679 /* fixup the target path */
681 strcpy(target,p_path) ; /* ;AN000;P Copy path recvd from parser */
682 if (target[0] == NULL)
684 inregs.x.ax = 0x1900 ; /* ;AC000; Get current drive */
685 intdos(&inregs,&outregs) ; /* ;AC000; */
686 if (status == NOERROR)
688 target[0] = 'A' + (outregs.x.ax & 0xff) ; /* ;AC000; */
694 strcpy(errfname,target) ;
695 if ( (strlen(target) == 2) && (target[1] == ':') && (status == NOERROR) )
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 */
708 strcpy(save,target) ;
709 strcpy(errfname,target) ;
710 if (target[1] != ':')
712 inregs.x.ax = 0x1900 ; /* ;AC000; Get current drive */
713 intdos(&inregs,&outregs) ; /* ;AC000; */
714 if (status == NOERROR)
716 target[0] = 'A' + (outregs.x.ax & 0xff) ; /* ;AC000; */
719 strcat(target,save) ;
723 strcpy(errfname,target) ;
724 if (target[2] != '\\') /* ;AC000; */
726 strcpy(save,&target[2]) ;
727 strcpy(&target[3],save) ; /* ;AN004; */
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)
739 if ((com_strrchr(target,'\\')) == NULL) /* ;AC004; DBCS func, if no backslash */
740 strcat(target,"\\") ; /* ;AC000; then add backslash */
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 */
747 if (save[1] == '.') /* ;AN004; If tgt is parent dir */
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 */
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,"\\") ;
764 if ( (status == NOERROR) && (!add) )
765 status = dodir(source,target,files,filecount) ;
767 if ( (status == NOERROR) && (add) )
768 status = doadd(source,target,files,filecount) ;
770 filecount = 0 ; /* ;AN000; Reset for next loop */
771 need_to_reset_filecount = TRUE ; /* ;AN000; Get to 0 element */
773 if (status != NOERROR) /* ;AN000; If there was an error */
774 search_more_files = FALSE ; /* ;AN000; somewhere, drop out */
782 case 2 : display_msg(MSG_ERRFNF,errfname) ; /* ;AC000; file not found */
784 case 3 : display_msg(MSG_ERRPNF,errfname) ; /* ;AC000; path not found */
786 case 5 : display_msg(MSG_ERRACCD,errfname) ; /* ;AC000; access denied */
788 case 15 : display_msg(MSG_ERRDRV,errfname) ; /* ;AC000; invalid drive */
790 default : dexit(ERRLEVEL1) ; /* ;AC000; */
796 display_msg(MSG_NONEADDE) ; /* ;AC000; no files added */
798 display_msg(MSG_SOMEADDE,(char *)&counted) ; /* ;AC000; %1 files added */
801 display_msg(MSG_NONEREPL) ; /* ;AC000; no files replaced */
803 display_msg(MSG_SOMEREPL,(char *)&counted) ; /* ;AC000; %1 files replaced */
805 restore() ; /* ;AN000; Cleanup before exit */
808 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
810 unsigned dodir(source,target,files,filecount) /* ;AC000; */
813 struct filedata *files ;
817 char subdirectory[MAX] ;
820 struct filedata file ;
822 dta_save(dta_area,128) ;
823 strcpy(subdirectory,target) ;
824 strcat(subdirectory,"*.*") ;
825 status = dsearchf(subdirectory,&file,TATTRIB) ;
826 while (status == NOERROR)
828 if ( ((file.attribute & SUBDIR) != 0) &&
829 (descending) && (file.name[0] != '.') )
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,"*.*") ;
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) ;
851 if (status == NOERROR)
852 status = dsearchn(&file) ;
855 dta_restore(dta_area,128) ;
856 if (status == NOMOREFILES)
860 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
862 unsigned doadd(source,target,files,filecount) /* ;AC000; */
865 struct filedata *files ;
870 unsigned status = NOERROR ;
872 struct filedata dummy ;
874 if (only_one_valid_file) /* ;AN003; Eliminate extra loop */
875 filecount-- ; /* ;AN003; */
877 for (index = 0; (index <= filecount) && (status == NOERROR) ; index++) /* ;AC000; */
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) ;
887 status = NOERROR ; /* ;AN000; Skip this null file */
891 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
893 unsigned findfile(files,file,filecount) /* ;AC000; */
894 struct filedata *files ;
895 struct filedata *file ;
900 if (only_one_valid_file) /* ;AN003; Eliminate extra loop */
901 filecount-- ; /* ;AN003 */
903 for (i = 0; i <= filecount; i++) /* ;AC000; */
905 if (same(files->name,file->name)) /* ;AC000; */
909 return(ERRLEVELNEG1) ; /* ;AC000; */
911 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
913 unsigned docopy(sdir,tdir,file,time,date) /* ;AC000; */
916 struct filedata *file ;
923 unsigned source_handle ;
925 unsigned target_handle ;
928 /* create the path names and check for equivalence */
930 strcpy(source,sdir) ;
931 strcat(source,file->name) ;
932 strcpy(target,tdir) ;
933 strcat(target,file->name) ;
935 status = strcmp(source,target) ;
936 if (status == NOERROR)
938 display_msg(MSG_WARNSAME,source) ; /* ;AC000; File cannot be copied... */
942 /* We can replace! if prompting, check to see */
943 /* if this file is to be replaced or not */
945 while ( (prompt) && (not_valid_input) ) /* ;AN000;M Flag set in dcompare */
948 display_msg(MSG_QADD,target) ; /* ;AC000; Add? filename */
950 display_msg(MSG_QREPLACE,target) ; /* ;AC000; Replace? filename */
951 status = dcompare() ; /* ;AN000; */
953 not_valid_input = TRUE ; /* ;AN000; Prepare for next file in loop */
955 return(ERRLEVEL0) ; /* ;AC000; */
957 /* indicate what we are replacing */
960 display_msg(MSG_ADDING,target) ; /* ;AC000; Adding filename */
962 display_msg(MSG_REPLACIN,target) ; /* ;AC000; Replacing filename */
964 /* open the input file */
966 status = dopen(source) ; /* ;AC000; Extended open */
969 strcpy(errfname,source) ;
973 source_handle = outregs.x.ax ; /* ;AN000; */
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 */
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 */
984 /* create the output file */
985 /* if we are to overwrite READONLY files, set the mode so we can */
989 inregs.x.cx = 0 ; /* ;AC000; */
990 status = dchmod(target,0) ;
993 strcpy(errfname,target) ;
994 dclose(source_handle) ;
997 file->attribute = outregs.x.cx ; /* ;AC000; */
999 outregs.x.cx = outregs.x.cx & 0xfffe ; /* ;AC000; */
1000 if (file->attribute != outregs.x.cx) /* ;AC000; */
1002 status = dchmod(target,1) ;
1005 strcpy(errfname,target) ;
1006 dclose(source_handle) ;
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 */
1017 strcpy(filename,target) ; /* Note that existing file*/
1018 if (status != 0) /* will be deleted */
1020 strcpy(errfname,target) ;
1021 dclose(source_handle) ;
1025 target_handle = outregs.x.ax ; /* ;AC000; */
1027 /* now, copy all of the data from the in file to the out file */
1030 while ( (try == length) && (status == NOERROR) )
1032 status = dread(source_handle,segment,0,try) ;
1033 if (status == NOERROR)
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 */
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 */
1048 if (status == NOERROR)
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 */
1061 if (status == NOERROR)
1063 status = dclose(target_handle) ; /* Close target file */
1064 if (status != NOERROR)
1065 strcpy(errfname,target) ;
1068 if ((file->attribute & ARCHIVE) != ARCHIVE)
1069 file->attribute += ARCHIVE ; /* ;AN001; Set archive bit ON */
1070 inregs.x.cx = file->attribute ; /* ;AC000; */
1072 status = dchmod(target,1) ; /* Reset attributes on target */
1073 if (status != NOERROR)
1074 strcpy(errfname,target) ;
1075 counted++ ; /* Increment num files processed */
1079 if (disk_full) /* RW If the target disk got full */
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; */
1086 dclose(source_handle) ;
1089 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1091 int same(s,t) /* ;AC000; */
1095 while ( (*s != NULL) && (*t != NULL) ) /* ;AC000; */
1097 if ( *s != *t ) /* ;AC000; */
1098 return(FALSE) ; /* ;AN000;Removed "casemap" */
1103 return(FALSE) ; /* ;AN000;Removed "casemap" */
1106 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1108 unsigned dallocate(s) /* ;AC000; */
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 */
1122 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1124 unsigned dfree(s) /* ;AC000; */
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; */
1139 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1141 unsigned dcreate(n,parm_value) /* ;AC000; */
1143 unsigned parm_value ;
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 */
1160 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1162 unsigned dopen(n) /* ;AC000; */
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 */
1180 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1182 unsigned ddelete(n) /* ;AC000; */
1183 char *n ; /* File to be deleted */
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 */
1196 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1198 unsigned dread(h,s,o,l) /* ;AC000; */
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 */
1218 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1220 unsigned dwrite(handle,segment,offset,length) /* ;AC000; */
1227 unsigned write_len ; /* Save area for num of bytes to write */
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 */
1245 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1247 unsigned dclose(h) /* ;AC000; */
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 */
1261 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1263 unsigned dchmod(n,a) /* ;AC000; */
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 */
1278 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1280 unsigned dsearchf(s,t,a) /* ;AC000; */
1282 struct filedata *t ;
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)
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; */
1308 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1310 unsigned dsearchn(t) /* ;AC000; */
1311 struct filedata *t ;
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)
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; */
1334 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1336 unsigned dexit(s) /* ;AC000; */
1339 if (target_full) /* ;AN000; If unable to copy any files */
1340 s = ERRLEVEL8 ; /* ;AN000; Insufficient memory */
1341 exit(s) ; /* ;AN000; terminate program */
1344 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1346 void dta_save(t,l) /* ;AC000; */
1352 for (i = 0; i < l; i++)
1353 *(t+i) = getbyte(_psp,0x80+i) ;
1354 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1355 return ; /* ;AC000; */
1357 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1359 void dta_restore(t,l) /* ;AC000; */
1365 for (i = 0; i < l; i++)
1366 putbyte(_psp,0x80+i,*(t+i)) ;
1367 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1368 return ; /* ;AC000; */
1370 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1372 char getbyte(msegment,moffset) /* ;AN000; */
1373 unsigned int msegment ; /* ;AN000; */
1374 unsigned int moffset ; /* ;AN000; */
1376 char far * cPtr ; /* ;AN000; */
1378 FP_SEG(cPtr) = msegment ; /* ;AN000; */
1379 FP_OFF(cPtr) = moffset ; /* ;AN000; */
1380 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1381 return(*cPtr) ; /* ;AN000; */
1383 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1385 unsigned getword(msegment,moffset) /* ;AN000; */
1386 unsigned int msegment ; /* ;AN000; */
1387 unsigned int moffset ; /* ;AN000; */
1389 unsigned far * uPtr ; /* ;AN000; */
1391 FP_SEG(uPtr) = msegment ; /* ;AN000; */
1392 FP_OFF(uPtr) = moffset ; /* ;AN000; */
1393 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1394 return(*uPtr) ; /* ;AN000; */
1396 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1398 long getdword(msegment,moffset) /* ;AN000; */
1399 unsigned int msegment ; /* ;AN000; */
1400 unsigned int moffset ; /* ;AN000; */
1402 long far * lPtr ; /* ;AN000; */
1404 FP_SEG(lPtr) = msegment ; /* ;AN000; */
1405 FP_OFF(lPtr) = moffset ; /* ;AN000; */
1406 strcpy(fix_es_reg,NULL) ; /* ;AN000; */
1407 return(*lPtr) ; /* ;AN000; */
1409 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1411 void putbyte(msegment,moffset,value) /* ;AN000; */
1412 unsigned int msegment ; /* ;AN000; */
1413 unsigned int moffset ; /* ;AN000; */
1414 char value ; /* ;AN000; */
1416 char far * cPtr ; /* ;AN000; */
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; */
1424 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1426 void putword(msegment,moffset,value) /* ;AN000; */
1427 unsigned int msegment ; /* ;AN000; */
1428 unsigned int moffset ; /* ;AN000; */
1429 unsigned value ; /* ;AN000; */
1431 unsigned far * uPtr ; /* ;AN000; */
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; */
1439 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1441 void putdword(msegment,moffset,value) /* ;AN000; */
1442 unsigned int msegment ; /* ;AN000; */
1443 unsigned int moffset ; /* ;AN000; */
1444 long value ; /* ;AN000; */
1446 long far * lPtr ; /* ;AN000; */
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; */
1454 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1455 /**************************************************************************/
1457 /* SUBROUTINE NAME: load_msg */
1459 /* SUBROUTINE FUNCTION: Load the set of REPLACE Utility messages to */
1460 /* become available for display_msg call. */
1462 /* ERROR EXIT: Utility will be terminated by sysloadmsg if */
1463 /* version check is incorrect. */
1465 /* EXTERNAL REF: SYSLOADMSG */
1467 /**************************************************************************/
1469 void load_msg() /* ;AN000;M */
1471 sysloadmsg(&inregs,&outregs) ; /* ;AN000;M Load utility messages */
1472 if (outregs.x.cflag & CARRY) /* ;AN000;M */
1474 sysdispmsg(&outregs,&outregs) ; /* ;AN000;M If load error, display err msg */
1475 dexit(ERRLEVEL1) ; /* ;AN000;M */
1477 return ; /* ;AN000;M Return with no error */
1479 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1480 /**************************************************************************/
1482 /* SUBROUTINE NAME: dcompare */
1484 /* SUBROUTINE FUNCTION: Check a Y/N response using an Int21 Get */
1485 /* Extended Country information. */
1487 /* INPUT: function (character to check) (global) */
1489 /* OUTPUT: status (carry flag if set or response) */
1491 /* NORMAL EXIT: AX=0=No (status = 2) */
1492 /* AX=1=Yes (status = 1) */
1494 /**************************************************************************/
1496 unsigned dcompare() /* ;AN000;EC */
1498 unsigned status ; /* ;AN000;EC Receives error cond or Y/N */
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 */
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 */
1514 return(status) ; /* ;AN000;EC */
1516 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1517 /**************************************************************************/
1519 /* SUBROUTINE NAME: display_msg */
1521 /* SUBROUTINE FUNCTION: The correct message called by main is displayed */
1522 /* to standard out or standard error. */
1524 /* INPUT: msg_num (message number to display) */
1525 /* outline (string for replacement parm) */
1529 /* NORMAL EXIT: The correct message called will be displayed to */
1530 /* standard out or standard error. */
1532 /* ERROR EXIT: Display error message corresponding to number */
1533 /* returned in AX. */
1535 /* EXTERNAL REF: SYSDISPMSG */
1537 /**************************************************************************/
1539 void display_msg(msg_num,outline) /* ;AN000;M */
1540 int msg_num ; /* ;AN000;M Message number #define'd */
1541 char *outline ; /* ;AN000;M String for replacemnt parm */
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? */
1550 struct sublist /* ;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 */
1562 switch (msg_num) /* ;AN000;M Which msg to display? */
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 */
1698 switch (msg_num) /* ;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 */
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 */
1789 return ; /* ;AN000;M */
1791 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1792 /**************************************************************************/
1794 /* SUBROUTINE NAME: get_ext_attr */
1796 /* SUBROUTINE FUNCTION: Get the Extended Attributes of the source */
1797 /* file for the copy operation. */
1799 /* INPUT: source_handle */
1800 /* size_buffer (0=get size) */
1802 /* OUTPUT: status (no extended attributes for DOS 4.00) */
1804 /**************************************************************************/
1806 unsigned get_ext_attr(source_handle,size_buffer) /* ;AN000;EA */
1807 unsigned source_handle ; /* ;AN000;EA */
1808 unsigned size_buffer ; /* ;AN000;EA 0 or size returned */
1810 unsigned status ; /* ;AN000;EA */
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 */
1823 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1824 /**************************************************************************/
1826 /* SUBROUTINE NAME: check_appendx_install */
1828 /* SUBROUTINE FUNCTION: Determine if append and correct version is */
1829 /* currently installed. */
1833 /* OUTPUT: status (TRUE or FALSE) */
1835 /**************************************************************************/
1837 unsigned check_appendx_install() /* ;AN000;X */
1839 unsigned status = FALSE ; /* ;AN000;X */
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 */
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 */
1850 return(status) ; /* ;AN000;X */
1852 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1853 /**************************************************************************/
1855 /* SUBROUTINE NAME: check_appendx */
1857 /* SUBROUTINE FUNCTION: Get the append /x status. */
1861 /* OUTPUT: bx (contains append bits set) */
1863 /**************************************************************************/
1865 unsigned check_appendx() /* ;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 */
1871 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1872 /**************************************************************************/
1874 /* SUBROUTINE NAME: set_appendx */
1876 /* SUBROUTINE FUNCTION: Set the append /x status. */
1878 /* INPUT: set_state (turn appendx bit off or reset original) */
1882 /**************************************************************************/
1884 void set_appendx(set_state) /* ;AN000;X */
1885 unsigned set_state ; /* ;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 */
1892 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1893 /**************************************************************************/
1895 /* SUBROUTINE NAME: parser_prep */
1897 /* SUBROUTINE FUNCTION: Initialize all structures for the parser. */
1899 /* INPUT: source (command line string) */
1903 /**************************************************************************/
1905 void parser_prep(source) /* ;AN000;P */
1906 char *source ; /* ;AN000;P Commandline */
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 */
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 */
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 */
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 */
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 */
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 */
1948 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1949 /**************************************************************************/
1951 /* SUBROUTINE NAME: display_exit */
1953 /* SUBROUTINE FUNCTION: Display the message, then terminate the utility.*/
1955 /* INPUT: msg_num (#define'd message to display) */
1956 /* outline (sublist substitution) */
1957 /* error_code (errorlevel return code) */
1961 /**************************************************************************/
1963 void display_exit(msg_num,outline,error_code) /* ;AN000;M */
1964 int msg_num ; /* ;AN000;M Message number #define'd */
1965 char *outline ; /* ;AN000;M */
1966 int error_code ; /* ;AN006; */
1968 display_msg(msg_num,outline) ; /* ;AN000;M First, display the msg */
1969 restore() ; /* ;AN006; */
1970 dexit(error_code) ; /* ;AN000;M Then, terminate utility */
1972 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1973 /**************************************************************************/
1975 /* SUBROUTINE NAME: setup_ctl_brk */
1977 /* SUBROUTINE FUNCTION: Change the CTL BRK vector to point to handler */
1984 /**************************************************************************/
1986 void setup_ctl_brk() /* ;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; */
1996 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
1997 /**************************************************************************/
1999 /* SUBROUTINE NAME: setup_crit_err */
2001 /* SUBROUTINE FUNCTION: Change the critical error vector to point to */
2002 /* the handler routine. */
2008 /**************************************************************************/
2010 void setup_crit_err() /* ;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; */
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; */
2028 /*ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ*/
2029 /**************************************************************************/
2031 /* SUBROUTINE NAME: restore */
2033 /* SUBROUTINE FUNCTION: Restore the original appendx before exiting. */
2039 /**************************************************************************/
2041 void restore() /* ;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; */