1 ; **************************************************************************** 2 ; chown386.s (chown1.s) - by Erdogan Tan - 29/04/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 386 v1 (v1.1 & v1.2) - chown - change (file's) owner 5 ; 6 ; [ Last Modification: 30/04/2022 ] 7 ; 8 ; Derived from (original) UNIX v2 (v1) 'chown.s' source Code 9 ; Ref: 10 ; www.tuhs.org (https://minnie.tuhs.org) 11 ; svntree-20081216.tar.gz 12 ; **************************************************************************** 13 ; [ unix72/src/cmd/chown.s (archive date: 16-12-2008) ] 14 15 ; UNIX v1 system calls 16 _rele equ 0 17 _exit equ 1 18 _fork equ 2 19 _read equ 3 20 _write equ 4 21 _open equ 5 22 _close equ 6 23 _wait equ 7 24 _creat equ 8 25 _link equ 9 26 _unlink equ 10 27 _exec equ 11 28 _chdir equ 12 29 _time equ 13 30 _mkdir equ 14 31 _chmod equ 15 32 _chown equ 16 33 _break equ 17 34 _stat equ 18 35 _seek equ 19 36 _tell equ 20 37 _mount equ 21 38 _umount equ 22 39 _setuid equ 23 40 _getuid equ 24 41 _stime equ 25 42 _quit equ 26 43 _intr equ 27 44 _fstat equ 28 45 _emt equ 29 46 _mdate equ 30 47 _stty equ 31 48 _gtty equ 32 49 _ilgins equ 33 50 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 51 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 52 53 ;;; 54 ESCKey equ 1Bh 55 EnterKey equ 0Dh 56 57 %macro sys 1-4 58 ; 03/09/2015 59 ; 13/04/2015 60 ; Retro UNIX 386 v1 system call. 61 %if %0 >= 2 62 mov ebx, %2 63 %if %0 >= 3 64 mov ecx, %3 65 %if %0 = 4 66 mov edx, %4 67 %endif 68 %endif 69 %endif 70 mov eax, %1 71 int 30h 72 %endmacro 73 74 ; Retro UNIX 386 v1 system call format: 75 ; sys systemcall (eax) , , 76 77 [BITS 32] ; We need 32-bit intructions for protected mode 78 79 [ORG 0] 80 81 START_CODE: 82 ; 30/04/2022 83 ; 29/04/2022 84 85 ;mov sp,r5 86 ;mov (r5),r4 87 ;cmp r4,$3 88 ;bge 1f 89 ;jsr r5,mesg; ; .even 90 91 00000000 58 pop eax ; eax = number of arguments 92 93 ;cmp eax, 3 94 00000001 3C03 cmp al, 3 95 00000003 7311 jnb short chown_1 96 97 00000005 B8[8C010000] mov eax, usage_msg 98 0000000A E8EE000000 call print_msg 99 exit: 100 sys _exit 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 <1> mov ebx, %2 63 <1> %if %0 >= 3 64 <1> mov ecx, %3 65 <1> %if %0 = 4 66 <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 0000000F B801000000 <1> mov eax, %1 71 00000014 CD30 <1> int 30h 101 ;hang: 102 ; nop 103 ; jmp short hang 104 105 chown_1: 106 ;1: 107 ;add $4,r5 108 ;mov (r5),r3 109 ;cmpb (r3),$'0 110 ;blt 1f 111 ;cmpb (r3),$'9 112 ;bgt 1f 113 ;jsr r5,cvnum; geta 114 ;br do 115 116 ;mov [argc], eax 117 00000016 A2[DC030000] mov [argc], al ; argument count 118 119 ;xor ecx, ecx 120 0000001B 58 pop eax ; argument 0 - (exec) file name 121 0000001C 5E pop esi ; argument 1 - (new) owner 122 0000001D 8A06 mov al, [esi] 123 0000001F 3C30 cmp al, '0' 124 00000021 7210 jb short chown_2 ; (new) owner name 125 00000023 3C39 cmp al, '9' 126 00000025 770C ja short chown_2 ; (new) owner name 127 ; (new) owner number 128 00000027 BB[3C010000] mov ebx, geta ; get user num from user input 129 0000002C E8E8000000 call cvnum 130 00000031 EB79 jmp short do 131 132 chown_2: 133 ;1: 134 ;mov $uids,r0 135 ;jsr r5,fopen; ubuf 136 ;bec 1f 137 ;jsr r5,mesg; ; .even 138 ;sys exit 139 140 sys _open, uids, 0 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 00000033 BB[7B010000] <1> mov ebx, %2 63 <1> %if %0 >= 3 64 00000038 B900000000 <1> mov ecx, %3 65 <1> %if %0 = 4 66 <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 0000003D B805000000 <1> mov eax, %1 71 00000042 CD30 <1> int 30h 141 00000044 7307 jnc short chown_3 142 143 00000046 B8[A8010000] mov eax, cant_open_msg 144 0000004B EB14 jmp short write_msg_and_exit 145 146 chown_3: 147 ;1: 148 ;mov r3,r2 149 ; 30/04/2022 150 0000004D 66A3[D4010000] mov [ubuf], ax ; file descriptor 151 chown_4: 152 ; get user name 153 ; (it is 1st word of a row in '/etc/passwd' file, 154 ; from 1st character in row to ':' character) 155 156 00000053 89F7 mov edi, esi 157 chown_5: 158 ;2: 159 ;jsr r5,getc; ubuf 160 ;bcc 3f 161 162 ;mov ebx, ubuf 163 00000055 E8E4000000 call getc 164 0000005A 731F jnc short chown_6 165 who: 166 ;jsr r5,mesg; ; .even 167 ;sys exit 168 169 0000005C B8[C1010000] mov eax, who_msg 170 write_msg_and_exit: 171 00000061 E897000000 call print_msg 172 closefile_and_exit: 173 00000066 0FB71D[D4010000] movzx ebx, word [ubuf] ; 30/04/2022 174 sys _close 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 <1> mov ebx, %2 63 <1> %if %0 >= 3 64 <1> mov ecx, %3 65 <1> %if %0 = 4 66 <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 0000006D B806000000 <1> mov eax, %1 71 00000072 CD30 <1> int 30h 175 sys _exit 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 <1> mov ebx, %2 63 <1> %if %0 >= 3 64 <1> mov ecx, %3 65 <1> %if %0 = 4 66 <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 00000074 B801000000 <1> mov eax, %1 71 00000079 CD30 <1> int 30h 176 177 ;hangemhigh: 178 ; nop 179 ; jmp short hangemhigh 180 181 chown_6: 182 ;3: 183 ;cmp r0,$': 184 ;beq 3f 185 ;cmpb (r2)+,r0 186 ;beq 2b 187 188 0000007B 3C3A cmp al, ':' 189 0000007D 7415 je short chown_8 190 0000007F AE scasb ; cmp al, [edi] .. inc edi 191 00000080 74D3 je short chown_5 192 193 chown_7: 194 ;2: 195 ;jsr r5,getc; ubuf 196 ;bcs who 197 ;cmp r0,$'\n 198 ;bne 2b 199 ;br 1b 200 201 ;mov ebx, ubuf 202 00000082 E8B7000000 call getc 203 00000087 72D3 jc short who 204 205 ; (there is CR character at the end of each row 206 ; in '/etc/passwd' file) 207 208 00000089 3C0D cmp al, EnterKey ; cmp al, 0Dh 209 0000008B 75F5 jne short chown_7 ; continue/pass (until CR) 210 ;jmp short chown_4 ; next row (in '/etc/passwd') 211 ; 30/04/2022 212 ; get linefeed 213 0000008D E8AC000000 call getc 214 ;jc short who 215 ;(line feed check is not necessary if 'etc/passwd') 216 ;cmp al, 0Ah ; line feed (lf byte of crlf) 217 ;je short chown_4 218 ;mov edi, esi 219 ;jmp short chown_6 220 00000092 EBBF jmp short chown_4 221 chown_8: 222 ;3: 223 ;tstb (r2) 224 ;bne 2b 225 226 00000094 F607FF test byte [edi], 0FFh 227 00000097 75E9 jnz short chown_7 228 chown_9: 229 ; user name is ok (matches with chown input) 230 ;3: 231 ;jsr r5,getc; ubuf 232 ;cmpb r0,$': 233 ;bne 3b 234 ;jsr r5,cvnum; getc 235 236 ;mov ebx, ubuf 237 00000099 E8A0000000 call getc 238 0000009E 3C3A cmp al, ':' 239 000000A0 75F7 jne short chown_9 240 241 ; get user number (which is in /'etc/passwd') 242 000000A2 BB[3E010000] mov ebx, getc ; get user num from '/etc/passwd' 243 000000A7 E86D000000 call cvnum 244 do: 245 ;sub $2,r4 246 ;mov r1,0f+2 247 ;tst (r5)+ 248 249 ; [esp] = argument 2 = file name 250 ; ecx = user number 251 ; (<= 255 for current Retro UNIX version) 252 253 ;sub dword [argc], 2 254 000000AC 802D[DC030000]02 sub byte [argc], 2 255 chown_10: 256 ;1: 257 ;mov (r5)+,0f 258 ;sys chown; 0:..; 0 259 ;bec 2f 260 ;mov 0b,r0 261 ;mov r0,0f 262 ;clr 0f+2 263 264 000000B3 5E pop esi ; argument 2 = file name 265 ; (and argument 3 .. argument 4) 266 ; ecx = user number 267 sys _chown, esi 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 000000B4 89F3 <1> mov ebx, %2 63 <1> %if %0 >= 3 64 <1> mov ecx, %3 65 <1> %if %0 = 4 66 <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 000000B6 B810000000 <1> mov eax, %1 71 000000BB CD30 <1> int 30h 268 000000BD 7331 jnc short chown_13 269 270 000000BF 31C9 xor ecx, ecx ; 0 271 chown_11: 272 ;3: 273 ;tstb (r0)+ 274 ;beq 3f 275 ;inc 0f+2 276 ;br 3b 277 278 ; strlen (calculating file name length) 279 000000C1 FEC9 dec cl ; max. 255 bytes (may be 64 to 70) 280 000000C3 89F7 mov edi, esi ; file name address 281 000000C5 28C0 sub al, al ; 0 282 000000C7 F2AE repne scasb 283 ; do: 284 ; and ecx ecx 285 ; jz short dont 286 ; cmp [edi], al 287 ; jne short dont 288 ; inc edi 289 ; dec ecx 290 ; jmp short do 291 ; dont: 292 000000C9 29F7 sub edi, esi 293 000000CB 4F dec edi ; 30/04/2022 294 ; edi = file name length 295 chown_12: 296 ;3: 297 ;mov $1,r0 298 ;sys write; 0:..; .. 299 ;jsr r5,mesg; ; .even 300 301 ; 30/04/2022 302 000000CC B8[89010000] mov eax, nextline 303 000000D1 E827000000 call print_msg 304 305 sys _write, 1, esi, edi 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 000000D6 BB01000000 <1> mov ebx, %2 63 <1> %if %0 >= 3 64 000000DB 89F1 <1> mov ecx, %3 65 <1> %if %0 = 4 66 000000DD 89FA <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 000000DF B804000000 <1> mov eax, %1 71 000000E4 CD30 <1> int 30h 306 000000E6 B8[87010000] mov eax, qu_msg 307 000000EB E80D000000 call print_msg 308 309 chown_13: 310 ;2: 311 ;dec r4 312 ;bgt 1b 313 ;sys exit 314 315 ;dec word [argc] 316 000000F0 FE0D[DC030000] dec byte [argc] 317 000000F6 7FBB jg short chown_10 318 000000F8 E969FFFFFF jmp closefile_and_exit 319 320 print_msg: 321 ; 29/04/2022 322 ; Modified registers: eax, ebx, ecx, edx 323 strlen: 324 ; eax = asciiz string address 325 000000FD 89C3 mov ebx, eax 326 000000FF 4B dec ebx 327 nextchr: 328 00000100 43 inc ebx 329 00000101 803B00 cmp byte [ebx], 0 330 00000104 77FA ja short nextchr 331 ;cmp [ebx], 0Dh 332 ;ja short nextchr 333 00000106 29C3 sub ebx, eax 334 ; bx = asciiz string length 335 ;retn 336 print_str: 337 00000108 89DA mov edx, ebx 338 sys _write, 1, eax 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 0000010A BB01000000 <1> mov ebx, %2 63 <1> %if %0 >= 3 64 0000010F 89C1 <1> mov ecx, %3 65 <1> %if %0 = 4 66 <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 00000111 B804000000 <1> mov eax, %1 71 00000116 CD30 <1> int 30h 339 ; 340 00000118 C3 retn 341 342 cvnum: 343 ; 30/04/2022 344 ; 29/04/2022 345 346 ;clr r1 347 348 ; INPUT: 349 ; ebx = getc address (*) 350 ; or geta address (**) 351 ; OUTPUT: 352 ; ecx = (user) number 353 354 ; Modified registers: ecx, eax, edx, ebx 355 ; and.. esi (**) or ebp (*) 356 357 00000119 31C9 xor ecx, ecx ; 0 358 0000011B 891D[D0010000] mov [function], ebx 359 cvn_1: 360 ;1: 361 ;jsr r5,*(r5); ubuf 362 ;bcs 1f 363 ;sub $'0,r0 364 ;cmp r0,$9. 365 ;bhi 1f 366 ;mpy $10.,r1 367 ;add r0,r1 368 ;br 1b 369 370 00000121 31C0 xor eax, eax 371 372 00000123 FF15[D0010000] call dword [function] ; 30/04/2022 373 00000129 7210 jc short cvn_2 374 ; al = 0 375 0000012B 2C30 sub al, '0' ; AL-30h 376 ;jb short cvn_2 377 ; AL-30h > 9 for AL values less than 30h 378 0000012D 3C09 cmp al, 9 379 0000012F 770A ja short cvn_2 380 00000131 50 push eax 381 00000132 B00A mov al, 10 382 00000134 F7E1 mul ecx 383 00000136 59 pop ecx 384 00000137 01C1 add ecx, eax 385 00000139 EBE6 jmp short cvn_1 386 cvn_2: 387 ;1: 388 ;tst (r5)+ 389 ;rts r5 390 391 0000013B C3 retn 392 geta: 393 ;movb (r3)+,r0 394 ;tst (r5)+ 395 ;rts r5 396 397 0000013C AC lodsb ; mov al, [esi] .. inc esi 398 0000013D C3 retn 399 400 getc: 401 ; 30/04/2022 402 ; 29/04/2022 403 404 ; INPUT: 405 ; ubuf = read buffer (header) address 406 ; OUTPUT: 407 ; al = character (if cf=0) 408 ; (if cf = 1 -> read error) 409 410 ; Modified registers: eax, ebx, ecx, edx, ebp 411 412 0000013E BD[D4010000] mov ebp, ubuf 413 ;mov ax, [ebp+2] 414 00000143 0FB74502 movzx eax, word [ebp+2] ; char count 415 ;and ax, ax 416 00000147 21C0 and eax, eax 417 00000149 751F jnz short gch1 418 gch0: 419 0000014B 0FB75D00 movzx ebx, word [ebp] 420 0000014F B9[DC010000] mov ecx, ubuf+8 ; read buff. (data) addr. 421 00000154 894D04 mov [ebp+4], ecx ; char offset 422 ;mov [ebp+2], ax ; 0 423 00000157 29D2 sub edx, edx 424 00000159 B602 mov dh, 2 425 ;mov edx, 512 426 sys _read ; sys _read, ebx, ecx, edx 58 <1> 59 <1> 60 <1> 61 <1> %if %0 >= 2 62 <1> mov ebx, %2 63 <1> %if %0 >= 3 64 <1> mov ecx, %3 65 <1> %if %0 = 4 66 <1> mov edx, %4 67 <1> %endif 68 <1> %endif 69 <1> %endif 70 0000015B B803000000 <1> mov eax, %1 71 00000160 CD30 <1> int 30h 427 00000162 7216 jc short gch2 428 00000164 09C0 or eax, eax 429 ;jz short gch3 430 00000166 7502 jnz short gch1 431 ; 432 00000168 F9 stc 433 00000169 C3 retn 434 gch1: 435 ;dec ax 436 0000016A 48 dec eax 437 0000016B 66894502 mov [ebp+2], ax 438 0000016F 8B5D04 mov ebx, [ebp+4] 439 ;xor eax, eax 440 00000172 30E4 xor ah, ah 441 00000174 8A03 mov al, [ebx] 442 00000176 43 inc ebx 443 00000177 895D04 mov [ebp+4], ebx 444 ;;xor ah, ah 445 ;retn 446 gch2: 447 ;;xor ax, ax 448 ;xor eax, eax 449 0000017A C3 retn 450 ;gch3: 451 ;stc 452 ;retn 453 454 ; 455 ;uids: 456 ; 457 ; .bss 458 ;ubuf: .=.+518. 459 460 ;----------------------------------------------------------------- 461 ; data - initialized data 462 ;----------------------------------------------------------------- 463 464 ;align 4 465 466 0000017B 2F6574632F70617373- uids: db "/etc/passwd", 0 ; password file (contains user IDs) 466 00000184 776400 467 468 qu_msg: ; 469 470 00000187 203F db " ?" 471 nextline: 472 00000189 0D0A00 db 0Dh, 0Ah, 0 473 474 usage_msg: 475 0000018C 0D0A db 0Dh, 0Ah 476 0000018E 55736167653A206368- db "Usage: chown uid f1 ...", 0Dh, 0Ah, 0 476 00000197 6F776E207569642066- 476 000001A0 31202E2E2E0D0A00 477 cant_open_msg: 478 000001A8 0D0A db 0Dh, 0Ah 479 000001AA 43616E2774206F7065- db "Can't open /etc/uids", 0Dh, 0Ah, 0 479 000001B3 6E202F6574632F7569- 479 000001BC 64730D0A00 480 who_msg: 481 000001C1 202D2057686F203F20- db " - Who ? ", 0Dh, 0Ah, 0 481 000001CA 0D0A00 482 483 ;----------------------------------------------------------------- 484 ; bss - uninitialized data 485 ;----------------------------------------------------------------- 486 487 000001CD 90 align 4 488 489 bss_start: 490 491 ABSOLUTE bss_start 492 493 function: 494 000001D0 ???????? resd 1 ; (is used by 'cvnum') 495 496 000001D4 ???????????????? ubuf: resb 8 ; Buffer header 497 ; word - file descriptor 498 ; word - character count 499 ; dword - character offset 500 000001DC resb 512 ; Buffer data 501 502 ;argc: resd 1 503 000003DC ?? argc: resb 1 ; argument count 504 505 ; 29/04/2022 506 507 ;----------------------------------------------------------------- 508 ; Original UNIX v2 - /bin/chown source code (chown.s) 509 ; in PDP-11 (unix) assembly language 510 ;----------------------------------------------------------------- 511 ; 512 ;/ chown -- change owner 513 ; 514 ; 515 ; .globl fopen, getc, mesg 516 ; 517 ; mov sp,r5 518 ; mov (r5),r4 519 ; cmp r4,$3 520 ; bge 1f 521 ; jsr r5,mesg; ; .even 522 ;1: 523 ; add $4,r5 524 ; mov (r5),r3 525 ; cmpb (r3),$'0 526 ; blt 1f 527 ; cmpb (r3),$'9 528 ; bgt 1f 529 ; jsr r5,cvnum; geta 530 ; br do 531 ;1: 532 ; mov $uids,r0 533 ; jsr r5,fopen; ubuf 534 ; bec 1f 535 ; jsr r5,mesg; ; .even 536 ; sys exit 537 ;1: 538 ; mov r3,r2 539 ;2: 540 ; jsr r5,getc; ubuf 541 ; bcc 3f 542 ;who: 543 ; jsr r5,mesg; ; .even 544 ; sys exit 545 ;3: 546 ; cmp r0,$': 547 ; beq 3f 548 ; cmpb (r2)+,r0 549 ; beq 2b 550 ;2: 551 ; jsr r5,getc; ubuf 552 ; bcs who 553 ; cmp r0,$'\n 554 ; bne 2b 555 ; br 1b 556 ;3: 557 ; tstb (r2) 558 ; bne 2b 559 ;3: 560 ; jsr r5,getc; ubuf 561 ; cmpb r0,$': 562 ; bne 3b 563 ; jsr r5,cvnum; getc 564 ;do: 565 ; sub $2,r4 566 ; mov r1,0f+2 567 ; tst (r5)+ 568 ;1: 569 ; mov (r5)+,0f 570 ; sys chown; 0:..; 0 571 ; bec 2f 572 ; mov 0b,r0 573 ; mov r0,0f 574 ; clr 0f+2 575 ;3: 576 ; tstb (r0)+ 577 ; beq 3f 578 ; inc 0f+2 579 ; br 3b 580 ;3: 581 ; mov $1,r0 582 ; sys write; 0:..; .. 583 ; jsr r5,mesg; ; .even 584 ;2: 585 ; dec r4 586 ; bgt 1b 587 ; sys exit 588 ; 589 ;cvnum: 590 ; clr r1 591 ;1: 592 ; jsr r5,*(r5); ubuf 593 ; bcs 1f 594 ; sub $'0,r0 595 ; cmp r0,$9. 596 ; bhi 1f 597 ; mpy $10.,r1 598 ; add r0,r1 599 ; br 1b 600 ;1: 601 ; tst (r5)+ 602 ; rts r5 603 ; 604 ;geta: 605 ; movb (r3)+,r0 606 ; tst (r5)+ 607 ; rts r5 608 ; 609 ;uids: 610 ; 611 ; .bss 612 ;ubuf: .=.+518.