1 ; **************************************************************************** 2 ; cp386.s (cp0.s) - by Erdogan Tan - 20/04/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 386 v1 - copy -- cp oldfile newfile 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 cp0.s -l cp0.txt -o cp0 -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 22 ; 12/01/2022 (Retro UNIX 386 v1.2) 23 ; 13/10/2015 24 25 ; UNIX v1 system calls 26 _rele equ 0 27 _exit equ 1 28 _fork equ 2 29 _read equ 3 30 _write equ 4 31 _open equ 5 32 _close equ 6 33 _wait equ 7 34 _creat equ 8 35 _link equ 9 36 _unlink equ 10 37 _exec equ 11 38 _chdir equ 12 39 _time equ 13 40 _mkdir equ 14 41 _chmod equ 15 42 _chown equ 16 43 _break equ 17 44 _stat equ 18 45 _seek equ 19 46 _tell equ 20 47 _mount equ 21 48 _umount equ 22 49 _setuid equ 23 50 _getuid equ 24 51 _stime equ 25 52 _quit equ 26 53 _intr equ 27 54 _fstat equ 28 55 _emt equ 29 56 _mdate equ 30 57 _stty equ 31 58 _gtty equ 32 59 _ilgins equ 33 60 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 61 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 62 _geterr equ 36 ; Retro UNIX 386 v1 feature only ! 63 ; 12/01/2022 - Retro UNIX 386 v1.2 64 ; Retro UNIX 386 v2 system calls 65 _setgid equ 37 66 _getgid equ 38 67 _sysver equ 39 ; (get) Retro Unix 386 version 68 69 ;;; 70 ESCKey equ 1Bh 71 EnterKey equ 0Dh 72 73 %macro sys 1-4 74 ; 03/09/2015 75 ; 13/04/2015 76 ; Retro UNIX 386 v1 system call. 77 %if %0 >= 2 78 mov ebx, %2 79 %if %0 >= 3 80 mov ecx, %3 81 ;%if %0 = 4 82 %if %0 >= 4 ; 11/03/2022 83 mov edx, %4 84 %endif 85 %endif 86 %endif 87 mov eax, %1 88 int 30h 89 %endmacro 90 91 ; Retro UNIX 386 v1 system call format: 92 ; sys systemcall (eax) , , 93 94 ; 11/03/2022 95 ; Note: Above 'sys' macro has limitation about register positions; 96 ; ebx, ecx, edx registers must not be used after their 97 ; positions in sys macro. 98 ; for example: 99 ; 'sys _write, 1, msg, ecx' is defective, because 100 ; ecx will be used/assigned before edx in 'sys' macro. 101 ; correct order may be: 102 ; 'sys _write, 1, msg, eax ; (eax = byte count) 103 104 struc stat 105 ; Note: This is for Retro UNIX v1.1 'sysstat' output !!! 106 ; (34 bytes) 107 00000000 ???? .inode: resw 1 108 00000002 ???? .mode: resw 1 109 00000004 ?? .nlinks: resb 1 110 00000005 ?? .uid: resb 1 111 00000006 ???? .size: resw 1 112 00000008 .dskptr: resw 8 113 00000018 ???????? .ctime: resd 1 114 0000001C ???????? .mtime: resd 1 115 00000020 ???? .rsvd: resw 1 116 .strucsize: 117 endstruc 118 119 ;struc stat 120 ; ; Note: This is for Retro UNIX v1.2 'sysstat' output !!! 121 ; ; (66 bytes) 122 ; .inode: resw 1 123 ; .mode: resw 1 124 ; .nlinks: resw 1 125 ; .uid: resw 1 126 ; .gid: resb 1 127 ; .size_h: resb 1 128 ; .size: resd 1 129 ; .dskptr: resd 10 130 ; .atime: resd 1 131 ; .mtime: resd 1 132 ; .ctime: resd 1 133 ; .strucsize: 134 ;endstruc 135 136 ;S_IFMT equ 0F000h ; /* type of file */ 137 ;S_IFDIR equ 04000h ; /* directory */ 138 ;S_IFCHR equ 02000h ; /* character special */ 139 ;S_IFBLK equ 06000h ; /* block special */ 140 ;S_IFREG equ 08000h ; /* regular */ 141 ;S_ISUID equ 00800h ; /* set user id on execution */ 142 ;S_ISGID equ 00400h ; /* set group id on execution */ 143 ;S_IREAD equ 00100h ; /* read permission, owner */ 144 ;S_IWRITE equ 00080h ; /* write permission, owner */ 145 ;S_IEXEC equ 00040h ; /* execute/search permission, owner */ 146 147 ; 24/04/2022 148 ; 21/04/2022 - UNIX v1 inode 149 ; byte 1 150 S_ALLOC equ 080h ; Allocated flag 151 S_IFDIR equ 040h ; Directory flag 152 S_IFMDF equ 020h ; File modified flag (always on) 153 S_IFLRG equ 010h ; Large File flag 154 ; byte 0 155 S_ISUID equ 020h ; Set User ID On Execution flag 156 S_IEXEC equ 010h ; Executable File flag 157 S_IREAD equ 008h ; Owner's Read Permission flag 158 S_IWRITE equ 004h ; Owner's Write Permission flag 159 160 BSIZE equ 512 161 162 ;----------------------------------------------------------------- 163 ; text - code 164 ;----------------------------------------------------------------- 165 166 [BITS 32] ; 32-bit intructions (for 80386 protected mode) 167 168 [ORG 0] 169 170 START_CODE: 171 ; 20/04/2022 172 ; main(argc, argv) 173 174 00000000 89E6 mov esi, esp 175 00000002 89F7 mov edi, esi 176 00000004 AD lodsd ; number of arguments 177 ;mov edi, esi 178 ;mov [argc], eax 179 00000005 A2[65020000] mov [argc], al 180 181 ;if (argc < 3) 182 ; goto usage; 183 184 ;cmp eax, 3 185 0000000A 3C03 cmp al, 3 186 0000000C 7337 jnb short cp_0 ; if (argc > 3) { 187 0000000E FEC8 dec al ; 21/04/2022 188 00000010 7516 jnz short cp_usage 189 sys _msg, program_msg, 255, 0Fh 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000012 BB[66020000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000017 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 0000001C BA0F000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000021 B823000000 <1> mov eax, %1 88 00000026 CD30 <1> int 30h 190 cp_usage: 191 ; fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n"); 192 sys _msg, usage_msg, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000028 BB[9D020000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 0000002D B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 00000032 BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000037 B823000000 <1> mov eax, %1 88 0000003C CD30 <1> int 30h 193 cp_exit: 194 sys _exit ; sys exit 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 0000003E B801000000 <1> mov eax, %1 88 00000043 CD30 <1> int 30h 195 ;hlt: 196 ; nop 197 ; nop 198 ; jmp short hlt 199 200 cp_0: 201 00000045 89C2 mov edx, eax ; [argc] 202 ; 21/04/2022 203 ;;dec edx ; argc-1 204 ;dec dl 205 00000047 C0E202 shl dl, 2 ; * 4 206 0000004A 01D7 add edi, edx 207 208 ; 21/04/2022 209 0000004C 3C03 cmp al,3 210 0000004E 7619 jna short cp_1 211 212 sys _stat, [edi], stbuf2 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000050 8B1F <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000052 B9[4C030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000057 B812000000 <1> mov eax, %1 88 0000005C CD30 <1> int 30h 213 0000005E 72C8 jc short cp_usage 214 215 ;; check retro unix v2 inode flags 216 ;; (a bit different than unix v7 inode flags) 217 ;; if it is a directory.. 218 ;; regular file flag and dir flag must be 1 219 ;mov al, [stbuf2+stat.mode+1] 220 ;and al, S_IFDIR|S_IFREG 221 ;cmp al, S_IFDIR|S_IFREG ; directory ? 222 ;jne short cp_usage ; no 223 224 ;; check if it is a device file 225 ;;test al, S_IFREG ; regular file ? 226 ;;jz short cp_usage ; no 227 ;;and al, S_IFDIR ; directory ? 228 ;;jz short cp_usage ; no 229 230 ; 21/04/2022 231 ; check (unix v1 inode) directory flag 232 00000060 F605[4F030000]40 test byte [stbuf2+stat.mode+1], S_IFDIR ; directory ? 233 00000067 74BF jz short cp_usage ; no 234 235 cp_1: 236 ; esi = esp+4 = argv[0] ; executable file name (cp) 237 00000069 AD lodsd ; 21/04/2022 238 cp_loop: ; for(i=1; i 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000085 BB[3B030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 0000008A B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 0000008F BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000094 B823000000 <1> mov eax, %1 88 00000099 CD30 <1> int 30h 257 ;cp_exit: 258 sys _exit ; sys exit 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 0000009B B801000000 <1> mov eax, %1 88 000000A0 CD30 <1> int 30h 259 260 ;_halt: 261 ; nop 262 ; jmp short _halt 263 264 copy: ; copy(from, to) 265 ; 266 ; 21/04/2022 267 ; 20/04/2022 268 ; INPUT: 269 ; esi = pointer to file name to be copied 270 ; edi = ptr to new file name or destination dir 271 ; OUTPUT: 272 ; cf = 0 -> OK 273 ; cf = 1 -> Error ! 274 ; 275 ; Modified registers: eax, ebx, ecx, edx, ebp 276 ; 277 278 ; open (old) file for read 279 sys _open, [esi], 0 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000A2 8B1E <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000A4 B900000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000000A9 B805000000 <1> mov eax, %1 88 000000AE CD30 <1> int 30h 280 000000B0 7341 jnc short cp_3 281 282 ; esi = file name (from) 283 284 ;fprintf(stderr, "cp: cannot open %s\n", from); 285 ; return(1); 286 287 sys _msg, cno_err_msg, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000B2 BB[C6020000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000B7 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000000BC BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000000C1 B823000000 <1> mov eax, %1 88 000000C6 CD30 <1> int 30h 288 ; file name (from) 289 sys _msg, [esi], 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000C8 8B1E <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000CA B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000000CF BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000000D4 B823000000 <1> mov eax, %1 88 000000D9 CD30 <1> int 30h 290 write_nl: 291 ; new/next line 292 sys _msg, nextline, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000DB BB[C3020000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000E0 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000000E5 BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000000EA B823000000 <1> mov eax, %1 88 000000EF CD30 <1> int 30h 293 000000F1 F9 stc ; return with error (cf=1) 294 000000F2 C3 retn 295 296 cp_3: 297 000000F3 A3[44030000] mov [fold], eax ; file (descriptor) number 298 299 ; (from) 300 sys _fstat, [fold], stbuf1 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000F8 8B1D[44030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000FE B9[6E030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000103 B81C000000 <1> mov eax, %1 88 00000108 CD30 <1> int 30h 301 302 ; save mode 303 ;mov ax, [stbuf1.mode] 304 ;mov [mode], ax 305 306 ; (to) 307 ;sys _stat, [edi], stbuf2 ; stat(to, &stbuf2) 308 ;jnc short cp_4 309 ;jmp cp_9 310 311 ; 22/04/2022 312 0000010A 8B2F mov ebp, [edi] ; ! (cp_8) ! 313 sys _stat, ebp, stbuf2 ; stat(to, &stbuf2) 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000010C 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 0000010E B9[4C030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000113 B812000000 <1> mov eax, %1 88 00000118 CD30 <1> int 30h 314 0000011A 7305 jnc short cp_4 315 0000011C E980000000 jmp cp_9 316 317 cp_4: 318 ; /* is target a directory? */ 319 320 ;; check retro unix v2 inode flags 321 ;; (a bit different than unix v7 inode flags) 322 ;; regular file flag and dir flag must be 1 for a dir 323 ;mov al, [stbuf2+stat.mode+1] 324 ;and al, S_IFDIR|S_IFREG 325 ;cmp al, S_IFDIR|S_IFREG ; directory ? 326 ;jne short cp_8 ; no, overwrite (create file) 327 ; (if the new file is not same file) 328 329 ;; check if it is a device file 330 ;;test al, S_IFREG ; regular file ? 331 ;;jz short cp_error ; no 332 ;;and al, S_IFDIR ; directory ? 333 ;;jz short cp_error ; no 334 335 ; 21/04/2022 336 ; check (unix v1 inode) directory flag 337 00000121 F605[4F030000]40 test byte [stbuf2+stat.mode+1], S_IFDIR ; directory ? 338 00000128 7441 jz short cp_8 ; no, overwrite (create file) 339 ; (if the new file is not same file) 340 341 ; add (old) file name to (destination ) path 342 ; (directory name +'/'+ file name) 343 344 0000012A 89F5 mov ebp, esi ; save esi 345 0000012C 8B37 mov esi, [edi] ; directory name address 346 0000012E 89FB mov ebx, edi ; save edi 347 00000130 BF[90030000] mov edi, iobuf ; (new) path name buffer addr 348 349 ; p1 = from; 350 ; p2 = to; 351 ; bp = iobuf; 352 cp_5: ; while(*bp++ = *p2++) 353 00000135 AC lodsb 354 00000136 AA stosb 355 00000137 20C0 and al, al 356 00000139 75FA jnz short cp_5 357 0000013B C647FF2F mov byte [edi-1], '/' ; bp[-1] = '/'; 358 ; p2 = bp 359 0000013F 89FA mov edx, edi 360 00000141 8B7500 mov esi, [ebp] ; *p1 ; from 361 cp_6: ; while(*bp = *p1++) 362 00000144 AC lodsb 363 00000145 AA stosb 364 00000146 08C0 or al, al 365 00000148 7408 jz short cp_7 366 0000014A 3C2F cmp al, '/' ; if (*bp++ == '/') 367 0000014C 75F6 jne short cp_6 368 ; bp = p2 369 ; 21/04/2022 370 0000014E 89D7 mov edi, edx ; (discard path before file name) 371 00000150 EBF2 jmp short cp_6 372 cp_7: 373 00000152 89EE mov esi, ebp ; restore esi 374 00000154 89DF mov edi, ebx ; restore edi 375 ; to = iobuf 376 00000156 BD[90030000] mov ebp, iobuf 377 378 sys _stat, ebp, stbuf2 ; stat(to, &stbuf2) >= 0 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000015B 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 0000015D B9[4C030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000162 B812000000 <1> mov eax, %1 88 00000167 CD30 <1> int 30h 379 00000169 7236 jc short cp_10 ; create new file 380 381 cp_8: 382 ;if (stbuf1.st_dev == stbuf2.st_dev && 383 ; stbuf1.st_ino == stbuf2.st_ino) { 384 ; fprintf(stderr, "cp: cannot copy file to itself.\n"); 385 ; return(1); 386 387 0000016B 66A1[6E030000] mov ax, [stbuf1+stat.inode] 388 00000171 663B05[4C030000] cmp ax, [stbuf2+stat.inode] 389 00000178 7527 jne short cp_10 390 391 ; same file ! error... 392 0000017A BD[D9020000] mov ebp, cncis_err_msg ; error message 393 ; esi = file name (from) 394 write_err_msg: 395 sys _msg, ebp, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000017F 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000181 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 00000186 BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 0000018B B823000000 <1> mov eax, %1 88 00000190 CD30 <1> int 30h 396 ; close (old) file 397 sys _close, [fold] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000192 8B1D[44030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000198 B806000000 <1> mov eax, %1 88 0000019D CD30 <1> int 30h 398 0000019F F9 stc ; return with error (cf=1) 399 000001A0 C3 retn 400 401 cp_9: 402 ; 22/04/2022 403 ; ebp = [edi] 404 ; 21/04/2022 405 ; new file (asciiz name address) 406 ;mov ebp, [edi] 407 408 ; create new file (truncate if it exists) 409 cp_10: 410 ; fnew = creat(to, mode) 411 000001A1 0FB70D[70030000] movzx ecx, word [stbuf1+stat.mode] 412 ; ecx = mode 413 sys _creat, ebp 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001A8 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000001AA B808000000 <1> mov eax, %1 88 000001AF CD30 <1> int 30h 414 000001B1 733B jnc short cp_11 415 416 ;if ((fnew = creat(to, mode)) < 0) { 417 ; fprintf(stderr, "cp: cannot create %s\n", to); 418 ; close(fold); 419 ; return(1); 420 421 ; 24/04/2022 422 sys _close, [fold] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001B3 8B1D[44030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000001B9 B806000000 <1> mov eax, %1 88 000001BE CD30 <1> int 30h 423 424 ; error message 425 sys _msg, ccf_err_msg, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001C0 BB[FD020000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000001C5 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000001CA BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000001CF B823000000 <1> mov eax, %1 88 000001D4 CD30 <1> int 30h 426 427 ; 24/04/2022 428 ; and file name (to) -at the end of error message- 429 sys _msg, ebp, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001D6 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000001D8 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000001DD BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000001E2 B823000000 <1> mov eax, %1 88 000001E7 CD30 <1> int 30h 430 ; write next line (move cursor to next line) 431 ; and return (from this/copy subroutine) 432 000001E9 E9EDFEFFFF jmp write_nl 433 434 cp_11: 435 ; 21/04/2022 436 000001EE A3[48030000] mov [fnew], eax 437 cp_rw_next: 438 ; while(n = read(fold, iobuf, BSIZE)) 439 sys _read, [fold], iobuf, BSIZE 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001F3 8B1D[44030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000001F9 B9[90030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000001FE BA00020000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000203 B803000000 <1> mov eax, %1 88 00000208 CD30 <1> int 30h 440 0000020A 7317 jnc short cp_12 441 442 ;if (n < 0) { 443 ; fprintf(stderr, "cp: read error\n"); 444 445 ; write read error message 446 0000020C BD[12030000] mov ebp, crd_err_msg 447 448 cp_rw_err: 449 ; 21/04/2022 450 ; cf = 1 451 sys _close, [fnew] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000211 8B1D[48030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000217 B806000000 <1> mov eax, %1 88 0000021C CD30 <1> int 30h 452 0000021E E95CFFFFFF jmp write_err_msg 453 454 cp_12: 455 ; eax = read count 456 ; eax = 0 -> eof 457 00000223 09C0 or eax, eax 458 00000225 7423 jz short cp_14 ; eof 459 460 00000227 89C5 mov ebp, eax ; n 461 ; write(fnew, iobuf, n) 462 sys _write, [fnew], iobuf, ebp 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000229 8B1D[48030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 0000022F B9[90030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 00000234 89EA <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000236 B804000000 <1> mov eax, %1 88 0000023B CD30 <1> int 30h 463 0000023D 7204 jc short cp_13 464 465 ;if (write(fnew, iobuf, n) != n) 466 ; fprintf(stderr, "cp: write error.\n"); 467 ; close(fold); 468 ; close(fnew); 469 ; return(1); 470 471 ; eax = written bytes 472 0000023F 39E8 cmp eax, ebp 473 ;je short cp_11 ; read next (block) 474 ; 21/04/2022 475 00000241 74B0 je short cp_rw_next 476 ; error ! 477 ; eax < ebp --> cf = 1 478 cp_13: 479 ; close new file 480 ; and then write error mesage 481 ; and then close old file 482 ; and then write (move cursor to) next line 483 ; and then return (from subroutine) 484 ;sys _close, [fnew] 485 486 ; write error message 487 00000243 BD[26030000] mov ebp, cwr_err_msg 488 ;jmp short write_err_msg 489 ; 21/04/2022 490 00000248 EBC7 jmp short cp_rw_err 491 492 ; eof 493 cp_14: 494 ;close(fold); 495 ;close(fnew); 496 ;return(0); 497 498 sys _close, [fold] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000024A 8B1D[44030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000250 B806000000 <1> mov eax, %1 88 00000255 CD30 <1> int 30h 499 sys _close, [fnew] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000257 8B1D[48030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 0000025D B806000000 <1> mov eax, %1 88 00000262 CD30 <1> int 30h 500 501 ;clc 502 00000264 C3 retn 503 504 ;----------------------------------------------------------------- 505 ; data - initialized data 506 ;----------------------------------------------------------------- 507 508 ;argc: dd 0 509 00000265 00 argc: db 0 510 511 ; ---------------------------------------------------------------- 512 513 program_msg: 514 00000266 0D0A db 0Dh, 0Ah 515 00000268 526574726F20554E49- db 'Retro UNIX 386 v1 COPY by Erdogan TAN - 24/04/2022' 515 00000271 582033383620763120- 515 0000027A 434F50592062792045- 515 00000283 72646F67616E205441- 515 0000028C 4E202D2032342F3034- 515 00000295 2F32303232 516 0000029A 0D0A00 db 0Dh, 0Ah, 0 517 518 usage_msg: 519 0000029D 0D0A db 0Dh, 0Ah 520 0000029F 55736167653A206370- db 'Usage: cp: f1 f2; or cp f1 ... fn d2' 520 000002A8 3A2066312066323B20- 520 000002B1 6F7220637020663120- 520 000002BA 2E2E2E20666E206432 521 nextline: 522 000002C3 0D0A00 db 0Dh, 0Ah, 0 523 524 cno_err_msg: 525 000002C6 0D0A db 0Dh, 0Ah 526 000002C8 63703A2063616E6E6F- db 'cp: cannot open ' 526 000002D1 74206F70656E20 527 000002D8 00 db 0 528 cncis_err_msg: 529 000002D9 0D0A db 0Dh, 0Ah 530 000002DB 63703A2063616E6E6F- db 'cp: cannot copy file to itself.' 530 000002E4 7420636F7079206669- 530 000002ED 6C6520746F20697473- 530 000002F6 656C662E 531 000002FA 0D0A00 db 0Dh, 0Ah, 0 532 533 ccf_err_msg: 534 000002FD 0D0A db 0Dh, 0Ah 535 000002FF 63703A2063616E6E6F- db 'cp: cannot create ' 535 00000308 742063726561746520 536 00000311 00 db 0 537 538 crd_err_msg: 539 00000312 0D0A db 0Dh, 0Ah 540 00000314 63703A207265616420- db 'cp: read error.' 540 0000031D 6572726F722E 541 00000323 0D0A00 db 0Dh, 0Ah, 0 542 543 cwr_err_msg: 544 00000326 0D0A db 0Dh, 0Ah 545 00000328 63703A207772697465- db 'cp: write error.' 545 00000331 206572726F722E 546 00000338 0D0A00 db 0Dh, 0Ah, 0 547 548 ok_msg: 549 0000033B 0D0A db 0Dh, 0Ah 550 0000033D 4F4B2E db 'OK.' 551 00000340 0D0A00 db 0Dh, 0Ah, 0 552 553 00000343 00 errors: db 0 554 555 ;----------------------------------------------------------------- 556 ; bss - uninitialized data 557 ;----------------------------------------------------------------- 558 559 align 2 560 561 bss_start: 562 563 ABSOLUTE bss_start 564 565 ; 20/04/2022 566 00000344 ???????? fold: resd 1 567 00000348 ???????? fnew: resd 1 568 569 ;stbuf2: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data) 570 ;stbuf1: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data) 571 ; 21/04/2022 572 0000034C stbuf2: resb 34 ; for Retro UNIX 386 v1.1 (34 byte sysstat data) 573 0000036E stbuf1: resb 34 ; for Retro UNIX 386 v1.1 (34 byte sysstat data) 574 575 00000390 iobuf: resb BSIZE ; resb 512 ; path name buffer 576 577 ; 20/04/2022 578 ;----------------------------------------------------------------- 579 ; Original UNIX v7 - cp (utility) c source code (cp.c) 580 ;----------------------------------------------------------------- 581 ;/* UNIX V7 source code: see www.tuhs.org for details. */; 582 ; 583 ;/* 584 ; * cp oldfile newfile 585 ; */ 586 ; 587 ;#define BSIZE 512 588 ;#include 589 ;#include 590 ;#include 591 ;struct stat stbuf1, stbuf2; 592 ;char iobuf[BSIZE]; 593 ; 594 ;main(argc, argv) 595 ;char *argv[]; 596 ;{ 597 ; register i, r; 598 ; 599 ; if (argc < 3) 600 ; goto usage; 601 ; if (argc > 3) { 602 ; if (stat(argv[argc-1], &stbuf2) < 0) 603 ; goto usage; 604 ; if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) 605 ; goto usage; 606 ; } 607 ; r = 0; 608 ; for(i=1; i=0 && 630 ; (stbuf2.st_mode&S_IFMT) == S_IFDIR) { 631 ; p1 = from; 632 ; p2 = to; 633 ; bp = iobuf; 634 ; while(*bp++ = *p2++) 635 ; ; 636 ; bp[-1] = '/'; 637 ; p2 = bp; 638 ; while(*bp = *p1++) 639 ; if (*bp++ == '/') 640 ; bp = p2; 641 ; to = iobuf; 642 ; } 643 ; if (stat(to, &stbuf2) >= 0) { 644 ; if (stbuf1.st_dev == stbuf2.st_dev && 645 ; stbuf1.st_ino == stbuf2.st_ino) { 646 ; fprintf(stderr, "cp: cannot copy file to itself.\n"); 647 ; return(1); 648 ; } 649 ; } 650 ; if ((fnew = creat(to, mode)) < 0) { 651 ; fprintf(stderr, "cp: cannot create %s\n", to); 652 ; close(fold); 653 ; return(1); 654 ; } 655 ; while(n = read(fold, iobuf, BSIZE)) { 656 ; if (n < 0) { 657 ; fprintf(stderr, "cp: read error\n"); 658 ; close(fold); 659 ; close(fnew); 660 ; return(1); 661 ; } else 662 ; if (write(fnew, iobuf, n) != n) { 663 ; fprintf(stderr, "cp: write error.\n"); 664 ; close(fold); 665 ; close(fnew); 666 ; return(1); 667 ; } 668 ; } 669 ; close(fold); 670 ; close(fnew); 671 ; return(0); 672 ;}