portreg.c
上传用户:lyxiangda
上传日期:2007-01-12
资源大小:3042k
文件大小:9k
源码类别:

CA认证

开发平台:

WINDOWS

  1. /*
  2.  * The contents of this file are subject to the Mozilla Public
  3.  * License Version 1.1 (the "License"); you may not use this file
  4.  * except in compliance with the License. You may obtain a copy of
  5.  * the License at http://www.mozilla.org/MPL/
  6.  * 
  7.  * Software distributed under the License is distributed on an "AS
  8.  * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
  9.  * implied. See the License for the specific language governing
  10.  * rights and limitations under the License.
  11.  * 
  12.  * The Original Code is the Netscape security libraries.
  13.  * 
  14.  * The Initial Developer of the Original Code is Netscape
  15.  * Communications Corporation.  Portions created by Netscape are 
  16.  * Copyright (C) 1994-2000 Netscape Communications Corporation.  All
  17.  * Rights Reserved.
  18.  * 
  19.  * Contributor(s):
  20.  * 
  21.  * Alternatively, the contents of this file may be used under the
  22.  * terms of the GNU General Public License Version 2 or later (the
  23.  * "GPL"), in which case the provisions of the GPL are applicable 
  24.  * instead of those above.  If you wish to allow use of your 
  25.  * version of this file only under the terms of the GPL and not to
  26.  * allow others to use your version of this file under the MPL,
  27.  * indicate your decision by deleting the provisions above and
  28.  * replace them with the notice and other provisions required by
  29.  * the GPL.  If you do not delete the provisions above, a recipient
  30.  * may use your version of this file under either the MPL or the
  31.  * GPL.
  32.  */
  33. /* 
  34.  * shexp.c: shell-like wildcard match routines
  35.  *
  36.  *
  37.  * See shexp.h for public documentation.
  38.  *
  39.  */
  40. #include "seccomon.h"
  41. #include "portreg.h"
  42. /* ----------------------------- shexp_valid ------------------------------ */
  43. static int 
  44. _valid_subexp(char *exp, char stop) 
  45. {
  46.     register int x,y,t;
  47.     int nsc,np,tld;
  48.     x=0;nsc=0;tld=0;
  49.     while(exp[x] && (exp[x] != stop)) {
  50.         switch(exp[x]) {
  51.           case '~':
  52.             if(tld) return INVALID_SXP;
  53.             else ++tld;
  54.           case '*':
  55.           case '?':
  56.           case '^':
  57.           case '$':
  58.             ++nsc;
  59.             break;
  60.           case '[':
  61.             ++nsc;
  62.             if((!exp[++x]) || (exp[x] == ']'))
  63.                 return INVALID_SXP;
  64.             for(++x;exp[x] && (exp[x] != ']');++x)
  65.                 if(exp[x] == '\')
  66.                     if(!exp[++x])
  67.                         return INVALID_SXP;
  68.             if(!exp[x])
  69.                 return INVALID_SXP;
  70.             break;
  71.           case '(':
  72.             ++nsc;np = 0;
  73.             while(1) {
  74.                 if(exp[++x] == ')')
  75.                     return INVALID_SXP;
  76.                 for(y=x;(exp[y]) && (exp[y] != '|') && (exp[y] != ')');++y)
  77.                     if(exp[y] == '\')
  78.                         if(!exp[++y])
  79.                             return INVALID_SXP;
  80.                 if(!exp[y])
  81.                     return INVALID_SXP;
  82.                 if(exp[y] == '|')
  83.                     ++np;
  84.                 t = _valid_subexp(&exp[x],exp[y]);
  85.                 if(t == INVALID_SXP)
  86.                     return INVALID_SXP;
  87.                 x+=t;
  88.                 if(exp[x] == ')') {
  89.                     if(!np)
  90.                         return INVALID_SXP;
  91.                     break;
  92.                 }
  93.             }
  94.             break;
  95.           case ')':
  96.           case ']':
  97.             return INVALID_SXP;
  98.           case '\':
  99.             if(!exp[++x])
  100.                 return INVALID_SXP;
  101.           default:
  102.             break;
  103.         }
  104.         ++x;
  105.     }
  106.     if((!stop) && (!nsc))
  107.         return NON_SXP;
  108.     return ((exp[x] == stop) ? x : INVALID_SXP);
  109. }
  110. int 
  111. PORT_RegExpValid(char *exp) 
  112. {
  113.     int x;
  114.     x = _valid_subexp(exp, '');
  115.     return (x < 0 ? x : VALID_SXP);
  116. }
  117. /* ----------------------------- shexp_match ----------------------------- */
  118. #define MATCH 0
  119. #define NOMATCH 1
  120. #define ABORTED -1
  121. static int _shexp_match(char *str, char *exp, PRBool case_insensitive);
  122. static int 
  123. _handle_union(char *str, char *exp, PRBool case_insensitive) 
  124. {
  125.     char *e2 = (char *) PORT_Alloc(sizeof(char)*strlen(exp));
  126.     register int t,p2,p1 = 1;
  127.     int cp;
  128.     while(1) {
  129.         for(cp=1;exp[cp] != ')';cp++)
  130.             if(exp[cp] == '\')
  131.                 ++cp;
  132.         for(p2 = 0;(exp[p1] != '|') && (p1 != cp);p1++,p2++) {
  133.             if(exp[p1] == '\')
  134.                 e2[p2++] = exp[p1++];
  135.             e2[p2] = exp[p1];
  136.         }
  137.         for (t=cp+1; ((e2[p2] = exp[t]) != 0); ++t,++p2) {}
  138.         if(_shexp_match(str,e2, case_insensitive) == MATCH) {
  139.             PORT_Free(e2);
  140.             return MATCH;
  141.         }
  142.         if(p1 == cp) {
  143.             PORT_Free(e2);
  144.             return NOMATCH;
  145.         }
  146.         else ++p1;
  147.     }
  148. }
  149. static int 
  150. _shexp_match(char *str, char *exp, PRBool case_insensitive) 
  151. {
  152.     register int x,y;
  153.     int ret,neg;
  154.     ret = 0;
  155.     for(x=0,y=0;exp[y];++y,++x) {
  156.         if((!str[x]) && (exp[y] != '(') && (exp[y] != '$') && (exp[y] != '*'))
  157.             ret = ABORTED;
  158.         else {
  159.             switch(exp[y]) {
  160.               case '$':
  161.                 if( (str[x]) )
  162.                     ret = NOMATCH;
  163.                 else
  164.                     --x;             /* we don't want loop to increment x */
  165.                 break;
  166.               case '*':
  167.                 while(exp[++y] == '*'){}
  168.                 if(!exp[y])
  169.                     return MATCH;
  170.                 while(str[x]) {
  171.                     switch(_shexp_match(&str[x++],&exp[y], case_insensitive)) {
  172.                     case NOMATCH:
  173.                         continue;
  174.                     case ABORTED:
  175.                         ret = ABORTED;
  176.                         break;
  177.                     default:
  178.                         return MATCH;
  179.                     }
  180.                     break;
  181.                 }
  182.                 if((exp[y] == '$') && (exp[y+1] == '') && (!str[x]))
  183.                     return MATCH;
  184.                 else
  185.                     ret = ABORTED;
  186.                 break;
  187.               case '[':
  188.                neg = ((exp[++y] == '^') && (exp[y+1] != ']'));
  189.                 if (neg)
  190.                     ++y;
  191.                 
  192.                 if ((isalnum(exp[y])) && (exp[y+1] == '-') && 
  193.                    (isalnum(exp[y+2])) && (exp[y+3] == ']'))
  194.                     {
  195.                         int start = exp[y], end = exp[y+2];
  196.                         
  197.                         /* no safeguards here */
  198.                         if(neg ^ ((str[x] < start) || (str[x] > end))) {
  199.                             ret = NOMATCH;
  200.                             break;
  201.                         }
  202.                         y+=3;
  203.                     }
  204.                 else {
  205.                     int matched;
  206.                     
  207.                     for (matched=0;exp[y] != ']';y++)
  208.                         matched |= (str[x] == exp[y]);
  209.                     if (neg ^ (!matched))
  210.                         ret = NOMATCH;
  211.                 }
  212.                 break;
  213.               case '(':
  214.                 return _handle_union(&str[x],&exp[y], case_insensitive);
  215.                 break;
  216.               case '?':
  217.                 break;
  218.               case '\':
  219.                 ++y;
  220.               default:
  221. if(case_insensitive)
  222.   {
  223.                     if(toupper(str[x]) != toupper(exp[y]))
  224.                         ret = NOMATCH;
  225.   }
  226. else
  227.   {
  228.                     if(str[x] != exp[y])
  229.                         ret = NOMATCH;
  230.   }
  231.                 break;
  232.             }
  233.         }
  234.         if(ret)
  235.             break;
  236.     }
  237.     return (ret ? ret : (str[x] ? NOMATCH : MATCH));
  238. }
  239. int 
  240. PORT_RegExpMatch(char *str, char *xp, PRBool case_insensitive) {
  241.     register int x;
  242.     char *exp = 0;
  243.     exp = PORT_Strdup(xp);
  244.     if(!exp)
  245. return 1;
  246.     for(x=strlen(exp)-1;x;--x) {
  247.         if((exp[x] == '~') && (exp[x-1] != '\')) {
  248.             exp[x] = '';
  249.             if(_shexp_match(str,&exp[++x], case_insensitive) == MATCH)
  250.                 goto punt;
  251.             break;
  252.         }
  253.     }
  254.     if(_shexp_match(str,exp, PR_FALSE) == MATCH) {
  255.         PORT_Free(exp);
  256.         return 0;
  257.     }
  258.   punt:
  259.     PORT_Free(exp);
  260.     return 1;
  261. }
  262. /* ------------------------------ shexp_cmp ------------------------------- */
  263. int 
  264. PORT_RegExpSearch(char *str, char *exp)
  265. {
  266.     switch(PORT_RegExpValid(exp)) 
  267.   {
  268.         case INVALID_SXP:
  269.             return -1;
  270.         case NON_SXP:
  271.             return (strcmp(exp,str) ? 1 : 0);
  272.         default:
  273.             return PORT_RegExpMatch(str, exp, PR_FALSE);
  274.       }
  275. }
  276. int
  277. PORT_RegExpCaseSearch(char *str, char *exp)
  278. {
  279.     switch(PORT_RegExpValid(exp))
  280.       {
  281.         case INVALID_SXP:
  282.             return -1;
  283.         case NON_SXP:
  284.             return (strcmp(exp,str) ? 1 : 0);
  285.         default:
  286.             return PORT_RegExpMatch(str, exp, PR_TRUE);
  287.       }
  288. }