* Copyright (c) 1980 Regents of the University of California.
* All rights reserved. The Berkeley Software License Agreement
* specifies the terms and conditions for redistribution.
static char *sccsid
= "@(#)glob.c 5.4 (Berkeley) %G%";
char *gpath
, *gpathp
, *lastgpathp
;
#define sort() qsort((char *)sortbas, &gargv[gargc] - sortbas, \
sizeof(*sortbas), sortscmp), sortbas = &gargv[gargc]
gpath
= agpath
; gpathp
= gpath
; *gpathp
= 0;
lastgpathp
= &gpath
[sizeof agpath
- 2];
ginit(agargv
); globcnt
= 0;
printf("glob entered: "); blkpr(v
); printf("\n");
noglob
= adrof("noglob") != 0;
nonomatch
= adrof("nonomatch") != 0;
globcnt
= noglob
| nonomatch
;
printf("glob done, globcnt=%d, gflag=%d: ", globcnt
, gflag
); blkpr(gargv
); printf("\n");
if (globcnt
== 0 && (gflag
&1)) {
blkfree(gargv
), gargv
= 0;
return (gargv
= copyblk(gargv
));
agargv
[0] = 0; gargv
= agargv
; sortbas
= agargv
; gargc
= 0;
printf("doing backp of %s\n", as
);
printf("backp done, acollect'ing\n");
for (i
= 0; i
< pargc
; i
++)
blkfree(pargv
), pargv
= 0;
printf("acollect done\n");
} else if (noglob
|| eq(as
, "{") || eq(as
, "{}")) {
register int ogargc
= gargc
;
gpathp
= gpath
; *gpathp
= 0; globbed
= 0;
* String compare for qsort. Also used by filec code in sh.file.c.
return (strcmp(*a1
, *a2
));
register char *sgpathp
, *oldcs
;
if (*cs
== '~' && gpathp
== gpath
) {
for (cs
++; letter(*cs
) || digit(*cs
) || *cs
== '-';)
if (!*cs
|| *cs
== '/') {
if (gpathp
!= gpath
+ 1) {
error("Unknown user: %s", gpath
+ 1);
(void) strcpy(gpath
, gpath
+ 1);
(void) strcpy(gpath
, value("home"));
else if (stat(gpath
, &stb
) >= 0) {
while (cs
> as
&& *cs
!= '/')
(void) execbrc(cs
, NOSTR
);
register struct direct
*dp
;
if (fstat(dirp
->dd_fd
, &stb
) < 0)
while ((dp
= readdir(dirp
)) != NULL
) {
if (match(dp
->d_name
, pattern
)) {
char restbuf
[BUFSIZ
+ 2];
register char *pe
, *pm
, *pl
;
char *lm
, savec
, *sgpathp
;
for (lm
= restbuf
; *p
!= '{'; *lm
++ = *p
++)
for (pe
= ++p
; *pe
; pe
++)
for (pe
++; *pe
&& *pe
!= ']'; pe
++)
for (pl
= pm
= p
; pm
<= pe
; pm
++)
switch (*pm
& (QUOTE
|TRIM
)) {
(void) strcat(restbuf
, pe
+ 1);
} else if (amatch(s
, restbuf
))
for (pm
++; *pm
&& *pm
!= ']'; pm
++)
if (*s
== '.' && *p
!= '.')
return (execbrc(p
- 1, s
- 1));
if (lc
<= scc
&& scc
<= *p
++)
if (stat(gpath
, &stb
) == 0 && isdir(stb
))
if (lc
<= scc
&& scc
<= *p
++)
gnleft
-= (n
= (p
- s1
) + (q
- s2
) - 1);
if (gnleft
<= 0 || ++gargc
>= GAVSIZ
)
error("Arguments too long");
p
= gargv
[gargc
- 1] = xalloc((unsigned)n
);
for (q
= s1
; *p
++ = *q
++;)
for (p
--, q
= s2
; *p
++ = *q
++;)
if (gpathp
>= lastgpathp
)
error("Pathname too long");
else if (*p
== '{' && (p
[1] == '\0' || p
[1] == '}' && p
[2] == '\0'))
gflag
|= c
== '{' ? 2 : 1;
bferr(cp ? "Ambiguous" : "No output");
xfree((char *)gargv
); gargv
= 0;
* Command substitute cp. If literal, then this is
* a substitution from a << redirection, and so we should
* not crunch blanks and tabs, separating words only at newlines.
char *apargv
[GAVSIZ
+ 2];
for (lp
= cp
; *lp
!= '`'; lp
++) {
printf("leaving dobackp\n");
return (pargv
= copyblk(pargv
));
for (rp
= lp
; *rp
&& *rp
!= '`'; rp
++)
printf("back from backeval\n");
int quoted
= (literal
|| (cp
[0] & QUOTE
)) ? QUOTE
: 0;
register int icnt
= 0, c
;
* We do the psave job to temporarily change the current job
* so that the following fork is considered a separate job.
* This is so that when backquotes are used in a
* builtin function that calls glob the "current job" is not corrupted.
* We only need one level of pushed jobs as long as we are sure to
* It would be nicer if we could integrate this redirection more
* with the routines in sh.sem.c by doing a fake execute on a builtin
* function that was piped out.
if (pfork(&faket
, -1) == 0) {
(void) dmove(pvec
[1], 1);
t
= syntax(paraml
.next
, ¶ml
, 0);
(void) signal(SIGTSTP
, SIG_IGN
);
(void) signal(SIGTTIN
, SIG_IGN
);
(void) signal(SIGTTOU
, SIG_IGN
);
icnt
= read(pvec
[0], ip
, BUFSIZ
);
* Continue around the loop one
* more time, so that we can eat
* the last newline without terminating
if (!quoted
&& (c
== ' ' || c
== '\t'))
* Unless at end-of-file, we will form a new word
* here if there were characters in the word, or in
* any case when we take text literally. If
* we didn't make empty words here when literal was
* set then we would lose blank lines.
if (c
!= -1 && (cnt
|| literal
))
printf("done in backeval, pvec: %d %d\n", pvec
[0], pvec
[1]);
printf("also c = %c <%o>\n", c
, c
);
error("Too many words from ``");
pargv
[pargc
++] = savestr(pargs
);
printf("got word %s\n", pargv
[pargc
-1]);