1 ; **************************************************************************** 2 ; chown386.s (chown0.s) - by Erdogan Tan - 29/04/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 8086 v1 - 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 ; Modified from: 16 ; chown1.s - 30/04/2022 - (Retro UNIX 386 v1 & v1.1 % v1.2) 17 18 ; UNIX v1 system calls 19 _rele equ 0 20 _exit equ 1 21 _fork equ 2 22 _read equ 3 23 _write equ 4 24 _open equ 5 25 _close equ 6 26 _wait equ 7 27 _creat equ 8 28 _link equ 9 29 _unlink equ 10 30 _exec equ 11 31 _chdir equ 12 32 _time equ 13 33 _mkdir equ 14 34 _chmod equ 15 35 _chown equ 16 36 _break equ 17 37 _stat equ 18 38 _seek equ 19 39 _tell equ 20 40 _mount equ 21 41 _umount equ 22 42 _setuid equ 23 43 _getuid equ 24 44 _stime equ 25 45 _quit equ 26 46 _intr equ 27 47 _fstat equ 28 48 _emt equ 29 49 _mdate equ 30 50 _stty equ 31 51 _gtty equ 32 52 _ilgins equ 33 53 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 54 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 55 56 ;;; 57 ESCKey equ 1Bh 58 EnterKey equ 0Dh 59 60 ;%macro sys 1-4 61 ; ; 03/09/2015 62 ; ; 13/04/2015 63 ; ; Retro UNIX 386 v1 system call. 64 ; %if %0 >= 2 65 ; mov ebx, %2 66 ; %if %0 >= 3 67 ; mov ecx, %3 68 ; ;%if %0 = 4 69 ; %if %0 >= 4 ; 11/03/2022 70 ; mov edx, %4 71 ; %endif 72 ; %endif 73 ; %endif 74 ; mov eax, %1 75 ; int 30h 76 ;%endmacro 77 78 %macro sys 1-4 79 ; Retro UNIX 8086 v1 system call. 80 %if %0 >= 2 81 mov bx, %2 82 %if %0 >= 3 83 mov cx, %3 84 %if %0 >= 4 85 mov dx, %4 86 %endif 87 %endif 88 %endif 89 mov ax, %1 90 int 20h 91 %endmacro 92 93 ;; Retro UNIX 386 v1 system call format: 94 ;; sys systemcall (eax) , , 95 96 ;; 11/03/2022 97 ;; Note: Above 'sys' macro has limitation about register positions; 98 ;; ebx, ecx, edx registers must not be used after their 99 ;; positions in sys macro. 100 ;; for example: 101 ;; 'sys _write, 1, msg, ecx' is defective, because 102 ;; ecx will be used/assigned before edx in 'sys' macro. 103 ;; correct order may be: 104 ;; 'sys _write, 1, msg, eax ; (eax = byte count) 105 106 ; Retro UNIX 8086 v1 system call format: 107 ; sys systemcall (ax) , , 108 109 ; ---------------------------------------------------------------------------- 110 111 [BITS 16] ; 16-bit intructions (8086/8088 - Real Mode) 112 113 [ORG 0] 114 115 START_CODE: 116 ; 30/04/2022 - Retro UNIX 8086 v1 117 ; 32 bit to 16 bit conversion 118 ; ----- 119 ; eax, edx, ecx, ebx -> ax, dx, cx, bx 120 ; esi, edi, ebp, esp -> si, di, bp, sp 121 ; register+4 -> register+2 122 ; dword values on stack -> word values on stack 123 ; 124 ; 30/04/2022 125 ; 29/04/2022 126 127 ;mov sp,r5 128 ;mov (r5),r4 129 ;cmp r4,$3 130 ;bge 1f 131 ;jsr r5,mesg; ; .even 132 133 00000000 58 pop ax ; ax = number of arguments 134 135 ;cmp ax, 3 136 00000001 3C03 cmp al, 3 137 00000003 730B jnb short chown_1 138 139 00000005 B8[3701] mov ax, usage_msg 140 00000008 E8AF00 call print_msg 141 exit: 142 sys _exit 79 <1> 80 <1> %if %0 >= 2 81 <1> mov bx, %2 82 <1> %if %0 >= 3 83 <1> mov cx, %3 84 <1> %if %0 >= 4 85 <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 0000000B B80100 <1> mov ax, %1 90 0000000E CD20 <1> int 20h 143 ;hang: 144 ; nop 145 ; jmp short hang 146 147 chown_1: 148 ;1: 149 ;add $4,r5 150 ;mov (r5),r3 151 ;cmpb (r3),$'0 152 ;blt 1f 153 ;cmpb (r3),$'9 154 ;bgt 1f 155 ;jsr r5,cvnum; geta 156 ;br do 157 158 ;mov [argc], ax 159 00000010 A2[8003] mov [argc], al ; argument count 160 161 ;xor cx, cx 162 00000013 58 pop ax ; argument 0 - (exec) file name 163 00000014 5E pop si ; argument 1 - (new) owner 164 00000015 8A04 mov al, [si] 165 00000017 3C30 cmp al, '0' 166 00000019 720C jb short chown_2 ; (new) owner name 167 0000001B 3C39 cmp al, '9' 168 0000001D 7708 ja short chown_2 ; (new) owner name 169 ; (new) owner number 170 0000001F BB[F000] mov bx, geta ; get user num from user input 171 00000022 E8AD00 call cvnum 172 00000025 EB57 jmp short do 173 174 chown_2: 175 ;1: 176 ;mov $uids,r0 177 ;jsr r5,fopen; ubuf 178 ;bec 1f 179 ;jsr r5,mesg; ; .even 180 ;sys exit 181 182 sys _open, uids, 0 79 <1> 80 <1> %if %0 >= 2 81 00000027 BB[2601] <1> mov bx, %2 82 <1> %if %0 >= 3 83 0000002A B90000 <1> mov cx, %3 84 <1> %if %0 >= 4 85 <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 0000002D B80500 <1> mov ax, %1 90 00000030 CD20 <1> int 20h 183 00000032 7305 jnc short chown_3 184 185 00000034 B8[5301] mov ax, cant_open_msg 186 00000037 EB0D jmp short write_msg_and_exit 187 188 chown_3: 189 ;1: 190 ;mov r3,r2 191 ; 30/04/2022 192 00000039 A3[7A01] mov [ubuf], ax ; file descriptor 193 chown_4: 194 ; get user name 195 ; (it is 1st word of a row in '/etc/passwd' file, 196 ; from 1st character in row to ':' character) 197 198 0000003C 89F7 mov di, si 199 chown_5: 200 ;2: 201 ;jsr r5,getc; ubuf 202 ;bcc 3f 203 204 ;mov bx, ubuf 205 0000003E E8B100 call getc 206 00000041 7314 jnc short chown_6 207 who: 208 ;jsr r5,mesg; ; .even 209 ;sys exit 210 211 00000043 B8[6C01] mov ax, who_msg 212 write_msg_and_exit: 213 00000046 E87100 call print_msg 214 closefile_and_exit: 215 00000049 8B1E[7A01] mov bx, [ubuf] ; 30/04/2022 216 sys _close 79 <1> 80 <1> %if %0 >= 2 81 <1> mov bx, %2 82 <1> %if %0 >= 3 83 <1> mov cx, %3 84 <1> %if %0 >= 4 85 <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 0000004D B80600 <1> mov ax, %1 90 00000050 CD20 <1> int 20h 217 sys _exit 79 <1> 80 <1> %if %0 >= 2 81 <1> mov bx, %2 82 <1> %if %0 >= 3 83 <1> mov cx, %3 84 <1> %if %0 >= 4 85 <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 00000052 B80100 <1> mov ax, %1 90 00000055 CD20 <1> int 20h 218 219 ;hangemhigh: 220 ; nop 221 ; jmp short hangemhigh 222 223 chown_6: 224 ;3: 225 ;cmp r0,$': 226 ;beq 3f 227 ;cmpb (r2)+,r0 228 ;beq 2b 229 230 00000057 3C3A cmp al, ':' 231 00000059 7411 je short chown_8 232 0000005B AE scasb ; cmp al, [di] .. inc di 233 0000005C 74E0 je short chown_5 234 235 chown_7: 236 ;2: 237 ;jsr r5,getc; ubuf 238 ;bcs who 239 ;cmp r0,$'\n 240 ;bne 2b 241 ;br 1b 242 243 ;mov bx, ubuf 244 0000005E E89100 call getc 245 00000061 72E0 jc short who 246 247 ; (there is CR character at the end of each row 248 ; in '/etc/passwd' file) 249 250 00000063 3C0D cmp al, EnterKey ; cmp al, 0Dh 251 00000065 75F7 jne short chown_7 ; continue/pass (until CR) 252 ;jmp short chown_4 ; next row (in '/etc/passwd') 253 ; 30/04/2022 254 ; get linefeed 255 00000067 E88800 call getc 256 ;jc short who 257 ;(line feed check is not necessary if 'etc/passwd') 258 ;cmp al, 0Ah ; line feed (lf byte of crlf) 259 ;je short chown_4 260 ;mov di, si 261 ;jmp short chown_6 262 0000006A EBD0 jmp short chown_4 263 chown_8: 264 ;3: 265 ;tstb (r2) 266 ;bne 2b 267 268 0000006C F605FF test byte [di], 0FFh 269 0000006F 75ED jnz short chown_7 270 chown_9: 271 ; user name is ok (matches with chown input) 272 ;3: 273 ;jsr r5,getc; ubuf 274 ;cmpb r0,$': 275 ;bne 3b 276 ;jsr r5,cvnum; getc 277 278 ;mov bx, ubuf 279 00000071 E87E00 call getc 280 00000074 3C3A cmp al, ':' 281 00000076 75F9 jne short chown_9 282 283 ; get user number (which is in /'etc/passwd') 284 00000078 BB[F200] mov bx, getc ; get user num from '/etc/passwd' 285 0000007B E85400 call cvnum 286 do: 287 ;sub $2,r4 288 ;mov r1,0f+2 289 ;tst (r5)+ 290 291 ; [sp] = argument 2 = file name 292 ; cx = user number 293 ; (<= 255 for current Retro UNIX version) 294 295 ;sub dword [argc], 2 296 0000007E 802E[8003]02 sub byte [argc], 2 297 chown_10: 298 ;1: 299 ;mov (r5)+,0f 300 ;sys chown; 0:..; 0 301 ;bec 2f 302 ;mov 0b,r0 303 ;mov r0,0f 304 ;clr 0f+2 305 306 00000083 5E pop si ; argument 2 = file name 307 ; (and argument 3 .. argument 4) 308 ; cx = user number 309 sys _chown, si 79 <1> 80 <1> %if %0 >= 2 81 00000084 89F3 <1> mov bx, %2 82 <1> %if %0 >= 3 83 <1> mov cx, %3 84 <1> %if %0 >= 4 85 <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 00000086 B81000 <1> mov ax, %1 90 00000089 CD20 <1> int 20h 310 0000008B 7325 jnc short chown_13 311 312 0000008D 31C9 xor cx, cx ; 0 313 chown_11: 314 ;3: 315 ;tstb (r0)+ 316 ;beq 3f 317 ;inc 0f+2 318 ;br 3b 319 320 ; strlen (calculating file name length) 321 0000008F FEC9 dec cl ; max. 255 bytes (may be 64 to 70) 322 00000091 89F7 mov di, si ; file name address 323 00000093 28C0 sub al, al ; 0 324 00000095 F2AE repne scasb 325 ; do: 326 ; and cx cx 327 ; jz short dont 328 ; cmp [di], al 329 ; jne short dont 330 ; inc di 331 ; dec cx 332 ; jmp short do 333 ; dont: 334 00000097 29F7 sub di, si 335 00000099 4F dec di ; 30/04/2022 336 ; di = file name length 337 chown_12: 338 ;3: 339 ;mov $1,r0 340 ;sys write; 0:..; .. 341 ;jsr r5,mesg; ; .even 342 343 ; 30/04/2022 344 0000009A B8[3401] mov ax, nextline 345 0000009D E81A00 call print_msg 346 347 sys _write, 1, si, di 79 <1> 80 <1> %if %0 >= 2 81 000000A0 BB0100 <1> mov bx, %2 82 <1> %if %0 >= 3 83 000000A3 89F1 <1> mov cx, %3 84 <1> %if %0 >= 4 85 000000A5 89FA <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 000000A7 B80400 <1> mov ax, %1 90 000000AA CD20 <1> int 20h 348 000000AC B8[3201] mov ax, qu_msg 349 000000AF E80800 call print_msg 350 351 chown_13: 352 ;2: 353 ;dec r4 354 ;bgt 1b 355 ;sys exit 356 357 ;dec word [argc] 358 000000B2 FE0E[8003] dec byte [argc] 359 000000B6 7FCB jg short chown_10 360 000000B8 EB8F jmp closefile_and_exit 361 362 print_msg: 363 ; 30/04/2022 364 ; (32 -> 16 bit buffer and register size 365 ; modifications for Retro UNIX 8086 v1) 366 ; 29/04/2022 367 ; Modified registers: ax, bx, cx, dx 368 strlen: 369 ; ax = asciiz string address 370 000000BA 89C3 mov bx, ax 371 000000BC 4B dec bx 372 nextchr: 373 000000BD 43 inc bx 374 000000BE 803F00 cmp byte [bx], 0 375 000000C1 77FA ja short nextchr 376 ;cmp [bx], 0Dh 377 ;ja short nextchr 378 000000C3 29C3 sub bx, ax 379 ; bx = asciiz string length 380 ;retn 381 print_str: 382 000000C5 89DA mov dx, bx 383 sys _write, 1, ax 79 <1> 80 <1> %if %0 >= 2 81 000000C7 BB0100 <1> mov bx, %2 82 <1> %if %0 >= 3 83 000000CA 89C1 <1> mov cx, %3 84 <1> %if %0 >= 4 85 <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 000000CC B80400 <1> mov ax, %1 90 000000CF CD20 <1> int 20h 384 ; 385 000000D1 C3 retn 386 387 cvnum: 388 ; 30/04/2022 389 ; (32 -> 16 bit buffer and register size 390 ; modifications for Retro UNIX 8086 v1) 391 ; 30/04/2022 392 ; 29/04/2022 393 394 ;clr r1 395 396 ; INPUT: 397 ; bx = getc address (*) 398 ; or geta address (**) 399 ; OUTPUT: 400 ; cx = (user) number 401 402 ; Modified registers: cx, ax, dx, bx 403 ; and.. si (**) or bp (*) 404 405 000000D2 31C9 xor cx, cx ; 0 406 000000D4 891E[7801] mov [function], bx 407 cvn_1: 408 ;1: 409 ;jsr r5,*(r5); ubuf 410 ;bcs 1f 411 ;sub $'0,r0 412 ;cmp r0,$9. 413 ;bhi 1f 414 ;mpy $10.,r1 415 ;add r0,r1 416 ;br 1b 417 418 000000D8 FF16[7801] call word [function] ; 30/04/2022 419 000000DC 7211 jc short cvn_2 420 ; al = 0 421 000000DE 2C30 sub al, '0' ; AL-30h 422 ;jb short cvn_2 423 ; AL-30h > 9 for AL values less than 30h 424 000000E0 3C09 cmp al, 9 425 000000E2 770B ja short cvn_2 426 000000E4 50 push ax 427 000000E5 B80A00 mov ax, 10 428 000000E8 F7E1 mul cx 429 000000EA 59 pop cx 430 000000EB 01C1 add cx, ax 431 000000ED EBE9 jmp short cvn_1 432 cvn_2: 433 ;1: 434 ;tst (r5)+ 435 ;rts r5 436 437 000000EF C3 retn 438 geta: 439 ;movb (r3)+,r0 440 ;tst (r5)+ 441 ;rts r5 442 443 000000F0 AC lodsb ; mov al, [si] .. inc si 444 000000F1 C3 retn 445 446 getc: 447 ; 30/04/2022 448 ; (32 -> 16 bit buffer and register size 449 ; modifications for Retro UNIX 8086 v1) 450 ; 30/04/2022 451 ; 29/04/2022 452 453 ; INPUT: 454 ; ubuf = read buffer (header) address 455 ; OUTPUT: 456 ; al = character (if cf=0) 457 ; (if cf = 1 -> read error) 458 459 ; Modified registers: ax, bx, cx, dx, bp 460 461 000000F2 BD[7A01] mov bp, ubuf 462 000000F5 8B4602 mov ax, [bp+2] ; char count 463 ;and ax, ax 464 000000F8 21C0 and ax, ax 465 000000FA 751A jnz short gch1 466 gch0: 467 000000FC 8B5E00 mov bx, [bp] 468 000000FF B9[8001] mov cx, ubuf+6 ; read buff. (data) addr. 469 00000102 894E04 mov [bp+4], cx ; char offset 470 ;mov [bp+2], ax ; 0 471 00000105 29D2 sub dx, dx 472 00000107 B602 mov dh, 2 473 ;mov dx, 512 474 sys _read ; sys _read, bx, cx, dx 79 <1> 80 <1> %if %0 >= 2 81 <1> mov bx, %2 82 <1> %if %0 >= 3 83 <1> mov cx, %3 84 <1> %if %0 >= 4 85 <1> mov dx, %4 86 <1> %endif 87 <1> %endif 88 <1> %endif 89 00000109 B80300 <1> mov ax, %1 90 0000010C CD20 <1> int 20h 475 0000010E 7215 jc short gch2 476 00000110 09C0 or ax, ax 477 ;jz short gch3 478 00000112 7502 jnz short gch1 479 ; 480 00000114 F9 stc 481 00000115 C3 retn 482 gch1: 483 00000116 48 dec ax 484 00000117 894602 mov [bp+2], ax 485 0000011A 8B5E04 mov bx, [bp+4] 486 0000011D 30E4 xor ah, ah 487 0000011F 8A07 mov al, [bx] 488 00000121 43 inc bx 489 00000122 895E04 mov [bp+4], bx 490 ;retn 491 gch2: 492 ;xor ax, ax 493 00000125 C3 retn 494 ;gch3: 495 ;stc 496 ;retn 497 498 ; 499 ;uids: 500 ; 501 ; .bss 502 ;ubuf: .=.+518. 503 504 ;----------------------------------------------------------------- 505 ; data - initialized data 506 ;----------------------------------------------------------------- 507 508 ;align 4 509 510 00000126 2F6574632F70617373- uids: db "/etc/passwd", 0 ; password file (contains user IDs) 510 0000012F 776400 511 512 qu_msg: ; 513 514 00000132 203F db " ?" 515 nextline: 516 00000134 0D0A00 db 0Dh, 0Ah, 0 517 518 usage_msg: 519 00000137 0D0A db 0Dh, 0Ah 520 00000139 55736167653A206368- db "Usage: chown uid f1 ...", 0Dh, 0Ah, 0 520 00000142 6F776E207569642066- 520 0000014B 31202E2E2E0D0A00 521 cant_open_msg: 522 00000153 0D0A db 0Dh, 0Ah 523 00000155 43616E2774206F7065- db "Can't open /etc/uids", 0Dh, 0Ah, 0 523 0000015E 6E202F6574632F7569- 523 00000167 64730D0A00 524 who_msg: 525 0000016C 202D2057686F203F20- db " - Who ? ", 0Dh, 0Ah, 0 525 00000175 0D0A00 526 527 ;----------------------------------------------------------------- 528 ; bss - uninitialized data 529 ;----------------------------------------------------------------- 530 531 align 4 532 533 bss_start: 534 535 ABSOLUTE bss_start 536 537 ; 30/04/2022 (Size modifications for Retro UNIX 8086 v1) 538 539 function: 540 00000178 ???? resw 1 ; (is used by 'cvnum') 541 542 0000017A ???????????? ubuf: resb 6 ; Buffer header 543 ; word - file descriptor 544 ; word - character count 545 ; word - character offset 546 00000180 resb 512 ; Buffer data 547 548 ;argc: resw 1 549 00000380 ?? argc: resb 1 ; argument count 550 551 ; 29/04/2022 552 553 ;----------------------------------------------------------------- 554 ; Original UNIX v2 - /bin/chown source code (chown.s) 555 ; in PDP-11 (unix) assembly language 556 ;----------------------------------------------------------------- 557 ; 558 ;/ chown -- change owner 559 ; 560 ; 561 ; .globl fopen, getc, mesg 562 ; 563 ; mov sp,r5 564 ; mov (r5),r4 565 ; cmp r4,$3 566 ; bge 1f 567 ; jsr r5,mesg; ; .even 568 ;1: 569 ; add $4,r5 570 ; mov (r5),r3 571 ; cmpb (r3),$'0 572 ; blt 1f 573 ; cmpb (r3),$'9 574 ; bgt 1f 575 ; jsr r5,cvnum; geta 576 ; br do 577 ;1: 578 ; mov $uids,r0 579 ; jsr r5,fopen; ubuf 580 ; bec 1f 581 ; jsr r5,mesg; ; .even 582 ; sys exit 583 ;1: 584 ; mov r3,r2 585 ;2: 586 ; jsr r5,getc; ubuf 587 ; bcc 3f 588 ;who: 589 ; jsr r5,mesg; ; .even 590 ; sys exit 591 ;3: 592 ; cmp r0,$': 593 ; beq 3f 594 ; cmpb (r2)+,r0 595 ; beq 2b 596 ;2: 597 ; jsr r5,getc; ubuf 598 ; bcs who 599 ; cmp r0,$'\n 600 ; bne 2b 601 ; br 1b 602 ;3: 603 ; tstb (r2) 604 ; bne 2b 605 ;3: 606 ; jsr r5,getc; ubuf 607 ; cmpb r0,$': 608 ; bne 3b 609 ; jsr r5,cvnum; getc 610 ;do: 611 ; sub $2,r4 612 ; mov r1,0f+2 613 ; tst (r5)+ 614 ;1: 615 ; mov (r5)+,0f 616 ; sys chown; 0:..; 0 617 ; bec 2f 618 ; mov 0b,r0 619 ; mov r0,0f 620 ; clr 0f+2 621 ;3: 622 ; tstb (r0)+ 623 ; beq 3f 624 ; inc 0f+2 625 ; br 3b 626 ;3: 627 ; mov $1,r0 628 ; sys write; 0:..; .. 629 ; jsr r5,mesg; ; .even 630 ;2: 631 ; dec r4 632 ; bgt 1b 633 ; sys exit 634 ; 635 ;cvnum: 636 ; clr r1 637 ;1: 638 ; jsr r5,*(r5); ubuf 639 ; bcs 1f 640 ; sub $'0,r0 641 ; cmp r0,$9. 642 ; bhi 1f 643 ; mpy $10.,r1 644 ; add r0,r1 645 ; br 1b 646 ;1: 647 ; tst (r5)+ 648 ; rts r5 649 ; 650 ;geta: 651 ; movb (r3)+,r0 652 ; tst (r5)+ 653 ; rts r5 654 ; 655 ;uids: 656 ; 657 ; .bss 658 ;ubuf: .=.+518.