blob: 5386df6c4190eb4f895867fccedfa95565e419bb [file] [log] [blame]
Damien Millerd4a8b7e1999-10-27 13:42:43 +10001/*
Damien Miller95def091999-11-25 00:26:21 +11002 *
3 * match.c
4 *
5 * Author: Tatu Ylonen <ylo@cs.hut.fi>
6 *
7 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
8 * All rights reserved
9 *
10 * Created: Thu Jun 22 01:17:50 1995 ylo
11 *
12 * Simple pattern matching, with '*' and '?' as wildcards.
13 *
14 */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100015
16#include "includes.h"
Damien Miller5428f641999-11-25 11:54:57 +110017RCSID("$Id: match.c,v 1.3 1999/11/25 00:54:59 damien Exp $");
Damien Millerd4a8b7e1999-10-27 13:42:43 +100018
19#include "ssh.h"
20
Damien Miller5428f641999-11-25 11:54:57 +110021/*
22 * Returns true if the given string matches the pattern (which may contain ?
23 * and * as wildcards), and zero if it does not match.
24 */
Damien Miller95def091999-11-25 00:26:21 +110025
26int
27match_pattern(const char *s, const char *pattern)
Damien Millerd4a8b7e1999-10-27 13:42:43 +100028{
Damien Miller95def091999-11-25 00:26:21 +110029 for (;;) {
30 /* If at end of pattern, accept if also at end of string. */
31 if (!*pattern)
32 return !*s;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100033
Damien Miller95def091999-11-25 00:26:21 +110034 if (*pattern == '*') {
35 /* Skip the asterisk. */
36 pattern++;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100037
Damien Miller95def091999-11-25 00:26:21 +110038 /* If at end of pattern, accept immediately. */
39 if (!*pattern)
40 return 1;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100041
Damien Miller95def091999-11-25 00:26:21 +110042 /* If next character in pattern is known, optimize. */
43 if (*pattern != '?' && *pattern != '*') {
Damien Miller5428f641999-11-25 11:54:57 +110044 /*
45 * Look instances of the next character in
46 * pattern, and try to match starting from
47 * those.
48 */
Damien Miller95def091999-11-25 00:26:21 +110049 for (; *s; s++)
50 if (*s == *pattern &&
51 match_pattern(s + 1, pattern + 1))
52 return 1;
53 /* Failed. */
54 return 0;
55 }
Damien Miller5428f641999-11-25 11:54:57 +110056 /*
57 * Move ahead one character at a time and try to
58 * match at each position.
59 */
Damien Miller95def091999-11-25 00:26:21 +110060 for (; *s; s++)
61 if (match_pattern(s, pattern))
62 return 1;
63 /* Failed. */
64 return 0;
65 }
Damien Miller5428f641999-11-25 11:54:57 +110066 /*
67 * There must be at least one more character in the string.
68 * If we are at the end, fail.
69 */
Damien Miller95def091999-11-25 00:26:21 +110070 if (!*s)
71 return 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100072
Damien Miller5428f641999-11-25 11:54:57 +110073 /* Check if the next character of the string is acceptable. */
Damien Miller95def091999-11-25 00:26:21 +110074 if (*pattern != '?' && *pattern != *s)
75 return 0;
Damien Millerd4a8b7e1999-10-27 13:42:43 +100076
Damien Miller5428f641999-11-25 11:54:57 +110077 /* Move to the next character, both in string and in pattern. */
Damien Miller95def091999-11-25 00:26:21 +110078 s++;
79 pattern++;
80 }
81 /* NOTREACHED */
Damien Millerd4a8b7e1999-10-27 13:42:43 +100082}