1 ; **************************************************************************** 2 ; rm386.s (rm2.s) - by Erdogan Tan - 25/04/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 386 v1.2 - remove -- remove (unlink/delete) file(s) 5 ; 6 ; [ Last Modification: 28/04/2022 ] 7 ; 8 ; Derived from (original) UNIX v7 (& v7 x86) 'rm.c' source Code 9 ; Ref: 10 ; www.tuhs.org (https://minnie.tuhs.org) 11 ; v7.tar.gz 12 ; **************************************************************************** 13 ; [ v7.tar - usr/src/cmd/rm.c (archive date: 10-1-1979) ] 14 ; 15 ; Assembler: NASM v2.15 16 ; ((nasm rm2.s -l rm2.txt -o rm2 -Z error.txt)) 17 ; 18 ; rm2.s - 28/04/2022 - Retro UNIX 386 v1.2 (modified unix v7 inode) 19 ; rm1.s - 28/04/2022 - Retro UNIX 386 v1.1 20 ; rm0.s - 28/04/2022 - Retro UNIX 386 v1 21 ; rm8086.s - 28/04/2022 - Retro UNIX 8086 v1 (16 bit 'rm0.s') 22 23 ; 12/01/2022 (Retro UNIX 386 v1.2) 24 ; 13/10/2015 25 26 ; UNIX v1 system calls 27 _rele equ 0 28 _exit equ 1 29 _fork equ 2 30 _read equ 3 31 _write equ 4 32 _open equ 5 33 _close equ 6 34 _wait equ 7 35 _creat equ 8 36 _link equ 9 37 _unlink equ 10 38 _exec equ 11 39 _chdir equ 12 40 _time equ 13 41 _mkdir equ 14 42 _chmod equ 15 43 _chown equ 16 44 _break equ 17 45 _stat equ 18 46 _seek equ 19 47 _tell equ 20 48 _mount equ 21 49 _umount equ 22 50 _setuid equ 23 51 _getuid equ 24 52 _stime equ 25 53 _quit equ 26 54 _intr equ 27 55 _fstat equ 28 56 _emt equ 29 57 _mdate equ 30 58 _stty equ 31 59 _gtty equ 32 60 _ilgins equ 33 61 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 62 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 63 _geterr equ 36 ; Retro UNIX 386 v1 feature only ! 64 ; 12/01/2022 - Retro UNIX 386 v1.2 65 ; Retro UNIX 386 v2 system calls 66 _setgid equ 37 67 _getgid equ 38 68 _sysver equ 39 ; (get) Retro Unix 386 version 69 70 ;;; 71 ESCKey equ 1Bh 72 EnterKey equ 0Dh 73 74 %macro sys 1-4 75 ; 03/09/2015 76 ; 13/04/2015 77 ; Retro UNIX 386 v1 system call. 78 %if %0 >= 2 79 mov ebx, %2 80 %if %0 >= 3 81 mov ecx, %3 82 ;%if %0 = 4 83 %if %0 >= 4 ; 11/03/2022 84 mov edx, %4 85 %endif 86 %endif 87 %endif 88 mov eax, %1 89 int 30h 90 %endmacro 91 92 ; Retro UNIX 386 v1 system call format: 93 ; sys systemcall (eax), , , 94 95 ; 11/03/2022 96 ; Note: Above 'sys' macro has limitation about register positions; 97 ; ebx, ecx, edx registers must not be used after their 98 ; positions in sys macro. 99 ; for example: 100 ; 'sys _write, 1, msg, ecx' is defective, because 101 ; ecx will be used/assigned before edx in 'sys' macro. 102 ; correct order may be: 103 ; 'sys _write, 1, msg, eax ; (eax = byte count) 104 105 ;struc stat 106 ; ; Note: This is for Retro UNIX v1.1 'sysstat' output !!! 107 ; ; (34 bytes) 108 ; .inode: resw 1 109 ; .mode: resw 1 110 ; .nlinks: resb 1 111 ; .uid: resb 1 112 ; .size: resw 1 113 ; .dskptr: resw 8 114 ; .ctime: resd 1 115 ; .mtime: resd 1 116 ; .rsvd: resw 1 117 ; .strucsize: 118 ;endstruc 119 120 struc stat 121 ; Note: This is for Retro UNIX v1.2 'sysstat' output !!! 122 ; (66 bytes) 123 00000000 ???? .inode: resw 1 124 00000002 ???? .mode: resw 1 125 00000004 ???? .nlinks: resw 1 126 00000006 ???? .uid: resw 1 127 00000008 ?? .gid: resb 1 128 00000009 ?? .size_h: resb 1 129 0000000A ???????? .size: resd 1 130 0000000E .dskptr: resd 10 131 00000036 ???????? .atime: resd 1 132 0000003A ???????? .mtime: resd 1 133 0000003E ???????? .ctime: resd 1 134 .strucsize: 135 endstruc 136 137 ;S_IFMT equ 0F000h ; /* type of file */ 138 ;S_IFDIR equ 04000h ; /* directory */ 139 ;S_IFCHR equ 02000h ; /* character special */ 140 ;S_IFBLK equ 06000h ; /* block special */ 141 ;S_IFREG equ 08000h ; /* regular */ 142 ;S_ISUID equ 00800h ; /* set user id on execution */ 143 ;S_ISGID equ 00400h ; /* set group id on execution */ 144 ;S_IREAD equ 00100h ; /* read permission, owner */ 145 ;S_IWRITE equ 00080h ; /* write permission, owner */ 146 ;S_IEXEC equ 00040h ; /* execute/search permission, owner */ 147 148 ; 27/04/2022 - Retro UNIX (386) v2 inode 149 ; byte 1 150 S_IFREG equ 80h ; Regular file flag (0 = device file) 151 S_IFDIR equ 40h ; Directory flag (for regular file) 152 S_IFBLK equ 40h ; Block device flag (for device) 153 S_IRSVD equ 20h ; Reserved (for regular file) flag = 0 154 S_IFCHR equ 20h ; Char special flag (for device) = 1 155 S_IFLRG equ 10h ; Large File flag 156 S_ISUID equ 08h ; Set User ID On Execution flag 157 S_ISGID equ 04h ; Set Group ID On Execution flag 158 S_IREAD equ 01h ; Owner's Read Permission flag 159 ; byte 0 160 S_IWRITE equ 80h ; Owner's Write Permission flag 161 S_IEXEC equ 40h ; Owner's Execute Permission flag 162 163 ; 24/04/2022 164 ; 21/04/2022 - UNIX v1 inode 165 ; byte 1 166 ;S_ALLOC equ 080h ; Allocated flag 167 ;S_IFDIR equ 040h ; Directory flag 168 ;S_IFMDF equ 020h ; File modified flag (always on) 169 ;S_IFLRG equ 010h ; Large File flag 170 ;; byte 0 171 ;S_ISUID equ 020h ; Set User ID On Execution flag 172 ;S_IEXEC equ 010h ; Executable File flag 173 ;S_IREAD equ 008h ; Owner's Read Permission flag 174 ;S_IWRITE equ 004h ; Owner's Write Permission flag 175 176 BSIZE equ 512 177 178 ;26/04/2022 179 ; Directory entry size 180 ;DIRSIZ equ 10 ; Retro UNIX 386 v1 181 DIRSIZ equ 16 ; Retro UNIX 386 v1.1 & v1.2 182 183 ;----------------------------------------------------------------- 184 ; text - code 185 ;----------------------------------------------------------------- 186 187 [BITS 32] ; 32-bit intructions (for 80386 protected mode) 188 189 [ORG 0] 190 191 START_CODE: 192 ; 27/04/2022 193 ; 26/04/2022 194 ; 25/04/2022 195 ; main(argc, argv) 196 197 00000000 58 pop eax ; [esp] = argument count 198 ;mov [argc], eax 199 00000001 A2[18060000] mov [argc], al 200 ;dec eax 201 00000006 FEC8 dec al 202 00000008 7533 jnz short rm_0 ; [argc] = 1 203 204 sys _msg, program_msg, 255, 0Fh 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000000A BB[1C060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000000F B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000014 BA0F000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000019 B823000000 <1> mov eax, %1 89 0000001E CD30 <1> int 30h 205 rm_usage: 206 ; "Usage: rm [–fri] file ..." 207 sys _msg, usage_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000020 BB[53060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000025 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000002A BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000002F B823000000 <1> mov eax, %1 89 00000034 CD30 <1> int 30h 208 rm_exit: 209 sys _exit ; sys exit 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000036 B801000000 <1> mov eax, %1 89 0000003B CD30 <1> int 30h 210 ;hlt: 211 ; nop 212 ; nop 213 ; jmp short hlt 214 215 rm_0: 216 ;if (isatty(0) == 0) 217 ; fflg++; 218 219 ; set '-f' flag if standard input is not a terminal 220 sys _fstat, 0, stbuf 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000003D BB00000000 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000042 B9[48070000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000047 B81C000000 <1> mov eax, %1 89 0000004C CD30 <1> int 30h 221 ;jc short rm_exit ; 27/04/2022 222 223 ; 27/04/2022 224 ; 25/04/2022 225 ; Retro UNIX v2 inode: 226 ; regular file flag is mode bit 15 227 ; 228 0000004E F605[4B070000]80 test byte [stbuf+stat.mode+1], S_IFREG 229 00000055 7406 jz short rm_1 ; device file (terminal/console) 230 231 ;inc byte [fflg] 232 233 ; 25/04/2022 234 ; Retro UNIX v1 inode: 235 ; regular file inode numbers are > 41 236 ; 237 ;cmp word [stbuf+stat.inode], 41 238 ;jna short rm_1 ; device file (or root dir?) 239 240 ; (if standard input is not a terminal) 241 ; force removing (without question and 'y' answer) 242 00000057 FE05[19060000] inc byte [fflg] 243 rm_1: 244 ;if(argc>1 && argv[1][0]=='-') { 245 ; arg = *++argv; 246 ; argc--; 247 ; 248 249 0000005D 89E5 mov ebp, esp ; 26/04/2022 250 0000005F 5E pop esi ; argv[0] ; executable file name (='rm') 251 ;mov [argv], esp 252 00000060 8B3424 mov esi, [esp] ; 26/04/2022 253 ; argv[1] ; option (if it is used) 254 00000063 AC lodsb 255 00000064 3C2D cmp al, '-' 256 00000066 754E jne short rm_2 257 00000068 89E5 mov ebp, esp ; 26/04/2022 258 0000006A FE0D[18060000] dec byte [argc] ; ARGC - 2 259 rm_28: 260 00000070 AC lodsb 261 00000071 A8FF test al, 0FFh 262 00000073 7441 jz short rm_2 263 264 ;while(*++arg != '\0') 265 ; switch(*arg) { 266 ; case 'f': 267 ; fflg++; 268 ; break; 269 ; case 'i': 270 ; iflg++; 271 ; break; 272 ; case 'r': 273 ; rflg++; 274 ; break; 275 ; default: 276 ; printf("rm: unknown option %s\n", *argv); 277 ; exit(1); 278 ; } 279 280 00000075 3C66 cmp al, 'f' 281 00000077 742D je short rm_1_f 282 00000079 3C69 cmp al, 'i' 283 0000007B 7431 je short rm_1_i 284 0000007D 3C72 cmp al, 'r' 285 0000007F 741D je short rm_1_r 286 rm_1_uop: 287 ; "rm: unknown option '-x'" 288 00000081 A2[89060000] mov [uop], al 289 sys _msg, unk_op_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000086 BB[73060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000008B B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000090 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000095 B823000000 <1> mov eax, %1 89 0000009A CD30 <1> int 30h 290 ; (exit code not used in Retro UNIX 386 v1 & v1.1) 291 ;sys _exit, 1 ; (ebx = exit code = 1) 292 0000009C EB98 jmp short rm_exit 293 rm_1_r: 294 0000009E FE05[1B060000] inc byte [rflg] ; rflg++; 295 ;jmp short rm_2 296 ; 27/04/2022 297 000000A4 EBCA jmp short rm_28 ; get next option char 298 rm_1_f: 299 000000A6 FE05[19060000] inc byte [fflg] ; fflg++; 300 ;jmp short rm_2 301 ; 27/04/2022 302 000000AC EBC2 jmp short rm_28 ; get next option char 303 rm_1_i: 304 000000AE FE05[1A060000] inc byte [iflg] ; iflg++ 305 ; 27/04/2022 306 000000B4 EBBA jmp short rm_28 ; get next option char 307 rm_2: 308 ;while(--argc > 0) { 309 ; if(!strcmp(*++argv, "..")) { 310 ; fprintf(stderr, "rm: cannot remove `..'\n"); 311 ; continue; 312 ; } 313 ; rm(*argv, fflg, rflg, iflg, 0); 314 ;} 315 316 000000B6 FE0D[18060000] dec byte [argc] 317 000000BC 7431 jz short rm_4 318 319 ;add word ptr [argv], 4 ; ++argv 320 ;mov esi, [argv] 321 000000BE 83C504 add ebp, 4 ; ++argv 322 000000C1 8B7500 mov esi, [ebp] 323 000000C4 66813E2E2E cmp word [esi], '..' ; strcmp(*++argv, "..") 324 000000C9 740E je short rm_3 325 ; rm(*argv, fflg, rflg, iflg, 0); 326 000000CB C605[8A070000]00 mov byte [level], 0 327 000000D2 E823000000 call remove_file 328 000000D7 EBDD jmp short rm_2 329 rm_3: 330 ; "rm: cannot remove '..'" 331 sys _msg, cnr_dotdot_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000000D9 BB[8D060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000000DE B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000000E3 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000000E8 B823000000 <1> mov eax, %1 89 000000ED CD30 <1> int 30h 332 rm_4: 333 ; (exit code not used in Retro UNIX 386 v1 & v1.1) 334 ;sys _exit, [errcode] 335 sys _exit 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000000EF B801000000 <1> mov eax, %1 89 000000F4 CD30 <1> int 30h 336 ;hang: 337 ; jmp short hang 338 339 _return: 340 ; 27/04/2022 341 000000F6 89EC mov esp, ebp ; add esp, 100 342 000000F8 5D pop ebp 343 344 000000F9 C3 retn 345 346 remove_file: 347 ; rm(arg, fflg, rflg, iflg, level) 348 349 ; 28/04/2022 350 ; 27/04/2022 351 ; 26/04/2022 352 ; modified registers: eax, ebx, ecx, edx, edi 353 354 ; INPUT: 355 ; esi = *argv ; [level] = 0 356 ; or esi = namebuf ; [level] > 0 -- 357 ; byte [fflg], [rflg], [iflg] 358 ; byte [level] = sub directory level 359 360 ;if(stat(arg, &buf)) { 361 ; if (fflg==0) { 362 ; printf("rm: %s nonexistent\n", arg); 363 ; ++errcode; 364 ; } 365 ; return; 366 ;} 367 368 ; 27/04/2022 369 000000FA 55 push ebp 370 000000FB 89E5 mov ebp, esp 371 000000FD 83EC64 sub esp, 100 ; char name[100]; 372 373 sys _stat, esi, stbuf 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000100 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000102 B9[48070000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000107 B812000000 <1> mov eax, %1 89 0000010C CD30 <1> int 30h 374 0000010E 734A jnc short rm_5 375 376 00000110 803D[19060000]00 cmp byte [fflg], 0 377 00000117 77DD ja short _return 378 379 ; "rm: non existent" 380 sys _msg, rm_hdr_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000119 BB[A8060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000011E B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000123 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000128 B823000000 <1> mov eax, %1 89 0000012D CD30 <1> int 30h 381 sys _msg, esi, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000012F 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000131 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000136 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000013B B823000000 <1> mov eax, %1 89 00000140 CD30 <1> int 30h 382 sys _msg, nonex_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000142 BB[AF060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000147 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000014C BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000151 B823000000 <1> mov eax, %1 89 00000156 CD30 <1> int 30h 383 384 ;inc dword [errcode] ; ++errcode; 385 386 00000158 EB9C jmp short _return 387 rm_5: 388 ;if ((buf.st_mode&S_IFMT) == S_IFDIR) { 389 ; if(rflg) { 390 391 ; Retro UNIX 386 v2 inode 392 0000015A A0[4B070000] mov al, [stbuf+stat.mode+1] 393 0000015F 24C0 and al, S_IFREG | S_IFDIR 394 00000161 3CC0 cmp al, S_IFREG | S_IFDIR 395 ;jne short rm_17 396 ; 27/04/2022 397 00000163 7405 je short rm_24 398 00000165 E9F0010000 jmp rm_17 399 400 ; Retro UNIX 386 v1 (unix v1) inode 401 ;test byte [stbuf+stat.mode+1], S_IFDIR 402 ;;jz short rm_17 403 ; 26/04/2022 404 ;jnz short rm_24 405 ;jmp rm_17 406 rm_24: 407 ; Directory ! ('-r' option is required) 408 409 ;if(rflg) { ... 410 ; .... 411 ;} 412 ;printf("rm: %s directory\n", arg); 413 ; ++errcode; 414 ; return; 415 416 0000016A 803D[1B060000]00 cmp byte [rflg], 0 417 ;jna short rm_9 418 ; 26/04/2022 419 00000171 7705 ja short rm_25 420 00000173 E907010000 jmp rm_9 421 422 rm_25: 423 ;if (access(arg, 02) < 0) { 424 ; if (fflg==0) 425 ; printf("%s not changed\n", arg); 426 ; errcode++; 427 ; return; 428 ;} 429 430 ; dl = permission/mode value 431 ; (dl = 2 for Retro UNIX 386 v2 inode) 432 ; (dl = 1 for Retro UNIX 386 v1 inode) 433 434 ;;mov dl, 2 435 ;mov dl, 1 436 437 00000178 E831030000 call access 438 0000017D 734D jnc short rm_7 439 440 0000017F 803D[19060000]00 cmp byte [fflg], 0 441 00000186 773F ja short rm_6 442 443 ; esi = arg = *[argv] 444 445 ; " not changed" 446 sys _msg, nextline, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000188 BB[70060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000018D B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000192 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000197 B823000000 <1> mov eax, %1 89 0000019C CD30 <1> int 30h 447 sys _msg, esi, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000019E 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000001A0 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001A5 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000001AA B823000000 <1> mov eax, %1 89 000001AF CD30 <1> int 30h 448 sys _msg, nchd_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000001B1 BB[BE060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000001B6 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001BB BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000001C0 B823000000 <1> mov eax, %1 89 000001C5 CD30 <1> int 30h 449 rm_6: 450 ;inc dword [errcode] ; ++errcode; 451 000001C7 E92AFFFFFF jmp _return ; return; 452 rm_7: 453 ;if(iflg && level!=0) { 454 ; printf("directory %s: ", arg); 455 ; if(!yes()) 456 ; return; 457 ;} 458 459 000001CC 803D[1A060000]00 cmp byte [iflg], 0 460 000001D3 764F jna short rm_8 461 000001D5 803D[8A070000]00 cmp byte [level], 0 462 000001DC 7646 jna short rm_8 463 464 ;"directory : ? " 465 sys _msg, dir_hdr_msg, 255, 07h ; message row header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000001DE BB[CD060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000001E3 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001E8 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000001ED B823000000 <1> mov eax, %1 89 000001F2 CD30 <1> int 30h 466 sys _msg, esi, 255, 07h ; directory name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000001F4 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000001F6 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001FB BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000200 B823000000 <1> mov eax, %1 89 00000205 CD30 <1> int 30h 467 sys _msg, qu_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000207 BB[DA060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000020C B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000211 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000216 B823000000 <1> mov eax, %1 89 0000021B CD30 <1> int 30h 468 469 ; get user input (answer) 470 ; and write it (as answer) via sysmsg system call 471 0000021D E8AE020000 call ifyes 472 00000222 72A3 jc short rm_6 ; no 473 ; yes 474 rm_8: 475 ;if((d=open(arg, 0)) < 0) { 476 ; printf("rm: %s: cannot read\n", arg); 477 ; exit(1); 478 ;} 479 480 sys _open, esi, 0 ; open directory for read 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000224 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000226 B900000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000022B B805000000 <1> mov eax, %1 89 00000230 CD30 <1> int 30h 481 ;jnc short rm_10 482 ; 26/04/2022 483 00000232 7205 jc short rm_26 484 00000234 E98A000000 jmp rm_10 485 rm_26: 486 ;"rm: : cannot read" 487 sys _msg, rm_hdr_msg, 255, 07h ; msg row header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000239 BB[A8060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000023E B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000243 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000248 B823000000 <1> mov eax, %1 89 0000024D CD30 <1> int 30h 488 sys _msg, esi, 255, 07h ; directory name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000024F 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000251 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000256 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000025B B823000000 <1> mov eax, %1 89 00000260 CD30 <1> int 30h 489 sys _msg, cnr_msg, 255, 07h ; 'cannot read' 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000262 BB[EA060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000267 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000026C BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000271 B823000000 <1> mov eax, %1 89 00000276 CD30 <1> int 30h 490 491 ; (exit code not used in Retro UNIX 386 v1 & v1.1) 492 ;sys _exit, 1 ; (ebx = exit code = 1) 493 sys _exit 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000278 B801000000 <1> mov eax, %1 89 0000027D CD30 <1> int 30h 494 ;here: 495 ; jmp short here 496 497 rm_9: 498 ;printf("rm: %s directory\n", arg); 499 ; ++errcode; 500 ; return; 501 502 ; "rm: directory" 503 sys _msg, rm_hdr_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000027F BB[A8060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000284 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000289 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000028E B823000000 <1> mov eax, %1 89 00000293 CD30 <1> int 30h 504 sys _msg, esi, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000295 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000297 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000029C BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000002A1 B823000000 <1> mov eax, %1 89 000002A6 CD30 <1> int 30h 505 sys _msg, dir_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000002A8 BB[FA060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000002AD B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000002B2 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000002B7 B823000000 <1> mov eax, %1 89 000002BC CD30 <1> int 30h 506 507 ;inc dword [errcode] ; ++errcode; 508 509 000002BE E933FEFFFF jmp _return ; return; 510 511 rm_10: 512 ;while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) { 513 ; if(direct.d_ino != 0 && !dotname(direct.d_name)) { 514 ; sprintf(name, "%s/%.14s", arg, direct.d_name); 515 ; rm(name, fflg, rflg, iflg, level+1); 516 ; } 517 ;} 518 ; 519 ;close(d); 520 ;errcode += rmdir(arg, iflg); 521 ;return; 522 523 ; 26/04/2022 524 000002C3 A3[34070000] mov [_d_], eax ; file (directory) descriptor 525 rm_29: 526 sys _read, [_d_], direct, DIRSIZ 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000002C8 8B1D[34070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000002CE B9[38070000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000002D3 BA10000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000002D8 B803000000 <1> mov eax, %1 89 000002DD CD30 <1> int 30h 527 000002DF 7262 jc short rm_15 528 000002E1 83F810 cmp eax, DIRSIZ ; 16 (runix v1.1&v1.2) or 10 (runix v1) 529 000002E4 725D jb short rm_15 ; (jne short rm_14) 530 531 ; 27/04/2022 532 ; if(direct.d_ino != 0 .. 533 000002E6 66833D[38070000]00 cmp word [direct], 0 ; is inode number > 0 ? 534 000002EE 76D8 jna short rm_29 ; no ; read next direntry ; 27/04/2022 535 ; yes 536 ; && !dotname(direct.d_name)) 537 000002F0 BB[3A070000] mov ebx, direct+2 538 000002F5 E828020000 call isdotname 539 000002FA 74CC jz short rm_29 ; '.' or '..' 540 ; read next direntry ; 27/04/2022 541 542 ; sprintf(name, "%s/%.14s", arg, direct.d_name); 543 ; 27/04/2022 544 000002FC 89E7 mov edi, esp ; name ; 100 byte frame on stack 545 000002FE 56 push esi ; * ; save esi (arg, *argv) 546 rm_11: 547 000002FF AC lodsb 548 00000300 08C0 or al, al 549 00000302 7403 jz short rm_12 ; (end of the path) 550 00000304 AA stosb 551 00000305 EBF8 jmp short rm_11 552 rm_12: 553 ; add file name to the path 554 00000307 B02F mov al, '/' 555 00000309 AA stosb 556 ;mov ecx, 14 ; max. 14 byte file name 557 0000030A B90E000000 mov ecx, DIRSIZ-2 558 0000030F BE[3A070000] mov esi, direct+2 ; direct.d_name 559 rm_13: 560 00000314 AC lodsb 561 00000315 AA stosb 562 00000316 08C0 or al, al 563 00000318 7405 jz short rm_14 ; end of the (full) path 564 0000031A E2F8 loop rm_13 565 ; 28/04/2022 566 0000031C C60700 mov byte [edi], 0 567 rm_14: 568 ; rm(name, fflg, rflg, iflg, level+1); 569 ; 27/04/2022 570 0000031F 8D742404 lea esi, [esp+4] ; path name buffer (stack frame) 571 00000323 FF35[34070000] push dword [_d_] ; save file (dir) descriptor 572 00000329 FE05[8A070000] inc byte [level] 573 0000032F E8C6FDFFFF call remove_file ; ! call itself ! 574 00000334 FE0D[8A070000] dec byte [level] ; (this may not be necessary) 575 0000033A 8F05[34070000] pop dword [_d_] ; restore file (dir) descriptor 576 00000340 5E pop esi ; * ; restore esi (arg, *argv) 577 00000341 EB85 jmp short rm_29 578 rm_15: 579 sys _close, [_d_] ; close(d); 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000343 8B1D[34070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000349 B806000000 <1> mov eax, %1 89 0000034E CD30 <1> int 30h 580 ; errcode += rmdir(arg, iflg); 581 ; 27/04/2022 582 00000350 E8E1010000 call rmdir 583 ;jnc short rm_16 584 ;mov byte [errcode], 1 585 ;---- 586 ;NOTE: 587 ; sysexit error code ((exit(errcode);) 588 ; is not used by current Retro UNIX version 589 ;---- 590 rm_16: ; 27/04/2022 591 00000355 E99CFDFFFF jmp _return ; return; 592 593 rm_17: 594 ;if(iflg) { 595 ; printf("%s: ", arg); 596 ; if(!yes()) 597 ; return; 598 ;} 599 ;else if(!fflg) { 600 ; if (access(arg, 02)<0) { 601 ; printf("rm: %s %o mode ", arg, buf.st_mode&0777); 602 ; if(!yes()) 603 ; return; 604 ; } 605 ;} 606 ; 607 ;if(unlink(arg) && (fflg==0 || iflg)) { 608 ; printf("rm: %s not removed\n", arg); 609 ; ++errcode; 610 ;} 611 612 ; 26/04/2022 613 0000035A 803D[1A060000]00 cmp byte [iflg], 0 614 ;jna short rm_20 615 00000361 7705 ja short rm_27 616 00000363 E9A2000000 jmp rm_20 617 rm_27: 618 sys _msg, nextline, 255, 07h ; next (new) line 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000368 BB[70060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000036D B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000372 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000377 B823000000 <1> mov eax, %1 89 0000037C CD30 <1> int 30h 619 sys _msg, esi, 255, 07h ; file name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000037E 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000380 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000385 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000038A B823000000 <1> mov eax, %1 89 0000038F CD30 <1> int 30h 620 sys _msg, qu_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000391 BB[DA060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000396 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000039B BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003A0 B823000000 <1> mov eax, %1 89 000003A5 CD30 <1> int 30h 621 000003A7 E824010000 call ifyes ; question 622 000003AC 72A7 jc short rm_16 ; answer = no (not 'y') 623 rm_18: 624 sys _unlink, esi 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003AE 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003B0 B80A000000 <1> mov eax, %1 89 000003B5 CD30 <1> int 30h 625 000003B7 739C jnc short rm_16 626 ; 627 000003B9 A0[19060000] mov al, [fflg] 628 000003BE 0A05[1A060000] or al, [iflg] 629 000003C4 748F jz short rm_16 630 ; "rm: not removed" 631 sys _msg, rm_hdr_msg, 255, 07h ; header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003C6 BB[A8060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000003CB B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000003D0 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003D5 B823000000 <1> mov eax, %1 89 000003DA CD30 <1> int 30h 632 sys _msg, esi, 255, 07h ; file name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003DC 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000003DE B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000003E3 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003E8 B823000000 <1> mov eax, %1 89 000003ED CD30 <1> int 30h 633 sys _msg, not_rmd_msg, 255, 07h ; 'not removed' 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003EF BB[05070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000003F4 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000003F9 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003FE B823000000 <1> mov eax, %1 89 00000403 CD30 <1> int 30h 634 ;---- 635 ;Note: Current Retro UNIX version 636 ; does not use error code return (to parent) 637 ;---- 638 ;inc byte [errcode] 639 ; 27/04/2022 640 00000405 E9ECFCFFFF jmp _return ; return; 641 rm_20: 642 0000040A 803D[19060000]00 cmp byte [fflg], 0 643 00000411 779B ja short rm_18 644 ; 645 ;if (access(arg, 02)<0) { 646 ; printf("rm: %s %o mode ", arg, buf.st_mode&0777); 647 ; if(!yes()) 648 ; return; 649 ;} 650 ; 651 ;;mov dl, 2 652 ;mov dl, 1 653 00000413 E896000000 call access 654 00000418 7394 jnc short rm_18 655 656 ; "rm: _octal_ mode" 657 0000041A 31C0 xor eax, eax 658 0000041C 31DB xor ebx, ebx 659 0000041E 89E1 mov ecx, esp 660 00000420 66A1[4A070000] mov ax, [stbuf+stat.mode] 661 ; 27/04/2022 662 00000426 6625FF01 and ax, 1FFh ; Retro UNIX 386 v2 inode 663 ;and ax, 1Fh ; Retro UNIX 386 v1 inode 664 0000042A B308 mov bl, 8 ; divisor for octal number calculation 665 0000042C BF[8B070000] mov edi, octal 666 rm_21: 667 00000431 31D2 xor edx, edx 668 00000433 F7F3 div ebx 669 00000435 52 push edx 670 00000436 09C0 or eax, eax 671 00000438 75F7 jnz short rm_21 672 rm_22: 673 0000043A 58 pop eax 674 0000043B 0430 add al, '0' 675 0000043D AA stosb 676 0000043E 39E1 cmp ecx, esp 677 00000440 77F8 ja short rm_22 678 00000442 28C0 sub al, al 679 00000444 AA stosb 680 681 sys _msg, rm_hdr_msg, 255, 07h ; header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000445 BB[A8060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000044A B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000044F BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000454 B823000000 <1> mov eax, %1 89 00000459 CD30 <1> int 30h 682 sys _msg, octal, 255, 07h ; octal mode 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000045B BB[8B070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000460 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000465 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000046A B823000000 <1> mov eax, %1 89 0000046F CD30 <1> int 30h 683 sys _msg, mode_msg, 255, 07h ; ' mode ' 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000471 BB[14070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000476 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000047B BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000480 B823000000 <1> mov eax, %1 89 00000485 CD30 <1> int 30h 684 sys _msg, que_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000487 BB[DB060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000048C B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000491 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000496 B823000000 <1> mov eax, %1 89 0000049B CD30 <1> int 30h 685 0000049D E82E000000 call ifyes ; question 686 000004A2 7205 jc short rm_23 ; answer = no (not 'y') 687 000004A4 E905FFFFFF jmp rm_18 688 rm_23: ; 27/04/2022 689 000004A9 E948FCFFFF jmp _return ; return; 690 691 access: 692 ; 27/04/2022 693 ; 26/04/2022 694 ; INPUT: 695 ; dl = permission/mode value 696 ; (dl = 2 for Retro UNIX 386 v2 inode) 697 ; (dl = 1 for Retro UNIX 386 v1 inode) 698 ; 699 ; stbuf = status (sysstat output) buffer 700 ; 701 ; OUTPUT: 702 ; cf = 0 -> ok 703 ; cf = 1 -> error (denied) 704 705 000004AE B202 mov dl, 2 ; retro unix v2 (write permit flag) 706 ;mov dl, 1 ; unix v1 (write permit flag) 707 708 000004B0 8A0D[4A070000] mov cl, [stbuf+stat.mode] ; Retro UNIX 386 v1 709 ;mov cx, [stbuf+stat.mode] ; Retro UNIX 386 v2 710 711 ; Retro UNIX 386 v1.2 (v2) 712 sys _getuid ; get user ID of current user 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000004B6 B818000000 <1> mov eax, %1 89 000004BB CD30 <1> int 30h 713 ;mov [uid], ax ; ax = real user ID (<=255) 714 ;sys _getgid ; get group ID of current user 715 ;mov [gid], al ; al = real group ID (<=255) 716 717 ; Retro UNIX 386 v1 (unix v1) 718 ;sys _getuid ; get user ID of current user 719 ;mov [uid], al ; al = user ID 720 721 ; dl = 2 -> write permission flag (retro unix v2) 722 ; dl = 1 -> write permission flag (retro unix v1) 723 724 ;mov ax, [uid] 725 000004BD 663B05[4E070000] cmp ax, [stbuf+stat.uid] ; Retro UNIX v2 inode 726 ;cmp al, [stbuf+stat.uid] ; unix v1 727 000004C4 7504 jne short access_1 728 729 ;; Retro UNIX 386 v1.2 note: 730 ;; group permission flags will not be used for now! 731 732 000004C6 66C1E906 shr cx, 6 ; Retro UNIX 386 v2 inode flags 733 ; AL bit 1 -> write permission owner 734 735 ;shr cl, 2 ; Retro UNIX 386 v1 inode flags 736 ; AL bit 0 -> write permission owner 737 access_1: 738 000004CA 20D1 and cl, dl 739 000004CC 7501 jnz short access_2 740 000004CE F9 stc 741 access_2: 742 000004CF C3 retn 743 744 ifyes: 745 ; 26/04/2022 746 ; check user input as yes or no 747 ; write answer and return with carry if it is 'no' 748 sys _read, 0, chr, 1 ; read standard input 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000004D0 BB00000000 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000004D5 B9[8F070000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000004DA BA01000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000004DF B803000000 <1> mov eax, %1 89 000004E4 CD30 <1> int 30h 749 000004E6 A0[8F070000] mov al, [chr] 750 000004EB 3C79 cmp al, 'y' 751 000004ED 741C je short ifyes_yes 752 000004EF 3C59 cmp al, 'Y' 753 000004F1 7418 je short ifyes_yes 754 ; another character means 'no' 755 ifyes_no: 756 ; write 'no' 757 sys _msg, no_msg, 255, 07h ; 'no' answer 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000004F3 BB[E5060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000004F8 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000004FD BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000502 B823000000 <1> mov eax, %1 89 00000507 CD30 <1> int 30h 758 00000509 F9 stc 759 0000050A C3 retn ; return 760 ifyes_yes: 761 ; write 'yes' 762 sys _msg, yes_msg, 255, 07h ; 'yes' answer 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000050B BB[DF060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000510 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000515 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000051A B823000000 <1> mov eax, %1 89 0000051F CD30 <1> int 30h 763 ;clc 764 00000521 C3 retn 765 766 ;isdotname: 767 ; 27/04/2022 768 ; 26/04/2022 769 ; check if file name is dot ('.') or dotdot ('..') 770 ; (return: zf=1 if it is dot or dotdot) 771 ;mov ax, [direct+2] ; 1st 2 chars of file name 772 isdotname: 773 ; ebx = file (or directory) name address 774 00000522 668B03 mov ax, [ebx] 775 00000525 3C2E cmp al, '.' 776 00000527 750C jne short isdot_retn 777 00000529 08E4 or ah, ah ; 0 ? 778 0000052B 7408 jz short isdot_retn ; '.' 779 0000052D 38E0 cmp al, ah ; '..' ? 780 ; 27/04/2022 781 0000052F 7504 jne short isdot_retn 782 00000531 807B0200 cmp byte [ebx+2], 0 783 ; zf = 1 if it is dotdot 784 isdot_retn: 785 00000535 C3 retn 786 787 rmdir: 788 ; 27/04/2022 789 ; 26/04/2022 790 ; INPUT: 791 ; esi = directory name address (*argv) 792 ; [iflg] = interactive option 793 ; 794 ; OUTPUT: 795 ; none 796 797 ;rmdir(f, iflg) 798 ;char *f; 799 ;{ 800 ; int status, i; 801 ; 802 ; if(dotname(f)) 803 ; return(0); 804 ; if(iflg) { 805 ; printf("%s: ", f); 806 ; if(!yes()) 807 ; return(0); 808 ;} 809 810 00000536 89F3 mov ebx, esi 811 00000538 E8E5FFFFFF call isdotname 812 0000053D 7464 jz short rmdir_retn 813 814 0000053F 803D[1A060000]01 cmp byte [iflg], 1 815 00000546 7246 jb short rmdir_1 816 817 sys _msg, dir_hdr_msg, 255, 07h ; message row header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000548 BB[CD060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000054D B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000552 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000557 B823000000 <1> mov eax, %1 89 0000055C CD30 <1> int 30h 818 sys _msg, esi, 255, 07h ; directory name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000055E 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000560 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000565 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000056A B823000000 <1> mov eax, %1 89 0000056F CD30 <1> int 30h 819 sys _msg, qu_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000571 BB[DA060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000576 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000057B BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000580 B823000000 <1> mov eax, %1 89 00000585 CD30 <1> int 30h 820 821 00000587 E844FFFFFF call ifyes ; question 822 0000058C 7215 jc short rmdir_retn ; answer = no (not 'y') 823 rmdir_1: 824 ;while((i=fork()) == -1) 825 ; sleep(3); 826 ;if(i) { 827 ; wait(&status); 828 ; return(status); 829 ;} 830 831 0000058E BB[A4050000] mov ebx, rmdir_2 ; ! Retro UNIX feature only ! 832 ; 'rmdir' child will continue from 833 sys _fork 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000593 B802000000 <1> mov eax, %1 89 00000598 CD30 <1> int 30h 834 0000059A 7207 jc short rmdir_retn 835 836 ; parent process will continue to run from here 837 ; (from 'jc' after 'sys _fork') 838 839 ; eax = child process ID 840 841 ; ---- 842 ; Note: Current Retro Unix version does not use 843 ; status return -exit code from the child- 844 ; ---- 845 846 sys _wait ; wait untill the child exits 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000059C B807000000 <1> mov eax, %1 89 000005A1 CD30 <1> int 30h 847 ;jc short rmdir_retn ; 27/04/2022 848 849 ; eax = child process ID -which has been terminated- 850 ; (ebx = status -may be used by retro unix later-) 851 852 ; cf = 0 ; return(0) 853 rmdir_retn: 854 ; if cf = 0 -> return(0) 855 ; else (if cf = 1) -> return(1) 856 857 000005A3 C3 retn 858 859 rmdir_2: 860 ; child process will continue to run from here 861 862 ;execl("/bin/rmdir", "rmdir", f, 0); 863 ;execl("/usr/bin/rmdir", "rmdir", f, 0); 864 ;printf("rm: can't find rmdir\n"); 865 ;exit(1); 866 867 ; run 'rmdir' utility/program 868 ; (it will/must not return here) 869 870 ; set directory address as /bin/rmdir argument 1 871 000005A4 8935[F0050000] mov [binrmdira1], esi 872 ;; set directory addr as /usr/bin/rmdir argument 1 873 ;mov [usrbinrmdira1], esi ; ((*)) 874 875 sys _exec, binrmdir, binrmdirp 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000005AA BB[FE050000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000005AF B9[EC050000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000005B4 B80B000000 <1> mov eax, %1 89 000005B9 CD30 <1> int 30h 876 sys _exec, usrbinrmdir, usrbinrmdirp 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000005BB BB[09060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000005C0 B9[EC050000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000005C5 B80B000000 <1> mov eax, %1 89 000005CA CD30 <1> int 30h 877 878 ; ! error ! 879 ; if sysexec fails (would fail) to run 'rmdir' 880 ; cpu will return here 881 882 ; "rm: can't find rmdir" 883 sys _msg, cnf_rd_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000005CC BB[1A070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000005D1 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000005D6 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000005DB B823000000 <1> mov eax, %1 89 000005E0 CD30 <1> int 30h 884 885 ; ebx = exit code (if there is an error, it is > 0) 886 ;sys _exit, 1 887 sys _exit ; Current Retro UNIX version 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000005E2 B801000000 <1> mov eax, %1 89 000005E7 CD30 <1> int 30h 888 ; does not use exit code from child 889 hangemhigh: 890 000005E9 90 nop 891 000005EA EBFD jmp short hangemhigh 892 893 ;----------------------------------------------------------------- 894 ; data - initialized data 895 ;----------------------------------------------------------------- 896 897 ; 26/04/202 898 899 binrmdirp: 900 usrbinrmdirp: 901 ;dd bindrmdir 902 000005EC [F8050000] dd _rmdir_ 903 binrmdira1: 904 usrbinrmdira1: ; ((*)) 905 000005F0 00000000 dd 0 906 binrmdira2: 907 usrbinrmdira2: ; ((*)) 908 000005F4 00000000 dd 0 909 ;usrbinrmdirp: 910 ; ;dd usrbindrmdir 911 ; dd _rmdir_ 912 ;usrbinrmdira1: 913 ; dd 0 914 ;usrbinrmdira2: 915 ; dd 0 916 917 _rmdir_: 918 000005F8 726D64697200 db 'rmdir', 0 919 binrmdir: 920 000005FE 2F62696E2F726D6469- db '/bin/rmdir', 0 920 00000607 7200 921 usrbinrmdir: 922 00000609 2F7573722F62696E2F- db '/usr/bin/rmdir', 0 922 00000612 726D64697200 923 924 ;argc: dd 0 925 00000618 00 argc: db 0 ; argument count 926 00000619 00 fflg: db 0 ; -f (forced) option 927 0000061A 00 iflg: db 0 ; -i (interactive) option 928 0000061B 00 rflg: db 0 ; -r (recursive) option 929 ;argv: dd 0 ; argument pointer (for argv[1]) 930 ;errcode: dd 0 ; error code (will be returned by sysexit) 931 ;uid: dw 0 ; user id 932 ;;gid: db 0 ; group id 933 ; 26/04/2022 934 ;nameptr: dd namebuf 935 936 ; ---------------------------------------------------------------- 937 938 program_msg: 939 0000061C 0D0A db 0Dh, 0Ah 940 0000061E 526574726F20554E49- db "Retro UNIX 386 v1.2 RM by Erdogan TAN - 28/04/2022" 940 00000627 58203338362076312E- 940 00000630 3220524D2062792045- 940 00000639 72646F67616E205441- 940 00000642 4E202D2032382F3034- 940 0000064B 2F32303232 941 00000650 0D0A00 db 0Dh, 0Ah, 0 942 usage_msg: 943 00000653 0D0A db 0Dh, 0Ah 944 00000655 55736167653A20726D- db "Usage: rm [ -fri ] file ..." 944 0000065E 205B202D667269205D- 944 00000667 2066696C65202E2E2E 945 nextline: 946 00000670 0D0A00 db 0Dh, 0Ah, 0 947 948 unk_op_msg: 949 00000673 0D0A db 0Dh, 0Ah 950 00000675 726D3A20756E6B6E6F- db "rm: unknown option -" 950 0000067E 776E206F7074696F6E- 950 00000687 202D 951 00000689 78 uop: db "x" 952 0000068A 0D0A00 db 0Dh, 0Ah, 0 953 954 cnr_dotdot_msg: 955 0000068D 0D0A db 0Dh, 0Ah 956 0000068F 726D3A2063616E6E6F- db "rm: cannot remove '..'" 956 00000698 742072656D6F766520- 956 000006A1 272E2E27 957 000006A5 0D0A00 db 0Dh, 0Ah, 0 958 959 rm_hdr_msg: 960 000006A8 0D0A db 0Dh, 0Ah 961 000006AA 726D3A20 db "rm: " 962 000006AE 00 db 0 963 964 nonex_msg: 965 000006AF 206E6F6E6578697374- db " nonexistent" 965 000006B8 656E74 966 000006BB 0D0A00 db 0Dh, 0Ah, 0 967 968 nchd_msg: 969 000006BE 206E6F74206368616E- db " not changed" 969 000006C7 676564 970 000006CA 0D0A00 db 0Dh, 0Ah, 0 971 dir_hdr_msg: 972 000006CD 0D0A db 0Dh, 0Ah 973 000006CF 6469726563746F7279- db "directory " 973 000006D8 20 974 000006D9 00 db 0 975 976 qu_msg: 977 000006DA 3A db ":" 978 000006DB 203F20 que_msg: db " ? " 979 000006DE 00 db 0 980 981 yes_msg: 982 000006DF 796573 db "yes" 983 000006E2 0D0A00 db 0Dh, 0Ah, 0 984 no_msg: 985 000006E5 6E6F db "no" 986 000006E7 0D0A00 db 0Dh, 0Ah, 0 987 988 cnr_msg: 989 000006EA 3A2063616E6E6F7420- db ": cannot read" 989 000006F3 72656164 990 000006F7 0D0A00 db 0Dh, 0Ah, 0 991 992 dir_msg: 993 000006FA 206469726563746F72- db " directory" 993 00000703 79 994 00000704 00 db 0 995 996 not_rmd_msg: 997 00000705 206E6F742072656D6F- db " not removed" 997 0000070E 766564 998 00000711 0D0A00 db 0Dh, 0Ah, 0 999 1000 mode_msg: 1001 00000714 206D6F6465 db " mode" 1002 00000719 00 db 0 1003 1004 cnf_rd_msg: 1005 0000071A 0D0A db 0Dh, 0Ah 1006 0000071C 726D3A2063616E2774- db "rm: can't find rmdir" 1006 00000725 2066696E6420726D64- 1006 0000072E 6972 1007 00000730 0D0A00 db 0Dh, 0Ah, 0 1008 1009 ;----------------------------------------------------------------- 1010 ; bss - uninitialized data 1011 ;----------------------------------------------------------------- 1012 1013 00000733 90 align 2 1014 1015 bss_start: 1016 1017 ABSOLUTE bss_start 1018 1019 ; 26/04/2022 1020 00000734 ???? _d_: resw 1 ; Sub directory's file descriptor 1021 00000736 ???? resw 1 1022 ;struct direct direct; 1023 00000738 direct: resb DIRSIZ ; Directory entry buffer 1024 1025 ; 25/04/2022 1026 ;;struct stat buf; 1027 00000748 stbuf: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data) 1028 ;stbuf: resb 34 ; for Retro UNIX 386 v1.1 (34 byte sysstat data) 1029 1030 ; 26/04/2022 1031 0000078A ?? level: resb 1 ; (sub directory level) 1032 0000078B ???????? octal: resb 4 ; (asciiz octal mode number string) 1033 0000078F ?? chr: resb 1 ; (sysread character buffer) 1034 ; 27/04/2022 1035 ;char name[100]; 1036 ;namebuf: resb 100 1037 1038 1039 ; 25/04/2022 1040 ;----------------------------------------------------------------- 1041 ; Original UNIX v7 - rm (utility) c source code (rm.c) 1042 ;----------------------------------------------------------------- 1043 ;/* UNIX V7 source code: see www.tuhs.org for details. */; 1044 ; 1045 ;int errcode; 1046 ; 1047 ;#include 1048 ;#include 1049 ;#include 1050 ;#include 1051 ; 1052 ;char *sprintf(); 1053 ; 1054 ;main(argc, argv) 1055 ;char *argv[]; 1056 ;{ 1057 ; register char *arg; 1058 ; int fflg, iflg, rflg; 1059 ; 1060 ; fflg = 0; 1061 ; if (isatty(0) == 0) 1062 ; fflg++; 1063 ; iflg = 0; 1064 ; rflg = 0; 1065 ; if(argc>1 && argv[1][0]=='-') { 1066 ; arg = *++argv; 1067 ; argc--; 1068 ; while(*++arg != '\0') 1069 ; switch(*arg) { 1070 ; case 'f': 1071 ; fflg++; 1072 ; break; 1073 ; case 'i': 1074 ; iflg++; 1075 ; break; 1076 ; case 'r': 1077 ; rflg++; 1078 ; break; 1079 ; default: 1080 ; printf("rm: unknown option %s\n", *argv); 1081 ; exit(1); 1082 ; } 1083 ; } 1084 ; while(--argc > 0) { 1085 ; if(!strcmp(*++argv, "..")) { 1086 ; fprintf(stderr, "rm: cannot remove `..'\n"); 1087 ; continue; 1088 ; } 1089 ; rm(*argv, fflg, rflg, iflg, 0); 1090 ; } 1091 ; 1092 ; exit(errcode); 1093 ;} 1094 ; 1095 ;rm(arg, fflg, rflg, iflg, level) 1096 ;char arg[]; 1097 ;{ 1098 ; struct stat buf; 1099 ; struct direct direct; 1100 ; char name[100]; 1101 ; int d; 1102 ; 1103 ; if(stat(arg, &buf)) { 1104 ; if (fflg==0) { 1105 ; printf("rm: %s nonexistent\n", arg); 1106 ; ++errcode; 1107 ; } 1108 ; return; 1109 ; } 1110 ; if ((buf.st_mode&S_IFMT) == S_IFDIR) { 1111 ; if(rflg) { 1112 ; if (access(arg, 02) < 0) { 1113 ; if (fflg==0) 1114 ; printf("%s not changed\n", arg); 1115 ; errcode++; 1116 ; return; 1117 ; } 1118 ; if(iflg && level!=0) { 1119 ; printf("directory %s: ", arg); 1120 ; if(!yes()) 1121 ; return; 1122 ; } 1123 ; if((d=open(arg, 0)) < 0) { 1124 ; printf("rm: %s: cannot read\n", arg); 1125 ; exit(1); 1126 ; } 1127 ; while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) { 1128 ; if(direct.d_ino != 0 && !dotname(direct.d_name)) { 1129 ; sprintf(name, "%s/%.14s", arg, direct.d_name); 1130 ; rm(name, fflg, rflg, iflg, level+1); 1131 ; } 1132 ; } 1133 ; close(d); 1134 ; errcode += rmdir(arg, iflg); 1135 ; return; 1136 ; } 1137 ; printf("rm: %s directory\n", arg); 1138 ; ++errcode; 1139 ; return; 1140 ; } 1141 ; 1142 ; if(iflg) { 1143 ; printf("%s: ", arg); 1144 ; if(!yes()) 1145 ; return; 1146 ; } 1147 ; else if(!fflg) { 1148 ; if (access(arg, 02)<0) { 1149 ; printf("rm: %s %o mode ", arg, buf.st_mode&0777); 1150 ; if(!yes()) 1151 ; return; 1152 ; } 1153 ; } 1154 ; if(unlink(arg) && (fflg==0 || iflg)) { 1155 ; printf("rm: %s not removed\n", arg); 1156 ; ++errcode; 1157 ; } 1158 ;} 1159 ; 1160 ;dotname(s) 1161 ;char *s; 1162 ;{ 1163 ; if(s[0] == '.') 1164 ; if(s[1] == '.') 1165 ; if(s[2] == '\0') 1166 ; return(1); 1167 ; else 1168 ; return(0); 1169 ; else if(s[1] == '\0') 1170 ; return(1); 1171 ; return(0); 1172 ;} 1173 ; 1174 ;rmdir(f, iflg) 1175 ;char *f; 1176 ;{ 1177 ; int status, i; 1178 ; 1179 ; if(dotname(f)) 1180 ; return(0); 1181 ; if(iflg) { 1182 ; printf("%s: ", f); 1183 ; if(!yes()) 1184 ; return(0); 1185 ; } 1186 ; while((i=fork()) == -1) 1187 ; sleep(3); 1188 ; if(i) { 1189 ; wait(&status); 1190 ; return(status); 1191 ; } 1192 ; execl("/bin/rmdir", "rmdir", f, 0); 1193 ; execl("/usr/bin/rmdir", "rmdir", f, 0); 1194 ; printf("rm: can't find rmdir\n"); 1195 ; exit(1); 1196 ;} 1197 ; 1198 ;yes() 1199 ;{ 1200 ; int i, b; 1201 ; 1202 ; i = b = getchar(); 1203 ; while(b != '\n' && b != EOF) 1204 ; b = getchar(); 1205 ; return(i == 'y'); 1206 ;}