     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) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    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; <chown uid f1 ...\n\0>; .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; <Can't open /etc/uids\n\0>; .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; <Who?\n\0>; .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; <?\n\0>; .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:	</etc/passwd\0>
   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:	; <?\n>
   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<rep 3h>              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 <res 200h>              	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; <chown uid f1 ...\n\0>; .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; <Can't open /etc/uids\n\0>; .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; <Who?\n\0>; .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; <?\n\0>; .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:	</etc/passwd\0>
   610                                  ;
   611                                  ;	.bss
   612                                  ;ubuf:	.=.+518.
