summaryrefslogtreecommitdiff
path: root/v4.0/src/CMD/COMMAND/COPYPR2.ASM
blob: 2913cabfc2c2bc3e7d92e86fb24a571a6a842009 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
 page 80,132
;	SCCSID = @(#)copypr2.asm	1.1 85/05/14
;	SCCSID = @(#)copypr2.asm	1.1 85/05/14
	INCLUDE comsw.asm

.xlist
.xcref
	INCLUDE DOSSYM.INC
	INCLUDE comseg.asm
	INCLUDE comequ.asm
.list
.cref


TRANDATA	SEGMENT PUBLIC BYTE	;AC000;
	EXTRN	FulDir_ptr:word 	;AN052;
TRANDATA ENDS

TRANSPACE	SEGMENT PUBLIC BYTE	;AC000;
	EXTRN	ASCII:BYTE
	EXTRN	BINARY:BYTE
	EXTRN	CONCAT:BYTE
	EXTRN	DESTBUF:BYTE
	EXTRN	DESTFCB:BYTE
	EXTRN	DESTINFO:BYTE
	EXTRN	DESTISDIR:BYTE
	EXTRN	DESTTAIL:WORD
	EXTRN	DESTVARS:BYTE
	EXTRN	DIRBUF:BYTE
	EXTRN	DIRCHAR:BYTE
	EXTRN	FIRSTDEST:BYTE
	EXTRN	INEXACT:BYTE
	EXTRN	MELCOPY:BYTE
	EXTRN	NXTADD:WORD
	EXTRN	PLUS:BYTE
	EXTRN	SDIRBUF:BYTE
	EXTRN	SRCINFO:BYTE
	EXTRN	srcxname:byte
	EXTRN	TPA:WORD
	EXTRN	trgxname:byte
	EXTRN	USERDIR1:BYTE
TRANSPACE	ENDS

TRANCODE	SEGMENT PUBLIC BYTE

	EXTRN	BADPATH_ERR:NEAR	;AN022;
	EXTRN	COPERR:NEAR		;AN052;
	EXTRN	EXTEND_SETUP:NEAR	;AN022;

	PUBLIC	BUILDPATH
	PUBLIC	SETSTARS
	PUBLIC	SETASC

ASSUME	CS:TRANGROUP,DS:TRANGROUP,ES:TRANGROUP,SS:NOTHING

SETASC:
;
; Given switch vector in AX,
;	Set ASCII switch if A is set
;	Clear ASCII switch if B is set
;	BINARY set if B specified
;	Leave ASCII unchanged if neither or both are set
; Also sets INEXACT if ASCII is ever set. AL = ASCII on exit, flags set
;
	AND	AL,SwitchA+SwitchB
	JPE	LOADSW				; PE means both or neither are set
	PUSH	AX
	AND	AL,SwitchB
	MOV	[BINARY],AL
	POP	AX
	AND	AL,SwitchA
	MOV	[ASCII],AL
	OR	[INEXACT],AL

LOADSW:
	MOV	AL,[ASCII]
	OR	AL,AL
	return

public builddest
BUILDDEST:
	cmp	[DESTISDIR],-1
	jnz	KNOWABOUTDEST			; Already done the figuring
	MOV	DI,OFFSET TRANGROUP:USERDIR1
	mov	bp,offset trangroup:DESTVARS
	call	BUILDPATH
	invoke	RESTUDIR1

; Now know all about the destination

KNOWABOUTDEST:
	xor	al,al
	xchg	al,[FIRSTDEST]
	or	al,al
	jnz	FIRSTDST
	jmp	NOTFIRSTDEST

FIRSTDST:
	mov	si,[DESTTAIL]			; Create an FCB of the original DEST
	mov	di,offset trangroup:DESTFCB
	mov	ax,PARSE_FILE_DESCRIPTOR SHL 8
	INT	int_command
	CMP	BYTE PTR [SI],0
	JZ	GoodParse
;AD052; MOV	BYTE PTR [DI+1],"|"             ; must be illegal file name character
	mov	dx,offset trangroup:fuldir_ptr	;AN052; Issue "File creation error"
	jmp	coperr				;AN052;

GoodParse:
	mov	ax,word ptr [DESTBUF]		; Get drive
	cmp	ah,':'
	jz	DRVSPEC4
	mov	al,'@'

DRVSPEC4:
	MOV	CL,[ASCII]			; Save current ASCII setting
	or	al,20h
	sub	al,60h
	mov	[DESTFCB],al
	mov	al,[DESTINFO]
	mov	ah,[SRCINFO]
	and	ax,0202H
	or	al,al
	jz	NOTMELCOPY
	cmp	al,ah
	jnz	NOTMELCOPY
	cmp	[PLUS],0
	jz	NOTMELCOPY
	inc	[MELCOPY]			; ambig source, ambig dest, and pluses
	xor	al,al
	jmp	short SETCONC

NOTMELCOPY:
	xor	al,2				; al=2 if unambig dest, =0 if ambig dest
	and	al,ah
	shr	al,1				; al=1 if unambig dest AND ambig sorce
						;   Implies concatenation
SETCONC:
	or	al,[PLUS]			; al=1 if concat
	mov	[CONCAT],al
	shl	al,1
	shl	al,1
	mov	[INEXACT],al			; Concat -> inexact copy
	cmp	[BINARY],0
	jnz	NOTFIRSTDEST			; Binary explicitly given, all OK
	mov	[ASCII],al			; Concat -> ASCII
	or	cl,cl
	jnz	NOTFIRSTDEST			; ASCII flag set before, DATA read correctly
	or	al,al
	JZ	NOTFIRSTDEST			; ASCII flag did not change states
;
; At this point there may already be binary read data in the read buffer.
; We need to find the first ^Z (if there is one) and trim the amount
; of data in the buffer correctly.
;
	MOV	CX,[NXTADD]
	JCXZ	NOTFIRSTDEST			; No data, everything OK
	MOV	AL,1AH
	PUSH	ES
	XOR	DI,DI
	MOV	ES,[TPA]
	REPNE	SCASB				; Scan for EOF
	POP	ES
	JNZ	NOTFIRSTDEST			; No ^Z in buffer, everything OK
	DEC	DI				; Point at ^Z
	MOV	[NXTADD],DI			; New buffer

NOTFIRSTDEST:
	mov	bx,offset trangroup:DIRBUF+1	; Source of replacement chars
	cmp	[CONCAT],0
	jz	GOTCHRSRC			; Not a concat
	mov	bx,offset trangroup:SDIRBUF+1	; Source of replacement chars

GOTCHRSRC:
	mov	si,offset trangroup:DESTFCB+1	; Original dest name
	mov	di,[DESTTAIL]			; Where to put result

public buildname
BUILDNAME:
	mov	cx,8

BUILDMAIN:
	lodsb
	cmp	al,'?'
	jnz	NOTAMBIG
	mov	al,byte ptr [BX]

NOTAMBIG:
	cmp	al,' '
	jz	NOSTORE
	stosb

NOSTORE:
	inc	bx
	loop	BUILDMAIN
	mov	cl,3
	mov	al,' '
	cmp	byte ptr [SI],al
	jz	ENDDEST 			; No extension
	mov	al,dot_chr
	stosb

BUILDEXT:
	lodsb
	cmp	al,'?'
	jnz	NOTAMBIGE
	mov	al,byte ptr [BX]

NOTAMBIGE:
	cmp	al,' '
	jz	NOSTOREE
	stosb

NOSTOREE:
	inc	bx
	loop	BUILDEXT
ENDDEST:
	xor	al,al
	stosb					; NUL terminate
	return

BUILDPATH:
	test	[BP.INFO],2
	jnz	NOTPFILE			; If ambig don't bother with open
	mov	dx,bp
	add	dx,BUF				; Set DX to spec

	push	di				;AN000;
	MOV	AX,EXTOPEN SHL 8		;AC000; open the file
	mov	bx,read_open_mode		;AN000; get open mode for COPY
	xor	cx,cx				;AN000; no special files
	mov	si,dx				;AN030; get file name offset
	mov	di,-1				;AN030; no parm list
	mov	dx,read_open_flag		;AN000; set up open flags
	INT	int_command
	pop	di				;AN000;
	jnc	pure_file			;AN022; is pure file
	invoke	get_ext_error_number		;AN022; get the extended error
	cmp	ax,error_file_not_found 	;AN022; if file not found - okay
	jz	notpfile			;AN022;
	cmp	ax,error_path_not_found 	;AN022; if path not found - okay
	jz	notpfile			;AN022;
	cmp	ax,error_access_denied		;AN022; if access denied - okay
	jz	notpfile			;AN022;
	jmp	extend_setup			;AN022; exit with error

pure_file:
	mov	bx,ax				; Is pure file
	mov	ax,IOCTL SHL 8
	INT	int_command
	mov	ah,CLOSE
	INT	int_command
	test	dl,devid_ISDEV
	jnz	ISADEV				; If device, done
	test	[BP.INFO],4
	jz	ISSIMPFILE			; If no path seps, done

NOTPFILE:
	mov	dx,word ptr [BP.BUF]
	cmp	dl,0				;AN034; If no drive specified, get
	jz	set_drive_spec			;AN034;    default drive dir
	cmp	dh,':'
	jz	DRVSPEC5

set_drive_spec: 				;AN034;
	mov	dl,'@'

DRVSPEC5:
	or	dl,20h
	sub	dl,60h				; A = 1
	invoke	SAVUDIR1
	jnc	curdir_ok			;AN022; if error - exit
	invoke	get_ext_error_number		;AN022; get the extended error
	jmp	extend_setup			;AN022; exit with error

curdir_ok:					;AN022;
	mov	dx,bp
	add	dx,BUF				; Set DX for upcomming CHDIRs
	mov	bh,[BP.INFO]
	and	bh,6
	cmp	bh,6				; Ambig and path ?
	jnz	CHECKAMB			; jmp if no
	mov	si,[BP.TTAIL]
	mov	bl,':'
	cmp	byte ptr [si-2],bl
	jnz	KNOWNOTSPEC
	mov	[BP.ISDIR],2			; Know is d:/file
	jmp	short DOPCDJ

KNOWNOTSPEC:
	mov	[BP.ISDIR],1			; Know is path/file
	dec	si				; Point to the /

DOPCDJ:
	jmp	DOPCD				;AC022; need long jump

CHECKAMB:
	cmp	bh,2
	jnz	CHECKCD

ISSIMPFILE:
ISADEV:
	mov	[BP.ISDIR],0			; Know is file since ambig but no path
	return

CHECKCD:
	invoke	SETREST1
	mov	ah,CHDIR
	INT	int_command
	jc	NOTPDIR
	mov	di,dx
	xor	ax,ax
	mov	cx,ax
	dec	cx

Kloop:						;AN000;  3/3/KK
	MOV	AL,ES:[DI]			;AN000;  3/3/KK
	INC	DI				;AN000;  3/3/KK
	OR	AL,AL				;AN000;  3/3/KK
	JZ	Done				;AN000;  3/3/KK
	xor	ah,ah				;AN000;  3/3/KK
	invoke	Testkanj			;AN000;  3/3/KK
	JZ	Kloop				;AN000;  3/3/KK
	INC	DI				;AN000;  3/3/KK
	INC	AH				;AN000;  3/3/KK
	jmp	Kloop				;AN000;  3/3/KK

Done:						;AN000;  3/3/KK
	dec	di
	mov	al,[DIRCHAR]
	mov	[bp.ISDIR],2			; assume d:/file
	OR	AH, AH				;AN000; 3/3/KK
	JNZ	Store_pchar			;AN000; 3/3/KK	 this is the trailing byte of ECS code
	cmp	al,[di-1]
	jz	GOTSRCSLSH

Store_pchar:					;AN000; 3/3/KK
	stosb
	mov	[bp.ISDIR],1			; know path/file

GOTSRCSLSH:
	or	[bp.INFO],6
	call	SETSTARS
	return


NOTPDIR:
	invoke	get_ext_error_number		;AN022; get the extended error
	cmp	ax,error_path_not_found 	;AN022; if path not found - okay
	jz	notpdir_try			;AN022;
	cmp	ax,error_access_denied		;AN022; if access denied - okay
	jnz	extend_setupj			;AN022; otherwise - exit error

notpdir_try:					;AN022;
	mov	[bp.ISDIR],0			; assume pure file
	mov	bh,[bp.INFO]
	test	bh,4
	retz					; Know pure file, no path seps
	mov	[bp.ISDIR],2			; assume d:/file
	mov	si,[bp.TTAIL]
	cmp	byte ptr [si],0
	jz	BADCDERRJ2			; Trailing '/'
	mov	bl,dot_chr
	cmp	byte ptr [si],bl
	jz	BADCDERRJ2			; If . or .. pure cd should have worked
	mov	bl,':'
	cmp	byte ptr [si-2],bl
	jz	DOPCD				; Know d:/file
	mov	[bp.ISDIR],1			; Know path/file
	dec	si				; Point at last '/'

DOPCD:
	xor	bl,bl
	xchg	bl,[SI] 			; Stick in a NUL
	invoke	SETREST1
	CMP	DX,SI				;AN000;  3/3/KK
	JAE	LookBack			;AN000;  3/3/KK
	PUSH	SI				;AN000;  3/3/KK
	PUSH	CX				;AN000;  3/3/KK
	MOV	CX,SI				;AN000;  3/3/KK
	MOV	SI,DX				;AN000;  3/3/KK

Kloop2: 					;AN000;  3/3/KK
	LODSB					;AN000;  3/3/KK
	invoke	TestKanj			;AN000;  3/3/KK
	jz	NotKanj4			;AN000;  3/3/KK
	LODSB					;AN000;  3/3/KK
	CMP	SI,CX				;AN000;  3/3/KK
	JB	Kloop2				;AN000;  3/3/KK
	POP	CX				;AN000;  3/3/KK
	POP	SI				;AN000;  3/3/KK
	JMP	SHORT DoCdr			;AN000;  3/3/KK  Last char is ECS code, don't check for
						;		 trailing path sep
NotKanj4:					;AN000;  3/3/KK
	CMP	SI,CX				;AN000;  3/3/KK
	JB	Kloop2				;AN000;  3/3/KK
	POP	CX				;AN000;  3/3/KK
	POP	SI				;AN000;  3/3/KK

LookBack:					;AN000;  3/3/KK
	CMP	BL,[SI-1]			; if double slash, then complain.
	JZ	BadCDErrJ2

DoCdr:						;AN000;  3/3/KK
	mov	ah,CHDIR
	INT	int_command
	xchg	bl,[SI]
	retnc
	invoke	get_ext_error_number		;AN022; get the extended error

EXTEND_SETUPJ:					;AN022;
	JMP	EXTEND_SETUP			;AN022; go issue the error message

BADCDERRJ2:
	jmp	badpath_err			;AC022; go issue path not found message

SETSTARS:
	mov	[bp.TTAIL],DI
	add	[bp.SIZ],12
	mov	ax,dot_qmark
	mov	cx,8
	rep	stosb
	xchg	al,ah
	stosb
	xchg	al,ah
	mov	cl,3
	rep	stosb
	xor	al,al
	stosb
	return

PUBLIC CompName
COMPNAME:

	mov	si,offset trangroup:DESTBUF	;g do name translate of target
	mov	di,offset trangroup:TRGXNAME	;g save for name comparison
	mov	ah,xnametrans			;g
	int	int_command			;g

	MOV	si,offset trangroup:SRCXNAME	;g get name translate of source
	MOV	di,offset trangroup:TRGXNAME	;g get name translate of target


	invoke	STRCOMP

	return

TRANCODE ENDS
	 END