1 ; **************************************************************************** 2 ; rm386.s (rm1.s) - by Erdogan Tan - 25/04/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 386 v1.1 - 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 rm1.s -l rm1.txt -o rm1 -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 00000000 ???? .inode: resw 1 109 00000002 ???? .mode: resw 1 110 00000004 ?? .nlinks: resb 1 111 00000005 ?? .uid: resb 1 112 00000006 ???? .size: resw 1 113 00000008 .dskptr: resw 8 114 00000018 ???????? .ctime: resd 1 115 0000001C ???????? .mtime: resd 1 116 00000020 ???? .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 ; .inode: resw 1 124 ; .mode: resw 1 125 ; .nlinks: resw 1 126 ; .uid: resw 1 127 ; .gid: resb 1 128 ; .size_h: resb 1 129 ; .size: resd 1 130 ; .dskptr: resd 10 131 ; .atime: resd 1 132 ; .mtime: resd 1 133 ; .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 ; 24/04/2022 149 ; 21/04/2022 - UNIX v1 inode 150 ; byte 1 151 S_ALLOC equ 080h ; Allocated flag 152 S_IFDIR equ 040h ; Directory flag 153 S_IFMDF equ 020h ; File modified flag (always on) 154 S_IFLRG equ 010h ; Large File flag 155 ; byte 0 156 S_ISUID equ 020h ; Set User ID On Execution flag 157 S_IEXEC equ 010h ; Executable File flag 158 S_IREAD equ 008h ; Owner's Read Permission flag 159 S_IWRITE equ 004h ; Owner's Write Permission flag 160 161 BSIZE equ 512 162 163 ;26/04/2022 164 ; Directory entry size 165 ;DIRSIZ equ 10 ; Retro UNIX 386 v1 166 DIRSIZ equ 16 ; Retro UNIX 386 v1.1 & v1.2 167 168 ;----------------------------------------------------------------- 169 ; text - code 170 ;----------------------------------------------------------------- 171 172 [BITS 32] ; 32-bit intructions (for 80386 protected mode) 173 174 [ORG 0] 175 176 START_CODE: 177 ; 27/04/2022 178 ; 26/04/2022 179 ; 25/04/2022 180 ; main(argc, argv) 181 182 00000000 58 pop eax ; [esp] = argument count 183 ;mov [argc], eax 184 00000001 A2[15060000] mov [argc], al 185 ;dec eax 186 00000006 FEC8 dec al 187 00000008 7533 jnz short rm_0 ; [argc] = 1 188 189 sys _msg, program_msg, 255, 0Fh 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000000A BB[19060000] <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 190 rm_usage: 191 ; "Usage: rm [–fri] file ..." 192 sys _msg, usage_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000020 BB[50060000] <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 193 rm_exit: 194 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 195 ;hlt: 196 ; nop 197 ; nop 198 ; jmp short hlt 199 200 rm_0: 201 ;if (isatty(0) == 0) 202 ; fflg++; 203 204 ; set '-f' flag if standard input is not a terminal 205 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[44070000] <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 206 ;jc short rm_exit ; 27/04/2022 207 208 ; 25/04/2022 209 ; Retro UNIX v2 inode: 210 ; regular file flag is mode bit 15 211 ; 212 ;test [stbuf+stat.mode+1], S_IFREG 213 ;jz short rm_1 ; device file (terminal/console) 214 215 ;inc byte [fflg] 216 217 ; 25/04/2022 218 ; Retro UNIX v1 inode: 219 ; regular file inode numbers are > 41 220 ; 221 0000004E 66833D[44070000]29 cmp word [stbuf+stat.inode], 41 222 00000056 7606 jna short rm_1 ; device file (or root dir?) 223 224 ; (if standard input is not a terminal) 225 ; force removing (without question and 'y' answer) 226 00000058 FE05[16060000] inc byte [fflg] 227 rm_1: 228 ;if(argc>1 && argv[1][0]=='-') { 229 ; arg = *++argv; 230 ; argc--; 231 ; 232 233 0000005E 89E5 mov ebp, esp ; 26/04/2022 234 00000060 5E pop esi ; argv[0] ; executable file name (='rm') 235 ;mov [argv], esp 236 00000061 8B3424 mov esi, [esp] ; 26/04/2022 237 ; argv[1] ; option (if it is used) 238 00000064 AC lodsb 239 00000065 3C2D cmp al, '-' 240 00000067 754E jne short rm_2 241 00000069 89E5 mov ebp, esp ; 26/04/2022 242 0000006B FE0D[15060000] dec byte [argc] ; ARGC - 2 243 rm_28: 244 00000071 AC lodsb 245 00000072 A8FF test al, 0FFh 246 00000074 7441 jz short rm_2 247 248 ;while(*++arg != '\0') 249 ; switch(*arg) { 250 ; case 'f': 251 ; fflg++; 252 ; break; 253 ; case 'i': 254 ; iflg++; 255 ; break; 256 ; case 'r': 257 ; rflg++; 258 ; break; 259 ; default: 260 ; printf("rm: unknown option %s\n", *argv); 261 ; exit(1); 262 ; } 263 264 00000076 3C66 cmp al, 'f' 265 00000078 742D je short rm_1_f 266 0000007A 3C69 cmp al, 'i' 267 0000007C 7431 je short rm_1_i 268 0000007E 3C72 cmp al, 'r' 269 00000080 741D je short rm_1_r 270 rm_1_uop: 271 ; "rm: unknown option '-x'" 272 00000082 A2[86060000] mov [uop], al 273 sys _msg, unk_op_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000087 BB[70060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000008C B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000091 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000096 B823000000 <1> mov eax, %1 89 0000009B CD30 <1> int 30h 274 ; (exit code not used in Retro UNIX 386 v1 & v1.1) 275 ;sys _exit, 1 ; (ebx = exit code = 1) 276 0000009D EB97 jmp short rm_exit 277 rm_1_r: 278 0000009F FE05[18060000] inc byte [rflg] ; rflg++; 279 ;jmp short rm_2 280 ; 27/04/2022 281 000000A5 EBCA jmp short rm_28 ; get next option char 282 rm_1_f: 283 000000A7 FE05[16060000] inc byte [fflg] ; fflg++; 284 ;jmp short rm_2 285 ; 27/04/2022 286 000000AD EBC2 jmp short rm_28 ; get next option char 287 rm_1_i: 288 000000AF FE05[17060000] inc byte [iflg] ; iflg++ 289 ; 27/04/2022 290 000000B5 EBBA jmp short rm_28 ; get next option char 291 rm_2: 292 ;while(--argc > 0) { 293 ; if(!strcmp(*++argv, "..")) { 294 ; fprintf(stderr, "rm: cannot remove `..'\n"); 295 ; continue; 296 ; } 297 ; rm(*argv, fflg, rflg, iflg, 0); 298 ;} 299 300 000000B7 FE0D[15060000] dec byte [argc] 301 000000BD 7431 jz short rm_4 302 303 ;add word ptr [argv], 4 ; ++argv 304 ;mov esi, [argv] 305 000000BF 83C504 add ebp, 4 ; ++argv 306 000000C2 8B7500 mov esi, [ebp] 307 000000C5 66813E2E2E cmp word [esi], '..' ; strcmp(*++argv, "..") 308 000000CA 740E je short rm_3 309 ; rm(*argv, fflg, rflg, iflg, 0); 310 000000CC C605[66070000]00 mov byte [level], 0 311 000000D3 E823000000 call remove_file 312 000000D8 EBDD jmp short rm_2 313 rm_3: 314 ; "rm: cannot remove '..'" 315 sys _msg, cnr_dotdot_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000000DA BB[8A060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000000DF B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000000E4 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000000E9 B823000000 <1> mov eax, %1 89 000000EE CD30 <1> int 30h 316 rm_4: 317 ; (exit code not used in Retro UNIX 386 v1 & v1.1) 318 ;sys _exit, [errcode] 319 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 000000F0 B801000000 <1> mov eax, %1 89 000000F5 CD30 <1> int 30h 320 ;hang: 321 ; jmp short hang 322 323 _return: 324 ; 27/04/2022 325 000000F7 89EC mov esp, ebp ; add esp, 100 326 000000F9 5D pop ebp 327 328 000000FA C3 retn 329 330 remove_file: 331 ; rm(arg, fflg, rflg, iflg, level) 332 333 ; 28/04/2022 334 ; 27/04/2022 335 ; 26/04/2022 336 ; modified registers: eax, ebx, ecx, edx, edi 337 338 ; INPUT: 339 ; esi = *argv ; [level] = 0 340 ; or esi = namebuf ; [level] > 0 -- 341 ; byte [fflg], [rflg], [iflg] 342 ; byte [level] = sub directory level 343 344 ;if(stat(arg, &buf)) { 345 ; if (fflg==0) { 346 ; printf("rm: %s nonexistent\n", arg); 347 ; ++errcode; 348 ; } 349 ; return; 350 ;} 351 352 ; 27/04/2022 353 000000FB 55 push ebp 354 000000FC 89E5 mov ebp, esp 355 000000FE 83EC64 sub esp, 100 ; char name[100]; 356 357 sys _stat, esi, stbuf 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000101 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000103 B9[44070000] <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 00000108 B812000000 <1> mov eax, %1 89 0000010D CD30 <1> int 30h 358 0000010F 734A jnc short rm_5 359 360 00000111 803D[16060000]00 cmp byte [fflg], 0 361 00000118 77DD ja short _return 362 363 ; "rm: non existent" 364 sys _msg, rm_hdr_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000011A BB[A5060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000011F B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000124 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000129 B823000000 <1> mov eax, %1 89 0000012E CD30 <1> int 30h 365 sys _msg, esi, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000130 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000132 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000137 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000013C B823000000 <1> mov eax, %1 89 00000141 CD30 <1> int 30h 366 sys _msg, nonex_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000143 BB[AC060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000148 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000014D BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000152 B823000000 <1> mov eax, %1 89 00000157 CD30 <1> int 30h 367 368 ;inc dword [errcode] ; ++errcode; 369 370 00000159 EB9C jmp short _return 371 rm_5: 372 ;if ((buf.st_mode&S_IFMT) == S_IFDIR) { 373 ; if(rflg) { 374 375 ; Retro UNIX 386 v2 inode 376 ;mov al, [stbuf+stat.mode+1] 377 ;and al, S_IFREG | S_IFDIR 378 ;cmp al, S_IFREG | S_IFDIR 379 ;;jne short rm_17 380 ; 27/04/2022 381 ;je short rm_24 382 ;jmp rm_17 383 384 ; Retro UNIX 386 v1 (unix v1) inode 385 0000015B F605[47070000]40 test byte [stbuf+stat.mode+1], S_IFDIR 386 ;jz short rm_17 387 ; 26/04/2022 388 00000162 7505 jnz short rm_24 389 00000164 E9F0010000 jmp rm_17 390 rm_24: 391 ; Directory ! ('-r' option is required) 392 393 ;if(rflg) { ... 394 ; .... 395 ;} 396 ;printf("rm: %s directory\n", arg); 397 ; ++errcode; 398 ; return; 399 400 00000169 803D[18060000]00 cmp byte [rflg], 0 401 ;jna short rm_9 402 ; 26/04/2022 403 00000170 7705 ja short rm_25 404 00000172 E907010000 jmp rm_9 405 406 rm_25: 407 ;if (access(arg, 02) < 0) { 408 ; if (fflg==0) 409 ; printf("%s not changed\n", arg); 410 ; errcode++; 411 ; return; 412 ;} 413 414 ; dl = permission/mode value 415 ; (dl = 2 for Retro UNIX 386 v2 inode) 416 ; (dl = 1 for Retro UNIX 386 v1 inode) 417 418 ;;mov dl, 2 419 ;mov dl, 1 420 421 00000177 E831030000 call access 422 0000017C 734D jnc short rm_7 423 424 0000017E 803D[16060000]00 cmp byte [fflg], 0 425 00000185 773F ja short rm_6 426 427 ; esi = arg = *[argv] 428 429 ; " not changed" 430 sys _msg, nextline, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000187 BB[6D060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000018C B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000191 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000196 B823000000 <1> mov eax, %1 89 0000019B CD30 <1> int 30h 431 sys _msg, esi, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000019D 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000019F B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001A4 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000001A9 B823000000 <1> mov eax, %1 89 000001AE CD30 <1> int 30h 432 sys _msg, nchd_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000001B0 BB[BB060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000001B5 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001BA BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000001BF B823000000 <1> mov eax, %1 89 000001C4 CD30 <1> int 30h 433 rm_6: 434 ;inc dword [errcode] ; ++errcode; 435 000001C6 E92CFFFFFF jmp _return ; return; 436 rm_7: 437 ;if(iflg && level!=0) { 438 ; printf("directory %s: ", arg); 439 ; if(!yes()) 440 ; return; 441 ;} 442 443 000001CB 803D[17060000]00 cmp byte [iflg], 0 444 000001D2 764F jna short rm_8 445 000001D4 803D[66070000]00 cmp byte [level], 0 446 000001DB 7646 jna short rm_8 447 448 ;"directory : ? " 449 sys _msg, dir_hdr_msg, 255, 07h ; message row header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000001DD BB[CA060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000001E2 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001E7 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000001EC B823000000 <1> mov eax, %1 89 000001F1 CD30 <1> int 30h 450 sys _msg, esi, 255, 07h ; directory name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000001F3 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000001F5 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000001FA BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000001FF B823000000 <1> mov eax, %1 89 00000204 CD30 <1> int 30h 451 sys _msg, qu_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000206 BB[D7060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000020B B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000210 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000215 B823000000 <1> mov eax, %1 89 0000021A CD30 <1> int 30h 452 453 ; get user input (answer) 454 ; and write it (as answer) via sysmsg system call 455 0000021C E8AC020000 call ifyes 456 00000221 72A3 jc short rm_6 ; no 457 ; yes 458 rm_8: 459 ;if((d=open(arg, 0)) < 0) { 460 ; printf("rm: %s: cannot read\n", arg); 461 ; exit(1); 462 ;} 463 464 sys _open, esi, 0 ; open directory for read 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000223 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000225 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 0000022A B805000000 <1> mov eax, %1 89 0000022F CD30 <1> int 30h 465 ;jnc short rm_10 466 ; 26/04/2022 467 00000231 7205 jc short rm_26 468 00000233 E98A000000 jmp rm_10 469 rm_26: 470 ;"rm: : cannot read" 471 sys _msg, rm_hdr_msg, 255, 07h ; msg row header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000238 BB[A5060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000023D B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000242 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000247 B823000000 <1> mov eax, %1 89 0000024C CD30 <1> int 30h 472 sys _msg, esi, 255, 07h ; directory name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000024E 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000250 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000255 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000025A B823000000 <1> mov eax, %1 89 0000025F CD30 <1> int 30h 473 sys _msg, cnr_msg, 255, 07h ; 'cannot read' 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000261 BB[E7060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000266 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000026B BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000270 B823000000 <1> mov eax, %1 89 00000275 CD30 <1> int 30h 474 475 ; (exit code not used in Retro UNIX 386 v1 & v1.1) 476 ;sys _exit, 1 ; (ebx = exit code = 1) 477 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 00000277 B801000000 <1> mov eax, %1 89 0000027C CD30 <1> int 30h 478 ;here: 479 ; jmp short here 480 481 rm_9: 482 ;printf("rm: %s directory\n", arg); 483 ; ++errcode; 484 ; return; 485 486 ; "rm: directory" 487 sys _msg, rm_hdr_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000027E BB[A5060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000283 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000288 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000028D B823000000 <1> mov eax, %1 89 00000292 CD30 <1> int 30h 488 sys _msg, esi, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000294 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000296 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000029B BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000002A0 B823000000 <1> mov eax, %1 89 000002A5 CD30 <1> int 30h 489 sys _msg, dir_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000002A7 BB[F7060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000002AC B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000002B1 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000002B6 B823000000 <1> mov eax, %1 89 000002BB CD30 <1> int 30h 490 491 ;inc dword [errcode] ; ++errcode; 492 493 000002BD E935FEFFFF jmp _return ; return; 494 495 rm_10: 496 ;while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) { 497 ; if(direct.d_ino != 0 && !dotname(direct.d_name)) { 498 ; sprintf(name, "%s/%.14s", arg, direct.d_name); 499 ; rm(name, fflg, rflg, iflg, level+1); 500 ; } 501 ;} 502 ; 503 ;close(d); 504 ;errcode += rmdir(arg, iflg); 505 ;return; 506 507 ; 26/04/2022 508 000002C2 A3[30070000] mov [_d_], eax ; file (directory) descriptor 509 rm_29: 510 sys _read, [_d_], direct, DIRSIZ 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000002C7 8B1D[30070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000002CD B9[34070000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000002D2 BA10000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000002D7 B803000000 <1> mov eax, %1 89 000002DC CD30 <1> int 30h 511 000002DE 7262 jc short rm_15 512 000002E0 83F810 cmp eax, DIRSIZ ; 16 (runix v1.1&v1.2) or 10 (runix v1) 513 000002E3 725D jb short rm_15 ; (jne short rm_14) 514 515 ; 27/04/2022 516 ; if(direct.d_ino != 0 .. 517 000002E5 66833D[34070000]00 cmp word [direct], 0 ; is inode number > 0 ? 518 000002ED 76D8 jna short rm_29 ; no ; read next direntry ; 27/04/2022 519 ; yes 520 ; && !dotname(direct.d_name)) 521 000002EF BB[36070000] mov ebx, direct+2 522 000002F4 E826020000 call isdotname 523 000002F9 74CC jz short rm_29 ; '.' or '..' 524 ; read next direntry ; 27/04/2022 525 526 ; sprintf(name, "%s/%.14s", arg, direct.d_name); 527 ; 27/04/2022 528 000002FB 89E7 mov edi, esp ; name ; 100 byte frame on stack 529 000002FD 56 push esi ; * ; save esi (arg, *argv) 530 rm_11: 531 000002FE AC lodsb 532 000002FF 08C0 or al, al 533 00000301 7403 jz short rm_12 ; (end of the path) 534 00000303 AA stosb 535 00000304 EBF8 jmp short rm_11 536 rm_12: 537 ; add file name to the path 538 00000306 B02F mov al, '/' 539 00000308 AA stosb 540 ;mov ecx, 14 ; max. 14 byte file name 541 00000309 B90E000000 mov ecx, DIRSIZ-2 542 0000030E BE[36070000] mov esi, direct+2 ; direct.d_name 543 rm_13: 544 00000313 AC lodsb 545 00000314 AA stosb 546 00000315 08C0 or al, al 547 00000317 7405 jz short rm_14 ; end of the (full) path 548 00000319 E2F8 loop rm_13 549 ; 28/04/2022 550 0000031B C60700 mov byte [edi], 0 551 rm_14: 552 ; rm(name, fflg, rflg, iflg, level+1); 553 ; 27/04/2022 554 0000031E 8D742404 lea esi, [esp+4] ; path name buffer (stack frame) 555 00000322 FF35[30070000] push dword [_d_] ; save file (dir) descriptor 556 00000328 FE05[66070000] inc byte [level] 557 0000032E E8C8FDFFFF call remove_file ; ! call itself ! 558 00000333 FE0D[66070000] dec byte [level] ; (this may not be necessary) 559 00000339 8F05[30070000] pop dword [_d_] ; restore file (dir) descriptor 560 0000033F 5E pop esi ; * ; restore esi (arg, *argv) 561 00000340 EB85 jmp short rm_29 562 rm_15: 563 sys _close, [_d_] ; close(d); 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000342 8B1D[30070000] <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 00000348 B806000000 <1> mov eax, %1 89 0000034D CD30 <1> int 30h 564 ; errcode += rmdir(arg, iflg); 565 ; 27/04/2022 566 0000034F E8DF010000 call rmdir 567 ;jnc short rm_16 568 ;mov byte [errcode], 1 569 ;---- 570 ;NOTE: 571 ; sysexit error code ((exit(errcode);) 572 ; is not used by current Retro UNIX version 573 ;---- 574 rm_16: ; 27/04/2022 575 00000354 E99EFDFFFF jmp _return ; return; 576 577 rm_17: 578 ;if(iflg) { 579 ; printf("%s: ", arg); 580 ; if(!yes()) 581 ; return; 582 ;} 583 ;else if(!fflg) { 584 ; if (access(arg, 02)<0) { 585 ; printf("rm: %s %o mode ", arg, buf.st_mode&0777); 586 ; if(!yes()) 587 ; return; 588 ; } 589 ;} 590 ; 591 ;if(unlink(arg) && (fflg==0 || iflg)) { 592 ; printf("rm: %s not removed\n", arg); 593 ; ++errcode; 594 ;} 595 596 ; 26/04/2022 597 00000359 803D[17060000]00 cmp byte [iflg], 0 598 ;jna short rm_20 599 00000360 7705 ja short rm_27 600 00000362 E9A2000000 jmp rm_20 601 rm_27: 602 sys _msg, nextline, 255, 07h ; next (new) line 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000367 BB[6D060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000036C B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000371 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000376 B823000000 <1> mov eax, %1 89 0000037B CD30 <1> int 30h 603 sys _msg, esi, 255, 07h ; file name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000037D 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000037F B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000384 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000389 B823000000 <1> mov eax, %1 89 0000038E CD30 <1> int 30h 604 sys _msg, qu_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000390 BB[D7060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000395 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000039A BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000039F B823000000 <1> mov eax, %1 89 000003A4 CD30 <1> int 30h 605 000003A6 E822010000 call ifyes ; question 606 000003AB 72A7 jc short rm_16 ; answer = no (not 'y') 607 rm_18: 608 sys _unlink, esi 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003AD 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 000003AF B80A000000 <1> mov eax, %1 89 000003B4 CD30 <1> int 30h 609 000003B6 739C jnc short rm_16 610 ; 611 000003B8 A0[16060000] mov al, [fflg] 612 000003BD 0A05[17060000] or al, [iflg] 613 000003C3 748F jz short rm_16 614 ; "rm: not removed" 615 sys _msg, rm_hdr_msg, 255, 07h ; header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003C5 BB[A5060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000003CA B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000003CF BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003D4 B823000000 <1> mov eax, %1 89 000003D9 CD30 <1> int 30h 616 sys _msg, esi, 255, 07h ; file name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003DB 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000003DD B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000003E2 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003E7 B823000000 <1> mov eax, %1 89 000003EC CD30 <1> int 30h 617 sys _msg, not_rmd_msg, 255, 07h ; 'not removed' 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000003EE BB[02070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000003F3 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000003F8 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000003FD B823000000 <1> mov eax, %1 89 00000402 CD30 <1> int 30h 618 ;---- 619 ;Note: Current Retro UNIX version 620 ; does not use error code return (to parent) 621 ;---- 622 ;inc byte [errcode] 623 ; 27/04/2022 624 00000404 E9EEFCFFFF jmp _return ; return; 625 rm_20: 626 00000409 803D[16060000]00 cmp byte [fflg], 0 627 00000410 779B ja short rm_18 628 ; 629 ;if (access(arg, 02)<0) { 630 ; printf("rm: %s %o mode ", arg, buf.st_mode&0777); 631 ; if(!yes()) 632 ; return; 633 ;} 634 ; 635 ;;mov dl, 2 636 ;mov dl, 1 637 00000412 E896000000 call access 638 00000417 7394 jnc short rm_18 639 640 ; "rm: _octal_ mode" 641 00000419 31C0 xor eax, eax 642 0000041B 31DB xor ebx, ebx 643 0000041D 89E1 mov ecx, esp 644 0000041F 66A1[46070000] mov ax, [stbuf+stat.mode] 645 ;and ax, 1FFh ; Retro UNIX 386 v2 inode 646 00000425 6683E01F and ax, 1Fh ; Retro UNIX 386 v1 inode 647 00000429 B308 mov bl, 8 ; divisor for octal number calculation 648 0000042B BF[67070000] mov edi, octal 649 rm_21: 650 00000430 31D2 xor edx, edx 651 00000432 F7F3 div ebx 652 00000434 52 push edx 653 00000435 09C0 or eax, eax 654 00000437 75F7 jnz short rm_21 655 rm_22: 656 00000439 58 pop eax 657 0000043A 0430 add al, '0' 658 0000043C AA stosb 659 0000043D 39E1 cmp ecx, esp 660 0000043F 77F8 ja short rm_22 661 00000441 28C0 sub al, al 662 00000443 AA stosb 663 664 sys _msg, rm_hdr_msg, 255, 07h ; header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000444 BB[A5060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000449 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000044E BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000453 B823000000 <1> mov eax, %1 89 00000458 CD30 <1> int 30h 665 sys _msg, octal, 255, 07h ; octal mode 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000045A BB[67070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000045F B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000464 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000469 B823000000 <1> mov eax, %1 89 0000046E CD30 <1> int 30h 666 sys _msg, mode_msg, 255, 07h ; ' mode ' 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000470 BB[11070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000475 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000047A BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000047F B823000000 <1> mov eax, %1 89 00000484 CD30 <1> int 30h 667 sys _msg, que_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000486 BB[D8060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000048B B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000490 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000495 B823000000 <1> mov eax, %1 89 0000049A CD30 <1> int 30h 668 0000049C E82C000000 call ifyes ; question 669 000004A1 7205 jc short rm_23 ; answer = no (not 'y') 670 000004A3 E905FFFFFF jmp rm_18 671 rm_23: ; 27/04/2022 672 000004A8 E94AFCFFFF jmp _return ; return; 673 674 access: 675 ; 26/04/2022 676 ; INPUT: 677 ; dl = permission/mode value 678 ; (dl = 2 for Retro UNIX 386 v2 inode) 679 ; (dl = 1 for Retro UNIX 386 v1 inode) 680 ; 681 ; stbuf = status (sysstat output) buffer 682 ; 683 ; OUTPUT: 684 ; cf = 0 -> ok 685 ; cf = 1 -> error (denied) 686 687 ;mov dl, 2 ; retro unix v2 (write permit flag) 688 000004AD B201 mov dl, 1 ; unix v1 (write permit flag) 689 690 000004AF 8A0D[46070000] mov cl, [stbuf+stat.mode] ; Retro UNIX 386 v1 691 ;mov cx, [stbuf+stat.mode] ; Retro UNIX 386 v2 692 693 ; Retro UNIX 386 v1.2 (v2) 694 ;sys _getuid ; get user ID of current user 695 ;mov [uid], al ; ax = real user ID (<=255) 696 ;sys _getgid ; get group ID of current user 697 ;mov [gid], al ; al = real group ID (<=255) 698 699 ; Retro UNIX 386 v1 (unix v1) 700 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 000004B5 B818000000 <1> mov eax, %1 89 000004BA CD30 <1> int 30h 701 ;mov [uid], al ; al = user ID 702 703 ; dl = 2 -> write permission flag (retro unix v2) 704 ; dl = 1 -> write permission flag (retro unix v1) 705 706 ;mov ax, [uid] 707 ;cmp ax, [stbuf+stat.uid] ; Retro UNIX v2 inode 708 000004BC 3A05[49070000] cmp al, [stbuf+stat.uid] ; unix v1 709 000004C2 7503 jne short access_1 710 711 ;; Retro UNIX 386 v1.2 note: 712 ;; group permission flags will not be used for now! 713 714 ;shr cx, 6 ; Retro UNIX 386 v2 inode flags 715 ; AL bit 1 -> write permission owner 716 717 000004C4 C0E902 shr cl, 2 ; Retro UNIX 386 v1 inode flags 718 ; AL bit 0 -> write permission owner 719 access_1: 720 000004C7 20D1 and cl, dl 721 000004C9 7501 jnz short access_2 722 000004CB F9 stc 723 access_2: 724 000004CC C3 retn 725 726 ifyes: 727 ; 26/04/2022 728 ; check user input as yes or no 729 ; write answer and return with carry if it is 'no' 730 sys _read, 0, chr, 1 ; read standard input 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000004CD BB00000000 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000004D2 B9[6B070000] <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000004D7 BA01000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000004DC B803000000 <1> mov eax, %1 89 000004E1 CD30 <1> int 30h 731 000004E3 A0[6B070000] mov al, [chr] 732 000004E8 3C79 cmp al, 'y' 733 000004EA 741C je short ifyes_yes 734 000004EC 3C59 cmp al, 'Y' 735 000004EE 7418 je short ifyes_yes 736 ; another character means 'no' 737 ifyes_no: 738 ; write 'no' 739 sys _msg, no_msg, 255, 07h ; 'no' answer 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000004F0 BB[E2060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000004F5 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000004FA BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000004FF B823000000 <1> mov eax, %1 89 00000504 CD30 <1> int 30h 740 00000506 F9 stc 741 00000507 C3 retn ; return 742 ifyes_yes: 743 ; write 'yes' 744 sys _msg, yes_msg, 255, 07h ; 'yes' answer 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000508 BB[DC060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000050D B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000512 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000517 B823000000 <1> mov eax, %1 89 0000051C CD30 <1> int 30h 745 ;clc 746 0000051E C3 retn 747 748 ;isdotname: 749 ; 27/04/2022 750 ; 26/04/2022 751 ; check if file name is dot ('.') or dotdot ('..') 752 ; (return: zf=1 if it is dot or dotdot) 753 ;mov ax, [direct+2] ; 1st 2 chars of file name 754 isdotname: 755 ; ebx = file (or directory) name address 756 0000051F 668B03 mov ax, [ebx] 757 00000522 3C2E cmp al, '.' 758 00000524 750C jne short isdot_retn 759 00000526 08E4 or ah, ah ; 0 ? 760 00000528 7408 jz short isdot_retn ; '.' 761 0000052A 38E0 cmp al, ah ; '..' ? 762 ; 27/04/2022 763 0000052C 7504 jne short isdot_retn 764 0000052E 807B0200 cmp byte [ebx+2], 0 765 ; zf = 1 if it is dotdot 766 isdot_retn: 767 00000532 C3 retn 768 769 rmdir: 770 ; 26/04/2022 771 ; INPUT: 772 ; esi = directory name address (*argv) 773 ; [iflg] = interactive option 774 ; 775 ; OUTPUT: 776 ; none 777 778 ;rmdir(f, iflg) 779 ;char *f; 780 ;{ 781 ; int status, i; 782 ; 783 ; if(dotname(f)) 784 ; return(0); 785 ; if(iflg) { 786 ; printf("%s: ", f); 787 ; if(!yes()) 788 ; return(0); 789 ;} 790 791 00000533 89F3 mov ebx, esi 792 00000535 E8E5FFFFFF call isdotname 793 0000053A 7464 jz short rmdir_retn 794 795 0000053C 803D[17060000]01 cmp byte [iflg], 1 796 00000543 7246 jb short rmdir_1 797 798 sys _msg, dir_hdr_msg, 255, 07h ; message row header 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 00000545 BB[CA060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000054A B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 0000054F BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000554 B823000000 <1> mov eax, %1 89 00000559 CD30 <1> int 30h 799 sys _msg, esi, 255, 07h ; directory name 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000055B 89F3 <1> mov ebx, %2 80 <1> %if %0 >= 3 81 0000055D B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000562 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 00000567 B823000000 <1> mov eax, %1 89 0000056C CD30 <1> int 30h 800 sys _msg, qu_msg, 255, 07h ; question 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 0000056E BB[D7060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 00000573 B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 00000578 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 0000057D B823000000 <1> mov eax, %1 89 00000582 CD30 <1> int 30h 801 802 00000584 E844FFFFFF call ifyes ; question 803 00000589 7215 jc short rmdir_retn ; answer = no (not 'y') 804 rmdir_1: 805 ;while((i=fork()) == -1) 806 ; sleep(3); 807 ;if(i) { 808 ; wait(&status); 809 ; return(status); 810 ;} 811 812 0000058B BB[A1050000] mov ebx, rmdir_2 ; ! Retro UNIX feature only ! 813 ; 'rmdir' child will continue from 814 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 00000590 B802000000 <1> mov eax, %1 89 00000595 CD30 <1> int 30h 815 00000597 7207 jc short rmdir_retn 816 817 ; parent process will continue to run from here 818 ; (from 'jc' after 'sys _fork') 819 820 ; eax = child process ID 821 822 ; ---- 823 ; Note: Current Retro Unix version does not use 824 ; status return -exit code from the child- 825 ; ---- 826 827 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 00000599 B807000000 <1> mov eax, %1 89 0000059E CD30 <1> int 30h 828 ;jc short rmdir_retn ; 27/04/2022 829 830 ; eax = child process ID -which has been terminated- 831 ; (ebx = status -may be used by retro unix later-) 832 833 834 ; cf = 0 ; return(0) 835 rmdir_retn: 836 ; if cf = 0 -> return(0) 837 ; else (if cf = 1) -> return(1) 838 839 000005A0 C3 retn 840 841 rmdir_2: 842 ; child process will continue to run from here 843 844 ;execl("/bin/rmdir", "rmdir", f, 0); 845 ;execl("/usr/bin/rmdir", "rmdir", f, 0); 846 ;printf("rm: can't find rmdir\n"); 847 ;exit(1); 848 849 ; run 'rmdir' utility/program 850 ; (it will/must not return here) 851 852 ; set directory address as /bin/rmdir argument 1 853 000005A1 8935[ED050000] mov [binrmdira1], esi 854 ;; set directory addr as /usr/bin/rmdir argument 1 855 ;mov [usrbinrmdira1], esi ; ((*)) 856 857 sys _exec, binrmdir, binrmdirp 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000005A7 BB[FB050000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000005AC B9[E9050000] <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 000005B1 B80B000000 <1> mov eax, %1 89 000005B6 CD30 <1> int 30h 858 sys _exec, usrbinrmdir, usrbinrmdirp 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000005B8 BB[06060000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000005BD B9[E9050000] <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 000005C2 B80B000000 <1> mov eax, %1 89 000005C7 CD30 <1> int 30h 859 860 ; ! error ! 861 ; if sysexec fails (would fail) to run 'rmdir' 862 ; cpu will return here 863 864 ; "rm: can't find rmdir" 865 sys _msg, cnf_rd_msg, 255, 07h 75 <1> 76 <1> 77 <1> 78 <1> %if %0 >= 2 79 000005C9 BB[17070000] <1> mov ebx, %2 80 <1> %if %0 >= 3 81 000005CE B9FF000000 <1> mov ecx, %3 82 <1> 83 <1> %if %0 >= 4 84 000005D3 BA07000000 <1> mov edx, %4 85 <1> %endif 86 <1> %endif 87 <1> %endif 88 000005D8 B823000000 <1> mov eax, %1 89 000005DD CD30 <1> int 30h 866 867 ; ebx = exit code (if there is an error, it is > 0) 868 ;sys _exit, 1 869 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 000005DF B801000000 <1> mov eax, %1 89 000005E4 CD30 <1> int 30h 870 ; does not use exit code from child 871 hangemhigh: 872 000005E6 90 nop 873 000005E7 EBFD jmp short hangemhigh 874 875 ;----------------------------------------------------------------- 876 ; data - initialized data 877 ;----------------------------------------------------------------- 878 879 ; 26/04/202 880 881 binrmdirp: 882 usrbinrmdirp: 883 ;dd bindrmdir 884 000005E9 [F5050000] dd _rmdir_ 885 binrmdira1: 886 usrbinrmdira1: ; ((*)) 887 000005ED 00000000 dd 0 888 binrmdira2: 889 usrbinrmdira2: ; ((*)) 890 000005F1 00000000 dd 0 891 ;usrbinrmdirp: 892 ; ;dd usrbindrmdir 893 ; dd _rmdir_ 894 ;usrbinrmdira1: 895 ; dd 0 896 ;usrbinrmdira2: 897 ; dd 0 898 899 _rmdir_: 900 000005F5 726D64697200 db 'rmdir', 0 901 binrmdir: 902 000005FB 2F62696E2F726D6469- db '/bin/rmdir', 0 902 00000604 7200 903 usrbinrmdir: 904 00000606 2F7573722F62696E2F- db '/usr/bin/rmdir', 0 904 0000060F 726D64697200 905 906 ;argc: dd 0 907 00000615 00 argc: db 0 ; argument count 908 00000616 00 fflg: db 0 ; -f (forced) option 909 00000617 00 iflg: db 0 ; -i (interactive) option 910 00000618 00 rflg: db 0 ; -r (recursive) option 911 ;argv: dd 0 ; argument pointer (for argv[1]) 912 ;errcode: dd 0 ; error code (will be returned by sysexit) 913 ;uid: dw 0 ; user id 914 ;;gid: db 0 ; group id 915 ; 26/04/2022 916 ;nameptr: dd namebuf 917 918 ; ---------------------------------------------------------------- 919 920 program_msg: 921 00000619 0D0A db 0Dh, 0Ah 922 0000061B 526574726F20554E49- db "Retro UNIX 386 v1.1 RM by Erdogan TAN - 28/04/2022" 922 00000624 58203338362076312E- 922 0000062D 3120524D2062792045- 922 00000636 72646F67616E205441- 922 0000063F 4E202D2032382F3034- 922 00000648 2F32303232 923 0000064D 0D0A00 db 0Dh, 0Ah, 0 924 usage_msg: 925 00000650 0D0A db 0Dh, 0Ah 926 00000652 55736167653A20726D- db "Usage: rm [ -fri ] file ..." 926 0000065B 205B202D667269205D- 926 00000664 2066696C65202E2E2E 927 nextline: 928 0000066D 0D0A00 db 0Dh, 0Ah, 0 929 930 unk_op_msg: 931 00000670 0D0A db 0Dh, 0Ah 932 00000672 726D3A20756E6B6E6F- db "rm: unknown option -" 932 0000067B 776E206F7074696F6E- 932 00000684 202D 933 00000686 78 uop: db "x" 934 00000687 0D0A00 db 0Dh, 0Ah, 0 935 936 cnr_dotdot_msg: 937 0000068A 0D0A db 0Dh, 0Ah 938 0000068C 726D3A2063616E6E6F- db "rm: cannot remove '..'" 938 00000695 742072656D6F766520- 938 0000069E 272E2E27 939 000006A2 0D0A00 db 0Dh, 0Ah, 0 940 941 rm_hdr_msg: 942 000006A5 0D0A db 0Dh, 0Ah 943 000006A7 726D3A20 db "rm: " 944 000006AB 00 db 0 945 946 nonex_msg: 947 000006AC 206E6F6E6578697374- db " nonexistent" 947 000006B5 656E74 948 000006B8 0D0A00 db 0Dh, 0Ah, 0 949 950 nchd_msg: 951 000006BB 206E6F74206368616E- db " not changed" 951 000006C4 676564 952 000006C7 0D0A00 db 0Dh, 0Ah, 0 953 dir_hdr_msg: 954 000006CA 0D0A db 0Dh, 0Ah 955 000006CC 6469726563746F7279- db "directory " 955 000006D5 20 956 000006D6 00 db 0 957 958 qu_msg: 959 000006D7 3A db ":" 960 000006D8 203F20 que_msg: db " ? " 961 000006DB 00 db 0 962 963 yes_msg: 964 000006DC 796573 db "yes" 965 000006DF 0D0A00 db 0Dh, 0Ah, 0 966 no_msg: 967 000006E2 6E6F db "no" 968 000006E4 0D0A00 db 0Dh, 0Ah, 0 969 970 cnr_msg: 971 000006E7 3A2063616E6E6F7420- db ": cannot read" 971 000006F0 72656164 972 000006F4 0D0A00 db 0Dh, 0Ah, 0 973 974 dir_msg: 975 000006F7 206469726563746F72- db " directory" 975 00000700 79 976 00000701 00 db 0 977 978 not_rmd_msg: 979 00000702 206E6F742072656D6F- db " not removed" 979 0000070B 766564 980 0000070E 0D0A00 db 0Dh, 0Ah, 0 981 982 mode_msg: 983 00000711 206D6F6465 db " mode" 984 00000716 00 db 0 985 986 cnf_rd_msg: 987 00000717 0D0A db 0Dh, 0Ah 988 00000719 726D3A2063616E2774- db "rm: can't find rmdir" 988 00000722 2066696E6420726D64- 988 0000072B 6972 989 0000072D 0D0A00 db 0Dh, 0Ah, 0 990 991 ;----------------------------------------------------------------- 992 ; bss - uninitialized data 993 ;----------------------------------------------------------------- 994 995 align 2 996 997 bss_start: 998 999 ABSOLUTE bss_start 1000 1001 ; 26/04/2022 1002 00000730 ???? _d_: resw 1 ; Sub directory's file descriptor 1003 00000732 ???? resw 1 1004 ;struct direct direct; 1005 00000734 direct: resb DIRSIZ ; Directory entry buffer 1006 1007 ; 25/04/2022 1008 ;;struct stat buf; 1009 ;stbuf: resb 66 ; for Retro UNIX 386 v1.2 (66 byte sysstat data) 1010 00000744 stbuf: resb 34 ; for Retro UNIX 386 v1.1 (34 byte sysstat data) 1011 1012 ; 26/04/2022 1013 00000766 ?? level: resb 1 ; (sub directory level) 1014 00000767 ???????? octal: resb 4 ; (asciiz octal mode number string) 1015 0000076B ?? chr: resb 1 ; (sysread character buffer) 1016 ; 27/04/2022 1017 ;char name[100]; 1018 ;namebuf: resb 100 1019 1020 1021 ; 25/04/2022 1022 ;----------------------------------------------------------------- 1023 ; Original UNIX v7 - rm (utility) c source code (rm.c) 1024 ;----------------------------------------------------------------- 1025 ;/* UNIX V7 source code: see www.tuhs.org for details. */; 1026 ; 1027 ;int errcode; 1028 ; 1029 ;#include 1030 ;#include 1031 ;#include 1032 ;#include 1033 ; 1034 ;char *sprintf(); 1035 ; 1036 ;main(argc, argv) 1037 ;char *argv[]; 1038 ;{ 1039 ; register char *arg; 1040 ; int fflg, iflg, rflg; 1041 ; 1042 ; fflg = 0; 1043 ; if (isatty(0) == 0) 1044 ; fflg++; 1045 ; iflg = 0; 1046 ; rflg = 0; 1047 ; if(argc>1 && argv[1][0]=='-') { 1048 ; arg = *++argv; 1049 ; argc--; 1050 ; while(*++arg != '\0') 1051 ; switch(*arg) { 1052 ; case 'f': 1053 ; fflg++; 1054 ; break; 1055 ; case 'i': 1056 ; iflg++; 1057 ; break; 1058 ; case 'r': 1059 ; rflg++; 1060 ; break; 1061 ; default: 1062 ; printf("rm: unknown option %s\n", *argv); 1063 ; exit(1); 1064 ; } 1065 ; } 1066 ; while(--argc > 0) { 1067 ; if(!strcmp(*++argv, "..")) { 1068 ; fprintf(stderr, "rm: cannot remove `..'\n"); 1069 ; continue; 1070 ; } 1071 ; rm(*argv, fflg, rflg, iflg, 0); 1072 ; } 1073 ; 1074 ; exit(errcode); 1075 ;} 1076 ; 1077 ;rm(arg, fflg, rflg, iflg, level) 1078 ;char arg[]; 1079 ;{ 1080 ; struct stat buf; 1081 ; struct direct direct; 1082 ; char name[100]; 1083 ; int d; 1084 ; 1085 ; if(stat(arg, &buf)) { 1086 ; if (fflg==0) { 1087 ; printf("rm: %s nonexistent\n", arg); 1088 ; ++errcode; 1089 ; } 1090 ; return; 1091 ; } 1092 ; if ((buf.st_mode&S_IFMT) == S_IFDIR) { 1093 ; if(rflg) { 1094 ; if (access(arg, 02) < 0) { 1095 ; if (fflg==0) 1096 ; printf("%s not changed\n", arg); 1097 ; errcode++; 1098 ; return; 1099 ; } 1100 ; if(iflg && level!=0) { 1101 ; printf("directory %s: ", arg); 1102 ; if(!yes()) 1103 ; return; 1104 ; } 1105 ; if((d=open(arg, 0)) < 0) { 1106 ; printf("rm: %s: cannot read\n", arg); 1107 ; exit(1); 1108 ; } 1109 ; while(read(d, (char *)&direct, sizeof(direct)) == sizeof(direct)) { 1110 ; if(direct.d_ino != 0 && !dotname(direct.d_name)) { 1111 ; sprintf(name, "%s/%.14s", arg, direct.d_name); 1112 ; rm(name, fflg, rflg, iflg, level+1); 1113 ; } 1114 ; } 1115 ; close(d); 1116 ; errcode += rmdir(arg, iflg); 1117 ; return; 1118 ; } 1119 ; printf("rm: %s directory\n", arg); 1120 ; ++errcode; 1121 ; return; 1122 ; } 1123 ; 1124 ; if(iflg) { 1125 ; printf("%s: ", arg); 1126 ; if(!yes()) 1127 ; return; 1128 ; } 1129 ; else if(!fflg) { 1130 ; if (access(arg, 02)<0) { 1131 ; printf("rm: %s %o mode ", arg, buf.st_mode&0777); 1132 ; if(!yes()) 1133 ; return; 1134 ; } 1135 ; } 1136 ; if(unlink(arg) && (fflg==0 || iflg)) { 1137 ; printf("rm: %s not removed\n", arg); 1138 ; ++errcode; 1139 ; } 1140 ;} 1141 ; 1142 ;dotname(s) 1143 ;char *s; 1144 ;{ 1145 ; if(s[0] == '.') 1146 ; if(s[1] == '.') 1147 ; if(s[2] == '\0') 1148 ; return(1); 1149 ; else 1150 ; return(0); 1151 ; else if(s[1] == '\0') 1152 ; return(1); 1153 ; return(0); 1154 ;} 1155 ; 1156 ;rmdir(f, iflg) 1157 ;char *f; 1158 ;{ 1159 ; int status, i; 1160 ; 1161 ; if(dotname(f)) 1162 ; return(0); 1163 ; if(iflg) { 1164 ; printf("%s: ", f); 1165 ; if(!yes()) 1166 ; return(0); 1167 ; } 1168 ; while((i=fork()) == -1) 1169 ; sleep(3); 1170 ; if(i) { 1171 ; wait(&status); 1172 ; return(status); 1173 ; } 1174 ; execl("/bin/rmdir", "rmdir", f, 0); 1175 ; execl("/usr/bin/rmdir", "rmdir", f, 0); 1176 ; printf("rm: can't find rmdir\n"); 1177 ; exit(1); 1178 ;} 1179 ; 1180 ;yes() 1181 ;{ 1182 ; int i, b; 1183 ; 1184 ; i = b = getchar(); 1185 ; while(b != '\n' && b != EOF) 1186 ; b = getchar(); 1187 ; return(i == 'y'); 1188 ;}