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