summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND/COPY.ASM
diff options
context:
space:
mode:
Diffstat (limited to 'v4.0/src/CMD/COMMAND/COPY.ASM')
-rw-r--r--v4.0/src/CMD/COMMAND/COPY.ASM1001
1 files changed, 1001 insertions, 0 deletions
diff --git a/v4.0/src/CMD/COMMAND/COPY.ASM b/v4.0/src/CMD/COMMAND/COPY.ASM
new file mode 100644
index 0000000..37bb886
--- /dev/null
+++ b/v4.0/src/CMD/COMMAND/COPY.ASM
@@ -0,0 +1,1001 @@
1 page 80,132
2; SCCSID = @(#)copy.asm 1.1 85/05/14
3; SCCSID = @(#)copy.asm 1.1 85/05/14
4TITLE COMMAND COPY routines.
5
6; MODIFICATION HISTORY
7;
8; 11/01/83 EE Added a few lines at the end of SCANSRC2 to get multiple
9; file concatenations (eg copy a.*+b.*+c.*) to work properly.
10; 11/02/83 EE Commented out the code in CPARSE which added drive designators
11; to tokens which begin with path characters so that PARSELINE
12; will work correctly.
13; 11/04/83 EE Commented out the code in CPARSE that considered paren's to be
14; individual tokens. That distinction is no longer needed for
15; FOR loop processing.
16; 11/17/83 EE CPARSE upper case conversion is now flag dependent. Flag is
17; 1 when Cparse is called from COPY.
18; 11/17/83 EE Took out the comment chars around code described in 11/04/83
19; mod. It now is conditional on flag like previous mod.
20; 11/21/83 NP Added printf
21; 12/09/83 EE CPARSE changed to use CPYFLAG to determine when a colon should
22; be added to a token.
23; 05/30/84 MZ Initialize all copy variables. Fix confusion with destclosed
24; NOTE: DestHand is the destination handle. There are two
25; special values: -1 meaning destination was never opened and
26; 0 which means that the destination has been openned and
27; closed.
28; 06/01/84 MZ Above reasoning totally specious. Returned things to normal
29; 06/06/86 EG Change to fix problem of source switches /a and /b getting
30; lost on large and multiple file (wildcard) copies.
31; 06/09/86 EG Change to use xnametrans call to verify that source and
32; destination are not equal.
33
34
35.xlist
36.xcref
37 INCLUDE comsw.asm
38 INCLUDE DOSSYM.INC
39 INCLUDE comseg.asm
40 INCLUDE comequ.asm
41.list
42.cref
43
44
45DATARES SEGMENT PUBLIC BYTE ;AC000;
46 EXTRN VERVAL:WORD
47 EXTRN RSRC_XA_SEG:WORD ;AN030;
48DATARES ENDS
49
50TRANDATA SEGMENT PUBLIC BYTE ;AC000;
51 EXTRN BADCD_ptr:word
52 EXTRN COPIED_ptr:word
53 EXTRN Extend_buf_ptr:word ;AN000;
54 EXTRN Extend_buf_sub:byte ;AN000;
55 EXTRN file_name_ptr:word
56 EXTRN INBDEV_ptr:word ;AC000;
57 EXTRN msg_disp_class:byte ;AN000;
58 EXTRN overwr_ptr:word
59TRANDATA ENDS
60
61TRANSPACE SEGMENT PUBLIC BYTE ;AC000;
62 EXTRN ALLSWITCH:WORD
63 EXTRN ARGC:BYTE
64 EXTRN ASCII:BYTE
65 EXTRN BINARY:BYTE
66 EXTRN BYTCNT:WORD
67 EXTRN CFLAG:BYTE
68 EXTRN comma:byte
69 EXTRN CONCAT:BYTE
70 EXTRN concat_xa:byte ;AN000;
71 EXTRN copy_num:word ;AC000;
72 EXTRN CPDATE:WORD
73 EXTRN CPTIME:WORD
74 EXTRN cpyflag:byte ;AC000;
75 EXTRN CURDRV:BYTE
76 EXTRN DESTBUF:BYTE
77 EXTRN DestClosed:BYTE
78 EXTRN DESTFCB:BYTE
79 EXTRN DESTFCB2:BYTE
80 EXTRN DESTHAND:WORD
81 EXTRN DESTINFO:BYTE
82 EXTRN DESTISDIR:BYTE
83 EXTRN DESTSIZ:BYTE
84 EXTRN DESTSWITCH:WORD
85 EXTRN DESTTAIL:WORD
86 EXTRN DESTVARS:BYTE
87 EXTRN DIRBUF:BYTE
88 EXTRN expand_star:byte
89 EXTRN FILECNT:WORD
90 EXTRN FIRSTDEST:BYTE
91 EXTRN FRSTSRCH:BYTE
92 EXTRN INEXACT:BYTE
93 EXTRN MELCOPY:BYTE
94 EXTRN MELSTART:WORD
95 EXTRN msg_flag:byte ;AN022;
96 EXTRN NOWRITE:BYTE
97 EXTRN NXTADD:WORD
98 EXTRN objcnt:byte
99 EXTRN one_char_val:byte ;AN000;
100 EXTRN parse_last:word ;AN018;
101 EXTRN PLUS:BYTE
102 EXTRN plus_comma:byte
103 EXTRN RDEOF:BYTE
104 EXTRN RESSEG:WORD
105 EXTRN SCANBUF:BYTE
106 EXTRN SDIRBUF:BYTE
107 EXTRN src_xa_size:word ;AN000;
108 EXTRN src_xa_seg:word ;AN000;
109 EXTRN SRCBUF:BYTE
110 EXTRN SRCHAND:WORD
111 EXTRN SRCINFO:BYTE
112 EXTRN SRCISDEV:BYTE
113 EXTRN SRCPT:WORD
114 EXTRN SRCSIZ:BYTE
115 EXTRN SRCTAIL:WORD
116 EXTRN SRCVARS:BYTE
117 EXTRN srcxname:byte
118 EXTRN STARTEL:WORD
119 EXTRN string_ptr_2:word
120 EXTRN TERMREAD:BYTE
121 EXTRN TPA:WORD
122 EXTRN USERDIR1:BYTE
123 EXTRN WRITTEN:WORD
124 EXTRN xa_cp_out:byte ;AN030;
125 EXTRN xa_list_attr:word ;AC030;
126TRANSPACE ENDS
127
128
129; ******************************************
130; COPY CODE
131;
132
133TRANCODE SEGMENT PUBLIC BYTE
134
135 EXTRN CERROR:NEAR
136 EXTRN COPERR:NEAR
137 EXTRN TCOMMAND:NEAR
138
139 PUBLIC COPY
140
141ASSUME CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING
142 break Copy
143assume ds:trangroup,es:trangroup
144
145COPY:
146; First order of buisness is to find out about the destination
147;
148; initialize all internal variables
149;
150 xor ax,ax
151 mov copy_num,ax
152 mov SrcPt,AX
153 mov SrcTail,AX
154 mov CFlag,AL
155 mov NxtAdd,AX
156 mov DestSwitch,AX
157 mov StartEl,AX
158 mov DestTail,AX
159 mov DestClosed,AL
160 mov DestSiz,AL
161 mov SrcSiz,AL
162 mov DestInfo,AL
163 mov SrcInfo,AL
164 mov InExact,AL
165 mov DestVars,AL
166 mov SrcVars,AL
167 mov UserDir1,AL
168 mov NoWrite,AL
169 mov RdEOF,AL
170 mov SrcHand,AX
171 mov CpDate,AX
172 mov CpTime,AX
173 mov xa_list_attr,ax ;AN030; initialize code page to none
174 mov SrcIsDev,AL
175 mov TermRead,AL
176 mov comma,al ;g
177 mov plus_comma,al ;g
178 mov msg_flag,al ;AN022;
179 mov [ALLSWITCH],AX ; no switches
180 mov [ARGC],al ; no arguments
181 mov [PLUS],al ; no concatenation
182 mov [BINARY],al ; Binary not specifically specified
183 mov [ASCII],al ; ASCII not specifically specified
184 mov [FILECNT],ax ; No files yet
185 mov [WRITTEN],ax ; Nothing written yet
186 mov [CONCAT],al ; No concatenation
187 mov [MELCOPY],al ; Not a Mel Hallerman copy
188 mov [concat_xa],al ;AN000; initialize flag for concatenation XA
189 mov MelStart,ax ; Not a Mel Hallerman copy
190 mov word ptr [SCANBUF],ax ; Init buffer
191 mov word ptr [DESTBUF],ax ; Init buffer
192 mov word ptr [SRCBUF],ax ; Init buffer
193 mov word ptr [SDIRBUF],ax ; Init buffer
194 mov word ptr [DIRBUF],ax ; Init buffer
195 mov word ptr [DESTFCB],ax ; Init buffer
196 mov objcnt,al ; Init command line object count
197 dec ax
198 mov DestHand,AX ; destination has never been opened
199 mov [FRSTSRCH],al ; First search call
200 mov [FIRSTDEST],al ; First time
201 mov [DESTISDIR],al ; Don't know about dest
202 mov src_xa_seg,ax ;AN000; initialize attribute segment to -1
203 mov si,81H
204 mov bl,plus_chr ; include '+' as a delimiter
205 inc byte ptr [expand_star] ; want to include * expansion in cparse
206 mov cpyflag,1 ; Turn "CPARSE called from COPY flag" on
207
208DESTSCAN:
209 xor bp,bp ; no switches
210 mov di,offset trangroup:SCANBUF
211 mov parse_last,si ;AN018; save start of parsed string
212 invoke CPARSE
213 PUSHF ; save flags
214 inc objcnt
215 test bh,80H ; A '+' argument?
216 jz NOPLUS ; no
217 mov [PLUS],1 ; yes
218NOPLUS:
219 test bh,1 ; Switch?
220 jz TESTP2 ; no
221
222 test bp,SwitchV ;AN038; Verify requested?
223 jz not_slashv ;AN038; No - set the switch
224 test [allswitch],SwitchV ;AN038; Verify already entered?
225 jz not_slashv ;AN038; No - set the switch
226;AD018; or [allswitch],FBadSwitch ;AN038; Set up bad switch
227 or BP,FBadSwitch ;AN018; Set up bad switch
228
229not_slashv: ;AN038;
230 or [DESTSWITCH],BP ; Yes, assume destination
231 or [ALLSWITCH],BP ; keep tabs on all switches
232
233 test BP,NOT SwitchCopy ;AN018; Bad switch?
234 jz NOT_BAD_SWITCH ;AN018; Switches are okay
235 popf ;AN018; fix up stack
236 mov ax,BadSwt_ptr ;AN018; get "Invalid switch" message number
237 invoke Setup_parse_error_msg ;AN018; setup to print the message
238 jmp CERROR ;AC018; exit
239
240NOT_BAD_SWITCH: ;AN018; switch okay
241 POPF ; get flags back
242 jc CHECKDONE ; Hit CR?
243 jmp short DESTSCAN
244
245TESTP2:
246 POPF ; get flags back
247 jc CHECKDONE ; Hit CR?
248 test bh,80H ; Plus?
249 jnz GOTPLUS ; Yes, not a separate arg
250 inc [ARGC] ; found a real arg
251GOTPLUS:
252 push SI
253 mov ax,[STARTEL]
254 mov SI,offset trangroup:SCANBUF ; Adjust to copy
255 sub ax,SI
256 mov DI,offset trangroup:DESTBUF
257 add ax,DI
258 mov [DESTTAIL],AX
259 mov [DESTSIZ],cl ; Save its size
260 inc cx ; Include the nul
261 rep movsb ; Save potential destination
262 mov [DESTINFO],bh ; Save info about it
263 mov [DESTSWITCH],0 ; reset switches
264 pop SI
265 jmp DESTSCAN ;AC018; keep going
266
267CHECKDONE:
268 cmp plus,1 ; If a statement like "copy file+" is
269 jnz cdcont ; entered, complain about it.
270 cmp argc,1
271 jnz cdcont
272 cmp objcnt,2
273 jnz cdcont
274 mov dx,offset trangroup:overwr_ptr
275 jmp coperr
276cdcont:
277 mov al,[PLUS]
278 mov [CONCAT],al ; PLUS -> Concatination
279 shl al,1
280 shl al,1
281 mov [INEXACT],al ; CONCAT -> inexact copy
282 mov al,[ARGC]
283 or al,al ; Good number of args?
284 jnz TRY_TOO_MANY ;AC000; there are args, see if too many
285 MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
286 mov Extend_Buf_ptr,LessArgs_ptr ;AN000; get "Required parameters missing" message number
287 jmp short cerror_parsej ;AN000; exit
288
289TRY_TOO_MANY:
290 cmp al,2
291 jbe ACOUNTOK
292 MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
293 mov Extend_Buf_ptr,MoreArgs_ptr ;AN000; get "Too many parameters" message number
294
295CERROR_PARSEJ:
296 mov msg_disp_class,parse_msg_class ;AN000; set up parse error msg class
297CERROR4J:
298 jmp CERROR ; no, too many
299
300ACOUNTOK:
301 mov bp,offset trangroup:DESTVARS
302 cmp al,1
303 jnz GOT2ARGS
304 mov al,[CURDRV] ; Dest is default drive:*.*
305 add al,capital_A
306 mov ah,':'
307 mov [bp.SIZ],2
308 mov di,offset trangroup:DESTBUF
309 stosw
310 mov [DESTSWITCH],0 ; no switches on dest
311 mov [bp.INFO],2 ; Flag dest is ambig
312 mov [bp.ISDIR],0 ; Know destination specs file
313 invoke SETSTARS
314GOT2ARGS:
315 cmp [bp.SIZ],2
316 jnz NOTSHORTDEST
317 mov al,':'
318 cmp [DESTBUF+1],al
319 jnz NOTSHORTDEST ; Two char file name
320 or [bp.INFO],2 ; Know dest is d:
321 mov di,offset trangroup:DESTBUF + 2
322 mov [bp.ISDIR],0 ; Know destination specs file
323 invoke SETSTARS
324NOTSHORTDEST:
325 mov di,[bp.TTAIL]
326 cmp byte ptr [DI],0
327 jnz CHKSWTCHES
328 mov dx,offset trangroup:BADCD_ptr
329 mov al,':'
330 cmp byte ptr [DI-2],al
331 jnz CERROR4J ; Trailing '/' error
332 mov [bp.ISDIR],2 ; Know destination is d:/
333 or [bp.INFO],6
334 invoke SETSTARS
335CHKSWTCHES:
336;AD018; mov ax,[ALLSWITCH]
337;AD018; test ax,NOT SwitchCopy
338;AD018; jz NOT_BAD_SWITCH ;AN000; Switches are okay
339;AD018; MOV DX,OFFSET TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
340;AD018; mov Extend_Buf_ptr,BadSwt_ptr ;AN000; get "Invalid switch" message number
341;AD018; jmp short CERROR_PARSEJ ;AC000; Switch specified which is not known
342
343; Now know most of the information needed about the destination
344
345;AD018; NOT_BAD_SWITCH:
346if not ibmcopyright
347 mov ax, [allswitch] ; Which switches were requested? Hmmm?
348endif
349 TEST AX,SwitchV ; Verify requested?
350 JZ NOVERIF ; No
351 MOV AH,GET_VERIFY_ON_WRITE
352 INT int_command ; Get current setting
353 PUSH DS
354 MOV DS,[RESSEG]
355ASSUME DS:RESGROUP
356 XOR AH,AH
357 MOV [VERVAL],AX ; Save current setting
358 POP DS
359ASSUME DS:TRANGROUP
360 MOV AX,(SET_VERIFY_ON_WRITE SHL 8) OR 1 ; Set verify
361 INT int_command
362NOVERIF:
363 xor bp,bp ; no switches
364 mov si,81H
365 mov bl,plus_chr ; include '+' as a delimiter
366SCANFSRC:
367 mov di,offset trangroup:SCANBUF
368 invoke CPARSE ; Parse first source name
369 test bh,1 ; Switch?
370 jnz SCANFSRC ; Yes, try again
371 or [DESTSWITCH],bp ; Include copy wide switches on dest
372 test bp,SwitchB
373 jnz NOSETCASC ; Binary explicit
374 cmp [CONCAT],0
375 JZ NOSETCASC ; Not Concat
376 mov [ASCII],SwitchA ; Concat -> ASCII copy if no B switch
377 mov [concat_xa],do_xa ;AN000; set up to do XA only on first file
378NOSETCASC:
379 call source_set
380 call FRSTSRC
381 jmp FIRSTENT
382
383PUBLIC EndCopy
384ENDCOPY:
385 CALL CLOSEDEST
386ENDCOPY2:
387 call deallocate_src_xa ;AN030; deallocate xa segment
388 invoke free_tpa ;AN000; Make sure work area
389 invoke alloc_tpa ;AN000; is reset properly
390 MOV DX,OFFSET TRANGROUP:COPIED_ptr
391 MOV SI,[FILECNT]
392 mov copy_num,si
393 invoke std_printf
394 JMP TCOMMAND ; Stack could be messed up
395
396SRCNONEXIST:
397 cmp [CONCAT],0
398 jnz NEXTSRC ; If in concat mode, ignore error
399 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
400 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
401 mov Extend_Buf_ptr,error_file_not_found ;AN000; get message number in control block
402 mov string_ptr_2,offset trangroup:srcbuf ;AC046; get address of failed string
403 mov Extend_buf_sub,one_subst ;AC046; put number of subst in control block
404 jmp COPERR
405
406SOURCEPROC:
407 call source_set
408 cmp [CONCAT],0
409 jnz LEAVECFLAG ; Leave CFLAG if concatination
410FRSTSRC:
411 xor ax,ax
412 mov [CFLAG],al ; Flag destination not created
413 mov [NXTADD],ax ; Zero out buffer
414 mov DestClosed,AL
415LEAVECFLAG:
416 mov [SRCPT],SI ; remember where we are
417 mov di,offset trangroup:USERDIR1
418 mov bp,offset trangroup:SRCVARS
419 invoke BUILDPATH ; Figure out everything about the source
420 mov si,[SRCTAIL] ; Create the search FCB
421 return
422
423NEXTSRC:
424 cmp [PLUS],0
425 jnz MORECP
426ENDCOPYJ2:
427 jmp ENDCOPY ; Done
428MORECP:
429 xor bp,bp ; no switches
430 mov si,[SRCPT]
431 mov bl,plus_chr ; include '+' as a delimiter
432SCANSRC:
433 mov di,offset trangroup:SCANBUF
434 invoke CPARSE ; Parse first source name
435 JC EndCopyJ2 ; if error, then end (trailing + case)
436 test bh,80H
437 jz ENDCOPYJ2 ; If no '+' we're done
438 test bh,1 ; Switch?
439 jnz SCANSRC ; Yes, try again
440 call SOURCEPROC
441 cmp comma,1 ;g was +,, found last time?
442 jnz nostamp ;g no - try for a file
443 mov plus_comma,1 ;g yes - set flag
444 jmp srcnonexist ;g we know we won't find it
445nostamp: ;g
446 mov plus_comma,0 ;g reset +,, flag
447FIRSTENT:
448 mov di,FCB
449 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
450 INT int_command
451 CMP BYTE PTR [SI],0 ; parse everything?
452 JNZ SrchDone ; no, error, simulate no more search
453 mov ax,word ptr [SRCBUF] ; Get drive
454 cmp ah,':'
455 jz DRVSPEC1
456 mov al,'@'
457DRVSPEC1:
458 or al,20h
459 sub al,60h
460 mov ds:[FCB],al
461 mov ah,DIR_SEARCH_FIRST
462 call SEARCH
463SrchDone:
464 pushf ; Save result of search
465 invoke RESTUDIR1 ; Restore users dir
466 popf
467 jz NEXTAMBIG0
468 jmp SRCNONEXIST ; Failed
469NEXTAMBIG0:
470 xor al,al
471 xchg al,[FRSTSRCH]
472 or al,al
473 jz NEXTAMBIG
474SETNMEL:
475 mov cx,12
476 mov di,OFFSET TRANGROUP:SDIRBUF
477 mov si,OFFSET TRANGROUP:DIRBUF
478 rep movsb ; Save very first source name
479NEXTAMBIG:
480 xor al,al
481 mov [NOWRITE],al ; Turn off NOWRITE
482 mov di,[SRCTAIL]
483 mov si,offset trangroup:DIRBUF + 1
484 invoke FCB_TO_ASCZ ; SRCBUF has complete name
485MELDO:
486 cmp [CONCAT],0
487 jnz SHOWCPNAM ; Show name if concat
488 test [SRCINFO],2 ; Show name if multi
489 jz DOREAD
490SHOWCPNAM:
491 mov dx,offset trangroup:file_name_ptr
492 invoke std_printf
493 invoke CRLF2
494DOREAD:
495 call DOCOPY
496 cmp [CONCAT],0
497 jnz NODCLOSE ; If concat, do not close
498 call CLOSEDEST ; else close current destination
499 jc NODCLOSE ; Concat flag got set, close didn't really happen
500 mov [CFLAG],0 ; Flag destination not created
501NODCLOSE:
502 cmp [CONCAT],0 ; Check CONCAT again
503 jz NOFLUSH
504 invoke FLSHFIL ; Flush output between source files on
505 ; CONCAT so LOSTERR stuff works
506 ; correctly
507 TEST [MELCOPY],0FFH
508 jz NOFLUSH
509 jmp SHORT DOMELCOPY
510
511NOFLUSH:
512 call SEARCHNEXT ; Try next match
513 jnz NEXTSRCJ ; Finished with this source spec
514 mov [DESTCLOSED],0 ; Not created or concat ->...
515 jmp NEXTAMBIG ; Do next ambig
516
517DOMELCOPY:
518 cmp [MELCOPY],0FFH
519 jz CONTMEL
520 mov SI,[SRCPT]
521 mov [MELSTART],si
522 mov [MELCOPY],0FFH
523CONTMEL:
524 xor BP,BP
525 mov si,[SRCPT]
526 mov bl,plus_chr
527SCANSRC2:
528 mov di,OFFSET TRANGROUP:SCANBUF
529 invoke CPARSE
530 test bh,80H
531 jz NEXTMEL ; Go back to start
532 test bh,1 ; Switch ?
533 jnz SCANSRC2 ; Yes
534 call SOURCEPROC
535 invoke RESTUDIR1
536 mov di,OFFSET TRANGROUP:DESTFCB2
537 mov ax,PARSE_FILE_DESCRIPTOR SHL 8
538 INT int_command
539 mov bx,OFFSET TRANGROUP:SDIRBUF + 1
540 mov si,OFFSET TRANGROUP:DESTFCB2 + 1
541 mov di,[SRCTAIL]
542 invoke BUILDNAME
543 cmp [CONCAT],0 ; Are we concatenating?
544 jz meldoj ; No, continue.
545;
546; Yes, turn off nowrite because this part of the code is only reached after
547; the first file has been dealt with.
548;
549 mov [NOWRITE],0
550meldoj:
551 jmp MELDO
552
553NEXTSRCJ:
554 jmp NEXTSRC
555
556NEXTMEL:
557 call CLOSEDEST
558 xor ax,ax
559 mov [CFLAG],al
560 mov [NXTADD],ax
561 mov [DESTCLOSED],al
562 mov si,[MELSTART]
563 mov [SRCPT],si
564 call SEARCHNEXT
565 jz SETNMELJ
566 jmp ENDCOPY2
567SETNMELJ:
568 jmp SETNMEL
569
570SEARCHNEXT:
571 MOV AH,DIR_SEARCH_NEXT
572 TEST [SRCINFO],2
573 JNZ SEARCH ; Do search-next if ambig
574 OR AH,AH ; Reset zero flag
575 return
576SEARCH:
577 PUSH AX
578 MOV AH,SET_DMA
579 MOV DX,OFFSET TRANGROUP:DIRBUF
580 INT int_command ; Put result of search in DIRBUF
581 POP AX ; Restore search first/next command
582 MOV DX,FCB
583 INT int_command ; Do the search
584 OR AL,AL
585 return
586
587DOCOPY:
588 mov si,offset trangroup:SRCBUF ;g do name translate of source
589 mov di,offset trangroup:SRCXNAME ;g save for name comparison
590 mov ah,xnametrans ;g
591 int int_command ;g
592
593 mov [RDEOF],0 ; No EOF yet
594
595 MOV AX,EXTOPEN SHL 8 ;AC000; open the file
596 mov bx,read_open_mode ;AN000; get open mode for COPY
597 xor cx,cx ;AN000; no special files
598 mov dx,read_open_flag ;AN000; set up open flags
599 mov di,-1 ;AN030; no parameter list
600 INT int_command
601
602 jnc OpenOK
603;
604; Bogosity: IBM wants us to issue Access denied in this case. THey asked
605; for it...
606;
607 jmp error_on_source ;AC022; clean up and exit
608
609OpenOK:
610 mov bx,ax ; Save handle
611 mov [SRCHAND],bx ; Save handle
612 mov ax,(FILE_TIMES SHL 8)
613 INT int_command
614 jc src_cp_error ;AN022; If error, exit
615 mov [CPDATE],dx ; Save DATE
616 mov [CPTIME],cx ; Save TIME
617
618 mov cx,xa_list_attr ;AN000; get old code page in cx
619 push cx ;AN000; save old attribute
620 mov xa_list_attr,0 ;AN000; initialize code page
621
622 mov ax,(file_times SHL 8)+get_XA ;AC030; get extended attribute size
623 mov si,-1 ;AN030; no querylist
624 xor cx,cx ;AN030; indicate we want size
625 int int_command ;AC000;
626 jc src_cp_error ;AN022; If error, exit
627 mov src_xa_size,cx ;AN000; save size
628 cmp cx,0 ;AN000; are there any?
629 pop cx ;AN000; get old attribute
630 jz no_cp_get ;AN030; no - don't get attributes
631
632 push cx ;AN030; save old code page
633 invoke get_file_code_page_tag ;AN000; get file's code page
634 pop cx ;AN030 retrieve old code page
635 jnc no_cp_get ;AN000; no error - continue
636src_cp_error: ;AN022;
637 jmp error_on_source ;AC022; and exit
638
639no_cp_get:
640 cmp [concat],0 ;AN000; are we doing concatenation
641 jz get_src_xa ;AN000; no get source extended attrib
642 cmp [concat_xa],do_xa ;AN000; is this the first file?
643 jz get_src_xa ;AN000; yes - get extended attributes
644 cmp cx,xa_list_attr ;AN000; no - see if code pages match
645 jz no_copy_xa_jmp ;AN000; code pages match - continue
646 mov xa_list_attr,inv_cp_tag ;AN000; set invalid code page tag
647no_copy_xa_jmp: ;AC022;
648 jmp no_copy_xa ;AN000; don't get extended attributes
649
650get_src_xa:
651 call deallocate_src_xa ;AN030; deallocate any existing XA segment
652 cmp src_xa_size,0 ;AN000; are there any extended attributes?
653 jz no_copy_xa_jmp ;AC022; nothing there - don't allocate memory
654 push bx ;AN000; save handle
655 invoke free_tpa ;AN000; need to make free memory, first
656 mov bx,src_xa_size ;AN000; get bytes (size of XA) into bx
657 mov cl,4 ;AN000; divide bytes by 16 to convert
658 shr bx,cl ;AN000; to paragraphs
659 inc bx ;AN000; round up
660 mov ax,(alloc SHL 8) ;AN000; allocate memory for XA
661 int int_command ;AN000;
662 pushf ;AN000; save flags
663 mov [src_xa_seg], AX ;AN000; save new segment
664 push ds ;AN030; get resident segment
665 mov ds,[resseg] ;AN030; and save copy of xa
666 assume ds:resgroup ;AN030; segment in resident
667 mov [rsrc_xa_seg],ax ;AN030; in case user breaks
668 pop ds ;AN030; out or has critical
669 assume ds:trangroup ;AN030; error
670 invoke alloc_tpa ;AN000; reallocate the work area
671 popf ;AN000; restore flags
672 pop bx ;AN000; restore handle
673 jnc Alloc_for_xa_okay ;AN000; no carry - everything okay
674 call closesrc ;AN000; close the source file
675 mov msg_disp_class,ext_msg_class ;AN000; set up extended error msg class
676 mov dx,offset TranGroup:Extend_Buf_ptr ;AC000; get extended message pointer
677 mov Extend_Buf_ptr,error_not_enough_memory ;AN000; get message number in control block
678 jmp cerror ;AN000; exit
679
680Alloc_for_xa_okay:
681
682 mov ax,(file_times SHL 8)+get_XA ;AN000; get extended attributes
683 push es ;AN000; save es
684 mov es,[src_xa_seg] ;AN000; get segment for XA list
685 xor di,di ;AN000; offset of return list
686 mov si,-1 ;AN030; get all attributes
687 mov cx,[src_xa_size] ;AN000; get size of list
688 int int_command ;AN000; get all the attributes
689 pop es ;AN000; restore es
690 jnc no_copy_xa ;AC022; no error - continue
691
692error_on_source: ;AN022; we have a BAD error
693 invoke set_ext_error_msg ;AN022; set up the error message
694 mov string_ptr_2,offset trangroup:srcbuf ;AN022; get address of failed string
695 mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block
696 invoke std_Eprintf ;AN022; print it
697 cmp [srchand],0 ;AN022; did we open the file?
698 jz no_close_src ;AN022; no - don't close
699 call closesrc ;AN022; clean up
700no_close_src: ;AN022;
701 cmp [cflag],0 ;AN022; was destination created?
702 jz endcopyj3 ;AN022; no - just cleanup and exit
703 jmp endcopy ;AN022; clean up concatenation and exit
704endcopyj3: ;AN022;
705 jmp endcopy2 ;AN022;
706no_copy_xa:
707 mov bx,[srchand] ;AN022; get handle back
708 mov ax,(IOCTL SHL 8)
709 INT int_command ; Get device stuff
710 and dl,devid_ISDEV
711 mov [SRCISDEV],dl ; Set source info
712 jz COPYLP ; Source not a device
713 cmp [BINARY],0
714 jz COPYLP ; ASCII device OK
715 mov dx,offset trangroup:INBDEV_ptr ; Cannot do binary input
716 jmp COPERR
717
718COPYLP:
719 mov bx,[SRCHAND]
720 mov cx,[BYTCNT]
721 mov dx,[NXTADD]
722 sub cx,dx ; Compute available space
723 jnz GOTROOM
724 invoke FLSHFIL
725 CMP [TERMREAD],0
726 JNZ CLOSESRC ; Give up
727 mov cx,[BYTCNT]
728GOTROOM:
729 push ds
730 mov ds,[TPA]
731ASSUME DS:NOTHING
732 mov ah,READ
733 INT int_command
734 pop ds
735ASSUME DS:TRANGROUP
736 jc error_on_source ;AC022; Give up if error
737 mov cx,ax ; Get count
738 jcxz CLOSESRC ; No more to read
739 cmp [SRCISDEV],0
740 jnz NOTESTA ; Is a device, ASCII mode
741 cmp [ASCII],0
742 jz BINREAD
743NOTESTA:
744 MOV DX,CX
745 MOV DI,[NXTADD]
746 MOV AL,1AH
747 PUSH ES
748 MOV ES,[TPA]
749 REPNE SCASB ; Scan for EOF
750 POP ES
751 JNZ USEALL
752 INC [RDEOF]
753 INC CX
754USEALL:
755 SUB DX,CX
756 MOV CX,DX
757BINREAD:
758 ADD CX,[NXTADD]
759 MOV [NXTADD],CX
760 CMP CX,[BYTCNT] ; Is buffer full?
761 JB TESTDEV ; If not, we may have found EOF
762 invoke FLSHFIL
763 CMP [TERMREAD],0
764 JNZ CLOSESRC ; Give up
765 JMP SHORT COPYLP
766
767TESTDEV:
768 cmp [SRCISDEV],0
769 JZ CLOSESRC ; If file then EOF
770 CMP [RDEOF],0
771 JZ COPYLP ; On device, go till ^Z
772CLOSESRC:
773 mov bx,[SRCHAND]
774 mov ah,CLOSE
775 INT int_command
776 return
777
778;
779; We are called to close the destination. We need to note whether or not
780; there is any internal data left to be flushed out.
781;
782CLOSEDEST:
783 cmp [DESTCLOSED],0
784 retnz ; Don't double close
785 MOV AL,BYTE PTR [DESTSWITCH]
786 invoke SETASC ; Check for B or A switch on destination
787 JZ BINCLOS
788 MOV BX,[NXTADD]
789 CMP BX,[BYTCNT] ; Is memory full?
790 JNZ PUTZ
791 invoke TRYFLUSH ; Make room for one lousy byte
792 jz NOCONC
793CONCHNG: ; Concat flag changed on us
794 stc
795 return
796NOCONC:
797 XOR BX,BX
798PUTZ:
799 PUSH DS
800 MOV DS,[TPA]
801 MOV WORD PTR [BX],1AH ; Add End-of-file mark (Ctrl-Z)
802 POP DS
803 INC [NXTADD]
804 MOV [NOWRITE],0 ; Make sure our ^Z gets written
805 MOV AX,[WRITTEN]
806 ADD AX,[NXTADD]
807 JC BINCLOS ; > 1
808 CMP AX,1
809 JZ FORGETITJ ; WRITTEN = 0 NXTADD = 1 (the ^Z)
810BINCLOS:
811 invoke TRYFLUSH
812 jnz CONCHNG
813 cmp [WRITTEN],0
814ForgetItJ:
815 jnz no_forget ;AC000; Wrote something
816 jmp FORGETIT ;AC000; Never wrote nothing
817no_forget:
818 MOV BX,[DESTHAND]
819 MOV CX,[CPTIME]
820 MOV DX,[CPDATE]
821 CMP [INEXACT],0 ; Copy not exact?
822 JZ DODCLOSE ; If no, copy date & time
823 MOV AH,GET_TIME
824 INT int_command
825 SHL CL,1
826 SHL CL,1 ; Left justify min in CL
827 SHL CX,1
828 SHL CX,1
829 SHL CX,1 ; hours to high 5 bits, min to 5-10
830 SHR DH,1 ; Divide seconds by 2 (now 5 bits)
831 OR CL,DH ; And stick into low 5 bits of CX
832 PUSH CX ; Save packed time
833 MOV AH,GET_DATE
834 INT int_command
835 SUB CX,1980
836 XCHG CH,CL
837 SHL CX,1 ; Year to high 7 bits
838 SHL DH,1 ; Month to high 3 bits
839 SHL DH,1
840 SHL DH,1
841 SHL DH,1
842 SHL DH,1 ; Most sig bit of month in carry
843 ADC CH,0 ; Put that bit next to year
844 OR DL,DH ; Or low three of month into day
845 MOV DH,CH ; Get year and high bit of month
846 POP CX ; Get time back
847DODCLOSE:
848 CMP BX,0
849 JLE CloseDone
850 MOV AX,(FILE_TIMES SHL 8) OR 1
851 INT int_command ; Set date and time
852 jc xa_cleanup_err ;AN022; handle error
853
854 mov ax,(file_times SHL 8)+set_XA ;AN000; set code page
855 mov di,offset trangroup:xa_cp_out ;AC030; offset of attr list
856 int int_command ;AN000;
857 jc xa_cleanup_err ;AN030; exit if error
858
859;
860; See if the destination has *anything* in it. If not, just close and delete
861; it.
862;
863no_xa_cleanup_err:
864 mov ax,(lseek shl 8) + 2 ; seek to EOF
865 xor dx,dx
866 mov cx,dx
867 int 21h
868;
869; DX:AX is file size
870;
871 or dx,ax
872 pushf
873 mov ax,(IOCTL SHL 8) + 0 ; get the destination attributes
874 int 21h
875 push dx ; save them away
876 MOV AH,CLOSE
877 INT int_command
878 pop dx
879 jnc close_cont ;AN022; handle error on close
880 popf ;AN022; get the flags back
881xa_cleanup_err: ;AN022;
882 call cleanuperr ;AN022; attempt to delete the target
883 call DestDelete ;AN022; attempt to delete the target
884 jmp short fileclosed ;AN022; close the file
885close_cont: ;AN022; no error - continue
886 popf
887 jnz CloseDone
888 test dx,80h ; is the destination a device?
889 jnz CloseDone ; yes, copy succeeded
890 call DestDelete
891 jmp short FileClosed
892CloseDone:
893 INC [FILECNT]
894FileClosed:
895 INC [DESTCLOSED]
896RET50:
897 CLC
898 return
899
900
901FORGETIT:
902 MOV BX,[DESTHAND]
903 CALL DODCLOSE ; Close the dest
904 call DestDelete
905 MOV [FILECNT],0 ; No files transferred
906 JMP RET50
907
908DestDelete:
909 MOV DX,OFFSET TRANGROUP:DESTBUF
910 MOV AH,UNLINK
911 INT int_command ; And delete it
912 return
913
914source_set proc near
915
916 push SI
917 mov ax,[STARTEL]
918 mov SI,offset trangroup:SCANBUF ; Adjust to copy
919 sub ax,SI
920 mov DI,offset trangroup:SRCBUF
921 add ax,DI
922 mov [SRCTAIL],AX
923 mov [SRCSIZ],cl ; Save its size
924 inc cx ; Include the nul
925 rep movsb ; Save this source
926 mov [SRCINFO],bh ; Save info about it
927 pop SI
928 mov ax,bp ; Switches so far
929 invoke SETASC ; Set A,B switches accordingly
930 invoke SWITCH ; Get any more switches on this arg
931 invoke SETASC ; Set
932 return
933
934source_set endp
935
936
937;****************************************************************
938;*
939;* ROUTINE: Cleanuperr
940;*
941;* FUNCTION: Issues extended error message for destination
942;* if not alreay issued
943;*
944;* INPUT: return from INT 21
945;*
946;* OUTPUT: none
947;*
948;****************************************************************
949
950cleanuperr proc near ;AN022;
951
952 cmp msg_flag,0 ;AN022; have we already issued a message?
953 jnz cleanuperr_cont ;AN022; yes - don't issue duplicate error
954 invoke set_ext_error_msg ;AN022; set up error message
955 mov string_ptr_2,offset trangroup:destbuf ;AN022; get address of failed string
956 mov Extend_buf_sub,one_subst ;AN022; put number of subst in control block
957 invoke std_eprintf ;AN022; issue the error message
958cleanuperr_cont: ;AN022;
959
960 ret ;AN022; return to caller
961cleanuperr endp ;AN022;
962
963;****************************************************************
964;*
965;* ROUTINE: Deallocate_Src_XA
966;*
967;* FUNCTION: Deallocates source extended attribute segment
968;* and resets both resident and transient variables.
969;*
970;*
971;* INPUT: none
972;*
973;* OUTPUT: none
974;*
975;****************************************************************
976
977Deallocate_Src_XA proc near ;AN030;
978
979 cmp [src_xa_seg],no_xa_seg ;AN030; has any XA segment been allocated
980 jz no_src_xa ;AN030; no - continue
981 push es ;AN030;
982 mov es,src_xa_seg ;AN030; yes - free it
983 mov ax,(Dealloc SHL 8) ;AN030; Deallocate memory call
984 int int_command ;AN030;
985 pop es ;AN030;
986 mov [src_xa_seg],no_xa_seg ;AN030; reset to no segment
987 push ds ;AN030; reinitialize resident
988 mov ds,[resseg] ;AN030; copy of xa segment
989 assume ds:resgroup ;AN030;
990 mov [rsrc_xa_seg],no_xa_seg ;AN030; reset to no segment
991 pop ds ;AN030;
992 assume ds:trangroup ;AN030;
993no_src_xa: ;AN030;
994
995 ret ;AN030; return to caller
996Deallocate_Src_XA endp ;AN030;
997
998
999TRANCODE ENDS
1000 END
1001 \ No newline at end of file