Merge branch 'topic/mm-fixes' of git://208.110.73.182/silc into silc.1.1.branch
[silc.git] / lib / silcutil / silcstrutil.c
index 1c537c1152f0ef7365916cd7520b5234418b856e..1133c88dbf87814b3ea9b8f8e20e9267d5d9dfe4 100644 (file)
 static unsigned char pem_enc[64] =
 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
 
-/* Encodes data into PEM encoding. Returns NULL terminated PEM encoded
+/* Encodes data into Base 64 encoding. Returns NULL terminated base 64 encoded
    data string. */
 
-char *silc_pem_encode(unsigned char *data, SilcUInt32 len)
+char *silc_base64_encode(unsigned char *data, SilcUInt32 len)
 {
   int i, j;
   SilcUInt32 bits, c, char_count;
@@ -75,13 +75,13 @@ char *silc_pem_encode(unsigned char *data, SilcUInt32 len)
 
 /* Same as above but puts newline ('\n') every 72 characters. */
 
-char *silc_pem_encode_file(unsigned char *data, SilcUInt32 data_len)
+char *silc_base64_encode_file(unsigned char *data, SilcUInt32 data_len)
 {
   int i, j;
   SilcUInt32 len, cols;
   char *pem, *pem2;
 
-  pem = silc_pem_encode(data, data_len);
+  pem = silc_base64_encode(data, data_len);
   len = strlen(pem);
 
   pem2 = silc_calloc(len + (len / 72) + 1, sizeof(*pem2));
@@ -101,10 +101,11 @@ char *silc_pem_encode_file(unsigned char *data, SilcUInt32 data_len)
   return pem2;
 }
 
-/* Decodes PEM into data. Returns the decoded data. */
+/* Decodes Base 64 into data. Returns the decoded data. */
 
-unsigned char *silc_pem_decode(unsigned char *pem, SilcUInt32 pem_len,
-                              SilcUInt32 *ret_len)
+unsigned char *silc_base64_decode(unsigned char *base64,
+                                 SilcUInt32 base64_len,
+                                 SilcUInt32 *ret_len)
 {
   int i, j;
   SilcUInt32 len, c, char_count, bits;
@@ -120,15 +121,15 @@ unsigned char *silc_pem_decode(unsigned char *pem, SilcUInt32 pem_len,
   bits = 0;
   j = 0;
 
-  if (!pem_len)
-    len = strlen(pem);
+  if (!base64_len)
+    len = strlen(base64);
   else
-    len = pem_len;
+    len = base64_len;
 
   data = silc_calloc(((len * 6) / 8), sizeof(*data));
 
   for (i = 0; i < len; i++) {
-    c = pem[i];
+    c = base64[i];
 
     if (c == '=')
       break;
@@ -313,3 +314,112 @@ char **silc_string_split(const char *string, char ch, int *ret_count)
 
   return splitted;
 }
+
+/* Inspects the `string' for wildcards and returns regex string that can
+   be used by the GNU regex library. A comma (`,') in the `string' means
+   that the string is list. */
+
+char *silc_string_regexify(const char *string)
+{
+  int i, len, count;
+  char *regex;
+
+  if (!string)
+    return NULL;
+
+  len = strlen(string);
+  count = 4;
+  for (i = 0; i < len; i++) {
+    if (string[i] == '*' || string[i] == '?')
+      count++;                 /* Will add '.' */
+    if (string[i] == ',')
+      count += 2;              /* Will add '|' and '^' */
+  }
+
+  regex = silc_calloc(len + count + 1, sizeof(*regex));
+  if (!regex)
+    return NULL;
+
+  count = 0;
+  regex[count++] = '(';
+  regex[count++] = '^';
+
+  for (i = 0; i < len; i++) {
+    if (string[i] == '*' || string[i] == '?') {
+      regex[count] = '.';
+      count++;
+    } else if (string[i] == ',') {
+      if (i + 2 == len)
+       continue;
+      regex[count++] = '|';
+      regex[count++] = '^';
+      continue;
+    }
+
+    regex[count++] = string[i];
+  }
+
+  regex[count++] = ')';
+  regex[count] = '$';
+
+  return regex;
+}
+
+/* Combines two regex strings into one regex string so that they can be
+   used as one by the GNU regex library. The `string2' is combine into
+   the `string1'. */
+
+char *silc_string_regex_combine(const char *string1, const char *string2)
+{
+  char *tmp;
+  int len1, len2;
+
+  if (!string1 || !string2)
+    return NULL;
+
+  len1 = strlen(string1);
+  len2 = strlen(string2);
+
+  tmp = silc_calloc(2 + len1 + len2, sizeof(*tmp));
+  strncat(tmp, string1, len1 - 2);
+  strncat(tmp, "|", 1);
+  strncat(tmp, string2 + 1, len2 - 1);
+
+  return tmp;
+}
+
+/* Matches the two strings and returns TRUE if the strings match. */
+
+int silc_string_regex_match(const char *regex, const char *string)
+{
+  regex_t preg;
+  int ret = FALSE;
+
+  if (regcomp(&preg, regex, REG_NOSUB | REG_EXTENDED) != 0)
+    return FALSE;
+
+  if (regexec(&preg, string, 0, NULL, 0) == 0)
+    ret = TRUE;
+
+  regfree(&preg);
+
+  return ret;
+}
+
+/* Do regex match to the two strings `string1' and `string2'. If the
+   `string2' matches the `string1' this returns TRUE. */
+
+int silc_string_match(const char *string1, const char *string2)
+{
+  char *s1;
+  int ret = FALSE;
+
+  if (!string1 || !string2)
+    return ret;
+
+  s1 = silc_string_regexify(string1);
+  ret = silc_string_regex_match(s1, string2);
+  silc_free(s1);
+
+  return ret;
+}