     1                                  ; ****************************************************************************
     2                                  ; mv8086.s (mv0.s) - by Erdogan Tan - 22/05/2022
     3                                  ; ----------------------------------------------------------------------------
     4                                  ; Retro UNIX 8086 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 mv0.s -l mv0.txt -o mv0 -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                                  %macro sys 1-4
    91                                      ; Retro UNIX 8086 v1 system call.
    92                                      %if %0 >= 2   
    93                                          mov bx, %2
    94                                          %if %0 >= 3
    95                                              mov cx, %3
    96                                              %if %0 >= 4
    97                                                 mov dx, %4
    98                                              %endif
    99                                          %endif
   100                                      %endif
   101                                      mov ax, %1
   102                                      int 20h
   103                                  %endmacro
   104                                  
   105                                  ;; Retro UNIX 386 v1 system call format:
   106                                  ;; sys systemcall (eax) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
   107                                  
   108                                  ;; 11/03/2022
   109                                  ;; Note: Above 'sys' macro has limitation about register positions;
   110                                  ;;	ebx, ecx, edx registers must not be used after their
   111                                  ;;	positions in sys macro.
   112                                  ;; for example:
   113                                  ;;	'sys _write, 1, msg, ecx' is defective, because
   114                                  ;;	 ecx will be used/assigned before edx in 'sys' macro.
   115                                  ;; correct order may be:
   116                                  ;;	'sys _write, 1, msg, eax ; (eax = byte count)
   117                                  
   118                                  ; Retro UNIX 8086 v1 system call format:
   119                                  ; sys systemcall (ax) <arg1 (bx)>, <arg2 (cx)>, <arg3 (dx)>
   120                                  
   121                                  struc stat
   122                                  	; Note: This is for Retro UNIX v1 'sysstat' output !!!
   123                                  	; (34 bytes)
   124 00000000 ????                    	.inode:  resw 1	
   125 00000002 ????                    	.mode:	 resw 1
   126 00000004 ??                      	.nlinks: resb 1
   127 00000005 ??                      	.uid:	 resb 1
   128 00000006 ????                    	.size:	 resw 1
   129 00000008 <res 10h>               	.dskptr: resw 8
   130 00000018 ????????                	.ctime:	 resd 1
   131 0000001C ????????                	.mtime:	 resd 1
   132 00000020 ????                    	.rsvd:   resw 1
   133                                  	.strucsize:
   134                                  endstruc 
   135                                  
   136                                  ;struc stat
   137                                  ;	; Note: This is for Retro UNIX v1.2 'sysstat' output !!!
   138                                  ;	; (66 bytes)
   139                                  ;	.inode:  resw 1	
   140                                  ;	.mode:	 resw 1
   141                                  ;	.nlinks: resw 1 
   142                                  ;	.uid:	 resw 1
   143                                  ;	.gid:	 resb 1
   144                                  ;	.size_h: resb 1
   145                                  ;	.size:	 resd 1
   146                                  ;	.dskptr: resd 10
   147                                  ;	.atime:	 resd 1
   148                                  ;	.mtime:	 resd 1
   149                                  ;	.ctime:  resd 1
   150                                  ;	.strucsize:
   151                                  ;endstruc   
   152                                  
   153                                  ;;struc stat
   154                                  ;;	; Note: Retro UNIX v2 'sysstat' output DRAFT !!!
   155                                  ;;	; (72 bytes)
   156                                  ;;	.idev:	 resb 1
   157                                  ;;	.rsvd:	 resb 3
   158                                  ;;	.inum:   resd 1	
   159                                  ;;	.mode:	 resw 1
   160                                  ;;	.nlinks: resw 1 
   161                                  ;;	.uid:	 resw 1
   162                                  ;;	.gid:	 resb 1
   163                                  ;;	.size_h: resb 1
   164                                  ;;	.size:	 resd 1
   165                                  ;;	.dskptr: resd 10
   166                                  ;;	.atime:	 resd 1
   167                                  ;;	.mtime:	 resd 1
   168                                  ;;	.ctime:  resd 1
   169                                  ;;	.strucsize:
   170                                  ;;endstruc 
   171                                  
   172                                  ;S_IFMT   equ 0F000h ; /* type of file */
   173                                  ;S_IFDIR  equ 04000h ; /* directory */
   174                                  ;S_IFCHR  equ 02000h ; /* character special */
   175                                  ;S_IFBLK  equ 06000h ; /* block special */
   176                                  ;S_IFREG  equ 08000h ; /* regular */
   177                                  ;S_ISUID  equ 00800h ; /* set user id on execution */
   178                                  ;S_ISGID  equ 00400h ; /* set group id on execution */
   179                                  ;S_IREAD  equ 00100h ; /* read permission, owner */
   180                                  ;S_IWRITE equ 00080h ; /* write permission, owner */
   181                                  ;S_IEXEC  equ 00040h ; /* execute/search permission, owner */
   182                                  
   183                                  S_IFMT   equ 0F0h ; /* type of file */
   184                                  S_IFDIR  equ 040h ; /* directory */
   185                                  S_IFCHR  equ 020h ; /* character special */
   186                                  S_IFBLK  equ 060h ; /* block special */
   187                                  S_IFREG  equ 080h ; /* regular */
   188                                  S_ISUID  equ 008h ; /* set user id on execution */
   189                                  S_ISGID  equ 004h ; /* set group id on execution */
   190                                  S_IREAD  equ 001h ; /* read permission, owner */
   191                                  S_IWRITE equ 080h ; /* write permission, owner */
   192                                  S_IEXEC  equ 040h ; /* execute/search permission, owner */
   193                                  
   194                                  ;; UNIX v1 inode
   195                                  ;; byte 1
   196                                  ;S_ALLOC  equ 080h ; Allocated flag
   197                                  ;S_IFDIR  equ 040h ; Directory flag
   198                                  ;S_IFMDF  equ 020h ; File modified flag (always on)
   199                                  ;S_IFLRG  equ 010h ; Large File flag
   200                                  ;; byte 0
   201                                  ;S_ISUID  equ 020h ; Set User ID On Execution flag
   202                                  ;S_IEXEC  equ 010h ; Executable File flag
   203                                  ;S_IREAD  equ 008h ; Owner's Read Permission flag
   204                                  ;S_IWRITE equ 004h ; Owner's Write Permission flag
   205                                  
   206                                  ;%define DOT "."
   207                                  ;%define DOTDOT ".."
   208                                  %define DELIM '/'
   209                                  ;%define SDELIM "/"
   210                                  MODEBITS equ 11111b ; Retro UNIX v1
   211                                  ;MODEBITS equ 111111111b ; Retro UNIX v1.2 (v2)
   212                                  ROOTINO equ 41 ; Retro UNIX v1
   213                                  ;ROOTINO equ 1 ; Retro UNIX v1.2 (v2)
   214                                  
   215                                  STDIN equ 0
   216                                  ; 23/05/2022
   217                                  MAXN equ 112
   218                                  
   219                                  ;-----------------------------------------------------------------
   220                                  ;  text - code
   221                                  ;-----------------------------------------------------------------
   222                                  
   223                                  [BITS 16] ; 16-bit intructions (for 8086 real mode)
   224                                  
   225                                  [ORG 0] 
   226                                  
   227                                  START_CODE:
   228                                  	; 27/05/2022
   229                                  	; (32 bit to 16 bit conversions for Retro UNIX 8086 v1)
   230                                  	; 27/05/2022
   231                                  	; 26/05/2022
   232                                  	; 24/05/2022
   233                                  	; 23/05/2022
   234                                  	; 22/05/2022
   235 00000000 58                      	pop	ax ; number of arguments
   236 00000001 5A                      	pop	dx ; argv[0]	gg
   237                                  	;mov	[argc], ax
   238 00000002 A2[4B06]                	mov	[argc], al
   239                                  
   240                                  	;cmp	ax, 3
   241 00000005 3C03                    	cmp	al, 3
   242 00000007 730F                    	jnb	short mv_0
   243 00000009 FEC8                    	dec	al
   244 0000000B 7506                    	jnz	short mv_usage
   245                                  	;sys	_msg, program_msg, 255, 0Fh
   246                                  	; 27/05/2022 (Retro UNIX 8086 v1)
   247 0000000D B8[6006]                	mov	ax, program_msg
   248 00000010 E82006                  	call	print_msg
   249                                  mv_usage:
   250                                  	;sys	_msg, usage_msg, 255, 07h
   251 00000013 B8[9806]                	mov	ax, usage_msg
   252                                  	;call	print_msg
   253 00000016 EB1B                    	jmp	print_exit ; 24/05/2022
   254                                  ;mv_exit:
   255                                  ;	sys	_exit	; sys exit
   256                                  ;;hlt:
   257                                  ;;	nop
   258                                  ;;	nop
   259                                  ;;	jmp	short hlt
   260                                  
   261                                  mv_0:
   262 00000018 5F                      	pop	di ; argv[1]
   263                                  
   264                                  	; 26/05/2022
   265                                  	sys	_stat, di, st1buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000019 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000001B B9[1009]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000001E B81200              <1>  mov ax, %1
   102 00000021 CD20                <1>  int 20h
   266 00000023 731E                    	jnc	short mv_1
   267                                  
   268 00000025 B8[FA06]                	mov	ax, msg_cant_access
   269                                  	; 24/05/2022
   270 00000028 E80806                  	call	print_msg
   271 0000002B 89F8                    	mov	ax, di  ; argv[1]
   272 0000002D E80306                  	call	print_msg
   273 00000030 B8[CA06]                	mov	ax, nextline
   274                                  print_exit:
   275 00000033 E8FD05                  	call	print_msg
   276                                  _exit_:
   277                                  	sys	_exit
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93                              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000036 B80100              <1>  mov ax, %1
   102 00000039 CD20                <1>  int 20h
   278                                  
   279                                  hang_em_high:
   280 0000003B 90                      	nop
   281 0000003C EBFD                    	jmp	short hang_em_high
   282                                  
   283                                  mv_61:
   284 0000003E B8[0109]                	mov	ax, msg_ok
   285 00000041 EBF0                    	jmp	short print_exit
   286                                  
   287                                  mv_1:
   288                                  	; Retro UNIX 386 v1.2
   289                                  	;mov	[st1dev], eax
   290                                  	;mov	al, byte [st1buf+stat.mode+1]
   291                                  	;and	al, S_IFREG|S_IFDIR
   292                                  	;cmp	al, S_IFREG|S_IFDIR
   293                                  	;jne	short mv_2
   294                                  	
   295                                  	; Retro UNIX 386 v1
   296                                  	;mov	[st1dev], ax ; device number
   297                                  			     ; (0 = root fs)
   298                                  			     ; (1 = mounted fs)
   299 00000043 F606[1309]40            	test	byte [st1buf+stat.mode+1], S_IFDIR
   300 00000048 740F                    	jz	short mv_2
   301                                  
   302 0000004A 803E[4B06]03            	cmp	byte [argc], 3
   303 0000004F 75C2                    	jne	short mv_usage
   304                                  
   305 00000051 5D                      	pop	bp ; argv[2]
   306                                  
   307 00000052 E8F001                  	call	mvdir
   308 00000055 73E7                    	jnc	short mv_61 ; "OK."
   309 00000057 EBDD                    	jmp	short _exit_
   310                                  
   311                                  mv_2:
   312                                  	;setuid(getuid());
   313                                  	sys	_getuid
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93                              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000059 B81800              <1>  mov ax, %1
   102 0000005C CD20                <1>  int 20h
   314                                  	sys	_setuid, ax
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000005E 89C3                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000060 B81700              <1>  mov ax, %1
   102 00000063 CD20                <1>  int 20h
   315 00000065 7305                    	jnc	short mv_3
   316                                  
   317                                  	; error (permission denied)
   318 00000067 B8[F508]                	mov	ax, err_msg
   319 0000006A EBC7                    	jmp	short print_exit
   320                                  mv_3:
   321                                  	; (here [sp] = argv[2]) 
   322 0000006C A0[4B06]                	mov	al, [argc]
   323                                  	;dec	al  ; (if [argc] = 3 then al = 2)
   324                                  	;mov	cl, 2 
   325                                  	;sub	al, cl  ; argv[0], argv[1]
   326 0000006F 2C03                    	sub	al, 3
   327 00000071 D1E0                    	shl	ax, 1 ; * 2
   328 00000073 89E5                    	mov	bp, sp
   329 00000075 01C5                    	add	bp, ax
   330                                  	; bp = argv[argc-1]
   331                                  	;mov	[target], bp
   332                                  
   333                                  	; 26/05/2022
   334 00000077 8B6E00                  	mov	bp, [bp]
   335                                  
   336                                  	; 24/05/2022
   337                                  	;cmp	byte [argc], 3
   338 0000007A 802E[4B06]02            	sub	byte [argc], 2
   339 0000007F 803E[4B06]01            	cmp	byte [argc], 1
   340 00000084 7616                    	jna	short mv_6
   341                                  
   342                                  	; (target must a -valid- directory)
   343                                  
   344                                  	sys	_stat, bp, st2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000086 89EB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000088 B9[3409]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000008B B81200              <1>  mov ax, %1
   102 0000008E CD20                <1>  int 20h
   345 00000090 7303                    	jnc	short mv_5
   346                                  mv_4:
   347 00000092 E97EFF                  	jmp	mv_usage
   348                                  mv_5:	
   349                                  	; Retro UNIX 386 v1.2
   350                                  	;mov	[st2dev], eax
   351                                  	;mov	al, byte [st2buf+stat.mode+1]
   352                                  	;and	al, S_IFREG|S_IFDIR
   353                                  	;cmp	al, S_IFREG|S_IFDIR
   354                                  	;jne	short mv_4
   355                                  	
   356                                  	; Retro UNIX 386 v1
   357                                  	;mov	[st2dev], ax ; device number
   358                                  			     ; (0 = root fs)
   359                                  			     ; (1 = mounted fs)
   360 00000095 F606[3709]40            	test	byte [st2buf+stat.mode+1], S_IFDIR
   361 0000009A 74F6                    	jz	short mv_4
   362                                  
   363                                  	; 26/05/2022
   364                                  	;sub	byte [argc], 2 ; [argc] >= 1
   365                                  	;	; i = 1
   366                                  mv_6:	
   367                                  	; di = argv[i] 
   368                                  	; bp = argv[argc-1]
   369 0000009C E81F00                  	call	move
   370 0000009F 7304                    	jnc	short mv_7
   371 000000A1 FE06[4C06]              	inc	byte [errors]
   372                                  mv_7:
   373 000000A5 FE0E[4B06]              	dec	byte [argc] ; i++
   374 000000A9 7403                    	jz	short mv_8
   375                                  		    ; i < argc-1
   376 000000AB 5F                      	pop	di ; argv[i]
   377 000000AC EBEE                    	jmp	short mv_6
   378                                  mv_8:
   379 000000AE 803E[4C06]00            	cmp	byte [errors], 0
   380 000000B3 7706                    	ja	short mv_9
   381                                  
   382 000000B5 B8[0109]                	mov	ax, msg_ok
   383                                  	;jmp	print_exit
   384 000000B8 E87805                  	call	print_msg
   385                                  mv_9:
   386 000000BB E978FF                  	jmp	_exit_
   387                                  
   388                                  ;-----------------------------------------------------------------
   389                                  
   390                                  move:
   391                                  	; 27/05/2022
   392                                  	; 26/05/2022
   393                                  	; 24/05/2022
   394                                  	; 22/05/2022
   395                                  
   396                                  	; move(source, target)
   397                                  
   398                                  	; INPUT:
   399                                  	;	di = source
   400                                  	;	bp = target
   401                                  	; OUTPUT:
   402                                  	;	cf = 0 -> ok
   403                                  	;	cf = 1 -> error
   404                                  
   405                                  	; if (stat(source, &s1) < 0)
   406                                  	sys	_stat, di, st1buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000000BE 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000000C0 B9[1009]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000000C3 B81200              <1>  mov ax, %1
   102 000000C6 CD20                <1>  int 20h
   407 000000C8 7313                    	jnc	short mv_10
   408                                  
   409 000000CA B8[FA06]                	mov	ax, msg_cant_access
   410                                  	; 24/05/2022
   411 000000CD E86305                  	call	print_msg
   412 000000D0 89F8                    	mov	ax, di ; source
   413 000000D2 E85E05                  	call	print_msg
   414 000000D5 B8[CA06]                	mov	ax, nextline
   415                                  move_err:
   416 000000D8 E85805                  	call	print_msg
   417 000000DB F9                      	stc
   418 000000DC C3                      	retn
   419                                  mv_10:
   420                                  	; Retro UNIX 386 v1.2
   421                                  	;mov	[st1dev], eax
   422                                  	;mov	al, byte [st1buf+stat.mode+1]
   423                                  	;and	al, S_IFREG|S_IFDIR
   424                                  	;cmp	al, S_IFREG|S_IFDIR
   425                                  	;jne	short mv_11
   426                                  
   427                                  	; Retro UNIX 386 v1 (& v1.1)
   428 000000DD A3[0E09]                	mov	[st1dev], ax ; device number
   429                                  			     ; (0 = root fs)
   430                                  			     ; (1 = mounted fs)
   431                                  
   432                                  	; if ((s1.st_mode & S_IFMT) == S_IFDIR)
   433 000000E0 F606[1309]40            	test	byte [st1buf+stat.mode+1], S_IFDIR
   434 000000E5 7405                    	jz	short mv_11
   435                                  
   436 000000E7 B8[0F07]                	mov	ax, msg_rename_only
   437 000000EA EBEC                    	jmp	short move_err
   438                                  mv_11:
   439                                  	; 26/05/2022
   440 000000EC 892E[0C09]              	mov	[target], bp
   441                                  
   442                                  	; if (stat(target, &s2) >= 0)
   443                                  	sys	_stat, bp, st2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000000F0 89EB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000000F2 B9[3409]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000000F5 B81200              <1>  mov ax, %1
   102 000000F8 CD20                <1>  int 20h
   444                                  	;jc	short mv_19
   445                                  	; 23/05/2022
   446 000000FA 7303                    	jnc	short mv_12
   447 000000FC E9CF00                  	jmp	mv_19
   448                                  mv_12:
   449                                  	; Retro UNIX 386 v1.2
   450                                  	;mov	[st2dev], eax
   451                                  	;mov	al, byte [st2buf+stat.mode+1]
   452                                  	;and	al, S_IFREG|S_IFDIR
   453                                  	;cmp	al, S_IFREG|S_IFDIR
   454                                  	;jne	short mv_14
   455                                  
   456                                  	; Retro UNIX 386 v1 (& v1.1)
   457 000000FF A3[3209]                	mov	[st2dev], ax ; device number
   458                                  			     ; (0 = root fs)
   459                                  			     ; (1 = mounted fs)
   460                                  
   461                                  	; if ((s2.st_mode & S_IFMT) == S_IFDIR)
   462 00000102 F606[3709]40            	test	byte [st2buf+stat.mode+1], S_IFDIR
   463 00000107 742E                    	jz	short mv_14
   464                                  
   465                                  	; sprintf(buf, "%s/%s", target, dname(source));
   466                                  
   467                                  ;	mov	si, bp ; target
   468                                  ;	mov	bx, di ; source
   469                                  ;	mov	dx, bx ; source 
   470                                  ;	mov	di, buf ; pathname buffer (100 bytes)
   471                                  ;	mov	[target], di
   472                                  ;mv_12:
   473                                  ;	lodsb
   474                                  ;	or	al, al
   475                                  ;	jz	short mv_13
   476                                  ;	stosb
   477                                  ;	jmp	short mv_12
   478                                  ;		
   479                                  ;mv_13:
   480                                  ;	mov	al, DELIM ; '/'
   481                                  ;	stosb
   482                                  ;	
   483                                  ;	; dx = source (pathname)
   484                                  ;	; di = buffer (offset) position
   485                                  ;	call	dname
   486                                  ;	mov	di, bx ; source
   487                                  ;			 ; target = buf;
   488                                  	; 22/05/2022
   489 00000109 E87A03                  	call	strcpy ; 27/05/2022
   490                                  
   491                                  	;if (stat(target, &s2) >= 0)
   492                                  
   493                                  	sys	_stat, buf, st2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000010C BB[5609]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000010F B9[3409]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000112 B81200              <1>  mov ax, %1
   102 00000115 CD20                <1>  int 20h
   494                                  	;jc	short mv_20 ; 26/05/2022
   495                                  	; 26/05/2022
   496 00000117 7303                    	jnc	short mv_13
   497 00000119 E9B200                  	jmp	mv_20
   498                                  mv_13:
   499                                  	; Retro UNIX 386 v1.2
   500                                  	;mov	[st2dev], eax
   501                                  	;mov	al, byte [st2buf+stat.mode+1]
   502                                  	;and	al, S_IFREG|S_IFDIR
   503                                  	;cmp	al, S_IFREG|S_IFDIR
   504                                  	;jne	short mv_14
   505                                  
   506                                  	; Retro UNIX 386 v1 (& v1.1)
   507 0000011C A3[3209]                	mov	[st2dev], ax ; device number
   508                                  			     ; (0 = root fs)
   509                                  			     ; (1 = mounted fs)
   510                                  
   511                                  	; if ((s2.st_mode & S_IFMT) == S_IFDIR)
   512 0000011F F606[3709]40            	test	byte [st2buf+stat.mode+1], S_IFDIR
   513 00000124 7411                    	jz	short mv_14
   514                                  
   515                                  	;fprintf(stderr, "mv: %s is a directory\n", target);
   516 00000126 B8[CD06]                	mov	ax, mv_header
   517 00000129 E80705                  	call	print_msg
   518 0000012C B8[5609]                	mov	ax, buf  ; target
   519 0000012F E80105                  	call	print_msg
   520 00000132 B8[E706]                	mov	ax, msg_is_a_dir
   521 00000135 EBA1                    	jmp	move_err
   522                                  
   523                                  mv_14:
   524                                  	; if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino)
   525 00000137 A1[1009]                	mov	ax, [st1buf+stat.inode]
   526 0000013A 3B06[3409]              	cmp	ax, [st2buf+stat.inode]
   527 0000013E 7526                    	jne	short mv_15
   528                                  	; 26/05/2022
   529 00000140 A1[0E09]                	mov	ax, [st1dev]
   530 00000143 3B06[3209]              	cmp	ax, [st2dev]
   531 00000147 751D                    	jne	short mv_15
   532                                  
   533                                  	;fprintf(stderr, "mv: %s and %s are identical\n",
   534                                  	;		source, target);
   535                                  
   536                                  	; di = source
   537                                  	; (buf = target or) [target] = target
   538                                  
   539 00000149 B8[CD06]                	mov	ax, mv_header
   540 0000014C E8E404                  	call	print_msg
   541 0000014F 89F8                    	mov	ax, di ; source
   542 00000151 E8DF04                  	call	print_msg
   543 00000154 B8[7E08]                	mov	ax, msg_and
   544 00000157 E8D904                  	call	print_msg
   545 0000015A A1[0C09]                	mov	ax, [target] ; target ; 26/05/2022
   546 0000015D E8D304                  	call	print_msg
   547 00000160 B8[8408]                	mov	ax, msg_identical
   548 00000163 E972FF                  	jmp	move_err
   549                                  
   550                                  mv_15:
   551                                  	; if (access(target, 2) < 0 && isatty(fileno(stdin)))
   552 00000166 BE[3409]                	mov	si, st2buf
   553 00000169 E83304                  	call	access
   554 0000016C 7544                    	jnz	short mv_18
   555                                  	; not permitted
   556                                  
   557 0000016E E84404                  	call	isatty
   558 00000171 723F                    	jc	short mv_18 ; not a tty
   559                                  	
   560                                  	;fprintf(stderr, "mv: %s: %o mode ", target,
   561                                  	;			s2.st_mode & MODEBITS);
   562                                  
   563 00000173 B8[CD06]                	mov	ax, mv_header
   564 00000176 E8BA04                  	call	print_msg
   565 00000179 A1[0C09]                	mov	ax, [target] ; target ; 26/05/2022
   566 0000017C E8B404                  	call	print_msg
   567 0000017F 8B1E[3609]              	mov	bx, [st2buf+stat.mode]
   568 00000183 83E31F                  	and	bx, MODEBITS
   569 00000186 BE[F90A]                	mov	si, octm 
   570 00000189 E84704                  	call	octalnumber
   571                                  	; 27/05/2022
   572                                  	;mov	ax, octm
   573 0000018C C606[F80A]20            	mov	byte [octms], 20h
   574 00000191 B8[F80A]                	mov	ax, octms
   575 00000194 E89C04                  	call	print_msg
   576 00000197 B8[D708]                	mov	ax, msg_mode
   577 0000019A E89604                  	call	print_msg	
   578                                  
   579                                  	; i = c = getchar();
   580 0000019D E86604                  	call	getchar
   581                                  	
   582 000001A0 3C79                    	cmp	al, 'y'
   583 000001A2 7408                    	je	short mv_17
   584                                  
   585 000001A4 B8[EE08]                	mov	ax, msg_no
   586                                  mv_16:
   587 000001A7 E88904                  	call	print_msg
   588 000001AA F9                      	stc
   589 000001AB C3                      	retn
   590                                  mv_17:
   591 000001AC B8[E608]                	mov	ax, msg_yes
   592 000001AF E88104                  	call	print_msg
   593                                  mv_18:
   594                                  	; if (unlink(target) < 0)	
   595                                  	sys	_unlink, [target] ; 26/05/2022
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000001B2 8B1E[0C09]          <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000001B6 B80A00              <1>  mov ax, %1
   102 000001B9 CD20                <1>  int 20h
   596 000001BB 7311                    	jnc	short mv_20
   597                                  
   598                                  	; fprintf(stderr, "mv: cannot unlink %s\n", target);
   599 000001BD B8[2D07]                	mov	ax, msg_cant_unlink
   600 000001C0 E87004                  	call	print_msg
   601 000001C3 A1[0C09]                	mov	ax, [target] ; 26/05/2022
   602 000001C6 E86A04                  	call	print_msg
   603 000001C9 B8[CA06]                	mov	ax, nextline 
   604 000001CC EBD9                    	jmp	short mv_16	
   605                                  mv_19:
   606                                  	; 26/05/2022
   607                                  	;mov	[target], bp ; target
   608                                  mv_20:
   609                                  	; if (link(source, target) < 0)
   610                                  
   611                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000001CE 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000001D0 8B0E[0C09]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000001D4 B80900              <1>  mov ax, %1
   102 000001D7 CD20                <1>  int 20h
   612 000001D9 7350                    	jnc	short mv_25
   613                                  
   614 000001DB BB[EA01]                	mov	bx, mv_21  ; child process jump address	
   615                                  	sys	_fork
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93                              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000001DE B80200              <1>  mov ax, %1
   102 000001E1 CD20                <1>  int 20h
   616 000001E3 7320                    	jnc	short mv_22 ; parent return and jump
   617                                  
   618 000001E5 B8[4207]                	mov	ax, msg_try_again
   619 000001E8 EBBD                    	jmp	short mv_16
   620                                  mv_21:
   621                                  	; child process will continue from here
   622                                  	
   623 000001EA A1[0C09]                	mov	ax, [target]
   624 000001ED A3[5906]                	mov	[cp_target], ax
   625 000001F0 893E[5706]              	mov	[cp_source], di
   626                                  
   627                                  	sys	_exec, cp_cmd, cp_args
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000001F4 BB[4D06]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000001F7 B9[5506]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000001FA B80B00              <1>  mov ax, %1
   102 000001FD CD20                <1>  int 20h
   628                                  	
   629                                  	; fprintf(stderr, "mv: cannot exec cp\n");
   630 000001FF B8[5407]                	mov	ax, msg_cant_exec_cp
   631                                  	;call	print_msg
   632                                  	;jmp	_exit_
   633                                  	; 23/05/2022
   634 00000202 E92EFE                  	jmp	print_exit
   635                                  
   636                                  mv_22:
   637 00000205 89C2                    	mov	dx, ax ; child process id
   638                                  mv_23:
   639                                  	; while ((c = wait(&status)) != i && c != -1)
   640                                  	;if (status != 0)
   641                                  	;	return(1);
   642                                  	; utime(target, &s1.st_atime);
   643                                  
   644                                  	sys	_wait
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93                              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000207 B80700              <1>  mov ax, %1
   102 0000020A CD20                <1>  int 20h
   645 0000020C 721C                    	jc	short mv_24
   646                                  
   647 0000020E 39D0                    	cmp	ax, dx
   648 00000210 75F5                     	jne	short mv_23
   649                                  
   650                                  	; 26/05/2022 (check if /bin/cp has been failed) 
   651                                  	sys	_stat, [target], fstbuf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000212 8B1E[0C09]          <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000216 B9[720A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000219 B81200              <1>  mov ax, %1
   102 0000021C CD20                <1>  int 20h
   652 0000021E 720A                    	jc	short mv_24
   653 00000220 A1[780A]                	mov	ax, [fstbuf+stat.size]
   654 00000223 3B06[1609]              	cmp	ax, [st1buf+stat.size]
   655 00000227 7402                    	je	short mv_25
   656 00000229 F9                      	stc
   657                                  mv_24:
   658 0000022A C3                      	retn
   659                                  
   660                                  	; utime(target, &s1.st_atime);
   661                                  
   662                                  	;;;
   663                                  mv_25:
   664                                  	;if (unlink(source) < 0) {
   665                                  	;	fprintf(stderr, "mv: cannot unlink %s\n", source);
   666                                  	;	return(1);
   667                                  	;}
   668                                  
   669                                  	sys	_unlink, di
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000022B 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000022D B80A00              <1>  mov ax, %1
   102 00000230 CD20                <1>  int 20h
   670 00000232 73F6                    	jnc	short mv_24
   671                                  
   672 00000234 B8[2D07]                	mov	ax, msg_cant_unlink
   673 00000237 E8F903                  	call	print_msg
   674 0000023A 89F8                    	mov	ax, di ; source
   675 0000023C E8F403                  	call	print_msg
   676 0000023F B8[CA06]                	mov	ax, nextline	
   677                                  	;if (status != 0)
   678                                  	;	return(1);
   679 00000242 E962FF                  	jmp	mv_16
   680                                  
   681                                  ;-----------------------------------------------------------------
   682                                  
   683                                  mvdir:
   684                                  	; 27/05/2022
   685                                  	; 26/05/2022
   686                                  	; 23/05/2022
   687                                  	; 22/05/2022
   688                                  	
   689                                  	; mvdir(source, target)
   690                                  
   691                                  	; INPUT:
   692                                  	;	di = source
   693                                  	;	bp = target
   694                                  	; OUTPUT:
   695                                  	;	cf = 0 -> ok
   696                                  	;	cf = 1 -> error
   697                                  
   698                                  	; st1buf = source (inode) stat(us) buffer
   699                                  
   700                                  	;if (stat(target, &s2) >= 0) 
   701                                  	sys	_stat, bp, st2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000245 89EB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000247 B9[3409]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000024A B81200              <1>  mov ax, %1
   102 0000024D CD20                <1>  int 20h
   702 0000024F 722D                    	jc	short mv_29
   703                                  
   704                                  	;if ((s2.st_mode&S_IFMT) != S_IFDIR)
   705                                  	
   706                                  	; Retro UNIX 386 v1.2
   707                                  	;mov	[st2dev], eax
   708                                  	;mov	al, byte [st2buf+stat.mode+1]
   709                                  	;and	al, S_IFREG|S_IFDIR
   710                                  	;cmp	al, S_IFREG|S_IFDIR
   711                                  	;je	short mv_28
   712                                  
   713                                  	; Retro UNIX 386 v1 (& v1.1)
   714                                  	;mov	[st2dev], ax ; device number
   715                                  			     ; (0 = root fs)
   716                                  			     ; (1 = mounted fs)
   717                                  
   718                                  	;if ((s2.st_mode & S_IFMT) == S_IFDIR)
   719 00000251 F606[3709]40            	test	byte [st2buf+stat.mode+1], S_IFDIR
   720 00000256 7513                    	jnz	short mv_28
   721                                  
   722                                  	;fprintf(stderr, "mv: %s exists\n", target);
   723                                  
   724 00000258 55                      	push	bp ; target
   725                                  mv_27:
   726 00000259 B8[CD06]                	mov	ax, mv_header
   727 0000025C E8D403                  	call	print_msg	
   728 0000025F 58                      	pop	ax  ; target
   729 00000260 E8D003                  	call	print_msg 
   730 00000263 B8[6B07]                	mov	ax, msg_exists
   731 00000266 E8CA03                  	call	print_msg
   732 00000269 F9                      	stc
   733 0000026A C3                      	retn
   734                                  
   735                                  mv_28:
   736                                  	;if (strlen(target) > MAXN-DIRSIZ-2) {
   737                                  	;	fprintf(stderr, "mv: target name too long\n");
   738                                  	;	return(1);
   739                                  	;}
   740                                  
   741                                  	;strcpy(buf, target);
   742                                  
   743                                  ;	mov	si, bp ; target
   744                                  ;	mov	dx, di ; source
   745                                  ;	mov	di, buf ; pathname buffer (100 bytes)
   746                                  ;	mov	[target], di 
   747                                  ;mv_29:
   748                                  ;	lodsb
   749                                  ;	stosb
   750                                  ;	and	al, al
   751                                  ;	jnz	short mv_29
   752                                  	
   753                                  	;strcat(buf, SDELIM);
   754                                  	;strcat(buf, dname(source));
   755                                  
   756 0000026B E81802                  	call	strcpy ; 27/05/2022
   757                                  
   758                                  	sys	_stat, buf, st2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000026E BB[5609]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000271 B9[3409]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000274 B81200              <1>  mov ax, %1
   102 00000277 CD20                <1>  int 20h
   759 00000279 7207                    	jc	short mv_30
   760                                  
   761 0000027B 53                      	push	bx ; buf ; [target]
   762 0000027C EBDB                    	jmp	short mv_27
   763                                  
   764                                  mv_29:
   765 0000027E 892E[0C09]              	mov	[target], bp
   766                                  mv_30:
   767                                  	; if (strcmp(source, target) == 0) {
   768                                  	
   769 00000282 57                      	push	di
   770 00000283 89FE                    	mov	si, di
   771 00000285 8B3E[0C09]              	mov	di, [target]
   772 00000289 E82302                  	call	strcmp
   773 0000028C 5F                      	pop	di
   774 0000028D 7508                    	jne	short mv_32
   775                                  
   776 0000028F B8[7607]                	mov	ax, msg_src_target
   777                                  mv_31:
   778 00000292 E89E03                  	call	print_msg
   779 00000295 F9                      	stc
   780 00000296 C3                      	retn
   781                                  
   782                                  mv_32:
   783 00000297 89FB                    	mov	bx, di
   784 00000299 BF[720A]                	mov	di, fstbuf ; (66 bytes buffer)
   785 0000029C 53                      	push	bx ; *
   786 0000029D E81A02                  	call	dname
   787                                  	; bx = fstbuf = file name
   788                                  
   789                                  	;!strcmp(p, "")
   790 000002A0 803F00                  	cmp	byte [bx], 0
   791 000002A3 7419                    	je	short mv_33 ; null
   792                                  	;!strcmp(p, DOT)
   793 000002A5 89DE                    	mov	si, bx		
   794 000002A7 803C2E                  	cmp	byte [si], '.'
   795 000002AA 751E                    	jne	short mv_34
   796 000002AC BF[5E06]                	mov	di, DOT
   797 000002AF E8FD01                  	call	strcmp
   798 000002B2 740A                    	je	short mv_33 ; '.'
   799                                  	;!strcmp(p, DOTDOT)
   800 000002B4 89DE                    	mov	si, bx
   801 000002B6 BF[5D06]                	mov	di, DOTDOT
   802 000002B9 E8F301                  	call	strcmp
   803 000002BC 750C                    	jne	short mv_34
   804                                  	; '..'
   805                                  mv_33:
   806 000002BE 5F                      	pop	di ; *
   807                                  	
   808                                  	;fprintf(stderr, "mv: cannot rename %s\n", p);
   809 000002BF B8[5108]                	mov	ax, msg_cant_rename
   810 000002C2 E86E03                  	call	print_msg
   811 000002C5 B8[720A]                	mov	ax, fstbuf
   812 000002C8 EBC8                    	jmp	short mv_31
   813                                  
   814                                  mv_34:
   815 000002CA 5F                      	pop	di ; *
   816 000002CB BB[BA09]                	mov	bx, sbuf
   817                                  	; di = source
   818                                  	; bx = buffer
   819 000002CE E80602                  	call	pname
   820                                  	; si = parent directory name address
   821                                  	;
   822                                  	;if (stat(pname(source), &s1) < 0 ||
   823                                  	sys	_stat, si, pst1buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000002D1 89F3                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000002D3 B9[B40A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000002D6 B81200              <1>  mov ax, %1
   102 000002D9 CD20                <1>  int 20h
   824 000002DB 7305                    	jnc	short mv_36
   825                                  mv_35:
   826 000002DD B8[B307]                	mov	ax, msg_cant_locate
   827 000002E0 EBB0                     	jmp	short mv_31
   828                                  mv_36:
   829 000002E2 A3[0E09]                	mov	[st1dev], ax
   830 000002E5 8B16[0C09]              	mov	dx, [target]
   831 000002E9 87D7                    	xchg	dx, di
   832                                  	;stat(pname(target), &s2) < 0)
   833                                  	; di = source
   834 000002EB BB[160A]                	mov	bx, tbuf ; buffer
   835 000002EE E8E601                  	call	pname
   836                                  	; si = parent directory name address
   837 000002F1 89D7                    	mov	di, dx
   838                                  	sys	_stat, si, pst2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000002F3 89F3                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000002F5 B9[D60A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000002F8 B81200              <1>  mov ax, %1
   102 000002FB CD20                <1>  int 20h
   839 000002FD 72DE                    	jc	short mv_35
   840 000002FF A3[3209]                	mov	[st2dev], ax
   841                                  	;if (access(pname(target), 2) < 0)		
   842 00000302 BE[D60A]                	mov	si, pst2buf
   843 00000305 E89702                  	call	access
   844 00000308 7516                    	jnz	short mv_39
   845                                  	; permission denied !
   846 0000030A BA[160A]                	mov	dx, tbuf ; pname(target)
   847                                  mv_37:
   848 0000030D 52                      	push	dx ; pname(target) or pname(source)
   849 0000030E B8[D007]                	mov	ax, msg_no_w_access
   850 00000311 E81F03                  	call	print_msg
   851 00000314 58                      	pop	ax ; pname(target) or pname(source)
   852 00000315 E81B03                  	call	print_msg
   853 00000318 B8[CA06]                	mov	ax, nextline
   854                                  mv_38:
   855 0000031B E81503                  	call	print_msg
   856 0000031E F9                      	stc
   857 0000031F C3                      	retn
   858                                  mv_39:
   859                                  	;if (access(pname(source), 2) < 0)
   860 00000320 BE[B40A]                	mov	si, pst1buf
   861 00000323 E87902                  	call	access
   862 00000326 7505                    	jnz	short mv_40
   863                                  	; permission denied !
   864 00000328 BA[BA09]                	mov	dx, sbuf ; pname(source)
   865 0000032B EBE0                    	jmp	short mv_37
   866                                  mv_40:
   867                                  	;if (access(source, 2) < 0)
   868                                   	; di = source
   869 0000032D BE[1009]                	mov	si, st1buf 
   870                                  		; source (inode) stat(us) buffer
   871 00000330 E86C02                  	call	access
   872 00000333 7504                    	jnz	short mv_41
   873 00000335 89FA                    	mov	dx, di ; source
   874 00000337 EBD4                    	jmp	short mv_37
   875                                  mv_41:
   876                                  	;if (s1.st_dev != s2.st_dev)
   877 00000339 A1[0E09]                	mov	ax, [st1dev]
   878 0000033C 3B06[3209]              	cmp	ax, [st2dev]
   879 00000340 7405                    	je	short mv_42
   880                                  	;fprintf(stderr, "mv: cannot move directories
   881                                  	;			 across devices\n");
   882 00000342 B8[EA07]                	mov	ax, msg_accross_devices
   883 00000345 EBD4                    	jmp	short mv_38
   884                                  mv_42:
   885                                  	;if (s1.st_ino != s2.st_ino)	
   886 00000347 A1[B40A]                	mov	ax, [pst1buf+stat.inode]
   887 0000034A 3B06[D60A]              	cmp	ax, [pst2buf+stat.inode]
   888 0000034E 7503                    	jne	short mv_43
   889 00000350 E9F400                  	jmp	mv_57
   890                                  mv_43:
   891                                  	; (move dir from parent dir to another dir)
   892                                  
   893                                  	;if (chkdot(source) || chkdot(target))
   894 00000353 89FB                    	mov	bx, di ; source
   895 00000355 E81102                  	call	chkdot
   896 00000358 7305                    	jnc	short mv_45
   897                                  mv_44:
   898                                  	;fprintf(stderr, "mv: Sorry, path names
   899                                  	;	 including %s aren't allowed\n", DOTDOT);
   900 0000035A B8[1908]                	mov	ax, msg_pathname_dotdot
   901 0000035D EBBC                    	jmp	short mv_38
   902                                  mv_45:
   903 0000035F 8B1E[0C09]              	mov	bx, [target] ; target
   904 00000363 E80302                  	call	chkdot
   905 00000366 72F2                    	jc	short mv_44
   906                                  mv_46:
   907                                  	;stat(source, &s1);
   908                                  	;if (check(pname(target), s1.st_ino))
   909 00000368 BB[160A]                	mov	bx, tbuf
   910 0000036B E89A01                  	call	check
   911 0000036E 722B                    	jc	short mv_49 ; return(1);
   912                                  mv_47:		
   913                                  	;for (i = 1; i <= NSIG; i++)
   914                                  	;	signal(i, SIG_IGN);
   915                                  	;   if (link(source, target) < 0) {
   916                                  	
   917                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000370 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000372 8B0E[0C09]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000376 B80900              <1>  mov ax, %1
   102 00000379 CD20                <1>  int 20h
   918 0000037B 731F                    	jnc	short mv_50
   919                                  	
   920                                  	; fprintf(stderr, "mv: cannot link %s to %s\n",
   921                                  	;		 target, source);
   922                                  mv_48:
   923 0000037D B8[6608]                	mov	ax, msg_cant_link
   924 00000380 E8B002                  	call	print_msg
   925 00000383 A1[0C09]                	mov	ax, [target] ; target
   926 00000386 E8AA02                  	call	print_msg
   927 00000389 B8[7908]                	mov	ax, msg_to
   928 0000038C E8A402                  	call	print_msg
   929 0000038F 89F8                    	mov	ax, di ; source
   930 00000391 E89F02                  	call	print_msg
   931 00000394 B8[CA06]                	mov	ax, nextline
   932 00000397 E89902                  	call	print_msg
   933 0000039A F9                      	stc
   934                                  mv_49:
   935 0000039B C3                      	retn
   936                                  mv_50:
   937                                   	;if (unlink(source) < 0) {
   938                                  	sys	_unlink, di	
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000039C 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000039E B80A00              <1>  mov ax, %1
   102 000003A1 CD20                <1>  int 20h
   939 000003A3 731C                    	jnc	short mv_51
   940                                  
   941                                  	;fprintf(stderr, "mv: %s: cannot unlink\n", source);
   942 000003A5 B8[2D07]                	mov	ax, msg_cant_unlink
   943 000003A8 E88802                  	call	print_msg
   944 000003AB 89F8                    	mov	ax, di ; source
   945 000003AD E88302                  	call	print_msg
   946 000003B0 B8[CA06]                	mov	ax, nextline
   947 000003B3 E87D02                  	call	print_msg
   948                                  	;unlink(target);
   949                                  	sys	_unlink, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000003B6 8B1E[0C09]          <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000003BA B80A00              <1>  mov ax, %1
   102 000003BD CD20                <1>  int 20h
   950                                  	;return(1);
   951 000003BF F9                      	stc
   952 000003C0 C3                      	retn
   953                                  mv_51:
   954                                  	;strcat(dst, target);
   955                                  	;strcat(dst, "/");
   956                                  	;strcat(dst, DOTDOT);
   957                                  
   958 000003C1 8B36[0C09]              	mov	si, [target]
   959 000003C5 57                      	push	di ; *
   960 000003C6 BF[FE0A]                	mov	di, nspth 
   961                                  mv_52:
   962 000003C9 AC                      	lodsb
   963 000003CA AA                      	stosb
   964 000003CB 20C0                    	and	al, al
   965 000003CD 75FA                    	jnz	short mv_52
   966 000003CF 4F                      	dec	di
   967                                  	; 27/05/2022
   968 000003D0 B82F2E                  	mov	ax, 2E2Fh ; db '/..', 0  
   969 000003D3 AB                      	stosw
   970 000003D4 B82E00                  	mov	ax, 02Eh
   971 000003D7 AB                      	stosw
   972 000003D8 5F                      	pop	di ; *
   973                                  
   974                                  	;if (unlink(dst) < 0)
   975                                  	sys	_unlink, nspth
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000003D9 BB[FE0A]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000003DC B80A00              <1>  mov ax, %1
   102 000003DF CD20                <1>  int 20h
   976 000003E1 732A                    	jnc	short mv_56
   977                                  
   978                                  	; fprintf(stderr, "mv: %s: cannot unlink\n", dst);
   979 000003E3 B8[2D07]                	mov	ax, msg_cant_unlink
   980 000003E6 E84A02                  	call	print_msg
   981 000003E9 B8[FE0A]                	mov	ax, nspth ; dst
   982 000003EC E84402                  	call	print_msg
   983 000003EF B8[CA06]                	mov	ax, nextline
   984 000003F2 E83E02                  	call	print_msg
   985                                  mv_53:
   986                                  	;if (link(target, source) >= 0)
   987                                  	;	unlink(target);
   988                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000003F5 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000003F7 8B0E[0C09]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000003FB B80900              <1>  mov ax, %1
   102 000003FE CD20                <1>  int 20h
   989 00000400 720A                    	jc	short mv_55
   990                                  mv_54:
   991                                  	;unlink(target);
   992                                  	sys	_unlink, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000402 8B1E[0C09]          <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000406 B80A00              <1>  mov ax, %1
   102 00000409 CD20                <1>  int 20h
   993                                  	;return(1);
   994 0000040B F9                      	stc
   995                                  mv_55:
   996 0000040C C3                      	retn
   997                                  mv_56:
   998                                  	;if (link(pname(target), dst) < 0)
   999                                  	sys	_link, tbuf, nspth
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000040D BB[160A]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000410 B9[FE0A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000413 B80900              <1>  mov ax, %1
   102 00000416 CD20                <1>  int 20h
  1000 00000418 73F2                    	jnc	short mv_55 ;return(0)
  1001                                  
  1002                                  	;fprintf(stderr, "mv: cannot link %s to %s\n",
  1003                                  	;		dst, pname(target));
  1004 0000041A B8[6608]                	mov	ax, msg_cant_link
  1005 0000041D E81302                  	call	print_msg
  1006 00000420 B8[FE0A]                	mov	ax, nspth ; dst
  1007 00000423 E80D02                  	call	print_msg
  1008 00000426 B8[7908]                	mov	ax, msg_to
  1009 00000429 E80702                  	call	print_msg
  1010 0000042C B8[160A]                	mov	ax, tbuf ; pname(taget)
  1011 0000042F E80102                  	call	print_msg
  1012 00000432 B8[CA06]                	mov	ax, nextline
  1013 00000435 E8FB01                  	call	print_msg
  1014                                  	;if (link(pname(source), dst) >= 0)
  1015                                  	sys	_link, sbuf, nspth
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000438 BB[BA09]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000043B B9[FE0A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000043E B80900              <1>  mov ax, %1
   102 00000441 CD20                <1>  int 20h
  1016 00000443 72C7                    	jc	short mv_55
  1017                                  	;if (link(target, source) >= 0)
  1018                                  	;	unlink(target);
  1019 00000445 EBAE                    	jmp	short mv_53
  1020                                  
  1021                                  mv_57:
  1022                                  	; (move dir in same parent directory)
  1023                                   
  1024                                  	;if (link(source, target) < 0)
  1025                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000447 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000449 8B0E[0C09]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000044D B80900              <1>  mov ax, %1
   102 00000450 CD20                <1>  int 20h
  1026 00000452 731F                    	jnc	short mv_60
  1027                                  	;fprintf(stderr, "mv: cannot link %s and %s\n",
  1028                                  	;		source, target);
  1029 00000454 B8[6608]                	mov	ax, msg_cant_link
  1030 00000457 E8D901                  	call	print_msg
  1031 0000045A 89F8                    	mov	ax, di ; source
  1032 0000045C E8D401                  	call	print_msg
  1033 0000045F B8[7E08]                	mov	ax, msg_and
  1034 00000462 E8CE01                  	call	print_msg
  1035 00000465 A1[0C09]                	mov	ax, [target] ; target
  1036                                  mv_58:
  1037 00000468 E8C801                  	call	print_msg
  1038 0000046B B8[CA06]                	mov	ax, nextline
  1039 0000046E E8C201                  	call	print_msg
  1040                                  	;return(1);
  1041 00000471 F9                      	stc
  1042                                  mv_59:
  1043 00000472 C3                      	retn	
  1044                                  mv_60:
  1045                                  	;if (unlink(source) < 0) {
  1046                                  	sys	_unlink, di
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000473 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000475 B80A00              <1>  mov ax, %1
   102 00000478 CD20                <1>  int 20h
  1047 0000047A 73F6                    	jnc	short mv_59 ;return(0)
  1048                                  	
  1049                                  	;fprintf(stderr, "mv: ?? cannot unlink
  1050                                  	;		 %s\n", source);
  1051                                  	
  1052 0000047C B8[2D07]                	mov	ax, msg_cant_unlink
  1053 0000047F E8B101                  	call	print_msg
  1054 00000482 89F8                    	mov	ax, di ; source
  1055 00000484 EBE2                    	jmp	short mv_58
  1056                                  
  1057                                  ;-----------------------------------------------------------------
  1058                                  
  1059                                  strcpy:
  1060 00000486 89EE                    	mov	si, bp ; target
  1061                                  	; 27/05/2022 (bx -> cx, dx -> bx)
  1062 00000488 89FB                    	mov	bx, di ; source
  1063 0000048A 89D9                    	mov	cx, bx
  1064 0000048C BF[5609]                	mov	di, buf ; pathname buffer (100 bytes)
  1065 0000048F 893E[0C09]              	mov	[target], di
  1066                                  strcp_1:
  1067 00000493 AC                      	lodsb
  1068 00000494 08C0                    	or	al, al
  1069 00000496 7403                    	jz	short strcp_2
  1070 00000498 AA                      	stosb
  1071 00000499 EBF8                    	jmp	short strcp_1
  1072                                  strcp_2:
  1073                                  	; 27/05/2022
  1074 0000049B B02F                    	mov	al, DELIM ; '/'
  1075 0000049D 81FF[5609]              	cmp	di, buf
  1076 000004A1 7605                    	jna	short strcp_3
  1077                                  	;cmp	byte [di-1], DELIM  ; '/'
  1078 000004A3 3845FF                  	cmp	byte [di-1], al ; '/'
  1079 000004A6 7401                    	je	short strcp_4
  1080                                  strcp_3:
  1081                                  	;mov	al, DELIM ; '/'
  1082 000004A8 AA                      	stosb
  1083                                  strcp_4:	
  1084                                  	; bx = source (pathname)
  1085                                  	; di = buffer (offset) position
  1086 000004A9 E80E00                  	call	dname
  1087 000004AC 89CF                    	mov	di, cx	; source
  1088                                  			; target = buf;
  1089 000004AE C3                      	retn
  1090                                  
  1091                                  ;-----------------------------------------------------------------
  1092                                  
  1093                                  strcmp:
  1094                                  	; si = source
  1095                                  	; di = target
  1096                                  strcmp_1:
  1097 000004AF AC                      	lodsb
  1098 000004B0 08C0                    	or	al, al
  1099 000004B2 7404                    	jz	short strcmp_2
  1100 000004B4 AE                      	scasb
  1101 000004B5 74F8                    	je	short strcmp_1
  1102 000004B7 C3                      	retn
  1103                                  strcmp_2:
  1104                                  	;cmp	[di], al ; 0
  1105 000004B8 AE                      	scasb
  1106                                  strcmp_3:
  1107                                  	; zf = 1 -> same
  1108 000004B9 C3                      	retn
  1109                                  	
  1110                                  ;-----------------------------------------------------------------
  1111                                  
  1112                                  dname:	; dname(name)
  1113                                  	; 27/05/2022 (dx -> bx)
  1114                                  	; bx = source (pathname)
  1115                                  	; di = buffer (offset) position
  1116                                  dname_0:
  1117 000004BA 89DE                    	mov	si, bx  ; name
  1118                                  	;p = name;
  1119                                  	;while (*p)
  1120                                  dname_1:
  1121 000004BC AC                      	lodsb
  1122 000004BD 20C0                    	and	al, al
  1123 000004BF 740D                    	jz	short dname_2
  1124 000004C1 3C2F                    	cmp	al, DELIM  ; cmp al, '/'
  1125 000004C3 75F7                    	jne	short dname_1
  1126                                  	;if (*p++ == DELIM && *p)
  1127 000004C5 803C00                  	cmp	byte [si], 0
  1128                                  	;je	short dname_1
  1129 000004C8 7404                    	je	short dname_2
  1130 000004CA 89F3                    	mov	bx, si
  1131 000004CC EBEE                    	jmp	short dname_1
  1132                                  dname_2:
  1133                                  	; dx = file name
  1134 000004CE 89DE                    	mov	si, bx
  1135                                  dname_3:
  1136 000004D0 AC                      	lodsb
  1137 000004D1 AA                      	stosb
  1138 000004D2 08C0                    	or	al, al	
  1139 000004D4 75FA                    	jnz	short dname_3
  1140 000004D6 C3                      	retn
  1141                                  
  1142                                  ;-----------------------------------------------------------------
  1143                                  
  1144                                  pname:	; pname(name)
  1145                                  	; 23/05/2022
  1146                                  
  1147                                  	; INPUT:
  1148                                  	;	di = source (pathname)
  1149                                  	;	bx = buffer address
  1150                                  	; OUTPUT:
  1151                                  	;	si = parent dir name address
  1152                                  pname_0:
  1153 000004D7 89FE                    	mov	si, di ; source
  1154 000004D9 57                      	push	di ; *
  1155                                  	;p = q = buf;
  1156 000004DA 89DF                    	mov	di, bx
  1157 000004DC 89D9                    	mov	cx, bx
  1158                                  	; while (c = *p++ = *name++)
  1159                                  pname_1:
  1160 000004DE AC                      	lodsb
  1161 000004DF AA                      	stosb
  1162 000004E0 20C0                    	and	al, al
  1163 000004E2 7409                    	jz	short pname_2
  1164                                  	;if (c == DELIM)
  1165                                  	;	q = p-1;
  1166 000004E4 3C2F                    	cmp	al, DELIM  ; cmp al, '/'
  1167 000004E6 75F6                    	jne	short pname_1
  1168 000004E8 89FB                    	mov	bx, di
  1169 000004EA 4B                      	dec	bx
  1170 000004EB EBF1                    	jmp	short pname_1
  1171                                  pname_2:
  1172                                  	;if (q == buf && *q == DELIM)
  1173                                  	;    q++;
  1174 000004ED 39CB                    	cmp	bx, cx
  1175 000004EF 7506                    	jne	short pname_3
  1176 000004F1 803F2F                  	cmp	byte [bx], DELIM ; '/'
  1177 000004F4 7501                    	jne	short pname_3
  1178 000004F6 43                      	inc	bx	
  1179                                  pname_3:
  1180                                  	;*q = 0;
  1181 000004F7 C60700                  	mov	byte [bx], 0
  1182 000004FA 89CE                    	mov	si, cx
  1183 000004FC 5F                      	pop	di ; *
  1184                                  	; return buf[0]? buf : DOT;
  1185 000004FD 803C00                  	cmp	byte [si], 0
  1186 00000500 7705                    	ja	short pname_4
  1187 00000502 A1[5E06]                	mov	ax, [DOT] ; db '.', 0
  1188 00000505 8904                    	mov	[si], ax
  1189                                  pname_4:
  1190 00000507 C3                      	retn
  1191                                  
  1192                                  ;-----------------------------------------------------------------
  1193                                  
  1194                                  check:	; check(spth, dinode)
  1195                                  	; 23/05/2022
  1196                                  
  1197                                  	; INPUT:
  1198                                  	;	bx = name buffer address
  1199                                  	;	[st1buf+stat.inode] = inode num to be compared
  1200                                  	; OUTPUT:
  1201                                  	;	cf = 1 -> error
  1202                                  	;	cf = 0 -> no problem
  1203                                  
  1204                                  	;strcpy(nspth, spth);
  1205                                  
  1206 00000508 89DE                    	mov	si, bx
  1207 0000050A 57                      	push	di ; *
  1208 0000050B BF[FE0A]                	mov	di, nspth 
  1209                                  check_1:
  1210 0000050E AC                      	lodsb
  1211 0000050F AA                      	stosb
  1212 00000510 20C0                    	and	al, al
  1213 00000512 75FA                    	jnz	short check_1
  1214 00000514 29DE                    	sub	si, bx 
  1215 00000516 4E                      	dec	si ; si = strlen(nspth)
  1216 00000517 5F                      	pop	di ; *
  1217                                  check_2:
  1218                                  	;if (stat(nspth, &sbuf) < 0)
  1219                                  	sys	_stat, nspth, fstbuf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000518 BB[FE0A]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000051B B9[720A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000051E B81200              <1>  mov ax, %1
   102 00000521 CD20                <1>  int 20h
  1220 00000523 7314                    	jnc	short check_5
  1221                                  	;fprintf(stderr, "mv: cannot access %s\n", nspth);
  1222 00000525 B8[FA06]                	mov	ax, msg_cant_access
  1223 00000528 E80801                  	call	print_msg
  1224 0000052B B8[FE0A]                	mov	ax, nspth
  1225 0000052E E80201                  	call	print_msg
  1226 00000531 B8[CA06]                	mov	ax, nextline
  1227                                  check_3:
  1228 00000534 E8FC00                  	call	print_msg
  1229 00000537 F9                      	stc
  1230                                  check_4:
  1231 00000538 C3                      	retn
  1232                                  check_5:
  1233                                  	;if (sbuf.st_ino == dinode)
  1234 00000539 A1[720A]                	mov	ax, [fstbuf+stat.inode]
  1235 0000053C 3B06[1009]              	cmp	ax, [st1buf+stat.inode]
  1236 00000540 7505                    	jne	short check_6
  1237                                  	; fprintf(stderr, "mv: cannot move a directory
  1238                                  	;			 into itself\n");
  1239 00000542 B8[9508]                	mov	ax, msg_cant_mv_itself
  1240 00000545 EBED                    	jmp	short check_3
  1241                                  check_6:
  1242                                  	;while (sbuf.st_ino != ROOTINO)
  1243 00000547 83F829                  	cmp	ax, ROOTINO
  1244 0000054A 74EC                    	je	short check_4
  1245                                  
  1246                                  	;if (strlen(nspth) > MAXN-2-sizeof(DOTDOT))
  1247 0000054C 83FE6C                  	cmp	si, MAXN-4
  1248 0000054F 7605                    	jna	short check_7
  1249                                  
  1250                                  	;fprintf(stderr, "mv: name too long\n");
  1251 00000551 B8[C108]                	mov	ax, msg_too_long
  1252 00000554 EBDE                    	jmp	short check_3
  1253                                  check_7:
  1254                                  	;strcat(nspth, SDELIM);
  1255                                  	;strcat(nspth, DOTDOT);
  1256                                  	;mov	eax, 002E2E2Fh ; db '/..', 0  
  1257                                  	;mov	[si+nspth], eax
  1258                                  	; 27/05/2022
  1259 00000556 B82F2E                  	mov	ax, 2E2Fh ; db '/.'
  1260 00000559 8984[FE0A]              	mov	[si+nspth], ax
  1261 0000055D B82E00                  	mov	ax, 02Eh ; db '.', 0
  1262 00000560 8984[000B]              	mov	[si+nspth+2], ax
  1263 00000564 83C603                  	add	si, 3
  1264 00000567 EBAF                    	jmp	short check_2
  1265                                  
  1266                                  ;-----------------------------------------------------------------
  1267                                  
  1268                                  chkdot:	; chkdot(s)
  1269                                  	; 23/05/2022
  1270                                  
  1271                                  	;do {
  1272                                  	;    if (strcmp(dname(s), DOTDOT) == 0)
  1273                                  	;	return(1);
  1274                                  	;    s = pname(s);
  1275                                  	;} while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0);
  1276                                  	;return(0);
  1277                                  
  1278                                  	; INPUT:
  1279                                  	;	bx = name buffer address
  1280                                  	; OUTPUT:
  1281                                  	;	cf = 1 -> DOTDOT (return 0)
  1282                                  	;	cf = 0 -> not DOTDOT (return 1)
  1283                                  
  1284                                  	; get last '/'
  1285 00000569 89DE                    	mov	si, bx
  1286                                  chkdot_0:
  1287 0000056B 89D9                    	mov	cx, bx
  1288                                  chkdot_1:
  1289 0000056D AC                      	lodsb
  1290 0000056E 20C0                    	and	al, al
  1291 00000570 740E                    	jz	short chkdot_2
  1292 00000572 3C2F                    	cmp	al, DELIM ; '/'
  1293 00000574 75F7                     	jne	short chkdot_1
  1294 00000576 803C00                  	cmp	byte [si], 0
  1295 00000579 7605                    	jna	short chkdot_2	
  1296 0000057B 89F1                    	mov	cx, si
  1297 0000057D 49                      	dec	cx
  1298 0000057E EBED                    	jmp	short chkdot_1 
  1299                                  chkdot_2:
  1300 00000580 57                      	push	di ; *
  1301 00000581 89CE                    	mov	si, cx
  1302 00000583 BF[5D06]                	mov	di, DOTDOT
  1303 00000586 E826FF                  	call	strcmp
  1304 00000589 7412                    	jz	short chkdot_4 ; DOTDOT
  1305 0000058B 89DF                    	mov	di, bx
  1306 0000058D BB[720A]                	mov	bx, fstbuf
  1307 00000590 E844FF                  	call	pname
  1308 00000593 5F                      	pop	di ; *
  1309 00000594 89F3                    	mov	bx, si  ; parent dir's pathname buf
  1310 00000596 8B04                    	mov	ax, [si]
  1311 00000598 08E4                    	or	ah, ah ; 0 ?
  1312 0000059A 75CF                    	jnz	short chkdot_0
  1313                                  	; (single character parent directory name)
  1314                                  	; (it's name may be '.' or '/' or another char)
  1315                                  	; pathname does not contain a DOTDOT
  1316 0000059C C3                      	retn
  1317                                  chkdot_4:
  1318                                  	; pathname contains DOTDOT
  1319 0000059D F9                      	stc
  1320 0000059E C3                      	retn
  1321                                  	 
  1322                                  ;-----------------------------------------------------------------
  1323                                  
  1324                                  access:
  1325                                  	; 22/05/2022
  1326                                  	; Retro UNIX 386 v1 & v1.1 & v1.2
  1327                                  
  1328                                  	; INPUT:
  1329                                  	;	si = stat(us) buffer 
  1330                                  	; OUTPUT:
  1331                                  	;	zf = 1 -> no write permission
  1332                                  	;	zf = 0 -> permitted to write
  1333                                  		
  1334                                  	sys	_getuid
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93                              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95                              <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000059F B81800              <1>  mov ax, %1
   102 000005A2 CD20                <1>  int 20h
  1335                                  	;mov	[uid], ax
  1336                                  
  1337                                  	; Retro UNIX 386 v1.2 (v2 fs)
  1338                                  	;mov	dl, 80h  ; write permission flag, owner
  1339                                  
  1340                                  	; Retro UNIX 386 v1
  1341 000005A4 B204                    	mov	dl, 4  ; write permission flag, owner
  1342                                  
  1343                                  	;or	ax, ax
  1344 000005A6 08C0                    	or	al, al
  1345 000005A8 7407                    	jz	short access_1 ; root
  1346                                  
  1347                                  	;cmp	ax, [si+stat.uid]	
  1348 000005AA 3A4405                  	cmp	al, [si+stat.uid]
  1349 000005AD 7402                    	je	short access_1
  1350                                  
  1351                                  	; Retro UNIX 386 v1.2 (v2 fs inode)
  1352                                  	;sys	_getgid
  1353                                  	;;mov	[gid], al
  1354                                  
  1355                                  	;mov	dl, 10h
  1356                                  	;cmp	al, [si+stat.gid]
  1357                                  	;je	short access_1
  1358                                  	;
  1359                                  	;mov	dl, 02h
  1360                                  
  1361                                  	; Retro UNIX 386 v1	
  1362 000005AF B201                    	mov	dl, 1
  1363                                  access_1:
  1364 000005B1 845402                  	test	dl, [si+stat.mode]
  1365 000005B4 C3                      	retn
  1366                                  
  1367                                  ;-----------------------------------------------------------------
  1368                                  
  1369                                  isatty:
  1370                                  	; 22/05/2022
  1371                                  	; Retro UNIX 386 v1 & v1.1 & v1.2
  1372                                  
  1373                                  	; Input: stdin (= 0)
  1374                                  	; output:
  1375                                  	;	cf = 1 -> not a tty
  1376                                  
  1377                                  	sys	_fstat, STDIN, fstbuf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000005B5 BB0000              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000005B8 B9[720A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000005BB B81C00              <1>  mov ax, %1
   102 000005BE CD20                <1>  int 20h
  1378                                  
  1379 000005C0 A1[720A]                	mov	ax, [fstbuf+stat.inode]
  1380                                  
  1381                                  	; Retro UNIX 386 v1.2
  1382                                  	;cmp	ax, 8 ; /dev/tty
  1383                                  	;je	short isatty_2
  1384                                  	;cmp	ax, 26 ; /dev/tty8
  1385                                  	;ja	short isatty_1
  1386                                  	;cmp	ax, 17 ; /dev/tty0
  1387                                  	;retn
  1388                                  
  1389                                  	; Retro UNIX 386 v1 (& v1.1)
  1390 000005C3 83F801                  	cmp	ax, 1 ; /dev/tty
  1391 000005C6 740A                    	je	short isatty_2
  1392 000005C8 83F813                  	cmp	ax, 19 ; /dev/tty8
  1393 000005CB 7704                    	ja	short isatty_1
  1394 000005CD 83F80A                  	cmp	ax, 10 ; /dev/tty0
  1395 000005D0 C3                      	retn
  1396                                  isatty_1:
  1397 000005D1 F9                      	stc
  1398                                  isatty_2:   
  1399 000005D2 C3                      	retn
  1400                                  
  1401                                  ;-----------------------------------------------------------------
  1402                                  	
  1403                                  octalnumber:
  1404                                  	; 27/05/2022
  1405                                  
  1406                                  	; Input:
  1407                                  	;   bx = binary number (max. 9 bit)
  1408                                  	;   si = string buffer (4 byte)
  1409                                  
  1410 000005D3 89D8                    	mov	ax, bx
  1411 000005D5 B103                    	mov	cl, 3
  1412 000005D7 D3EB                    	shr	bx, cl ; 3
  1413 000005D9 2407                    	and	al, 7
  1414 000005DB 50                      	push	ax
  1415 000005DC 89D8                    	mov	ax, bx
  1416 000005DE D3EB                    	shr	bx, cl ; 3 
  1417 000005E0 2407                    	and	al, 7	
  1418 000005E2 50                      	push	ax
  1419 000005E3 89D8                    	mov	ax, bx
  1420 000005E5 2407                    	and	al, 7
  1421                                  octn_0:
  1422                                  	; 27/05/2022
  1423                                  	;mov	byte [si], 20h
  1424                                  	;inc	si
  1425 000005E7 89F3                    	mov	bx, si
  1426                                  	;or	al, al
  1427                                  	;jz	short octn_1
  1428 000005E9 E80C00                  	call	octn_3
  1429                                  octn_1:
  1430 000005EC 58                      	pop	ax
  1431                                  	; 27/05/2022
  1432 000005ED E80800                  	call	octn_3
  1433                                  octn_2:
  1434 000005F0 58                      	pop	ax
  1435                                  	;call	octn_3
  1436 000005F1 E80C00                  	call	octn_4 ; 27/05/2022
  1437 000005F4 30C0                    	xor	al, al
  1438 000005F6 EB0A                    	jmp	short octn_5
  1439                                  
  1440                                  octn_3:
  1441                                  	; 27/05/2022
  1442 000005F8 20C0                    	and	al, al
  1443 000005FA 7504                    	jnz	short octn_4
  1444 000005FC 39DE                    	cmp	si, bx
  1445 000005FE 7405                    	je	short octn_6
  1446                                  octn_4:
  1447 00000600 0430                    	add	al, '0'
  1448                                  octn_5:
  1449 00000602 8804                    	mov	[si], al
  1450 00000604 46                      	inc	si
  1451                                  octn_6:
  1452 00000605 C3                      	retn
  1453                                  
  1454                                  ;-----------------------------------------------------------------
  1455                                  
  1456                                  getchar:
  1457                                  	; i = c = getchar();
  1458                                  	; while (c != '\n' && c != EOF)
  1459                                  	;		c = getchar();
  1460                                  getc_0:	
  1461                                  	sys	_read, STDIN, char, 1
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000606 BB0000              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000609 B9[FD0A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97 0000060C BA0100              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000060F B80300              <1>  mov ax, %1
   102 00000612 CD20                <1>  int 20h
  1462 00000614 A0[FD0A]                	mov	al, [char]
  1463 00000617 3C79                    	cmp	al, 'y'
  1464 00000619 7417                    	je	short getc_2
  1465 0000061B 3C6E                    	cmp	al, 'n'
  1466 0000061D 7413                    	je	short getc_2	
  1467 0000061F 3C1B                    	cmp	al, ESCKey
  1468 00000621 740F                    	je	short getc_2
  1469 00000623 3C0D                    	cmp	al, EnterKey
  1470 00000625 740B                    	je	short getc_2
  1471 00000627 3C59                    	cmp	al, 'Y'	
  1472 00000629 7503                    	jne	short getc_1
  1473 0000062B B079                    	mov	al, 'y'
  1474 0000062D C3                      	retn
  1475                                  getc_1:
  1476 0000062E 3C4E                    	cmp	al, 'N'
  1477 00000630 75D4                    	jne	short getc_0
  1478                                  getc_2:
  1479 00000632 C3                      	retn	
  1480                                  
  1481                                  ;-----------------------------------------------------------------
  1482                                  
  1483                                  print_msg:
  1484                                  	; ax = asciiz string address
  1485 00000633 89C6                    	mov	si, ax
  1486 00000635 4E                      	dec	si
  1487                                  nextchr:
  1488 00000636 46                      	inc	si
  1489 00000637 803C00                  	cmp	byte [si], 0
  1490 0000063A 77FA                    	ja	short nextchr
  1491                                  	;cmp	[si], 0Dh
  1492                                  	;ja	short nextchr
  1493 0000063C 29C6                    	sub	si, ax
  1494                                  	; si = asciiz string length
  1495                                  	;
  1496                                  	sys	_write, 1, ax, si
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000063E BB0100              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000641 89C1                <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97 00000643 89F2                <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000645 B80400              <1>  mov ax, %1
   102 00000648 CD20                <1>  int 20h
  1497                                  	;
  1498 0000064A C3                      	retn
  1499                                  
  1500                                  ;-----------------------------------------------------------------
  1501                                  ;  data - initialized data
  1502                                  ;-----------------------------------------------------------------
  1503                                  
  1504                                  ;argc:	dd 0
  1505 0000064B 00                      argc:	db 0
  1506 0000064C 00                      errors:	db 0
  1507                                  
  1508                                  cp_cmd:
  1509 0000064D 2F62696E2F637000        	db '/bin/cp', 0
  1510                                  
  1511                                  ;cp_args:
  1512                                  ;	dd cp_cmd
  1513                                  ;cp_source:
  1514                                  ;	dd 0
  1515                                  ;cp_target:
  1516                                  ;	dd 0
  1517                                  ;	dd 0
  1518                                  
  1519                                  ; 27/05/2022 - Retro UNIX 8086 v1
  1520                                  cp_args:
  1521 00000655 [4D06]                  	dw cp_cmd
  1522                                  cp_source:
  1523 00000657 0000                    	dw 0		
  1524                                  cp_target:
  1525 00000659 0000                    	dw 0
  1526 0000065B 0000                    	dw 0
  1527                                  
  1528 0000065D 2E                      DOTDOT:	db '.'
  1529 0000065E 2E00                    DOT:	db '.', 0
  1530                                  	;db 0, 0
  1531                                  
  1532                                  ; ----------------------------------------------------------------
  1533                                  
  1534                                  program_msg:
  1535 00000660 0D0A                    	db  0Dh, 0Ah
  1536 00000662 526574726F20554E49-     	db  'Retro UNIX 8086 v1 MOVE by Erdogan TAN - 27/05/2022'
  1536 0000066B 582038303836207631-
  1536 00000674 204D4F564520627920-
  1536 0000067D 4572646F67616E2054-
  1536 00000686 414E202D2032372F30-
  1536 0000068F 352F32303232       
  1537 00000695 0D0A00                  	db  0Dh, 0Ah, 0
  1538                                  
  1539                                  usage_msg:
  1540 00000698 0D0A                    	db  0Dh, 0Ah
  1541 0000069A 75736167653A206D76-     	db  'usage: mv f1 f2; or mv d1 d2; or mv f1 ... fn d1'
  1541 000006A3 2066312066323B206F-
  1541 000006AC 72206D762064312064-
  1541 000006B5 323B206F72206D7620-
  1541 000006BE 6631202E2E2E20666E-
  1541 000006C7 206431             
  1542                                  nextline:
  1543 000006CA 0D0A00                  	db  0Dh, 0Ah, 0
  1544                                  
  1545                                  mv_header:
  1546 000006CD 0D0A                    	db 0Dh, 0Ah
  1547 000006CF 6D763A20                	db 'mv: '
  1548 000006D3 00                      	db 0
  1549                                  msg_not_exists:
  1550                                  	;db 0Dh, 0Ah
  1551 000006D4 20646F6573206E6F74-     	db ' does not exist '
  1551 000006DD 20657869737420     
  1552 000006E4 0D0A00                  	db 0Dh, 0Ah, 0
  1553                                  
  1554                                  msg_is_a_dir:
  1555 000006E7 206973206120646972-     	db ' is a directory '
  1555 000006F0 6563746F727920     
  1556 000006F7 0D0A00                  	db 0Dh, 0Ah, 0
  1557                                  
  1558                                  msg_cant_access:
  1559 000006FA 0D0A                    	db 0Dh, 0Ah
  1560 000006FC 6D763A2063616E6E6F-     	db 'mv: cannot access '
  1560 00000705 742061636365737320 
  1561 0000070E 00                      	db 0
  1562                                  
  1563                                  msg_rename_only:
  1564 0000070F 0D0A                    	db 0Dh, 0Ah
  1565 00000711 6D763A206469726563-     	db 'mv: directory rename only'
  1565 0000071A 746F72792072656E61-
  1565 00000723 6D65206F6E6C79     
  1566 0000072A 0D0A00                  	db 0Dh, 0Ah, 0
  1567                                  
  1568                                  msg_cant_unlink:
  1569 0000072D 0D0A                    	db 0Dh, 0Ah
  1570 0000072F 6D763A2063616E6E6F-     	db 'mv: cannot unlink '
  1570 00000738 7420756E6C696E6B20 
  1571 00000741 00                      	db 0
  1572                                  
  1573                                  msg_try_again:
  1574 00000742 0D0A                    	db 0Dh, 0Ah
  1575 00000744 6D763A207472792061-     	db 'mv: try again'
  1575 0000074D 6761696E           
  1576 00000751 0D0A00                  	db 0Dh, 0Ah, 0
  1577                                  
  1578                                  msg_cant_exec_cp:
  1579 00000754 0D0A                    	db 0Dh, 0Ah
  1580 00000756 6D763A2063616E6E6F-     	db 'mv: cannot exec cp'
  1580 0000075F 742065786563206370 
  1581 00000768 0D0A00                  	db 0Dh, 0Ah, 0
  1582                                  
  1583                                  msg_exists:
  1584 0000076B 2065786973747320        	db ' exists '
  1585 00000773 0D0A00                  	db 0Dh, 0Ah, 0
  1586                                  
  1587                                  ;msg_long_target:
  1588                                  ;	db 0Dh, 0Ah
  1589                                  ;	db 'mv: target name too long'
  1590                                  ;	db 0Dh, 0Ah, 0
  1591                                  
  1592                                  msg_src_target:
  1593 00000776 0D0A                    	db 0Dh, 0Ah
  1594 00000778 6D763A203F3F20736F-     	db 'mv: ?? source == target, source exists and target doesnt'
  1594 00000781 75726365203D3D2074-
  1594 0000078A 61726765742C20736F-
  1594 00000793 757263652065786973-
  1594 0000079C 747320616E64207461-
  1594 000007A5 7267657420646F6573-
  1594 000007AE 6E74               
  1595 000007B0 0D0A00                  	db 0Dh, 0Ah, 0
  1596                                  
  1597                                  msg_cant_locate:
  1598 000007B3 0D0A                    	db 0Dh, 0Ah
  1599 000007B5 6D763A2063616E6E6F-     	db 'mv: cannot locate parent'
  1599 000007BE 74206C6F6361746520-
  1599 000007C7 706172656E74       
  1600 000007CD 0D0A00                  	db 0Dh, 0Ah, 0
  1601                                  
  1602                                  msg_no_w_access:
  1603 000007D0 0D0A                    	db 0Dh, 0Ah
  1604 000007D2 6D763A206E6F207772-     	db 'mv: no write access to '
  1604 000007DB 697465206163636573-
  1604 000007E4 7320746F20         
  1605 000007E9 00                      	db 0
  1606                                  
  1607                                  msg_accross_devices:
  1608 000007EA 0D0A                    	db 0Dh, 0Ah
  1609 000007EC 6D763A2063616E6E6F-     	db 'mv: cannot move directories across devices'
  1609 000007F5 74206D6F7665206469-
  1609 000007FE 726563746F72696573-
  1609 00000807 206163726F73732064-
  1609 00000810 657669636573       
  1610 00000816 0D0A00                  	db 0Dh, 0Ah, 0
  1611                                  
  1612                                  msg_pathname_dotdot:
  1613 00000819 0D0A                    	db 0Dh, 0Ah
  1614 0000081B 6D763A20536F727279-     	db "mv: Sorry, path names including '..' aren't allowed"
  1614 00000824 2C2070617468206E61-
  1614 0000082D 6D657320696E636C75-
  1614 00000836 64696E6720272E2E27-
  1614 0000083F 206172656E27742061-
  1614 00000848 6C6C6F776564       
  1615 0000084E 0D0A00                  	db 0Dh, 0Ah, 0
  1616                                  
  1617                                  msg_cant_rename:
  1618 00000851 0D0A                    	db 0Dh, 0Ah
  1619 00000853 6D763A2063616E6E6F-     	db 'mv: cannot rename '
  1619 0000085C 742072656E616D6520 
  1620 00000865 00                      	db 0
  1621                                  
  1622                                  msg_cant_link:
  1623 00000866 0D0A                    	db 0Dh, 0Ah
  1624 00000868 6D763A2063616E6E6F-     	db 'mv: cannot link '
  1624 00000871 74206C696E6B20     
  1625 00000878 00                      	db 0
  1626                                  msg_to:
  1627 00000879 20746F20                	db ' to '
  1628 0000087D 00                      	db 0
  1629                                  msg_and:
  1630 0000087E 20616E6420              	db ' and '
  1631 00000883 00                      	db 0
  1632                                  
  1633                                  msg_identical:
  1634 00000884 20617265206964656E-     	db ' are identical'
  1634 0000088D 746963616C         
  1635 00000892 0D0A00                  	db 0Dh, 0Ah, 0	 
  1636                                  
  1637                                  msg_cant_mv_itself:
  1638 00000895 0D0A                    	db 0Dh, 0Ah
  1639 00000897 6D763A2063616E6E6F-     	db 'mv: cannot move a directory into itself'
  1639 000008A0 74206D6F7665206120-
  1639 000008A9 6469726563746F7279-
  1639 000008B2 20696E746F20697473-
  1639 000008BB 656C66             
  1640 000008BE 0D0A00                  	db 0Dh, 0Ah, 0
  1641                                  
  1642                                  msg_too_long:
  1643 000008C1 0D0A                    	db 0Dh, 0Ah
  1644 000008C3 6D763A206E616D6520-     	db 'mv: name too long'
  1644 000008CC 746F6F206C6F6E67   
  1645 000008D4 0D0A00                  	db 0Dh, 0Ah, 0
  1646                                  
  1647                                  msg_mode:
  1648 000008D7 206D6F6465203F2028-     	db ' mode ? (y/n) '
  1648 000008E0 792F6E2920         
  1649 000008E5 00                      	db 0
  1650                                  
  1651                                  msg_yes:
  1652 000008E6 2059455320              	db ' YES '
  1653 000008EB 0D0A00                  	db 0Dh, 0Ah, 0
  1654                                  
  1655                                  msg_no:
  1656 000008EE 204E4F20                	db ' NO '
  1657 000008F2 0D0A00                  	db 0Dh, 0Ah, 0
  1658                                  
  1659                                  err_msg:
  1660 000008F5 0D0A                    	db 0Dh, 0Ah
  1661 000008F7 4572726F722120          	db 'Error! '
  1662 000008FE 0D0A00                  	db 0Dh, 0Ah, 0
  1663                                  
  1664                                  msg_ok:
  1665 00000901 0D0A                    	db  0Dh, 0Ah
  1666 00000903 4F4B2E                  	db  'OK.'
  1667 00000906 0D0A00                  	db  0Dh, 0Ah, 0
  1668                                  
  1669                                  ;-----------------------------------------------------------------
  1670                                  ;  bss - uninitialized data
  1671                                  ;-----------------------------------------------------------------
  1672                                  
  1673 00000909 90<rep 3h>              align 4
  1674                                  
  1675                                  bss_start:
  1676                                  
  1677                                  ABSOLUTE bss_start
  1678                                  
  1679                                  ;uid:	resw 1
  1680                                  ;;gid:	resw 1  ; Retro UNIX 386 v1.2
  1681                                  
  1682                                  ;target: resd 1	; destination/target pathname pointer
  1683                                  ; 27/05/2022
  1684 0000090C ????                    target:	resw 1  ; Retro UNIX 8086 v1
  1685                                  
  1686 0000090E ????                    st1dev: resw 1
  1687 00000910 <res 22h>               st1buf: resb 34 ; for Retro UNIX 386 v1 & v1.1
  1688 00000932 ????                    st2dev: resw 1
  1689 00000934 <res 22h>               st2buf: resb 34 ; 
  1690                                  ;st1dev: resd 1
  1691                                  ;st1buf: resb 66 ; for Retro UNIX 386 v1.2
  1692                                  ;st2dev: resd 1
  1693                                  ;st2buf: resb 66 ;
  1694                                  
  1695 00000956 <res 64h>               buf:	resb 100 ; pathname buffer
  1696 000009BA <res 5Ch>               sbuf:	resb 92 ; source, parent name buffer ; 23/05/2022
  1697 00000A16 <res 5Ch>               tbuf:	resb 92 ; target, parent name buffer ; 23/05/2022			
  1698 00000A72 <res 42h>               fstbuf:	resb 66	; fstat buffer
  1699                                  ; 23/05/2022
  1700                                  ;pst1buf: resb 66
  1701                                  ;pst2buf: resb 66
  1702 00000AB4 <res 22h>               pst1buf: resb 34
  1703 00000AD6 <res 22h>               pst2buf: resb 34
  1704 00000AF8 ??                      octms:	resb 1	; 27/05/2022
  1705 00000AF9 ????????                octm:	resb 4	; octal mode number
  1706 00000AFD ??                      char:	resb 1	; getchar buffer
  1707 00000AFE <res 70h>               nspth:	resb MAXN ; 112 ; buffer for 'check' procedure
  1708                                  
  1709                                  ; 22/05/2022
  1710                                  ;-----------------------------------------------------------------
  1711                                  ; Original UNIX v7 - mv (utility) c source code (mv.c)
  1712                                  ;-----------------------------------------------------------------
  1713                                  ;/* UNIX V7 source code: see www.tuhs.org for details. */;
  1714                                  ;
  1715                                  ;/*
  1716                                  ; * mv file1 file2
  1717                                  ; */
  1718                                  ;
  1719                                  ;#include <stdio.h>
  1720                                  ;#include <sys/types.h>
  1721                                  ;#include <sys/stat.h>
  1722                                  ;#include <sys/dir.h>
  1723                                  ;#include <signal.h>
  1724                                  ;
  1725                                  ;#define DOT	"."
  1726                                  ;#define DOTDOT	".."
  1727                                  ;#define DELIM	'/'
  1728                                  ;#define SDELIM "/"
  1729                                  ;#define MAXN	100
  1730                                  ;#define MODEBITS 07777
  1731                                  ;#define ROOTINO 2
  1732                                  ;
  1733                                  ;char	*pname();
  1734                                  ;char	*sprintf();
  1735                                  ;char	*dname();
  1736                                  ;struct	stat s1, s2;
  1737                                  ;
  1738                                  ;main(argc, argv)
  1739                                  ;register char *argv[];
  1740                                  ;{
  1741                                  ;	register i, r;
  1742                                  ;
  1743                                  ;	if (argc < 3)
  1744                                  ;		goto usage;
  1745                                  ;	if (stat(argv[1], &s1) < 0) {
  1746                                  ;		fprintf(stderr, "mv: cannot access %s\n", argv[1]);
  1747                                  ;		return(1);
  1748                                  ;	}
  1749                                  ;	if ((s1.st_mode & S_IFMT) == S_IFDIR) {
  1750                                  ;		if (argc != 3)
  1751                                  ;			goto usage;
  1752                                  ;		return mvdir(argv[1], argv[2]);
  1753                                  ;	}
  1754                                  ;	setuid(getuid());
  1755                                  ;	if (argc > 3)
  1756                                  ;		if (stat(argv[argc-1], &s2) < 0 || (s2.st_mode & S_IFMT) != S_IFDIR)
  1757                                  ;			goto usage;
  1758                                  ;	r = 0;
  1759                                  ;	for (i=1; i<argc-1; i++)
  1760                                  ;		r |= move(argv[i], argv[argc-1]);
  1761                                  ;	return(r);
  1762                                  ;usage:
  1763                                  ;	fprintf(stderr, "usage: mv f1 f2; or mv d1 d2; or mv f1 ... fn d1\n");
  1764                                  ;	return(1);
  1765                                  ;}
  1766                                  ;
  1767                                  ;move(source, target)
  1768                                  ;char *source, *target;
  1769                                  ;{
  1770                                  ;	register c, i;
  1771                                  ;	int	status;
  1772                                  ;	char	buf[MAXN];
  1773                                  ;
  1774                                  ;	if (stat(source, &s1) < 0) {
  1775                                  ;		fprintf(stderr, "mv: cannot access %s\n", source);
  1776                                  ;		return(1);
  1777                                  ;	}
  1778                                  ;	if ((s1.st_mode & S_IFMT) == S_IFDIR) {
  1779                                  ;		fprintf(stderr, "mv: directory rename only\n");
  1780                                  ;		return(1);
  1781                                  ;	}
  1782                                  ;	if (stat(target, &s2) >= 0) {
  1783                                  ;		if ((s2.st_mode & S_IFMT) == S_IFDIR) {
  1784                                  ;			sprintf(buf, "%s/%s", target, dname(source));
  1785                                  ;			target = buf;
  1786                                  ;		}
  1787                                  ;		if (stat(target, &s2) >= 0) {
  1788                                  ;			if ((s2.st_mode & S_IFMT) == S_IFDIR) {
  1789                                  ;				fprintf(stderr, "mv: %s is a directory\n", target);
  1790                                  ;				return(1);
  1791                                  ;			}
  1792                                  ;			if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) {
  1793                                  ;				fprintf(stderr, "mv: %s and %s are identical\n",
  1794                                  ;						source, target);
  1795                                  ;				return(1);
  1796                                  ;			}
  1797                                  ;			if (access(target, 2) < 0 && isatty(fileno(stdin))) {
  1798                                  ;				fprintf(stderr, "mv: %s: %o mode ", target,
  1799                                  ;					s2.st_mode & MODEBITS);
  1800                                  ;				i = c = getchar();
  1801                                  ;				while (c != '\n' && c != EOF)
  1802                                  ;					c = getchar();
  1803                                  ;				if (i != 'y')
  1804                                  ;					return(1);
  1805                                  ;			}
  1806                                  ;			if (unlink(target) < 0) {
  1807                                  ;				fprintf(stderr, "mv: cannot unlink %s\n", target);
  1808                                  ;				return(1);
  1809                                  ;			}
  1810                                  ;		}
  1811                                  ;	}
  1812                                  ;	if (link(source, target) < 0) {
  1813                                  ;		i = fork();
  1814                                  ;		if (i == -1) {
  1815                                  ;			fprintf(stderr, "mv: try again\n");
  1816                                  ;			return(1);
  1817                                  ;		}
  1818                                  ;		if (i == 0) {
  1819                                  ;			execl("/bin/cp", "cp", source, target, 0);
  1820                                  ;			fprintf(stderr, "mv: cannot exec cp\n");
  1821                                  ;			exit(1);
  1822                                  ;		}
  1823                                  ;		while ((c = wait(&status)) != i && c != -1)
  1824                                  ;			;
  1825                                  ;		if (status != 0)
  1826                                  ;			return(1);
  1827                                  ;		utime(target, &s1.st_atime);
  1828                                  ;	}
  1829                                  ;	if (unlink(source) < 0) {
  1830                                  ;		fprintf(stderr, "mv: cannot unlink %s\n", source);
  1831                                  ;		return(1);
  1832                                  ;	}
  1833                                  ;	return(0);
  1834                                  ;}
  1835                                  ;
  1836                                  ;mvdir(source, target)
  1837                                  ;char *source, *target;
  1838                                  ;{
  1839                                  ;	register char *p;
  1840                                  ;	register i;
  1841                                  ;	char buf[MAXN];
  1842                                  ;
  1843                                  ;	if (stat(target, &s2) >= 0) {
  1844                                  ;		if ((s2.st_mode&S_IFMT) != S_IFDIR) {
  1845                                  ;			fprintf(stderr, "mv: %s exists\n", target);
  1846                                  ;			return(1);
  1847                                  ;		}
  1848                                  ;		if (strlen(target) > MAXN-DIRSIZ-2) {
  1849                                  ;			fprintf(stderr, "mv :target name too long\n");
  1850                                  ;			return(1);
  1851                                  ;		}
  1852                                  ;		strcpy(buf, target);
  1853                                  ;		target = buf;
  1854                                  ;		strcat(buf, SDELIM);
  1855                                  ;		strcat(buf, dname(source));
  1856                                  ;		if (stat(target, &s2) >= 0) {
  1857                                  ;			fprintf(stderr, "mv: %s exists\n", buf);
  1858                                  ;			return(1);
  1859                                  ;		}
  1860                                  ;	}
  1861                                  ;	if (strcmp(source, target) == 0) {
  1862                                  ;		fprintf(stderr, "mv: ?? source == target, source exists and target doesnt\n");
  1863                                  ;		return(1);
  1864                                  ;	}
  1865                                  ;	p = dname(source);
  1866                                  ;	if (!strcmp(p, DOT) || !strcmp(p, DOTDOT) || !strcmp(p, "") || p[strlen(p)-1]=='/') {
  1867                                  ;		fprintf(stderr, "mv: cannot rename %s\n", p);
  1868                                  ;		return(1);
  1869                                  ;	}
  1870                                  ;	if (stat(pname(source), &s1) < 0 || stat(pname(target), &s2) < 0) {
  1871                                  ;		fprintf(stderr, "mv: cannot locate parent\n");
  1872                                  ;		return(1);
  1873                                  ;	}
  1874                                  ;	if (access(pname(target), 2) < 0) {
  1875                                  ;		fprintf(stderr, "mv: no write access to %s\n", pname(target));
  1876                                  ;		return(1);
  1877                                  ;	}
  1878                                  ;	if (access(pname(source), 2) < 0) {
  1879                                  ;		fprintf(stderr, "mv: no write access to %s\n", pname(source));
  1880                                  ;		return(1);
  1881                                  ;	}
  1882                                  ;	if (access(source, 2) < 0) {
  1883                                  ;		fprintf(stderr, "mv: no write access to %s\n", source);
  1884                                  ;		return(1);
  1885                                  ;	}
  1886                                  ;	if (s1.st_dev != s2.st_dev) {
  1887                                  ;		fprintf(stderr, "mv: cannot move directories across devices\n");
  1888                                  ;		return(1);
  1889                                  ;	}
  1890                                  ;	if (s1.st_ino != s2.st_ino) {
  1891                                  ;		char dst[MAXN+5];
  1892                                  ;
  1893                                  ;		if (chkdot(source) || chkdot(target)) {
  1894                                  ;			fprintf(stderr, "mv: Sorry, path names including %s aren't allowed\n", DOTDOT);
  1895                                  ;			return(1);
  1896                                  ;		}
  1897                                  ;		stat(source, &s1);
  1898                                  ;		if (check(pname(target), s1.st_ino))
  1899                                  ;			return(1);
  1900                                  ;		for (i = 1; i <= NSIG; i++)
  1901                                  ;			signal(i, SIG_IGN);
  1902                                  ;		if (link(source, target) < 0) {
  1903                                  ;			fprintf(stderr, "mv: cannot link %s to %s\n", target, source);
  1904                                  ;			return(1);
  1905                                  ;		}
  1906                                  ;		if (unlink(source) < 0) {
  1907                                  ;			fprintf(stderr, "mv: %s: cannot unlink\n", source);
  1908                                  ;			unlink(target);
  1909                                  ;			return(1);
  1910                                  ;		}
  1911                                  ;		strcat(dst, target);
  1912                                  ;		strcat(dst, "/");
  1913                                  ;		strcat(dst, DOTDOT);
  1914                                  ;		if (unlink(dst) < 0) {
  1915                                  ;			fprintf(stderr, "mv: %s: cannot unlink\n", dst);
  1916                                  ;			if (link(target, source) >= 0)
  1917                                  ;				unlink(target);
  1918                                  ;			return(1);
  1919                                  ;		}
  1920                                  ;		if (link(pname(target), dst) < 0) {
  1921                                  ;			fprintf(stderr, "mv: cannot link %s to %s\n",
  1922                                  ;				dst, pname(target));
  1923                                  ;			if (link(pname(source), dst) >= 0)
  1924                                  ;				if (link(target, source) >= 0)
  1925                                  ;					unlink(target);
  1926                                  ;			return(1);
  1927                                  ;		}
  1928                                  ;		return(0);
  1929                                  ;	}
  1930                                  ;	if (link(source, target) < 0) {
  1931                                  ;		fprintf(stderr, "mv: cannot link %s and %s\n",
  1932                                  ;			source, target);
  1933                                  ;		return(1);
  1934                                  ;	}
  1935                                  ;	if (unlink(source) < 0) {
  1936                                  ;		fprintf(stderr, "mv: ?? cannot unlink %s\n", source);
  1937                                  ;		return(1);
  1938                                  ;	}
  1939                                  ;	return(0);
  1940                                  ;}
  1941                                  ;
  1942                                  ;char *
  1943                                  ;pname(name)
  1944                                  ;register char *name;
  1945                                  ;{
  1946                                  ;	register c;
  1947                                  ;	register char *p, *q;
  1948                                  ;	static	char buf[MAXN];
  1949                                  ;
  1950                                  ;	p = q = buf;
  1951                                  ;	while (c = *p++ = *name++)
  1952                                  ;		if (c == DELIM)
  1953                                  ;			q = p-1;
  1954                                  ;	if (q == buf && *q == DELIM)
  1955                                  ;		q++;
  1956                                  ;	*q = 0;
  1957                                  ;	return buf[0]? buf : DOT;
  1958                                  ;}
  1959                                  ;
  1960                                  ;char *
  1961                                  ;dname(name)
  1962                                  ;register char *name;
  1963                                  ;{
  1964                                  ;	register char *p;
  1965                                  ;
  1966                                  ;	p = name;
  1967                                  ;	while (*p)
  1968                                  ;		if (*p++ == DELIM && *p)
  1969                                  ;			name = p;
  1970                                  ;	return name;
  1971                                  ;}
  1972                                  ;
  1973                                  ;check(spth, dinode)
  1974                                  ;char *spth;
  1975                                  ;ino_t dinode;
  1976                                  ;{
  1977                                  ;	char nspth[MAXN];
  1978                                  ;	struct stat sbuf;
  1979                                  ;
  1980                                  ;	sbuf.st_ino = 0;
  1981                                  ;
  1982                                  ;	strcpy(nspth, spth);
  1983                                  ;	while (sbuf.st_ino != ROOTINO) {
  1984                                  ;		if (stat(nspth, &sbuf) < 0) {
  1985                                  ;			fprintf(stderr, "mv: cannot access %s\n", nspth);
  1986                                  ;			return(1);
  1987                                  ;		}
  1988                                  ;		if (sbuf.st_ino == dinode) {
  1989                                  ;			fprintf(stderr, "mv: cannot move a directory into itself\n");
  1990                                  ;			return(1);
  1991                                  ;		}
  1992                                  ;		if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) {
  1993                                  ;			fprintf(stderr, "mv: name too long\n");
  1994                                  ;			return(1);
  1995                                  ;		}
  1996                                  ;		strcat(nspth, SDELIM);
  1997                                  ;		strcat(nspth, DOTDOT);
  1998                                  ;	}
  1999                                  ;	return(0);
  2000                                  ;}
  2001                                  ;
  2002                                  ;chkdot(s)
  2003                                  ;register char *s;
  2004                                  ;{
  2005                                  ;	do {
  2006                                  ;		if (strcmp(dname(s), DOTDOT) == 0)
  2007                                  ;			return(1);
  2008                                  ;		s = pname(s);
  2009                                  ;	} while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0);
  2010                                  ;	return(0);
  2011                                  ;}
  2012                                  ;
