1 ; **************************************************************************** 2 ; glob8086.s (glob0.s) - by Erdogan Tan - 28/05/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 8086 v1 - global command (/etc/glob) 5 ; 6 ; [ Last Modification: 30/05/2022 ] 7 ; 8 ; Derived from (original) UNIX v5 'glob.c' source Code 9 ; Ref: 10 ; www.tuhs.org (https://minnie.tuhs.org) 11 ; **************************************************************************** 12 ; [ v5root.tar.gz - usr/source/s1/glob.c (archive date: 27-11-1974) ] 13 ; 14 ; Assembler: NASM v2.15 15 ; ((nasm glob1.s -l glob1.txt -o glob1 -Z error.txt)) 16 17 ; glob2.s - 30/05/2022 - Retro UNIX 386 v1.1 & v1.2 & v2 18 ; glob1.s - 30/05/2022 - Retro UNIX 386 v1 19 ; glob0.s - 30/05/2022 - Retro UNIX 8086 v1 (16 bit 'glob1.s') 20 21 ; 12/01/2022 (Retro UNIX 386 v1.2) 22 ; 13/10/2015 23 24 ; UNIX v1 system calls 25 _rele equ 0 26 _exit equ 1 27 _fork equ 2 28 _read equ 3 29 _write equ 4 30 _open equ 5 31 _close equ 6 32 _wait equ 7 33 _creat equ 8 34 _link equ 9 35 _unlink equ 10 36 _exec equ 11 37 _chdir equ 12 38 _time equ 13 39 _mkdir equ 14 40 _chmod equ 15 41 _chown equ 16 42 _break equ 17 43 _stat equ 18 44 _seek equ 19 45 _tell equ 20 46 _mount equ 21 47 _umount equ 22 48 _setuid equ 23 49 _getuid equ 24 50 _stime equ 25 51 _quit equ 26 52 _intr equ 27 53 _fstat equ 28 54 _emt equ 29 55 _mdate equ 30 56 _stty equ 31 57 _gtty equ 32 58 _ilgins equ 33 59 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 60 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 61 _geterr equ 36 ; Retro UNIX 386 v1 feature only ! 62 ; 12/01/2022 - Retro UNIX 386 v1.2 63 ; Retro UNIX 386 v2 system calls 64 _setgid equ 37 65 _getgid equ 38 66 _sysver equ 39 ; (get) Retro Unix 386 version 67 68 ;;; 69 ESCKey equ 1Bh 70 EnterKey equ 0Dh 71 72 ;%macro sys 1-4 73 ; ; 03/09/2015 74 ; ; 13/04/2015 75 ; ; Retro UNIX 386 v1 system call. 76 ; %if %0 >= 2 77 ; mov ebx, %2 78 ; %if %0 >= 3 79 ; mov ecx, %3 80 ; ;%if %0 = 4 81 ; %if %0 >= 4 ; 11/03/2022 82 ; mov edx, %4 83 ; %endif 84 ; %endif 85 ; %endif 86 ; mov eax, %1 87 ; int 30h 88 ;%endmacro 89 90 %macro sys 1-4 91 ; Retro UNIX 8086 v1 system call. 92 %if %0 >= 2 93 mov bx, %2 94 %if %0 >= 3 95 mov cx, %3 96 %if %0 >= 4 97 mov dx, %4 98 %endif 99 %endif 100 %endif 101 mov ax, %1 102 int 20h 103 %endmacro 104 105 ;; Retro UNIX 386 v1 system call format: 106 ;; sys systemcall (eax) , , 107 108 ;; 11/03/2022 109 ;; Note: Above 'sys' macro has limitation about register positions; 110 ;; ebx, ecx, edx registers must not be used after their 111 ;; positions in sys macro. 112 ;; for example: 113 ;; 'sys _write, 1, msg, ecx' is defective, because 114 ;; ecx will be used/assigned before edx in 'sys' macro. 115 ;; correct order may be: 116 ;; 'sys _write, 1, msg, eax ; (eax = byte count) 117 118 ; Retro UNIX 8086 v1 system call format: 119 ; sys systemcall (ax) , , 120 121 struc stat 122 ; Note: This is for Retro UNIX v1 'sysstat' output !!! 123 ; (34 bytes) 124 00000000 ???? .inode: resw 1 125 00000002 ???? .mode: resw 1 126 00000004 ?? .nlinks: resb 1 127 00000005 ?? .uid: resb 1 128 00000006 ???? .size: resw 1 129 00000008 .dskptr: resw 8 130 00000018 ???????? .ctime: resd 1 131 0000001C ???????? .mtime: resd 1 132 00000020 ???? .rsvd: resw 1 133 .strucsize: 134 endstruc 135 136 ;struc stat 137 ; ; Note: This is for Retro UNIX v1.2 'sysstat' output !!! 138 ; ; (66 bytes) 139 ; .inode: resw 1 140 ; .mode: resw 1 141 ; .nlinks: resw 1 142 ; .uid: resw 1 143 ; .gid: resb 1 144 ; .size_h: resb 1 145 ; .size: resd 1 146 ; .dskptr: resd 10 147 ; .atime: resd 1 148 ; .mtime: resd 1 149 ; .ctime: resd 1 150 ; .strucsize: 151 ;endstruc 152 153 ;;struc stat 154 ;; ; Note: Retro UNIX v2 'sysstat' output DRAFT !!! 155 ;; ; (72 bytes) 156 ;; .idev: resb 1 157 ;; .rsvd: resb 3 158 ;; .inum: resd 1 159 ;; .mode: resw 1 160 ;; .nlinks: resw 1 161 ;; .uid: resw 1 162 ;; .gid: resb 1 163 ;; .size_h: resb 1 164 ;; .size: resd 1 165 ;; .dskptr: resd 10 166 ;; .atime: resd 1 167 ;; .mtime: resd 1 168 ;; .ctime: resd 1 169 ;; .strucsize: 170 ;;endstruc 171 172 ;S_IFMT equ 0F000h ; /* type of file */ 173 ;S_IFDIR equ 04000h ; /* directory */ 174 ;S_IFCHR equ 02000h ; /* character special */ 175 ;S_IFBLK equ 06000h ; /* block special */ 176 ;S_IFREG equ 08000h ; /* regular */ 177 ;S_ISUID equ 00800h ; /* set user id on execution */ 178 ;S_ISGID equ 00400h ; /* set group id on execution */ 179 ;S_IREAD equ 00100h ; /* read permission, owner */ 180 ;S_IWRITE equ 00080h ; /* write permission, owner */ 181 ;S_IEXEC equ 00040h ; /* execute/search permission, owner */ 182 183 S_IFMT equ 0F0h ; /* type of file */ 184 S_IFDIR equ 040h ; /* directory */ 185 S_IFCHR equ 020h ; /* character special */ 186 S_IFBLK equ 060h ; /* block special */ 187 S_IFREG equ 080h ; /* regular */ 188 S_ISUID equ 008h ; /* set user id on execution */ 189 S_ISGID equ 004h ; /* set group id on execution */ 190 S_IREAD equ 001h ; /* read permission, owner */ 191 S_IWRITE equ 080h ; /* write permission, owner */ 192 S_IEXEC equ 040h ; /* execute/search permission, owner */ 193 194 ;; UNIX v1 inode 195 ;; byte 1 196 ;S_ALLOC equ 080h ; Allocated flag 197 ;S_IFDIR equ 040h ; Directory flag 198 ;S_IFMDF equ 020h ; File modified flag (always on) 199 ;S_IFLRG equ 010h ; Large File flag 200 ;; byte 0 201 ;S_ISUID equ 020h ; Set User ID On Execution flag 202 ;S_IEXEC equ 010h ; Executable File flag 203 ;S_IREAD equ 008h ; Owner's Read Permission flag 204 ;S_IWRITE equ 004h ; Owner's Write Permission flag 205 206 ; 28/05/2022 207 STRSIZ equ 522 208 ;DIRSIZ equ 16 ; Retro UNIX 386 v1.1 & v1.2 209 DIRSIZ equ 10 ; Retro UNIX 8086 v1 & 386 v1 210 211 ;----------------------------------------------------------------- 212 ; text - code 213 ;----------------------------------------------------------------- 214 215 [BITS 16] ; 16-bit intructions (for 8086-80386 real mode) 216 217 [ORG 0] 218 219 START_CODE: 220 ; 28/05/2022 221 ;----------------------------------------------------------------- 222 223 main: 224 ; main(argc, argv) 225 226 00000000 58 pop ax ; number of arguments 227 228 ;mov [argc], ax 229 00000001 A2[1803] mov [argc], al 230 231 ;if (argc < 3) { 232 ; write(2, "Arg count\n", 10); 233 ; return; 234 ;} 235 236 ;cmp ax, 3 237 00000004 3C03 cmp al, 3 238 00000006 730B jnb short glb_0 239 240 00000008 B8[B802] mov ax, msg_arg_count 241 glb_print_exit: 242 0000000B E84A02 call print_msg 243 glb_exit: 244 sys _exit ; sys exit 91 <1> 92 <1> %if %0 >= 2 93 <1> mov bx, %2 94 <1> %if %0 >= 3 95 <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 0000000E B80100 <1> mov ax, %1 102 00000011 CD20 <1> int 20h 245 ;hlt: 246 ; nop 247 ; nop 248 ; jmp short hlt 249 250 glb_0: 251 ;argv++; 252 ;*av++ = *argv; 253 00000013 5A pop dx ; argv[0] 254 00000014 BB[2A03] mov bx, ava 255 00000017 8917 mov [bx], dx 256 00000019 83C302 add bx, 2 257 0000001C 5A pop dx ; argv[1] 258 0000001D 8917 mov [bx], dx 259 0000001F 83C302 add bx, 2 260 00000022 891E[1103] mov [av], bx 261 262 ;while (--argc >= 2) 263 ; expand(*++argv); 264 glb_1: 265 00000026 FE0E[1803] dec byte [argc] 266 0000002A 803E[1803]02 cmp byte [argc], 2 267 0000002F 7206 jb short glb_2 268 269 00000031 5D pop bp ; argument pointer 270 271 00000032 E83E00 call expand 272 00000035 EBEF jmp short glb_1 273 274 glb_2: 275 ;if (ncoll==0) { 276 ; write(2, "No match\n", 9); 277 ; return; 278 ;} 279 280 00000037 803E[1A03]00 cmp byte [ncoll], 0 281 0000003C 7705 ja short glb_3 282 283 0000003E B8[C602] mov ax, msg_no_match 284 00000041 EBC8 jmp short glb_print_exit 285 286 glb_3: 287 ;execute(ava[1], &ava[1]); 288 ;cp = cat("/usr/bin/", ava[1]); 289 ;execute(cp+4, &ava[1]); 290 ;execute(cp, &ava[1]); 291 292 sys _exec, [ava+2], ava+2 91 <1> 92 <1> %if %0 >= 2 93 00000043 8B1E[2C03] <1> mov bx, %2 94 <1> %if %0 >= 3 95 00000047 B9[2C03] <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 0000004A B80B00 <1> mov ax, %1 102 0000004D CD20 <1> int 20h 293 0000004F BD[AE02] mov bp, usr_bin 294 ;mov bx, [ava+2] 295 00000052 E8B301 call cat 296 ; cp = binary file name pointer 297 ; dx = cp 298 00000055 89D7 mov di, dx 299 00000057 83C704 add di, 4 300 ;execute(cp+4, &ava[1]) 301 sys _exec, di, ava+2 ; '/bin...' 91 <1> 92 <1> %if %0 >= 2 93 0000005A 89FB <1> mov bx, %2 94 <1> %if %0 >= 3 95 0000005C B9[2C03] <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 0000005F B80B00 <1> mov ax, %1 102 00000062 CD20 <1> int 20h 302 ;execute(cp, &ava[1]); 303 sys _exec, dx, ava+2 ; '/usr/bin...' 91 <1> 92 <1> %if %0 >= 2 93 00000064 89D3 <1> mov bx, %2 94 <1> %if %0 >= 3 95 00000066 B9[2C03] <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 00000069 B80B00 <1> mov ax, %1 102 0000006C CD20 <1> int 20h 304 305 0000006E B8[D302] mov ax, msg_not_found 306 00000071 EB98 jmp glb_print_exit 307 308 ;----------------------------------------------------------------- 309 310 expand: ;expand(as) 311 312 ;register char *s, *cs; 313 ;register int dirf; 314 ;char **oav; 315 316 ;static struct { 317 ; int ino; 318 ; char name[16]; 319 ;} entry; 320 321 ;s = cs = as 322 323 ; INPUT: 324 ; bp = argument pointer 325 326 ; Modified regs: ax, bx, cx, dx, si, di, bp 327 328 00000073 89EE mov si, bp 329 00000075 31D2 xor dx, dx ; dx = 0 330 331 expd_0: 332 ;while (*cs!='*' && *cs!='?' && *cs!='[') { 333 334 00000077 8A04 mov al, [si] 335 00000079 3C2A cmp al, '*' 336 0000007B 7420 je short expd_1 337 0000007D 3C3F cmp al, '?' 338 0000007F 741C je short expd_1 339 00000081 3C5B cmp al, '[' 340 00000083 7418 je short expd_1 341 342 ;if (*cs++ == 0) { 343 ; *av++ = cat(s, ""); 344 ; return; 345 ;} 346 347 00000085 46 inc si 348 00000086 08C0 or al, al 349 00000088 75ED jnz short expd_0 350 351 0000008A 29DB sub bx, bx ; 0 352 353 ; bp = pointer to (current) argument 354 ; bx = 0 355 356 cat_get_av: 357 0000008C E87901 call cat 358 ; dx = concatenated string address (ab[]) 359 360 0000008F 8B1E[1103] mov bx, [av] ; offset address of ava[] pointer 361 00000093 8917 mov [bx], dx ; [bx] = ava[] pointer's itself 362 00000095 83C302 add bx, 2 363 00000098 891E[1103] mov [av], bx ; next ava[] address 364 365 0000009C C3 retn 366 367 expd_1: 368 0000009D 29FF sub di, di ; 0 369 expd_2: 370 ;for (;;) { 371 372 ;if (cs==s) { 373 ; dirf = open(".", 0); 374 ; s = ""; 375 ; break; 376 377 0000009F 39EE cmp si, bp 378 ;jne short expd_4 379 000000A1 7713 ja short expd_4 380 381 ;sub di, di ; 0 382 sys _open, DOT, di ; open '.' for read 91 <1> 92 <1> %if %0 >= 2 93 000000A3 BB[AC02] <1> mov bx, %2 94 <1> %if %0 >= 3 95 000000A6 89F9 <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 000000A8 B80500 <1> mov ax, %1 102 000000AB CD20 <1> int 20h 383 000000AD 7203 jc short expd_3 384 000000AF 89C7 mov di, ax ; file descriptor (>=0) 385 000000B1 47 inc di ; file descriptor + 1 386 expd_3: 387 ; dx = 1 388 000000B2 29ED sub bp, bp ; 0 ; s = "" 389 000000B4 EB24 jmp short expd_break 390 expd_4: 391 ;if (*--cs == '/') { 392 ; *cs = 0; 393 ; dirf = open(s==cs? "/": s, 0); 394 ; *cs++ = 0200; 395 ; break; 396 000000B6 4E dec si 397 000000B7 803C2F cmp byte [si], '/' 398 000000BA 75E3 jne short expd_2 399 000000BC C60400 mov byte [si], 0 400 000000BF 89EA mov dx, bp 401 000000C1 39EE cmp si, bp 402 000000C3 7503 jne short expd_5 403 ;ja short expd_5 404 000000C5 BA[AA02] mov dx, ROOTDIR 405 expd_5: 406 ;dirf = open(s==cs? "/": s, 0); 407 ;sub di, di ; 0 408 sys _open, dx, di ; ; open for read 91 <1> 92 <1> %if %0 >= 2 93 000000C8 89D3 <1> mov bx, %2 94 <1> %if %0 >= 3 95 000000CA 89F9 <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 000000CC B80500 <1> mov ax, %1 102 000000CF CD20 <1> int 20h 409 000000D1 7203 jc short expd_6 410 000000D3 89C7 mov di, ax ; file descriptor (>=0) 411 000000D5 47 inc di ; file descriptor + 1 412 expd_6: 413 000000D6 C60480 mov byte [si], 80h ; *cs++ = 0200; 414 000000D9 46 inc si 415 expd_7: 416 expd_break: 417 ;if (dirf<0) { 418 ; write(2, "No directory\n", 13); 419 ; exit(); 420 ;} 421 000000DA 4F dec di ; 1 -> 0 or 0 -> -1 422 000000DB 790B jns short expd_9 423 424 000000DD B8[EA02] mov ax, msg_no_dir 425 expd_8: 426 000000E0 E87501 call print_msg 427 _exit_: 428 sys _exit 91 <1> 92 <1> %if %0 >= 2 93 <1> mov bx, %2 94 <1> %if %0 >= 3 95 <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 000000E3 B80100 <1> mov ax, %1 102 000000E6 CD20 <1> int 20h 429 ;hang: 430 ;nop 431 ;jmp short hang 432 433 expd_9: 434 ;oav = av; 435 000000E8 FF36[1103] push word [av] 436 expd_10: 437 ;while (read(dirf, &entry, 16) == 16) { 438 439 sys _read, di, entry, DIRSIZ 91 <1> 92 <1> %if %0 >= 2 93 000000EC 89FB <1> mov bx, %2 94 <1> %if %0 >= 3 95 000000EE B9[1C03] <1> mov cx, %3 96 <1> %if %0 >= 4 97 000000F1 BA0A00 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 000000F4 B80300 <1> mov ax, %1 102 000000F7 CD20 <1> int 20h 440 000000F9 721C jc short expd_11 441 ;cmp ax, 10 442 ;jne short expd_11 443 000000FB 09C0 or ax, ax ; read count 444 000000FD 7418 jz short expd_11 445 446 ;if (entry.ino==0) 447 ; continue; 448 000000FF 833E[1C03]00 cmp word [entry.ino], 0 449 00000104 76E6 jna short expd_10 ; continue 450 451 ;if (match(entry.name, cs) 452 00000106 BB[1E03] mov bx, entry.name 453 ; si = cs 454 00000109 E85200 call match 455 0000010C 75DE jnz short expd_10 456 457 ; bp = pointer to (current) argument 458 ; bx = entry.name 459 460 ;; *av++ = cat(s, entry.name); 461 ;call cat 462 ;; dx = concatenated string address (ab[]) 463 464 ;mov bx, [av] 465 ;mov [bx], dx 466 ;add bx, 2 467 ;mov [av], bx 468 469 ; *av++ = cat(s, entry.name); 470 0000010E E87BFF call cat_get_av 471 472 ; ncoll++; 473 00000111 FE06[1A03] inc byte [ncoll] 474 475 ; di = file descriptor = dirf 476 ; si = cs 477 ; bp = s 478 479 00000115 EBD5 jmp short expd_10 480 481 expd_11: 482 ;close(dirf); 483 sys _close, di 91 <1> 92 <1> %if %0 >= 2 93 00000117 89FB <1> mov bx, %2 94 <1> %if %0 >= 3 95 <1> mov cx, %3 96 <1> %if %0 >= 4 97 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 00000119 B80600 <1> mov ax, %1 102 0000011C CD20 <1> int 20h 484 0000011E 5E pop si ; oav 485 ;sort(oav); 486 ;call sort 487 ;retn 488 ;;jmp sort 489 490 ;----------------------------------------------------------------- 491 492 sort: ;sort(oav) 493 494 ; INPUT: 495 ; si = first ptr to 496 ; file/dir names to be sorted 497 498 ;p1 = oav; 499 0000011F A1[1103] mov ax, [av] 500 00000122 83E802 sub ax, 2 501 00000125 8B16[1103] mov dx, [av] ; dx = [av] 502 srt_1: 503 ; ax = [av] - 2 504 ;while (p1 < av-1) { 505 00000129 39C6 cmp si, ax ; si = p1 506 0000012B 731B jnb short srt_4 507 0000012D 89F7 mov di, si ; p2 = p1; 508 srt_2: 509 ;while(++p2 < av) { 510 0000012F 83C702 add di, 2 511 00000132 39D7 cmp di, dx ; di = p2 512 00000134 730D jnb short srt_3 513 514 ;if (compar(*p1, *p2) > 0) 515 00000136 E81000 call compar 516 00000139 76F4 jna short srt_2 517 518 ;c = *p1; 519 ;*p1 = *p2; 520 ;*p2 = c; 521 0000013B 8B0D mov cx, [di] 522 0000013D 870C xchg [si], cx 523 0000013F 890D mov [di], cx 524 525 00000141 EBEC jmp short srt_2 526 527 srt_3: 528 ;p1++; 529 00000143 83C602 add si, 2 530 00000146 EBE1 jmp short srt_1 531 srt_4: 532 00000148 C3 retn 533 534 ;----------------------------------------------------------------- 535 536 compar: ;compar(as1, as2) 537 ; INPUT: 538 ; si = p1 ; asciiz string (compared) 539 ; di = p2 ; asciiz string (with this) 540 ; 541 ; OUTPUT: 542 ; *p1 - *p2 (first non-equal chars) 543 ; 0 = equal strings (with p2 length) 544 545 ; Modified registers: cx, bx, bp 546 ; 547 548 ;s1 = as1; 549 ;s2 = as2; 550 551 00000149 8B1C mov bx, [si] ; *p1 552 0000014B 8B2D mov bp, [di] ; *p2 553 comp_1: 554 ;while (*s1++ == *s2) 555 ; if (*s2++ == 0) 556 0000014D 8A0F mov cl, [bx] ; *s1++ 557 0000014F 43 inc bx 558 00000150 8A6E00 mov ch, [bp] ; *s2 559 00000153 45 inc bp 560 ;return (*--s1 - *s2); 561 00000154 28E9 sub cl, ch 562 00000156 7401 jz short comp_2 563 00000158 C3 retn 564 comp_2: 565 ;if (*s2++ == 0) 566 ; return(0); 567 00000159 08ED or ch, ch 568 0000015B 75F0 jnz short comp_1 569 ; zf = 1 570 mtch_0: 571 0000015D C3 retn 572 573 ;----------------------------------------------------------------- 574 575 match: ; match(s, p) 576 577 ; char *s, *p; 578 ; if (*s=='.' && *p!='.') 579 ; return(0); 580 ; return(amatch(s, p)); 581 582 ; INPUT: 583 ; bx = directory entry 584 ; si = user input 585 ; OUTPUT: 586 ; zf = 1 -> 587 ; dir entry matches with input 588 ; zf = 0 -> 589 ; dir entry does not match with input 590 ; 591 ; Modified registers: ax, cx, dx 592 593 0000015E 8A07 mov al, [bx] ; *s 594 00000160 3C2E cmp al, '.' 595 00000162 7504 jne short mtch_1 596 00000164 3A04 cmp al, [si] ; *p 597 ;je short mtch_1 598 ;retn ; zf = 0 599 00000166 75F5 jne short mtch_0 ; retn ; zf = 0 600 mtch_1: 601 00000168 56 push si ; * 602 00000169 57 push di ; ** 603 0000016A 53 push bx ; *** 604 0000016B 55 push bp ; **** 605 606 0000016C E80500 call amatch 607 608 0000016F 5D pop bp ; **** 609 00000170 5B pop bx ; *** 610 00000171 5F pop di ; ** 611 00000172 5E pop si ; * 612 613 00000173 C3 retn 614 615 ;----------------------------------------------------------------- 616 617 amatch: ;amatch(as, ap) 618 619 ;char *as, *ap; 620 ; 621 ;register char *s, *p; 622 ;register scc; 623 ;int c, cc, ok, lc; 624 625 ; INPUT: 626 ; bx = directory entry 627 ; si = user input 628 ; OUTPUT: 629 ; zf = 1 -> 630 ; dir entry matches with input 631 ; zf = 0 -> 632 ; dir entry does not match with input 633 ; 634 ; Modified registers: ax, cx, dx, bx, si, di, bp 635 636 00000174 31C0 xor ax, ax 637 638 ;s = as; 639 ;p = ap; 640 641 amch_next: 642 ;if (scc = *s++) 643 ; if ((scc =& 0177) == 0) 644 ; scc = 0200; 645 646 ; si = p 647 ; bx = s 648 649 00000176 8A07 mov al, [bx] ; *s++ 650 00000178 43 inc bx 651 ;mov bp, ax ; scc 652 00000179 20C0 and al, al 653 0000017B 7406 jz short amch_0 654 0000017D 247F and al, 7Fh ; 127 655 0000017F 7502 jnz short amch_0 656 00000181 0C80 or al, 80h ; scc = 80h 657 amch_0: 658 00000183 89C5 mov bp, ax ; scc 659 660 switch: ;switch (c = *p++) { 661 662 00000185 AC lodsb 663 00000186 3C5B cmp al, '[' 664 00000188 7531 jne short amch_10 665 amch_1: 666 ;case '[': 667 ;ok = 0; 668 ;lc = 077777; 669 ;while (cc = *p++) { 670 ; if (cc==']') { 671 ; if (ok) 672 ; return(amatch(s, p)); 673 ; else 674 ; return(0); 675 ; } else if (cc=='-') { 676 ; if (lc<=scc && scc<=(c = *p++)) 677 ; ok++; 678 ; } else 679 ; if (scc == (lc=cc)) 680 ; ok++; 681 ; } 682 ; return(0); 683 684 0000018A 31C9 xor cx, cx ; ok = 0 685 0000018C BAFF7F mov dx, 7FFFh ; lc = 077777 686 amch_2: 687 ;while (cc = *p++) { 688 0000018F AC lodsb ; cc = *p++ 689 00000190 20C0 and al, al 690 00000192 7456 jz short amch_x 691 00000194 3C5D cmp al, ']' ; if (cc=']') 692 00000196 750B jne short amch_3 693 00000198 21C9 and cx, cx ; 0 ; if (ok) 694 0000019A 744C jz short amch_xx 695 696 ;return(amatch(s, p)); 697 ; bx = s 698 ; si = p 699 0000019C E8D5FF call amatch 700 0000019F FEC8 dec al ; 1 -> 0, 0 -> 0FFh 701 000001A1 EB47 jmp short amch_x 702 amch_3: 703 000001A3 3C2D cmp al, '-' ; else if (cc='-') 704 000001A5 750C jne short amch_5 705 000001A7 39EA cmp dx, bp ; if (lc<=scc 706 000001A9 77E4 ja short amch_2 ; while 707 ; && scc<=(c = *p++)) 708 000001AB AC lodsb 709 000001AC 39C5 cmp bp, ax 710 000001AE 77DF ja short amch_2 ; while 711 amch_4: 712 000001B0 41 inc cx ; ok++; 713 000001B1 EBDC jmp short amch_2 ; while 714 amch_5: 715 000001B3 89C2 mov dx, ax ; (lc=cc) 716 000001B5 39C5 cmp bp, ax ; if (scc == (lc=cc)) 717 000001B7 75D6 jne short amch_2 ; while 718 000001B9 EBF5 jmp short amch_4 ; ok++; ; while 719 amch_10: 720 000001BB 3C3F cmp al, '?' 721 000001BD 750B jne short amch_20 722 amch_11: 723 ;case '?': 724 ; if (scc) 725 ; return(amatch(s, p)); 726 ; return(0); 727 728 000001BF 09ED or bp, bp 729 000001C1 7425 jz short amch_xx ; not match 730 731 ;return(amatch(s, p)); 732 ; bx = s 733 ; si = p 734 000001C3 E8AEFF call amatch 735 000001C6 FEC8 dec al ; 1 -> 0, 0 -> 0FFh 736 000001C8 EB20 jmp short amch_x 737 amch_20: 738 000001CA 3C2A cmp al, '*' 739 000001CC 7508 jne short amch_30 740 amch_21: 741 ;case '*': 742 ; return(umatch(--s, p)); 743 744 000001CE 4B dec bx ; --s 745 ; bx = s 746 ; si = p 747 000001CF E81B00 call umatch 748 000001D2 FEC8 dec al ; 1 -> 0, 0 -> 0FFh 749 000001D4 EB14 jmp short amch_x 750 amch_30: 751 000001D6 20C0 and al, al 752 000001D8 7508 jnz short amch_40 ; default 753 amch_31: 754 ;case '\0': 755 ; return(!scc); 756 757 ; al = 0 758 000001DA 09ED or bp, bp 759 000001DC 750C jnz short amch_x ; not match 760 000001DE FEC8 dec al ; 0FFh 761 000001E0 EB08 jmp short amch_x ; match 762 amch_40: 763 ;default: 764 ; if (c!=scc) 765 ; return(0); 766 767 000001E2 39E8 cmp ax, bp 768 000001E4 7502 jne short amch_xx ; not match 769 ;mov al, 0FFh 770 ;jmp short amch_x ; match 771 000001E6 EB8E jmp amch_next 772 773 amch_xx: 774 000001E8 30C0 xor al, al ; 0 775 amch_x: 776 ; al = 0 -> not match 777 ; al = 0FFh -> match 778 779 000001EA FEC0 inc al ; 0 -> 1, 0FFh -> 0 780 781 ; al = 0 -> zf = 1 782 ; al > 0 -> zf = 0 783 umch_x: 784 000001EC C3 retn 785 786 ;----------------------------------------------------------------- 787 788 umatch: ; umatch(s, p) 789 ; char *s, *p; 790 791 ; INPUT: 792 ; bx = s 793 ; si = p 794 ; OUTPUT: 795 ; zf = 1 -> 796 ; dir entry matches with input 797 ; zf = 0 -> 798 ; dir entry does not match with input 799 ; 800 ; Modified registers: ax, bx, cx, dx 801 802 ;if(*p==0) 803 ; return(1); 804 ;while(*s) 805 ; if (amatch(s++,p)) 806 ; return(1); 807 ;return(0); 808 809 000001ED 8A04 mov al, [si] 810 000001EF 08C0 or al, al ; if (*p==0) 811 000001F1 74F9 jz short umch_x ; return(1) ; match 812 umch_0: 813 000001F3 8A07 mov al, [bx] ; while(*s) 814 000001F5 20C0 and al, al 815 000001F7 7503 jnz short umch_2 816 000001F9 FEC0 inc al ; 1 ; not match 817 umch_1: 818 000001FB C3 retn 819 umch_2: 820 ; bx = s 821 ; si = p 822 000001FC 56 push si 823 000001FD 53 push bx 824 000001FE E873FF call amatch 825 00000201 5B pop bx 826 00000202 5E pop si 827 00000203 74F6 jz short umch_1 ; al = 0 ; match 828 829 ; al = 1 ; not match 830 00000205 43 inc bx ; s++ 831 00000206 EBEB jmp short umch_0 832 833 ;----------------------------------------------------------------- 834 835 cat: ;cat(as1, as2) 836 837 ;char *as1, *as2; 838 839 ;register char *s1, *s2; 840 ;register int c; 841 842 ; INPUT: 843 ; bp = base name (path) 844 ; bx = name to be added 845 ; OUTPUT: 846 ; dx = concatenated name (path) 847 ; 848 ; Modified regs: ax, cx, dx 849 850 ;s2 = string; 851 ;s1 = as1; 852 853 ; bp = as1 854 ; bx = as2 855 856 00000208 56 push si ; * 857 00000209 57 push di ; ** 858 859 0000020A 8B3E[1303] mov di, [string] ; s2 = string 860 0000020E 09ED or bp, bp ; 0 ? 861 00000210 7425 jz short cat_3 862 00000212 89EE mov si, bp ; s1 = as1 863 cat_0: 864 ;while (c = *s1++) { 865 866 00000214 AC lodsb 867 00000215 08C0 or al, al 868 00000217 7412 jz short cat_2 869 870 ;if (s2 > &ab[STRSIZ]) 871 ; toolong(); 872 873 00000219 81FF[FC05] cmp di, ab+STRSIZ 874 0000021D 7331 jnb short cat_too_long 875 876 0000021F 247F and al, 7Fh ; c =& 0177; 877 00000221 7505 jnz short cat_1 878 879 ;if (c==0) { 880 ; *s2++ = '/'; 881 ; break; 882 883 ;or bx, bx ; bx = 0 ? 884 ;jz short cat_5 ; al = 0 885 886 00000223 B02F mov al, '/' 887 00000225 AA stosb 888 ;jmp short cat_3 889 00000226 EB03 jmp short cat_2 890 891 cat_1: 892 ; *s2++ = c; 893 00000228 AA stosb 894 00000229 EBE9 jmp short cat_0 ; while 895 cat_2: 896 ; al = 0 897 0000022B 21DB and bx, bx ; bx = 0 ? 898 0000022D 7508 jnz short cat_3 899 0000022F 81FF[FC05] cmp di, ab+STRSIZ 900 00000233 720B jb short cat_5 901 00000235 EB19 jmp short cat_too_long 902 cat_3: 903 ;s1 = as2; 904 00000237 89DE mov si, bx 905 cat_4: 906 ;do { 907 ; if (s2 > &ab[STRSIZ]) 908 ; toolong(); 909 ; *s2++ = c = *s1++; 910 ;} while (c); 911 912 00000239 81FF[FC05] cmp di, ab+STRSIZ 913 0000023D 7311 jnb short cat_too_long 914 915 0000023F AC lodsb ; c = *s1++; 916 cat_5: 917 00000240 AA stosb ; *s2++ = c 918 00000241 20C0 and al, al ; while (c); 919 00000243 75F4 jnz short cat_4 920 921 ;s1 = string; 922 ;string = s2; 923 924 00000245 8B16[1303] mov dx, [string] 925 00000249 893E[1303] mov [string], di 926 927 ;return(s1); 928 929 0000024D 5F pop di ; ** 930 0000024E 5E pop si ; * 931 0000024F C3 retn 932 933 ;----------------------------------------------------------------- 934 935 cat_too_long: 936 00000250 5F pop di ; ** 937 00000251 5E pop si ; * 938 too_long: 939 00000252 B8[FB02] mov ax, msg_too_long 940 00000255 E9B3FD jmp glb_print_exit 941 942 ; call print_msg 943 ; 944 ; sys _exit ; sys exit 945 ;hangemhigh: 946 ; nop 947 ; nop 948 ; jmp short hangemhigh 949 950 ;----------------------------------------------------------------- 951 952 print_msg: 953 ; ax = asciiz string address 954 00000258 89C6 mov si, ax 955 0000025A 4E dec si 956 nextchr: 957 0000025B 46 inc si 958 0000025C 803C00 cmp byte [si], 0 959 0000025F 77FA ja short nextchr 960 ;cmp [si], 0Dh 961 ;ja short nextchr 962 00000261 29C6 sub si, ax 963 ; si = asciiz string length 964 ; 965 sys _write, 1, ax, si 91 <1> 92 <1> %if %0 >= 2 93 00000263 BB0100 <1> mov bx, %2 94 <1> %if %0 >= 3 95 00000266 89C1 <1> mov cx, %3 96 <1> %if %0 >= 4 97 00000268 89F2 <1> mov dx, %4 98 <1> %endif 99 <1> %endif 100 <1> %endif 101 0000026A B80400 <1> mov ax, %1 102 0000026D CD20 <1> int 20h 966 ; 967 0000026F C3 retn 968 969 ;----------------------------------------------------------------- 970 ; data - initialized data 971 ;----------------------------------------------------------------- 972 973 program_msg: 974 00000270 00 db 0 975 00000271 526574726F20554E49- db 'Retro UNIX 8086 v1 /etc/glob by Erdogan TAN' 975 0000027A 582038303836207631- 975 00000283 202F6574632F676C6F- 975 0000028C 62206279204572646F- 975 00000295 67616E2054414E 976 0000029C 202D2033302F30352F- db ' - 30/05/2022' 976 000002A5 32303232 977 000002A9 00 db 0 978 979 ROOTDIR: 980 000002AA 2F00 db '/', 0 981 982 000002AC 2E00 DOT: db '.', 0 983 ;db 0, 0 984 985 usr_bin: 986 000002AE 2F7573722F62696E2F- db '/usr/bin/', 0 986 000002B7 00 987 988 msg_arg_count: 989 000002B8 0D0A db 0Dh, 0Ah 990 000002BA 41726720636F756E74 db "Arg count" 991 nextline: 992 000002C3 0D0A00 db 0Dh, 0Ah, 0 993 994 msg_no_match: 995 000002C6 0D0A db 0Dh, 0Ah 996 000002C8 4E6F206D61746368 db "No match" 997 000002D0 0D0A00 db 0Dh, 0Ah, 0 998 999 msg_not_found: 1000 000002D3 0D0A db 0Dh, 0Ah 1001 000002D5 436F6D6D616E64206E- db "Command not found." 1001 000002DE 6F7420666F756E642E 1002 000002E7 0D0A00 db 0Dh, 0Ah, 0 1003 1004 msg_no_dir: 1005 000002EA 0D0A db 0Dh, 0Ah 1006 000002EC 4E6F20646972656374- db "No directory" 1006 000002F5 6F7279 1007 000002F8 0D0A00 db 0Dh, 0Ah, 0 1008 1009 msg_too_long: 1010 000002FB 0D0A db 0Dh, 0Ah 1011 000002FD 417267206C69737420- db 'Arg list too long' 1011 00000306 746F6F206C6F6E67 1012 0000030E 0D0A00 db 0Dh, 0Ah, 0 1013 1014 00000311 [2A03] av: dw ava ;char **av &ava[1]; 1015 00000313 [F203] string: dw ab ;char *string ab; 1016 1017 ;----------------------------------------------------------------- 1018 ; bss - uninitialized data 1019 ;----------------------------------------------------------------- 1020 1021 00000315 90 align 4 1022 1023 bss_start: 1024 1025 ABSOLUTE bss_start 1026 1027 ;argc: resd 1 1028 00000318 ?? argc: resb 1 1029 00000319 ?? errno: resb 1 ;int errno; 1030 0000031A ???? ncoll: resw 1 ;int ncoll; 1031 entry: 1032 entry.ino: 1033 0000031C ???? resw 1 1034 entry.name: 1035 ;resb 14 1036 0000031E resb 10 1037 00000328 ???? resb 2 1038 1039 0000032A ava: resb 200 1040 000003F2 ab: resb STRSIZ ; 522 1041 1042 ; 28/05/2022 1043 ;----------------------------------------------------------------- 1044 ; Original UNIX v5 - /etc/glob (utility) c source code (glob.c) 1045 ;----------------------------------------------------------------- 1046 ;/* UNIX V5 source code: see www.tuhs.org for details. */; 1047 ; * v5root.tar.gz (/usr/source/s1) * 1048 ; 1049 ;# 1050 ;/* global command -- 1051 ; 1052 ; glob params 1053 ; 1054 ; "*" in params matches r.e ".*" 1055 ; "?" in params matches r.e. "." 1056 ; "[...]" in params matches character class 1057 ; "[...a-z...]" in params matches a through z. 1058 ; 1059 ; perform command with argument list 1060 ; constructed as follows: 1061 ; if param does not contain "*", "[", or "?", use it as is 1062 ; if it does, find all files in current directory 1063 ; which match the param, sort them, and use them 1064 ; 1065 ; prepend the command name with "/bin" or "/usr/bin" 1066 ; as required. 1067 ;*/ 1068 ; 1069 ;#define E2BIG 7 1070 ;#define ENOEXEC 8 1071 ;#define ENOENT 2 1072 ; 1073 ;#define STRSIZ 522 1074 ;char ab[STRSIZ]; /* generated characters */ 1075 ;char *ava[200]; /* generated arguments */ 1076 ;char **av &ava[1]; 1077 ;char *string ab; 1078 ;int errno; 1079 ;int ncoll; 1080 ; 1081 ;main(argc, argv) 1082 ;char *argv[]; 1083 ;{ 1084 ; register char *cp; 1085 ; 1086 ; if (argc < 3) { 1087 ; write(2, "Arg count\n", 10); 1088 ; return; 1089 ; } 1090 ; argv++; 1091 ; *av++ = *argv; 1092 ; while (--argc >= 2) 1093 ; expand(*++argv); 1094 ; if (ncoll==0) { 1095 ; write(2, "No match\n", 9); 1096 ; return; 1097 ; } 1098 ; execute(ava[1], &ava[1]); 1099 ; cp = cat("/usr/bin/", ava[1]); 1100 ; execute(cp+4, &ava[1]); 1101 ; execute(cp, &ava[1]); 1102 ; write(2, "Command not found.\n", 19); 1103 ;} 1104 ; 1105 ;expand(as) 1106 ;char *as; 1107 ;{ 1108 ; register char *s, *cs; 1109 ; register int dirf; 1110 ; char **oav; 1111 ; static struct { 1112 ; int ino; 1113 ; char name[16]; 1114 ; } entry; 1115 ; 1116 ; s = cs = as; 1117 ; while (*cs!='*' && *cs!='?' && *cs!='[') { 1118 ; if (*cs++ == 0) { 1119 ; *av++ = cat(s, ""); 1120 ; return; 1121 ; } 1122 ; } 1123 ; for (;;) { 1124 ; if (cs==s) { 1125 ; dirf = open(".", 0); 1126 ; s = ""; 1127 ; break; 1128 ; } 1129 ; if (*--cs == '/') { 1130 ; *cs = 0; 1131 ; dirf = open(s==cs? "/": s, 0); 1132 ; *cs++ = 0200; 1133 ; break; 1134 ; } 1135 ; } 1136 ; if (dirf<0) { 1137 ; write(2, "No directory\n", 13); 1138 ; exit(); 1139 ; } 1140 ; oav = av; 1141 ; while (read(dirf, &entry, 16) == 16) { 1142 ; if (entry.ino==0) 1143 ; continue; 1144 ; if (match(entry.name, cs)) { 1145 ; *av++ = cat(s, entry.name); 1146 ; ncoll++; 1147 ; } 1148 ; } 1149 ; close(dirf); 1150 ; sort(oav); 1151 ;} 1152 ; 1153 ;sort(oav) 1154 ;char **oav; 1155 ;{ 1156 ; register char **p1, **p2, **c; 1157 ; 1158 ; p1 = oav; 1159 ; while (p1 < av-1) { 1160 ; p2 = p1; 1161 ; while(++p2 < av) { 1162 ; if (compar(*p1, *p2) > 0) { 1163 ; c = *p1; 1164 ; *p1 = *p2; 1165 ; *p2 = c; 1166 ; } 1167 ; } 1168 ; p1++; 1169 ; } 1170 ;} 1171 ; 1172 ;execute(afile, aarg) 1173 ;char *afile; 1174 ;char **aarg; 1175 ;{ 1176 ; register char *file, **arg; 1177 ; 1178 ; arg = aarg; 1179 ; file = afile; 1180 ; execv(file, arg); 1181 ; if (errno==ENOEXEC) { 1182 ; arg[0] = file; 1183 ; *--arg = "/bin/sh"; 1184 ; execv(*arg, arg); 1185 ; } 1186 ; if (errno==E2BIG) 1187 ; toolong(); 1188 ;} 1189 ; 1190 ;toolong() 1191 ;{ 1192 ; write(2, "Arg list too long\n", 18); 1193 ; exit(); 1194 ;} 1195 ; 1196 ;match(s, p) 1197 ;char *s, *p; 1198 ;{ 1199 ; if (*s=='.' && *p!='.') 1200 ; return(0); 1201 ; return(amatch(s, p)); 1202 ;} 1203 ; 1204 ;amatch(as, ap) 1205 ;char *as, *ap; 1206 ;{ 1207 ; register char *s, *p; 1208 ; register scc; 1209 ; int c, cc, ok, lc; 1210 ; 1211 ; s = as; 1212 ; p = ap; 1213 ; if (scc = *s++) 1214 ; if ((scc =& 0177) == 0) 1215 ; scc = 0200; 1216 ; switch (c = *p++) { 1217 ; 1218 ; case '[': 1219 ; ok = 0; 1220 ; lc = 077777; 1221 ; while (cc = *p++) { 1222 ; if (cc==']') { 1223 ; if (ok) 1224 ; return(amatch(s, p)); 1225 ; else 1226 ; return(0); 1227 ; } else if (cc=='-') { 1228 ; if (lc<=scc && scc<=(c = *p++)) 1229 ; ok++; 1230 ; } else 1231 ; if (scc == (lc=cc)) 1232 ; ok++; 1233 ; } 1234 ; return(0); 1235 ; 1236 ; default: 1237 ; if (c!=scc) 1238 ; return(0); 1239 ; 1240 ; case '?': 1241 ; if (scc) 1242 ; return(amatch(s, p)); 1243 ; return(0); 1244 ; 1245 ; case '*': 1246 ; return(umatch(--s, p)); 1247 ; 1248 ; case '\0': 1249 ; return(!scc); 1250 ; } 1251 ;} 1252 ; 1253 ;umatch(s, p) 1254 ;char *s, *p; 1255 ;{ 1256 ; if(*p==0) 1257 ; return(1); 1258 ; while(*s) 1259 ; if (amatch(s++,p)) 1260 ; return(1); 1261 ; return(0); 1262 ;} 1263 ; 1264 ;compar(as1, as2) 1265 ;char *as1, *as2; 1266 ;{ 1267 ; register char *s1, *s2; 1268 ; 1269 ; s1 = as1; 1270 ; s2 = as2; 1271 ; while (*s1++ == *s2) 1272 ; if (*s2++ == 0) 1273 ; return(0); 1274 ; return (*--s1 - *s2); 1275 ;} 1276 ; 1277 ;cat(as1, as2) 1278 ;char *as1, *as2; 1279 ;{ 1280 ; register char *s1, *s2; 1281 ; register int c; 1282 ; 1283 ; s2 = string; 1284 ; s1 = as1; 1285 ; while (c = *s1++) { 1286 ; if (s2 > &ab[STRSIZ]) 1287 ; toolong(); 1288 ; c =& 0177; 1289 ; if (c==0) { 1290 ; *s2++ = '/'; 1291 ; break; 1292 ; } 1293 ; *s2++ = c; 1294 ; } 1295 ; s1 = as2; 1296 ; do { 1297 ; if (s2 > &ab[STRSIZ]) 1298 ; toolong(); 1299 ; *s2++ = c = *s1++; 1300 ; } while (c); 1301 ; s1 = string; 1302 ; string = s2; 1303 ; return(s1); 1304 ;} 1305 1306 ; 28/05/2022 1307 ;----------------------------------------------------------------- 1308 ; Original UNIX v2 - /etc/glob (utility) c source code (glob.c) 1309 ;----------------------------------------------------------------- 1310 ;/* UNIX V2 source code: see www.tuhs.org for details. */; 1311 ; * svntree-20081216.tar.gz (unix72) * 1312 ; 1313 ;/* global command -- 1314 ; 1315 ; glob params 1316 ; 1317 ; "*" in params matches r.e ".*" 1318 ; "?" in params matches r.e. "." 1319 ; "[...]" in params matches character class 1320 ; "[...a-z...]" in params matches a through z. 1321 ; 1322 ; perform command with argument list 1323 ; constructed as follows: 1324 ; if param does not contain "*", "[", or "?", use it as is 1325 ; if it does, find all files in current directory 1326 ; which match the param, sort them, and use them 1327 ; 1328 ; prepend the command name with "/bin" or "/usr/bin" 1329 ; as required. 1330 ;*/ 1331 ; 1332 ;char ab[2000]; /* generated characters */ 1333 ;char *ava[200]; /* generated arguments */ 1334 ;char **av ava; 1335 ;char *string ab; 1336 ; 1337 ;main(argc, argv) 1338 ;char *argv[]; 1339 ;{ 1340 ; int i, j, c; 1341 ; int inode, dirf, ap; 1342 ; int fb[5], sb[17]; 1343 ; char *cp, *cpo; 1344 ; 1345 ; if (argc < 3) { 1346 ; write(1, "Arg count\n", 10); 1347 ; return; 1348 ; } 1349 ; ap = 0; 1350 ; av++; 1351 ; fb[4] = 0; 1352 ;loop: 1353 ; cpo = cp = *++argv; 1354 ; while(c = *cp++) if (c=='*' | c=='?' | c=='[') goto compl; 1355 ; av[ap++] = copy(cpo); 1356 ; if (--argc>=2) goto loop; 1357 ; goto donow; 1358 ; 1359 ;compl: 1360 ; if(*--cp == '/') { 1361 ; *cp = '\0'; 1362 ; if((dirf=open(cp==cpo? "/" : cpo, 0))<0) 1363 ; goto oper; 1364 ; *cp++ = '/'; 1365 ; goto compl1; 1366 ; } 1367 ; if(cp != cpo) goto compl; 1368 ; if((dirf=open(".",0)) >= 0) goto compl1; 1369 ;oper: 1370 ; write(1, "No directory\n", 13); 1371 ; return; 1372 ;compl1: 1373 ; j = ap; 1374 ;l2: 1375 ; while (read(dirf, &inode, 2)>0) { 1376 ; read(dirf, fb, 8); 1377 ; if (inode==0) goto l2; 1378 ; if (match(fb, cp)) { 1379 ; c = *cp; 1380 ; *cp = '\0'; 1381 ; av[ap++] = cat(cpo, fb); 1382 ; *cp = c; 1383 ; } 1384 ; } 1385 ; close(dirf); 1386 ; i = j; 1387 ; while(i=2) goto loop; 1399 ;donow: 1400 ; if (ap<=1) { 1401 ; write(1, "No match\n", 9); 1402 ; return; 1403 ; } 1404 ; av[ap] = 0; 1405 ; execv(av[0], av); 1406 ; i = cat("/bin/", av[0]); 1407 ; execv(i, av); 1408 ; i = cat("/usr", i); 1409 ; execv(i, av); 1410 ; if (stat(i, sb) == 0) { 1411 ; *av = i; 1412 ; *--av = "/bin/sh"; 1413 ; execv(av[0], av); 1414 ; } 1415 ; write(1, "No command\n", 11); 1416 ;} 1417 ; 1418 ;match(s, p) 1419 ;char *s, *p; { 1420 ; if (*s=='.' & *p!='.') return(0); 1421 ; return(amatch(s, p)); 1422 ;} 1423 ; 1424 ;amatch(s, p) 1425 ;char *s, *p; 1426 ;{ 1427 ; int c, cc, ok, lc, scc; 1428 ; 1429 ; scc = *s; 1430 ; lc = 077777; 1431 ; switch (c = *p) { 1432 ; 1433 ; case '[': 1434 ; ok = 0; 1435 ; while (cc = *++p) { 1436 ; switch (cc) { 1437 ; 1438 ; case ']': 1439 ; if (ok) 1440 ; return(amatch(++s, ++p)); 1441 ; else 1442 ; return(0); 1443 ; 1444 ; case '-': 1445 ; ok =| lc <= scc & scc <= (cc=p[1]); 1446 ; } 1447 ; if (scc==(lc=cc)) ok++; 1448 ; } 1449 ; return(0); 1450 ; 1451 ; case '?': 1452 ; caseq: 1453 ; if(scc) return(amatch(++s, ++p)); 1454 ; return(0); 1455 ; case '*': 1456 ; return(umatch(s, ++p)); 1457 ; case 0: 1458 ; return(!scc); 1459 ; } 1460 ; if (c==scc) goto caseq; 1461 ; return(0); 1462 ;} 1463 ; 1464 ;umatch(s, p) 1465 ;char *s, *p; 1466 ;{ 1467 ; if(*p==0) return(1); 1468 ; while(*s) 1469 ; if (amatch(s++,p)) return(1); 1470 ; return(0); 1471 ;} 1472 ; 1473 ;compar(s1,s2) 1474 ;char *s1, *s2; 1475 ;{ 1476 ; int c1,c2; 1477 ; 1478 ;loop: 1479 ; if ((c1 = *s1++)==0) return(0); 1480 ; if ((c2 = *s2++)==0) return(1); 1481 ; if (c1==c2) goto loop; 1482 ; return(c1>c2); 1483 ;} 1484 ; 1485 ;copy(s1) 1486 ;char *s1; 1487 ;{ 1488 ; char *ts; 1489 ; 1490 ; ts = string; 1491 ; while(*string++ = *s1++); 1492 ; return(ts); 1493 ;} 1494 ; 1495 ;cat(s1, s2) 1496 ;char *s1, *s2; 1497 ;{ 1498 ; char *ts; 1499 ; 1500 ; ts = string; 1501 ; while(*string++ = *s1++); 1502 ; string--; 1503 ; while(*string++ = *s2++); 1504 ; return(ts); 1505 ;}