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