     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[4006]                	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[5506]                	mov	ax, program_msg
   248 00000010 E81506                  	call	print_msg
   249                                  mv_usage:
   250                                  	;sys	_msg, usage_msg, 255, 07h
   251 00000013 B8[8D06]                	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[0409]            <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[EF06]                	mov	ax, msg_cant_access
   269                                  	; 24/05/2022
   270 00000028 E8FD05                  	call	print_msg
   271 0000002B 89F8                    	mov	ax, di  ; argv[1]
   272 0000002D E8F805                  	call	print_msg
   273 00000030 B8[BF06]                	mov	ax, nextline
   274                                  print_exit:
   275 00000033 E8F205                  	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[F608]                	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[0709]40            	test	byte [st1buf+stat.mode+1], S_IFDIR
   300 00000048 740F                    	jz	short mv_2
   301                                  
   302 0000004A 803E[4006]03            	cmp	byte [argc], 3
   303 0000004F 75C2                    	jne	short mv_usage
   304                                  
   305 00000051 5D                      	pop	bp ; argv[2]
   306                                  
   307 00000052 E8E501                  	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[EA08]                	mov	ax, err_msg
   319 0000006A EBC7                    	jmp	short print_exit
   320                                  mv_3:
   321                                  	; (here [sp] = argv[2]) 
   322 0000006C A0[4006]                	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[4006]02            	sub	byte [argc], 2
   339 0000007F 803E[4006]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[2809]            <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[2B09]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[4106]              	inc	byte [errors]
   372                                  mv_7:
   373 000000A5 FE0E[4006]              	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[4106]00            	cmp	byte [errors], 0
   380 000000B3 7706                    	ja	short mv_9
   381                                  
   382 000000B5 B8[F608]                	mov	ax, msg_ok
   383                                  	;jmp	print_exit
   384 000000B8 E86D05                  	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[0409]            <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[EF06]                	mov	ax, msg_cant_access
   410                                  	; 24/05/2022
   411 000000CD E85805                  	call	print_msg
   412 000000D0 89F8                    	mov	ax, di ; source
   413 000000D2 E85305                  	call	print_msg
   414 000000D5 B8[BF06]                	mov	ax, nextline
   415                                  move_err:
   416 000000D8 E84D05                  	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[0209]                	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[0709]40            	test	byte [st1buf+stat.mode+1], S_IFDIR
   434 000000E5 7405                    	jz	short mv_11
   435                                  
   436 000000E7 B8[0407]                	mov	ax, msg_rename_only
   437 000000EA EBEC                    	jmp	short move_err
   438                                  mv_11:
   439                                  	; 26/05/2022
   440 000000EC 892E[0009]              	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[2809]            <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 E9C400                  	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[2609]                	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[2B09]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 E86F03                  	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[4A09]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000010F B9[2809]            <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 E9A700                  	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[2609]                	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[2B09]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[C206]                	mov	ax, mv_header
   517 00000129 E8FC04                  	call	print_msg
   518 0000012C B8[4A09]                	mov	ax, buf  ; target
   519 0000012F E8F604                  	call	print_msg
   520 00000132 B8[DC06]                	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[0409]                	mov	ax, [st1buf+stat.inode]
   526 0000013A 3B06[2809]              	cmp	ax, [st2buf+stat.inode]
   527 0000013E 7526                    	jne	short mv_15
   528                                  	; 26/05/2022
   529 00000140 A1[0209]                	mov	ax, [st1dev]
   530 00000143 3B06[2609]              	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[C206]                	mov	ax, mv_header
   540 0000014C E8D904                  	call	print_msg
   541 0000014F 89F8                    	mov	ax, di ; source
   542 00000151 E8D404                  	call	print_msg
   543 00000154 B8[7308]                	mov	ax, msg_and
   544 00000157 E8CE04                  	call	print_msg
   545 0000015A A1[0009]                	mov	ax, [target] ; target ; 26/05/2022
   546 0000015D E8C804                  	call	print_msg
   547 00000160 B8[7908]                	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[2809]                	mov	si, st2buf
   553 00000169 E82804                  	call	access
   554 0000016C 7539                    	jnz	short mv_18
   555                                  	; not permitted
   556                                  
   557 0000016E E83904                  	call	isatty
   558 00000171 7234                    	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[C206]                	mov	ax, mv_header
   564 00000176 E8AF04                  	call	print_msg
   565 00000179 A1[0009]                	mov	ax, [target] ; target ; 26/05/2022
   566 0000017C E8A904                  	call	print_msg
   567 0000017F 8B1E[2A09]              	mov	bx, [st2buf+stat.mode]
   568 00000183 83E31F                  	and	bx, MODEBITS
   569 00000186 BE[EC0A]                	mov	si, octm 
   570 00000189 E83C04                  	call	octalnumber
   571 0000018C B8[EC0A]                	mov	ax, octm
   572 0000018F E89604                  	call	print_msg
   573                                  
   574                                  	; i = c = getchar();
   575 00000192 E86604                  	call	getchar
   576                                  	
   577 00000195 3C79                    	cmp	al, 'y'
   578 00000197 7408                    	je	short mv_17
   579                                  
   580 00000199 B8[E308]                	mov	ax, msg_no
   581                                  mv_16:
   582 0000019C E88904                  	call	print_msg
   583 0000019F F9                      	stc
   584 000001A0 C3                      	retn
   585                                  mv_17:
   586 000001A1 B8[DB08]                	mov	ax, msg_yes
   587 000001A4 E88104                  	call	print_msg
   588                                  mv_18:
   589                                  	; if (unlink(target) < 0)	
   590                                  	sys	_unlink, [target] ; 26/05/2022
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000001A7 8B1E[0009]          <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 000001AB B80A00              <1>  mov ax, %1
   102 000001AE CD20                <1>  int 20h
   591 000001B0 7311                    	jnc	short mv_20
   592                                  
   593                                  	; fprintf(stderr, "mv: cannot unlink %s\n", target);
   594 000001B2 B8[2207]                	mov	ax, msg_cant_unlink
   595 000001B5 E87004                  	call	print_msg
   596 000001B8 A1[0009]                	mov	ax, [target] ; 26/05/2022
   597 000001BB E86A04                  	call	print_msg
   598 000001BE B8[BF06]                	mov	ax, nextline 
   599 000001C1 EBD9                    	jmp	short mv_16	
   600                                  mv_19:
   601                                  	; 26/05/2022
   602                                  	;mov	[target], bp ; target
   603                                  mv_20:
   604                                  	; if (link(source, target) < 0)
   605                                  
   606                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000001C3 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000001C5 8B0E[0009]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000001C9 B80900              <1>  mov ax, %1
   102 000001CC CD20                <1>  int 20h
   607 000001CE 7350                    	jnc	short mv_25
   608                                  
   609 000001D0 BB[DF01]                	mov	bx, mv_21  ; child process jump address	
   610                                  	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 000001D3 B80200              <1>  mov ax, %1
   102 000001D6 CD20                <1>  int 20h
   611 000001D8 7320                    	jnc	short mv_22 ; parent return and jump
   612                                  
   613 000001DA B8[3707]                	mov	ax, msg_try_again
   614 000001DD EBBD                    	jmp	short mv_16
   615                                  mv_21:
   616                                  	; child process will continue from here
   617                                  	
   618 000001DF A1[0009]                	mov	ax, [target]
   619 000001E2 A3[4E06]                	mov	[cp_target], ax
   620 000001E5 893E[4C06]              	mov	[cp_source], di
   621                                  
   622                                  	sys	_exec, cp_cmd, cp_args
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000001E9 BB[4206]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000001EC B9[4A06]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000001EF B80B00              <1>  mov ax, %1
   102 000001F2 CD20                <1>  int 20h
   623                                  	
   624                                  	; fprintf(stderr, "mv: cannot exec cp\n");
   625 000001F4 B8[4907]                	mov	ax, msg_cant_exec_cp
   626                                  	;call	print_msg
   627                                  	;jmp	_exit_
   628                                  	; 23/05/2022
   629 000001F7 E939FE                  	jmp	print_exit
   630                                  
   631                                  mv_22:
   632 000001FA 89C2                    	mov	dx, ax ; child process id
   633                                  mv_23:
   634                                  	; while ((c = wait(&status)) != i && c != -1)
   635                                  	;if (status != 0)
   636                                  	;	return(1);
   637                                  	; utime(target, &s1.st_atime);
   638                                  
   639                                  	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 000001FC B80700              <1>  mov ax, %1
   102 000001FF CD20                <1>  int 20h
   640 00000201 721C                    	jc	short mv_24
   641                                  
   642 00000203 39D0                    	cmp	ax, dx
   643 00000205 75F5                     	jne	short mv_23
   644                                  
   645                                  	; 26/05/2022 (check if /bin/cp has been failed) 
   646                                  	sys	_stat, [target], fstbuf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000207 8B1E[0009]          <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000020B B9[660A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000020E B81200              <1>  mov ax, %1
   102 00000211 CD20                <1>  int 20h
   647 00000213 720A                    	jc	short mv_24
   648 00000215 A1[6C0A]                	mov	ax, [fstbuf+stat.size]
   649 00000218 3B06[0A09]              	cmp	ax, [st1buf+stat.size]
   650 0000021C 7402                    	je	short mv_25
   651 0000021E F9                      	stc
   652                                  mv_24:
   653 0000021F C3                      	retn
   654                                  
   655                                  	; utime(target, &s1.st_atime);
   656                                  
   657                                  	;;;
   658                                  mv_25:
   659                                  	;if (unlink(source) < 0) {
   660                                  	;	fprintf(stderr, "mv: cannot unlink %s\n", source);
   661                                  	;	return(1);
   662                                  	;}
   663                                  
   664                                  	sys	_unlink, di
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000220 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 00000222 B80A00              <1>  mov ax, %1
   102 00000225 CD20                <1>  int 20h
   665 00000227 73F6                    	jnc	short mv_24
   666                                  
   667 00000229 B8[2207]                	mov	ax, msg_cant_unlink
   668 0000022C E8F903                  	call	print_msg
   669 0000022F 89F8                    	mov	ax, di ; source
   670 00000231 E8F403                  	call	print_msg
   671 00000234 B8[BF06]                	mov	ax, nextline	
   672                                  	;if (status != 0)
   673                                  	;	return(1);
   674 00000237 E962FF                  	jmp	mv_16
   675                                  
   676                                  ;-----------------------------------------------------------------
   677                                  
   678                                  mvdir:
   679                                  	; 27/05/2022
   680                                  	; 26/05/2022
   681                                  	; 23/05/2022
   682                                  	; 22/05/2022
   683                                  	
   684                                  	; mvdir(source, target)
   685                                  
   686                                  	; INPUT:
   687                                  	;	di = source
   688                                  	;	bp = target
   689                                  	; OUTPUT:
   690                                  	;	cf = 0 -> ok
   691                                  	;	cf = 1 -> error
   692                                  
   693                                  	; st1buf = source (inode) stat(us) buffer
   694                                  
   695                                  	;if (stat(target, &s2) >= 0) 
   696                                  	sys	_stat, bp, st2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000023A 89EB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000023C B9[2809]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000023F B81200              <1>  mov ax, %1
   102 00000242 CD20                <1>  int 20h
   697 00000244 722D                    	jc	short mv_29
   698                                  
   699                                  	;if ((s2.st_mode&S_IFMT) != S_IFDIR)
   700                                  	
   701                                  	; Retro UNIX 386 v1.2
   702                                  	;mov	[st2dev], eax
   703                                  	;mov	al, byte [st2buf+stat.mode+1]
   704                                  	;and	al, S_IFREG|S_IFDIR
   705                                  	;cmp	al, S_IFREG|S_IFDIR
   706                                  	;je	short mv_28
   707                                  
   708                                  	; Retro UNIX 386 v1 (& v1.1)
   709                                  	;mov	[st2dev], ax ; device number
   710                                  			     ; (0 = root fs)
   711                                  			     ; (1 = mounted fs)
   712                                  
   713                                  	;if ((s2.st_mode & S_IFMT) == S_IFDIR)
   714 00000246 F606[2B09]40            	test	byte [st2buf+stat.mode+1], S_IFDIR
   715 0000024B 7513                    	jnz	short mv_28
   716                                  
   717                                  	;fprintf(stderr, "mv: %s exists\n", target);
   718                                  
   719 0000024D 55                      	push	bp ; target
   720                                  mv_27:
   721 0000024E B8[C206]                	mov	ax, mv_header
   722 00000251 E8D403                  	call	print_msg	
   723 00000254 58                      	pop	ax  ; target
   724 00000255 E8D003                  	call	print_msg 
   725 00000258 B8[6007]                	mov	ax, msg_exists
   726 0000025B E8CA03                  	call	print_msg
   727 0000025E F9                      	stc
   728 0000025F C3                      	retn
   729                                  
   730                                  mv_28:
   731                                  	;if (strlen(target) > MAXN-DIRSIZ-2) {
   732                                  	;	fprintf(stderr, "mv: target name too long\n");
   733                                  	;	return(1);
   734                                  	;}
   735                                  
   736                                  	;strcpy(buf, target);
   737                                  
   738                                  ;	mov	si, bp ; target
   739                                  ;	mov	dx, di ; source
   740                                  ;	mov	di, buf ; pathname buffer (100 bytes)
   741                                  ;	mov	[target], di 
   742                                  ;mv_29:
   743                                  ;	lodsb
   744                                  ;	stosb
   745                                  ;	and	al, al
   746                                  ;	jnz	short mv_29
   747                                  	
   748                                  	;strcat(buf, SDELIM);
   749                                  	;strcat(buf, dname(source));
   750                                  
   751 00000260 E81802                  	call	strcpy ; 27/05/2022
   752                                  
   753                                  	sys	_stat, buf, st2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000263 BB[4A09]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000266 B9[2809]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000269 B81200              <1>  mov ax, %1
   102 0000026C CD20                <1>  int 20h
   754 0000026E 7207                    	jc	short mv_30
   755                                  
   756 00000270 53                      	push	bx ; buf ; [target]
   757 00000271 EBDB                    	jmp	short mv_27
   758                                  
   759                                  mv_29:
   760 00000273 892E[0009]              	mov	[target], bp
   761                                  mv_30:
   762                                  	; if (strcmp(source, target) == 0) {
   763                                  	
   764 00000277 57                      	push	di
   765 00000278 89FE                    	mov	si, di
   766 0000027A 8B3E[0009]              	mov	di, [target]
   767 0000027E E82302                  	call	strcmp
   768 00000281 5F                      	pop	di
   769 00000282 7508                    	jne	short mv_32
   770                                  
   771 00000284 B8[6B07]                	mov	ax, msg_src_target
   772                                  mv_31:
   773 00000287 E89E03                  	call	print_msg
   774 0000028A F9                      	stc
   775 0000028B C3                      	retn
   776                                  
   777                                  mv_32:
   778 0000028C 89FB                    	mov	bx, di
   779 0000028E BF[660A]                	mov	di, fstbuf ; (66 bytes buffer)
   780 00000291 53                      	push	bx ; *
   781 00000292 E81A02                  	call	dname
   782                                  	; bx = fstbuf = file name
   783                                  
   784                                  	;!strcmp(p, "")
   785 00000295 803F00                  	cmp	byte [bx], 0
   786 00000298 7419                    	je	short mv_33 ; null
   787                                  	;!strcmp(p, DOT)
   788 0000029A 89DE                    	mov	si, bx		
   789 0000029C 803C2E                  	cmp	byte [si], '.'
   790 0000029F 751E                    	jne	short mv_34
   791 000002A1 BF[5306]                	mov	di, DOT
   792 000002A4 E8FD01                  	call	strcmp
   793 000002A7 740A                    	je	short mv_33 ; '.'
   794                                  	;!strcmp(p, DOTDOT)
   795 000002A9 89DE                    	mov	si, bx
   796 000002AB BF[5206]                	mov	di, DOTDOT
   797 000002AE E8F301                  	call	strcmp
   798 000002B1 750C                    	jne	short mv_34
   799                                  	; '..'
   800                                  mv_33:
   801 000002B3 5F                      	pop	di ; *
   802                                  	
   803                                  	;fprintf(stderr, "mv: cannot rename %s\n", p);
   804 000002B4 B8[4608]                	mov	ax, msg_cant_rename
   805 000002B7 E86E03                  	call	print_msg
   806 000002BA B8[660A]                	mov	ax, fstbuf
   807 000002BD EBC8                    	jmp	short mv_31
   808                                  
   809                                  mv_34:
   810 000002BF 5F                      	pop	di ; *
   811 000002C0 BB[AE09]                	mov	bx, sbuf
   812                                  	; di = source
   813                                  	; bx = buffer
   814 000002C3 E80602                  	call	pname
   815                                  	; si = parent directory name address
   816                                  	;
   817                                  	;if (stat(pname(source), &s1) < 0 ||
   818                                  	sys	_stat, si, pst1buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000002C6 89F3                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000002C8 B9[A80A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000002CB B81200              <1>  mov ax, %1
   102 000002CE CD20                <1>  int 20h
   819 000002D0 7305                    	jnc	short mv_36
   820                                  mv_35:
   821 000002D2 B8[A807]                	mov	ax, msg_cant_locate
   822 000002D5 EBB0                     	jmp	short mv_31
   823                                  mv_36:
   824 000002D7 A3[0209]                	mov	[st1dev], ax
   825 000002DA 8B16[0009]              	mov	dx, [target]
   826 000002DE 87D7                    	xchg	dx, di
   827                                  	;stat(pname(target), &s2) < 0)
   828                                  	; di = source
   829 000002E0 BB[0A0A]                	mov	bx, tbuf ; buffer
   830 000002E3 E8E601                  	call	pname
   831                                  	; si = parent directory name address
   832 000002E6 89D7                    	mov	di, dx
   833                                  	sys	_stat, si, pst2buf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000002E8 89F3                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000002EA B9[CA0A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000002ED B81200              <1>  mov ax, %1
   102 000002F0 CD20                <1>  int 20h
   834 000002F2 72DE                    	jc	short mv_35
   835 000002F4 A3[2609]                	mov	[st2dev], ax
   836                                  	;if (access(pname(target), 2) < 0)		
   837 000002F7 BE[CA0A]                	mov	si, pst2buf
   838 000002FA E89702                  	call	access
   839 000002FD 7516                    	jnz	short mv_39
   840                                  	; permission denied !
   841 000002FF BA[0A0A]                	mov	dx, tbuf ; pname(target)
   842                                  mv_37:
   843 00000302 52                      	push	dx ; pname(target) or pname(source)
   844 00000303 B8[C507]                	mov	ax, msg_no_w_access
   845 00000306 E81F03                  	call	print_msg
   846 00000309 58                      	pop	ax ; pname(target) or pname(source)
   847 0000030A E81B03                  	call	print_msg
   848 0000030D B8[BF06]                	mov	ax, nextline
   849                                  mv_38:
   850 00000310 E81503                  	call	print_msg
   851 00000313 F9                      	stc
   852 00000314 C3                      	retn
   853                                  mv_39:
   854                                  	;if (access(pname(source), 2) < 0)
   855 00000315 BE[A80A]                	mov	si, pst1buf
   856 00000318 E87902                  	call	access
   857 0000031B 7505                    	jnz	short mv_40
   858                                  	; permission denied !
   859 0000031D BA[AE09]                	mov	dx, sbuf ; pname(source)
   860 00000320 EBE0                    	jmp	short mv_37
   861                                  mv_40:
   862                                  	;if (access(source, 2) < 0)
   863                                   	; di = source
   864 00000322 BE[0409]                	mov	si, st1buf 
   865                                  		; source (inode) stat(us) buffer
   866 00000325 E86C02                  	call	access
   867 00000328 7504                    	jnz	short mv_41
   868 0000032A 89FA                    	mov	dx, di ; source
   869 0000032C EBD4                    	jmp	short mv_37
   870                                  mv_41:
   871                                  	;if (s1.st_dev != s2.st_dev)
   872 0000032E A1[0209]                	mov	ax, [st1dev]
   873 00000331 3B06[2609]              	cmp	ax, [st2dev]
   874 00000335 7405                    	je	short mv_42
   875                                  	;fprintf(stderr, "mv: cannot move directories
   876                                  	;			 across devices\n");
   877 00000337 B8[DF07]                	mov	ax, msg_accross_devices
   878 0000033A EBD4                    	jmp	short mv_38
   879                                  mv_42:
   880                                  	;if (s1.st_ino != s2.st_ino)	
   881 0000033C A1[A80A]                	mov	ax, [pst1buf+stat.inode]
   882 0000033F 3B06[CA0A]              	cmp	ax, [pst2buf+stat.inode]
   883 00000343 7503                    	jne	short mv_43
   884 00000345 E9F400                  	jmp	mv_57
   885                                  mv_43:
   886                                  	; (move dir from parent dir to another dir)
   887                                  
   888                                  	;if (chkdot(source) || chkdot(target))
   889 00000348 89FB                    	mov	bx, di ; source
   890 0000034A E81102                  	call	chkdot
   891 0000034D 7305                    	jnc	short mv_45
   892                                  mv_44:
   893                                  	;fprintf(stderr, "mv: Sorry, path names
   894                                  	;	 including %s aren't allowed\n", DOTDOT);
   895 0000034F B8[0E08]                	mov	ax, msg_pathname_dotdot
   896 00000352 EBBC                    	jmp	short mv_38
   897                                  mv_45:
   898 00000354 8B1E[0009]              	mov	bx, [target] ; target
   899 00000358 E80302                  	call	chkdot
   900 0000035B 72F2                    	jc	short mv_44
   901                                  mv_46:
   902                                  	;stat(source, &s1);
   903                                  	;if (check(pname(target), s1.st_ino))
   904 0000035D BB[0A0A]                	mov	bx, tbuf
   905 00000360 E89A01                  	call	check
   906 00000363 722B                    	jc	short mv_49 ; return(1);
   907                                  mv_47:		
   908                                  	;for (i = 1; i <= NSIG; i++)
   909                                  	;	signal(i, SIG_IGN);
   910                                  	;   if (link(source, target) < 0) {
   911                                  	
   912                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000365 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000367 8B0E[0009]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000036B B80900              <1>  mov ax, %1
   102 0000036E CD20                <1>  int 20h
   913 00000370 731F                    	jnc	short mv_50
   914                                  	
   915                                  	; fprintf(stderr, "mv: cannot link %s to %s\n",
   916                                  	;		 target, source);
   917                                  mv_48:
   918 00000372 B8[5B08]                	mov	ax, msg_cant_link
   919 00000375 E8B002                  	call	print_msg
   920 00000378 A1[0009]                	mov	ax, [target] ; target
   921 0000037B E8AA02                  	call	print_msg
   922 0000037E B8[6E08]                	mov	ax, msg_to
   923 00000381 E8A402                  	call	print_msg
   924 00000384 89F8                    	mov	ax, di ; source
   925 00000386 E89F02                  	call	print_msg
   926 00000389 B8[BF06]                	mov	ax, nextline
   927 0000038C E89902                  	call	print_msg
   928 0000038F F9                      	stc
   929                                  mv_49:
   930 00000390 C3                      	retn
   931                                  mv_50:
   932                                   	;if (unlink(source) < 0) {
   933                                  	sys	_unlink, di	
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000391 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 00000393 B80A00              <1>  mov ax, %1
   102 00000396 CD20                <1>  int 20h
   934 00000398 731C                    	jnc	short mv_51
   935                                  
   936                                  	;fprintf(stderr, "mv: %s: cannot unlink\n", source);
   937 0000039A B8[2207]                	mov	ax, msg_cant_unlink
   938 0000039D E88802                  	call	print_msg
   939 000003A0 89F8                    	mov	ax, di ; source
   940 000003A2 E88302                  	call	print_msg
   941 000003A5 B8[BF06]                	mov	ax, nextline
   942 000003A8 E87D02                  	call	print_msg
   943                                  	;unlink(target);
   944                                  	sys	_unlink, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000003AB 8B1E[0009]          <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 000003AF B80A00              <1>  mov ax, %1
   102 000003B2 CD20                <1>  int 20h
   945                                  	;return(1);
   946 000003B4 F9                      	stc
   947 000003B5 C3                      	retn
   948                                  mv_51:
   949                                  	;strcat(dst, target);
   950                                  	;strcat(dst, "/");
   951                                  	;strcat(dst, DOTDOT);
   952                                  
   953 000003B6 8B36[0009]              	mov	si, [target]
   954 000003BA 57                      	push	di ; *
   955 000003BB BF[F20A]                	mov	di, nspth 
   956                                  mv_52:
   957 000003BE AC                      	lodsb
   958 000003BF AA                      	stosb
   959 000003C0 20C0                    	and	al, al
   960 000003C2 75FA                    	jnz	short mv_52
   961 000003C4 4F                      	dec	di
   962                                  	; 27/05/2022
   963 000003C5 B82F2E                  	mov	ax, 2E2Fh ; db '/..', 0  
   964 000003C8 AB                      	stosw
   965 000003C9 B82E00                  	mov	ax, 02Eh
   966 000003CC AB                      	stosw
   967 000003CD 5F                      	pop	di ; *
   968                                  
   969                                  	;if (unlink(dst) < 0)
   970                                  	sys	_unlink, nspth
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000003CE BB[F20A]            <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 000003D1 B80A00              <1>  mov ax, %1
   102 000003D4 CD20                <1>  int 20h
   971 000003D6 732A                    	jnc	short mv_56
   972                                  
   973                                  	; fprintf(stderr, "mv: %s: cannot unlink\n", dst);
   974 000003D8 B8[2207]                	mov	ax, msg_cant_unlink
   975 000003DB E84A02                  	call	print_msg
   976 000003DE B8[F20A]                	mov	ax, nspth ; dst
   977 000003E1 E84402                  	call	print_msg
   978 000003E4 B8[BF06]                	mov	ax, nextline
   979 000003E7 E83E02                  	call	print_msg
   980                                  mv_53:
   981                                  	;if (link(target, source) >= 0)
   982                                  	;	unlink(target);
   983                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000003EA 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000003EC 8B0E[0009]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000003F0 B80900              <1>  mov ax, %1
   102 000003F3 CD20                <1>  int 20h
   984 000003F5 720A                    	jc	short mv_55
   985                                  mv_54:
   986                                  	;unlink(target);
   987                                  	sys	_unlink, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000003F7 8B1E[0009]          <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 000003FB B80A00              <1>  mov ax, %1
   102 000003FE CD20                <1>  int 20h
   988                                  	;return(1);
   989 00000400 F9                      	stc
   990                                  mv_55:
   991 00000401 C3                      	retn
   992                                  mv_56:
   993                                  	;if (link(pname(target), dst) < 0)
   994                                  	sys	_link, tbuf, nspth
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000402 BB[0A0A]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000405 B9[F20A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000408 B80900              <1>  mov ax, %1
   102 0000040B CD20                <1>  int 20h
   995 0000040D 73F2                    	jnc	short mv_55 ;return(0)
   996                                  
   997                                  	;fprintf(stderr, "mv: cannot link %s to %s\n",
   998                                  	;		dst, pname(target));
   999 0000040F B8[5B08]                	mov	ax, msg_cant_link
  1000 00000412 E81302                  	call	print_msg
  1001 00000415 B8[F20A]                	mov	ax, nspth ; dst
  1002 00000418 E80D02                  	call	print_msg
  1003 0000041B B8[6E08]                	mov	ax, msg_to
  1004 0000041E E80702                  	call	print_msg
  1005 00000421 B8[0A0A]                	mov	ax, tbuf ; pname(taget)
  1006 00000424 E80102                  	call	print_msg
  1007 00000427 B8[BF06]                	mov	ax, nextline
  1008 0000042A E8FB01                  	call	print_msg
  1009                                  	;if (link(pname(source), dst) >= 0)
  1010                                  	sys	_link, sbuf, nspth
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000042D BB[AE09]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000430 B9[F20A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000433 B80900              <1>  mov ax, %1
   102 00000436 CD20                <1>  int 20h
  1011 00000438 72C7                    	jc	short mv_55
  1012                                  	;if (link(target, source) >= 0)
  1013                                  	;	unlink(target);
  1014 0000043A EBAE                    	jmp	short mv_53
  1015                                  
  1016                                  mv_57:
  1017                                  	; (move dir in same parent directory)
  1018                                   
  1019                                  	;if (link(source, target) < 0)
  1020                                  	sys	_link, di, [target]
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000043C 89FB                <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 0000043E 8B0E[0009]          <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000442 B80900              <1>  mov ax, %1
   102 00000445 CD20                <1>  int 20h
  1021 00000447 731F                    	jnc	short mv_60
  1022                                  	;fprintf(stderr, "mv: cannot link %s and %s\n",
  1023                                  	;		source, target);
  1024 00000449 B8[5B08]                	mov	ax, msg_cant_link
  1025 0000044C E8D901                  	call	print_msg
  1026 0000044F 89F8                    	mov	ax, di ; source
  1027 00000451 E8D401                  	call	print_msg
  1028 00000454 B8[7308]                	mov	ax, msg_and
  1029 00000457 E8CE01                  	call	print_msg
  1030 0000045A A1[0009]                	mov	ax, [target] ; target
  1031                                  mv_58:
  1032 0000045D E8C801                  	call	print_msg
  1033 00000460 B8[BF06]                	mov	ax, nextline
  1034 00000463 E8C201                  	call	print_msg
  1035                                  	;return(1);
  1036 00000466 F9                      	stc
  1037                                  mv_59:
  1038 00000467 C3                      	retn	
  1039                                  mv_60:
  1040                                  	;if (unlink(source) < 0) {
  1041                                  	sys	_unlink, di
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000468 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 0000046A B80A00              <1>  mov ax, %1
   102 0000046D CD20                <1>  int 20h
  1042 0000046F 73F6                    	jnc	short mv_59 ;return(0)
  1043                                  	
  1044                                  	;fprintf(stderr, "mv: ?? cannot unlink
  1045                                  	;		 %s\n", source);
  1046                                  	
  1047 00000471 B8[2207]                	mov	ax, msg_cant_unlink
  1048 00000474 E8B101                  	call	print_msg
  1049 00000477 89F8                    	mov	ax, di ; source
  1050 00000479 EBE2                    	jmp	short mv_58
  1051                                  
  1052                                  ;-----------------------------------------------------------------
  1053                                  
  1054                                  strcpy:
  1055 0000047B 89EE                    	mov	si, bp ; target
  1056                                  	; 27/05/2022 (bx -> cx, dx -> bx)
  1057 0000047D 89FB                    	mov	bx, di ; source
  1058 0000047F 89D9                    	mov	cx, bx
  1059 00000481 BF[4A09]                	mov	di, buf ; pathname buffer (100 bytes)
  1060 00000484 893E[0009]              	mov	[target], di
  1061                                  strcp_1:
  1062 00000488 AC                      	lodsb
  1063 00000489 08C0                    	or	al, al
  1064 0000048B 7403                    	jz	short strcp_2
  1065 0000048D AA                      	stosb
  1066 0000048E EBF8                    	jmp	short strcp_1
  1067                                  strcp_2:
  1068                                  	; 27/05/2022
  1069 00000490 B02F                    	mov	al, DELIM ; '/'
  1070 00000492 81FF[4A09]              	cmp	di, buf
  1071 00000496 7605                    	jna	short strcp_3
  1072                                  	;cmp	byte [di-1], DELIM  ; '/'
  1073 00000498 3845FF                  	cmp	byte [di-1], al ; '/'
  1074 0000049B 7401                    	je	short strcp_4
  1075                                  strcp_3:
  1076                                  	;mov	al, DELIM ; '/'
  1077 0000049D AA                      	stosb
  1078                                  strcp_4:	
  1079                                  	; bx = source (pathname)
  1080                                  	; di = buffer (offset) position
  1081 0000049E E80E00                  	call	dname
  1082 000004A1 89CF                    	mov	di, cx	; source
  1083                                  			; target = buf;
  1084 000004A3 C3                      	retn
  1085                                  
  1086                                  ;-----------------------------------------------------------------
  1087                                  
  1088                                  strcmp:
  1089                                  	; si = source
  1090                                  	; di = target
  1091                                  strcmp_1:
  1092 000004A4 AC                      	lodsb
  1093 000004A5 08C0                    	or	al, al
  1094 000004A7 7404                    	jz	short strcmp_2
  1095 000004A9 AE                      	scasb
  1096 000004AA 74F8                    	je	short strcmp_1
  1097 000004AC C3                      	retn
  1098                                  strcmp_2:
  1099                                  	;cmp	[di], al ; 0
  1100 000004AD AE                      	scasb
  1101                                  strcmp_3:
  1102                                  	; zf = 1 -> same
  1103 000004AE C3                      	retn
  1104                                  	
  1105                                  ;-----------------------------------------------------------------
  1106                                  
  1107                                  dname:	; dname(name)
  1108                                  	; 27/05/2022 (dx -> bx)
  1109                                  	; bx = source (pathname)
  1110                                  	; di = buffer (offset) position
  1111                                  dname_0:
  1112 000004AF 89DE                    	mov	si, bx  ; name
  1113                                  	;p = name;
  1114                                  	;while (*p)
  1115                                  dname_1:
  1116 000004B1 AC                      	lodsb
  1117 000004B2 20C0                    	and	al, al
  1118 000004B4 740D                    	jz	short dname_2
  1119 000004B6 3C2F                    	cmp	al, DELIM  ; cmp al, '/'
  1120 000004B8 75F7                    	jne	short dname_1
  1121                                  	;if (*p++ == DELIM && *p)
  1122 000004BA 803C00                  	cmp	byte [si], 0
  1123                                  	;je	short dname_1
  1124 000004BD 7404                    	je	short dname_2
  1125 000004BF 89F3                    	mov	bx, si
  1126 000004C1 EBEE                    	jmp	short dname_1
  1127                                  dname_2:
  1128                                  	; dx = file name
  1129 000004C3 89DE                    	mov	si, bx
  1130                                  dname_3:
  1131 000004C5 AC                      	lodsb
  1132 000004C6 AA                      	stosb
  1133 000004C7 08C0                    	or	al, al	
  1134 000004C9 75FA                    	jnz	short dname_3
  1135 000004CB C3                      	retn
  1136                                  
  1137                                  ;-----------------------------------------------------------------
  1138                                  
  1139                                  pname:	; pname(name)
  1140                                  	; 23/05/2022
  1141                                  
  1142                                  	; INPUT:
  1143                                  	;	di = source (pathname)
  1144                                  	;	bx = buffer address
  1145                                  	; OUTPUT:
  1146                                  	;	si = parent dir name address
  1147                                  pname_0:
  1148 000004CC 89FE                    	mov	si, di ; source
  1149 000004CE 57                      	push	di ; *
  1150                                  	;p = q = buf;
  1151 000004CF 89DF                    	mov	di, bx
  1152 000004D1 89D9                    	mov	cx, bx
  1153                                  	; while (c = *p++ = *name++)
  1154                                  pname_1:
  1155 000004D3 AC                      	lodsb
  1156 000004D4 AA                      	stosb
  1157 000004D5 20C0                    	and	al, al
  1158 000004D7 7409                    	jz	short pname_2
  1159                                  	;if (c == DELIM)
  1160                                  	;	q = p-1;
  1161 000004D9 3C2F                    	cmp	al, DELIM  ; cmp al, '/'
  1162 000004DB 75F6                    	jne	short pname_1
  1163 000004DD 89FB                    	mov	bx, di
  1164 000004DF 4B                      	dec	bx
  1165 000004E0 EBF1                    	jmp	short pname_1
  1166                                  pname_2:
  1167                                  	;if (q == buf && *q == DELIM)
  1168                                  	;    q++;
  1169 000004E2 39CB                    	cmp	bx, cx
  1170 000004E4 7506                    	jne	short pname_3
  1171 000004E6 803F2F                  	cmp	byte [bx], DELIM ; '/'
  1172 000004E9 7501                    	jne	short pname_3
  1173 000004EB 43                      	inc	bx	
  1174                                  pname_3:
  1175                                  	;*q = 0;
  1176 000004EC C60700                  	mov	byte [bx], 0
  1177 000004EF 89CE                    	mov	si, cx
  1178 000004F1 5F                      	pop	di ; *
  1179                                  	; return buf[0]? buf : DOT;
  1180 000004F2 803C00                  	cmp	byte [si], 0
  1181 000004F5 7705                    	ja	short pname_4
  1182 000004F7 A1[5306]                	mov	ax, [DOT] ; db '.', 0
  1183 000004FA 8904                    	mov	[si], ax
  1184                                  pname_4:
  1185 000004FC C3                      	retn
  1186                                  
  1187                                  ;-----------------------------------------------------------------
  1188                                  
  1189                                  check:	; check(spth, dinode)
  1190                                  	; 23/05/2022
  1191                                  
  1192                                  	; INPUT:
  1193                                  	;	bx = name buffer address
  1194                                  	;	[st1buf+stat.inode] = inode num to be compared
  1195                                  	; OUTPUT:
  1196                                  	;	cf = 1 -> error
  1197                                  	;	cf = 0 -> no problem
  1198                                  
  1199                                  	;strcpy(nspth, spth);
  1200                                  
  1201 000004FD 89DE                    	mov	si, bx
  1202 000004FF 57                      	push	di ; *
  1203 00000500 BF[F20A]                	mov	di, nspth 
  1204                                  check_1:
  1205 00000503 AC                      	lodsb
  1206 00000504 AA                      	stosb
  1207 00000505 20C0                    	and	al, al
  1208 00000507 75FA                    	jnz	short check_1
  1209 00000509 29DE                    	sub	si, bx 
  1210 0000050B 4E                      	dec	si ; si = strlen(nspth)
  1211 0000050C 5F                      	pop	di ; *
  1212                                  check_2:
  1213                                  	;if (stat(nspth, &sbuf) < 0)
  1214                                  	sys	_stat, nspth, fstbuf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 0000050D BB[F20A]            <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000510 B9[660A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000513 B81200              <1>  mov ax, %1
   102 00000516 CD20                <1>  int 20h
  1215 00000518 7314                    	jnc	short check_5
  1216                                  	;fprintf(stderr, "mv: cannot access %s\n", nspth);
  1217 0000051A B8[EF06]                	mov	ax, msg_cant_access
  1218 0000051D E80801                  	call	print_msg
  1219 00000520 B8[F20A]                	mov	ax, nspth
  1220 00000523 E80201                  	call	print_msg
  1221 00000526 B8[BF06]                	mov	ax, nextline
  1222                                  check_3:
  1223 00000529 E8FC00                  	call	print_msg
  1224 0000052C F9                      	stc
  1225                                  check_4:
  1226 0000052D C3                      	retn
  1227                                  check_5:
  1228                                  	;if (sbuf.st_ino == dinode)
  1229 0000052E A1[660A]                	mov	ax, [fstbuf+stat.inode]
  1230 00000531 3B06[0409]              	cmp	ax, [st1buf+stat.inode]
  1231 00000535 7505                    	jne	short check_6
  1232                                  	; fprintf(stderr, "mv: cannot move a directory
  1233                                  	;			 into itself\n");
  1234 00000537 B8[8A08]                	mov	ax, msg_cant_mv_itself
  1235 0000053A EBED                    	jmp	short check_3
  1236                                  check_6:
  1237                                  	;while (sbuf.st_ino != ROOTINO)
  1238 0000053C 83F829                  	cmp	ax, ROOTINO
  1239 0000053F 74EC                    	je	short check_4
  1240                                  
  1241                                  	;if (strlen(nspth) > MAXN-2-sizeof(DOTDOT))
  1242 00000541 83FE6C                  	cmp	si, MAXN-4
  1243 00000544 7605                    	jna	short check_7
  1244                                  
  1245                                  	;fprintf(stderr, "mv: name too long\n");
  1246 00000546 B8[B608]                	mov	ax, msg_too_long
  1247 00000549 EBDE                    	jmp	short check_3
  1248                                  check_7:
  1249                                  	;strcat(nspth, SDELIM);
  1250                                  	;strcat(nspth, DOTDOT);
  1251                                  	;mov	eax, 002E2E2Fh ; db '/..', 0  
  1252                                  	;mov	[si+nspth], eax
  1253                                  	; 27/05/2022
  1254 0000054B B82F2E                  	mov	ax, 2E2Fh ; db '/.'
  1255 0000054E 8984[F20A]              	mov	[si+nspth], ax
  1256 00000552 B82E00                  	mov	ax, 02Eh ; db '.', 0
  1257 00000555 8984[F40A]              	mov	[si+nspth+2], ax
  1258 00000559 83C603                  	add	si, 3
  1259 0000055C EBAF                    	jmp	short check_2
  1260                                  
  1261                                  ;-----------------------------------------------------------------
  1262                                  
  1263                                  chkdot:	; chkdot(s)
  1264                                  	; 23/05/2022
  1265                                  
  1266                                  	;do {
  1267                                  	;    if (strcmp(dname(s), DOTDOT) == 0)
  1268                                  	;	return(1);
  1269                                  	;    s = pname(s);
  1270                                  	;} while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0);
  1271                                  	;return(0);
  1272                                  
  1273                                  	; INPUT:
  1274                                  	;	bx = name buffer address
  1275                                  	; OUTPUT:
  1276                                  	;	cf = 1 -> DOTDOT (return 0)
  1277                                  	;	cf = 0 -> not DOTDOT (return 1)
  1278                                  
  1279                                  	; get last '/'
  1280 0000055E 89DE                    	mov	si, bx
  1281                                  chkdot_0:
  1282 00000560 89D9                    	mov	cx, bx
  1283                                  chkdot_1:
  1284 00000562 AC                      	lodsb
  1285 00000563 20C0                    	and	al, al
  1286 00000565 740E                    	jz	short chkdot_2
  1287 00000567 3C2F                    	cmp	al, DELIM ; '/'
  1288 00000569 75F7                     	jne	short chkdot_1
  1289 0000056B 803C00                  	cmp	byte [si], 0
  1290 0000056E 7605                    	jna	short chkdot_2	
  1291 00000570 89F1                    	mov	cx, si
  1292 00000572 49                      	dec	cx
  1293 00000573 EBED                    	jmp	short chkdot_1 
  1294                                  chkdot_2:
  1295 00000575 57                      	push	di ; *
  1296 00000576 89CE                    	mov	si, cx
  1297 00000578 BF[5206]                	mov	di, DOTDOT
  1298 0000057B E826FF                  	call	strcmp
  1299 0000057E 7412                    	jz	short chkdot_4 ; DOTDOT
  1300 00000580 89DF                    	mov	di, bx
  1301 00000582 BB[660A]                	mov	bx, fstbuf
  1302 00000585 E844FF                  	call	pname
  1303 00000588 5F                      	pop	di ; *
  1304 00000589 89F3                    	mov	bx, si  ; parent dir's pathname buf
  1305 0000058B 8B04                    	mov	ax, [si]
  1306 0000058D 08E4                    	or	ah, ah ; 0 ?
  1307 0000058F 75CF                    	jnz	short chkdot_0
  1308                                  	; (single character parent directory name)
  1309                                  	; (it's name may be '.' or '/' or another char)
  1310                                  	; pathname does not contain a DOTDOT
  1311 00000591 C3                      	retn
  1312                                  chkdot_4:
  1313                                  	; pathname contains DOTDOT
  1314 00000592 F9                      	stc
  1315 00000593 C3                      	retn
  1316                                  	 
  1317                                  ;-----------------------------------------------------------------
  1318                                  
  1319                                  access:
  1320                                  	; 22/05/2022
  1321                                  	; Retro UNIX 386 v1 & v1.1 & v1.2
  1322                                  
  1323                                  	; INPUT:
  1324                                  	;	si = stat(us) buffer 
  1325                                  	; OUTPUT:
  1326                                  	;	zf = 1 -> no write permission
  1327                                  	;	zf = 0 -> permitted to write
  1328                                  		
  1329                                  	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 00000594 B81800              <1>  mov ax, %1
   102 00000597 CD20                <1>  int 20h
  1330                                  	;mov	[uid], ax
  1331                                  
  1332                                  	; Retro UNIX 386 v1.2 (v2 fs)
  1333                                  	;mov	dl, 80h  ; write permission flag, owner
  1334                                  
  1335                                  	; Retro UNIX 386 v1
  1336 00000599 B204                    	mov	dl, 4  ; write permission flag, owner
  1337                                  
  1338                                  	;or	ax, ax
  1339 0000059B 08C0                    	or	al, al
  1340 0000059D 7407                    	jz	short access_1 ; root
  1341                                  
  1342                                  	;cmp	ax, [si+stat.uid]	
  1343 0000059F 3A4405                  	cmp	al, [si+stat.uid]
  1344 000005A2 7402                    	je	short access_1
  1345                                  
  1346                                  	; Retro UNIX 386 v1.2 (v2 fs inode)
  1347                                  	;sys	_getgid
  1348                                  	;;mov	[gid], al
  1349                                  
  1350                                  	;mov	dl, 10h
  1351                                  	;cmp	al, [si+stat.gid]
  1352                                  	;je	short access_1
  1353                                  	;
  1354                                  	;mov	dl, 02h
  1355                                  
  1356                                  	; Retro UNIX 386 v1	
  1357 000005A4 B201                    	mov	dl, 1
  1358                                  access_1:
  1359 000005A6 845402                  	test	dl, [si+stat.mode]
  1360 000005A9 C3                      	retn
  1361                                  
  1362                                  ;-----------------------------------------------------------------
  1363                                  
  1364                                  isatty:
  1365                                  	; 22/05/2022
  1366                                  	; Retro UNIX 386 v1 & v1.1 & v1.2
  1367                                  
  1368                                  	; Input: stdin (= 0)
  1369                                  	; output:
  1370                                  	;	cf = 1 -> not a tty
  1371                                  
  1372                                  	sys	_fstat, STDIN, fstbuf
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000005AA BB0000              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000005AD B9[660A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97                              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 000005B0 B81C00              <1>  mov ax, %1
   102 000005B3 CD20                <1>  int 20h
  1373                                  
  1374 000005B5 A1[660A]                	mov	ax, [fstbuf+stat.inode]
  1375                                  
  1376                                  	; Retro UNIX 386 v1.2
  1377                                  	;cmp	ax, 8 ; /dev/tty
  1378                                  	;je	short isatty_2
  1379                                  	;cmp	ax, 26 ; /dev/tty8
  1380                                  	;ja	short isatty_1
  1381                                  	;cmp	ax, 17 ; /dev/tty0
  1382                                  	;retn
  1383                                  
  1384                                  	; Retro UNIX 386 v1 (& v1.1)
  1385 000005B8 83F801                  	cmp	ax, 1 ; /dev/tty
  1386 000005BB 740A                    	je	short isatty_2
  1387 000005BD 83F813                  	cmp	ax, 19 ; /dev/tty8
  1388 000005C0 7704                    	ja	short isatty_1
  1389 000005C2 83F80A                  	cmp	ax, 10 ; /dev/tty0
  1390 000005C5 C3                      	retn
  1391                                  isatty_1:
  1392 000005C6 F9                      	stc
  1393                                  isatty_2:   
  1394 000005C7 C3                      	retn
  1395                                  
  1396                                  ;-----------------------------------------------------------------
  1397                                  	
  1398                                  octalnumber:
  1399                                  	; 27/05/2022
  1400                                  
  1401                                  	; Input:
  1402                                  	;   bx = binary number (max. 9 bit)
  1403                                  	;   si = string buffer (4 byte)
  1404                                  
  1405 000005C8 89D8                    	mov	ax, bx
  1406 000005CA B103                    	mov	cl, 3
  1407 000005CC D3EB                    	shr	bx, cl ; 3
  1408 000005CE 2407                    	and	al, 7
  1409 000005D0 50                      	push	ax
  1410 000005D1 89D8                    	mov	ax, bx
  1411 000005D3 D3EB                    	shr	bx, cl ; 3 
  1412 000005D5 2407                    	and	al, 7	
  1413 000005D7 50                      	push	ax
  1414 000005D8 89D8                    	mov	ax, bx
  1415 000005DA 2407                    	and	al, 7
  1416                                  octn_0:
  1417                                  	; 27/05/2022
  1418 000005DC 89F3                    	mov	bx, si
  1419                                  	;or	al, al
  1420                                  	;jz	short octn_1
  1421 000005DE E80C00                  	call	octn_3
  1422                                  octn_1:
  1423 000005E1 58                      	pop	ax
  1424                                  	; 27/05/2022
  1425 000005E2 E80800                  	call	octn_3
  1426                                  octn_2:
  1427 000005E5 58                      	pop	ax
  1428                                  	;call	octn_3
  1429 000005E6 E80C00                  	call	octn_4 ; 27/05/2022
  1430 000005E9 30C0                    	xor	al, al
  1431 000005EB EB0A                    	jmp	short octn_5
  1432                                  
  1433                                  octn_3:
  1434                                  	; 27/05/2022
  1435 000005ED 20C0                    	and	al, al
  1436 000005EF 7504                    	jnz	short octn_4
  1437 000005F1 39DE                    	cmp	si, bx
  1438 000005F3 7405                    	je	short octn_6
  1439                                  octn_4:
  1440 000005F5 0430                    	add	al, '0'
  1441                                  octn_5:
  1442 000005F7 8804                    	mov	[si], al
  1443 000005F9 46                      	inc	si
  1444                                  octn_6:
  1445 000005FA C3                      	retn
  1446                                  
  1447                                  ;-----------------------------------------------------------------
  1448                                  
  1449                                  getchar:
  1450                                  	; i = c = getchar();
  1451                                  	; while (c != '\n' && c != EOF)
  1452                                  	;		c = getchar();
  1453                                  getc_0:	
  1454                                  	sys	_read, STDIN, char, 1
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 000005FB BB0000              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 000005FE B9[F00A]            <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97 00000601 BA0100              <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 00000604 B80300              <1>  mov ax, %1
   102 00000607 CD20                <1>  int 20h
  1455 00000609 A0[F00A]                	mov	al, [char]
  1456 0000060C 3C79                    	cmp	al, 'y'
  1457 0000060E 7417                    	je	short getc_2
  1458 00000610 3C6E                    	cmp	al, 'n'
  1459 00000612 7413                    	je	short getc_2	
  1460 00000614 3C1B                    	cmp	al, ESCKey
  1461 00000616 740F                    	je	short getc_2
  1462 00000618 3C0D                    	cmp	al, EnterKey
  1463 0000061A 740B                    	je	short getc_2
  1464 0000061C 3C59                    	cmp	al, 'Y'	
  1465 0000061E 7503                    	jne	short getc_1
  1466 00000620 B079                    	mov	al, 'y'
  1467 00000622 C3                      	retn
  1468                                  getc_1:
  1469 00000623 3C4E                    	cmp	al, 'N'
  1470 00000625 75D4                    	jne	short getc_0
  1471                                  getc_2:
  1472 00000627 C3                      	retn	
  1473                                  
  1474                                  ;-----------------------------------------------------------------
  1475                                  
  1476                                  print_msg:
  1477                                  	; ax = asciiz string address
  1478 00000628 89C6                    	mov	si, ax
  1479 0000062A 4E                      	dec	si
  1480                                  nextchr:
  1481 0000062B 46                      	inc	si
  1482 0000062C 803C00                  	cmp	byte [si], 0
  1483 0000062F 77FA                    	ja	short nextchr
  1484                                  	;cmp	[si], 0Dh
  1485                                  	;ja	short nextchr
  1486 00000631 29C6                    	sub	si, ax
  1487                                  	; si = asciiz string length
  1488                                  	;
  1489                                  	sys	_write, 1, ax, si
    91                              <1> 
    92                              <1>  %if %0 >= 2
    93 00000633 BB0100              <1>  mov bx, %2
    94                              <1>  %if %0 >= 3
    95 00000636 89C1                <1>  mov cx, %3
    96                              <1>  %if %0 >= 4
    97 00000638 89F2                <1>  mov dx, %4
    98                              <1>  %endif
    99                              <1>  %endif
   100                              <1>  %endif
   101 0000063A B80400              <1>  mov ax, %1
   102 0000063D CD20                <1>  int 20h
  1490                                  	;
  1491 0000063F C3                      	retn
  1492                                  
  1493                                  ;-----------------------------------------------------------------
  1494                                  ;  data - initialized data
  1495                                  ;-----------------------------------------------------------------
  1496                                  
  1497                                  ;argc:	dd 0
  1498 00000640 00                      argc:	db 0
  1499 00000641 00                      errors:	db 0
  1500                                  
  1501                                  cp_cmd:
  1502 00000642 2F62696E2F637000        	db '/bin/cp', 0
  1503                                  
  1504                                  ;cp_args:
  1505                                  ;	dd cp_cmd
  1506                                  ;cp_source:
  1507                                  ;	dd 0
  1508                                  ;cp_target:
  1509                                  ;	dd 0
  1510                                  ;	dd 0
  1511                                  
  1512                                  ; 27/05/2022 - Retro UNIX 8086 v1
  1513                                  cp_args:
  1514 0000064A [4206]                  	dw cp_cmd
  1515                                  cp_source:
  1516 0000064C 0000                    	dw 0		
  1517                                  cp_target:
  1518 0000064E 0000                    	dw 0
  1519 00000650 0000                    	dw 0
  1520                                  
  1521 00000652 2E                      DOTDOT:	db '.'
  1522 00000653 2E00                    DOT:	db '.', 0
  1523                                  	;db 0, 0
  1524                                  
  1525                                  ; ----------------------------------------------------------------
  1526                                  
  1527                                  program_msg:
  1528 00000655 0D0A                    	db  0Dh, 0Ah
  1529 00000657 526574726F20554E49-     	db  'Retro UNIX 8086 v1 MOVE by Erdogan TAN - 27/05/2022'
  1529 00000660 582038303836207631-
  1529 00000669 204D4F564520627920-
  1529 00000672 4572646F67616E2054-
  1529 0000067B 414E202D2032372F30-
  1529 00000684 352F32303232       
  1530 0000068A 0D0A00                  	db  0Dh, 0Ah, 0
  1531                                  
  1532                                  usage_msg:
  1533 0000068D 0D0A                    	db  0Dh, 0Ah
  1534 0000068F 75736167653A206D76-     	db  'usage: mv f1 f2; or mv d1 d2; or mv f1 ... fn d1'
  1534 00000698 2066312066323B206F-
  1534 000006A1 72206D762064312064-
  1534 000006AA 323B206F72206D7620-
  1534 000006B3 6631202E2E2E20666E-
  1534 000006BC 206431             
  1535                                  nextline:
  1536 000006BF 0D0A00                  	db  0Dh, 0Ah, 0
  1537                                  
  1538                                  mv_header:
  1539 000006C2 0D0A                    	db 0Dh, 0Ah
  1540 000006C4 6D763A20                	db 'mv: '
  1541 000006C8 00                      	db 0
  1542                                  msg_not_exists:
  1543                                  	;db 0Dh, 0Ah
  1544 000006C9 20646F6573206E6F74-     	db ' does not exist '
  1544 000006D2 20657869737420     
  1545 000006D9 0D0A00                  	db 0Dh, 0Ah, 0
  1546                                  
  1547                                  msg_is_a_dir:
  1548 000006DC 206973206120646972-     	db ' is a directory '
  1548 000006E5 6563746F727920     
  1549 000006EC 0D0A00                  	db 0Dh, 0Ah, 0
  1550                                  
  1551                                  msg_cant_access:
  1552 000006EF 0D0A                    	db 0Dh, 0Ah
  1553 000006F1 6D763A2063616E6E6F-     	db 'mv: cannot access '
  1553 000006FA 742061636365737320 
  1554 00000703 00                      	db 0
  1555                                  
  1556                                  msg_rename_only:
  1557 00000704 0D0A                    	db 0Dh, 0Ah
  1558 00000706 6D763A206469726563-     	db 'mv: directory rename only'
  1558 0000070F 746F72792072656E61-
  1558 00000718 6D65206F6E6C79     
  1559 0000071F 0D0A00                  	db 0Dh, 0Ah, 0
  1560                                  
  1561                                  msg_cant_unlink:
  1562 00000722 0D0A                    	db 0Dh, 0Ah
  1563 00000724 6D763A2063616E6E6F-     	db 'mv: cannot unlink '
  1563 0000072D 7420756E6C696E6B20 
  1564 00000736 00                      	db 0
  1565                                  
  1566                                  msg_try_again:
  1567 00000737 0D0A                    	db 0Dh, 0Ah
  1568 00000739 6D763A207472792061-     	db 'mv: try again'
  1568 00000742 6761696E           
  1569 00000746 0D0A00                  	db 0Dh, 0Ah, 0
  1570                                  
  1571                                  msg_cant_exec_cp:
  1572 00000749 0D0A                    	db 0Dh, 0Ah
  1573 0000074B 6D763A2063616E6E6F-     	db 'mv: cannot exec cp'
  1573 00000754 742065786563206370 
  1574 0000075D 0D0A00                  	db 0Dh, 0Ah, 0
  1575                                  
  1576                                  msg_exists:
  1577 00000760 2065786973747320        	db ' exists '
  1578 00000768 0D0A00                  	db 0Dh, 0Ah, 0
  1579                                  
  1580                                  ;msg_long_target:
  1581                                  ;	db 0Dh, 0Ah
  1582                                  ;	db 'mv: target name too long'
  1583                                  ;	db 0Dh, 0Ah, 0
  1584                                  
  1585                                  msg_src_target:
  1586 0000076B 0D0A                    	db 0Dh, 0Ah
  1587 0000076D 6D763A203F3F20736F-     	db 'mv: ?? source == target, source exists and target doesnt'
  1587 00000776 75726365203D3D2074-
  1587 0000077F 61726765742C20736F-
  1587 00000788 757263652065786973-
  1587 00000791 747320616E64207461-
  1587 0000079A 7267657420646F6573-
  1587 000007A3 6E74               
  1588 000007A5 0D0A00                  	db 0Dh, 0Ah, 0
  1589                                  
  1590                                  msg_cant_locate:
  1591 000007A8 0D0A                    	db 0Dh, 0Ah
  1592 000007AA 6D763A2063616E6E6F-     	db 'mv: cannot locate parent'
  1592 000007B3 74206C6F6361746520-
  1592 000007BC 706172656E74       
  1593 000007C2 0D0A00                  	db 0Dh, 0Ah, 0
  1594                                  
  1595                                  msg_no_w_access:
  1596 000007C5 0D0A                    	db 0Dh, 0Ah
  1597 000007C7 6D763A206E6F207772-     	db 'mv: no write access to '
  1597 000007D0 697465206163636573-
  1597 000007D9 7320746F20         
  1598 000007DE 00                      	db 0
  1599                                  
  1600                                  msg_accross_devices:
  1601 000007DF 0D0A                    	db 0Dh, 0Ah
  1602 000007E1 6D763A2063616E6E6F-     	db 'mv: cannot move directories across devices'
  1602 000007EA 74206D6F7665206469-
  1602 000007F3 726563746F72696573-
  1602 000007FC 206163726F73732064-
  1602 00000805 657669636573       
  1603 0000080B 0D0A00                  	db 0Dh, 0Ah, 0
  1604                                  
  1605                                  msg_pathname_dotdot:
  1606 0000080E 0D0A                    	db 0Dh, 0Ah
  1607 00000810 6D763A20536F727279-     	db "mv: Sorry, path names including '..' aren't allowed"
  1607 00000819 2C2070617468206E61-
  1607 00000822 6D657320696E636C75-
  1607 0000082B 64696E6720272E2E27-
  1607 00000834 206172656E27742061-
  1607 0000083D 6C6C6F776564       
  1608 00000843 0D0A00                  	db 0Dh, 0Ah, 0
  1609                                  
  1610                                  msg_cant_rename:
  1611 00000846 0D0A                    	db 0Dh, 0Ah
  1612 00000848 6D763A2063616E6E6F-     	db 'mv: cannot rename '
  1612 00000851 742072656E616D6520 
  1613 0000085A 00                      	db 0
  1614                                  
  1615                                  msg_cant_link:
  1616 0000085B 0D0A                    	db 0Dh, 0Ah
  1617 0000085D 6D763A2063616E6E6F-     	db 'mv: cannot link '
  1617 00000866 74206C696E6B20     
  1618 0000086D 00                      	db 0
  1619                                  msg_to:
  1620 0000086E 20746F20                	db ' to '
  1621 00000872 00                      	db 0
  1622                                  msg_and:
  1623 00000873 20616E6420              	db ' and '
  1624 00000878 00                      	db 0
  1625                                  
  1626                                  msg_identical:
  1627 00000879 20617265206964656E-     	db ' are identical'
  1627 00000882 746963616C         
  1628 00000887 0D0A00                  	db 0Dh, 0Ah, 0	 
  1629                                  
  1630                                  msg_cant_mv_itself:
  1631 0000088A 0D0A                    	db 0Dh, 0Ah
  1632 0000088C 6D763A2063616E6E6F-     	db 'mv: cannot move a directory into itself'
  1632 00000895 74206D6F7665206120-
  1632 0000089E 6469726563746F7279-
  1632 000008A7 20696E746F20697473-
  1632 000008B0 656C66             
  1633 000008B3 0D0A00                  	db 0Dh, 0Ah, 0
  1634                                  
  1635                                  msg_too_long:
  1636 000008B6 0D0A                    	db 0Dh, 0Ah
  1637 000008B8 6D763A206E616D6520-     	db 'mv: name too long'
  1637 000008C1 746F6F206C6F6E67   
  1638 000008C9 0D0A00                  	db 0Dh, 0Ah, 0
  1639                                  
  1640                                  msg_mode:
  1641 000008CC 206D6F6465203F2028-     	db ' mode ? (y/n) '
  1641 000008D5 792F6E2920         
  1642 000008DA 00                      	db 0
  1643                                  
  1644                                  msg_yes:
  1645 000008DB 2059455320              	db ' YES '
  1646 000008E0 0D0A00                  	db 0Dh, 0Ah, 0
  1647                                  
  1648                                  msg_no:
  1649 000008E3 204E4F20                	db ' NO '
  1650 000008E7 0D0A00                  	db 0Dh, 0Ah, 0
  1651                                  
  1652                                  err_msg:
  1653 000008EA 0D0A                    	db 0Dh, 0Ah
  1654 000008EC 4572726F722120          	db 'Error! '
  1655 000008F3 0D0A00                  	db 0Dh, 0Ah, 0
  1656                                  
  1657                                  msg_ok:
  1658 000008F6 0D0A                    	db  0Dh, 0Ah
  1659 000008F8 4F4B2E                  	db  'OK.'
  1660 000008FB 0D0A00                  	db  0Dh, 0Ah, 0
  1661                                  
  1662                                  ;-----------------------------------------------------------------
  1663                                  ;  bss - uninitialized data
  1664                                  ;-----------------------------------------------------------------
  1665                                  
  1666 000008FE 90<rep 2h>              align 4
  1667                                  
  1668                                  bss_start:
  1669                                  
  1670                                  ABSOLUTE bss_start
  1671                                  
  1672                                  ;uid:	resw 1
  1673                                  ;;gid:	resw 1  ; Retro UNIX 386 v1.2
  1674                                  
  1675                                  ;target: resd 1	; destination/target pathname pointer
  1676                                  ; 27/05/2022
  1677 00000900 ????                    target:	resw 1  ; Retro UNIX 8086 v1
  1678                                  
  1679 00000902 ????                    st1dev: resw 1
  1680 00000904 <res 22h>               st1buf: resb 34 ; for Retro UNIX 386 v1 & v1.1
  1681 00000926 ????                    st2dev: resw 1
  1682 00000928 <res 22h>               st2buf: resb 34 ; 
  1683                                  ;st1dev: resd 1
  1684                                  ;st1buf: resb 66 ; for Retro UNIX 386 v1.2
  1685                                  ;st2dev: resd 1
  1686                                  ;st2buf: resb 66 ;
  1687                                  
  1688 0000094A <res 64h>               buf:	resb 100 ; pathname buffer
  1689 000009AE <res 5Ch>               sbuf:	resb 92 ; source, parent name buffer ; 23/05/2022
  1690 00000A0A <res 5Ch>               tbuf:	resb 92 ; target, parent name buffer ; 23/05/2022			
  1691 00000A66 <res 42h>               fstbuf:	resb 66	; fstat buffer
  1692                                  ; 23/05/2022
  1693                                  ;pst1buf: resb 66
  1694                                  ;pst2buf: resb 66
  1695 00000AA8 <res 22h>               pst1buf: resb 34
  1696 00000ACA <res 22h>               pst2buf: resb 34
  1697 00000AEC ????????                octm:	resb 4	; octal mode number
  1698 00000AF0 ??                      char:	resb 1	; getchar buffer
  1699 00000AF1 ??                      	resb 1		
  1700 00000AF2 <res 70h>               nspth:	resb MAXN ; 112 ; buffer for 'check' procedure
  1701                                  
  1702                                  ; 22/05/2022
  1703                                  ;-----------------------------------------------------------------
  1704                                  ; Original UNIX v7 - mv (utility) c source code (mv.c)
  1705                                  ;-----------------------------------------------------------------
  1706                                  ;/* UNIX V7 source code: see www.tuhs.org for details. */;
  1707                                  ;
  1708                                  ;/*
  1709                                  ; * mv file1 file2
  1710                                  ; */
  1711                                  ;
  1712                                  ;#include <stdio.h>
  1713                                  ;#include <sys/types.h>
  1714                                  ;#include <sys/stat.h>
  1715                                  ;#include <sys/dir.h>
  1716                                  ;#include <signal.h>
  1717                                  ;
  1718                                  ;#define DOT	"."
  1719                                  ;#define DOTDOT	".."
  1720                                  ;#define DELIM	'/'
  1721                                  ;#define SDELIM "/"
  1722                                  ;#define MAXN	100
  1723                                  ;#define MODEBITS 07777
  1724                                  ;#define ROOTINO 2
  1725                                  ;
  1726                                  ;char	*pname();
  1727                                  ;char	*sprintf();
  1728                                  ;char	*dname();
  1729                                  ;struct	stat s1, s2;
  1730                                  ;
  1731                                  ;main(argc, argv)
  1732                                  ;register char *argv[];
  1733                                  ;{
  1734                                  ;	register i, r;
  1735                                  ;
  1736                                  ;	if (argc < 3)
  1737                                  ;		goto usage;
  1738                                  ;	if (stat(argv[1], &s1) < 0) {
  1739                                  ;		fprintf(stderr, "mv: cannot access %s\n", argv[1]);
  1740                                  ;		return(1);
  1741                                  ;	}
  1742                                  ;	if ((s1.st_mode & S_IFMT) == S_IFDIR) {
  1743                                  ;		if (argc != 3)
  1744                                  ;			goto usage;
  1745                                  ;		return mvdir(argv[1], argv[2]);
  1746                                  ;	}
  1747                                  ;	setuid(getuid());
  1748                                  ;	if (argc > 3)
  1749                                  ;		if (stat(argv[argc-1], &s2) < 0 || (s2.st_mode & S_IFMT) != S_IFDIR)
  1750                                  ;			goto usage;
  1751                                  ;	r = 0;
  1752                                  ;	for (i=1; i<argc-1; i++)
  1753                                  ;		r |= move(argv[i], argv[argc-1]);
  1754                                  ;	return(r);
  1755                                  ;usage:
  1756                                  ;	fprintf(stderr, "usage: mv f1 f2; or mv d1 d2; or mv f1 ... fn d1\n");
  1757                                  ;	return(1);
  1758                                  ;}
  1759                                  ;
  1760                                  ;move(source, target)
  1761                                  ;char *source, *target;
  1762                                  ;{
  1763                                  ;	register c, i;
  1764                                  ;	int	status;
  1765                                  ;	char	buf[MAXN];
  1766                                  ;
  1767                                  ;	if (stat(source, &s1) < 0) {
  1768                                  ;		fprintf(stderr, "mv: cannot access %s\n", source);
  1769                                  ;		return(1);
  1770                                  ;	}
  1771                                  ;	if ((s1.st_mode & S_IFMT) == S_IFDIR) {
  1772                                  ;		fprintf(stderr, "mv: directory rename only\n");
  1773                                  ;		return(1);
  1774                                  ;	}
  1775                                  ;	if (stat(target, &s2) >= 0) {
  1776                                  ;		if ((s2.st_mode & S_IFMT) == S_IFDIR) {
  1777                                  ;			sprintf(buf, "%s/%s", target, dname(source));
  1778                                  ;			target = buf;
  1779                                  ;		}
  1780                                  ;		if (stat(target, &s2) >= 0) {
  1781                                  ;			if ((s2.st_mode & S_IFMT) == S_IFDIR) {
  1782                                  ;				fprintf(stderr, "mv: %s is a directory\n", target);
  1783                                  ;				return(1);
  1784                                  ;			}
  1785                                  ;			if (s1.st_dev==s2.st_dev && s1.st_ino==s2.st_ino) {
  1786                                  ;				fprintf(stderr, "mv: %s and %s are identical\n",
  1787                                  ;						source, target);
  1788                                  ;				return(1);
  1789                                  ;			}
  1790                                  ;			if (access(target, 2) < 0 && isatty(fileno(stdin))) {
  1791                                  ;				fprintf(stderr, "mv: %s: %o mode ", target,
  1792                                  ;					s2.st_mode & MODEBITS);
  1793                                  ;				i = c = getchar();
  1794                                  ;				while (c != '\n' && c != EOF)
  1795                                  ;					c = getchar();
  1796                                  ;				if (i != 'y')
  1797                                  ;					return(1);
  1798                                  ;			}
  1799                                  ;			if (unlink(target) < 0) {
  1800                                  ;				fprintf(stderr, "mv: cannot unlink %s\n", target);
  1801                                  ;				return(1);
  1802                                  ;			}
  1803                                  ;		}
  1804                                  ;	}
  1805                                  ;	if (link(source, target) < 0) {
  1806                                  ;		i = fork();
  1807                                  ;		if (i == -1) {
  1808                                  ;			fprintf(stderr, "mv: try again\n");
  1809                                  ;			return(1);
  1810                                  ;		}
  1811                                  ;		if (i == 0) {
  1812                                  ;			execl("/bin/cp", "cp", source, target, 0);
  1813                                  ;			fprintf(stderr, "mv: cannot exec cp\n");
  1814                                  ;			exit(1);
  1815                                  ;		}
  1816                                  ;		while ((c = wait(&status)) != i && c != -1)
  1817                                  ;			;
  1818                                  ;		if (status != 0)
  1819                                  ;			return(1);
  1820                                  ;		utime(target, &s1.st_atime);
  1821                                  ;	}
  1822                                  ;	if (unlink(source) < 0) {
  1823                                  ;		fprintf(stderr, "mv: cannot unlink %s\n", source);
  1824                                  ;		return(1);
  1825                                  ;	}
  1826                                  ;	return(0);
  1827                                  ;}
  1828                                  ;
  1829                                  ;mvdir(source, target)
  1830                                  ;char *source, *target;
  1831                                  ;{
  1832                                  ;	register char *p;
  1833                                  ;	register i;
  1834                                  ;	char buf[MAXN];
  1835                                  ;
  1836                                  ;	if (stat(target, &s2) >= 0) {
  1837                                  ;		if ((s2.st_mode&S_IFMT) != S_IFDIR) {
  1838                                  ;			fprintf(stderr, "mv: %s exists\n", target);
  1839                                  ;			return(1);
  1840                                  ;		}
  1841                                  ;		if (strlen(target) > MAXN-DIRSIZ-2) {
  1842                                  ;			fprintf(stderr, "mv :target name too long\n");
  1843                                  ;			return(1);
  1844                                  ;		}
  1845                                  ;		strcpy(buf, target);
  1846                                  ;		target = buf;
  1847                                  ;		strcat(buf, SDELIM);
  1848                                  ;		strcat(buf, dname(source));
  1849                                  ;		if (stat(target, &s2) >= 0) {
  1850                                  ;			fprintf(stderr, "mv: %s exists\n", buf);
  1851                                  ;			return(1);
  1852                                  ;		}
  1853                                  ;	}
  1854                                  ;	if (strcmp(source, target) == 0) {
  1855                                  ;		fprintf(stderr, "mv: ?? source == target, source exists and target doesnt\n");
  1856                                  ;		return(1);
  1857                                  ;	}
  1858                                  ;	p = dname(source);
  1859                                  ;	if (!strcmp(p, DOT) || !strcmp(p, DOTDOT) || !strcmp(p, "") || p[strlen(p)-1]=='/') {
  1860                                  ;		fprintf(stderr, "mv: cannot rename %s\n", p);
  1861                                  ;		return(1);
  1862                                  ;	}
  1863                                  ;	if (stat(pname(source), &s1) < 0 || stat(pname(target), &s2) < 0) {
  1864                                  ;		fprintf(stderr, "mv: cannot locate parent\n");
  1865                                  ;		return(1);
  1866                                  ;	}
  1867                                  ;	if (access(pname(target), 2) < 0) {
  1868                                  ;		fprintf(stderr, "mv: no write access to %s\n", pname(target));
  1869                                  ;		return(1);
  1870                                  ;	}
  1871                                  ;	if (access(pname(source), 2) < 0) {
  1872                                  ;		fprintf(stderr, "mv: no write access to %s\n", pname(source));
  1873                                  ;		return(1);
  1874                                  ;	}
  1875                                  ;	if (access(source, 2) < 0) {
  1876                                  ;		fprintf(stderr, "mv: no write access to %s\n", source);
  1877                                  ;		return(1);
  1878                                  ;	}
  1879                                  ;	if (s1.st_dev != s2.st_dev) {
  1880                                  ;		fprintf(stderr, "mv: cannot move directories across devices\n");
  1881                                  ;		return(1);
  1882                                  ;	}
  1883                                  ;	if (s1.st_ino != s2.st_ino) {
  1884                                  ;		char dst[MAXN+5];
  1885                                  ;
  1886                                  ;		if (chkdot(source) || chkdot(target)) {
  1887                                  ;			fprintf(stderr, "mv: Sorry, path names including %s aren't allowed\n", DOTDOT);
  1888                                  ;			return(1);
  1889                                  ;		}
  1890                                  ;		stat(source, &s1);
  1891                                  ;		if (check(pname(target), s1.st_ino))
  1892                                  ;			return(1);
  1893                                  ;		for (i = 1; i <= NSIG; i++)
  1894                                  ;			signal(i, SIG_IGN);
  1895                                  ;		if (link(source, target) < 0) {
  1896                                  ;			fprintf(stderr, "mv: cannot link %s to %s\n", target, source);
  1897                                  ;			return(1);
  1898                                  ;		}
  1899                                  ;		if (unlink(source) < 0) {
  1900                                  ;			fprintf(stderr, "mv: %s: cannot unlink\n", source);
  1901                                  ;			unlink(target);
  1902                                  ;			return(1);
  1903                                  ;		}
  1904                                  ;		strcat(dst, target);
  1905                                  ;		strcat(dst, "/");
  1906                                  ;		strcat(dst, DOTDOT);
  1907                                  ;		if (unlink(dst) < 0) {
  1908                                  ;			fprintf(stderr, "mv: %s: cannot unlink\n", dst);
  1909                                  ;			if (link(target, source) >= 0)
  1910                                  ;				unlink(target);
  1911                                  ;			return(1);
  1912                                  ;		}
  1913                                  ;		if (link(pname(target), dst) < 0) {
  1914                                  ;			fprintf(stderr, "mv: cannot link %s to %s\n",
  1915                                  ;				dst, pname(target));
  1916                                  ;			if (link(pname(source), dst) >= 0)
  1917                                  ;				if (link(target, source) >= 0)
  1918                                  ;					unlink(target);
  1919                                  ;			return(1);
  1920                                  ;		}
  1921                                  ;		return(0);
  1922                                  ;	}
  1923                                  ;	if (link(source, target) < 0) {
  1924                                  ;		fprintf(stderr, "mv: cannot link %s and %s\n",
  1925                                  ;			source, target);
  1926                                  ;		return(1);
  1927                                  ;	}
  1928                                  ;	if (unlink(source) < 0) {
  1929                                  ;		fprintf(stderr, "mv: ?? cannot unlink %s\n", source);
  1930                                  ;		return(1);
  1931                                  ;	}
  1932                                  ;	return(0);
  1933                                  ;}
  1934                                  ;
  1935                                  ;char *
  1936                                  ;pname(name)
  1937                                  ;register char *name;
  1938                                  ;{
  1939                                  ;	register c;
  1940                                  ;	register char *p, *q;
  1941                                  ;	static	char buf[MAXN];
  1942                                  ;
  1943                                  ;	p = q = buf;
  1944                                  ;	while (c = *p++ = *name++)
  1945                                  ;		if (c == DELIM)
  1946                                  ;			q = p-1;
  1947                                  ;	if (q == buf && *q == DELIM)
  1948                                  ;		q++;
  1949                                  ;	*q = 0;
  1950                                  ;	return buf[0]? buf : DOT;
  1951                                  ;}
  1952                                  ;
  1953                                  ;char *
  1954                                  ;dname(name)
  1955                                  ;register char *name;
  1956                                  ;{
  1957                                  ;	register char *p;
  1958                                  ;
  1959                                  ;	p = name;
  1960                                  ;	while (*p)
  1961                                  ;		if (*p++ == DELIM && *p)
  1962                                  ;			name = p;
  1963                                  ;	return name;
  1964                                  ;}
  1965                                  ;
  1966                                  ;check(spth, dinode)
  1967                                  ;char *spth;
  1968                                  ;ino_t dinode;
  1969                                  ;{
  1970                                  ;	char nspth[MAXN];
  1971                                  ;	struct stat sbuf;
  1972                                  ;
  1973                                  ;	sbuf.st_ino = 0;
  1974                                  ;
  1975                                  ;	strcpy(nspth, spth);
  1976                                  ;	while (sbuf.st_ino != ROOTINO) {
  1977                                  ;		if (stat(nspth, &sbuf) < 0) {
  1978                                  ;			fprintf(stderr, "mv: cannot access %s\n", nspth);
  1979                                  ;			return(1);
  1980                                  ;		}
  1981                                  ;		if (sbuf.st_ino == dinode) {
  1982                                  ;			fprintf(stderr, "mv: cannot move a directory into itself\n");
  1983                                  ;			return(1);
  1984                                  ;		}
  1985                                  ;		if (strlen(nspth) > MAXN-2-sizeof(DOTDOT)) {
  1986                                  ;			fprintf(stderr, "mv: name too long\n");
  1987                                  ;			return(1);
  1988                                  ;		}
  1989                                  ;		strcat(nspth, SDELIM);
  1990                                  ;		strcat(nspth, DOTDOT);
  1991                                  ;	}
  1992                                  ;	return(0);
  1993                                  ;}
  1994                                  ;
  1995                                  ;chkdot(s)
  1996                                  ;register char *s;
  1997                                  ;{
  1998                                  ;	do {
  1999                                  ;		if (strcmp(dname(s), DOTDOT) == 0)
  2000                                  ;			return(1);
  2001                                  ;		s = pname(s);
  2002                                  ;	} while (strcmp(s, DOT) != 0 && strcmp(s, SDELIM) != 0);
  2003                                  ;	return(0);
  2004                                  ;}
  2005                                  ;
