     1                                  ; ****************************************************************************
     2                                  ; glob386.s (glob2.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 glob2.s -l glob2.txt -o glob2 -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) <arg1 (ebx)>, <arg2 (ecx)>, <arg3 (edx)>
    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 <res 10h>               	.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[98030000]            	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[35030000]            	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[AE030000]            	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[8E030000]          	mov	[av], ebx
   243                                  
   244                                  	;while (--argc >= 2)
   245                                  	;	expand(*++argv);
   246                                  glb_1:
   247 00000032 FE0D[98030000]          	dec	byte [argc]
   248 00000038 803D[98030000]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[9A030000]00        	cmp	byte [ncoll], 0
   263 00000050 7707                    	ja	short glb_3
   264                                  
   265 00000052 B8[43030000]            	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[B2030000]      <1>  mov ebx, %2
    78                              <1>  %if %0 >= 3
    79 0000005F B9[B2030000]        <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[2B030000]            	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[B2030000]        <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[B2030000]        <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[50030000]            	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[8E030000]          	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[8E030000]          	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[29030000]        <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[27030000]            	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[67030000]            	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[8E030000]          	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[9C030000]        <1>  mov ecx, %3
    80                              <1> 
    81                              <1>  %if %0 >= 4
    82 00000136 BA10000000          <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, 16
   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[9C030000]00      	cmp	word [entry.ino], 0
   431 00000150 76DD                    	jna	short expd_10 ; continue
   432                                  	
   433                                  	;if (match(entry.name, cs)
   434 00000152 BB[9E030000]            	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[9A030000]          	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[8E030000]          	mov	ebx, [av]
   484 0000017B 83EB04                  	sub	ebx, 4
   485 0000017E 8B2D[8E030000]          	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[92030000]          	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[80060000]          	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[80060000]          	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[80060000]          	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[92030000]          	mov	edx, [string]
   908 000002BB 893D[92030000]          	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[78030000]            	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.1 /etc/glob by Erdogan TAN'
   958 000002F6 58203338362076312E-
   958 000002FF 31202F6574632F676C-
   958 00000308 6F6220627920457264-
   958 00000311 6F67616E2054414E   
   959 00000319 202D2033302F30352F-     	db  ' - 30/05/2022'
   959 00000322 32303232           
   960 00000326 00                      	db  0
   961                                  
   962                                  ROOTDIR:
   963 00000327 2F00                    	db '/', 0
   964                                  
   965 00000329 2E00                    DOT:	db '.', 0
   966                                  	;db 0, 0
   967                                  
   968                                  usr_bin:	
   969 0000032B 2F7573722F62696E2F-     	db '/usr/bin/', 0
   969 00000334 00                 
   970                                  
   971                                  msg_arg_count:
   972 00000335 0D0A                    	db 0Dh, 0Ah
   973 00000337 41726720636F756E74      	db "Arg count"
   974                                  nextline:
   975 00000340 0D0A00                  	db  0Dh, 0Ah, 0
   976                                  
   977                                  msg_no_match:
   978 00000343 0D0A                    	db 0Dh, 0Ah
   979 00000345 4E6F206D61746368        	db "No match"
   980 0000034D 0D0A00                  	db  0Dh, 0Ah, 0
   981                                  
   982                                  msg_not_found:
   983 00000350 0D0A                    	db 0Dh, 0Ah
   984 00000352 436F6D6D616E64206E-     	db "Command not found."
   984 0000035B 6F7420666F756E642E 
   985 00000364 0D0A00                  	db  0Dh, 0Ah, 0
   986                                  
   987                                  msg_no_dir:
   988 00000367 0D0A                    	db 0Dh, 0Ah
   989 00000369 4E6F20646972656374-     	db "No directory"
   989 00000372 6F7279             
   990 00000375 0D0A00                  	db  0Dh, 0Ah, 0
   991                                  
   992                                  msg_too_long:
   993 00000378 0D0A                    	db 0Dh, 0Ah
   994 0000037A 417267206C69737420-     	db 'Arg list too long'
   994 00000383 746F6F206C6F6E67   
   995 0000038B 0D0A00                  	db  0Dh, 0Ah, 0
   996                                  
   997 0000038E [AE030000]              av:	dd ava	 ;char **av &ava[1];
   998 00000392 [76040000]              string:	dd ab	 ;char *string ab;
   999                                  
  1000                                  ;-----------------------------------------------------------------
  1001                                  ;  bss - uninitialized data
  1002                                  ;-----------------------------------------------------------------
  1003                                  
  1004 00000396 90<rep 2h>              align 4
  1005                                  
  1006                                  bss_start:
  1007                                  
  1008                                  ABSOLUTE bss_start
  1009                                  
  1010                                  ;argc:	resd 1
  1011 00000398 ??                      argc:	resb 1
  1012 00000399 ??                      errno:	resb 1	;int errno;
  1013 0000039A ????                    ncoll:	resw 1	;int ncoll;
  1014                                  entry:
  1015                                  entry.ino:
  1016 0000039C ????                    	resw 1
  1017                                  entry.name:
  1018 0000039E <res Eh>                	resb 14
  1019 000003AC ????                    	resb 2
  1020                                  
  1021 000003AE <res C8h>               ava:	resb 200
  1022 00000476 <res 20Ah>              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<ap-1) {
  1370                                  ;		j = i;
  1371                                  ;		while(++j<ap) {
  1372                                  ;			if (compar(av[i],av[j])) {
  1373                                  ;				c = av[i];
  1374                                  ;				av[i] = av[j];
  1375                                  ;				av[j] = c;
  1376                                  ;			}
  1377                                  ;		}
  1378                                  ;		i++;
  1379                                  ;	}
  1380                                  ;	if (--argc>=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                                  ;}
