match.c revision 57429
157429Smarkm/*
257429Smarkm *
357429Smarkm * match.c
457429Smarkm *
557429Smarkm * Author: Tatu Ylonen <ylo@cs.hut.fi>
657429Smarkm *
757429Smarkm * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
857429Smarkm *                    All rights reserved
957429Smarkm *
1057429Smarkm * Created: Thu Jun 22 01:17:50 1995 ylo
1157429Smarkm *
1257429Smarkm * Simple pattern matching, with '*' and '?' as wildcards.
1357429Smarkm *
1457429Smarkm */
1557429Smarkm
1657429Smarkm#include "includes.h"
1757429SmarkmRCSID("$Id: match.c,v 1.4 1999/11/24 19:53:48 markus Exp $");
1857429Smarkm
1957429Smarkm#include "ssh.h"
2057429Smarkm
2157429Smarkm/*
2257429Smarkm * Returns true if the given string matches the pattern (which may contain ?
2357429Smarkm * and * as wildcards), and zero if it does not match.
2457429Smarkm */
2557429Smarkm
2657429Smarkmint
2757429Smarkmmatch_pattern(const char *s, const char *pattern)
2857429Smarkm{
2957429Smarkm	for (;;) {
3057429Smarkm		/* If at end of pattern, accept if also at end of string. */
3157429Smarkm		if (!*pattern)
3257429Smarkm			return !*s;
3357429Smarkm
3457429Smarkm		if (*pattern == '*') {
3557429Smarkm			/* Skip the asterisk. */
3657429Smarkm			pattern++;
3757429Smarkm
3857429Smarkm			/* If at end of pattern, accept immediately. */
3957429Smarkm			if (!*pattern)
4057429Smarkm				return 1;
4157429Smarkm
4257429Smarkm			/* If next character in pattern is known, optimize. */
4357429Smarkm			if (*pattern != '?' && *pattern != '*') {
4457429Smarkm				/*
4557429Smarkm				 * Look instances of the next character in
4657429Smarkm				 * pattern, and try to match starting from
4757429Smarkm				 * those.
4857429Smarkm				 */
4957429Smarkm				for (; *s; s++)
5057429Smarkm					if (*s == *pattern &&
5157429Smarkm					    match_pattern(s + 1, pattern + 1))
5257429Smarkm						return 1;
5357429Smarkm				/* Failed. */
5457429Smarkm				return 0;
5557429Smarkm			}
5657429Smarkm			/*
5757429Smarkm			 * Move ahead one character at a time and try to
5857429Smarkm			 * match at each position.
5957429Smarkm			 */
6057429Smarkm			for (; *s; s++)
6157429Smarkm				if (match_pattern(s, pattern))
6257429Smarkm					return 1;
6357429Smarkm			/* Failed. */
6457429Smarkm			return 0;
6557429Smarkm		}
6657429Smarkm		/*
6757429Smarkm		 * There must be at least one more character in the string.
6857429Smarkm		 * If we are at the end, fail.
6957429Smarkm		 */
7057429Smarkm		if (!*s)
7157429Smarkm			return 0;
7257429Smarkm
7357429Smarkm		/* Check if the next character of the string is acceptable. */
7457429Smarkm		if (*pattern != '?' && *pattern != *s)
7557429Smarkm			return 0;
7657429Smarkm
7757429Smarkm		/* Move to the next character, both in string and in pattern. */
7857429Smarkm		s++;
7957429Smarkm		pattern++;
8057429Smarkm	}
8157429Smarkm	/* NOTREACHED */
8257429Smarkm}
83