Deleted Added
full compact
22c22
< __FBSDID("$FreeBSD: head/usr.sbin/pkg_install/lib/match.c 123770 2003-12-23 15:01:12Z schweikh $");
---
> __FBSDID("$FreeBSD: head/usr.sbin/pkg_install/lib/match.c 131275 2004-06-29 18:54:47Z eik $");
40c40,41
< static int rex_match(const char *, const char *);
---
> static int rex_match(const char *, const char *, int);
> static int csh_match(const char *, const char *, int);
47c48
< * MatchType - one of MATCH_ALL, MATCH_REGEX, MATCH_GLOB;
---
> * MatchType - one of MATCH_ALL, MATCH_EREGEX, MATCH_REGEX, MATCH_GLOB, MATCH_NGLOB;
111,126c112,116
< switch (MatchType) {
< case MATCH_REGEX:
< errcode = rex_match(patterns[i], f->fts_name);
< if (errcode == 1) {
< matched = f->fts_name;
< errcode = 0;
< }
< break;
< case MATCH_GLOB:
< if (fnmatch(patterns[i], f->fts_name, 0) == 0) {
< matched = f->fts_name;
< lmatched[i] = TRUE;
< }
< break;
< default:
< break;
---
> errcode = pattern_match(MatchType, patterns[i], f->fts_name);
> if (errcode == 1) {
> matched = f->fts_name;
> lmatched[i] = TRUE;
> errcode = 0;
155a146,235
> int
> pattern_match(match_t MatchType, char *pattern, const char *pkgname)
> {
> int errcode = 0;
> const char *fname = pkgname;
> char basefname[PATH_MAX];
> char condchar = '\0';
> char *condition;
>
> /* do we have an appended condition? */
> condition = strpbrk(pattern, "<>=");
> if (condition) {
> const char *ch;
> /* yes, isolate the pattern from the condition ... */
> if (condition > pattern && condition[-1] == '!')
> condition--;
> condchar = *condition;
> *condition = '\0';
> /* ... and compare the name without version */
> ch = strrchr(fname, '-');
> if (ch && ch - fname < PATH_MAX) {
> strlcpy(basefname, fname, ch - fname + 1);
> fname = basefname;
> }
> }
>
> switch (MatchType) {
> case MATCH_EREGEX:
> case MATCH_REGEX:
> errcode = rex_match(pattern, fname, MatchType == MATCH_EREGEX ? 1 : 0);
> break;
> case MATCH_NGLOB:
> case MATCH_GLOB:
> errcode = (csh_match(pattern, fname, 0) == 0) ? 1 : 0;
> break;
> case MATCH_EXACT:
> errcode = (strcmp(pattern, fname) == 0) ? 1 : 0;
> break;
> case MATCH_ALL:
> errcode = 1;
> break;
> default:
> break;
> }
>
> /* loop over all appended conditions */
> while (condition) {
> /* restore the pattern */
> *condition = condchar;
> /* parse the condition (fun with bits) */
> if (errcode == 1) {
> char *nextcondition;
> /* compare version numbers */
> int match = 0;
> if (*++condition == '=') {
> match = 2;
> condition++;
> }
> switch(condchar) {
> case '<':
> match |= 1;
> break;
> case '>':
> match |= 4;
> break;
> case '=':
> match |= 2;
> break;
> case '!':
> match = 5;
> break;
> }
> /* isolate the version number from the next condition ... */
> nextcondition = strpbrk(condition, "<>=!");
> if (nextcondition) {
> condchar = *nextcondition;
> *nextcondition = '\0';
> }
> /* and compare the versions (version_cmp removes the filename for us) */
> if ((match & (1 << (version_cmp(pkgname, condition) + 1))) == 0)
> errcode = 0;
> condition = nextcondition;
> } else {
> break;
> }
> }
>
> return errcode;
> }
>
196,199c276,277
< warn("%s", tmp);
< if (retval != NULL)
< *retval = 1;
< return NULL;
---
> warnx("the package info for package '%s' is corrupt", installed[i]);
> continue;
215c293
< if (strcmp(origin, cp) == 0)
---
> if (csh_match(origin, cp, FNM_PATHNAME) == 0)
258c336
< rex_match(const char *pattern, const char *pkgname)
---
> rex_match(const char *pattern, const char *pkgname, int extended)
267c345
< errcode = regcomp(&rex, pattern, REG_BASIC | REG_NOSUB);
---
> errcode = regcomp(&rex, pattern, (extended ? REG_EXTENDED : REG_BASIC) | REG_NOSUB);
284a363,455
> * Match string by a csh-style glob pattern. Returns 0 on
> * match and FNM_NOMATCH otherwise, to be compatible with
> * fnmatch(3).
> */
> static int
> csh_match(const char *pattern, const char *string, int flags)
> {
> int ret = FNM_NOMATCH;
>
>
> const char *nextchoice = pattern;
> const char *current = NULL;
>
> int prefixlen = -1;
> int currentlen = 0;
>
> int level = 0;
>
> do {
> const char *pos = nextchoice;
> const char *postfix = NULL;
>
> Boolean quoted = FALSE;
>
> nextchoice = NULL;
>
> do {
> const char *eb;
> if (!*pos) {
> postfix = pos;
> } else if (quoted) {
> quoted = FALSE;
> } else {
> switch (*pos) {
> case '{':
> ++level;
> if (level == 1) {
> current = pos+1;
> prefixlen = pos-pattern;
> }
> break;
> case ',':
> if (level == 1 && !nextchoice) {
> nextchoice = pos+1;
> currentlen = pos-current;
> }
> break;
> case '}':
> if (level == 1) {
> postfix = pos+1;
> if (!nextchoice)
> currentlen = pos-current;
> }
> level--;
> break;
> case '[':
> eb = pos+1;
> if (*eb == '!' || *eb == '^')
> eb++;
> if (*eb == ']')
> eb++;
> while(*eb && *eb != ']')
> eb++;
> if (*eb)
> pos=eb;
> break;
> case '\\':
> quoted = TRUE;
> break;
> default:
> ;
> }
> }
> pos++;
> } while (!postfix);
>
> if (current) {
> char buf[FILENAME_MAX];
> snprintf(buf, sizeof(buf), "%.*s%.*s%s", prefixlen, pattern, currentlen, current, postfix);
> ret = csh_match(buf, string, flags);
> if (ret) {
> current = nextchoice;
> level = 1;
> } else
> current = NULL;
> } else
> ret = fnmatch(pattern, string, flags);
> } while (current);
>
> return ret;
> }
>
> /*