⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bsd-glob.c

📁 功能强大的ftp服务器源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
    qpatnext = pattern;#endif    oldpathc = pglob->gl_pathc;    bufnext = patbuf;    /* We don't need to check for buffer overflow any more. */    while ((c = *qpatnext++) != EOS) {        switch (c) {        case LBRACKET:            c = *qpatnext;            if (c == NOT)                ++qpatnext;            if (*qpatnext == EOS ||                g_strchr((const Char *) qpatnext + 1, RBRACKET) == NULL) {                *bufnext++ = LBRACKET;                if (c == NOT)                    --qpatnext;                break;            }            *bufnext++ = M_SET;            if (c == NOT)                *bufnext++ = M_NOT;            c = *qpatnext++;            do {                *bufnext++ = CHAR(c);                if (*qpatnext == RANGE && (c = qpatnext[1]) != RBRACKET) {                    *bufnext++ = M_RNG;                    *bufnext++ = CHAR(c);                    qpatnext += 2;                }            } while ((c = *qpatnext++) != RBRACKET);            pglob->gl_flags |= GLOB_MAGCHAR;            *bufnext++ = M_END;            break;        case QUESTION:            pglob->gl_flags |= GLOB_MAGCHAR;            *bufnext++ = M_ONE;            break;        case STAR:            pglob->gl_flags |= GLOB_MAGCHAR;            /* collapse adjacent stars to one,             * to avoid exponential behavior             */            if (bufnext == patbuf || bufnext[-1] != M_ALL) {                *bufnext++ = M_ALL;            }            break;        default:            *bufnext++ = CHAR(c);            break;        }    }    *bufnext = EOS;    if ((err = glob1(patbuf, patbuf + MAXPATHLEN, pglob, &limit)) != 0) {        return (err);    }    /*     * 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) {        return (GLOB_NOMATCH);    }    if (!(pglob->gl_flags & GLOB_NOSORT)) {        qsort(pglob->gl_pathv + oldpathc,              (size_t) (pglob->gl_pathc - oldpathc), sizeof (char *), compare);    }    return 0;}static int compare(const void *p, const void *q){    return (strcmp(*(const char **) p, *(const char **) q));}static intglob1(Char * pattern, Char * pattern_last, glob_t * pglob, size_t * limitp){    Char pathbuf[MAXPATHLEN + 1];    /* A null pathname is invalid -- POSIX 1003.1 sect. 2.4. */    if (*pattern == EOS) {        return 0;    }    return (glob2(pathbuf, pathbuf + MAXPATHLEN,                  pathbuf, pathbuf + MAXPATHLEN,                  pattern, pattern_last, pglob, limitp, 0));}/* * The functions glob2 and glob3 are mutually recursive; there is one level * of recursion for each segment in the pattern that contains one or more * meta characters. */static intglob2(Char * pathbuf,      Char * pathbuf_last,      Char * pathend,      Char * pathend_last,      Char * pattern,      Char * pattern_last, glob_t * pglob, size_t * limitp, int recursion){    struct stat sb;    Char *p, *q;    int anymeta;    if (pglob->gl_maxdepth > 0 && recursion > pglob->gl_maxdepth) {        errno = 0;        return (GLOB_NOSPACE);    }    /*     * Loop over pattern segments until end of pattern or until     * segment with meta character found.     */    for (anymeta = 0;;) {        if (*pattern == EOS) {  /* End of pattern? */            *pathend = EOS;            if (g_lstat(pathbuf, &sb))                return 0;            ++pglob->gl_matchc;            return (globextend(pathbuf, pglob, limitp));        }        /* Find end of next segment, copy tentatively to pathend. */        q = pathend;        p = pattern;        while (*p != EOS && *p != SEP) {            if (ismeta(*p))                anymeta = 1;            if (q + 1 > pathend_last)                return 1;            *q++ = *p++;        }        if (!anymeta) {         /* No expansion, do next segment. */            pathend = q;            pattern = p;            while (*pattern == SEP) {                if (pathend + 1 > pathend_last)                    return 1;                *pathend++ = *pattern++;            }        } else            /* Need expansion, recurse. */            return (glob3(pathbuf, pathbuf_last, pathend,                          pathend_last, pattern,                          p, pattern_last, pglob, limitp, recursion + 1));    }    /* NOTREACHED */}static intglob3(Char * pathbuf, Char * pathbuf_last, Char * pathend,      Char * pathend_last, Char * pattern, Char * restpattern,      Char * restpattern_last, glob_t * pglob, size_t * limitp,      int recursion){    register struct dirent *dp;    DIR *dirp;    int err;    char buf[MAXPATHLEN + 1];    if (pathend > pathend_last)        return 1;    *pathend = EOS;    errno = 0;    if (pglob->gl_maxdepth > 0 && recursion > pglob->gl_maxdepth) {        return (GLOB_NOSPACE);    }    if ((dirp = g_opendir(pathbuf)) == NULL) {        /* TODO: don't call for ENOENT or ENOTDIR? */        if (pglob->gl_errfunc) {            if (g_Ctoc(pathbuf, buf, sizeof (buf))) {                return (GLOB_ABORTED);            }            if (pglob->gl_errfunc(buf, errno) ||                pglob->gl_flags & GLOB_ERR) {                return (GLOB_ABORTED);            }        }        return 0;    }    err = 0;    while ((dp = (*readdir) (dirp))) {        register unsigned char *sc;        register Char *dc;        /* Initial DOT must be matched literally. */        if (dp->d_name[0] == DOT && *pattern != DOT) {            continue;        }#ifndef GLOB_UNPRINTABLE        if (checkprintable(dp->d_name) != 0) {            continue;        }#endif        dc = pathend;        sc = (unsigned char *) dp->d_name;        while (dc < pathend_last && (*dc++ = *sc++) != EOS);        if (dc >= pathend_last) {            *dc = EOS;            err = 1;            break;        }        if (!match(pathend, pattern, restpattern)) {            *pathend = EOS;            continue;        }        err = glob2(pathbuf, pathbuf_last, --dc, pathend_last,                    restpattern, restpattern_last, pglob, limitp,                    recursion + 1);        if (err)            break;    }    closedir(dirp);    return (err);}/* * 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 * crosses a power-of-two boundary; for v7 realloc, this would cause quadratic * behavior. * * Return 0 if new item added, error code if memory couldn't be allocated. * * Invariant of the glob_t structure: *    Either gl_pathc is zero and gl_pathv is NULL; or gl_pathc > 0 and *    gl_pathv points to (gl_offs + gl_pathc + 1) items. */static int globextend(const Char * path, glob_t * pglob, size_t * limitp){    register char **pathv;    unsigned int newsize;    size_t len;    char *copy;    const Char *p;    if (pglob->gl_maxfiles != (unsigned long) -1) {        if (pglob->gl_maxfiles == 0) {            return 0;        }        pglob->gl_maxfiles--;    }    newsize = sizeof (*pathv) * (2 + pglob->gl_pathc);    pathv = pglob->gl_pathv ? realloc((char *) pglob->gl_pathv, newsize) :        malloc(newsize);    if (pathv == NULL) {        free(pglob->gl_pathv);        pglob->gl_pathv = NULL;        return (GLOB_NOSPACE);    }    pglob->gl_pathv = pathv;    for (p = path; *p++;);    len = (size_t) (p - path);    *limitp += len;    if ((copy = malloc(len)) != NULL) {        if (g_Ctoc(path, copy, len)) {            free(copy);            return (GLOB_NOSPACE);        }        pathv[pglob->gl_pathc++] = copy;    }    pathv[pglob->gl_pathc] = NULL;#ifdef USELESS_FOR_PUREFTPD    if ((pglob->gl_flags & GLOB_LIMIT) && newsize + *limitp >= ARG_MAX) {        errno = 0;        return (GLOB_NOSPACE);    }#endif    return (copy == NULL ? GLOB_NOSPACE : 0);}/* * pattern matching function for filenames.  Each occurrence of the * * pattern causes a recursion level. */static intmatch(register Char * name, register Char * pat, register Char * patend){    int ok, negate_range;    Char c, k;    while (pat < patend) {        c = *pat++;        switch (c & M_MASK) {        case M_ALL:            if (pat == patend)                return 1;            do {                if (match(name, pat, patend)) {                    return 1;                }            } while (*name++ != EOS);            return 0;        case M_ONE:            if (*name++ == EOS) {                return 0;            }            break;        case M_SET:            ok = 0;            if ((k = *name++) == EOS)                return 0;            if ((negate_range = ((*pat & M_MASK) == M_NOT)) != EOS) {                ++pat;            }            while (((c = *pat++) & M_MASK) != M_END) {                if ((*pat & M_MASK) == M_RNG) {                    if (c <= k && k <= pat[1])                        ok = 1;                    pat += 2;                } else if (c == k) {                    ok = 1;                }            }            if (ok == negate_range) {                return 0;            }            break;        default:            if (*name++ != c) {                return 0;            }            break;        }    }    return (*name == EOS);}/* Free allocated data belonging to a glob_t structure. */void globfree(glob_t * pglob){    register int i;    register char **pp;    if (pglob->gl_pathv != NULL) {        pp = pglob->gl_pathv;        for (i = pglob->gl_pathc; i--; ++pp) {            free(*pp);        }        free(pglob->gl_pathv);        pglob->gl_pathv = NULL;    }}static DIR *g_opendir(register Char * str){    char buf[MAXPATHLEN + 1];    if (!*str) {	buf[0] = '.';	buf[1] = 0;         /* safe : sizeof buf > 2 */    } else {        if (g_Ctoc(str, buf, sizeof (buf)))            return NULL;    }    return (opendir(buf));}static int g_lstat(register Char * fn, struct stat *sb){    char buf[MAXPATHLEN + 1];    if (g_Ctoc(fn, buf, sizeof (buf)))        return -1;    return (lstat(buf, sb));}static const Char *g_strchr(const Char * str, int ch){    do {        if (*str == (Char) ch)            return (str);    } while (*str++);    return NULL;}static int g_Ctoc(register const Char * str, char *buf, unsigned int len){    while (len--) {        if ((*buf++ = (char) *str++) == EOS)            return 0;    }    return 1;}#elseextern signed char v6ready;#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -