summaryrefslogtreecommitdiff
path: root/usr.bin/ssh/match.c
blob: a5cab2877e4ff612d288f78fccc5543cda2389bd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/*

match.c

Author: Tatu Ylonen <ylo@cs.hut.fi>

Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
                   All rights reserved

Created: Thu Jun 22 01:17:50 1995 ylo

Simple pattern matching, with '*' and '?' as wildcards.

*/

#include "includes.h"
RCSID("$Id: match.c,v 1.1 1999/09/26 20:53:36 deraadt Exp $");

#include "ssh.h"

/* Returns true if the given string matches the pattern (which may contain
   ? and * as wildcards), and zero if it does not match. */
	  
int match_pattern(const char *s, const char *pattern)
{
  while (1)
    {
      /* If at end of pattern, accept if also at end of string. */
      if (!*pattern)
        return !*s;

      /* Process '*'. */
      if (*pattern == '*')
        {
	  /* Skip the asterisk. */
	  pattern++;

	  /* If at end of pattern, accept immediately. */
          if (!*pattern)
            return 1;

	  /* If next character in pattern is known, optimize. */
          if (*pattern != '?' && *pattern != '*')
            {
	      /* Look instances of the next character in pattern, and try
		 to match starting from those. */
              for (; *s; s++)
                if (*s == *pattern &&
                    match_pattern(s + 1, pattern + 1))
                  return 1;
	      /* Failed. */
              return 0;
            }

	  /* Move ahead one character at a time and try to match at each
	     position. */
          for (; *s; s++)
            if (match_pattern(s, pattern))
              return 1;
	  /* Failed. */
          return 0;
        }

      /* There must be at least one more character in the string.  If we are
	 at the end, fail. */
      if (!*s)
        return 0;

      /* Check if the next character of the string is acceptable. */
      if (*pattern != '?' && *pattern != *s)
	return 0;
      
      /* Move to the next character, both in string and in pattern. */
      s++;
      pattern++;
    }
  /*NOTREACHED*/
}