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