1 ; **************************************************************************** 2 ; mv386.s (mv1.s) - by Erdogan Tan - 22/05/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 386 v1 - 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 mv1.s -l mv1.txt -o mv1 -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 00000000 ???? .inode: resw 1 107 00000002 ???? .mode: resw 1 108 00000004 ?? .nlinks: resb 1 109 00000005 ?? .uid: resb 1 110 00000006 ???? .size: resw 1 111 00000008 .dskptr: resw 8 112 00000018 ???????? .ctime: resd 1 113 0000001C ???????? .mtime: resd 1 114 00000020 ???? .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 ; .inode: resw 1 122 ; .mode: resw 1 123 ; .nlinks: resw 1 124 ; .uid: resw 1 125 ; .gid: resb 1 126 ; .size_h: resb 1 127 ; .size: resd 1 128 ; .dskptr: resd 10 129 ; .atime: resd 1 130 ; .mtime: resd 1 131 ; .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[B4080000] 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[D1080000] <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[08090000] 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[820B0000] <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[6A090000] mov eax, msg_cant_access 248 ; 24/05/2022 249 00000042 E851080000 call print_msg 250 00000047 89F8 mov eax, edi ; argv[1] 251 00000049 E84A080000 call print_msg 252 0000004E B8[3A090000] mov eax, nextline 253 print_exit: 254 00000053 E840080000 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[710B0000] 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 ;mov al, byte [st1buf+stat.mode+1] 270 ;and al, S_IFREG|S_IFDIR 271 ;cmp al, S_IFREG|S_IFDIR 272 ;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 00000069 F605[850B0000]40 test byte [st1buf+stat.mode+1], S_IFDIR 279 00000070 7413 jz short mv_2 280 281 00000072 803D[B4080000]03 cmp byte [argc], 3 282 00000079 75AA jne short mv_usage 283 284 0000007B 5D pop ebp ; argv[2] 285 286 0000007C E8DC020000 call mvdir 287 00000081 73DF jnc short mv_61 ; "OK." 288 00000083 EBD3 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 00000085 B818000000 <1> mov eax, %1 87 0000008A CD30 <1> int 30h 293 sys _setuid, eax 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000008C 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 0000008E B817000000 <1> mov eax, %1 87 00000093 CD30 <1> int 30h 294 00000095 7307 jnc short mv_3 295 296 ; error (permission denied) 297 00000097 B8[650B0000] mov eax, err_msg 298 0000009C EBB5 jmp short print_exit 299 mv_3: 300 ; (here [esp] = argv[2]) 301 0000009E A0[B4080000] mov al, [argc] 302 000000A3 FEC8 dec al ; (if [argc] = 3 then al = 2) 303 000000A5 B102 mov cl, 2 304 000000A7 28C8 sub al, cl ; argv[0], argv[1] 305 000000A9 D3E0 shl eax, cl ; * 4 306 000000AB 89E5 mov ebp, esp 307 000000AD 01C5 add ebp, eax 308 ; ebp = argv[argc-1] 309 ;mov [target], ebp 310 311 ; 26/05/2022 312 000000AF 8B6D00 mov ebp, [ebp] 313 314 ; 24/05/2022 315 ;cmp byte [argc], 3 316 000000B2 802D[B4080000]02 sub byte [argc], 2 317 000000B9 803D[B4080000]01 cmp byte [argc], 1 318 000000C0 761E 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 000000C2 89EB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000000C4 B9[A60B0000] <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 000000C9 B812000000 <1> mov eax, %1 87 000000CE CD30 <1> int 30h 323 000000D0 7305 jnc short mv_5 324 mv_4: 325 000000D2 E94EFFFFFF jmp mv_usage 326 mv_5: 327 ; Retro UNIX 386 v1.2 328 ;mov [st2dev], eax 329 ;mov al, byte [st2buf+stat.mode+1] 330 ;and al, S_IFREG|S_IFDIR 331 ;cmp al, S_IFREG|S_IFDIR 332 ;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 000000D7 F605[A90B0000]40 test byte [st2buf+stat.mode+1], S_IFDIR 339 000000DE 74F2 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 000000E0 E82B000000 call move 348 000000E5 7306 jnc short mv_7 349 000000E7 FE05[B5080000] inc byte [errors] 350 mv_7: 351 000000ED FE0D[B4080000] dec byte [argc] ; i++ 352 000000F3 7403 jz short mv_8 353 ; i < argc-1 354 000000F5 5F pop edi ; argv[i] 355 000000F6 EBE8 jmp short mv_6 356 mv_8: 357 000000F8 803D[B5080000]00 cmp byte [errors], 0 358 000000FF 770A ja short mv_9 359 360 00000101 B8[710B0000] mov eax, msg_ok 361 ;jmp print_exit 362 00000106 E88D070000 call print_msg 363 mv_9: 364 0000010B E948FFFFFF 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 00000110 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000112 B9[820B0000] <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 00000117 B812000000 <1> mov eax, %1 87 0000011C CD30 <1> int 30h 385 0000011E 731D jnc short mv_10 386 387 00000120 B8[6A090000] mov eax, msg_cant_access 388 ; 24/05/2022 389 00000125 E86E070000 call print_msg 390 0000012A 89F8 mov eax, edi ; source 391 0000012C E867070000 call print_msg 392 00000131 B8[3A090000] mov eax, nextline 393 move_err: 394 00000136 E85D070000 call print_msg 395 0000013B F9 stc 396 0000013C C3 retn 397 mv_10: 398 ; Retro UNIX 386 v1.2 399 ;mov [st1dev], eax 400 ;mov al, byte [st1buf+stat.mode+1] 401 ;and al, S_IFREG|S_IFDIR 402 ;cmp al, S_IFREG|S_IFDIR 403 ;jne short mv_11 404 405 ; Retro UNIX 386 v1 (& v1.1) 406 0000013D 66A3[800B0000] mov [st1dev], ax ; device number 407 ; (0 = root fs) 408 ; (1 = mounted fs) 409 410 ; if ((s1.st_mode & S_IFMT) == S_IFDIR) 411 00000143 F605[850B0000]40 test byte [st1buf+stat.mode+1], S_IFDIR 412 0000014A 7407 jz short mv_11 413 414 0000014C B8[7F090000] mov eax, msg_rename_only 415 00000151 EBE3 jmp short move_err 416 mv_11: 417 ; 26/05/2022 418 00000153 892D[7C0B0000] 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 00000159 89EB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000015B B9[A60B0000] <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 00000160 B812000000 <1> mov eax, %1 87 00000165 CD30 <1> int 30h 422 ;jc short mv_19 423 ; 23/05/2022 424 00000167 7305 jnc short mv_12 425 00000169 E944010000 jmp mv_19 426 mv_12: 427 ; Retro UNIX 386 v1.2 428 ;mov [st2dev], eax 429 ;mov al, byte [st2buf+stat.mode+1] 430 ;and al, S_IFREG|S_IFDIR 431 ;cmp al, S_IFREG|S_IFDIR 432 ;jne short mv_14 433 434 ; Retro UNIX 386 v1 (& v1.1) 435 0000016E 66A3[A40B0000] mov [st2dev], ax ; device number 436 ; (0 = root fs) 437 ; (1 = mounted fs) 438 439 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) 440 00000174 F605[A90B0000]40 test byte [st2buf+stat.mode+1], S_IFDIR 441 0000017B 744A 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 0000017D E81C050000 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 00000182 BB[C80B0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000187 B9[A60B0000] <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 0000018C B812000000 <1> mov eax, %1 87 00000191 CD30 <1> int 30h 472 ;jc short mv_20 ; 26/05/2022 473 ; 26/05/2022 474 00000193 7305 jnc short mv_13 475 00000195 E918010000 jmp mv_20 476 mv_13: 477 ; Retro UNIX 386 v1.2 478 ;mov [st2dev], eax 479 ;mov al, byte [st2buf+stat.mode+1] 480 ;and al, S_IFREG|S_IFDIR 481 ;cmp al, S_IFREG|S_IFDIR 482 ;jne short mv_14 483 484 ; Retro UNIX 386 v1 (& v1.1) 485 0000019A 66A3[A40B0000] mov [st2dev], ax ; device number 486 ; (0 = root fs) 487 ; (1 = mounted fs) 488 489 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) 490 000001A0 F605[A90B0000]40 test byte [st2buf+stat.mode+1], S_IFDIR 491 000001A7 741E jz short mv_14 492 493 ;fprintf(stderr, "mv: %s is a directory\n", target); 494 000001A9 B8[3D090000] mov eax, mv_header 495 000001AE E8E5060000 call print_msg 496 000001B3 B8[C80B0000] mov eax, buf ; target 497 000001B8 E8DB060000 call print_msg 498 000001BD B8[57090000] mov eax, msg_is_a_dir 499 000001C2 E96FFFFFFF jmp move_err 500 501 mv_14: 502 ; if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) 503 000001C7 66A1[820B0000] mov ax, [st1buf+stat.inode] 504 000001CD 663B05[A60B0000] cmp ax, [st2buf+stat.inode] 505 000001D4 753E jne short mv_15 506 ; 26/05/2022 507 000001D6 66A1[800B0000] mov ax, [st1dev] 508 000001DC 663B05[A40B0000] cmp ax, [st2dev] 509 000001E3 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 000001E5 B8[3D090000] mov eax, mv_header 518 000001EA E8A9060000 call print_msg 519 000001EF 89F8 mov eax, edi ; source 520 000001F1 E8A2060000 call print_msg 521 000001F6 B8[EE0A0000] mov eax, msg_and 522 000001FB E898060000 call print_msg 523 00000200 A1[7C0B0000] mov eax, [target] ; target ; 26/05/2022 524 00000205 E88E060000 call print_msg 525 0000020A B8[F40A0000] mov eax, msg_identical 526 0000020F E922FFFFFF jmp move_err 527 528 mv_15: 529 ; if (access(target, 2) < 0 && isatty(fileno(stdin))) 530 00000214 BE[A60B0000] mov esi, st2buf 531 00000219 E8C8050000 call access 532 0000021E 7568 jnz short mv_18 533 ; not permitted 534 535 00000220 E8D9050000 call isatty 536 00000225 7261 jc short mv_18 ; not a tty 537 538 ;fprintf(stderr, "mv: %s: %o mode ", target, 539 ; s2.st_mode & MODEBITS); 540 541 00000227 B8[3D090000] mov eax, mv_header 542 0000022C E867060000 call print_msg 543 00000231 A1[7C0B0000] mov eax, [target] ; target ; 26/05/2022 544 00000236 E85D060000 call print_msg 545 0000023B 8B1D[A80B0000] mov ebx, [st2buf+stat.mode] 546 00000241 83E31F and ebx, MODEBITS 547 00000244 BE[6B0D0000] mov esi, octm 548 00000249 E8DA050000 call octalnumber 549 ; 27/05/2022 550 ;mov eax, octm 551 0000024E C605[6A0D0000]20 mov byte [octms], 20h 552 00000255 B8[6A0D0000] mov eax, octms 553 0000025A E839060000 call print_msg 554 0000025F B8[470B0000] mov eax, msg_mode 555 00000264 E82F060000 call print_msg 556 557 ; i = c = getchar(); 558 00000269 E8F3050000 call getchar 559 560 0000026E 3C79 cmp al, 'y' 561 00000270 740C je short mv_17 562 563 00000272 B8[5E0B0000] mov eax, msg_no 564 mv_16: 565 00000277 E81C060000 call print_msg 566 0000027C F9 stc 567 0000027D C3 retn 568 mv_17: 569 0000027E B8[560B0000] mov eax, msg_yes 570 00000283 E810060000 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 00000288 8B1D[7C0B0000] <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 0000028E B80A000000 <1> mov eax, %1 87 00000293 CD30 <1> int 30h 574 00000295 731B jnc short mv_20 575 576 ; fprintf(stderr, "mv: cannot unlink %s\n", target); 577 00000297 B8[9D090000] mov eax, msg_cant_unlink 578 0000029C E8F7050000 call print_msg 579 000002A1 A1[7C0B0000] mov eax, [target] ; 26/05/2022 580 000002A6 E8ED050000 call print_msg 581 000002AB B8[3A090000] mov eax, nextline 582 000002B0 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 000002B2 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000002B4 8B0D[7C0B0000] <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 000002BA B809000000 <1> mov eax, %1 87 000002BF CD30 <1> int 30h 590 000002C1 7374 jnc short mv_25 591 592 000002C3 BB[D8020000] 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 000002C8 B802000000 <1> mov eax, %1 87 000002CD CD30 <1> int 30h 594 000002CF 7332 jnc short mv_22 ; parent return and jump 595 596 000002D1 B8[B2090000] mov eax, msg_try_again 597 000002D6 EB9F jmp short mv_16 598 mv_21: 599 ; child process will continue from here 600 601 000002D8 A1[7C0B0000] mov eax, [target] 602 000002DD A3[C6080000] mov [cp_target], eax 603 000002E2 893D[C2080000] mov [cp_source], edi 604 605 sys _exec, cp_cmd, cp_args 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000002E8 BB[B6080000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000002ED B9[BE080000] <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 000002F2 B80B000000 <1> mov eax, %1 87 000002F7 CD30 <1> int 30h 606 607 ; fprintf(stderr, "mv: cannot exec cp\n"); 608 000002F9 B8[C4090000] mov eax, msg_cant_exec_cp 609 ;call print_msg 610 ;jmp _exit_ 611 ; 23/05/2022 612 000002FE E950FDFFFF jmp print_exit 613 614 mv_22: 615 00000303 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 00000305 B807000000 <1> mov eax, %1 87 0000030A CD30 <1> int 30h 623 0000030C 7228 jc short mv_24 624 625 0000030E 39D0 cmp eax, edx 626 00000310 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 00000312 8B1D[7C0B0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000318 B9[E40C0000] <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 0000031D B812000000 <1> mov eax, %1 87 00000322 CD30 <1> int 30h 630 00000324 7210 jc short mv_24 631 00000326 66A1[EA0C0000] mov ax, [fstbuf+stat.size] 632 0000032C 663B05[880B0000] cmp ax, [st1buf+stat.size] 633 00000333 7402 je short mv_25 634 00000335 F9 stc 635 mv_24: 636 00000336 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 00000337 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 00000339 B80A000000 <1> mov eax, %1 87 0000033E CD30 <1> int 30h 648 00000340 73F4 jnc short mv_24 649 650 00000342 B8[9D090000] mov eax, msg_cant_unlink 651 00000347 E84C050000 call print_msg 652 0000034C 89F8 mov eax, edi ; source 653 0000034E E845050000 call print_msg 654 00000353 B8[3A090000] mov eax, nextline 655 ;if (status != 0) 656 ; return(1); 657 00000358 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 0000035D 89EB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000035F B9[A60B0000] <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 00000364 B812000000 <1> mov eax, %1 87 00000369 CD30 <1> int 30h 680 0000036B 7241 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 ;mov al, byte [st2buf+stat.mode+1] 687 ;and al, S_IFREG|S_IFDIR 688 ;cmp al, S_IFREG|S_IFDIR 689 ;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 0000036D F605[A90B0000]40 test byte [st2buf+stat.mode+1], S_IFDIR 698 00000374 751D jnz short mv_28 699 700 ;fprintf(stderr, "mv: %s exists\n", target); 701 702 00000376 55 push ebp ; target 703 mv_27: 704 00000377 B8[3D090000] mov eax, mv_header 705 0000037C E817050000 call print_msg 706 00000381 58 pop eax ; target 707 00000382 E811050000 call print_msg 708 00000387 B8[DB090000] mov eax, msg_exists 709 0000038C E807050000 call print_msg 710 00000391 F9 stc 711 00000392 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 00000393 E806030000 call strcpy ; 27/05/2022 735 736 sys _stat, buf, st2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000398 BB[C80B0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000039D B9[A60B0000] <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 000003A2 B812000000 <1> mov eax, %1 87 000003A7 CD30 <1> int 30h 737 000003A9 7209 jc short mv_30 738 739 000003AB 53 push ebx ; buf ; [target] 740 000003AC EBC9 jmp short mv_27 741 742 mv_29: 743 000003AE 892D[7C0B0000] mov [target], ebp 744 mv_30: 745 ; if (strcmp(source, target) == 0) { 746 747 000003B4 57 push edi 748 000003B5 89FE mov esi, edi 749 000003B7 8B3D[7C0B0000] mov edi, [target] 750 000003BD E80D030000 call strcmp 751 000003C2 5F pop edi 752 000003C3 750C jne short mv_32 753 754 000003C5 B8[E6090000] mov eax, msg_src_target 755 mv_31: 756 000003CA E8C9040000 call print_msg 757 000003CF F9 stc 758 000003D0 C3 retn 759 760 mv_32: 761 000003D1 89FA mov edx, edi 762 000003D3 BF[E40C0000] mov edi, fstbuf ; (66 bytes buffer) 763 ;mov ebx, edi 764 000003D8 52 push edx ; * 765 000003D9 E8FC020000 call dname 766 ; edx = fstbuf = file name 767 768 ;!strcmp(p, "") 769 000003DE 803A00 cmp byte [edx], 0 770 000003E1 7421 je short mv_33 ; null 771 ;!strcmp(p, DOT) 772 000003E3 89D6 mov esi, edx 773 000003E5 803E2E cmp byte [esi], '.' 774 000003E8 752C jne short mv_34 775 000003EA BF[CF080000] mov edi, DOT 776 000003EF E8DB020000 call strcmp 777 000003F4 740E je short mv_33 ; '.' 778 ;!strcmp(p, DOTDOT) 779 000003F6 89D6 mov esi, edx 780 000003F8 BF[CE080000] mov edi, DOTDOT 781 000003FD E8CD020000 call strcmp 782 00000402 7512 jne short mv_34 783 ; '..' 784 mv_33: 785 00000404 5F pop edi ; * 786 787 ;fprintf(stderr, "mv: cannot rename %s\n", p); 788 00000405 B8[C10A0000] mov eax, msg_cant_rename 789 0000040A E889040000 call print_msg 790 0000040F B8[E40C0000] mov eax, fstbuf 791 00000414 EBB4 jmp short mv_31 792 793 mv_34: 794 00000416 5F pop edi ; * 795 00000417 BB[2C0C0000] mov ebx, sbuf 796 ; edi = source 797 ; ebx = buffer 798 0000041C E8D6020000 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 00000421 89F3 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000423 B9[260D0000] <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 00000428 B812000000 <1> mov eax, %1 87 0000042D CD30 <1> int 30h 803 0000042F 7307 jnc short mv_36 804 mv_35: 805 00000431 B8[230A0000] mov eax, msg_cant_locate 806 00000436 EB92 jmp short mv_31 807 mv_36: 808 00000438 66A3[800B0000] mov [st1dev], ax 809 0000043E 8B15[7C0B0000] mov edx, [target] 810 00000444 87D7 xchg edx, edi 811 ;stat(pname(target), &s2) < 0) 812 ; edi = source 813 00000446 BB[880C0000] mov ebx, tbuf ; buffer 814 0000044B E8A7020000 call pname 815 ; esi = parent directory name address 816 00000450 89D7 mov edi, edx 817 sys _stat, esi, pst2buf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000452 89F3 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000454 B9[480D0000] <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 00000459 B812000000 <1> mov eax, %1 87 0000045E CD30 <1> int 30h 818 00000460 72CF jc short mv_35 819 00000462 66A3[A40B0000] mov [st2dev], ax 820 ;if (access(pname(target), 2) < 0) 821 00000468 BE[480D0000] mov esi, pst2buf 822 0000046D E874030000 call access 823 00000472 7522 jnz short mv_39 824 ; permission denied ! 825 00000474 BA[880C0000] mov edx, tbuf ; pname(target) 826 mv_37: 827 00000479 52 push edx ; pname(target) or pname(source) 828 0000047A B8[400A0000] mov eax, msg_no_w_access 829 0000047F E814040000 call print_msg 830 00000484 58 pop eax ; pname(target) or pname(source) 831 00000485 E80E040000 call print_msg 832 0000048A B8[3A090000] mov eax, nextline 833 mv_38: 834 0000048F E804040000 call print_msg 835 00000494 F9 stc 836 00000495 C3 retn 837 mv_39: 838 ;if (access(pname(source), 2) < 0) 839 00000496 BE[260D0000] mov esi, pst1buf 840 0000049B E846030000 call access 841 000004A0 7507 jnz short mv_40 842 ; permission denied ! 843 000004A2 BA[2C0C0000] mov edx, sbuf ; pname(source) 844 000004A7 EBD0 jmp short mv_37 845 mv_40: 846 ;if (access(source, 2) < 0) 847 ; edi = source 848 000004A9 BE[820B0000] mov esi, st1buf 849 ; source (inode) stat(us) buffer 850 000004AE E833030000 call access 851 000004B3 7504 jnz short mv_41 852 000004B5 89FA mov edx, edi ; source 853 000004B7 EBC0 jmp short mv_37 854 mv_41: 855 ;if (s1.st_dev != s2.st_dev) 856 000004B9 66A1[800B0000] mov ax, [st1dev] 857 000004BF 663B05[A40B0000] cmp ax, [st2dev] 858 000004C6 7407 je short mv_42 859 ;fprintf(stderr, "mv: cannot move directories 860 ; across devices\n"); 861 000004C8 B8[5A0A0000] mov eax, msg_accross_devices 862 000004CD EBC0 jmp short mv_38 863 mv_42: 864 ;if (s1.st_ino != s2.st_ino) 865 000004CF 66A1[260D0000] mov ax, [pst1buf+stat.inode] 866 000004D5 663B05[480D0000] cmp ax, [pst2buf+stat.inode] 867 000004DC 7505 jne short mv_43 868 000004DE E960010000 jmp mv_57 869 mv_43: 870 ; (move dir from parent dir to another dir) 871 872 ;if (chkdot(source) || chkdot(target)) 873 000004E3 89FB mov ebx, edi ; source 874 000004E5 E8BD020000 call chkdot 875 000004EA 7307 jnc short mv_45 876 mv_44: 877 ;fprintf(stderr, "mv: Sorry, path names 878 ; including %s aren't allowed\n", DOTDOT); 879 000004EC B8[890A0000] mov eax, msg_pathname_dotdot 880 000004F1 EB9C jmp short mv_38 881 mv_45: 882 000004F3 8B1D[7C0B0000] mov ebx, [target] ; target 883 000004F9 E8A9020000 call chkdot 884 000004FE 72EC jc short mv_44 885 mv_46: 886 ;stat(source, &s1); 887 ;if (check(pname(target), s1.st_ino)) 888 00000500 BB[880C0000] mov ebx, tbuf 889 00000505 E820020000 call check 890 0000050A 7241 jc short mv_49 ; return(1); 891 mv_47: 892 ;for (i = 1; i <= NSIG; i++) 893 ; signal(i, SIG_IGN); 894 ; if (link(source, target) < 0) { 895 896 sys _link, edi, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000050C 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 0000050E 8B0D[7C0B0000] <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 00000514 B809000000 <1> mov eax, %1 87 00000519 CD30 <1> int 30h 897 0000051B 7331 jnc short mv_50 898 899 ; fprintf(stderr, "mv: cannot link %s to %s\n", 900 ; target, source); 901 mv_48: 902 0000051D B8[D60A0000] mov eax, msg_cant_link 903 00000522 E871030000 call print_msg 904 00000527 A1[7C0B0000] mov eax, [target] ; target 905 0000052C E867030000 call print_msg 906 00000531 B8[E90A0000] mov eax, msg_to 907 00000536 E85D030000 call print_msg 908 0000053B 89F8 mov eax, edi ; source 909 0000053D E856030000 call print_msg 910 00000542 B8[3A090000] mov eax, nextline 911 00000547 E84C030000 call print_msg 912 0000054C F9 stc 913 mv_49: 914 0000054D C3 retn 915 mv_50: 916 ;if (unlink(source) < 0) { 917 sys _unlink, edi 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000054E 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 00000550 B80A000000 <1> mov eax, %1 87 00000555 CD30 <1> int 30h 918 00000557 732A jnc short mv_51 919 920 ;fprintf(stderr, "mv: %s: cannot unlink\n", source); 921 00000559 B8[9D090000] mov eax, msg_cant_unlink 922 0000055E E835030000 call print_msg 923 00000563 89F8 mov eax, edi ; source 924 00000565 E82E030000 call print_msg 925 0000056A B8[3A090000] mov eax, nextline 926 0000056F E824030000 call print_msg 927 ;unlink(target); 928 sys _unlink, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000574 8B1D[7C0B0000] <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 0000057A B80A000000 <1> mov eax, %1 87 0000057F CD30 <1> int 30h 929 ;return(1); 930 00000581 F9 stc 931 00000582 C3 retn 932 mv_51: 933 ;strcat(dst, target); 934 ;strcat(dst, "/"); 935 ;strcat(dst, DOTDOT); 936 937 00000583 8B35[7C0B0000] mov esi, [target] 938 00000589 57 push edi ; * 939 0000058A BF[700D0000] mov edi, nspth 940 mv_52: 941 0000058F AC lodsb 942 00000590 AA stosb 943 00000591 20C0 and al, al 944 00000593 75FA jnz short mv_52 945 00000595 4F dec edi 946 00000596 B82F2E2E00 mov eax, 002E2E2Fh ; db '/..', 0 947 0000059B AB stosd 948 0000059C 5F pop edi ; * 949 950 ;if (unlink(dst) < 0) 951 sys _unlink, nspth 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000059D BB[700D0000] <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 000005A2 B80A000000 <1> mov eax, %1 87 000005A7 CD30 <1> int 30h 952 000005A9 733E jnc short mv_56 953 954 ; fprintf(stderr, "mv: %s: cannot unlink\n", dst); 955 000005AB B8[9D090000] mov eax, msg_cant_unlink 956 000005B0 E8E3020000 call print_msg 957 000005B5 B8[700D0000] mov eax, nspth ; dst 958 000005BA E8D9020000 call print_msg 959 000005BF B8[3A090000] mov eax, nextline 960 000005C4 E8CF020000 call print_msg 961 mv_53: 962 ;if (link(target, source) >= 0) 963 ; unlink(target); 964 sys _link, edi, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000005C9 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000005CB 8B0D[7C0B0000] <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 000005D1 B809000000 <1> mov eax, %1 87 000005D6 CD30 <1> int 30h 965 000005D8 720E jc short mv_55 966 mv_54: 967 ;unlink(target); 968 sys _unlink, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000005DA 8B1D[7C0B0000] <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 000005E0 B80A000000 <1> mov eax, %1 87 000005E5 CD30 <1> int 30h 969 ;return(1); 970 000005E7 F9 stc 971 mv_55: 972 000005E8 C3 retn 973 mv_56: 974 ;if (link(pname(target), dst) < 0) 975 sys _link, tbuf, nspth 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000005E9 BB[880C0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000005EE B9[700D0000] <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 000005F3 B809000000 <1> mov eax, %1 87 000005F8 CD30 <1> int 30h 976 000005FA 73EC jnc short mv_55 ;return(0) 977 978 ;fprintf(stderr, "mv: cannot link %s to %s\n", 979 ; dst, pname(target)); 980 000005FC B8[D60A0000] mov eax, msg_cant_link 981 00000601 E892020000 call print_msg 982 00000606 B8[700D0000] mov eax, nspth ; dst 983 0000060B E888020000 call print_msg 984 00000610 B8[E90A0000] mov eax, msg_to 985 00000615 E87E020000 call print_msg 986 0000061A B8[880C0000] mov eax, tbuf ; pname(taget) 987 0000061F E874020000 call print_msg 988 00000624 B8[3A090000] mov eax, nextline 989 00000629 E86A020000 call print_msg 990 ;if (link(pname(source), dst) >= 0) 991 sys _link, sbuf, nspth 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000062E BB[2C0C0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000633 B9[700D0000] <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 00000638 B809000000 <1> mov eax, %1 87 0000063D CD30 <1> int 30h 992 0000063F 72A7 jc short mv_55 993 ;if (link(target, source) >= 0) 994 ; unlink(target); 995 00000641 EB86 jmp short mv_53 996 997 mv_57: 998 ; (move dir in same parent directory) 999 1000 ;if (link(source, target) < 0) 1001 sys _link, edi, [target] 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000643 89FB <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000645 8B0D[7C0B0000] <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 0000064B B809000000 <1> mov eax, %1 87 00000650 CD30 <1> int 30h 1002 00000652 7331 jnc short mv_60 1003 ;fprintf(stderr, "mv: cannot link %s and %s\n", 1004 ; source, target); 1005 00000654 B8[D60A0000] mov eax, msg_cant_link 1006 00000659 E83A020000 call print_msg 1007 0000065E 89F8 mov eax, edi ; source 1008 00000660 E833020000 call print_msg 1009 00000665 B8[EE0A0000] mov eax, msg_and 1010 0000066A E829020000 call print_msg 1011 0000066F A1[7C0B0000] mov eax, [target] ; target 1012 mv_58: 1013 00000674 E81F020000 call print_msg 1014 00000679 B8[3A090000] mov eax, nextline 1015 0000067E E815020000 call print_msg 1016 ;return(1); 1017 00000683 F9 stc 1018 mv_59: 1019 00000684 C3 retn 1020 mv_60: 1021 ;if (unlink(source) < 0) { 1022 sys _unlink, edi 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000685 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 00000687 B80A000000 <1> mov eax, %1 87 0000068C CD30 <1> int 30h 1023 0000068E 73F4 jnc short mv_59 ;return(0) 1024 1025 ;fprintf(stderr, "mv: ?? cannot unlink 1026 ; %s\n", source); 1027 1028 00000690 B8[9D090000] mov eax, msg_cant_unlink 1029 00000695 E8FE010000 call print_msg 1030 0000069A 89F8 mov eax, edi ; source 1031 0000069C EBD6 jmp short mv_58 1032 1033 ;----------------------------------------------------------------- 1034 1035 strcpy: 1036 0000069E 89EE mov esi, ebp ; target 1037 000006A0 89FB mov ebx, edi ; source 1038 000006A2 89DA mov edx, ebx 1039 000006A4 BF[C80B0000] mov edi, buf ; pathname buffer (100 bytes) 1040 000006A9 893D[7C0B0000] mov [target], edi 1041 strcp_1: 1042 000006AF AC lodsb 1043 000006B0 08C0 or al, al 1044 000006B2 7403 jz short strcp_2 1045 000006B4 AA stosb 1046 000006B5 EBF8 jmp short strcp_1 1047 strcp_2: 1048 ; 27/05/2022 1049 000006B7 B02F mov al, DELIM ; '/' 1050 000006B9 81FF[C80B0000] cmp edi, buf 1051 000006BF 7605 jna short strcp_3 1052 ;cmp byte [edi-1], DELIM ; '/' 1053 000006C1 3847FF cmp byte [edi-1], al ; '/' 1054 000006C4 7401 je short strcp_4 1055 strcp_3: 1056 ;mov al, DELIM ; '/' 1057 000006C6 AA stosb 1058 strcp_4: 1059 ; edx = source (pathname) 1060 ; edi = buffer (offset) position 1061 000006C7 E80E000000 call dname 1062 000006CC 89DF mov edi, ebx ; source 1063 ; target = buf; 1064 000006CE C3 retn 1065 1066 ;----------------------------------------------------------------- 1067 1068 strcmp: 1069 ; esi = source 1070 ; edi = target 1071 strcmp_1: 1072 000006CF AC lodsb 1073 000006D0 08C0 or al, al 1074 000006D2 7404 jz short strcmp_2 1075 000006D4 AE scasb 1076 000006D5 74F8 je short strcmp_1 1077 000006D7 C3 retn 1078 strcmp_2: 1079 ;cmp [edi], al ; 0 1080 000006D8 AE scasb 1081 strcmp_3: 1082 ; zf = 1 -> same 1083 000006D9 C3 retn 1084 1085 ;----------------------------------------------------------------- 1086 1087 dname: ; dname(name) 1088 ; edx = source (pathname) 1089 ; edi = buffer (offset) position 1090 dname_0: 1091 000006DA 89D6 mov esi, edx ; name 1092 ;p = name; 1093 ;while (*p) 1094 dname_1: 1095 000006DC AC lodsb 1096 000006DD 20C0 and al, al 1097 000006DF 740D jz short dname_2 1098 000006E1 3C2F cmp al, DELIM ; cmp al, '/' 1099 000006E3 75F7 jne short dname_1 1100 ;if (*p++ == DELIM && *p) 1101 000006E5 803E00 cmp byte [esi], 0 1102 ;je short dname_1 1103 000006E8 7404 je short dname_2 1104 000006EA 89F2 mov edx, esi 1105 000006EC EBEE jmp short dname_1 1106 dname_2: 1107 ; edx = file name 1108 000006EE 89D6 mov esi, edx 1109 dname_3: 1110 000006F0 AC lodsb 1111 000006F1 AA stosb 1112 000006F2 08C0 or al, al 1113 000006F4 75FA jnz short dname_3 1114 000006F6 C3 retn 1115 1116 ;----------------------------------------------------------------- 1117 1118 pname: ; pname(name) 1119 ; 23/05/2022 1120 1121 ; INPUT: 1122 ; edi = source (pathname) 1123 ; ebx = buffer address 1124 ; OUTPUT: 1125 ; esi = parent dir name address 1126 pname_0: 1127 000006F7 89FE mov esi, edi ; source 1128 000006F9 57 push edi ; * 1129 ;p = q = buf; 1130 000006FA 89DF mov edi, ebx 1131 000006FC 89D9 mov ecx, ebx 1132 ; while (c = *p++ = *name++) 1133 pname_1: 1134 000006FE AC lodsb 1135 000006FF AA stosb 1136 00000700 20C0 and al, al 1137 00000702 7409 jz short pname_2 1138 ;if (c == DELIM) 1139 ; q = p-1; 1140 00000704 3C2F cmp al, DELIM ; cmp al, '/' 1141 00000706 75F6 jne short pname_1 1142 00000708 89FB mov ebx, edi 1143 0000070A 4B dec ebx 1144 0000070B EBF1 jmp short pname_1 1145 pname_2: 1146 ;if (q == buf && *q == DELIM) 1147 ; q++; 1148 0000070D 39CB cmp ebx, ecx 1149 0000070F 7506 jne short pname_3 1150 00000711 803B2F cmp byte [ebx], DELIM ; '/' 1151 00000714 7501 jne short pname_3 1152 00000716 43 inc ebx 1153 pname_3: 1154 ;*q = 0; 1155 00000717 C60300 mov byte [ebx], 0 1156 0000071A 89CE mov esi, ecx 1157 0000071C 5F pop edi ; * 1158 ; return buf[0]? buf : DOT; 1159 0000071D 803E00 cmp byte [esi], 0 1160 00000720 7707 ja short pname_4 1161 00000722 A1[CF080000] mov eax, [DOT] ; db '.', 0 1162 00000727 8906 mov [esi], eax 1163 pname_4: 1164 00000729 C3 retn 1165 1166 ;----------------------------------------------------------------- 1167 1168 check: ; check(spth, dinode) 1169 ; 23/05/2022 1170 1171 ; INPUT: 1172 ; ebx = name buffer address 1173 ; [st1buf+stat.inode] = inode num to be compared 1174 ; OUTPUT: 1175 ; cf = 1 -> error 1176 ; cf = 0 -> no problem 1177 1178 ;strcpy(nspth, spth); 1179 1180 0000072A 89DE mov esi, ebx 1181 0000072C 57 push edi ; * 1182 0000072D BF[700D0000] mov edi, nspth 1183 check_1: 1184 00000732 AC lodsb 1185 00000733 AA stosb 1186 00000734 20C0 and al, al 1187 00000736 75FA jnz short check_1 1188 00000738 29DE sub esi, ebx 1189 0000073A 4E dec esi ; esi = strlen(nspth) 1190 0000073B 5F pop edi ; * 1191 check_2: 1192 ;if (stat(nspth, &sbuf) < 0) 1193 sys _stat, nspth, fstbuf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 0000073C BB[700D0000] <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000741 B9[E40C0000] <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 00000746 B812000000 <1> mov eax, %1 87 0000074B CD30 <1> int 30h 1194 0000074D 7320 jnc short check_5 1195 ;fprintf(stderr, "mv: cannot access %s\n", nspth); 1196 0000074F B8[6A090000] mov eax, msg_cant_access 1197 00000754 E83F010000 call print_msg 1198 00000759 B8[700D0000] mov eax, nspth 1199 0000075E E835010000 call print_msg 1200 00000763 B8[3A090000] mov eax, nextline 1201 check_3: 1202 00000768 E82B010000 call print_msg 1203 0000076D F9 stc 1204 check_4: 1205 0000076E C3 retn 1206 check_5: 1207 ;if (sbuf.st_ino == dinode) 1208 0000076F 66A1[E40C0000] mov ax, [fstbuf+stat.inode] 1209 00000775 663B05[820B0000] cmp ax, [st1buf+stat.inode] 1210 0000077C 7507 jne short check_6 1211 ; fprintf(stderr, "mv: cannot move a directory 1212 ; into itself\n"); 1213 0000077E B8[050B0000] mov eax, msg_cant_mv_itself 1214 00000783 EBE3 jmp short check_3 1215 check_6: 1216 ;while (sbuf.st_ino != ROOTINO) 1217 00000785 6683F829 cmp ax, ROOTINO 1218 00000789 74E3 je short check_4 1219 1220 ;if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) 1221 0000078B 83FE6C cmp esi, MAXN-4 1222 0000078E 7607 jna short check_7 1223 1224 ;fprintf(stderr, "mv: name too long\n"); 1225 00000790 B8[310B0000] mov eax, msg_too_long 1226 00000795 EBD1 jmp short check_3 1227 check_7: 1228 ;strcat(nspth, SDELIM); 1229 ;strcat(nspth, DOTDOT); 1230 00000797 B82F2E2E00 mov eax, 002E2E2Fh ; db '/..', 0 1231 0000079C 8986[700D0000] mov [esi+nspth], eax 1232 000007A2 83C603 add esi, 3 1233 000007A5 EB95 jmp short check_2 1234 1235 ;----------------------------------------------------------------- 1236 1237 chkdot: ; chkdot(s) 1238 ; 23/05/2022 1239 1240 ;do { 1241 ; if (strcmp(dname(s), DOTDOT) == 0) 1242 ; return(1); 1243 ; s = pname(s); 1244 ;} while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0); 1245 ;return(0); 1246 1247 ; INPUT: 1248 ; ebx = name buffer address 1249 ; OUTPUT: 1250 ; cf = 1 -> DOTDOT (return 0) 1251 ; cf = 0 -> not DOTDOT (return 1) 1252 1253 ; get last '/' 1254 000007A7 89DE mov esi, ebx 1255 chkdot_0: 1256 000007A9 89D9 mov ecx, ebx 1257 chkdot_1: 1258 000007AB AC lodsb 1259 000007AC 20C0 and al, al 1260 000007AE 740E jz short chkdot_2 1261 000007B0 3C2F cmp al, DELIM ; '/' 1262 000007B2 75F7 jne short chkdot_1 1263 000007B4 803E00 cmp byte [esi], 0 1264 000007B7 7605 jna short chkdot_2 1265 000007B9 89F1 mov ecx, esi 1266 000007BB 49 dec ecx 1267 000007BC EBED jmp short chkdot_1 1268 chkdot_2: 1269 000007BE 57 push edi ; * 1270 000007BF 89CE mov esi, ecx 1271 000007C1 BF[CE080000] mov edi, DOTDOT 1272 000007C6 E804FFFFFF call strcmp 1273 000007CB 7417 jz short chkdot_4 ; DOTDOT 1274 000007CD 89DF mov edi, ebx 1275 000007CF BB[E40C0000] mov ebx, fstbuf 1276 000007D4 E81EFFFFFF call pname 1277 000007D9 5F pop edi ; * 1278 000007DA 89F3 mov ebx, esi ; parent dir's pathname buf 1279 000007DC 668B06 mov ax, [esi] 1280 000007DF 08E4 or ah, ah ; 0 ? 1281 000007E1 75C6 jnz short chkdot_0 1282 ; (single character parent directory name) 1283 ; (it's name may be '.' or '/' or another char) 1284 ; pathname does not contain a DOTDOT 1285 000007E3 C3 retn 1286 chkdot_4: 1287 ; pathname contains DOTDOT 1288 000007E4 F9 stc 1289 000007E5 C3 retn 1290 1291 ;----------------------------------------------------------------- 1292 1293 access: 1294 ; 22/05/2022 1295 ; Retro UNIX 386 v1 & v1.1 & v1.2 1296 1297 ; INPUT: 1298 ; esi = stat(us) buffer 1299 ; OUTPUT: 1300 ; zf = 1 -> no write permission 1301 ; zf = 0 -> permitted to write 1302 1303 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 000007E6 B818000000 <1> mov eax, %1 87 000007EB CD30 <1> int 30h 1304 ;mov [uid], ax 1305 1306 ; Retro UNIX 386 v1.2 (v2 fs) 1307 ;mov dl, 80h ; write permission flag, owner 1308 1309 ; Retro UNIX 386 v1 1310 000007ED B204 mov dl, 4 ; write permission flag, owner 1311 1312 ;or ax, ax 1313 000007EF 08C0 or al, al 1314 000007F1 7407 jz short access_1 ; root 1315 1316 ;cmp ax, [esi+stat.uid] 1317 000007F3 3A4605 cmp al, [esi+stat.uid] 1318 000007F6 7402 je short access_1 1319 1320 ; Retro UNIX 386 v1.2 (v2 fs inode) 1321 ;sys _getgid 1322 ;;mov [gid], al 1323 1324 ;mov dl, 10h 1325 ;cmp al, [esi+stat.gid] 1326 ;je short access_1 1327 ; 1328 ;mov dl, 02h 1329 1330 ; Retro UNIX 386 v1 1331 000007F8 B201 mov dl, 1 1332 access_1: 1333 000007FA 845602 test dl, [esi+stat.mode] 1334 000007FD C3 retn 1335 1336 ;----------------------------------------------------------------- 1337 1338 isatty: 1339 ; 22/05/2022 1340 ; Retro UNIX 386 v1 & v1.1 & v1.2 1341 1342 ; Input: stdin (= 0) 1343 ; output: 1344 ; cf = 1 -> not a tty 1345 1346 sys _fstat, STDIN, fstbuf 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000007FE BB00000000 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000803 B9[E40C0000] <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 00000808 B81C000000 <1> mov eax, %1 87 0000080D CD30 <1> int 30h 1347 1348 0000080F 66A1[E40C0000] mov ax, [fstbuf+stat.inode] 1349 1350 ; Retro UNIX 386 v1.2 1351 ;cmp ax, 8 ; /dev/tty 1352 ;je short isatty_2 1353 ;cmp ax, 26 ; /dev/tty8 1354 ;ja short isatty_1 1355 ;cmp ax, 17 ; /dev/tty0 1356 ;retn 1357 1358 ; Retro UNIX 386 v1 (& v1.1) 1359 00000815 6683F801 cmp ax, 1 ; /dev/tty 1360 00000819 740C je short isatty_2 1361 0000081B 6683F813 cmp ax, 19 ; /dev/tty8 1362 0000081F 7705 ja short isatty_1 1363 00000821 6683F80A cmp ax, 10 ; /dev/tty0 1364 00000825 C3 retn 1365 isatty_1: 1366 00000826 F9 stc 1367 isatty_2: 1368 00000827 C3 retn 1369 1370 ;----------------------------------------------------------------- 1371 1372 octalnumber: 1373 ; 27/05/2022 1374 1375 ; Input: 1376 ; ebx = binary number (max. 9 bit) 1377 ; esi = string buffer (4 byte) 1378 1379 00000828 89D8 mov eax, ebx 1380 0000082A B103 mov cl, 3 1381 0000082C D3EB shr ebx, cl ; 3 1382 0000082E 2407 and al, 7 1383 00000830 50 push eax 1384 00000831 89D8 mov eax, ebx 1385 00000833 D3EB shr ebx, cl ; 3 1386 00000835 2407 and al, 7 1387 00000837 50 push eax 1388 00000838 89D8 mov eax, ebx 1389 0000083A 2407 and al, 7 1390 octn_0: 1391 ; 27/05/2022 1392 ;mov byte [esi], 20h 1393 ;inc esi 1394 0000083C 89F3 mov ebx, esi 1395 ;or al, al 1396 ;jz short octn_1 1397 0000083E E810000000 call octn_3 1398 octn_1: 1399 00000843 58 pop eax 1400 ; 27/05/2022 1401 00000844 E80A000000 call octn_3 1402 octn_2: 1403 00000849 58 pop eax 1404 ;call octn_3 1405 0000084A E80C000000 call octn_4 ; 27/05/2022 1406 0000084F 30C0 xor al, al 1407 00000851 EB0A jmp short octn_5 1408 1409 octn_3: 1410 ; 27/05/2022 1411 00000853 20C0 and al, al 1412 00000855 7504 jnz short octn_4 1413 00000857 39DE cmp esi, ebx 1414 00000859 7405 je short octn_6 1415 octn_4: 1416 0000085B 0430 add al, '0' 1417 octn_5: 1418 0000085D 8806 mov [esi], al 1419 0000085F 46 inc esi 1420 octn_6: 1421 00000860 C3 retn 1422 1423 ;----------------------------------------------------------------- 1424 1425 getchar: 1426 ; i = c = getchar(); 1427 ; while (c != '\n' && c != EOF) 1428 ; c = getchar(); 1429 getc_0: 1430 sys _read, STDIN, char, 1 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 00000861 BB00000000 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 00000866 B9[6F0D0000] <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 0000086B BA01000000 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 00000870 B803000000 <1> mov eax, %1 87 00000875 CD30 <1> int 30h 1431 00000877 A0[6F0D0000] mov al, [char] 1432 0000087C 3C79 cmp al, 'y' 1433 0000087E 7417 je short getc_2 1434 00000880 3C6E cmp al, 'n' 1435 00000882 7413 je short getc_2 1436 00000884 3C1B cmp al, ESCKey 1437 00000886 740F je short getc_2 1438 00000888 3C0D cmp al, EnterKey 1439 0000088A 740B je short getc_2 1440 0000088C 3C59 cmp al, 'Y' 1441 0000088E 7503 jne short getc_1 1442 00000890 B079 mov al, 'y' 1443 00000892 C3 retn 1444 getc_1: 1445 00000893 3C4E cmp al, 'N' 1446 00000895 75CA jne short getc_0 1447 getc_2: 1448 00000897 C3 retn 1449 1450 ;----------------------------------------------------------------- 1451 1452 print_msg: 1453 ; eax = asciiz string address 1454 00000898 89C6 mov esi, eax 1455 0000089A 4E dec esi 1456 nextchr: 1457 0000089B 46 inc esi 1458 0000089C 803E00 cmp byte [esi], 0 1459 0000089F 77FA ja short nextchr 1460 ;cmp [esi], 0Dh 1461 ;ja short nextchr 1462 000008A1 29C6 sub esi, eax 1463 ; esi = asciiz string length 1464 ; 1465 sys _write, 1, eax, esi 73 <1> 74 <1> 75 <1> 76 <1> %if %0 >= 2 77 000008A3 BB01000000 <1> mov ebx, %2 78 <1> %if %0 >= 3 79 000008A8 89C1 <1> mov ecx, %3 80 <1> 81 <1> %if %0 >= 4 82 000008AA 89F2 <1> mov edx, %4 83 <1> %endif 84 <1> %endif 85 <1> %endif 86 000008AC B804000000 <1> mov eax, %1 87 000008B1 CD30 <1> int 30h 1466 ; 1467 000008B3 C3 retn 1468 1469 ;----------------------------------------------------------------- 1470 ; data - initialized data 1471 ;----------------------------------------------------------------- 1472 1473 ;argc: dd 0 1474 000008B4 00 argc: db 0 1475 000008B5 00 errors: db 0 1476 1477 cp_cmd: 1478 000008B6 2F62696E2F637000 db '/bin/cp', 0 1479 1480 cp_args: 1481 000008BE [B6080000] dd cp_cmd 1482 cp_source: 1483 000008C2 00000000 dd 0 1484 cp_target: 1485 000008C6 00000000 dd 0 1486 000008CA 00000000 dd 0 1487 1488 000008CE 2E DOTDOT: db '.' 1489 000008CF 2E00 DOT: db '.', 0 1490 ;db 0, 0 1491 1492 ; ---------------------------------------------------------------- 1493 1494 program_msg: 1495 000008D1 0D0A db 0Dh, 0Ah 1496 000008D3 526574726F20554E49- db 'Retro UNIX 386 v1 MOVE by Erdogan TAN - 27/05/2022' 1496 000008DC 582033383620763120- 1496 000008E5 4D4F56452062792045- 1496 000008EE 72646F67616E205441- 1496 000008F7 4E202D2032372F3035- 1496 00000900 2F32303232 1497 00000905 0D0A00 db 0Dh, 0Ah, 0 1498 1499 usage_msg: 1500 00000908 0D0A db 0Dh, 0Ah 1501 0000090A 75736167653A206D76- db 'usage: mv f1 f2; or mv d1 d2; or mv f1 ... fn d1' 1501 00000913 2066312066323B206F- 1501 0000091C 72206D762064312064- 1501 00000925 323B206F72206D7620- 1501 0000092E 6631202E2E2E20666E- 1501 00000937 206431 1502 nextline: 1503 0000093A 0D0A00 db 0Dh, 0Ah, 0 1504 1505 mv_header: 1506 0000093D 0D0A db 0Dh, 0Ah 1507 0000093F 6D763A20 db 'mv: ' 1508 00000943 00 db 0 1509 msg_not_exists: 1510 ;db 0Dh, 0Ah 1511 00000944 20646F6573206E6F74- db ' does not exist ' 1511 0000094D 20657869737420 1512 00000954 0D0A00 db 0Dh, 0Ah, 0 1513 1514 msg_is_a_dir: 1515 00000957 206973206120646972- db ' is a directory ' 1515 00000960 6563746F727920 1516 00000967 0D0A00 db 0Dh, 0Ah, 0 1517 1518 msg_cant_access: 1519 0000096A 0D0A db 0Dh, 0Ah 1520 0000096C 6D763A2063616E6E6F- db 'mv: cannot access ' 1520 00000975 742061636365737320 1521 0000097E 00 db 0 1522 1523 msg_rename_only: 1524 0000097F 0D0A db 0Dh, 0Ah 1525 00000981 6D763A206469726563- db 'mv: directory rename only' 1525 0000098A 746F72792072656E61- 1525 00000993 6D65206F6E6C79 1526 0000099A 0D0A00 db 0Dh, 0Ah, 0 1527 1528 msg_cant_unlink: 1529 0000099D 0D0A db 0Dh, 0Ah 1530 0000099F 6D763A2063616E6E6F- db 'mv: cannot unlink ' 1530 000009A8 7420756E6C696E6B20 1531 000009B1 00 db 0 1532 1533 msg_try_again: 1534 000009B2 0D0A db 0Dh, 0Ah 1535 000009B4 6D763A207472792061- db 'mv: try again' 1535 000009BD 6761696E 1536 000009C1 0D0A00 db 0Dh, 0Ah, 0 1537 1538 msg_cant_exec_cp: 1539 000009C4 0D0A db 0Dh, 0Ah 1540 000009C6 6D763A2063616E6E6F- db 'mv: cannot exec cp' 1540 000009CF 742065786563206370 1541 000009D8 0D0A00 db 0Dh, 0Ah, 0 1542 1543 msg_exists: 1544 000009DB 2065786973747320 db ' exists ' 1545 000009E3 0D0A00 db 0Dh, 0Ah, 0 1546 1547 ;msg_long_target: 1548 ; db 0Dh, 0Ah 1549 ; db 'mv: target name too long' 1550 ; db 0Dh, 0Ah, 0 1551 1552 msg_src_target: 1553 000009E6 0D0A db 0Dh, 0Ah 1554 000009E8 6D763A203F3F20736F- db 'mv: ?? source == target, source exists and target doesnt' 1554 000009F1 75726365203D3D2074- 1554 000009FA 61726765742C20736F- 1554 00000A03 757263652065786973- 1554 00000A0C 747320616E64207461- 1554 00000A15 7267657420646F6573- 1554 00000A1E 6E74 1555 00000A20 0D0A00 db 0Dh, 0Ah, 0 1556 1557 msg_cant_locate: 1558 00000A23 0D0A db 0Dh, 0Ah 1559 00000A25 6D763A2063616E6E6F- db 'mv: cannot locate parent' 1559 00000A2E 74206C6F6361746520- 1559 00000A37 706172656E74 1560 00000A3D 0D0A00 db 0Dh, 0Ah, 0 1561 1562 msg_no_w_access: 1563 00000A40 0D0A db 0Dh, 0Ah 1564 00000A42 6D763A206E6F207772- db 'mv: no write access to ' 1564 00000A4B 697465206163636573- 1564 00000A54 7320746F20 1565 00000A59 00 db 0 1566 1567 msg_accross_devices: 1568 00000A5A 0D0A db 0Dh, 0Ah 1569 00000A5C 6D763A2063616E6E6F- db 'mv: cannot move directories across devices' 1569 00000A65 74206D6F7665206469- 1569 00000A6E 726563746F72696573- 1569 00000A77 206163726F73732064- 1569 00000A80 657669636573 1570 00000A86 0D0A00 db 0Dh, 0Ah, 0 1571 1572 msg_pathname_dotdot: 1573 00000A89 0D0A db 0Dh, 0Ah 1574 00000A8B 6D763A20536F727279- db "mv: Sorry, path names including '..' aren't allowed" 1574 00000A94 2C2070617468206E61- 1574 00000A9D 6D657320696E636C75- 1574 00000AA6 64696E6720272E2E27- 1574 00000AAF 206172656E27742061- 1574 00000AB8 6C6C6F776564 1575 00000ABE 0D0A00 db 0Dh, 0Ah, 0 1576 1577 msg_cant_rename: 1578 00000AC1 0D0A db 0Dh, 0Ah 1579 00000AC3 6D763A2063616E6E6F- db 'mv: cannot rename ' 1579 00000ACC 742072656E616D6520 1580 00000AD5 00 db 0 1581 1582 msg_cant_link: 1583 00000AD6 0D0A db 0Dh, 0Ah 1584 00000AD8 6D763A2063616E6E6F- db 'mv: cannot link ' 1584 00000AE1 74206C696E6B20 1585 00000AE8 00 db 0 1586 msg_to: 1587 00000AE9 20746F20 db ' to ' 1588 00000AED 00 db 0 1589 msg_and: 1590 00000AEE 20616E6420 db ' and ' 1591 00000AF3 00 db 0 1592 1593 msg_identical: 1594 00000AF4 20617265206964656E- db ' are identical' 1594 00000AFD 746963616C 1595 00000B02 0D0A00 db 0Dh, 0Ah, 0 1596 1597 msg_cant_mv_itself: 1598 00000B05 0D0A db 0Dh, 0Ah 1599 00000B07 6D763A2063616E6E6F- db 'mv: cannot move a directory into itself' 1599 00000B10 74206D6F7665206120- 1599 00000B19 6469726563746F7279- 1599 00000B22 20696E746F20697473- 1599 00000B2B 656C66 1600 00000B2E 0D0A00 db 0Dh, 0Ah, 0 1601 1602 msg_too_long: 1603 00000B31 0D0A db 0Dh, 0Ah 1604 00000B33 6D763A206E616D6520- db 'mv: name too long' 1604 00000B3C 746F6F206C6F6E67 1605 00000B44 0D0A00 db 0Dh, 0Ah, 0 1606 1607 msg_mode: 1608 00000B47 206D6F6465203F2028- db ' mode ? (y/n) ' 1608 00000B50 792F6E2920 1609 00000B55 00 db 0 1610 1611 msg_yes: 1612 00000B56 2059455320 db ' YES ' 1613 00000B5B 0D0A00 db 0Dh, 0Ah, 0 1614 1615 msg_no: 1616 00000B5E 204E4F20 db ' NO ' 1617 00000B62 0D0A00 db 0Dh, 0Ah, 0 1618 1619 err_msg: 1620 00000B65 0D0A db 0Dh, 0Ah 1621 00000B67 4572726F722120 db 'Error! ' 1622 00000B6E 0D0A00 db 0Dh, 0Ah, 0 1623 1624 msg_ok: 1625 00000B71 0D0A db 0Dh, 0Ah 1626 00000B73 4F4B2E db 'OK.' 1627 00000B76 0D0A00 db 0Dh, 0Ah, 0 1628 1629 ;----------------------------------------------------------------- 1630 ; bss - uninitialized data 1631 ;----------------------------------------------------------------- 1632 1633 00000B79 90 align 4 1634 1635 bss_start: 1636 1637 ABSOLUTE bss_start 1638 1639 ;uid: resw 1 1640 ;;gid: resw 1 ; Retro UNIX 386 v1.2 1641 1642 00000B7C ???????? target: resd 1 ; destination/target pathname pointer 1643 1644 00000B80 ???? st1dev: resw 1 1645 00000B82 st1buf: resb 34 ; for Retro UNIX 386 v1 & v1.1 1646 00000BA4 ???? st2dev: resw 1 1647 00000BA6 st2buf: resb 34 ; 1648 ;st1dev: resd 1 1649 ;st1buf: resb 66 ; for Retro UNIX 386 v1.2 1650 ;st2dev: resd 1 1651 ;st2buf: resb 66 ; 1652 1653 00000BC8 buf: resb 100 ; pathname buffer 1654 00000C2C sbuf: resb 92 ; source, parent name buffer ; 23/05/2022 1655 00000C88 tbuf: resb 92 ; target, parent name buffer ; 23/05/2022 1656 00000CE4 fstbuf: resb 66 ; fstat buffer 1657 ; 23/05/2022 1658 ;pst1buf: resb 66 1659 ;pst2buf: resb 66 1660 00000D26 pst1buf: resb 34 1661 00000D48 pst2buf: resb 34 1662 00000D6A ?? octms: resb 1 ; 27/05/2022 1663 00000D6B ???????? octm: resb 4 ; octal mode number 1664 00000D6F ?? char: resb 1 ; getchar buffer 1665 00000D70 nspth: resb MAXN ; 112 ; buffer for 'check' procedure 1666 1667 ; 22/05/2022 1668 ;----------------------------------------------------------------- 1669 ; Original UNIX v7 - mv (utility) c source code (mv.c) 1670 ;----------------------------------------------------------------- 1671 ;/* UNIX V7 source code: see www.tuhs.org for details. */; 1672 ; 1673 ;/* 1674 ; * mv file1 file2 1675 ; */ 1676 ; 1677 ;#include 1678 ;#include 1679 ;#include 1680 ;#include 1681 ;#include 1682 ; 1683 ;#define DOT "." 1684 ;#define DOTDOT ".." 1685 ;#define DELIM '/' 1686 ;#define SDELIM "/" 1687 ;#define MAXN 100 1688 ;#define MODEBITS 07777 1689 ;#define ROOTINO 2 1690 ; 1691 ;char *pname(); 1692 ;char *sprintf(); 1693 ;char *dname(); 1694 ;struct stat s1, s2; 1695 ; 1696 ;main(argc, argv) 1697 ;register char *argv[]; 1698 ;{ 1699 ; register i, r; 1700 ; 1701 ; if (argc < 3) 1702 ; goto usage; 1703 ; if (stat(argv[1], &s1) < 0) { 1704 ; fprintf(stderr, "mv: cannot access %s\n", argv[1]); 1705 ; return(1); 1706 ; } 1707 ; if ((s1.st_mode & S_IFMT) == S_IFDIR) { 1708 ; if (argc != 3) 1709 ; goto usage; 1710 ; return mvdir(argv[1], argv[2]); 1711 ; } 1712 ; setuid(getuid()); 1713 ; if (argc > 3) 1714 ; if (stat(argv[argc-1], &s2) < 0 || (s2.st_mode & S_IFMT) != S_IFDIR) 1715 ; goto usage; 1716 ; r = 0; 1717 ; for (i=1; i= 0) { 1741 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) { 1742 ; sprintf(buf, "%s/%s", target, dname(source)); 1743 ; target = buf; 1744 ; } 1745 ; if (stat(target, &s2) >= 0) { 1746 ; if ((s2.st_mode & S_IFMT) == S_IFDIR) { 1747 ; fprintf(stderr, "mv: %s is a directory\n", target); 1748 ; return(1); 1749 ; } 1750 ; if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) { 1751 ; fprintf(stderr, "mv: %s and %s are identical\n", 1752 ; source, target); 1753 ; return(1); 1754 ; } 1755 ; if (access(target, 2) < 0 && isatty(fileno(stdin))) { 1756 ; fprintf(stderr, "mv: %s: %o mode ", target, 1757 ; s2.st_mode & MODEBITS); 1758 ; i = c = getchar(); 1759 ; while (c != '\n' && c != EOF) 1760 ; c = getchar(); 1761 ; if (i != 'y') 1762 ; return(1); 1763 ; } 1764 ; if (unlink(target) < 0) { 1765 ; fprintf(stderr, "mv: cannot unlink %s\n", target); 1766 ; return(1); 1767 ; } 1768 ; } 1769 ; } 1770 ; if (link(source, target) < 0) { 1771 ; i = fork(); 1772 ; if (i == -1) { 1773 ; fprintf(stderr, "mv: try again\n"); 1774 ; return(1); 1775 ; } 1776 ; if (i == 0) { 1777 ; execl("/bin/cp", "cp", source, target, 0); 1778 ; fprintf(stderr, "mv: cannot exec cp\n"); 1779 ; exit(1); 1780 ; } 1781 ; while ((c = wait(&status)) != i && c != -1) 1782 ; ; 1783 ; if (status != 0) 1784 ; return(1); 1785 ; utime(target, &s1.st_atime); 1786 ; } 1787 ; if (unlink(source) < 0) { 1788 ; fprintf(stderr, "mv: cannot unlink %s\n", source); 1789 ; return(1); 1790 ; } 1791 ; return(0); 1792 ;} 1793 ; 1794 ;mvdir(source, target) 1795 ;char *source, *target; 1796 ;{ 1797 ; register char *p; 1798 ; register i; 1799 ; char buf[MAXN]; 1800 ; 1801 ; if (stat(target, &s2) >= 0) { 1802 ; if ((s2.st_mode&S_IFMT) != S_IFDIR) { 1803 ; fprintf(stderr, "mv: %s exists\n", target); 1804 ; return(1); 1805 ; } 1806 ; if (strlen(target) > MAXN-DIRSIZ-2) { 1807 ; fprintf(stderr, "mv :target name too long\n"); 1808 ; return(1); 1809 ; } 1810 ; strcpy(buf, target); 1811 ; target = buf; 1812 ; strcat(buf, SDELIM); 1813 ; strcat(buf, dname(source)); 1814 ; if (stat(target, &s2) >= 0) { 1815 ; fprintf(stderr, "mv: %s exists\n", buf); 1816 ; return(1); 1817 ; } 1818 ; } 1819 ; if (strcmp(source, target) == 0) { 1820 ; fprintf(stderr, "mv: ?? source == target, source exists and target doesnt\n"); 1821 ; return(1); 1822 ; } 1823 ; p = dname(source); 1824 ; if (!strcmp(p, DOT) || !strcmp(p, DOTDOT) || !strcmp(p, "") || p[strlen(p)-1]=='/') { 1825 ; fprintf(stderr, "mv: cannot rename %s\n", p); 1826 ; return(1); 1827 ; } 1828 ; if (stat(pname(source), &s1) < 0 || stat(pname(target), &s2) < 0) { 1829 ; fprintf(stderr, "mv: cannot locate parent\n"); 1830 ; return(1); 1831 ; } 1832 ; if (access(pname(target), 2) < 0) { 1833 ; fprintf(stderr, "mv: no write access to %s\n", pname(target)); 1834 ; return(1); 1835 ; } 1836 ; if (access(pname(source), 2) < 0) { 1837 ; fprintf(stderr, "mv: no write access to %s\n", pname(source)); 1838 ; return(1); 1839 ; } 1840 ; if (access(source, 2) < 0) { 1841 ; fprintf(stderr, "mv: no write access to %s\n", source); 1842 ; return(1); 1843 ; } 1844 ; if (s1.st_dev != s2.st_dev) { 1845 ; fprintf(stderr, "mv: cannot move directories across devices\n"); 1846 ; return(1); 1847 ; } 1848 ; if (s1.st_ino != s2.st_ino) { 1849 ; char dst[MAXN+5]; 1850 ; 1851 ; if (chkdot(source) || chkdot(target)) { 1852 ; fprintf(stderr, "mv: Sorry, path names including %s aren't allowed\n", DOTDOT); 1853 ; return(1); 1854 ; } 1855 ; stat(source, &s1); 1856 ; if (check(pname(target), s1.st_ino)) 1857 ; return(1); 1858 ; for (i = 1; i <= NSIG; i++) 1859 ; signal(i, SIG_IGN); 1860 ; if (link(source, target) < 0) { 1861 ; fprintf(stderr, "mv: cannot link %s to %s\n", target, source); 1862 ; return(1); 1863 ; } 1864 ; if (unlink(source) < 0) { 1865 ; fprintf(stderr, "mv: %s: cannot unlink\n", source); 1866 ; unlink(target); 1867 ; return(1); 1868 ; } 1869 ; strcat(dst, target); 1870 ; strcat(dst, "/"); 1871 ; strcat(dst, DOTDOT); 1872 ; if (unlink(dst) < 0) { 1873 ; fprintf(stderr, "mv: %s: cannot unlink\n", dst); 1874 ; if (link(target, source) >= 0) 1875 ; unlink(target); 1876 ; return(1); 1877 ; } 1878 ; if (link(pname(target), dst) < 0) { 1879 ; fprintf(stderr, "mv: cannot link %s to %s\n", 1880 ; dst, pname(target)); 1881 ; if (link(pname(source), dst) >= 0) 1882 ; if (link(target, source) >= 0) 1883 ; unlink(target); 1884 ; return(1); 1885 ; } 1886 ; return(0); 1887 ; } 1888 ; if (link(source, target) < 0) { 1889 ; fprintf(stderr, "mv: cannot link %s and %s\n", 1890 ; source, target); 1891 ; return(1); 1892 ; } 1893 ; if (unlink(source) < 0) { 1894 ; fprintf(stderr, "mv: ?? cannot unlink %s\n", source); 1895 ; return(1); 1896 ; } 1897 ; return(0); 1898 ;} 1899 ; 1900 ;char * 1901 ;pname(name) 1902 ;register char *name; 1903 ;{ 1904 ; register c; 1905 ; register char *p, *q; 1906 ; static char buf[MAXN]; 1907 ; 1908 ; p = q = buf; 1909 ; while (c = *p++ = *name++) 1910 ; if (c == DELIM) 1911 ; q = p-1; 1912 ; if (q == buf && *q == DELIM) 1913 ; q++; 1914 ; *q = 0; 1915 ; return buf[0]? buf : DOT; 1916 ;} 1917 ; 1918 ;char * 1919 ;dname(name) 1920 ;register char *name; 1921 ;{ 1922 ; register char *p; 1923 ; 1924 ; p = name; 1925 ; while (*p) 1926 ; if (*p++ == DELIM && *p) 1927 ; name = p; 1928 ; return name; 1929 ;} 1930 ; 1931 ;check(spth, dinode) 1932 ;char *spth; 1933 ;ino_t dinode; 1934 ;{ 1935 ; char nspth[MAXN]; 1936 ; struct stat sbuf; 1937 ; 1938 ; sbuf.st_ino = 0; 1939 ; 1940 ; strcpy(nspth, spth); 1941 ; while (sbuf.st_ino != ROOTINO) { 1942 ; if (stat(nspth, &sbuf) < 0) { 1943 ; fprintf(stderr, "mv: cannot access %s\n", nspth); 1944 ; return(1); 1945 ; } 1946 ; if (sbuf.st_ino == dinode) { 1947 ; fprintf(stderr, "mv: cannot move a directory into itself\n"); 1948 ; return(1); 1949 ; } 1950 ; if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) { 1951 ; fprintf(stderr, "mv: name too long\n"); 1952 ; return(1); 1953 ; } 1954 ; strcat(nspth, SDELIM); 1955 ; strcat(nspth, DOTDOT); 1956 ; } 1957 ; return(0); 1958 ;} 1959 ; 1960 ;chkdot(s) 1961 ;register char *s; 1962 ;{ 1963 ; do { 1964 ; if (strcmp(dname(s), DOTDOT) == 0) 1965 ; return(1); 1966 ; s = pname(s); 1967 ; } while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0); 1968 ; return(0); 1969 ;} 1970 ;