1 ; **************************************************************************** 2 ; cp386.s (cp1.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 cp1.s -l cp1.txt -o cp1 -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.2 'sysstat' output !!! 106 ; (66 bytes) 107 00000000 ???? .inode: resw 1 108 00000002 ???? .mode: resw 1 109 00000004 ???? .nlinks: resw 1 110 00000006 ???? .uid: resw 1 111 00000008 ?? .gid: resb 1 112 00000009 ?? .size_h: resb 1 113 0000000A ???????? .size: resd 1 114 0000000E .dskptr: resd 10 115 00000036 ???????? .atime: resd 1 116 0000003A ???????? .mtime: resd 1 117 0000003E ???????? .ctime: resd 1 118 .strucsize: 119 endstruc 120 121 ; ; 20/04/2022 122 ;struc stat 123 ; ; Note: Retro UNIX v2 'sysstat' output DRAFT !!! 124 ; ; (72 bytes) 125 ; .idev: resb 1 126 ; .rsvd: resb 3 127 ; .inum: resd 1 128 ; .mode: resw 1 129 ; .nlinks: resw 1 130 ; .uid: resw 1 131 ; .gid: resb 1 132 ; .size_h: resb 1 133 ; .size: resd 1 134 ; .dskptr: resd 10 135 ; .atime: resd 1 136 ; .mtime: resd 1 137 ; .ctime: resd 1 138 ; .strucsize: 139 ;endstruc 140 141 ;S_IFMT equ 0F000h ; /* type of file */ 142 ;S_IFDIR equ 04000h ; /* directory */ 143 ;S_IFCHR equ 02000h ; /* character special */ 144 ;S_IFBLK equ 06000h ; /* block special */ 145 ;S_IFREG equ 08000h ; /* regular */ 146 ;S_ISUID equ 00800h ; /* set user id on execution */ 147 ;S_ISGID equ 00400h ; /* set group id on execution */ 148 ;S_IREAD equ 00100h ; /* read permission, owner */ 149 ;S_IWRITE equ 00080h ; /* write permission, owner */ 150 ;S_IEXEC equ 00040h ; /* execute/search permission, owner */ 151 152 S_IFMT equ 0F0h ; /* type of file */ 153 S_IFDIR equ 040h ; /* directory */ 154 S_IFCHR equ 020h ; /* character special */ 155 S_IFBLK equ 060h ; /* block special */ 156 S_IFREG equ 080h ; /* regular */ 157 S_ISUID equ 008h ; /* set user id on execution */ 158 S_ISGID equ 004h ; /* set group id on execution */ 159 S_IREAD equ 001h ; /* read permission, owner */ 160 S_IWRITE equ 080h ; /* write permission, owner */ 161 S_IEXEC equ 040h ; /* execute/search permission, owner */ 162 163 BSIZE equ 512 164 165 ;----------------------------------------------------------------- 166 ; text - code 167 ;----------------------------------------------------------------- 168 169 [BITS 32] ; 32-bit intructions (for 80386 protected mode) 170 171 [ORG 0] 172 173 START_CODE: 174 ; 20/04/2022 175 ; main(argc, argv) 176 177 00000000 89E6 mov esi, esp 178 00000002 89F7 mov edi, esi 179 00000004 AD lodsd ; number of arguments 180 ;mov edi, esi 181 ;mov [argc], eax 182 00000005 A2[69020000] mov [argc], al 183 184 ;if (argc < 3) 185 ; goto usage; 186 187 ;cmp eax, 3 188 0000000A 3C03 cmp al, 3 189 0000000C 7337 jnb short cp_0 ; if (argc > 3) { 190 0000000E FEC8 dec al ; 21/04/2022 191 00000010 7516 jnz short cp_usage 192 sys _msg, program_msg, 255, 0Fh 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000012 BB[6A020000] <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 193 cp_usage: 194 ; fprintf(stderr, "Usage: cp: f1 f2; or cp f1 ... fn d2\n"); 195 sys _msg, usage_msg, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000028 BB[A3020000] <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 196 cp_exit: 197 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 198 ;hlt: 199 ; nop 200 ; nop 201 ; jmp short hlt 202 203 cp_0: 204 00000045 89C2 mov edx, eax ; [argc] 205 ; 21/04/2022 206 ;;dec edx ; argc-1 207 ;dec dl 208 00000047 C0E202 shl dl, 2 ; * 4 209 0000004A 01D7 add edi, edx 210 211 ; 21/04/2022 212 0000004C 3C03 cmp al,3 213 0000004E 761B jna short cp_1 214 215 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[52030000] <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 216 0000005E 72C8 jc short cp_usage 217 218 ; check retro unix v2 inode flags 219 ; (a bit different than unix v7 inode flags) 220 ; if it is a directory.. 221 ; regular file flag and dir flag must be 1 222 00000060 A0[55030000] mov al, [stbuf2+stat.mode+1] 223 00000065 24C0 and al, S_IFDIR|S_IFREG 224 00000067 3CC0 cmp al, S_IFDIR|S_IFREG ; directory ? 225 00000069 75BD jne short cp_usage ; no 226 227 ; check if it is a device file 228 ;test al, S_IFREG ; regular file ? 229 ;jz short cp_usage ; no 230 ;and al, S_IFDIR ; directory ? 231 ;jz short cp_usage ; no 232 233 cp_1: 234 ; esi = esp+4 = argv[0] ; executable file name (cp) 235 0000006B AD lodsd ; 21/04/2022 236 cp_loop: ; for(i=1; i 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000087 BB[41030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 0000008C B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 00000091 BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000096 B823000000 <1> mov eax, %1 88 0000009B CD30 <1> int 30h 255 ;cp_exit: 256 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 0000009D B801000000 <1> mov eax, %1 88 000000A2 CD30 <1> int 30h 257 258 ;_halt: 259 ; nop 260 ; jmp short _halt 261 262 copy: ; copy(from, to) 263 ; 264 ; 21/04/2022 265 ; 20/04/2022 266 ; INPUT: 267 ; esi = pointer to file name to be copied 268 ; edi = ptr to new file name or destination dir 269 ; OUTPUT: 270 ; cf = 0 -> OK 271 ; cf = 1 -> Error ! 272 ; 273 ; Modified registers: eax, ebx, ecx, edx, ebp 274 ; 275 276 ; open (old) file for read 277 sys _open, [esi], 0 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000A4 8B1E <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000A6 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 000000AB B805000000 <1> mov eax, %1 88 000000B0 CD30 <1> int 30h 278 000000B2 7341 jnc short cp_3 279 280 ; esi = file name (from) 281 282 ;fprintf(stderr, "cp: cannot open %s\n", from); 283 ; return(1); 284 285 sys _msg, cno_err_msg, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000B4 BB[CC020000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000B9 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000000BE BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000000C3 B823000000 <1> mov eax, %1 88 000000C8 CD30 <1> int 30h 286 ; file name (from) 287 sys _msg, [esi], 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000CA 8B1E <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000CC B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000000D1 BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000000D6 B823000000 <1> mov eax, %1 88 000000DB CD30 <1> int 30h 288 write_nl: 289 ; new/next line 290 sys _msg, nextline, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000DD BB[C9020000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000000E2 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000000E7 BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000000EC B823000000 <1> mov eax, %1 88 000000F1 CD30 <1> int 30h 291 000000F3 F9 stc ; return with error (cf=1) 292 000000F4 C3 retn 293 294 cp_3: 295 000000F5 A3[4A030000] mov [fold], eax ; file (descriptor) number 296 297 ; (from) 298 sys _fstat, [fold], stbuf1 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000000FA 8B1D[4A030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000100 B9[94030000] <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 00000105 B81C000000 <1> mov eax, %1 88 0000010A CD30 <1> int 30h 299 300 ; save mode 301 ;mov ax, [stbuf1.mode] 302 ;mov [mode], ax 303 304 ; (to) 305 ;sys _stat, [edi], stbuf2 ; stat(to, &stbuf2) 306 ;jnc short cp_4 307 ;jmp cp_9 308 309 ; 22/04/2022 310 0000010C 8B2F mov ebp, [edi] ; ! (cp_8) ! 311 sys _stat, ebp, stbuf2 ; stat(to, &stbuf2) 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000010E 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000110 B9[52030000] <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 00000115 B812000000 <1> mov eax, %1 88 0000011A CD30 <1> int 30h 312 0000011C 7305 jnc short cp_4 313 0000011E E982000000 jmp cp_9 314 315 cp_4: 316 ; /* is target a directory? */ 317 318 ; check retro unix v2 inode flags 319 ; (a bit different than unix v7 inode flags) 320 ; regular file flag and dir flag must be 1 for a dir 321 00000123 A0[55030000] mov al, [stbuf2+stat.mode+1] 322 00000128 24C0 and al, S_IFDIR|S_IFREG 323 0000012A 3CC0 cmp al, S_IFDIR|S_IFREG ; directory ? 324 0000012C 7541 jne short cp_8 ; no, overwrite (create file) 325 ; (if the new file is not same file) 326 327 ; check if it is a device file 328 ;test al, S_IFREG ; regular file ? 329 ;jz short cp_error ; no 330 ;and al, S_IFDIR ; directory ? 331 ;jz short cp_error ; no 332 333 ; add (old) file name to (destination ) path 334 ; (directory name +'/'+ file name) 335 336 0000012E 89F5 mov ebp, esi ; save esi 337 00000130 8B37 mov esi, [edi] ; directory name address 338 00000132 89FB mov ebx, edi ; save edi 339 00000134 BF[D6030000] mov edi, iobuf ; (new) path name buffer addr 340 341 ; p1 = from; 342 ; p2 = to; 343 ; bp = iobuf; 344 cp_5: ; while(*bp++ = *p2++) 345 00000139 AC lodsb 346 0000013A AA stosb 347 0000013B 20C0 and al, al 348 0000013D 75FA jnz short cp_5 349 0000013F C647FF2F mov byte [edi-1], '/' ; bp[-1] = '/'; 350 ; p2 = bp 351 00000143 89FA mov edx, edi 352 00000145 8B7500 mov esi, [ebp] ; *p1 ; from 353 cp_6: ; while(*bp = *p1++) 354 00000148 AC lodsb 355 00000149 AA stosb 356 0000014A 08C0 or al, al 357 0000014C 7408 jz short cp_7 358 0000014E 3C2F cmp al, '/' ; if (*bp++ == '/') 359 00000150 75F6 jne short cp_6 360 ; bp = p2 361 ; 21/04/2022 362 00000152 89D7 mov edi, edx ; (discard path before file name) 363 00000154 EBF2 jmp short cp_6 364 cp_7: 365 00000156 89EE mov esi, ebp ; restore esi 366 00000158 89DF mov edi, ebx ; restore edi 367 ; to = iobuf 368 0000015A BD[D6030000] mov ebp, iobuf 369 370 sys _stat, ebp, stbuf2 ; stat(to, &stbuf2) >= 0 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000015F 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000161 B9[52030000] <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 00000166 B812000000 <1> mov eax, %1 88 0000016B CD30 <1> int 30h 371 0000016D 7236 jc short cp_10 ; create new file 372 373 cp_8: 374 ;if (stbuf1.st_dev == stbuf2.st_dev && 375 ; stbuf1.st_ino == stbuf2.st_ino) { 376 ; fprintf(stderr, "cp: cannot copy file to itself.\n"); 377 ; return(1); 378 379 0000016F 66A1[94030000] mov ax, [stbuf1+stat.inode] 380 00000175 663B05[52030000] cmp ax, [stbuf2+stat.inode] 381 0000017C 7527 jne short cp_10 382 383 ; same file ! error... 384 0000017E BD[DF020000] mov ebp, cncis_err_msg ; error message 385 ; esi = file name (from) 386 write_err_msg: 387 sys _msg, ebp, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000183 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000185 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 0000018A BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 0000018F B823000000 <1> mov eax, %1 88 00000194 CD30 <1> int 30h 388 ; close (old) file 389 sys _close, [fold] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000196 8B1D[4A030000] <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 0000019C B806000000 <1> mov eax, %1 88 000001A1 CD30 <1> int 30h 390 000001A3 F9 stc ; return with error (cf=1) 391 000001A4 C3 retn 392 393 cp_9: 394 ; 22/04/2022 395 ; ebp = [edi] 396 ; 21/04/2022 397 ; new file (asciiz name address) 398 ;mov ebp, [edi] 399 400 ; create new file (truncate if it exists) 401 cp_10: 402 ; fnew = creat(to, mode) 403 000001A5 0FB70D[96030000] movzx ecx, word [stbuf1+stat.mode] 404 ; ecx = mode 405 sys _creat, ebp 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001AC 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 000001AE B808000000 <1> mov eax, %1 88 000001B3 CD30 <1> int 30h 406 000001B5 733B jnc short cp_11 407 408 ;if ((fnew = creat(to, mode)) < 0) { 409 ; fprintf(stderr, "cp: cannot create %s\n", to); 410 ; close(fold); 411 ; return(1); 412 413 ; 24/04/2022 414 sys _close, [fold] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001B7 8B1D[4A030000] <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 000001BD B806000000 <1> mov eax, %1 88 000001C2 CD30 <1> int 30h 415 416 ; error message 417 sys _msg, ccf_err_msg, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001C4 BB[03030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000001C9 B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000001CE BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000001D3 B823000000 <1> mov eax, %1 88 000001D8 CD30 <1> int 30h 418 419 ; 24/04/2022 420 ; and file name (to) -at the end of error message- 421 sys _msg, ebp, 255, 07h 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001DA 89EB <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000001DC B9FF000000 <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 000001E1 BA07000000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 000001E6 B823000000 <1> mov eax, %1 88 000001EB CD30 <1> int 30h 422 ; write next line (move cursor to next line) 423 ; and return (from this/copy subroutine) 424 000001ED E9EBFEFFFF jmp write_nl 425 426 cp_11: 427 ; 21/04/2022 428 000001F2 A3[4E030000] mov [fnew], eax 429 cp_rw_next: 430 ; while(n = read(fold, iobuf, BSIZE)) 431 sys _read, [fold], iobuf, BSIZE 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 000001F7 8B1D[4A030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 000001FD B9[D6030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 00000202 BA00020000 <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 00000207 B803000000 <1> mov eax, %1 88 0000020C CD30 <1> int 30h 432 0000020E 7317 jnc short cp_12 433 434 ;if (n < 0) { 435 ; fprintf(stderr, "cp: read error\n"); 436 437 ; write read error message 438 00000210 BD[18030000] mov ebp, crd_err_msg 439 440 cp_rw_err: 441 ; 21/04/2022 442 ; cf = 1 443 sys _close, [fnew] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 00000215 8B1D[4E030000] <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 0000021B B806000000 <1> mov eax, %1 88 00000220 CD30 <1> int 30h 444 00000222 E95CFFFFFF jmp write_err_msg 445 446 cp_12: 447 ; eax = read count 448 ; eax = 0 -> eof 449 00000227 09C0 or eax, eax 450 00000229 7423 jz short cp_14 ; eof 451 452 0000022B 89C5 mov ebp, eax ; n 453 ; write(fnew, iobuf, n) 454 sys _write, [fnew], iobuf, ebp 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000022D 8B1D[4E030000] <1> mov ebx, %2 79 <1> %if %0 >= 3 80 00000233 B9[D6030000] <1> mov ecx, %3 81 <1> 82 <1> %if %0 >= 4 83 00000238 89EA <1> mov edx, %4 84 <1> %endif 85 <1> %endif 86 <1> %endif 87 0000023A B804000000 <1> mov eax, %1 88 0000023F CD30 <1> int 30h 455 00000241 7204 jc short cp_13 456 457 ;if (write(fnew, iobuf, n) != n) 458 ; fprintf(stderr, "cp: write error.\n"); 459 ; close(fold); 460 ; close(fnew); 461 ; return(1); 462 463 ; eax = written bytes 464 00000243 39E8 cmp eax, ebp 465 ;je short cp_11 ; read next (block) 466 ; 21/04/2022 467 00000245 74B0 je short cp_rw_next 468 ; error ! 469 ; eax < ebp --> cf = 1 470 cp_13: 471 ; close new file 472 ; and then write error mesage 473 ; and then close old file 474 ; and then write (move cursor to) next line 475 ; and then return (from subroutine) 476 ;sys _close, [fnew] 477 478 ; write error message 479 00000247 BD[2C030000] mov ebp, cwr_err_msg 480 ;jmp short write_err_msg 481 ; 21/04/2022 482 0000024C EBC7 jmp short cp_rw_err 483 484 ; eof 485 cp_14: 486 ;close(fold); 487 ;close(fnew); 488 ;return(0); 489 490 sys _close, [fold] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000024E 8B1D[4A030000] <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 00000254 B806000000 <1> mov eax, %1 88 00000259 CD30 <1> int 30h 491 sys _close, [fnew] 74 <1> 75 <1> 76 <1> 77 <1> %if %0 >= 2 78 0000025B 8B1D[4E030000] <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 00000261 B806000000 <1> mov eax, %1 88 00000266 CD30 <1> int 30h 492 493 ;clc 494 00000268 C3 retn 495 496 ;----------------------------------------------------------------- 497 ; data - initialized data 498 ;----------------------------------------------------------------- 499 500 ;argc: dd 0 501 00000269 00 argc: db 0 502 503 ; ---------------------------------------------------------------- 504 505 program_msg: 506 0000026A 0D0A db 0Dh, 0Ah 507 0000026C 526574726F20554E49- db 'Retro UNIX 386 v1.2 COPY by Erdogan TAN - 24/04/2022' 507 00000275 58203338362076312E- 507 0000027E 3220434F5059206279- 507 00000287 204572646F67616E20- 507 00000290 54414E202D2032342F- 507 00000299 30342F32303232 508 000002A0 0D0A00 db 0Dh, 0Ah, 0 509 510 usage_msg: 511 000002A3 0D0A db 0Dh, 0Ah 512 000002A5 55736167653A206370- db 'Usage: cp: f1 f2; or cp f1 ... fn d2' 512 000002AE 3A2066312066323B20- 512 000002B7 6F7220637020663120- 512 000002C0 2E2E2E20666E206432 513 nextline: 514 000002C9 0D0A00 db 0Dh, 0Ah, 0 515 516 cno_err_msg: 517 000002CC 0D0A db 0Dh, 0Ah 518 000002CE 63703A2063616E6E6F- db 'cp: cannot open ' 518 000002D7 74206F70656E20 519 000002DE 00 db 0 520 cncis_err_msg: 521 000002DF 0D0A db 0Dh, 0Ah 522 000002E1 63703A2063616E6E6F- db 'cp: cannot copy file to itself.' 522 000002EA 7420636F7079206669- 522 000002F3 6C6520746F20697473- 522 000002FC 656C662E 523 00000300 0D0A00 db 0Dh, 0Ah, 0 524 525 ccf_err_msg: 526 00000303 0D0A db 0Dh, 0Ah 527 00000305 63703A2063616E6E6F- db 'cp: cannot create ' 527 0000030E 742063726561746520 528 00000317 00 db 0 529 530 crd_err_msg: 531 00000318 0D0A db 0Dh, 0Ah 532 0000031A 63703A207265616420- db 'cp: read error.' 532 00000323 6572726F722E 533 00000329 0D0A00 db 0Dh, 0Ah, 0 534 535 cwr_err_msg: 536 0000032C 0D0A db 0Dh, 0Ah 537 0000032E 63703A207772697465- db 'cp: write error.' 537 00000337 206572726F722E 538 0000033E 0D0A00 db 0Dh, 0Ah, 0 539 540 ok_msg: 541 00000341 0D0A db 0Dh, 0Ah 542 00000343 4F4B2E db 'OK.' 543 00000346 0D0A00 db 0Dh, 0Ah, 0 544 545 00000349 00 errors: db 0 546 547 ;----------------------------------------------------------------- 548 ; bss - uninitialized data 549 ;----------------------------------------------------------------- 550 551 align 2 552 553 bss_start: 554 555 ABSOLUTE bss_start 556 557 ; 20/04/2022 558 0000034A ???????? fold: resd 1 559 0000034E ???????? fnew: resd 1 560 561 00000352 stbuf2: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data) 562 00000394 stbuf1: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data) 563 564 000003D6 iobuf: resb BSIZE ; resb 512 ; path name buffer 565 566 ; 20/04/2022 567 ;----------------------------------------------------------------- 568 ; Original UNIX v7 - cp (utility) c source code (cp.c) 569 ;----------------------------------------------------------------- 570 ;/* UNIX V7 source code: see www.tuhs.org for details. */; 571 ; 572 ;/* 573 ; * cp oldfile newfile 574 ; */ 575 ; 576 ;#define BSIZE 512 577 ;#include 578 ;#include 579 ;#include 580 ;struct stat stbuf1, stbuf2; 581 ;char iobuf[BSIZE]; 582 ; 583 ;main(argc, argv) 584 ;char *argv[]; 585 ;{ 586 ; register i, r; 587 ; 588 ; if (argc < 3) 589 ; goto usage; 590 ; if (argc > 3) { 591 ; if (stat(argv[argc-1], &stbuf2) < 0) 592 ; goto usage; 593 ; if ((stbuf2.st_mode&S_IFMT) != S_IFDIR) 594 ; goto usage; 595 ; } 596 ; r = 0; 597 ; for(i=1; i=0 && 619 ; (stbuf2.st_mode&S_IFMT) == S_IFDIR) { 620 ; p1 = from; 621 ; p2 = to; 622 ; bp = iobuf; 623 ; while(*bp++ = *p2++) 624 ; ; 625 ; bp[-1] = '/'; 626 ; p2 = bp; 627 ; while(*bp = *p1++) 628 ; if (*bp++ == '/') 629 ; bp = p2; 630 ; to = iobuf; 631 ; } 632 ; if (stat(to, &stbuf2) >= 0) { 633 ; if (stbuf1.st_dev == stbuf2.st_dev && 634 ; stbuf1.st_ino == stbuf2.st_ino) { 635 ; fprintf(stderr, "cp: cannot copy file to itself.\n"); 636 ; return(1); 637 ; } 638 ; } 639 ; if ((fnew = creat(to, mode)) < 0) { 640 ; fprintf(stderr, "cp: cannot create %s\n", to); 641 ; close(fold); 642 ; return(1); 643 ; } 644 ; while(n = read(fold, iobuf, BSIZE)) { 645 ; if (n < 0) { 646 ; fprintf(stderr, "cp: read error\n"); 647 ; close(fold); 648 ; close(fnew); 649 ; return(1); 650 ; } else 651 ; if (write(fnew, iobuf, n) != n) { 652 ; fprintf(stderr, "cp: write error.\n"); 653 ; close(fold); 654 ; close(fnew); 655 ; return(1); 656 ; } 657 ; } 658 ; close(fold); 659 ; close(fnew); 660 ; return(0); 661 ;}