* Copyright (c) 1980 Regents of the University of California.
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
static char sccsid
[] = "@(#)glob.c 5.9 (Berkeley) 2/25/91";
* C-shell glob for random programs.
#define eq(a,b) (strcmp(a, b)==0)
#define GAVSIZ (NCARGS/6)
#define isdir(d) ((d.st_mode & S_IFMT) == S_IFDIR)
static char **gargv
; /* Pointer to the (stack) arglist */
static int gargc
; /* Number args in gargv */
static char *strspl(), *strend();
static void acollect(), addpath(), collect(), expand(), Gcat();
static void ginit(), matchdir(), rscan(), sort();
static int amatch(), execbrc(), match();
char *globchars
= "`{[*?";
static char *gpath
, *gpathp
, *lastgpathp
;
gpath
= agpath
; gpathp
= gpath
; *gpathp
= 0;
lastgpathp
= &gpath
[sizeof agpath
- 2];
ginit(agargv
); globcnt
= 0;
if (globcnt
== 0 && (gflag
&1)) {
blkfree(gargv
), gargv
= 0;
return (gargv
= copyblk(gargv
));
agargv
[0] = 0; gargv
= agargv
; sortbas
= agargv
; gargc
= 0;
if (eq(as
, "{") || eq(as
, "{}")) {
register int ogargc
= gargc
;
gpathp
= gpath
; *gpathp
= 0; globbed
= 0;
register char **p1
, **p2
, *c
;
char **Gvp
= &gargv
[gargc
];
if (strcmp(*p1
, *p2
) > 0)
c
= *p1
, *p1
= *p2
, *p2
= c
;
register char *sgpathp
, *oldcs
;
if (*cs
== '~' && gpathp
== gpath
) {
for (cs
++; letter(*cs
) || digit(*cs
) || *cs
== '-';)
if (!*cs
|| *cs
== '/') {
if (gpathp
!= gpath
+ 1) {
globerr
= "Unknown user name after ~";
(void) strcpy(gpath
, gpath
+ 1);
(void) strcpy(gpath
, home
);
while (!any(*cs
, globchars
)) {
else if (stat(gpath
, &stb
) >= 0) {
while (cs
> as
&& *cs
!= '/')
(void) execbrc(cs
, ((char *)0));
register struct dirent
*dp
;
if (fstat(dirp
->dd_fd
, &stb
) < 0)
while ((dp
= readdir(dirp
)) != NULL
) {
if (match(dp
->d_name
, pattern
)) {
globerr
= "Bad directory components";
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
++)
register int len
= strlen(s1
) + strlen(s2
) + 1;
if (len
>= gnleft
|| gargc
>= GAVSIZ
- 1)
globerr
= "Arguments too long";
gargv
[gargc
- 1] = strspl(s1
, s2
);
if (gpathp
>= lastgpathp
)
globerr
= "Pathname too long";
else if (eq(p
, "{") || eq(p
, "{}"))
gflag
|= c
== '{' ? 2 : 1;
return (c
>= 'a' && c
<= 'z' || c
>= 'A' && c
<= 'Z' || c
== '_');
return (c
>= '0' && c
<= '9');
register char **av
= oav
;
register char **av
= av0
;
register char *ep
= malloc((unsigned)(strlen(cp
) + strlen(dp
) + 1));
register char **nv
= (char **)malloc((unsigned)((blklen(v
) + 1) *
* Extract a home directory from the password file
* The argument points to a buffer where the name of the
* user whose home directory is sought is currently.
* We write the home directory of the user back there.
register struct passwd
*pp
= getpwnam(home
);
if (!pp
|| home
+ strlen(pp
->pw_dir
) >= lastgpathp
)
(void) strcpy(home
, pp
->pw_dir
);