     1                                  ; ****************************************************************************
     2                                  ; cptest1.s (cp0.s) - by Erdogan Tan - 20/04/2022
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Retro UNIX 8086 v1 - copy -- cp oldfile newfile (test version)
     5                                  ;
     6                                  ; [ Last Modification: 24/04/2022 ]
     7                                  ;
     8                                  ; Derived from (original) UNIX v7 (& v7 x86) 'cp.c' source Code
     9                                  ; Ref:
    10                                  ; www.tuhs.org (https://minnie.tuhs.org)
    11                                  ; v7.tar.gz
    12                                  ; ****************************************************************************
    13                                  ; [ v7.tar - usr/src/cmd/cp.c (archive date: 10-1-1979) ]
    14                                  ;
    15                                  ; Assembler: NASM v2.15
    16                                  ; ((nasm cp8086.s -l cp8086.txt -o cp8086.bin -Z error.txt))
    17                                  ;
    18                                  ; cp1.s - 21/04/2022 - Retro UNIX 386 v1.2 (modified unix v7 inode)
    19                                  ; cp0.s - 21/04/2022 - Retro UNIX 386 v1 & v1.1
    20                                  ; cp8086.s - 22/04/2022 - Retro UNIX 8086 v1 (16 bit 'cp0.s')
    21                                  ; cptest0.s - 24/04/2022 - Retro UNIX 8086 v1 - Test version of 'cp8086.s'
    22                                  ; cptest1.s - 24/04/2022 - Retro UNIX 8086 v1 - Test version of 'cp8086.s'
    23                                  
    24                                  ; 24/04/2022
    25                                  ; Test version - Normal running version difference:
    26                                  ;	Test version write new file after reading old file at all..
    27                                  ; (what for: to understand where -which stage- is causing to failure while
    28                                  ;  creating a new file.. because i could not understand it for 'cp8086.s')	
    29                                  
    30                                  ; 12/01/2022 (Retro UNIX 386 v1.2)
    31                                  ; 13/10/2015
    32                                  
    33                                  ; UNIX v1 system calls
    34                                  _rele 	equ 0
    35                                  _exit 	equ 1
    36                                  _fork 	equ 2
    37                                  _read 	equ 3
    38                                  _write	equ 4
    39                                  _open	equ 5
    40                                  _close 	equ 6
    41                                  _wait 	equ 7
    42                                  _creat 	equ 8
    43                                  _link 	equ 9
    44                                  _unlink	equ 10
    45                                  _exec	equ 11
    46                                  _chdir	equ 12
    47                                  _time 	equ 13
    48                                  _mkdir 	equ 14
    49                                  _chmod	equ 15
    50                                  _chown	equ 16
    51                                  _break	equ 17
    52                                  _stat	equ 18
    53                                  _seek	equ 19
    54                                  _tell 	equ 20
    55                                  _mount	equ 21
    56                                  _umount	equ 22
    57                                  _setuid	equ 23
    58                                  _getuid	equ 24
    59                                  _stime	equ 25
    60                                  _quit	equ 26	
    61                                  _intr	equ 27
    62                                  _fstat	equ 28
    63                                  _emt 	equ 29
    64                                  _mdate 	equ 30
    65                                  _stty 	equ 31
    66                                  _gtty	equ 32
    67                                  _ilgins	equ 33
    68                                  _sleep	equ 34 ; Retro UNIX 8086 v1 feature only !
    69                                  _msg    equ 35 ; Retro UNIX 386 v1 feature only !
    70                                  _geterr	equ 36 ; Retro UNIX 386 v1 feature only !
    71                                  ; 12/01/2022 - Retro UNIX 386 v1.2
    72                                  ; Retro UNIX 386 v2 system calls
    73                                  _setgid	equ 37
    74                                  _getgid	equ 38
    75                                  _sysver	equ 39 ; (get) Retro Unix 386 version
    76                                  
    77                                  ;;;
    78                                  ESCKey equ 1Bh
    79                                  EnterKey equ 0Dh
    80                                  
    81                                  ;%macro sys 1-4
    82                                  ;   ; 03/09/2015	
    83                                  ;   ; 13/04/2015
    84                                  ;   ; Retro UNIX 386 v1 system call.		
    85                                  ;   %if %0 >= 2   
    86                                  ;       mov ebx, %2
    87                                  ;       %if %0 >= 3    
    88                                  ;           mov ecx, %3
    89                                  ;           ;%if %0 = 4
    90                                  ;           %if	%0 >= 4 ; 11/03/2022
    91                                  ;		mov edx, %4   
    92                                  ;           %endif
    93                                  ;       %endif
    94                                  ;   %endif
    95                                  ;   mov eax, %1
    96                                  ;   int 30h	   
    97                                  ;%endmacro
    98                                  
    99                                  %macro sys 1-4
   100                                      ; Retro UNIX 8086 v1 system call.
   101                                      %if %0 >= 2   
   102                                          mov bx, %2
   103                                          %if %0 >= 3
   104                                              mov cx, %3
   105                                              %if %0 >= 4
   106                                                 mov dx, %4
   107                                              %endif
   108                                          %endif
   109                                      %endif
   110                                      mov ax, %1
   111                                      int 20h
   112                                  %endmacro
   113                                  
   114                                  ;; Retro UNIX 386 v1 system call format:
   115                                  ;; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   116                                  
   117                                  ;; 11/03/2022
   118                                  ;; Note: Above 'sys' macro has limitation about register positions;
   119                                  ;;	ebx, ecx, edx registers must not be used after their
   120                                  ;;	positions in sys macro.
   121                                  ;; for example:
   122                                  ;;	'sys _write, 1, msg, ecx' is defective, because
   123                                  ;;	 ecx will be used/assigned before edx in 'sys' macro.
   124                                  ;; correct order may be:
   125                                  ;;	'sys _write, 1, msg, eax ; (eax = byte count)
   126                                  
   127                                  ; Retro UNIX 8086 v1 system call format:
   128                                  ; sys systemcall (ax) <arg1 (bx)>, <arg2 (cx)>, <arg3 (dx)>
   129                                  
   130                                  struc stat
   131                                  	; Note: This is for Retro UNIX v1 'sysstat' output !!!
   132                                  	; (34 bytes)
   133 00000000 ????                    	.inode:  resw 1	
   134 00000002 ????                    	.mode:	 resw 1
   135 00000004 ??                      	.nlinks: resb 1
   136 00000005 ??                      	.uid:	 resb 1
   137 00000006 ????                    	.size:	 resw 1
   138 00000008 <res 10h>               	.dskptr: resw 8
   139 00000018 ????????                	.ctime:	 resd 1
   140 0000001C ????????                	.mtime:	 resd 1
   141 00000020 ????                    	.rsvd:   resw 1
   142                                  	.strucsize:
   143                                  endstruc   
   144                                  
   145                                  ;struc stat
   146                                  ;	; Note: This is for Retro UNIX v1.2 'sysstat' output !!!
   147                                  ;	; (66 bytes)
   148                                  ;	.inode:  resw 1	
   149                                  ;	.mode:	 resw 1
   150                                  ;	.nlinks: resw 1 
   151                                  ;	.uid:	 resw 1
   152                                  ;	.gid:	 resb 1
   153                                  ;	.size_h: resb 1
   154                                  ;	.size:	 resd 1
   155                                  ;	.dskptr: resd 10
   156                                  ;	.atime:	 resd 1
   157                                  ;	.mtime:	 resd 1
   158                                  ;	.ctime:  resd 1
   159                                  ;	.strucsize:
   160                                  ;endstruc   
   161                                  
   162                                  ;S_IFMT   equ 0F000h ; /* type of file */
   163                                  ;S_IFDIR  equ 04000h ; /* directory */
   164                                  ;S_IFCHR  equ 02000h ; /* character special */
   165                                  ;S_IFBLK  equ 06000h ; /* block special */
   166                                  ;S_IFREG  equ 08000h ; /* regular */
   167                                  ;S_ISUID  equ 00800h ; /* set user id on execution */
   168                                  ;S_ISGID  equ 00400h ; /* set group id on execution */
   169                                  ;S_IREAD  equ 00100h ; /* read permission, owner */
   170                                  ;S_IWRITE equ 00080h ; /* write permission, owner */
   171                                  ;S_IEXEC  equ 00040h ; /* execute/search permission, owner */
   172                                  
   173                                  ; 21/04/2022 - UNIX v1 inode
   174                                  ; byte 1
   175                                  S_ALLOC  equ 080h ; Allocated flag
   176                                  S_IFDIR  equ 040h ; Directory flag
   177                                  S_IFCHR  equ 020h ; File modified flag (always on)
   178                                  S_IFBLK  equ 010h ; Large File flag
   179                                  ; byte 0
   180                                  S_ISUID  equ 020h ; Set User ID On Execution flag
   181                                  S_IEXEC  equ 010h ; Executable File flag
   182                                  S_IREAD  equ 008h ; Owner's Read Permission flag
   183                                  S_IWRITE equ 004h ; Owner's Write Permission flag
   184                                  
   185                                  BSIZE equ 512
   186                                  
   187                                  ; 24/04/2022 - cptest0.s
   188                                  MAXFSIZE equ 32530 - iobuf
   189                                  
   190                                  ;-----------------------------------------------------------------
   191                                  ;  text - code
   192                                  ;-----------------------------------------------------------------
   193                                  
   194                                  ;[BITS 32] ; 32-bit intructions (for 80386 protected mode)
   195                                  
   196                                  [BITS 16] ; 16-bit (x86 real mode) intructions
   197                                  
   198                                  [ORG 0] 
   199                                  
   200                                  START_CODE:
   201                                  	; 22/04/2022 - 16 bit version (Retro UNIX 8086 v1) 
   202                                  	;
   203                                  	; 20/04/2022
   204                                  	; main(argc, argv)
   205                                  
   206                                  	;mov	esi, esp		
   207                                  	;mov	edi, esi
   208                                  	;lodsd		; number of arguments
   209                                  	;;mov	edi, esi			
   210                                  	;;mov	[argc], eax
   211                                  	;mov	[argc], al
   212                                  
   213                                  	; 22/04/2022
   214 00000000 89E6                    	mov	si, sp
   215 00000002 89F7                    	mov	di, si
   216 00000004 AD                      	lodsw
   217                                  	;mov	[argc], ax
   218 00000005 A2[BE01]                	mov	[argc], al
   219                                  
   220                                  	;if (argc < 3) 
   221                                  	;   goto usage;
   222                                  
   223                                  	;;cmp	eax, 3
   224                                  	;cmp	ax, 3
   225 00000008 3C03                    	cmp	al, 3
   226 0000000A 732D                    	jnb	short cp_0  ; if (argc > 3) {
   227 0000000C FEC8                    	dec	al	; 21/04/2022
   228 0000000E 7506                    	jnz	short cp_usage
   229                                  
   230                                  	;sys	_msg, program_msg, 255, 0Fh
   231                                  	; 22/04/2022
   232 00000010 B8[BF01]                	mov	ax, program_msg ; asciiz message address
   233 00000013 E80B00                  	call	print_msg
   234                                  
   235                                  cp_usage:
   236                                     ; fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
   237                                  	;sys	_msg, usage_msg, 255, 07h
   238 00000016 B8[FA01]                	mov	ax, usage_msg
   239 00000019 E80500                  	call	print_msg
   240                                  cp_exit:
   241                                  	sys	_exit	; sys exit
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102                              <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104                              <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 0000001C B80100              <1>  mov ax, %1
   111 0000001F CD20                <1>  int 20h
   242                                  ;hlt:
   243                                  ;	nop
   244                                  ;	nop
   245                                  ;	jmp	short hlt
   246                                  
   247                                  print_msg:
   248                                  	; 22/04/2022
   249                                  strlen:
   250                                  	; ax = asciiz string address
   251 00000021 89C3                    	mov	bx, ax
   252 00000023 4B                      	dec	bx
   253                                  nextchr:
   254 00000024 43                      	inc	bx
   255 00000025 803F00                  	cmp	byte [bx], 0
   256 00000028 77FA                    	ja	short nextchr
   257                                  	;cmp	[bx], 0Dh
   258                                  	;ja	short nextchr
   259 0000002A 29C3                    	sub	bx, ax
   260                                  	; bx = asciiz string length
   261                                  	;retn
   262                                  print_str:
   263 0000002C 89DA                    	mov	dx, bx
   264                                  	sys	_write, 1, ax
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 0000002E BB0100              <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 00000031 89C1                <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 00000033 B80400              <1>  mov ax, %1
   111 00000036 CD20                <1>  int 20h
   265                                  
   266 00000038 C3                      	retn
   267                                  
   268                                  cp_0:
   269                                  	;mov	edx, eax ; [argc]
   270                                  	;; 21/04/2022
   271                                  	;;;dec	edx  ; argc-1
   272                                  	;;dec	dl
   273                                  	;shl	dl, 2 ; * 4 
   274                                  	;add	edi, edx
   275                                  
   276                                  	; 22/04/2022
   277 00000039 89C2                    	mov	dx, ax
   278 0000003B D0E2                    	shl	dl, 1 ; * 2 ; 16 bit argument pointers
   279 0000003D 01D7                    	add	di, dx
   280                                  
   281                                  	; 21/04/2022
   282 0000003F 3C03                    	cmp	al,3
   283 00000041 7613                    	jna	short cp_1
   284                                  
   285                                  	;sys	_stat, [edi], stbuf2
   286                                  	sys	_stat, [di], stbuf2  ; 22/04/2022
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 00000043 8B1D                <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 00000045 B9[1203]            <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 00000048 B81200              <1>  mov ax, %1
   111 0000004B CD20                <1>  int 20h
   287 0000004D 72C7                    	jc	short cp_usage
   288                                  
   289                                  	;; check retro unix v2 inode flags
   290                                  	;;	(a bit different than unix v7 inode flags)
   291                                  	;; if it is a directory..
   292                                  	;;	regular file flag and dir flag must be 1
   293                                  	;mov	al, [stbuf2+stat.mode+1]
   294                                  	;and	al, S_IFDIR|S_IFREG
   295                                  	;cmp	al, S_IFDIR|S_IFREG ; directory ?
   296                                  	;jne	short cp_usage ; no
   297                                  	
   298                                  	;; check if it is a device file
   299                                  	;;test	al, S_IFREG ; regular file ?
   300                                  	;;jz	short cp_usage ; no
   301                                  	;;and	al, S_IFDIR ; directory ?
   302                                  	;;jz	short cp_usage ; no
   303                                  
   304                                  	; 21/04/2022
   305                                  	; check (unix v1 inode) directory flag
   306 0000004F F606[1503]40            	test	byte [stbuf2+stat.mode+1], S_IFDIR ; directory ?
   307 00000054 74C0                    	jz	short cp_usage ; no
   308                                   
   309                                  cp_1:	
   310                                  	; esi = esp+4 = argv[0] ; executable file name (cp)
   311                                  	;lodsd	; 21/04/2022
   312 00000056 AD                      	lodsw ; 22/04/2022 - Retro UNIX 8086 v1
   313                                  cp_loop: ; for(i=1; i<argc-1;i++)
   314                                  	;lodsd
   315                                  	; ((esi = esp+8 = argv[1] ; (old) file 1))
   316                                  
   317                                  	; esi = argv[i] 
   318                                   	; edi = argv[argc-1] ; *
   319                                  	; 22/04/2022 - Retro UNIX 8086 v1 (16 bit Retro UNIX)
   320                                  	; si = argv[i]
   321                                  	; di = argv[argc-1] ; *
   322                                   	
   323 00000057 E81D00                  	call	copy
   324 0000005A 7304                    	jnc	short cp_2
   325                                  
   326 0000005C FE06[B802]              	inc	byte [errors]
   327                                  cp_2:
   328                                  	;lodsd	; 21/04/2022
   329                                  	;cmp	esi, edi
   330                                  	;jb	short cp_loop
   331                                  
   332                                  	; 22/04/2022 - Retro UNIX 8086 v1
   333 00000060 AD                      	lodsw
   334 00000061 39FE                    	cmp	si, di
   335 00000063 72F2                    	jb	short cp_loop
   336                                  
   337                                  	; bypass 'OK.' message if there was an error
   338 00000065 803E[B802]00            	cmp	byte [errors], 0
   339 0000006A 77B0                    	ja	short cp_exit
   340                                  cp_ok:
   341                                  	;sys	_msg, ok_msg, 255, 07h
   342                                  	; 22/04/2022
   343 0000006C B8[B002]                	mov	ax, ok_msg
   344                                  cp_err_exit:  ; cptest0.s ; 24/04/2022
   345 0000006F E8AFFF                  	call	print_msg
   346                                  ;cp_exit:
   347                                  	sys	_exit	; sys exit
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102                              <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104                              <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 00000072 B80100              <1>  mov ax, %1
   111 00000075 CD20                <1>  int 20h
   348                                  
   349                                  ;_halt:
   350                                  ;	nop
   351                                  ;	jmp	short _halt
   352                                  
   353                                  copy:	; copy(from, to)
   354                                  	;
   355                                  	; 22/04/2022 - 16 bit version (Retro UNIX 8086 v1) 
   356                                  	; 21/04/2022
   357                                  	; 20/04/2022
   358                                  	; INPUT:
   359                                  	;	esi = pointer to file name to be copied
   360                                  	;  	edi = ptr to new file name or destination dir
   361                                  	; OUTPUT:
   362                                  	;	cf = 0 -> OK
   363                                  	;	cf = 1 -> Error !
   364                                  	;
   365                                  	; Modified registers: eax, ebx, ecx, edx, ebp
   366                                  	;
   367                                  	
   368                                  	; open (old) file for read
   369                                  	;sys	_open, [esi], 0
   370                                  	sys	_open, [si], 0 ; 22/04/2022
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 00000077 8B1C                <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 00000079 B90000              <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 0000007C B80500              <1>  mov ax, %1
   111 0000007F CD20                <1>  int 20h
   371 00000081 7313                    	jnc	short cp_3
   372                                  	
   373                                  	; esi = file name (from)
   374                                  
   375                                  	;fprintf(stderr, "cp: cannot open %s\n", from);
   376                                  	;	return(1);
   377                                  
   378                                  	;sys	_msg, cno_err_msg, 255, 07h
   379                                  	; 22/04/2022
   380 00000083 B8[2702]                	mov	ax, cno_err_msg
   381 00000086 E898FF                  	call	print_msg
   382                                  
   383                                  	; file name (from) 
   384                                  	;sys	_msg, [esi], 255, 07h
   385                                  	; 22/04/2022
   386 00000089 8B04                    	mov	ax, [si]
   387                                  write_err_nl: ; 24/04/2022
   388 0000008B E893FF                  	call	print_msg
   389                                  write_nl:
   390                                  	; new/next line
   391                                  	;sys	_msg, nextline, 255, 07h
   392                                  	; 22/04/2022
   393 0000008E B8[2402]                	mov	ax, nextline
   394 00000091 E88DFF                  	call	print_msg
   395                                  	;
   396 00000094 F9                      	stc	; return with error (cf=1)
   397 00000095 C3                      	retn
   398                                  
   399                                  cp_3:
   400                                  	;mov	[fold], eax ; file (descriptor) number
   401                                  	; 22/04/2022
   402 00000096 A3[0C03]                	mov	[fold], ax ; file (descriptor) number
   403                                  
   404                                  	; (from)
   405                                  	sys	_fstat, [fold], stbuf1
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 00000099 8B1E[0C03]          <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 0000009D B9[3403]            <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 000000A0 B81C00              <1>  mov ax, %1
   111 000000A3 CD20                <1>  int 20h
   406                                  
   407                                  
   408                                  	; 24/04/2022 - cptest0.s
   409                                  
   410 000000A5 813E[3A03]3C7B          	cmp	word [stbuf1+stat.size], MAXFSIZE
   411 000000AB 762A                    	jna	short cp_3_
   412                                  
   413                                  	; close file
   414                                  	sys	_close, [fold]
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 000000AD 8B1E[0C03]          <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104                              <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 000000B1 B80600              <1>  mov ax, %1
   111 000000B4 CD20                <1>  int 20h
   415                                   
   416                                  write_mfs:
   417 000000B6 89E5                    	mov	bp, sp
   418 000000B8 B83C7B                  	mov	ax, MAXFSIZE
   419 000000BB B90A00                  	mov	cx, 10
   420                                  div_again:
   421 000000BE 31D2                    	xor	dx, dx	
   422 000000C0 F7F1                    	div	cx
   423 000000C2 52                      	push	dx
   424 000000C3 21C0                    	and	ax, ax
   425 000000C5 75F7                    	jnz	short div_again
   426 000000C7 BF[CE02]                	mov	di, mfsstr
   427                                  wrt_again:
   428 000000CA 58                      	pop	ax
   429 000000CB 0430                    	add	al, '0'
   430 000000CD AA                      	stosb
   431 000000CE 39E5                    	cmp	bp, sp
   432 000000D0 77F8                    	ja	short wrt_again
   433                                  
   434 000000D2 B8[B902]                	mov	ax, bigfile_err
   435 000000D5 EB98                    	jmp	cp_err_exit
   436                                  	
   437                                  cp_3_:
   438                                  	; save mode
   439                                  	;mov	ax, [stbuf1+stat.mode]
   440                                  	;mov	[mode], ax
   441                                  	
   442                                  	; 24/04/2022 - cptest1.s
   443 000000D7 B8[DD02]                	mov	ax, reading_msg
   444 000000DA E844FF                  	call	print_msg
   445 000000DD 8B04                    	mov	ax, [si] ; (old) file name
   446 000000DF E83FFF                  	call	print_msg
   447                                  
   448                                  	sys	_read, [fold], iobuf, [stbuf1+stat.size]
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 000000E2 8B1E[0C03]          <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 000000E6 B9[D603]            <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106 000000E9 8B16[3A03]          <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 000000ED B80300              <1>  mov ax, %1
   111 000000F0 CD20                <1>  int 20h
   449 000000F2 730E                    	jnc	short cp_4_
   450                                  
   451                                  	;if (n < 0) {
   452                                  	;   fprintf(stderr, "cp: read error\n");
   453                                  
   454                                  	sys	_close, [fold]
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 000000F4 8B1E[0C03]          <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104                              <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 000000F8 B80600              <1>  mov ax, %1
   111 000000FB CD20                <1>  int 20h
   455                                  
   456 000000FD B8[7F02]                	mov	ax, crd_err_msg
   457                                  
   458                                  	; 24/04/2022 - cptest1.s
   459 00000100 EB89                    	jmp	short write_err_nl
   460                                  
   461                                  cp_4_:
   462                                  	; 24/04/2022 - cptest1.s
   463 00000102 A3[1003]                	mov	[filesize], ax
   464                                  
   465                                  	; (to)
   466                                  	;;sys	_stat, [edi], stbuf2  ; stat(to, &stbuf2)
   467                                  	; 22/04/2022
   468                                  	;sys	_stat, [di], stbuf2
   469                                  	;jnc	short cp_4
   470                                  	;jmp	cp_9
   471                                  	; 22/04/2022
   472 00000105 8B2D                    	mov	bp, [di]
   473                                  	sys	_stat, bp, stbuf2  ; stat(to, &stbuf2)
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 00000107 89EB                <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 00000109 B9[1203]            <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 0000010C B81200              <1>  mov ax, %1
   111 0000010F CD20                <1>  int 20h
   474                                  	;jnc	short cp_4
   475                                  	;jmp	cp_9
   476 00000111 724F                    	jc	short cp_9
   477                                  cp_4:
   478                                  	; /* is target a directory? */
   479                                  
   480                                  	;; check retro unix v2 inode flags
   481                                  	;;	(a bit different than unix v7 inode flags)
   482                                  	;; regular file flag and dir flag must be 1 for a dir
   483                                  	;mov	al, [stbuf2+stat.mode+1]
   484                                  	;and	al, S_IFDIR|S_IFREG
   485                                  	;cmp	al, S_IFDIR|S_IFREG ; directory ?
   486                                  	;jne	short cp_8 ; no, overwrite (create file)
   487                                  			   ; (if the new file is not same file)
   488                                  
   489                                  	;; check if it is a device file
   490                                  	;;test	al, S_IFREG ; regular file ?
   491                                  	;;jz	short cp_error ; no
   492                                  	;;and	al, S_IFDIR ; directory ?
   493                                  	;;jz	short cp_error ; no
   494                                  
   495                                  	; 21/04/2022
   496                                  	; check (unix v1 inode) directory flag
   497 00000113 F606[1503]40            	test	byte [stbuf2+stat.mode+1], S_IFDIR ; directory ?
   498 00000118 7439                    	jz	short cp_8 ; no, overwrite (create file)
   499                                  			   ; (if the new file is not same file)
   500                                  
   501                                  	; add (old) file name to (destination ) path
   502                                  	; (directory name +'/'+ file name)  
   503                                  	
   504                                  	;mov	ebp, esi   ; save esi
   505                                  	;mov	esi, [edi] ; directory name address
   506                                  	;mov	ebx, edi   ; save edi			
   507                                  	;mov	edi, iobuf ; (new) path name buffer addr
   508                                  	; 22/04/2022 - Retro UNIX 8086 v1 (16 bit utility)
   509 0000011A 89F5                    	mov	bp, si
   510 0000011C 8B35                    	mov	si, [di]
   511 0000011E 89FB                    	mov	bx, di
   512                                  	;mov	di, iobuf
   513                                  	; 24/04/2022 - cptest1.s
   514 00000120 BF[5603]                	mov	di, fnbuf
   515                                  
   516                                  	; p1 = from;
   517                                  	; p2 = to;
   518                                  	; bp = iobuf;
   519                                  cp_5:	; while(*bp++ = *p2++)
   520 00000123 AC                      	lodsb	
   521 00000124 AA                      	stosb
   522 00000125 20C0                    	and	al, al
   523 00000127 75FA                    	jnz	short cp_5
   524                                  	;mov	byte [edi-1], '/' ; bp[-1] = '/';
   525                                  	; 22/04/2022
   526 00000129 C645FF2F                	mov	byte [di-1], '/'
   527                                  	; p2 = bp
   528                                  	;mov	edx, edi
   529                                  	;mov	esi, [ebp] ; *p1 ; from
   530                                  	; 22/04/2022
   531 0000012D 89FA                    	mov	dx, di
   532 0000012F 8B7600                  	mov	si, [bp]
   533                                  cp_6:	; while(*bp = *p1++)
   534 00000132 AC                      	lodsb
   535 00000133 AA                      	stosb
   536 00000134 08C0                    	or	al, al
   537 00000136 7408                    	jz	short cp_7
   538 00000138 3C2F                    	cmp	al, '/' ; if (*bp++ == '/')
   539 0000013A 75F6                    	jne	short cp_6
   540                                  	; bp = p2
   541                                  	; 21/04/2022
   542                                  	;mov	edi, edx ; (discard path before file name)
   543                                  	; 22/04/2022
   544 0000013C 89D7                    	mov	di, dx
   545 0000013E EBF2                    	jmp	short cp_6
   546                                  cp_7:	
   547                                  	;mov	esi, ebp ; restore esi
   548                                  	;mov	edi, ebx ; restore edi
   549                                  	; 22/04/2022
   550 00000140 89EE                    	mov	si, bp
   551 00000142 89DF                    	mov	di, bx
   552                                  	; to = iobuf
   553                                  	;;mov	ebp, iobuf
   554                                  	; 22/04/2022
   555                                  	;mov	bp, iobuf
   556                                  	; 24/04/2022 - cptest1.s
   557 00000144 BD[5603]                	mov	bp, fnbuf
   558                                  	
   559                                  	;sys	_stat, ebp, stbuf2  ; stat(to, &stbuf2) >= 0
   560                                  	sys	_stat, bp, stbuf2 ; 22/04/2022
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 00000147 89EB                <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 00000149 B9[1203]            <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 0000014C B81200              <1>  mov ax, %1
   111 0000014F CD20                <1>  int 20h
   561 00000151 720F                    	jc	short cp_10 ; create new file
   562                                  
   563                                  cp_8:
   564                                  	;if (stbuf1.st_dev == stbuf2.st_dev &&
   565                                  	;   stbuf1.st_ino == stbuf2.st_ino) {
   566                                  	;	fprintf(stderr, "cp: cannot copy file to itself.\n");
   567                                  	; 	return(1);
   568                                  
   569 00000153 A1[3403]                	mov	ax, [stbuf1+stat.inode]
   570 00000156 3B06[1203]              	cmp	ax, [stbuf2+stat.inode]
   571 0000015A 7506                    	jne	short cp_10
   572                                  
   573                                  	; same file ! error...
   574                                  	;;mov	ebp, cncis_err_msg ; error message
   575                                  	; 22/04/2022
   576                                  	;mov	bp, cncis_err_msg ; error message
   577                                  	; 24/04/2022 - cptest1.s
   578 0000015C B8[3E02]                	mov	ax, cncis_err_msg 
   579                                  	; esi = file name (from)
   580 0000015F E929FF                  	jmp	write_err_nl
   581                                  
   582                                  cp_9:	
   583                                  	; 22/04/2022
   584                                  	; bp = [di]
   585                                  	;; new file (asciiz name address)
   586                                  	;;mov	ebp, [edi] ; 21/04/2022
   587                                  	;mov	bp, [di] ; 22/04/2022
   588                                  
   589                                  	; create new file (truncate if it exists) 
   590                                  cp_10:
   591                                  	; fnew = creat(to, mode)
   592                                  	;movzx 	ecx, word [stbuf1+stat.mode]
   593                                  	; ecx = mode 
   594                                  	; 22/04/2022
   595 00000162 8B0E[3603]              	mov	cx, [stbuf1+stat.mode]
   596                                  	;sys	_creat, ebp
   597                                  	sys	_creat, bp ; 22/04/2022
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 00000166 89EB                <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104                              <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 00000168 B80800              <1>  mov ax, %1
   111 0000016B CD20                <1>  int 20h
   598 0000016D 730B                    	jnc	short cp_11
   599                                  
   600                                  	;if ((fnew = creat(to, mode)) < 0) {
   601                                  	;	fprintf(stderr, "cp: cannot create %s\n", to);
   602                                  	;	close(fold);
   603                                  	;	return(1);
   604                                  
   605                                  	; error message
   606                                  	;sys	_msg, ccf_err_msg, 255, 07h
   607                                  	; 22/04/2022
   608 0000016F B8[6602]                	mov	ax, ccf_err_msg ; 'can not create' error msg
   609 00000172 E8ACFE                  	call	print_msg
   610                                  
   611                                  	; and file name (to) -at the end of error message-
   612                                  	;sys	_msg, ebp, 255, 07h
   613                                  	; 22/04/2022
   614 00000175 89E8                    	mov	ax, bp ; write (new) file name
   615                                   
   616                                  	; write next line (move cursor to next line)
   617                                  	; and return (from this/copy subroutine)
   618 00000177 E911FF                  	jmp	write_err_nl
   619                                  
   620                                  cp_11:	
   621                                  	; 21/04/2022 
   622                                  	;mov	[fnew], eax
   623                                  	; 22/04/2022 - Retro UNIX 8086 v1
   624 0000017A A3[0E03]                	mov	[fnew], ax ; (16 bit)
   625                                  ;cp_rw_next:
   626                                  ;	; while(n = read(fold, iobuf, BSIZE))
   627                                  ;	sys	_read, [fold], iobuf, BSIZE
   628                                  ;	jnc	short cp_12
   629                                  
   630                                  	;if (n < 0) {
   631                                  	;   fprintf(stderr, "cp: read error\n");
   632                                  
   633                                  	; 24/04/2022 - cptest0.s
   634                                  	;mov	ax, nextline
   635                                  	;call	print_msg
   636                                  
   637                                  	; write read error message
   638                                  	;;mov	ebp, crd_err_msg
   639                                  	;mov	bp, crd_err_msg ; 22/04/2022
   640                                  
   641                                  ;cp_rw_err:
   642                                  	;; 21/04/2022
   643                                  	;; cf = 1
   644                                  	;sys	_close, [fnew]	
   645                                  	;;jmp	cp_err_exit
   646                                  	;; 24/04/2022 - cptest1.s
   647                                  	;jmp	short rw_err_retn
   648                                  
   649                                  cp_12:
   650                                  	; 24/04/2022 - cptest0.s
   651                                  	;mov	[filesize], ax
   652                                  
   653 0000017D B8[FF02]                	mov	ax, rw_ok_msg
   654 00000180 E89EFE                  	call	print_msg
   655                                  
   656                                  	; eax = read count
   657                                  	; eax = 0 -> eof
   658                                  	;or	eax, eax
   659                                  ; 24/04/2022 - cptest0.s
   660                                  ;	or	ax, ax ; 22/04/2022 (Retro UNIX 8086 v1)
   661                                  ;	jz	short cp_14 ; eof
   662                                  
   663                                  	; 24/04/2022 - cptest0.s
   664 00000183 B8[EF02]                	mov	ax, writing_msg
   665 00000186 E898FE                  	call	print_msg
   666 00000189 89E8                    	mov	ax, bp ; (new) file name
   667 0000018B E893FE                  	call	print_msg
   668                                  
   669                                  	;;mov	ebp, eax  ; n
   670                                  	;mov	dx, ax ; 22/04/2022
   671                                  	; 24/04/2022 - cptest0.s
   672                                  	; [filesize] = read/write byte count
   673 0000018E 8B16[1003]              	mov	dx, [filesize]
   674                                  
   675                                  	; write(fnew, iobuf, n)
   676                                  	;sys	_write, [fnew], iobuf, ebp
   677                                  	; 22/04/2022
   678                                  	sys	_write, [fnew], iobuf
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 00000192 8B1E[0E03]          <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104 00000196 B9[D603]            <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 00000199 B80400              <1>  mov ax, %1
   111 0000019C CD20                <1>  int 20h
   679                                  	;jc	short cp_13
   680                                  	; 24/04/2022 - cptest1.s
   681 0000019E 9C                      	pushf
   682                                  	sys	_close, [fnew]
   100                              <1> 
   101                              <1>  %if %0 >= 2
   102 0000019F 8B1E[0E03]          <1>  mov bx, %2
   103                              <1>  %if %0 >= 3
   104                              <1>  mov cx, %3
   105                              <1>  %if %0 >= 4
   106                              <1>  mov dx, %4
   107                              <1>  %endif
   108                              <1>  %endif
   109                              <1>  %endif
   110 000001A3 B80600              <1>  mov ax, %1
   111 000001A6 CD20                <1>  int 20h
   683 000001A8 9D                      	popf
   684 000001A9 730C                    	jnc	short cp_14
   685                                  
   686                                  	;if (write(fnew, iobuf, n) != n)
   687                                  	;   fprintf(stderr, "cp: write error.\n");
   688                                  	;   close(fold);
   689                                  	;   close(fnew);
   690                                  	;   return(1);
   691                                  
   692                                  	; eax = written bytes
   693                                  	;cmp	eax, ebp
   694                                  	;;je	short cp_11 ; read next (block)
   695                                  	;; 21/04/2022
   696                                  	;je	short cp_rw_next
   697                                  
   698                                  ; 24/04/2022 - cptest0.s
   699                                  ;	; 22/04/2022
   700                                  ;	cmp	ax, dx
   701                                  ;	je	short cp_rw_next
   702                                  
   703                                  ;	; 24/04/2022 - cptest0.s
   704                                  ;	mov	ax, rw_ok_msg
   705                                  ;	call	print_msg
   706                                  ;	jmp	short cp_14
   707                                  
   708                                  	; error !
   709                                  	;; eax < ebp --> cf = 1
   710                                  	; 22/04/2022 - Retro UNIX 8086 v1
   711                                  	; ax < dx --> cf = 1
   712                                  cp_13:
   713                                  	; close new file
   714                                  	; and then write error mesage
   715                                  	; and then close old file
   716                                  	; and then write (move cursor to) next line
   717                                  	; and then return (from subroutine) 
   718                                  	;sys	_close, [fnew]
   719                                  
   720                                  	; 24/04/2022 - cptest0.s
   721 000001AB B8[2402]                	mov	ax, nextline
   722 000001AE E870FE                  	call	print_msg
   723                                  
   724                                  	; write error message
   725                                  	;mov	ebp, cwr_err_msg
   726                                  	; 22/04/2022
   727                                  	;mov	bp, cwr_err_msg
   728                                  	; 24/04/2022 - cptest1.s
   729 000001B1 B8[9702]                	mov	ax, cwr_err_msg
   730                                  	;
   731                                  	;jmp	short write_err_msg
   732                                  	; 24/04/2022 - cptest1.s
   733 000001B4 E9D4FE                  	jmp	write_err_nl
   734                                  
   735                                  
   736                                  	; eof
   737                                  cp_14:
   738                                  	;close(fold);
   739                                  	;close(fnew);
   740                                  	;return(0);
   741                                  
   742                                  
   743                                  	; 24/04/2022 - cptest1.s
   744 000001B7 B8[FF02]                	mov	ax, rw_ok_msg
   745 000001BA E864FE                  	call	print_msg
   746                                  		
   747                                  	;sys	_close, [fold]
   748                                  	;sys	_close, [fnew]
   749                                  	
   750                                  	;clc
   751 000001BD C3                      	retn
   752                                  	
   753                                  ;-----------------------------------------------------------------
   754                                  ;  data - initialized data
   755                                  ;-----------------------------------------------------------------
   756                                  
   757                                  ;argc:	dd 0
   758 000001BE 00                      argc:	db 0
   759                                  
   760                                  ; ----------------------------------------------------------------
   761                                  
   762                                  program_msg:
   763 000001BF 0D0A                    	db  0Dh, 0Ah
   764 000001C1 526574726F20554E49-     	db  'Retro UNIX 8086 v1 COPY TEST by Erdogan TAN - 24/04/2022'
   764 000001CA 582038303836207631-
   764 000001D3 20434F505920544553-
   764 000001DC 54206279204572646F-
   764 000001E5 67616E2054414E202D-
   764 000001EE 2032342F30342F3230-
   764 000001F7 3232               
   765                                  	;db 0Dh, 0Ah
   766 000001F9 00                      	db  0
   767                                  
   768                                  usage_msg:
   769 000001FA 0D0A                    	db  0Dh, 0Ah
   770 000001FC 55736167653A206370-     	db  'Usage: cptest: f1 f2; or cp f1 ... fn d2'
   770 00000205 746573743A20663120-
   770 0000020E 66323B206F72206370-
   770 00000217 206631202E2E2E2066-
   770 00000220 6E206432           
   771                                  nextline:
   772 00000224 0D0A00                  	db  0Dh, 0Ah, 0
   773                                  
   774                                  cno_err_msg:
   775 00000227 0D0A                    	db 0Dh, 0Ah
   776 00000229 6370746573743A2063-     	db 'cptest: cannot open '
   776 00000232 616E6E6F74206F7065-
   776 0000023B 6E20               
   777 0000023D 00                      	db 0
   778                                  cncis_err_msg:
   779 0000023E 0D0A                    	db 0Dh, 0Ah
   780 00000240 6370746573743A2063-     	db 'cptest: cannot copy file to itself.'
   780 00000249 616E6E6F7420636F70-
   780 00000252 792066696C6520746F-
   780 0000025B 20697473656C662E   
   781 00000263 0D0A00                  	db 0Dh, 0Ah, 0
   782                                  
   783                                  ccf_err_msg:
   784 00000266 0D0A                    	db 0Dh, 0Ah
   785 00000268 6370746573743A2063-     	db 'cptest: cannot create '
   785 00000271 616E6E6F7420637265-
   785 0000027A 61746520           
   786 0000027E 00                      	db 0
   787                                  
   788                                  crd_err_msg:
   789 0000027F 0D0A                    	db 0Dh, 0Ah
   790 00000281 6370746573743A2072-     	db 'cptest: read error.'
   790 0000028A 656164206572726F72-
   790 00000293 2E                 
   791 00000294 0D0A00                  	db 0Dh, 0Ah, 0
   792                                  
   793                                  cwr_err_msg:
   794 00000297 0D0A                    	db 0Dh, 0Ah
   795 00000299 6370746573743A2077-     	db 'cptest: write error.'
   795 000002A2 72697465206572726F-
   795 000002AB 722E               
   796 000002AD 0D0A00                  	db 0Dh, 0Ah, 0
   797                                  
   798                                  ok_msg:
   799 000002B0 0D0A                    	db  0Dh, 0Ah
   800 000002B2 4F4B2E                  	db  'OK.'
   801 000002B5 0D0A00                  	db  0Dh, 0Ah, 0
   802                                  
   803 000002B8 00                      errors:	db 0
   804                                  
   805                                  	; 24/04/2022 - cptest0.s
   806                                  bigfile_err:
   807 000002B9 0D0A                    	db 0Dh, 0Ah
   808 000002BB 6370746573743A2062-     	db 'cptest: big file > '
   808 000002C4 69672066696C65203E-
   808 000002CD 20                 
   809                                  mfsstr:	
   810 000002CE 333235333020627974-     	db '32530 bytes.'
   810 000002D7 65732E             
   811 000002DA 0D0A00                  	db 0Dh, 0Ah, 0
   812                                  
   813                                  reading_msg:
   814 000002DD 0D0A                    	db 0Dh, 0Ah
   815 000002DF 52656164696E672066-     	db 'Reading file : '
   815 000002E8 696C65203A20       
   816 000002EE 00                      	db 0
   817                                  writing_msg:
   818                                  	;db 0Dh, 0Ah
   819 000002EF 57726974696E672066-     	db 'Writing file : '
   819 000002F8 696C65203A20       
   820 000002FE 00                      	db 0
   821                                  rw_ok_msg:
   822 000002FF 206973204F4B202E2E      	db ' is OK ..'
   823 00000308 0D0A00                  	db 0Dh, 0Ah, 0
   824                                  
   825                                  ;-----------------------------------------------------------------
   826                                  ;  bss - uninitialized data
   827                                  ;-----------------------------------------------------------------
   828                                  
   829 0000030B 90                      align 2
   830                                  
   831                                  bss_start:
   832                                  
   833                                  ABSOLUTE bss_start
   834                                  
   835                                  ; 20/04/2022 - Retro UNIX 386 v1 & v1.1 & v1.2
   836                                  ;fold:	resd 1
   837                                  ;fnew:	resd 1
   838                                  ; 22/04/2022 - Retro UNIX 8086 v1
   839 0000030C ????                    fold:	resw 1
   840 0000030E ????                    fnew:	resw 1
   841                                  
   842                                  ; 24/04/2022
   843 00000310 ????                    filesize: resw 1 ; cptest0.s
   844                                  
   845                                  ;stbuf2: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data)
   846                                  ;stbuf1: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data)
   847                                  ; 21/04/2022
   848 00000312 <res 22h>               stbuf2: resb 34 ; for Retro UNIX 386 v1.1 (34 byte sysstat data)
   849 00000334 <res 22h>               stbuf1: resb 34 ; for Retro UNIX 386 v1.1 (34 byte sysstat data)
   850                                  
   851                                  ; 24/04/2022 - cptest1.s
   852 00000356 <res 80h>               fnbuf:	resb 128 ; file name buffer
   853                                  
   854                                  ;iobuf:	resb BSIZE ; resb 512 ; path name buffer
   855 000003D6 <res 7B3Ch>             iobuf:	resb MAXFSIZE
   856                                  
   857                                  ; 20/04/2022
   858                                  ;-----------------------------------------------------------------
   859                                  ; Original UNIX v7 - cp (utility) c source code (cp.c)
   860                                  ;-----------------------------------------------------------------
   861                                  ;/* UNIX V7 source code: see www.tuhs.org for details. */;
   862                                  ;
   863                                  ;/*
   864                                  ; * cp oldfile newfile
   865                                  ; */
   866                                  ;
   867                                  ;#define BSIZE	512
   868                                  ;#include <stdio.h>
   869                                  ;#include <sys/types.h>
   870                                  ;#include <sys/stat.h>
   871                                  ;struct	stat stbuf1, stbuf2;
   872                                  ;char iobuf[BSIZE];
   873                                  ;
   874                                  ;main(argc, argv)
   875                                  ;char *argv[];
   876                                  ;{
   877                                  ;	register i, r;
   878                                  ;
   879                                  ;	if (argc < 3) 
   880                                  ;		goto usage;
   881                                  ;	if (argc > 3) {
   882                                  ;		if (stat(argv[argc-1], &stbuf2) < 0)
   883                                  ;			goto usage;
   884                                  ;		if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) 
   885                                  ;			goto usage;
   886                                  ;	}
   887                                  ;	r = 0;
   888                                  ;	for(i=1; i<argc-1;i++)
   889                                  ;		r |= copy(argv[i], argv[argc-1]);
   890                                  ;	exit(r);
   891                                  ;usage:
   892                                  ;	fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n");
   893                                  ;	exit(1);
   894                                  ;}
   895                                  ;
   896                                  ;copy(from, to)
   897                                  ;char *from, *to;
   898                                  ;{
   899                                  ;	int fold, fnew, n;
   900                                  ;	register char *p1, *p2, *bp;
   901                                  ;	int mode;
   902                                  ;	if ((fold = open(from, 0)) < 0) {
   903                                  ;		fprintf(stderr, "cp: cannot open %s\n", from);
   904                                  ;		return(1);
   905                                  ;	}
   906                                  ;	fstat(fold, &stbuf1);
   907                                  ;	mode = stbuf1.st_mode;
   908                                  ;	/* is target a directory? */
   909                                  ;	if (stat(to, &stbuf2) >=0 &&
   910                                  ;	   (stbuf2.st_mode&S_IFMT) == S_IFDIR) {
   911                                  ;		p1 = from;
   912                                  ;		p2 = to;
   913                                  ;		bp = iobuf;
   914                                  ;		while(*bp++ = *p2++)
   915                                  ;			;
   916                                  ;		bp[-1] = '/';
   917                                  ;		p2 = bp;
   918                                  ;		while(*bp = *p1++)
   919                                  ;			if (*bp++ == '/')
   920                                  ;				bp = p2;
   921                                  ;		to = iobuf;
   922                                  ;	}
   923                                  ;	if (stat(to, &stbuf2) >= 0) {
   924                                  ;		if (stbuf1.st_dev == stbuf2.st_dev &&
   925                                  ;		   stbuf1.st_ino == stbuf2.st_ino) {
   926                                  ;			fprintf(stderr, "cp: cannot copy file to itself.\n");
   927                                  ;			return(1);
   928                                  ;		}
   929                                  ;	}
   930                                  ;	if ((fnew = creat(to, mode)) < 0) {
   931                                  ;		fprintf(stderr, "cp: cannot create %s\n", to);
   932                                  ;		close(fold);
   933                                  ;		return(1);
   934                                  ;	}
   935                                  ;	while(n = read(fold,  iobuf,  BSIZE)) {
   936                                  ;		if (n < 0) {
   937                                  ;			fprintf(stderr, "cp: read error\n");
   938                                  ;			close(fold);
   939                                  ;			close(fnew);
   940                                  ;			return(1);
   941                                  ;		} else
   942                                  ;			if (write(fnew, iobuf, n) != n) {
   943                                  ;				fprintf(stderr, "cp: write error.\n");
   944                                  ;				close(fold);
   945                                  ;				close(fnew);
   946                                  ;				return(1);
   947                                  ;			}
   948                                  ;	}
   949                                  ;	close(fold);
   950                                  ;	close(fnew);
   951                                  ;	return(0);
   952                                  ;}
