Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files. =================================================================== RCS file: /ftp/cvs/cvsroot/src/lib/libc/gen/glob.c,v rcsdiff: /ftp/cvs/cvsroot/src/lib/libc/gen/glob.c,v: warning: Unknown phrases like `commitid ...;' are present. retrieving revision 1.4.4.1 retrieving revision 1.17 diff -u -p -r1.4.4.1 -r1.17 --- src/lib/libc/gen/glob.c 1995/05/02 19:34:51 1.4.4.1 +++ src/lib/libc/gen/glob.c 2006/11/24 19:46:58 1.17 @@ -1,3 +1,5 @@ +/* $NetBSD: glob.c,v 1.17 2006/11/24 19:46:58 christos Exp $ */ + /* * Copyright (c) 1989, 1993 * The Regents of the University of California. All rights reserved. @@ -13,11 +15,7 @@ * 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 + * 3. 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. * @@ -34,9 +32,13 @@ * SUCH DAMAGE. */ +#include #if defined(LIBC_SCCS) && !defined(lint) -/* from: static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; */ -static char *rcsid = "$Id: glob.c,v 1.4.4.1 1995/05/02 19:34:51 jtc Exp $"; +#if 0 +static char sccsid[] = "@(#)glob.c 8.3 (Berkeley) 10/13/93"; +#else +__RCSID("$NetBSD: glob.c,v 1.17 2006/11/24 19:46:58 christos Exp $"); +#endif #endif /* LIBC_SCCS and not lint */ /* @@ -46,9 +48,6 @@ static char *rcsid = "$Id: glob.c,v 1.4. * * Optional extra services, controlled by flags not defined by POSIX: * - * GLOB_QUOTE: - * Escaping convention: \ inhibits any special meaning the following - * character might have (except \ at end of string is retained). * GLOB_MAGCHAR: * Set in gl_flags if pattern contained a globbing character. * GLOB_NOMAGIC: @@ -68,6 +67,7 @@ static char *rcsid = "$Id: glob.c,v 1.4. #include #include +#include #include #include #include @@ -78,6 +78,17 @@ static char *rcsid = "$Id: glob.c,v 1.4. #include #include +#ifdef HAVE_NBTOOL_CONFIG_H +#define NO_GETPW_R +#endif + +/* + * XXX: For NetBSD 1.4.x compatibility. (kill me l8r) + */ +#ifndef _DIAGASSERT +#define _DIAGASSERT(a) +#endif + #define DOLLAR '$' #define DOT '.' #define EOS '\0' @@ -96,7 +107,7 @@ static char *rcsid = "$Id: glob.c,v 1.4. #define SLASH '/' #define COMMA ',' -#ifndef DEBUG +#ifndef USE_8BIT_CHARS #define M_QUOTE 0x8000 #define M_PROTECT 0x4000 @@ -107,10 +118,10 @@ typedef u_short Char; #else -#define M_QUOTE 0x80 -#define M_PROTECT 0x40 -#define M_MASK 0xff -#define M_ASCII 0x7f +#define M_QUOTE (Char)0x80 +#define M_PROTECT (Char)0x40 +#define M_MASK (Char)0xff +#define M_ASCII (Char)0x7f typedef char Char; @@ -129,20 +140,19 @@ typedef char Char; static int compare __P((const void *, const void *)); -static void g_Ctoc __P((const Char *, char *)); -static int g_lstat __P((Char *, struct stat *, glob_t *)); +static int g_Ctoc __P((const Char *, char *, size_t)); +static int g_lstat __P((Char *, __gl_stat_t *, glob_t *)); static DIR *g_opendir __P((Char *, glob_t *)); -static Char *g_strchr __P((Char *, int)); -#ifdef notdef -static Char *g_strcat __P((Char *, const Char *)); -#endif -static int g_stat __P((Char *, struct stat *, glob_t *)); +static Char *g_strchr __P((const Char *, int)); +static int g_stat __P((Char *, __gl_stat_t *, glob_t *)); static int glob0 __P((const Char *, glob_t *)); -static int glob1 __P((Char *, glob_t *)); -static int glob2 __P((Char *, Char *, Char *, glob_t *)); -static int glob3 __P((Char *, Char *, Char *, Char *, glob_t *)); -static int globextend __P((const Char *, glob_t *)); -static const Char * globtilde __P((const Char *, Char *, glob_t *)); +static int glob1 __P((Char *, glob_t *, size_t *)); +static int glob2 __P((Char *, Char *, Char *, Char *, glob_t *, + size_t *)); +static int glob3 __P((Char *, Char *, Char *, Char *, Char *, glob_t *, + size_t *)); +static int globextend __P((const Char *, glob_t *, size_t *)); +static const Char *globtilde __P((const Char *, Char *, size_t, glob_t *)); static int globexp1 __P((const Char *, glob_t *)); static int globexp2 __P((const Char *, const Char *, glob_t *, int *)); static int match __P((Char *, Char *, Char *)); @@ -160,7 +170,9 @@ glob(pattern, flags, errfunc, pglob) int c; Char *bufnext, *bufend, patbuf[MAXPATHLEN+1]; - patnext = (u_char *) pattern; + _DIAGASSERT(pattern != NULL); + + patnext = (const u_char *) pattern; if (!(flags & GLOB_APPEND)) { pglob->gl_pathc = 0; pglob->gl_pathv = NULL; @@ -173,7 +185,10 @@ glob(pattern, flags, errfunc, pglob) bufnext = patbuf; bufend = bufnext + MAXPATHLEN; - if (flags & GLOB_QUOTE) { + if (flags & GLOB_NOESCAPE) { + while (bufnext < bufend && (c = *patnext++) != EOS) + *bufnext++ = c; + } else { /* Protect the quoted characters. */ while (bufnext < bufend && (c = *patnext++) != EOS) if (c == QUOTE) { @@ -186,9 +201,6 @@ glob(pattern, flags, errfunc, pglob) else *bufnext++ = c; } - else - while (bufnext < bufend && (c = *patnext++) != EOS) - *bufnext++ = c; *bufnext = EOS; if (flags & GLOB_BRACE) @@ -202,18 +214,22 @@ glob(pattern, flags, errfunc, pglob) * invoke the standard globbing routine to glob the rest of the magic * characters */ -static int globexp1(pattern, pglob) +static int +globexp1(pattern, pglob) const Char *pattern; glob_t *pglob; { const Char* ptr = pattern; int rv; + _DIAGASSERT(pattern != NULL); + _DIAGASSERT(pglob != NULL); + /* Protect a single {}, for find(1), like csh */ if (pattern[0] == LBRACE && pattern[1] == RBRACE && pattern[2] == EOS) return glob0(pattern, pglob); - while ((ptr = (const Char *) g_strchr((Char *) ptr, LBRACE)) != NULL) + while ((ptr = (const Char *) g_strchr(ptr, LBRACE)) != NULL) if (!globexp2(ptr, pattern, pglob, &rv)) return rv; @@ -226,7 +242,8 @@ static int globexp1(pattern, pglob) * If it succeeds then it invokes globexp1 with the new pattern. * If it fails then it tries to glob the rest of the pattern and returns. */ -static int globexp2(ptr, pattern, pglob, rv) +static int +globexp2(ptr, pattern, pglob, rv) const Char *ptr, *pattern; glob_t *pglob; int *rv; @@ -236,6 +253,11 @@ static int globexp2(ptr, pattern, pglob, const Char *pe, *pm, *pl; Char patbuf[MAXPATHLEN + 1]; + _DIAGASSERT(ptr != NULL); + _DIAGASSERT(pattern != NULL); + _DIAGASSERT(pglob != NULL); + _DIAGASSERT(rv != NULL); + /* copy part up to the brace */ for (lm = patbuf, pm = pattern; pm != ptr; *lm++ = *pm++) continue; @@ -265,11 +287,15 @@ static int globexp2(ptr, pattern, pglob, /* Non matching braces; just glob the pattern */ if (i != 0 || *pe == EOS) { - *rv = glob0(patbuf, pglob); + /* + * we use `pattern', not `patbuf' here so that that + * unbalanced braces are passed to the match + */ + *rv = glob0(pattern, pglob); return 0; } - for (i = 0, pl = pm = ptr; pm <= pe; pm++) + for (i = 0, pl = pm = ptr; pm <= pe; pm++) { switch (*pm) { case LBRACKET: /* Ignore everything between [] */ @@ -290,8 +316,8 @@ static int globexp2(ptr, pattern, pglob, case RBRACE: if (i) { - i--; - break; + i--; + break; } /* FALLTHROUGH */ case COMMA: @@ -322,6 +348,7 @@ static int globexp2(ptr, pattern, pglob, default: break; } + } *rv = 0; return 0; } @@ -332,33 +359,56 @@ static int globexp2(ptr, pattern, pglob, * expand tilde from the passwd file. */ static const Char * -globtilde(pattern, patbuf, pglob) +globtilde(pattern, patbuf, patsize, pglob) const Char *pattern; Char *patbuf; + size_t patsize; glob_t *pglob; { struct passwd *pwd; - char *h; + const char *h; const Char *p; Char *b; + char *d; + Char *pend = &patbuf[patsize / sizeof(Char)]; +#ifndef NO_GETPW_R + struct passwd pwres; + char pwbuf[1024]; +#endif + + pend--; + + _DIAGASSERT(pattern != NULL); + _DIAGASSERT(patbuf != NULL); + _DIAGASSERT(pglob != NULL); if (*pattern != TILDE || !(pglob->gl_flags & GLOB_TILDE)) return pattern; /* Copy up to the end of the string or / */ - for (p = pattern + 1, h = (char *) patbuf; *p && *p != SLASH; - *h++ = *p++) + for (p = pattern + 1, d = (char *)(void *)patbuf; + d < (char *)(void *)pend && *p && *p != SLASH; + *d++ = *p++) continue; - *h = EOS; + if (d == (char *)(void *)pend) + return NULL; + + *d = EOS; + d = (char *)(void *)patbuf; - if (((char *) patbuf)[0] == EOS) { + if (*d == EOS) { /* * handle a plain ~ or ~/ by expanding $HOME * first and then trying the password file */ if ((h = getenv("HOME")) == NULL) { +#ifdef NO_GETPW_R if ((pwd = getpwuid(getuid())) == NULL) +#else + if (getpwuid_r(getuid(), &pwres, pwbuf, sizeof(pwbuf), + &pwd) != 0 || pwd == NULL) +#endif return pattern; else h = pwd->pw_dir; @@ -368,20 +418,31 @@ globtilde(pattern, patbuf, pglob) /* * Expand a ~user */ - if ((pwd = getpwnam((char*) patbuf)) == NULL) +#ifdef NO_GETPW_R + if ((pwd = getpwnam(d)) == NULL) +#else + if (getpwnam_r(d, &pwres, pwbuf, sizeof(pwbuf), &pwd) != 0 || + pwd == NULL) +#endif return pattern; else h = pwd->pw_dir; } /* Copy the home directory */ - for (b = patbuf; *h; *b++ = *h++) + for (b = patbuf; b < pend && *h; *b++ = *h++) continue; + + if (b == pend) + return NULL; /* Append the rest of the pattern */ - while ((*b++ = *p++) != EOS) + while (b < pend && (*b++ = *p++) != EOS) continue; + if (b == pend) + return NULL; + return patbuf; } @@ -399,10 +460,17 @@ glob0(pattern, pglob) glob_t *pglob; { const Char *qpatnext; - int c, err, oldpathc; + int c, error; + __gl_size_t oldpathc; Char *bufnext, patbuf[MAXPATHLEN+1]; + size_t limit = 0; + + _DIAGASSERT(pattern != NULL); + _DIAGASSERT(pglob != NULL); - qpatnext = globtilde(pattern, patbuf, pglob); + if ((qpatnext = globtilde(pattern, patbuf, sizeof(patbuf), + pglob)) == NULL) + return GLOB_ABEND; oldpathc = pglob->gl_pathc; bufnext = patbuf; @@ -414,7 +482,7 @@ glob0(pattern, pglob) if (c == NOT) ++qpatnext; if (*qpatnext == EOS || - g_strchr((Char *) qpatnext+1, RBRACKET) == NULL) { + g_strchr(qpatnext+1, RBRACKET) == NULL) { *bufnext++ = LBRACKET; if (c == NOT) --qpatnext; @@ -446,7 +514,7 @@ glob0(pattern, pglob) * to avoid exponential behavior */ if (bufnext == patbuf || bufnext[-1] != M_ALL) - *bufnext++ = M_ALL; + *bufnext++ = M_ALL; break; default: *bufnext++ = CHAR(c); @@ -458,23 +526,30 @@ glob0(pattern, pglob) qprintf("glob0:", patbuf); #endif - if ((err = glob1(patbuf, pglob)) != 0) - return(err); + if ((error = glob1(patbuf, pglob, &limit)) != 0) + return(error); - /* - * If there was no match we are going to append the pattern - * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was specified - * and the pattern did not contain any magic characters - * GLOB_NOMAGIC is there just for compatibility with csh. - */ - if (pglob->gl_pathc == oldpathc && - ((pglob->gl_flags & GLOB_NOCHECK) || - ((pglob->gl_flags & GLOB_NOMAGIC) && - !(pglob->gl_flags & GLOB_MAGCHAR)))) - return(globextend(pattern, pglob)); - else if (!(pglob->gl_flags & GLOB_NOSORT)) + if (pglob->gl_pathc == oldpathc) { + /* + * If there was no match we are going to append the pattern + * if GLOB_NOCHECK was specified or if GLOB_NOMAGIC was + * specified and the pattern did not contain any magic + * characters GLOB_NOMAGIC is there just for compatibility + * with csh. + */ + if ((pglob->gl_flags & GLOB_NOCHECK) || + ((pglob->gl_flags & (GLOB_NOMAGIC|GLOB_MAGCHAR)) + == GLOB_NOMAGIC)) { + return globextend(pattern, pglob, &limit); + } else { + return (GLOB_NOMATCH); + } + } else if (!(pglob->gl_flags & GLOB_NOSORT)) { qsort(pglob->gl_pathv + pglob->gl_offs + oldpathc, - pglob->gl_pathc - oldpathc, sizeof(char *), compare); + (size_t)pglob->gl_pathc - oldpathc, sizeof(char *), + compare); + } + return(0); } @@ -482,20 +557,35 @@ static int compare(p, q) const void *p, *q; { - return(strcmp(*(char **)p, *(char **)q)); + + _DIAGASSERT(p != NULL); + _DIAGASSERT(q != NULL); + + return(strcoll(*(const char * const *)p, *(const char * const *)q)); } static int -glob1(pattern, pglob) +glob1(pattern, pglob, limit) Char *pattern; glob_t *pglob; + size_t *limit; { Char pathbuf[MAXPATHLEN+1]; + _DIAGASSERT(pattern != NULL); + _DIAGASSERT(pglob != NULL); + /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */ if (*pattern == EOS) return(0); - return(glob2(pathbuf, pathbuf, pattern, pglob)); + /* + * we save one character so that we can use ptr >= limit, + * in the general case when we are appending non nul chars only. + */ + return(glob2(pathbuf, pathbuf, + pathbuf + (sizeof(pathbuf) / sizeof(*pathbuf)) - 1, + pattern, + pglob, limit)); } /* @@ -504,14 +594,20 @@ glob1(pattern, pglob) * meta characters. */ static int -glob2(pathbuf, pathend, pattern, pglob) - Char *pathbuf, *pathend, *pattern; +glob2(pathbuf, pathend, pathlim, pattern, pglob, limit) + Char *pathbuf, *pathend, *pathlim, *pattern; glob_t *pglob; + size_t *limit; { - struct stat sb; + __gl_stat_t sb; Char *p, *q; int anymeta; + _DIAGASSERT(pathbuf != NULL); + _DIAGASSERT(pathend != NULL); + _DIAGASSERT(pattern != NULL); + _DIAGASSERT(pglob != NULL); + /* * Loop over pattern segments until end of pattern or until * segment with meta character found. @@ -523,15 +619,17 @@ glob2(pathbuf, pathend, pattern, pglob) return(0); if (((pglob->gl_flags & GLOB_MARK) && - pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) - || (S_ISLNK(sb.st_mode) && + pathend[-1] != SEP) && (S_ISDIR(sb.st_mode) || + (S_ISLNK(sb.st_mode) && (g_stat(pathbuf, &sb, pglob) == 0) && S_ISDIR(sb.st_mode)))) { + if (pathend >= pathlim) + return (GLOB_ABORTED); *pathend++ = SEP; *pathend = EOS; } ++pglob->gl_matchc; - return(globextend(pathbuf, pglob)); + return(globextend(pathbuf, pglob, limit)); } /* Find end of next segment, copy tentatively to pathend. */ @@ -540,28 +638,35 @@ glob2(pathbuf, pathend, pattern, pglob) while (*p != EOS && *p != SEP) { if (ismeta(*p)) anymeta = 1; + if (q >= pathlim) + return GLOB_ABORTED; *q++ = *p++; } if (!anymeta) { /* No expansion, do next segment. */ pathend = q; pattern = p; - while (*pattern == SEP) + while (*pattern == SEP) { + if (pathend >= pathlim) + return GLOB_ABORTED; *pathend++ = *pattern++; + } } else /* Need expansion, recurse. */ - return(glob3(pathbuf, pathend, pattern, p, pglob)); + return(glob3(pathbuf, pathend, pathlim, pattern, p, + pglob, limit)); } /* NOTREACHED */ } static int -glob3(pathbuf, pathend, pattern, restpattern, pglob) - Char *pathbuf, *pathend, *pattern, *restpattern; +glob3(pathbuf, pathend, pathlim, pattern, restpattern, pglob, limit) + Char *pathbuf, *pathend, *pathlim, *pattern, *restpattern; glob_t *pglob; + size_t *limit; { - register struct dirent *dp; + struct dirent *dp; DIR *dirp; - int err; + int error; char buf[MAXPATHLEN]; /* @@ -570,45 +675,84 @@ glob3(pathbuf, pathend, pattern, restpat * and dirent.h as taking pointers to differently typed opaque * structures. */ - struct dirent *(*readdirfunc)(); + struct dirent *(*readdirfunc) __P((void *)); + + _DIAGASSERT(pathbuf != NULL); + _DIAGASSERT(pathend != NULL); + _DIAGASSERT(pattern != NULL); + _DIAGASSERT(restpattern != NULL); + _DIAGASSERT(pglob != NULL); *pathend = EOS; errno = 0; if ((dirp = g_opendir(pathbuf, pglob)) == NULL) { - /* TODO: don't call for ENOENT or ENOTDIR? */ if (pglob->gl_errfunc) { - g_Ctoc(pathbuf, buf); + if (g_Ctoc(pathbuf, buf, sizeof(buf))) + return (GLOB_ABORTED); if (pglob->gl_errfunc(buf, errno) || pglob->gl_flags & GLOB_ERR) - return (GLOB_ABEND); + return (GLOB_ABORTED); } + /* + * Posix/XOpen: glob should return when it encounters a + * directory that it cannot open or read + * XXX: Should we ignore ENOTDIR and ENOENT though? + * I think that Posix had in mind EPERM... + */ + if (pglob->gl_flags & GLOB_ERR) + return (GLOB_ABORTED); + return(0); } - err = 0; + error = 0; /* Search directory for matching names. */ if (pglob->gl_flags & GLOB_ALTDIRFUNC) readdirfunc = pglob->gl_readdir; else - readdirfunc = readdir; - while ((dp = (*readdirfunc)(dirp))) { - register u_char *sc; - register Char *dc; + readdirfunc = (struct dirent *(*)__P((void *))) readdir; + while ((dp = (*readdirfunc)(dirp)) != NULL) { + u_char *sc; + Char *dc; /* Initial DOT must be matched literally. */ if (dp->d_name[0] == DOT && *pattern != DOT) continue; + /* + * The resulting string contains EOS, so we can + * use the pathlim character, if it is the nul + */ for (sc = (u_char *) dp->d_name, dc = pathend; - (*dc++ = *sc++) != EOS;) + dc <= pathlim && (*dc++ = *sc++) != EOS;) continue; + + /* + * Have we filled the buffer without seeing EOS? + */ + if (dc > pathlim && *pathlim != EOS) { + /* + * Abort when requested by caller, otherwise + * reset pathend back to last SEP and continue + * with next dir entry. + */ + if (pglob->gl_flags & GLOB_ERR) { + error = GLOB_ABORTED; + break; + } + else { + *pathend = EOS; + continue; + } + } + if (!match(pathend, pattern, restpattern)) { *pathend = EOS; continue; } - err = glob2(pathbuf, --dc, restpattern, pglob); - if (err) + error = glob2(pathbuf, --dc, pathlim, restpattern, pglob, limit); + if (error) break; } @@ -616,12 +760,19 @@ glob3(pathbuf, pathend, pattern, restpat (*pglob->gl_closedir)(dirp); else closedir(dirp); - return(err); + + /* + * Again Posix X/Open issue with regards to error handling. + */ + if ((error || errno) && (pglob->gl_flags & GLOB_ERR)) + return (GLOB_ABORTED); + + return(error); } /* - * Extend the gl_pathv member of a glob_t structure to accomodate a new item, + * Extend the gl_pathv member of a glob_t structure to accommodate a new item, * add the new item, and update gl_pathc. * * This assumes the BSD realloc, which only copies the block when its size @@ -635,38 +786,51 @@ glob3(pathbuf, pathend, pattern, restpat * gl_pathv points to (gl_offs + gl_pathc + 1) items. */ static int -globextend(path, pglob) +globextend(path, pglob, limit) const Char *path; glob_t *pglob; + size_t *limit; { - register char **pathv; - register int i; - u_int newsize; + char **pathv; + size_t i, newsize, len; char *copy; const Char *p; + _DIAGASSERT(path != NULL); + _DIAGASSERT(pglob != NULL); + newsize = sizeof(*pathv) * (2 + pglob->gl_pathc + pglob->gl_offs); - pathv = pglob->gl_pathv ? - realloc((char *)pglob->gl_pathv, newsize) : - malloc(newsize); + pathv = pglob->gl_pathv ? realloc(pglob->gl_pathv, newsize) : + malloc(newsize); if (pathv == NULL) return(GLOB_NOSPACE); if (pglob->gl_pathv == NULL && pglob->gl_offs > 0) { /* first time around -- clear initial gl_offs items */ pathv += pglob->gl_offs; - for (i = pglob->gl_offs; --i >= 0; ) + for (i = pglob->gl_offs + 1; --i > 0; ) *--pathv = NULL; } pglob->gl_pathv = pathv; for (p = path; *p++;) continue; - if ((copy = malloc(p - path)) != NULL) { - g_Ctoc(path, copy); + len = (size_t)(p - path); + *limit += len; + if ((copy = malloc(len)) != NULL) { + if (g_Ctoc(path, copy, len)) { + free(copy); + return(GLOB_ABORTED); + } pathv[pglob->gl_offs + pglob->gl_pathc++] = copy; } pathv[pglob->gl_offs + pglob->gl_pathc] = NULL; + + if ((pglob->gl_flags & GLOB_LIMIT) && (newsize + *limit) >= ARG_MAX) { + errno = 0; + return(GLOB_NOSPACE); + } + return(copy == NULL ? GLOB_NOSPACE : 0); } @@ -677,11 +841,15 @@ globextend(path, pglob) */ static int match(name, pat, patend) - register Char *name, *pat, *patend; + Char *name, *pat, *patend; { int ok, negate_range; Char c, k; + _DIAGASSERT(name != NULL); + _DIAGASSERT(pat != NULL); + _DIAGASSERT(patend != NULL); + while (pat < patend) { c = *pat++; switch (c & M_MASK) { @@ -727,8 +895,10 @@ void globfree(pglob) glob_t *pglob; { - register int i; - register char **pp; + size_t i; + char **pp; + + _DIAGASSERT(pglob != NULL); if (pglob->gl_pathv != NULL) { pp = pglob->gl_pathv + pglob->gl_offs; @@ -736,20 +906,27 @@ globfree(pglob) if (*pp) free(*pp); free(pglob->gl_pathv); + pglob->gl_pathv = NULL; + pglob->gl_pathc = 0; } } static DIR * g_opendir(str, pglob) - register Char *str; + Char *str; glob_t *pglob; { char buf[MAXPATHLEN]; + _DIAGASSERT(str != NULL); + _DIAGASSERT(pglob != NULL); + if (!*str) - strcpy(buf, "."); - else - g_Ctoc(str, buf); + (void)strlcpy(buf, ".", sizeof(buf)); + else { + if (g_Ctoc(str, buf, sizeof(buf))) + return NULL; + } if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_opendir)(buf)); @@ -759,13 +936,18 @@ g_opendir(str, pglob) static int g_lstat(fn, sb, pglob) - register Char *fn; - struct stat *sb; + Char *fn; + __gl_stat_t *sb; glob_t *pglob; { char buf[MAXPATHLEN]; - g_Ctoc(fn, buf); + _DIAGASSERT(fn != NULL); + _DIAGASSERT(sb != NULL); + _DIAGASSERT(pglob != NULL); + + if (g_Ctoc(fn, buf, sizeof(buf))) + return -1; if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_lstat)(buf, sb)); return(lstat(buf, sb)); @@ -773,13 +955,18 @@ g_lstat(fn, sb, pglob) static int g_stat(fn, sb, pglob) - register Char *fn; - struct stat *sb; + Char *fn; + __gl_stat_t *sb; glob_t *pglob; { char buf[MAXPATHLEN]; - g_Ctoc(fn, buf); + _DIAGASSERT(fn != NULL); + _DIAGASSERT(sb != NULL); + _DIAGASSERT(pglob != NULL); + + if (g_Ctoc(fn, buf, sizeof(buf))) + return -1; if (pglob->gl_flags & GLOB_ALTDIRFUNC) return((*pglob->gl_stat)(buf, sb)); return(stat(buf, sb)); @@ -787,52 +974,49 @@ g_stat(fn, sb, pglob) static Char * g_strchr(str, ch) - Char *str; + const Char *str; int ch; { + + _DIAGASSERT(str != NULL); + do { if (*str == ch) - return (str); + return __UNCONST(str); } while (*str++); - return (NULL); + return NULL; } -#ifdef notdef -static Char * -g_strcat(dst, src) - Char *dst; - const Char* src; +static int +g_Ctoc(str, buf, len) + const Char *str; + char *buf; + size_t len; { - Char *sdst = dst; - - while (*dst++) - continue; - --dst; - while((*dst++ = *src++) != EOS) - continue; + char *dc; - return (sdst); -} -#endif + _DIAGASSERT(str != NULL); + _DIAGASSERT(buf != NULL); -static void -g_Ctoc(str, buf) - register const Char *str; - char *buf; -{ - register char *dc; + if (len == 0) + return 1; - for (dc = buf; (*dc++ = *str++) != EOS;) + for (dc = buf; len && (*dc++ = *str++) != EOS; len--) continue; + + return len == 0; } #ifdef DEBUG static void qprintf(str, s) const char *str; - register Char *s; + Char *s; { - register Char *p; + Char *p; + + _DIAGASSERT(str != NULL); + _DIAGASSERT(s != NULL); (void)printf("%s:\n", str); for (p = s; *p; p++)