OSSP CVS Repository

ossp - Check-in [240]
Not logged in
[Honeypot]  [Browse]  [Home]  [Login]  [Reports
[Search]  [Ticket]  [Timeline
  [Patchset]  [Tagging/Branching

Check-in Number: 240
Date: 2000-Dec-15 13:38:22 (local)
2000-Dec-15 12:38:22 (UTC)
User:simons
Branch:
Comment: Initial revision
Tickets:
Inspections:
Files:
ossp-pkg/petidomo/librfc822/decomment.c      added-> 1.1

ossp-pkg/petidomo/librfc822/decomment.c -> 1.1

*** /dev/null    Sun May 19 12:31:51 2024
--- -    Sun May 19 12:32:51 2024
***************
*** 0 ****
--- 1,217 ----
+ /*
+  *      $Source: /v/ossp/cvs/ossp-pkg/petidomo/librfc822/decomment.c,v $
+  *      $Revision: 1.1 $
+  *      $Date: 2000/12/16 12:38:22 $
+  *
+  *      Copyright (C) 1997 by CyberSolutions GmbH.
+  *      All rights reserved.
+  */
+ 
+ #include <stdio.h>
+ #include <stdlib.h>
+ #include <errno.h>
+ #include <assert.h>
+ #ifdef DEBUG_DMALLOC
+ #  include <dmalloc.h>
+ #endif
+ 
+ #include "rfc822.h"
+ 
+ static const char *
+ read_until_next_quote(const char * p)
+ {
+     while (*p) {
+        if (*p == '"') {
+            break;
+        }
+        if (*p == '\\' && p[1] != '\0') {
+            p += 2;
+            continue;
+        }
+        p++;
+     }
+     return p;
+ }
+ 
+ static const char *
+ read_until_close_bracket(const char * p)
+ {
+     while (*p) {
+        if (*p == ')') {
+            break;
+        }
+        if (*p == '(') {
+            p = read_until_close_bracket(p+1);
+            if (*p == '\0')
+              break;
+            else {
+                p++;
+                continue;
+            }
+        }
+        else if (*p == '\\' && p[1] != '\0') {
+            p += 2;
+            continue;
+        }
+        else if (*p == '"') {
+            p = read_until_next_quote(p+1);
+            if (*p == '\0')
+              break;
+            else {
+                p++;
+                continue;
+            }
+        }
+        p++;
+     }
+     return p;
+ }
+ 
+ /* remove all comments from an rfc822 address
+ 
+    This routine takes as argument an address string conforming to the
+    RFC822 syntax and removes all comments from it, returning the
+    result in the pointer specified as second argument.
+ 
+    This is very useful if you want to parse the address with a context
+    free grammer parser, like yacc, because recognizing the various
+    forms of commenting with a BNF grammar is very complicated.
+ 
+    RETURNS: The routine returns an integer describing whether the
+    decommenting process succeeded or not. In case of an error, the
+    return code described the reason for failure.
+ 
+    RFC822_OK: Success.
+ 
+    RFC822_FATAL_ERROR: A fatal system error occured, like malloc()
+    failed. The global errno variable will be set accordingly.
+ 
+    RFC822_UNCLOSED_COMMENT: A "(comment)"-like expression was not
+    closed properly.
+ 
+    RFC822_UNMATCHED_CLOSE_BRACKET: A close bracket (")") was
+    encountered outside the comment context.
+ 
+    RFC822_UNCLOSED_QUOTE: A quoted `"string"'-like expression was not
+    closed properly.
+ 
+    RFC822_UNCLOSED_ANGEL_BRACKET: An "<address>"-like expression was
+    not closed properly.
+ 
+    RFC822_NESTED_ANGEL_BRACKET: An open angel bracket ("<") was
+    encountered inside the "<address>" context.
+ 
+    RFC822_UNMATCHED_CLOSE_ANGEL_BRACKET: A close angel bracket (">") was
+    encountered outside the "<address>" context.
+ 
+    RFC822_SYNTAX_ERROR: The address does not follow the rfc822 syntax.
+ 
+    NOTE: The returned by rfc822_decomment() has been allocated with
+    malloc(3) and should be freed when not needed anymore.
+ 
+    AUTHOR: Peter Simons <simons@rhein.de>
+ 
+  */
+ 
+ int
+ rfc822_decomment(const char *  source  /* String containing a formatted rfc822 address. */,
+                 char **   destination  /* Location where to store the parsed string. */)
+ {
+     char *   buffer,
+         *   address_start,
+         *   p;
+     const char * s;
+     int      in_quote,
+             angel_bracket_count;
+ 
+ 
+     /* Sanity checks. */
+ 
+     assert(source != NULL);
+     if (!source || *source == '\0') {
+        errno = EINVAL;
+        return NULL;
+     }
+ 
+     /* Allocate buffer. */
+ 
+     buffer = malloc(strlen(source)+1);
+     if (buffer == NULL) {
+        errno = ENOMEM;
+        return RFC822_FATAL_ERROR;
+     }
+ 
+     /* Let's parse it. */
+ 
+     address_start = p = buffer;
+     s = source;
+     in_quote = 0;
+     angel_bracket_count = 0;
+ 
+     while(*s) {
+ 
+        if (*s == '"') {
+            in_quote = !in_quote;
+        }
+        else if (!in_quote && *s == '(') {
+            s = read_until_close_bracket(s+1);
+            if (*s == '\0') {
+                free(buffer);
+                return RFC822_UNCLOSED_COMMENT;
+            }
+            s++;
+            *p++ = ' ';
+            continue;
+        }
+        else if (!in_quote && *s == ')') {
+            free(buffer);
+            return RFC822_UNMATCHED_CLOSE_BRACKET;
+        }
+        else if (!in_quote && *s == '<') {
+            if (angel_bracket_count > 0) {
+                free(buffer);
+                return RFC822_NESTED_ANGEL_BRACKET;
+            }
+            s++;
+            p = address_start;
+            *p = '\0';
+            angel_bracket_count++;
+            continue;
+        }
+        else if (!in_quote && *s == '>') {
+            if (angel_bracket_count == 0) {
+                free(buffer);
+                return RFC822_UNMATCHED_CLOSE_ANGEL_BRACKET;
+            }
+            *p = '\0';
+            angel_bracket_count--;
+            break;
+        }
+        else if (!in_quote && *s == '\\') {
+            if (s[1] != '\0') {
+                *p++ = *s++;
+            }
+            else {
+                free(buffer);
+                return RFC822_SYNTAX_ERROR;
+            }
+        }
+ 
+ 
+        *p++ = *s++;
+     }
+     *p = '\0';
+     if (in_quote) {
+        free(buffer);
+        return RFC822_UNCLOSED_QUOTE;
+     }
+ 
+     if (angel_bracket_count > 0) {
+        free(buffer);
+        return RFC822_UNCLOSED_ANGEL_BRACKET;
+     }
+ 
+ 
+     *destination = buffer;
+     return RFC822_OK;
+ }

CVSTrac 2.0.1