1 /* $NetBSD: glob.c,v 1.24 2007/07/16 14:07:01 christos Exp $ */
4 * Copyright (c) 1980, 1991, 1993
5 * The Regents of the University of California. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the University nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/cdefs.h>
35 static char sccsid
[] = "@(#)glob.c 8.1 (Berkeley) 5/31/93";
37 __RCSID("$NetBSD: glob.c,v 1.24 2007/07/16 14:07:01 christos Exp $");
41 #include <sys/param.h>
54 static int gargsiz
, pargsiz
;
59 #define G_NONE 0 /* No globbing needed */
60 #define G_GLOB 1 /* string contains *?[] characters */
61 #define G_CSH 2 /* string contains ~`{ characters */
63 #define GLOBSPACE 100 /* Alloc increment */
77 * globbing is now done in two stages. In the first pass we expand
78 * csh globbing idioms ~`{ and then we proceed doing the normal
79 * globbing if needed ?*[
81 * Csh type globbing is handled in globexpand() and the rest is
82 * handled in glob() which is part of the 4.4BSD libc.
85 static Char
*globtilde(Char
**, Char
*);
86 static Char
*handleone(Char
*, Char
**, int);
87 static Char
**libglob(Char
**);
88 static Char
**globexpand(Char
**);
89 static int globbrace(Char
*, Char
*, Char
***);
90 static void expbrace(Char
***, Char
***, int);
91 static int pmatch(Char
*, Char
*);
92 static void pword(void);
93 static void psave(int);
94 static void backeval(Char
*, int);
97 globtilde(Char
**nv
, Char
*s
)
99 Char gbuf
[MAXPATHLEN
], *b
, *e
, *gstart
, *u
;
104 for (b
= gstart
, e
= &gbuf
[MAXPATHLEN
- 1];
105 *s
&& *s
!= '/' && *s
!= ':' && b
< e
;
109 if (gethdir(gstart
)) {
112 stderror(ERR_UNKUSER
, vis_str(gstart
));
114 stderror(ERR_NOHOME
);
116 b
= &gstart
[Strlen(gstart
)];
122 return (Strsave(gstart
));
126 globbrace(Char
*s
, Char
*p
, Char
***bl
)
128 Char gbuf
[MAXPATHLEN
];
129 Char
*lm
, *pe
, *pl
, *pm
, **nv
, **vl
;
133 nv
= vl
= (Char
**)xmalloc((size_t) sizeof(Char
*) * size
);
136 /* copy part up to the brace */
137 for (lm
= gbuf
, p
= s
; *p
!= LBRC
; *lm
++ = *p
++)
140 /* check for balanced braces */
141 for (i
= 0, pe
= ++p
; *pe
; pe
++)
143 /* Ignore everything between [] */
144 for (++pe
; *pe
!= RBRK
&& *pe
!= EOS
; pe
++)
151 else if (*pe
== LBRC
)
153 else if (*pe
== RBRC
) {
159 if (i
!= 0 || *pe
== '\0') {
164 for (i
= 0, pl
= pm
= p
; pm
<= pe
; pm
++)
167 for (++pm
; *pm
!= RBRK
&& *pm
!= EOS
; pm
++)
191 (void)Strcpy(lm
, pl
);
192 (void)Strcat(gbuf
, pe
+ 1);
194 *vl
++ = Strsave(gbuf
);
197 if (vl
== &nv
[size
]) {
199 nv
= (Char
**)xrealloc((ptr_t
) nv
,
200 (size_t)size
* sizeof(Char
*));
201 vl
= &nv
[size
- GLOBSPACE
];
214 expbrace(Char
***nvp
, Char
***elp
, int size
)
216 Char
**el
, **nv
, *s
, **vl
;
222 for (el
= vl
; *el
; el
++)
225 for (s
= *vl
; s
; s
= *++vl
) {
228 /* leave {} untouched for find */
229 if (s
[0] == '{' && (s
[1] == '\0' || (s
[1] == '}' && s
[2] == '\0')))
231 if ((b
= Strchr(s
, '{')) != NULL
) {
235 if ((len
= globbrace(s
, b
, &bl
)) < 0) {
237 stderror(ERR_MISSING
, -len
);
246 if (&el
[len
] >= &nv
[size
]) {
249 l
= &el
[len
] - &nv
[size
];
250 size
+= GLOBSPACE
> l
? GLOBSPACE
: l
;
253 nv
= (Char
**)xrealloc((ptr_t
)nv
,
254 (size_t)size
* sizeof(Char
*));
261 for (bp
= el
; bp
!= vp
; bp
--)
265 for (bp
= bl
+ 1; *bp
; *vp
++ = *bp
++)
279 Char
**el
, **nv
, *s
, **vl
;
283 nv
= vl
= (Char
**)xmalloc((size_t)sizeof(Char
*) * size
);
287 * Step 1: expand backquotes.
289 while ((s
= *v
++) != NULL
) {
290 if (Strchr(s
, '`')) {
293 (void) dobackp(s
, 0);
294 for (i
= 0; i
< pargc
; i
++) {
296 if (vl
== &nv
[size
]) {
298 nv
= (Char
**)xrealloc((ptr_t
) nv
,
299 (size_t)size
* sizeof(Char
*));
300 vl
= &nv
[size
- GLOBSPACE
];
308 if (vl
== &nv
[size
]) {
310 nv
= (Char
**)xrealloc((ptr_t
)nv
,
311 (size_t)size
* sizeof(Char
*));
312 vl
= &nv
[size
- GLOBSPACE
];
322 * Step 2: expand braces
325 expbrace(&nv
, &el
, size
);
331 for (s
= *vl
; s
; s
= *++vl
)
333 *vl
= globtilde(nv
, s
);
339 handleone(Char
*str
, Char
**vl
, int action
)
346 setname(vis_str(str
));
348 stderror(ERR_NAME
| ERR_AMBIG
);
352 str
= Strsave(*vlp
++);
354 cp
= Strspl(str
, STRspace
);
356 str
= Strspl(cp
, *vlp
);
363 str
= Strsave(strip(*vlp
));
377 int gflgs
, magic
, match
, nonomatch
;
379 gflgs
= GLOB_NOMAGIC
;
382 nonomatch
= adrof(STRnonomatch
) != 0;
392 gflgs
|= GLOB_NOCHECK
;
395 ptr
= short2qstr(*vl
);
396 switch (glob(ptr
, gflgs
, 0, &globv
)) {
398 setname(vis_str(*vl
));
399 stderror(ERR_NAME
| ERR_GLOB
);
407 if (globv
.gl_flags
& GLOB_MAGCHAR
) {
408 match
|= (globv
.gl_matchc
!= 0);
411 gflgs
|= GLOB_APPEND
;
414 vl
= (globv
.gl_pathc
== 0 || (magic
&& !match
&& !nonomatch
)) ?
415 NULL
: blk2short(globv
.gl_pathv
);
421 globone(Char
*str
, int action
)
423 Char
*v
[2], **vl
, **vo
;
426 noglob
= adrof(STRnoglob
) != 0;
433 return (strip(Strsave(str
)));
437 * Expand back-quote, tilde and brace
440 if (noglob
|| (gflg
& G_GLOB
) == 0) {
443 return (Strsave(STRNULL
));
446 return (handleone(str
, vo
, action
));
454 else if (noglob
|| (gflg
& G_GLOB
) == 0)
455 return (strip(Strsave(str
)));
460 if ((gflg
& G_CSH
) && vl
!= vo
)
463 setname(vis_str(str
));
464 stderror(ERR_NAME
| ERR_NOMATCH
);
468 return (Strsave(STRNULL
));
471 return (handleone(str
, vl
, action
));
488 gargc
= blklen(gargv
);
492 noglob
= adrof(STRnoglob
) != 0;
496 * Expand back-quote, tilde and brace
498 vl
= vo
= globexpand(v
);
500 vl
= vo
= saveblk(v
);
502 if (!noglob
&& (gflg
& G_GLOB
)) {
504 if ((gflg
& G_CSH
) && vl
!= vo
)
510 gargc
= vl
? blklen(vl
) : 0;
518 gargv
= (Char
**)xmalloc((size_t)sizeof(Char
*) * gargsiz
);
524 rscan(Char
**t
, void (*f
)(int))
528 while ((p
= *t
++) != NULL
)
538 while ((p
= *t
++) != NULL
)
548 while ((p
= *t
++) != NULL
) {
549 if (*p
== '~' || *p
== '=')
551 else if (*p
== '{' &&
552 (p
[1] == '\0' || (p
[1] == '}' && p
[2] == '\0')))
554 while ((c
= *p
++) != '\0') {
556 * eat everything inside the matching backquotes
560 while (*p
&& *p
!= '`')
562 if (*p
) /* Quoted chars */
567 if (*p
) /* The matching ` */
581 * Command substitute cp. If literal, then this is a substitution from a
582 * << redirection, and so we should not crunch blanks and tabs, separating
583 * words only at newlines.
586 dobackp(Char
*cp
, int literal
)
588 Char word
[MAXPATHLEN
], *ep
, *lp
, *rp
;
597 pargv
= (Char
**)xmalloc((size_t)sizeof(Char
*) * pargsiz
);
599 pargcp
= pargs
= word
;
601 pnleft
= MAXPATHLEN
- 4;
603 for (lp
= cp
; *lp
!= '`'; lp
++) {
612 for (rp
= lp
; *rp
&& *rp
!= '`'; rp
++)
620 stderror(ERR_UNMATCHED
, '`');
624 backeval(ep
, literal
);
630 backeval(Char
*cp
, int literal
)
632 struct command faket
;
634 Char ibuf
[BUFSIZE
], *fakecom
[2], *ip
;
635 int pvec
[2], c
, icnt
, quoted
;
640 quoted
= (literal
|| (cp
[0] & QUOTE
)) ? QUOTE
: 0;
641 faket
.t_dtyp
= NODE_COMMAND
;
646 faket
.t_dcom
= fakecom
;
647 fakecom
[0] = STRfakecom1
;
651 * We do the psave job to temporarily change the current job so that the
652 * following fork is considered a separate job. This is so that when
653 * backquotes are used in a builtin function that calls glob the "current
654 * job" is not corrupted. We only need one level of pushed jobs as long as
655 * we are sure to fork here.
660 * It would be nicer if we could integrate this redirection more with the
661 * routines in sh.sem.c by doing a fake execute on a builtin function that
665 if (pfork(&faket
, -1) == 0) {
666 struct wordent fparaml
;
669 (void)close(pvec
[0]);
670 (void)dmove(pvec
[1], 1);
671 (void)dmove(SHERR
, 2);
674 * Bugfix for nested backquotes by Michael Greim <greim@sbsvax.UUCP>,
675 * posted to comp.bugs.4bsd 12 Sep. 1989.
677 if (pargv
) /* mg, 21.dec.88 */
678 blkfree(pargv
), pargv
= 0, pargsiz
= 0;
681 for (arginp
= cp
; *cp
; cp
++) {
683 if (*cp
== '\n' || *cp
== '\r')
688 * In the child ``forget'' everything about current aliases or
695 (void) lex(&fparaml
);
699 t
= syntax(fparaml
.next
, &fparaml
, 0);
703 t
->t_dflg
|= F_NOFORK
;
704 (void)signal(SIGTSTP
, SIG_IGN
);
705 (void)signal(SIGTTIN
, SIG_IGN
);
706 (void)signal(SIGTTOU
, SIG_IGN
);
707 execute(t
, -1, NULL
, NULL
);
711 (void)close(pvec
[1]);
725 icnt
= read(pvec
[0], tibuf
, BUFSIZE
);
726 while (icnt
== -1 && errno
== EINTR
);
731 for (i
= 0; i
< icnt
; i
++)
732 ip
[i
] = (unsigned char) tibuf
[i
];
742 * Continue around the loop one more time, so that we can eat
743 * the last newline without terminating this word.
748 if (!quoted
&& (c
== ' ' || c
== '\t'))
754 * Unless at end-of-file, we will form a new word here if there were
755 * characters in the word, or in any case when we take text literally.
756 * If we didn't make empty words here when literal was set then we
757 * would lose blank lines.
759 if (c
!= -1 && (cnt
|| literal
))
763 (void)close(pvec
[0]);
772 stderror(ERR_WTOOLONG
);
780 if (pargc
== pargsiz
- 1) {
781 pargsiz
+= GLOBSPACE
;
782 pargv
= (Char
**)xrealloc((ptr_t
)pargv
,
783 (size_t)pargsiz
* sizeof(Char
*));
785 pargv
[pargc
++] = Strsave(pargs
);
788 pnleft
= MAXPATHLEN
- 4;
792 Gmatch(Char
*string
, Char
*pattern
)
800 if (*pattern
== '^') {
805 blk
= (Char
**)xmalloc(GLOBSPACE
* sizeof(Char
*));
806 blk
[0] = Strsave(pattern
);
809 expbrace(&blk
, NULL
, GLOBSPACE
);
811 for (p
= blk
; *p
; p
++)
812 gres
|= pmatch(string
, *p
);
815 return(gres
== gpol
);
819 pmatch(Char
*string
, Char
*pattern
)
821 int match
, negate_range
;
822 Char patternc
, rangec
, stringc
;
825 stringc
= *string
& TRIM
;
826 patternc
= *pattern
++;
829 return (stringc
== 0);
838 if (Gmatch(string
++, pattern
))
843 if ((negate_range
= (*pattern
== '^')) != 0)
845 while ((rangec
= *pattern
++) != '\0') {
850 if (rangec
== '-' && *(pattern
-2) != '[' && *pattern
!= ']') {
851 match
= (stringc
<= (*pattern
& TRIM
) &&
852 (*(pattern
-2) & TRIM
) <= stringc
);
856 match
= (stringc
== (rangec
& TRIM
));
859 stderror(ERR_NAME
| ERR_MISSING
, ']');
860 if (match
== negate_range
)
864 if ((patternc
& TRIM
) != stringc
)
873 Gcat(Char
*s1
, Char
*s2
)
882 n
= (p
- s1
) + (q
- s2
) - 1;
883 if (++gargc
>= gargsiz
) {
884 gargsiz
+= GLOBSPACE
;
885 gargv
= (Char
**)xrealloc((ptr_t
)gargv
,
886 (size_t)gargsiz
* sizeof(Char
*));
889 p
= gargv
[gargc
- 1] = (Char
*)xmalloc((size_t)n
* sizeof(Char
));
890 for (q
= s1
; (*p
++ = *q
++) != '\0';)
892 for (p
--, q
= s2
; (*p
++ = *q
++) != '\0';)
898 sortscmp(const ptr_t a
, const ptr_t b
)
900 #if defined(NLS) && !defined(NOSTRCOLL)
904 if (!a
) /* check for NULL */
909 if (!*(Char
**)a
) /* check for NULL */
910 return (*(Char
**)b
? 1 : 0);
914 #if defined(NLS) && !defined(NOSTRCOLL)
915 (void)strcpy(buf
, short2str(*(Char
**)a
));
916 return ((int)strcoll(buf
, short2str(*(Char
**)b
)));
918 return ((int)Strcmp(*(Char
**)a
, *(Char
**)b
));