1 ; **************************************************************************** 2 ; mv386.s (mv2.s) - by Erdogan Tan - 22/05/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 386 v1.2 - mv -- move (or rename) file (or directory) 5 ; 6 ; [ Last Modification: 27/05/2022 ] 7 ; 8 ; Derived from (original) UNIX v7 'mv.c' source Code 9 ; Ref: 10 ; www.tuhs.org (https://minnie.tuhs.org) 11 ; **************************************************************************** 12 ; [ v7.tar.gz - usr/src/cmd/mv.c (archive date: 10-01-1979) ] 13 ; 14 ; Assembler: NASM v2.15 15 ; ((nasm mv2.s -l mv2.txt -o mv2 -Z error.txt)) 16 17 ; mv2.s - 27/05/2022 - Retro UNIX 386 v1.2 & v2 18 ; mv1.s - 27/05/2022 - Retro UNIX 386 v1 & v1.1 19 ; mv0.s - 27/05/2022 - Retro UNIX 8086 v1 (16 bit 'mv1.s') 20 21 ; 12/01/2022 (Retro UNIX 386 v1.2) 22 ; 13/10/2015 23 24 ; UNIX v1 system calls 25 _rele equ 0 26 _exit equ 1 27 _fork equ 2 28 _read equ 3 29 _write equ 4 30 _open equ 5 31 _close equ 6 32 _wait equ 7 33 _creat equ 8 34 _link equ 9 35 _unlink equ 10 36 _exec equ 11 37 _chdir equ 12 38 _time equ 13 39 _mkdir equ 14 40 _chmod equ 15 41 _chown equ 16 42 _break equ 17 43 _stat equ 18 44 _seek equ 19 45 _tell equ 20 46 _mount equ 21 47 _umount equ 22 48 _setuid equ 23 49 _getuid equ 24 50 _stime equ 25 51 _quit equ 26 52 _intr equ 27 53 _fstat equ 28 54 _emt equ 29 55 _mdate equ 30 56 _stty equ 31 57 _gtty equ 32 58 _ilgins equ 33 59 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 60 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 61 _geterr equ 36 ; Retro UNIX 386 v1 feature only ! 62 ; 12/01/2022 - Retro UNIX 386 v1.2 63 ; Retro UNIX 386 v2 system calls 64 _setgid equ 37 65 _getgid equ 38 66 _sysver equ 39 ; (get) Retro Unix 386 version 67 68 ;;; 69 ESCKey equ 1Bh 70 EnterKey equ 0Dh 71 72 %macro sys 1-4 73 ; 03/09/2015 74 ; 13/04/2015 75 ; Retro UNIX 386 v1 system call. 76 %if %0 >= 2 77 mov ebx, %2 78 %if %0 >= 3 79 mov ecx, %3 80 ;%if %0 = 4 81 %if %0 >= 4 ; 11/03/2022 82 mov edx, %4 83 %endif 84 %endif 85 %endif 86 mov eax, %1 87 int 30h 88 %endmacro 89 90 ; Retro UNIX 386 v1 system call format: 91 ; sys systemcall (eax) , , 92 93 ; 11/03/2022 94 ; Note: Above 'sys' macro has limitation about register positions; 95 ; ebx, ecx, edx registers must not be used after their 96 ; positions in sys macro. 97 ; for example: 98 ; 'sys _write, 1, msg, ecx' is defective, because 99 ; ecx will be used/assigned before edx in 'sys' macro. 100 ; correct order may be: 101 ; 'sys _write, 1, msg, eax ; (eax = byte count) 102 103 ;struc stat 104 ; ; Note: This is for Retro UNIX v1 'sysstat' output !!! 105 ; ; (34 bytes) 106 ; .inode: resw 1 107 ; .mode: resw 1 108 ; .nlinks: resb 1 109 ; .uid: resb 1 110 ; .size: resw 1 111 ; .dskptr: resw 8 112 ; .ctime: resd 1 113 ; .mtime: resd 1 114 ; .rsvd: resw 1 115 ; .strucsize: 116 ;endstruc 117 118 struc stat 119 ; Note: This is for Retro UNIX v1.2 'sysstat' output !!! 120 ; (66 bytes) 121 00000000 ???? .inode: resw 1 122 00000002 ???? .mode: resw 1 123 00000004 ???? .nlinks: resw 1 124 00000006 ???? .uid: resw 1 125 00000008 ?? .gid: resb 1 126 00000009 ?? .size_h: resb 1 127 0000000A ???????? .size: resd 1 128 0000000E .dskptr: resd 10 129 00000036 ???????? .atime: resd 1 130 0000003A ???????? .mtime: resd 1 131 0000003E ???????? .ctime: resd 1 132 .strucsize: 133 endstruc 134 135 ;struc stat 136 ; ; Note: Retro UNIX v2 'sysstat' output DRAFT !!! 137 ; ; (72 bytes) 138 ; .idev: resb 1 139 ; .rsvd: resb 3 140 ; .inum: resd 1 141 ; .mode: resw 1 142 ; .nlinks: resw 1 143 ; .uid: resw 1 144 ; .gid: resb 1 145 ; .size_h: resb 1 146 ; .size: resd 1 147 ; .dskptr: resd 10 148 ; .atime: resd 1 149 ; .mtime: resd 1 150 ; .ctime: resd 1 151 ; .strucsize: 152 ;endstruc 153 154 ;S_IFMT equ 0F000h ; /* type of file */ 155 ;S_IFDIR equ 04000h ; /* directory */ 156 ;S_IFCHR equ 02000h ; /* character special */ 157 ;S_IFBLK equ 06000h ; /* block special */ 158 ;S_IFREG equ 08000h ; /* regular */ 159 ;S_ISUID equ 00800h ; /* set user id on execution */ 160 ;S_ISGID equ 00400h ; /* set group id on execution */ 161 ;S_IREAD equ 00100h ; /* read permission, owner */ 162 ;S_IWRITE equ 00080h ; /* write permission, owner */ 163 ;S_IEXEC equ 00040h ; /* execute/search permission, owner */ 164 165 S_IFMT equ 0F0h ; /* type of file */ 166 S_IFDIR equ 040h ; /* directory */ 167 S_IFCHR equ 020h ; /* character special */ 168 S_IFBLK equ 060h ; /* block special */ 169 S_IFREG equ 080h ; /* regular */ 170 S_ISUID equ 008h ; /* set user id on execution */ 171 S_ISGID equ 004h ; /* set group id on execution */ 172 S_IREAD equ 001h ; /* read permission, owner */ 173 S_IWRITE equ 080h ; /* write permission, owner */ 174 S_IEXEC equ 040h ; /* execute/search permission, owner */ 175 176 ;; UNIX v1 inode 177 ;; byte 1 178 ;S_ALLOC equ 080h ; Allocated flag 179 ;S_IFDIR equ 040h ; Directory flag 180 ;S_IFMDF equ 020h ; File modified flag (always on) 181 ;S_IFLRG equ 010h ; Large File flag 182 ;; byte 0 183 ;S_ISUID equ 020h ; Set User ID On Execution flag 184 ;S_IEXEC equ 010h ; Executable File flag 185 ;S_IREAD equ 008h ; Owner's Read Permission flag 186 ;S_IWRITE equ 004h ; Owner's Write Permission flag 187 188 ;%define DOT "." 189 ;%define DOTDOT ".." 190 %define DELIM '/' 191 ;%define SDELIM "/" 192 ;MODEBITS equ 11111b ; Retro UNIX v1 193 MODEBITS equ 111111111b ; Retro UNIX v1.2 (v2) 194 ;ROOTINO equ 41 ; Retro UNIX v1 195 ROOTINO equ 1 ; Retro UNIX v1.2 (v2) 196 197 STDIN equ 0 198 ; 23/05/2022 199 MAXN equ 112 200 201 ;----------------------------------------------------------------- 202 ; text - code 203 ;----------------------------------------------------------------- 204 205 [BITS 32] ; 32-bit intructions (for 80386 protected mode) 206 207 [ORG 0] 208 209 START_CODE: 210 ; 27/05/2022 211 ; 26/05/2022 212 ; 24/05/2022 213 ; 23/05/2022 214 ; 22/05/2022 215 00000000 58 pop eax ; number of arguments 216 00000001 5A pop edx ; argv[0] 217 ;mov [argc], eax 218 00000002 A2[CA080000] mov [argc], al 219 220 ;cmp eax, 3 221 00000007 3C03 cmp al, 3 222 00000009 7321 jnb short mv_0 223 0000000B FEC8 dec al 224 0000000D 7516 jnz short mv_usage 225 sys _msg, program_msg, 255, 0Fh 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000000F BB[E7080000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000014 B9FF000000 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 00000019 BA0F000000 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000001E B823000000 <1> mov eax, %1 87 00000023 CD30 <1> int 30h 226 ;mov eax, program_msg 227 ;call print_msg 228 mv_usage: 229 ;sys _msg, usage_msg, 255, 07h 230 00000025 B8[20090000] mov eax, usage_msg 231 ;call print_msg 232 0000002A EB27 jmp print_exit ; 24/05/2022 233 ;mv_exit: 234 ; sys _exit ; sys exit 235 ;;hlt: 236 ;; nop 237 ;; nop 238 ;; jmp short hlt 239 240 mv_0: 241 0000002C 5F pop edi ; argv[1] 242 243 ; 26/05/2022 244 sys _stat, edi, st1buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000002D 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000002F B9[9C0B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000034 B812000000 <1> mov eax, %1 87 00000039 CD30 <1> int 30h 245 0000003B 732C jnc short mv_1 246 247 0000003D B8[82090000] mov eax, msg_cant_access 248 ; 24/05/2022 249 00000042 E867080000 call print_msg 250 00000047 89F8 mov eax, edi ; argv[1] 251 00000049 E860080000 call print_msg 252 0000004E B8[52090000] mov eax, nextline 253 print_exit: 254 00000053 E856080000 call print_msg 255 _exit_: 256 sys _exit 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000058 B801000000 <1> mov eax, %1 87 0000005D CD30 <1> int 30h 257 258 hang_em_high: 259 0000005F 90 nop 260 00000060 EBFD jmp short hang_em_high 261 262 mv_61: 263 00000062 B8[890B0000] mov eax, msg_ok 264 00000067 EBEA jmp short print_exit 265 266 mv_1: 267 ; Retro UNIX 386 v1.2 268 ;mov [st1dev], eax 269 00000069 A0[9F0B0000] mov al, byte [st1buf+stat.mode+1] 270 0000006E 24C0 and al, S_IFREG|S_IFDIR 271 00000070 3CC0 cmp al, S_IFREG|S_IFDIR 272 00000072 7513 jne short mv_2 273 274 ; Retro UNIX 386 v1 275 ;;mov [st1dev], ax ; device number 276 ; (0 = root fs) 277 ; (1 = mounted fs) 278 ;test byte [st1buf+stat.mode+1], S_IFDIR 279 ;jz short mv_2 280 281 00000074 803D[CA080000]03 cmp byte [argc], 3 282 0000007B 75A8 jne short mv_usage 283 284 0000007D 5D pop ebp ; argv[2] 285 286 0000007E E8E4020000 call mvdir 287 00000083 73DD jnc short mv_61 ; "OK." 288 00000085 EBD1 jmp short _exit_ 289 290 mv_2: 291 ;setuid(getuid()); 292 sys _getuid 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000087 B818000000 <1> mov eax, %1 87 0000008C CD30 <1> int 30h 293 sys _setuid, eax 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000008E 89C3 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000090 B817000000 <1> mov eax, %1 87 00000095 CD30 <1> int 30h 294 00000097 7307 jnc short mv_3 295 296 ; error (permission denied) 297 00000099 B8[7D0B0000] mov eax, err_msg 298 0000009E EBB3 jmp short print_exit 299 mv_3: 300 ; (here [esp] = argv[2]) 301 000000A0 A0[CA080000] mov al, [argc] 302 000000A5 FEC8 dec al ; (if [argc] = 3 then al = 2) 303 000000A7 B102 mov cl, 2 304 000000A9 28C8 sub al, cl ; argv[0], argv[1] 305 000000AB D3E0 shl eax, cl ; * 4 306 000000AD 89E5 mov ebp, esp 307 000000AF 01C5 add ebp, eax 308 ; ebp = argv[argc-1] 309 ;mov [target], ebp 310 311 ; 26/05/2022 312 000000B1 8B6D00 mov ebp, [ebp] 313 314 ; 24/05/2022 315 ;cmp byte [argc], 3 316 000000B4 802D[CA080000]02 sub byte [argc], 2 317 000000BB 803D[CA080000]01 cmp byte [argc], 1 318 000000C2 7620 jna short mv_6 319 320 ; (target must a -valid- directory) 321 322 sys _stat, ebp, st2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000000C4 89EB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000000C6 B9[E20B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000000CB B812000000 <1> mov eax, %1 87 000000D0 CD30 <1> int 30h 323 000000D2 7305 jnc short mv_5 324 mv_4: 325 000000D4 E94CFFFFFF jmp mv_usage 326 mv_5: 327 ; Retro UNIX 386 v1.2 328 ;mov [st2dev], eax 329 000000D9 A0[E50B0000] mov al, byte [st2buf+stat.mode+1] 330 000000DE 24C0 and al, S_IFREG|S_IFDIR 331 000000E0 3CC0 cmp al, S_IFREG|S_IFDIR 332 000000E2 75F0 jne short mv_4 333 334 ; Retro UNIX 386 v1 335 ;;mov [st2dev], ax ; device number 336 ; (0 = root fs) 337 ; (1 = mounted fs) 338 ;test byte [st2buf+stat.mode+1], S_IFDIR 339 ;jz short mv_4 340 341 ; 26/05/2022 342 ;sub byte [argc], 2 ; [argc] >= 1 343 ; ; i = 1 344 mv_6: 345 ; edi = argv[i] 346 ; ebp = argv[argc-1] 347 000000E4 E82B000000 call move 348 000000E9 7306 jnc short mv_7 349 000000EB FE05[CB080000] inc byte [errors] 350 mv_7: 351 000000F1 FE0D[CA080000] dec byte [argc] ; i++ 352 000000F7 7403 jz short mv_8 353 ; i < argc-1 354 000000F9 5F pop edi ; argv[i] 355 000000FA EBE8 jmp short mv_6 356 mv_8: 357 000000FC 803D[CB080000]00 cmp byte [errors], 0 358 00000103 770A ja short mv_9 359 360 00000105 B8[890B0000] mov eax, msg_ok 361 ;jmp print_exit 362 0000010A E89F070000 call print_msg 363 mv_9: 364 0000010F E944FFFFFF jmp _exit_ 365 366 ;----------------------------------------------------------------- 367 368 move: 369 ; 27/05/2022 370 ; 26/05/2022 371 ; 24/05/2022 372 ; 22/05/2022 373 374 ; move(source, target) 375 376 ; INPUT: 377 ; edi = source 378 ; ebp = target 379 ; OUTPUT: 380 ; cf = 0 -> ok 381 ; cf = 1 -> error 382 383 ; if (stat(source, &s1) < 0) 384 sys _stat, edi, st1buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000114 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000116 B9[9C0B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000011B B812000000 <1> mov eax, %1 87 00000120 CD30 <1> int 30h 385 00000122 731D jnc short mv_10 386 387 00000124 B8[82090000] mov eax, msg_cant_access 388 ; 24/05/2022 389 00000129 E880070000 call print_msg 390 0000012E 89F8 mov eax, edi ; source 391 00000130 E879070000 call print_msg 392 00000135 B8[52090000] mov eax, nextline 393 move_err: 394 0000013A E86F070000 call print_msg 395 0000013F F9 stc 396 00000140 C3 retn 397 mv_10: 398 ; Retro UNIX 386 v1.2 399 00000141 A3[980B0000] mov [st1dev], eax 400 00000146 A0[9F0B0000] mov al, byte [st1buf+stat.mode+1] 401 0000014B 24C0 and al, S_IFREG|S_IFDIR 402 0000014D 3CC0 cmp al, S_IFREG|S_IFDIR 403 0000014F 7507 jne short mv_11 404 405 ; Retro UNIX 386 v1 (& v1.1) 406 ;mov [st1dev], ax ; device number 407 ; (0 = root fs) 408 ; (1 = mounted fs) 409 410 ; if ((s1.st_mode & S_IFMT) == S_IFDIR) 411 ;test byte [st1buf+stat.mode+1], S_IFDIR 412 ;jz short mv_11 413 414 00000151 B8[97090000] mov eax, msg_rename_only 415 00000156 EBE2 jmp short move_err 416 mv_11: 417 ; 26/05/2022 418 00000158 892D[940B0000] mov [target], ebp 419 420 ; if (stat(target, &s2) >= 0) 421 sys _stat, ebp, st2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000015E 89EB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000160 B9[E20B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000165 B812000000 <1> mov eax, %1 87 0000016A CD30 <1> int 30h 422 ;jc short mv_19 423 ; 23/05/2022 424 0000016C 7305 jnc short mv_12 425 0000016E E949010000 jmp mv_19 426 mv_12: 427 ; Retro UNIX 386 v1.2 428 00000173 A3[DE0B0000] mov [st2dev], eax 429 00000178 A0[E50B0000] mov al, byte [st2buf+stat.mode+1] 430 0000017D 24C0 and al, S_IFREG|S_IFDIR 431 0000017F 3CC0 cmp al, S_IFREG|S_IFDIR 432 00000181 754B jne short mv_14 433 434 ; Retro UNIX 386 v1 (& v1.1) 435 ;mov [st2dev], ax ; device number 436 ; (0 = root fs) 437 ; (1 = mounted fs) 438 439 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) 440 ;test byte [st2buf+stat.mode+1], S_IFDIR 441 ;jz short mv_14 442 443 ; sprintf(buf, "%s/%s", target, dname(source)); 444 445 ; mov esi, ebp ; target 446 ; mov ebx, edi ; source 447 ; mov edx, ebx ; source 448 ; mov edi, buf ; pathname buffer (100 bytes) 449 ; mov [target], edi 450 ;mv_12: 451 ; lodsb 452 ; or al, al 453 ; jz short mv_13 454 ; stosb 455 ; jmp short mv_12 456 ; 457 ;mv_13: 458 ; mov al, DELIM ; '/' 459 ; stosb 460 ; 461 ; ; edx = source (pathname) 462 ; ; edi = buffer (offset) position 463 ; call dname 464 ; mov edi, ebx ; source 465 ; ; target = buf; 466 ; 22/05/2022 467 00000183 E81E050000 call strcpy ; 27/05/2022 468 469 ;if (stat(target, &s2) >= 0) 470 471 sys _stat, buf, st2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000188 BB[240C0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000018D B9[E20B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000192 B812000000 <1> mov eax, %1 87 00000197 CD30 <1> int 30h 472 ;jc short mv_20 ; 26/05/2022 473 ; 26/05/2022 474 00000199 7305 jnc short mv_13 475 0000019B E91C010000 jmp mv_20 476 mv_13: 477 ; Retro UNIX 386 v1.2 478 000001A0 A3[DE0B0000] mov [st2dev], eax 479 000001A5 A0[E50B0000] mov al, byte [st2buf+stat.mode+1] 480 000001AA 24C0 and al, S_IFREG|S_IFDIR 481 000001AC 3CC0 cmp al, S_IFREG|S_IFDIR 482 000001AE 751E jne short mv_14 483 484 ; Retro UNIX 386 v1 (& v1.1) 485 ;mov [st2dev], ax ; device number 486 ; (0 = root fs) 487 ; (1 = mounted fs) 488 489 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) 490 ;test byte [st2buf+stat.mode+1], S_IFDIR 491 ;jz short mv_14 492 493 ;fprintf(stderr, "mv: %s is a directory\n", target); 494 000001B0 B8[55090000] mov eax, mv_header 495 000001B5 E8F4060000 call print_msg 496 000001BA B8[240C0000] mov eax, buf ; target 497 000001BF E8EA060000 call print_msg 498 000001C4 B8[6F090000] mov eax, msg_is_a_dir 499 000001C9 E96CFFFFFF jmp move_err 500 501 mv_14: 502 ; if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) 503 000001CE 66A1[9C0B0000] mov ax, [st1buf+stat.inode] 504 000001D4 663B05[E20B0000] cmp ax, [st2buf+stat.inode] 505 000001DB 753E jne short mv_15 506 ; 26/05/2022 507 000001DD 66A1[980B0000] mov ax, [st1dev] 508 000001E3 663B05[DE0B0000] cmp ax, [st2dev] 509 000001EA 752F jne short mv_15 510 511 ;fprintf(stderr, "mv: %s and %s are identical\n", 512 ; source, target); 513 514 ; edi = source 515 ; (buf = target or) [target] = target 516 517 000001EC B8[55090000] mov eax, mv_header 518 000001F1 E8B8060000 call print_msg 519 000001F6 89F8 mov eax, edi ; source 520 000001F8 E8B1060000 call print_msg 521 000001FD B8[060B0000] mov eax, msg_and 522 00000202 E8A7060000 call print_msg 523 00000207 A1[940B0000] mov eax, [target] ; target ; 26/05/2022 524 0000020C E89D060000 call print_msg 525 00000211 B8[0C0B0000] mov eax, msg_identical 526 00000216 E91FFFFFFF jmp move_err 527 528 mv_15: 529 ; if (access(target, 2) < 0 && isatty(fileno(stdin))) 530 0000021B BE[E20B0000] mov esi, st2buf 531 00000220 E8C9050000 call access 532 00000225 756B jnz short mv_18 533 ; not permitted 534 535 00000227 E8E8050000 call isatty 536 0000022C 7264 jc short mv_18 ; not a tty 537 538 ;fprintf(stderr, "mv: %s: %o mode ", target, 539 ; s2.st_mode & MODEBITS); 540 541 0000022E B8[55090000] mov eax, mv_header 542 00000233 E876060000 call print_msg 543 00000238 A1[940B0000] mov eax, [target] ; target ; 26/05/2022 544 0000023D E86C060000 call print_msg 545 00000242 8B1D[E40B0000] mov ebx, [st2buf+stat.mode] 546 00000248 81E3FF010000 and ebx, MODEBITS 547 0000024E BE[070E0000] mov esi, octm 548 00000253 E8E6050000 call octalnumber 549 ; 27/05/2022 550 ;mov eax, octm 551 00000258 C605[060E0000]20 mov byte [octms], 20h 552 0000025F B8[060E0000] mov eax, octms 553 00000264 E845060000 call print_msg 554 00000269 B8[5F0B0000] mov eax, msg_mode 555 0000026E E83B060000 call print_msg 556 557 ; i = c = getchar(); 558 00000273 E8FF050000 call getchar 559 560 00000278 3C79 cmp al, 'y' 561 0000027A 740C je short mv_17 562 563 0000027C B8[760B0000] mov eax, msg_no 564 mv_16: 565 00000281 E828060000 call print_msg 566 00000286 F9 stc 567 00000287 C3 retn 568 mv_17: 569 00000288 B8[6E0B0000] mov eax, msg_yes 570 0000028D E81C060000 call print_msg 571 mv_18: 572 ; if (unlink(target) < 0) 573 sys _unlink, [target] ; 26/05/2022 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000292 8B1D[940B0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000298 B80A000000 <1> mov eax, %1 87 0000029D CD30 <1> int 30h 574 0000029F 731B jnc short mv_20 575 576 ; fprintf(stderr, "mv: cannot unlink %s\n", target); 577 000002A1 B8[B5090000] mov eax, msg_cant_unlink 578 000002A6 E803060000 call print_msg 579 000002AB A1[940B0000] mov eax, [target] ; 26/05/2022 580 000002B0 E8F9050000 call print_msg 581 000002B5 B8[52090000] mov eax, nextline 582 000002BA EBC5 jmp short mv_16 583 mv_19: 584 ; 26/05/2022 585 ;mov [target], ebp ; target 586 mv_20: 587 ; if (link(source, target) < 0) 588 589 sys _link, edi, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000002BC 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000002BE 8B0D[940B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000002C4 B809000000 <1> mov eax, %1 87 000002C9 CD30 <1> int 30h 590 000002CB 7374 jnc short mv_25 591 592 000002CD BB[E2020000] mov ebx, mv_21 ; child process jump address 593 sys _fork 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000002D2 B802000000 <1> mov eax, %1 87 000002D7 CD30 <1> int 30h 594 000002D9 7332 jnc short mv_22 ; parent return and jump 595 596 000002DB B8[CA090000] mov eax, msg_try_again 597 000002E0 EB9F jmp short mv_16 598 mv_21: 599 ; child process will continue from here 600 601 000002E2 A1[940B0000] mov eax, [target] 602 000002E7 A3[DC080000] mov [cp_target], eax 603 000002EC 893D[D8080000] mov [cp_source], edi 604 605 sys _exec, cp_cmd, cp_args 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000002F2 BB[CC080000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000002F7 B9[D4080000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000002FC B80B000000 <1> mov eax, %1 87 00000301 CD30 <1> int 30h 606 607 ; fprintf(stderr, "mv: cannot exec cp\n"); 608 00000303 B8[DC090000] mov eax, msg_cant_exec_cp 609 ;call print_msg 610 ;jmp _exit_ 611 ; 23/05/2022 612 00000308 E946FDFFFF jmp print_exit 613 614 mv_22: 615 0000030D 89C2 mov edx, eax ; child process id 616 mv_23: 617 ; while ((c = wait(&status)) != i && c != -1) 618 ;if (status != 0) 619 ; return(1); 620 ; utime(target, &s1.st_atime); 621 622 sys _wait 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000030F B807000000 <1> mov eax, %1 87 00000314 CD30 <1> int 30h 623 00000316 7228 jc short mv_24 624 625 00000318 39D0 cmp eax, edx 626 0000031A 75F3 jne short mv_23 627 628 ; 26/05/2022 (check if /bin/cp has been failed) 629 sys _stat, [target], fstbuf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000031C 8B1D[940B0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000322 B9[400D0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000327 B812000000 <1> mov eax, %1 87 0000032C CD30 <1> int 30h 630 0000032E 7210 jc short mv_24 631 00000330 66A1[4A0D0000] mov ax, [fstbuf+stat.size] 632 00000336 663B05[A60B0000] cmp ax, [st1buf+stat.size] 633 0000033D 7402 je short mv_25 634 0000033F F9 stc 635 mv_24: 636 00000340 C3 retn 637 638 ; utime(target, &s1.st_atime); 639 640 ;;; 641 mv_25: 642 ;if (unlink(source) < 0) { 643 ; fprintf(stderr, "mv: cannot unlink %s\n", source); 644 ; return(1); 645 ;} 646 647 sys _unlink, edi 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000341 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000343 B80A000000 <1> mov eax, %1 87 00000348 CD30 <1> int 30h 648 0000034A 73F4 jnc short mv_24 649 650 0000034C B8[B5090000] mov eax, msg_cant_unlink 651 00000351 E858050000 call print_msg 652 00000356 89F8 mov eax, edi ; source 653 00000358 E851050000 call print_msg 654 0000035D B8[52090000] mov eax, nextline 655 ;if (status != 0) 656 ; return(1); 657 00000362 E91AFFFFFF jmp mv_16 658 659 ;----------------------------------------------------------------- 660 661 mvdir: 662 ; 27/05/2022 663 ; 26/05/2022 664 ; 23/05/2022 665 ; 22/05/2022 666 667 ; mvdir(source, target) 668 669 ; INPUT: 670 ; edi = source 671 ; ebp = target 672 ; OUTPUT: 673 ; cf = 0 -> ok 674 ; cf = 1 -> error 675 676 ; st1buf = source (inode) stat(us) buffer 677 678 ;if (stat(target, &s2) >= 0) 679 sys _stat, ebp, st2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000367 89EB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000369 B9[E20B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000036E B812000000 <1> mov eax, %1 87 00000373 CD30 <1> int 30h 680 00000375 7243 jc short mv_29 681 682 ;if ((s2.st_mode&S_IFMT) != S_IFDIR) 683 684 ; Retro UNIX 386 v1.2 685 ;mov [st2dev], eax 686 00000377 A0[E50B0000] mov al, byte [st2buf+stat.mode+1] 687 0000037C 24C0 and al, S_IFREG|S_IFDIR 688 0000037E 3CC0 cmp al, S_IFREG|S_IFDIR 689 00000380 741D je short mv_28 690 691 ; Retro UNIX 386 v1 (& v1.1) 692 ;mov [st2dev], ax ; device number 693 ; (0 = root fs) 694 ; (1 = mounted fs) 695 696 ;if ((s2.st_mode & S_IFMT) == S_IFDIR) 697 ;test byte [st2buf+stat.mode+1], S_IFDIR 698 ;jnz short mv_28 699 700 ;fprintf(stderr, "mv: %s exists\n", target); 701 702 00000382 55 push ebp ; target 703 mv_27: 704 00000383 B8[55090000] mov eax, mv_header 705 00000388 E821050000 call print_msg 706 0000038D 58 pop eax ; target 707 0000038E E81B050000 call print_msg 708 00000393 B8[F3090000] mov eax, msg_exists 709 00000398 E811050000 call print_msg 710 0000039D F9 stc 711 0000039E C3 retn 712 713 mv_28: 714 ;if (strlen(target) > MAXN-DIRSIZ-2) { 715 ; fprintf(stderr, "mv: target name too long\n"); 716 ; return(1); 717 ;} 718 719 ;strcpy(buf, target); 720 721 ; mov esi, ebp ; target 722 ; mov edx, edi ; source 723 ; mov edi, buf ; pathname buffer (100 bytes) 724 ; mov [target], edi 725 ;mv_29: 726 ; lodsb 727 ; stosb 728 ; and al, al 729 ; jnz short mv_29 730 731 ;strcat(buf, SDELIM); 732 ;strcat(buf, dname(source)); 733 734 0000039F E802030000 call strcpy ; 27/05/2022 735 736 sys _stat, buf, st2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000003A4 BB[240C0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000003A9 B9[E20B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000003AE B812000000 <1> mov eax, %1 87 000003B3 CD30 <1> int 30h 737 000003B5 7209 jc short mv_30 738 739 000003B7 53 push ebx ; buf ; [target] 740 000003B8 EBC9 jmp short mv_27 741 742 mv_29: 743 000003BA 892D[940B0000] mov [target], ebp 744 mv_30: 745 ; if (strcmp(source, target) == 0) { 746 747 000003C0 57 push edi 748 000003C1 89FE mov esi, edi 749 000003C3 8B3D[940B0000] mov edi, [target] 750 000003C9 E809030000 call strcmp 751 000003CE 5F pop edi 752 000003CF 750C jne short mv_32 753 754 000003D1 B8[FE090000] mov eax, msg_src_target 755 mv_31: 756 000003D6 E8D3040000 call print_msg 757 000003DB F9 stc 758 000003DC C3 retn 759 760 mv_32: 761 000003DD 89FA mov edx, edi 762 000003DF BF[400D0000] mov edi, fstbuf ; (66 bytes buffer) 763 ;mov ebx, edi 764 000003E4 52 push edx ; * 765 000003E5 E8F8020000 call dname 766 ; edx = fstbuf = file name 767 768 ;!strcmp(p, "") 769 000003EA 803A00 cmp byte [edx], 0 770 000003ED 7421 je short mv_33 ; null 771 ;!strcmp(p, DOT) 772 000003EF 89D6 mov esi, edx 773 000003F1 803E2E cmp byte [esi], '.' 774 000003F4 752C jne short mv_34 775 000003F6 BF[E5080000] mov edi, DOT 776 000003FB E8D7020000 call strcmp 777 00000400 740E je short mv_33 ; '.' 778 ;!strcmp(p, DOTDOT) 779 00000402 89D6 mov esi, edx 780 00000404 BF[E4080000] mov edi, DOTDOT 781 00000409 E8C9020000 call strcmp 782 0000040E 7512 jne short mv_34 783 ; '..' 784 mv_33: 785 00000410 5F pop edi ; * 786 787 ;fprintf(stderr, "mv: cannot rename %s\n", p); 788 00000411 B8[D90A0000] mov eax, msg_cant_rename 789 00000416 E893040000 call print_msg 790 0000041B B8[400D0000] mov eax, fstbuf 791 00000420 EBB4 jmp short mv_31 792 793 mv_34: 794 00000422 5F pop edi ; * 795 00000423 BB[880C0000] mov ebx, sbuf 796 ; edi = source 797 ; ebx = buffer 798 00000428 E8D2020000 call pname 799 ; esi = parent directory name address 800 ; 801 ;if (stat(pname(source), &s1) < 0 || 802 sys _stat, esi, pst1buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000042D 89F3 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000042F B9[820D0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000434 B812000000 <1> mov eax, %1 87 00000439 CD30 <1> int 30h 803 0000043B 7307 jnc short mv_36 804 mv_35: 805 0000043D B8[3B0A0000] mov eax, msg_cant_locate 806 00000442 EB92 jmp short mv_31 807 mv_36: 808 ;mov [st1dev], ax 809 00000444 A3[980B0000] mov [st1dev], eax ; 27/05/2022 810 00000449 8B15[940B0000] mov edx, [target] 811 0000044F 87D7 xchg edx, edi 812 ;stat(pname(target), &s2) < 0) 813 ; edi = source 814 00000451 BB[E40C0000] mov ebx, tbuf ; buffer 815 00000456 E8A4020000 call pname 816 ; esi = parent directory name address 817 0000045B 89D7 mov edi, edx 818 sys _stat, esi, pst2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000045D 89F3 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000045F B9[C40D0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000464 B812000000 <1> mov eax, %1 87 00000469 CD30 <1> int 30h 819 0000046B 72D0 jc short mv_35 820 ;mov [st2dev], ax 821 0000046D A3[DE0B0000] mov [st2dev], eax ; 27/05/2022 822 ;if (access(pname(target), 2) < 0) 823 00000472 BE[C40D0000] mov esi, pst2buf 824 00000477 E872030000 call access 825 0000047C 7522 jnz short mv_39 826 ; permission denied ! 827 0000047E BA[E40C0000] mov edx, tbuf ; pname(target) 828 mv_37: 829 00000483 52 push edx ; pname(target) or pname(source) 830 00000484 B8[580A0000] mov eax, msg_no_w_access 831 00000489 E820040000 call print_msg 832 0000048E 58 pop eax ; pname(target) or pname(source) 833 0000048F E81A040000 call print_msg 834 00000494 B8[52090000] mov eax, nextline 835 mv_38: 836 00000499 E810040000 call print_msg 837 0000049E F9 stc 838 0000049F C3 retn 839 mv_39: 840 ;if (access(pname(source), 2) < 0) 841 000004A0 BE[820D0000] mov esi, pst1buf 842 000004A5 E844030000 call access 843 000004AA 7507 jnz short mv_40 844 ; permission denied ! 845 000004AC BA[880C0000] mov edx, sbuf ; pname(source) 846 000004B1 EBD0 jmp short mv_37 847 mv_40: 848 ;if (access(source, 2) < 0) 849 ; edi = source 850 000004B3 BE[9C0B0000] mov esi, st1buf 851 ; source (inode) stat(us) buffer 852 000004B8 E831030000 call access 853 000004BD 7504 jnz short mv_41 854 000004BF 89FA mov edx, edi ; source 855 000004C1 EBC0 jmp short mv_37 856 mv_41: 857 ;if (s1.st_dev != s2.st_dev) 858 ; 27/05/2022 (Retro UNIX 386 v1.2) 859 000004C3 A1[980B0000] mov eax, [st1dev] 860 000004C8 3B05[DE0B0000] cmp eax, [st2dev] 861 000004CE 7407 je short mv_42 862 ;fprintf(stderr, "mv: cannot move directories 863 ; across devices\n"); 864 000004D0 B8[720A0000] mov eax, msg_accross_devices 865 000004D5 EBC2 jmp short mv_38 866 mv_42: 867 ;if (s1.st_ino != s2.st_ino) 868 000004D7 66A1[820D0000] mov ax, [pst1buf+stat.inode] 869 000004DD 663B05[C40D0000] cmp ax, [pst2buf+stat.inode] 870 000004E4 7505 jne short mv_43 871 000004E6 E960010000 jmp mv_57 872 mv_43: 873 ; (move dir from parent dir to another dir) 874 875 ;if (chkdot(source) || chkdot(target)) 876 000004EB 89FB mov ebx, edi ; source 877 000004ED E8BD020000 call chkdot 878 000004F2 7307 jnc short mv_45 879 mv_44: 880 ;fprintf(stderr, "mv: Sorry, path names 881 ; including %s aren't allowed\n", DOTDOT); 882 000004F4 B8[A10A0000] mov eax, msg_pathname_dotdot 883 000004F9 EB9E jmp short mv_38 884 mv_45: 885 000004FB 8B1D[940B0000] mov ebx, [target] ; target 886 00000501 E8A9020000 call chkdot 887 00000506 72EC jc short mv_44 888 mv_46: 889 ;stat(source, &s1); 890 ;if (check(pname(target), s1.st_ino)) 891 00000508 BB[E40C0000] mov ebx, tbuf 892 0000050D E820020000 call check 893 00000512 7241 jc short mv_49 ; return(1); 894 mv_47: 895 ;for (i = 1; i <= NSIG; i++) 896 ; signal(i, SIG_IGN); 897 ; if (link(source, target) < 0) { 898 899 sys _link, edi, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000514 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000516 8B0D[940B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000051C B809000000 <1> mov eax, %1 87 00000521 CD30 <1> int 30h 900 00000523 7331 jnc short mv_50 901 902 ; fprintf(stderr, "mv: cannot link %s to %s\n", 903 ; target, source); 904 mv_48: 905 00000525 B8[EE0A0000] mov eax, msg_cant_link 906 0000052A E87F030000 call print_msg 907 0000052F A1[940B0000] mov eax, [target] ; target 908 00000534 E875030000 call print_msg 909 00000539 B8[010B0000] mov eax, msg_to 910 0000053E E86B030000 call print_msg 911 00000543 89F8 mov eax, edi ; source 912 00000545 E864030000 call print_msg 913 0000054A B8[52090000] mov eax, nextline 914 0000054F E85A030000 call print_msg 915 00000554 F9 stc 916 mv_49: 917 00000555 C3 retn 918 mv_50: 919 ;if (unlink(source) < 0) { 920 sys _unlink, edi 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000556 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000558 B80A000000 <1> mov eax, %1 87 0000055D CD30 <1> int 30h 921 0000055F 732A jnc short mv_51 922 923 ;fprintf(stderr, "mv: %s: cannot unlink\n", source); 924 00000561 B8[B5090000] mov eax, msg_cant_unlink 925 00000566 E843030000 call print_msg 926 0000056B 89F8 mov eax, edi ; source 927 0000056D E83C030000 call print_msg 928 00000572 B8[52090000] mov eax, nextline 929 00000577 E832030000 call print_msg 930 ;unlink(target); 931 sys _unlink, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000057C 8B1D[940B0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000582 B80A000000 <1> mov eax, %1 87 00000587 CD30 <1> int 30h 932 ;return(1); 933 00000589 F9 stc 934 0000058A C3 retn 935 mv_51: 936 ;strcat(dst, target); 937 ;strcat(dst, "/"); 938 ;strcat(dst, DOTDOT); 939 940 0000058B 8B35[940B0000] mov esi, [target] 941 00000591 57 push edi ; * 942 00000592 BF[0C0E0000] mov edi, nspth 943 mv_52: 944 00000597 AC lodsb 945 00000598 AA stosb 946 00000599 20C0 and al, al 947 0000059B 75FA jnz short mv_52 948 0000059D 4F dec edi 949 0000059E B82F2E2E00 mov eax, 002E2E2Fh ; db '/..', 0 950 000005A3 AB stosd 951 000005A4 5F pop edi ; * 952 953 ;if (unlink(dst) < 0) 954 sys _unlink, nspth 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000005A5 BB[0C0E0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000005AA B80A000000 <1> mov eax, %1 87 000005AF CD30 <1> int 30h 955 000005B1 733E jnc short mv_56 956 957 ; fprintf(stderr, "mv: %s: cannot unlink\n", dst); 958 000005B3 B8[B5090000] mov eax, msg_cant_unlink 959 000005B8 E8F1020000 call print_msg 960 000005BD B8[0C0E0000] mov eax, nspth ; dst 961 000005C2 E8E7020000 call print_msg 962 000005C7 B8[52090000] mov eax, nextline 963 000005CC E8DD020000 call print_msg 964 mv_53: 965 ;if (link(target, source) >= 0) 966 ; unlink(target); 967 sys _link, edi, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000005D1 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000005D3 8B0D[940B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000005D9 B809000000 <1> mov eax, %1 87 000005DE CD30 <1> int 30h 968 000005E0 720E jc short mv_55 969 mv_54: 970 ;unlink(target); 971 sys _unlink, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000005E2 8B1D[940B0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000005E8 B80A000000 <1> mov eax, %1 87 000005ED CD30 <1> int 30h 972 ;return(1); 973 000005EF F9 stc 974 mv_55: 975 000005F0 C3 retn 976 mv_56: 977 ;if (link(pname(target), dst) < 0) 978 sys _link, tbuf, nspth 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000005F1 BB[E40C0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000005F6 B9[0C0E0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000005FB B809000000 <1> mov eax, %1 87 00000600 CD30 <1> int 30h 979 00000602 73EC jnc short mv_55 ;return(0) 980 981 ;fprintf(stderr, "mv: cannot link %s to %s\n", 982 ; dst, pname(target)); 983 00000604 B8[EE0A0000] mov eax, msg_cant_link 984 00000609 E8A0020000 call print_msg 985 0000060E B8[0C0E0000] mov eax, nspth ; dst 986 00000613 E896020000 call print_msg 987 00000618 B8[010B0000] mov eax, msg_to 988 0000061D E88C020000 call print_msg 989 00000622 B8[E40C0000] mov eax, tbuf ; pname(taget) 990 00000627 E882020000 call print_msg 991 0000062C B8[52090000] mov eax, nextline 992 00000631 E878020000 call print_msg 993 ;if (link(pname(source), dst) >= 0) 994 sys _link, sbuf, nspth 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000636 BB[880C0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000063B B9[0C0E0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000640 B809000000 <1> mov eax, %1 87 00000645 CD30 <1> int 30h 995 00000647 72A7 jc short mv_55 996 ;if (link(target, source) >= 0) 997 ; unlink(target); 998 00000649 EB86 jmp short mv_53 999 1000 mv_57: 1001 ; (move dir in same parent directory) 1002 1003 ;if (link(source, target) < 0) 1004 sys _link, edi, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000064B 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000064D 8B0D[940B0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000653 B809000000 <1> mov eax, %1 87 00000658 CD30 <1> int 30h 1005 0000065A 7331 jnc short mv_60 1006 ;fprintf(stderr, "mv: cannot link %s and %s\n", 1007 ; source, target); 1008 0000065C B8[EE0A0000] mov eax, msg_cant_link 1009 00000661 E848020000 call print_msg 1010 00000666 89F8 mov eax, edi ; source 1011 00000668 E841020000 call print_msg 1012 0000066D B8[060B0000] mov eax, msg_and 1013 00000672 E837020000 call print_msg 1014 00000677 A1[940B0000] mov eax, [target] ; target 1015 mv_58: 1016 0000067C E82D020000 call print_msg 1017 00000681 B8[52090000] mov eax, nextline 1018 00000686 E823020000 call print_msg 1019 ;return(1); 1020 0000068B F9 stc 1021 mv_59: 1022 0000068C C3 retn 1023 mv_60: 1024 ;if (unlink(source) < 0) { 1025 sys _unlink, edi 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000068D 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000068F B80A000000 <1> mov eax, %1 87 00000694 CD30 <1> int 30h 1026 00000696 73F4 jnc short mv_59 ;return(0) 1027 1028 ;fprintf(stderr, "mv: ?? cannot unlink 1029 ; %s\n", source); 1030 1031 00000698 B8[B5090000] mov eax, msg_cant_unlink 1032 0000069D E80C020000 call print_msg 1033 000006A2 89F8 mov eax, edi ; source 1034 000006A4 EBD6 jmp short mv_58 1035 1036 ;----------------------------------------------------------------- 1037 1038 strcpy: 1039 000006A6 89EE mov esi, ebp ; target 1040 000006A8 89FB mov ebx, edi ; source 1041 000006AA 89DA mov edx, ebx 1042 000006AC BF[240C0000] mov edi, buf ; pathname buffer (100 bytes) 1043 000006B1 893D[940B0000] mov [target], edi 1044 strcp_1: 1045 000006B7 AC lodsb 1046 000006B8 08C0 or al, al 1047 000006BA 7403 jz short strcp_2 1048 000006BC AA stosb 1049 000006BD EBF8 jmp short strcp_1 1050 strcp_2: 1051 ; 27/05/2022 1052 000006BF B02F mov al, DELIM ; '/' 1053 000006C1 81FF[240C0000] cmp edi, buf 1054 000006C7 7605 jna short strcp_3 1055 ;cmp byte [edi-1], DELIM ; '/' 1056 000006C9 3847FF cmp byte [edi-1], al ; '/' 1057 000006CC 7401 je short strcp_4 1058 strcp_3: 1059 ;mov al, DELIM ; '/' 1060 000006CE AA stosb 1061 strcp_4: 1062 ; edx = source (pathname) 1063 ; edi = buffer (offset) position 1064 000006CF E80E000000 call dname 1065 000006D4 89DF mov edi, ebx ; source 1066 ; target = buf; 1067 000006D6 C3 retn 1068 1069 ;----------------------------------------------------------------- 1070 1071 strcmp: 1072 ; esi = source 1073 ; edi = target 1074 strcmp_1: 1075 000006D7 AC lodsb 1076 000006D8 08C0 or al, al 1077 000006DA 7404 jz short strcmp_2 1078 000006DC AE scasb 1079 000006DD 74F8 je short strcmp_1 1080 000006DF C3 retn 1081 strcmp_2: 1082 ;cmp [edi], al ; 0 1083 000006E0 AE scasb 1084 strcmp_3: 1085 ; zf = 1 -> same 1086 000006E1 C3 retn 1087 1088 ;----------------------------------------------------------------- 1089 1090 dname: ; dname(name) 1091 ; edx = source (pathname) 1092 ; edi = buffer (offset) position 1093 dname_0: 1094 000006E2 89D6 mov esi, edx ; name 1095 ;p = name; 1096 ;while (*p) 1097 dname_1: 1098 000006E4 AC lodsb 1099 000006E5 20C0 and al, al 1100 000006E7 740D jz short dname_2 1101 000006E9 3C2F cmp al, DELIM ; cmp al, '/' 1102 000006EB 75F7 jne short dname_1 1103 ;if (*p++ == DELIM && *p) 1104 000006ED 803E00 cmp byte [esi], 0 1105 ;je short dname_1 1106 000006F0 7404 je short dname_2 1107 000006F2 89F2 mov edx, esi 1108 000006F4 EBEE jmp short dname_1 1109 dname_2: 1110 ; edx = file name 1111 000006F6 89D6 mov esi, edx 1112 dname_3: 1113 000006F8 AC lodsb 1114 000006F9 AA stosb 1115 000006FA 08C0 or al, al 1116 000006FC 75FA jnz short dname_3 1117 000006FE C3 retn 1118 1119 ;----------------------------------------------------------------- 1120 1121 pname: ; pname(name) 1122 ; 23/05/2022 1123 1124 ; INPUT: 1125 ; edi = source (pathname) 1126 ; ebx = buffer address 1127 ; OUTPUT: 1128 ; esi = parent dir name address 1129 pname_0: 1130 000006FF 89FE mov esi, edi ; source 1131 00000701 57 push edi ; * 1132 ;p = q = buf; 1133 00000702 89DF mov edi, ebx 1134 00000704 89D9 mov ecx, ebx 1135 ; while (c = *p++ = *name++) 1136 pname_1: 1137 00000706 AC lodsb 1138 00000707 AA stosb 1139 00000708 20C0 and al, al 1140 0000070A 7409 jz short pname_2 1141 ;if (c == DELIM) 1142 ; q = p-1; 1143 0000070C 3C2F cmp al, DELIM ; cmp al, '/' 1144 0000070E 75F6 jne short pname_1 1145 00000710 89FB mov ebx, edi 1146 00000712 4B dec ebx 1147 00000713 EBF1 jmp short pname_1 1148 pname_2: 1149 ;if (q == buf && *q == DELIM) 1150 ; q++; 1151 00000715 39CB cmp ebx, ecx 1152 00000717 7506 jne short pname_3 1153 00000719 803B2F cmp byte [ebx], DELIM ; '/' 1154 0000071C 7501 jne short pname_3 1155 0000071E 43 inc ebx 1156 pname_3: 1157 ;*q = 0; 1158 0000071F C60300 mov byte [ebx], 0 1159 00000722 89CE mov esi, ecx 1160 00000724 5F pop edi ; * 1161 ; return buf[0]? buf : DOT; 1162 00000725 803E00 cmp byte [esi], 0 1163 00000728 7707 ja short pname_4 1164 0000072A A1[E5080000] mov eax, [DOT] ; db '.', 0 1165 0000072F 8906 mov [esi], eax 1166 pname_4: 1167 00000731 C3 retn 1168 1169 ;----------------------------------------------------------------- 1170 1171 check: ; check(spth, dinode) 1172 ; 23/05/2022 1173 1174 ; INPUT: 1175 ; ebx = name buffer address 1176 ; [st1buf+stat.inode] = inode num to be compared 1177 ; OUTPUT: 1178 ; cf = 1 -> error 1179 ; cf = 0 -> no problem 1180 1181 ;strcpy(nspth, spth); 1182 1183 00000732 89DE mov esi, ebx 1184 00000734 57 push edi ; * 1185 00000735 BF[0C0E0000] mov edi, nspth 1186 check_1: 1187 0000073A AC lodsb 1188 0000073B AA stosb 1189 0000073C 20C0 and al, al 1190 0000073E 75FA jnz short check_1 1191 00000740 29DE sub esi, ebx 1192 00000742 4E dec esi ; esi = strlen(nspth) 1193 00000743 5F pop edi ; * 1194 check_2: 1195 ;if (stat(nspth, &sbuf) < 0) 1196 sys _stat, nspth, fstbuf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000744 BB[0C0E0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000749 B9[400D0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000074E B812000000 <1> mov eax, %1 87 00000753 CD30 <1> int 30h 1197 00000755 7320 jnc short check_5 1198 ;fprintf(stderr, "mv: cannot access %s\n", nspth); 1199 00000757 B8[82090000] mov eax, msg_cant_access 1200 0000075C E84D010000 call print_msg 1201 00000761 B8[0C0E0000] mov eax, nspth 1202 00000766 E843010000 call print_msg 1203 0000076B B8[52090000] mov eax, nextline 1204 check_3: 1205 00000770 E839010000 call print_msg 1206 00000775 F9 stc 1207 check_4: 1208 00000776 C3 retn 1209 check_5: 1210 ;if (sbuf.st_ino == dinode) 1211 00000777 66A1[400D0000] mov ax, [fstbuf+stat.inode] 1212 0000077D 663B05[9C0B0000] cmp ax, [st1buf+stat.inode] 1213 00000784 7507 jne short check_6 1214 ; fprintf(stderr, "mv: cannot move a directory 1215 ; into itself\n"); 1216 00000786 B8[1D0B0000] mov eax, msg_cant_mv_itself 1217 0000078B EBE3 jmp short check_3 1218 check_6: 1219 ;while (sbuf.st_ino != ROOTINO) 1220 0000078D 6683F801 cmp ax, ROOTINO 1221 00000791 74E3 je short check_4 1222 1223 ;if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) 1224 00000793 83FE6C cmp esi, MAXN-4 1225 00000796 7607 jna short check_7 1226 1227 ;fprintf(stderr, "mv: name too long\n"); 1228 00000798 B8[490B0000] mov eax, msg_too_long 1229 0000079D EBD1 jmp short check_3 1230 check_7: 1231 ;strcat(nspth, SDELIM); 1232 ;strcat(nspth, DOTDOT); 1233 0000079F B82F2E2E00 mov eax, 002E2E2Fh ; db '/..', 0 1234 000007A4 8986[0C0E0000] mov [esi+nspth], eax 1235 000007AA 83C603 add esi, 3 1236 000007AD EB95 jmp short check_2 1237 1238 ;----------------------------------------------------------------- 1239 1240 chkdot: ; chkdot(s) 1241 ; 23/05/2022 1242 1243 ;do { 1244 ; if (strcmp(dname(s), DOTDOT) == 0) 1245 ; return(1); 1246 ; s = pname(s); 1247 ;} while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0); 1248 ;return(0); 1249 1250 ; INPUT: 1251 ; ebx = name buffer address 1252 ; OUTPUT: 1253 ; cf = 1 -> DOTDOT (return 0) 1254 ; cf = 0 -> not DOTDOT (return 1) 1255 1256 ; get last '/' 1257 000007AF 89DE mov esi, ebx 1258 chkdot_0: 1259 000007B1 89D9 mov ecx, ebx 1260 chkdot_1: 1261 000007B3 AC lodsb 1262 000007B4 20C0 and al, al 1263 000007B6 740E jz short chkdot_2 1264 000007B8 3C2F cmp al, DELIM ; '/' 1265 000007BA 75F7 jne short chkdot_1 1266 000007BC 803E00 cmp byte [esi], 0 1267 000007BF 7605 jna short chkdot_2 1268 000007C1 89F1 mov ecx, esi 1269 000007C3 49 dec ecx 1270 000007C4 EBED jmp short chkdot_1 1271 chkdot_2: 1272 000007C6 57 push edi ; * 1273 000007C7 89CE mov esi, ecx 1274 000007C9 BF[E4080000] mov edi, DOTDOT 1275 000007CE E804FFFFFF call strcmp 1276 000007D3 7417 jz short chkdot_4 ; DOTDOT 1277 000007D5 89DF mov edi, ebx 1278 000007D7 BB[400D0000] mov ebx, fstbuf 1279 000007DC E81EFFFFFF call pname 1280 000007E1 5F pop edi ; * 1281 000007E2 89F3 mov ebx, esi ; parent dir's pathname buf 1282 000007E4 668B06 mov ax, [esi] 1283 000007E7 08E4 or ah, ah ; 0 ? 1284 000007E9 75C6 jnz short chkdot_0 1285 ; (single character parent directory name) 1286 ; (it's name may be '.' or '/' or another char) 1287 ; pathname does not contain a DOTDOT 1288 000007EB C3 retn 1289 chkdot_4: 1290 ; pathname contains DOTDOT 1291 000007EC F9 stc 1292 000007ED C3 retn 1293 1294 ;----------------------------------------------------------------- 1295 1296 access: 1297 ; 27/05/2022 1298 ; 22/05/2022 1299 ; Retro UNIX 386 v1 & v1.1 & v1.2 1300 1301 ; INPUT: 1302 ; esi = stat(us) buffer 1303 ; OUTPUT: 1304 ; zf = 1 -> no write permission 1305 ; zf = 0 -> permitted to write 1306 1307 sys _getuid 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000007EE B818000000 <1> mov eax, %1 87 000007F3 CD30 <1> int 30h 1308 ;mov [uid], ax 1309 1310 ; Retro UNIX 386 v1.2 (v2 fs) 1311 000007F5 B280 mov dl, 80h ; write permission flag, owner 1312 1313 ; Retro UNIX 386 v1 1314 ;mov dl, 4 ; write permission flag, owner 1315 1316 ;or ax, ax 1317 000007F7 08C0 or al, al 1318 000007F9 7415 jz short access_1 ; root 1319 1320 ;cmp ax, [esi+stat.uid] 1321 000007FB 3A4606 cmp al, [esi+stat.uid] 1322 000007FE 7410 je short access_1 1323 1324 ; 27/05/2022 1325 ; Retro UNIX 386 v1.2 (v2 fs inode) 1326 sys _getgid 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000800 B826000000 <1> mov eax, %1 87 00000805 CD30 <1> int 30h 1327 ;;mov [gid], al 1328 1329 00000807 B210 mov dl, 10h 1330 00000809 3A4608 cmp al, [esi+stat.gid] 1331 0000080C 7402 je short access_1 1332 ; 1333 0000080E B202 mov dl, 02h 1334 1335 ; Retro UNIX 386 v1 1336 ;mov dl, 1 1337 access_1: 1338 00000810 845602 test dl, [esi+stat.mode] 1339 00000813 C3 retn 1340 1341 ;----------------------------------------------------------------- 1342 1343 isatty: 1344 ; 27/05/2022 1345 ; 22/05/2022 1346 ; Retro UNIX 386 v1 & v1.1 & v1.2 1347 1348 ; Input: stdin (= 0) 1349 ; output: 1350 ; cf = 1 -> not a tty 1351 1352 sys _fstat, STDIN, fstbuf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000814 BB00000000 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000819 B9[400D0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 0000081E B81C000000 <1> mov eax, %1 87 00000823 CD30 <1> int 30h 1353 1354 00000825 66A1[400D0000] mov ax, [fstbuf+stat.inode] 1355 1356 ; Retro UNIX 386 v1.2 1357 0000082B 6683F808 cmp ax, 8 ; /dev/tty 1358 0000082F 740C je short isatty_2 1359 00000831 6683F81A cmp ax, 26 ; /dev/tty8 1360 00000835 7705 ja short isatty_1 1361 00000837 6683F811 cmp ax, 17 ; /dev/tty0 1362 0000083B C3 retn 1363 1364 ; Retro UNIX 386 v1 (& v1.1) 1365 ;cmp ax, 1 ; /dev/tty 1366 ;je short isatty_2 1367 ;cmp ax, 19 ; /dev/tty8 1368 ;ja short isatty_1 1369 ;cmp ax, 10 ; /dev/tty0 1370 ;retn 1371 isatty_1: 1372 0000083C F9 stc 1373 isatty_2: 1374 0000083D C3 retn 1375 1376 ;----------------------------------------------------------------- 1377 1378 octalnumber: 1379 ; 27/05/2022 1380 1381 ; Input: 1382 ; ebx = binary number (max. 9 bit) 1383 ; esi = string buffer (4 byte) 1384 1385 0000083E 89D8 mov eax, ebx 1386 00000840 B103 mov cl, 3 1387 00000842 D3EB shr ebx, cl ; 3 1388 00000844 2407 and al, 7 1389 00000846 50 push eax 1390 00000847 89D8 mov eax, ebx 1391 00000849 D3EB shr ebx, cl ; 3 1392 0000084B 2407 and al, 7 1393 0000084D 50 push eax 1394 0000084E 89D8 mov eax, ebx 1395 00000850 2407 and al, 7 1396 octn_0: 1397 ; 27/05/2022 1398 ;mov byte [esi], 20h 1399 ;inc esi 1400 00000852 89F3 mov ebx, esi 1401 ;or al, al 1402 ;jz short octn_1 1403 00000854 E810000000 call octn_3 1404 octn_1: 1405 00000859 58 pop eax 1406 ; 27/05/2022 1407 0000085A E80A000000 call octn_3 1408 octn_2: 1409 0000085F 58 pop eax 1410 ;call octn_3 1411 00000860 E80C000000 call octn_4 ; 27/05/2022 1412 00000865 30C0 xor al, al 1413 00000867 EB0A jmp short octn_5 1414 1415 octn_3: 1416 ; 27/05/2022 1417 00000869 20C0 and al, al 1418 0000086B 7504 jnz short octn_4 1419 0000086D 39DE cmp esi, ebx 1420 0000086F 7405 je short octn_6 1421 octn_4: 1422 00000871 0430 add al, '0' 1423 octn_5: 1424 00000873 8806 mov [esi], al 1425 00000875 46 inc esi 1426 octn_6: 1427 00000876 C3 retn 1428 1429 ;----------------------------------------------------------------- 1430 1431 getchar: 1432 ; i = c = getchar(); 1433 ; while (c != '\n' && c != EOF) 1434 ; c = getchar(); 1435 getc_0: 1436 sys _read, STDIN, char, 1 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000877 BB00000000 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000087C B9[0B0E0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 00000881 BA01000000 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000886 B803000000 <1> mov eax, %1 87 0000088B CD30 <1> int 30h 1437 0000088D A0[0B0E0000] mov al, [char] 1438 00000892 3C79 cmp al, 'y' 1439 00000894 7417 je short getc_2 1440 00000896 3C6E cmp al, 'n' 1441 00000898 7413 je short getc_2 1442 0000089A 3C1B cmp al, ESCKey 1443 0000089C 740F je short getc_2 1444 0000089E 3C0D cmp al, EnterKey 1445 000008A0 740B je short getc_2 1446 000008A2 3C59 cmp al, 'Y' 1447 000008A4 7503 jne short getc_1 1448 000008A6 B079 mov al, 'y' 1449 000008A8 C3 retn 1450 getc_1: 1451 000008A9 3C4E cmp al, 'N' 1452 000008AB 75CA jne short getc_0 1453 getc_2: 1454 000008AD C3 retn 1455 1456 ;----------------------------------------------------------------- 1457 1458 print_msg: 1459 ; eax = asciiz string address 1460 000008AE 89C6 mov esi, eax 1461 000008B0 4E dec esi 1462 nextchr: 1463 000008B1 46 inc esi 1464 000008B2 803E00 cmp byte [esi], 0 1465 000008B5 77FA ja short nextchr 1466 ;cmp [esi], 0Dh 1467 ;ja short nextchr 1468 000008B7 29C6 sub esi, eax 1469 ; esi = asciiz string length 1470 ; 1471 sys _write, 1, eax, esi 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000008B9 BB01000000 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000008BE 89C1 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 000008C0 89F2 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000008C2 B804000000 <1> mov eax, %1 87 000008C7 CD30 <1> int 30h 1472 ; 1473 000008C9 C3 retn 1474 1475 ;----------------------------------------------------------------- 1476 ; data - initialized data 1477 ;----------------------------------------------------------------- 1478 1479 ;argc: dd 0 1480 000008CA 00 argc: db 0 1481 000008CB 00 errors: db 0 1482 1483 cp_cmd: 1484 000008CC 2F62696E2F637000 db '/bin/cp', 0 1485 1486 cp_args: 1487 000008D4 [CC080000] dd cp_cmd 1488 cp_source: 1489 000008D8 00000000 dd 0 1490 cp_target: 1491 000008DC 00000000 dd 0 1492 000008E0 00000000 dd 0 1493 1494 000008E4 2E DOTDOT: db '.' 1495 000008E5 2E00 DOT: db '.', 0 1496 ;db 0, 0 1497 1498 ; ---------------------------------------------------------------- 1499 1500 program_msg: 1501 000008E7 0D0A db 0Dh, 0Ah 1502 000008E9 526574726F20554E49- db 'Retro UNIX 386 v1.2 MOVE by Erdogan TAN - 27/05/2022' 1502 000008F2 58203338362076312E- 1502 000008FB 32204D4F5645206279- 1502 00000904 204572646F67616E20- 1502 0000090D 54414E202D2032372F- 1502 00000916 30352F32303232 1503 0000091D 0D0A00 db 0Dh, 0Ah, 0 1504 1505 usage_msg: 1506 00000920 0D0A db 0Dh, 0Ah 1507 00000922 75736167653A206D76- db 'usage: mv f1 f2; or mv d1 d2; or mv f1 ... fn d1' 1507 0000092B 2066312066323B206F- 1507 00000934 72206D762064312064- 1507 0000093D 323B206F72206D7620- 1507 00000946 6631202E2E2E20666E- 1507 0000094F 206431 1508 nextline: 1509 00000952 0D0A00 db 0Dh, 0Ah, 0 1510 1511 mv_header: 1512 00000955 0D0A db 0Dh, 0Ah 1513 00000957 6D763A20 db 'mv: ' 1514 0000095B 00 db 0 1515 msg_not_exists: 1516 ;db 0Dh, 0Ah 1517 0000095C 20646F6573206E6F74- db ' does not exist ' 1517 00000965 20657869737420 1518 0000096C 0D0A00 db 0Dh, 0Ah, 0 1519 1520 msg_is_a_dir: 1521 0000096F 206973206120646972- db ' is a directory ' 1521 00000978 6563746F727920 1522 0000097F 0D0A00 db 0Dh, 0Ah, 0 1523 1524 msg_cant_access: 1525 00000982 0D0A db 0Dh, 0Ah 1526 00000984 6D763A2063616E6E6F- db 'mv: cannot access ' 1526 0000098D 742061636365737320 1527 00000996 00 db 0 1528 1529 msg_rename_only: 1530 00000997 0D0A db 0Dh, 0Ah 1531 00000999 6D763A206469726563- db 'mv: directory rename only' 1531 000009A2 746F72792072656E61- 1531 000009AB 6D65206F6E6C79 1532 000009B2 0D0A00 db 0Dh, 0Ah, 0 1533 1534 msg_cant_unlink: 1535 000009B5 0D0A db 0Dh, 0Ah 1536 000009B7 6D763A2063616E6E6F- db 'mv: cannot unlink ' 1536 000009C0 7420756E6C696E6B20 1537 000009C9 00 db 0 1538 1539 msg_try_again: 1540 000009CA 0D0A db 0Dh, 0Ah 1541 000009CC 6D763A207472792061- db 'mv: try again' 1541 000009D5 6761696E 1542 000009D9 0D0A00 db 0Dh, 0Ah, 0 1543 1544 msg_cant_exec_cp: 1545 000009DC 0D0A db 0Dh, 0Ah 1546 000009DE 6D763A2063616E6E6F- db 'mv: cannot exec cp' 1546 000009E7 742065786563206370 1547 000009F0 0D0A00 db 0Dh, 0Ah, 0 1548 1549 msg_exists: 1550 000009F3 2065786973747320 db ' exists ' 1551 000009FB 0D0A00 db 0Dh, 0Ah, 0 1552 1553 ;msg_long_target: 1554 ; db 0Dh, 0Ah 1555 ; db 'mv: target name too long' 1556 ; db 0Dh, 0Ah, 0 1557 1558 msg_src_target: 1559 000009FE 0D0A db 0Dh, 0Ah 1560 00000A00 6D763A203F3F20736F- db 'mv: ?? source == target, source exists and target doesnt' 1560 00000A09 75726365203D3D2074- 1560 00000A12 61726765742C20736F- 1560 00000A1B 757263652065786973- 1560 00000A24 747320616E64207461- 1560 00000A2D 7267657420646F6573- 1560 00000A36 6E74 1561 00000A38 0D0A00 db 0Dh, 0Ah, 0 1562 1563 msg_cant_locate: 1564 00000A3B 0D0A db 0Dh, 0Ah 1565 00000A3D 6D763A2063616E6E6F- db 'mv: cannot locate parent' 1565 00000A46 74206C6F6361746520- 1565 00000A4F 706172656E74 1566 00000A55 0D0A00 db 0Dh, 0Ah, 0 1567 1568 msg_no_w_access: 1569 00000A58 0D0A db 0Dh, 0Ah 1570 00000A5A 6D763A206E6F207772- db 'mv: no write access to ' 1570 00000A63 697465206163636573- 1570 00000A6C 7320746F20 1571 00000A71 00 db 0 1572 1573 msg_accross_devices: 1574 00000A72 0D0A db 0Dh, 0Ah 1575 00000A74 6D763A2063616E6E6F- db 'mv: cannot move directories across devices' 1575 00000A7D 74206D6F7665206469- 1575 00000A86 726563746F72696573- 1575 00000A8F 206163726F73732064- 1575 00000A98 657669636573 1576 00000A9E 0D0A00 db 0Dh, 0Ah, 0 1577 1578 msg_pathname_dotdot: 1579 00000AA1 0D0A db 0Dh, 0Ah 1580 00000AA3 6D763A20536F727279- db "mv: Sorry, path names including '..' aren't allowed" 1580 00000AAC 2C2070617468206E61- 1580 00000AB5 6D657320696E636C75- 1580 00000ABE 64696E6720272E2E27- 1580 00000AC7 206172656E27742061- 1580 00000AD0 6C6C6F776564 1581 00000AD6 0D0A00 db 0Dh, 0Ah, 0 1582 1583 msg_cant_rename: 1584 00000AD9 0D0A db 0Dh, 0Ah 1585 00000ADB 6D763A2063616E6E6F- db 'mv: cannot rename ' 1585 00000AE4 742072656E616D6520 1586 00000AED 00 db 0 1587 1588 msg_cant_link: 1589 00000AEE 0D0A db 0Dh, 0Ah 1590 00000AF0 6D763A2063616E6E6F- db 'mv: cannot link ' 1590 00000AF9 74206C696E6B20 1591 00000B00 00 db 0 1592 msg_to: 1593 00000B01 20746F20 db ' to ' 1594 00000B05 00 db 0 1595 msg_and: 1596 00000B06 20616E6420 db ' and ' 1597 00000B0B 00 db 0 1598 1599 msg_identical: 1600 00000B0C 20617265206964656E- db ' are identical' 1600 00000B15 746963616C 1601 00000B1A 0D0A00 db 0Dh, 0Ah, 0 1602 1603 msg_cant_mv_itself: 1604 00000B1D 0D0A db 0Dh, 0Ah 1605 00000B1F 6D763A2063616E6E6F- db 'mv: cannot move a directory into itself' 1605 00000B28 74206D6F7665206120- 1605 00000B31 6469726563746F7279- 1605 00000B3A 20696E746F20697473- 1605 00000B43 656C66 1606 00000B46 0D0A00 db 0Dh, 0Ah, 0 1607 1608 msg_too_long: 1609 00000B49 0D0A db 0Dh, 0Ah 1610 00000B4B 6D763A206E616D6520- db 'mv: name too long' 1610 00000B54 746F6F206C6F6E67 1611 00000B5C 0D0A00 db 0Dh, 0Ah, 0 1612 1613 msg_mode: 1614 00000B5F 206D6F6465203F2028- db ' mode ? (y/n) ' 1614 00000B68 792F6E2920 1615 00000B6D 00 db 0 1616 1617 msg_yes: 1618 00000B6E 2059455320 db ' YES ' 1619 00000B73 0D0A00 db 0Dh, 0Ah, 0 1620 1621 msg_no: 1622 00000B76 204E4F20 db ' NO ' 1623 00000B7A 0D0A00 db 0Dh, 0Ah, 0 1624 1625 err_msg: 1626 00000B7D 0D0A db 0Dh, 0Ah 1627 00000B7F 4572726F722120 db 'Error! ' 1628 00000B86 0D0A00 db 0Dh, 0Ah, 0 1629 1630 msg_ok: 1631 00000B89 0D0A db 0Dh, 0Ah 1632 00000B8B 4F4B2E db 'OK.' 1633 00000B8E 0D0A00 db 0Dh, 0Ah, 0 1634 1635 ;----------------------------------------------------------------- 1636 ; bss - uninitialized data 1637 ;----------------------------------------------------------------- 1638 1639 00000B91 90 align 4 1640 1641 bss_start: 1642 1643 ABSOLUTE bss_start 1644 1645 ;uid: resw 1 1646 ;gid: resw 1 ; Retro UNIX 386 v1.2 1647 1648 00000B94 ???????? target: resd 1 ; destination/target pathname pointer 1649 1650 ;st1dev: resw 1 1651 ;st1buf: resb 34 ; for Retro UNIX 386 v1 & v1.1 1652 ;st2dev: resw 1 1653 ;st2buf: resb 34 ; 1654 00000B98 ???????? st1dev: resd 1 1655 00000B9C st1buf: resb 66 ; for Retro UNIX 386 v1.2 1656 00000BDE ???????? st2dev: resd 1 1657 00000BE2 st2buf: resb 66 ; 1658 1659 00000C24 buf: resb 100 ; pathname buffer 1660 00000C88 sbuf: resb 92 ; source, parent name buffer ; 23/05/2022 1661 00000CE4 tbuf: resb 92 ; target, parent name buffer ; 23/05/2022 1662 00000D40 fstbuf: resb 66 ; fstat buffer 1663 ; 23/05/2022 1664 00000D82 pst1buf: resb 66 1665 00000DC4 pst2buf: resb 66 1666 ;pst1buf: resb 34 1667 ;pst2buf: resb 34 1668 00000E06 ?? octms: resb 1 ; 27/05/2022 1669 00000E07 ???????? octm: resb 4 ; octal mode number 1670 00000E0B ?? char: resb 1 ; getchar buffer 1671 00000E0C nspth: resb MAXN ; 112 ; buffer for 'check' procedure 1672 1673 ; 22/05/2022 1674 ;----------------------------------------------------------------- 1675 ; Original UNIX v7 - mv (utility) c source code (mv.c) 1676 ;----------------------------------------------------------------- 1677 ;/* UNIX V7 source code: see www.tuhs.org for details. */; 1678 ; 1679 ;/* 1680 ; * mv file1 file2 1681 ; */ 1682 ; 1683 ;#include 1684 ;#include 1685 ;#include 1686 ;#include 1687 ;#include 1688 ; 1689 ;#define DOT "." 1690 ;#define DOTDOT ".." 1691 ;#define DELIM '/' 1692 ;#define SDELIM "/" 1693 ;#define MAXN 100 1694 ;#define MODEBITS 07777 1695 ;#define ROOTINO 2 1696 ; 1697 ;char *pname(); 1698 ;char *sprintf(); 1699 ;char *dname(); 1700 ;struct stat s1, s2; 1701 ; 1702 ;main(argc, argv) 1703 ;register char *argv[]; 1704 ;{ 1705 ; register i, r; 1706 ; 1707 ; if (argc < 3) 1708 ; goto usage; 1709 ; if (stat(argv[1], &s1) < 0) { 1710 ; fprintf(stderr, "mv: cannot access %s\n", argv[1]); 1711 ; return(1); 1712 ; } 1713 ; if ((s1.st_mode & S_IFMT) == S_IFDIR) { 1714 ; if (argc != 3) 1715 ; goto usage; 1716 ; return mvdir(argv[1], argv[2]); 1717 ; } 1718 ; setuid(getuid()); 1719 ; if (argc > 3) 1720 ; if (stat(argv[argc-1], &s2) < 0 || (s2.st_mode & S_IFMT) != S_IFDIR) 1721 ; goto usage; 1722 ; r = 0; 1723 ; for (i=1; i= 0) { 1747 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) { 1748 ; sprintf(buf, "%s/%s", target, dname(source)); 1749 ; target = buf; 1750 ; } 1751 ; if (stat(target, &s2) >= 0) { 1752 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) { 1753 ; fprintf(stderr, "mv: %s is a directory\n", target); 1754 ; return(1); 1755 ; } 1756 ; if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) { 1757 ; fprintf(stderr, "mv: %s and %s are identical\n", 1758 ; source, target); 1759 ; return(1); 1760 ; } 1761 ; if (access(target, 2) < 0 && isatty(fileno(stdin))) { 1762 ; fprintf(stderr, "mv: %s: %o mode ", target, 1763 ; s2.st_mode & MODEBITS); 1764 ; i = c = getchar(); 1765 ; while (c != '\n' && c != EOF) 1766 ; c = getchar(); 1767 ; if (i != 'y') 1768 ; return(1); 1769 ; } 1770 ; if (unlink(target) < 0) { 1771 ; fprintf(stderr, "mv: cannot unlink %s\n", target); 1772 ; return(1); 1773 ; } 1774 ; } 1775 ; } 1776 ; if (link(source, target) < 0) { 1777 ; i = fork(); 1778 ; if (i == -1) { 1779 ; fprintf(stderr, "mv: try again\n"); 1780 ; return(1); 1781 ; } 1782 ; if (i == 0) { 1783 ; execl("/bin/cp", "cp", source, target, 0); 1784 ; fprintf(stderr, "mv: cannot exec cp\n"); 1785 ; exit(1); 1786 ; } 1787 ; while ((c = wait(&status)) != i && c != -1) 1788 ; ; 1789 ; if (status != 0) 1790 ; return(1); 1791 ; utime(target, &s1.st_atime); 1792 ; } 1793 ; if (unlink(source) < 0) { 1794 ; fprintf(stderr, "mv: cannot unlink %s\n", source); 1795 ; return(1); 1796 ; } 1797 ; return(0); 1798 ;} 1799 ; 1800 ;mvdir(source, target) 1801 ;char *source, *target; 1802 ;{ 1803 ; register char *p; 1804 ; register i; 1805 ; char buf[MAXN]; 1806 ; 1807 ; if (stat(target, &s2) >= 0) { 1808 ; if ((s2.st_mode&S_IFMT) != S_IFDIR) { 1809 ; fprintf(stderr, "mv: %s exists\n", target); 1810 ; return(1); 1811 ; } 1812 ; if (strlen(target) > MAXN-DIRSIZ-2) { 1813 ; fprintf(stderr, "mv :target name too long\n"); 1814 ; return(1); 1815 ; } 1816 ; strcpy(buf, target); 1817 ; target = buf; 1818 ; strcat(buf, SDELIM); 1819 ; strcat(buf, dname(source)); 1820 ; if (stat(target, &s2) >= 0) { 1821 ; fprintf(stderr, "mv: %s exists\n", buf); 1822 ; return(1); 1823 ; } 1824 ; } 1825 ; if (strcmp(source, target) == 0) { 1826 ; fprintf(stderr, "mv: ?? source == target, source exists and target doesnt\n"); 1827 ; return(1); 1828 ; } 1829 ; p = dname(source); 1830 ; if (!strcmp(p, DOT) || !strcmp(p, DOTDOT) || !strcmp(p, "") || p[strlen(p)-1]=='/') { 1831 ; fprintf(stderr, "mv: cannot rename %s\n", p); 1832 ; return(1); 1833 ; } 1834 ; if (stat(pname(source), &s1) < 0 || stat(pname(target), &s2) < 0) { 1835 ; fprintf(stderr, "mv: cannot locate parent\n"); 1836 ; return(1); 1837 ; } 1838 ; if (access(pname(target), 2) < 0) { 1839 ; fprintf(stderr, "mv: no write access to %s\n", pname(target)); 1840 ; return(1); 1841 ; } 1842 ; if (access(pname(source), 2) < 0) { 1843 ; fprintf(stderr, "mv: no write access to %s\n", pname(source)); 1844 ; return(1); 1845 ; } 1846 ; if (access(source, 2) < 0) { 1847 ; fprintf(stderr, "mv: no write access to %s\n", source); 1848 ; return(1); 1849 ; } 1850 ; if (s1.st_dev != s2.st_dev) { 1851 ; fprintf(stderr, "mv: cannot move directories across devices\n"); 1852 ; return(1); 1853 ; } 1854 ; if (s1.st_ino != s2.st_ino) { 1855 ; char dst[MAXN+5]; 1856 ; 1857 ; if (chkdot(source) || chkdot(target)) { 1858 ; fprintf(stderr, "mv: Sorry, path names including %s aren't allowed\n", DOTDOT); 1859 ; return(1); 1860 ; } 1861 ; stat(source, &s1); 1862 ; if (check(pname(target), s1.st_ino)) 1863 ; return(1); 1864 ; for (i = 1; i <= NSIG; i++) 1865 ; signal(i, SIG_IGN); 1866 ; if (link(source, target) < 0) { 1867 ; fprintf(stderr, "mv: cannot link %s to %s\n", target, source); 1868 ; return(1); 1869 ; } 1870 ; if (unlink(source) < 0) { 1871 ; fprintf(stderr, "mv: %s: cannot unlink\n", source); 1872 ; unlink(target); 1873 ; return(1); 1874 ; } 1875 ; strcat(dst, target); 1876 ; strcat(dst, "/"); 1877 ; strcat(dst, DOTDOT); 1878 ; if (unlink(dst) < 0) { 1879 ; fprintf(stderr, "mv: %s: cannot unlink\n", dst); 1880 ; if (link(target, source) >= 0) 1881 ; unlink(target); 1882 ; return(1); 1883 ; } 1884 ; if (link(pname(target), dst) < 0) { 1885 ; fprintf(stderr, "mv: cannot link %s to %s\n", 1886 ; dst, pname(target)); 1887 ; if (link(pname(source), dst) >= 0) 1888 ; if (link(target, source) >= 0) 1889 ; unlink(target); 1890 ; return(1); 1891 ; } 1892 ; return(0); 1893 ; } 1894 ; if (link(source, target) < 0) { 1895 ; fprintf(stderr, "mv: cannot link %s and %s\n", 1896 ; source, target); 1897 ; return(1); 1898 ; } 1899 ; if (unlink(source) < 0) { 1900 ; fprintf(stderr, "mv: ?? cannot unlink %s\n", source); 1901 ; return(1); 1902 ; } 1903 ; return(0); 1904 ;} 1905 ; 1906 ;char * 1907 ;pname(name) 1908 ;register char *name; 1909 ;{ 1910 ; register c; 1911 ; register char *p, *q; 1912 ; static char buf[MAXN]; 1913 ; 1914 ; p = q = buf; 1915 ; while (c = *p++ = *name++) 1916 ; if (c == DELIM) 1917 ; q = p-1; 1918 ; if (q == buf && *q == DELIM) 1919 ; q++; 1920 ; *q = 0; 1921 ; return buf[0]? buf : DOT; 1922 ;} 1923 ; 1924 ;char * 1925 ;dname(name) 1926 ;register char *name; 1927 ;{ 1928 ; register char *p; 1929 ; 1930 ; p = name; 1931 ; while (*p) 1932 ; if (*p++ == DELIM && *p) 1933 ; name = p; 1934 ; return name; 1935 ;} 1936 ; 1937 ;check(spth, dinode) 1938 ;char *spth; 1939 ;ino_t dinode; 1940 ;{ 1941 ; char nspth[MAXN]; 1942 ; struct stat sbuf; 1943 ; 1944 ; sbuf.st_ino = 0; 1945 ; 1946 ; strcpy(nspth, spth); 1947 ; while (sbuf.st_ino != ROOTINO) { 1948 ; if (stat(nspth, &sbuf) < 0) { 1949 ; fprintf(stderr, "mv: cannot access %s\n", nspth); 1950 ; return(1); 1951 ; } 1952 ; if (sbuf.st_ino == dinode) { 1953 ; fprintf(stderr, "mv: cannot move a directory into itself\n"); 1954 ; return(1); 1955 ; } 1956 ; if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) { 1957 ; fprintf(stderr, "mv: name too long\n"); 1958 ; return(1); 1959 ; } 1960 ; strcat(nspth, SDELIM); 1961 ; strcat(nspth, DOTDOT); 1962 ; } 1963 ; return(0); 1964 ;} 1965 ; 1966 ;chkdot(s) 1967 ;register char *s; 1968 ;{ 1969 ; do { 1970 ; if (strcmp(dname(s), DOTDOT) == 0) 1971 ; return(1); 1972 ; s = pname(s); 1973 ; } while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0); 1974 ; return(0); 1975 ;} 1976 ;