]> git.ipfire.org Git - thirdparty/mlmmj.git/commitdiff
*** empty log message ***
authormmj <none@none>
Tue, 15 Nov 2005 21:46:52 +0000 (08:46 +1100)
committermmj <none@none>
Tue, 15 Nov 2005 21:46:52 +0000 (08:46 +1100)
ChangeLog
src/find_email_adr.c
src/mlmmj-process.c

index 4b0a2d236da3595371c9b1c1bfb17f463033c97a..eea5807d663899ac6fe29927bb372e0acfdfdc5b 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,4 +1,5 @@
 1.2.9
+ o Make the email address check case-insensitive. (Neale Pickett)
  o Add spanish listtext translations (Enrique Matías Sánchez)
  o Make recipient delimiter configurable per list. SIC! (Joel Aelwyn)
  o Added italian list texts translation. A thanks to Andrea Barisani, he has
index 2cfd8ddfddccd4b81fde482e24d1d7d619a07a34..f9c11700148113237823bd3d1eb21c09aadfc43c 100644 (file)
-/* Copyright (C) 2002, 2003 Mads Martin Joergensen <mmj at mmj.dk>
+/* Some crap from BSD mail to parse email addresses.
  *
- * $Id$
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to
- * deal in the Software without restriction, including without limitation the
- * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
- * sell copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
+ * Neale Pickett <neale@woozle.org> stole these functions from FreeBSD
+ * ports, and reformatted them to use mlmmj's coding style.  The
+ * original functions (skip_comment and skin) had the following
+ * copyright notice:
+ */
+
+/*
+ * Copyright (c) 1980, 1993
+ *     The Regents of the University of California.  All rights reserved.
  *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by the University of
+ *     California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
  *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
- * IN THE SOFTWARE.
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  */
 
 #include <string.h>
-#include <strings.h>
 #include <stdio.h>
 #include <stdlib.h>
 
 #include "find_email_adr.h"
 #include "memory.h"
 
+/*
+ * Start of a "comment".
+ * Ignore it.
+ */
+static char *
+skip_comment(char *cp)
+{
+       int nesting = 1;
+
+       for (; nesting > 0 && *cp; cp++) {
+               switch (*cp) {
+                       case '\\':
+                               if (cp[1])
+                                       cp++;
+                               break;
+                       case '(':
+                               nesting++;
+                               break;
+                       case ')':
+                               nesting--;
+                               break;
+               }
+       }
+       return (cp);
+}
+
+/*
+ * Skin an arpa net address according to the RFC 822 interpretation
+ * of "host-phrase."
+ */
+static char *skin(char *name)
+{
+       char *nbuf, *bufend, *cp, *cp2;
+       int c, gotlt, lastsp;
+
+       if (name == NULL)
+               return (NULL);
+
+       /* We assume that length(input) <= length(output) */
+       nbuf = mymalloc(strlen(name) + 1);
+
+       if (strchr(name, '(') == NULL && strchr(name, '<') == NULL
+           && strchr(name, ' ') == NULL) {
+               strcpy(nbuf, name);
+               return (nbuf);
+       }
+
+       gotlt = 0;
+       lastsp = 0;
+       bufend = nbuf;
+       for (cp = name, cp2 = bufend; (c = *cp++) != '\0'; ) {
+               switch (c) {
+               case '(':
+                       cp = skip_comment(cp);
+                       lastsp = 0;
+                       break;
+
+               case '"':
+                       /*
+                        * Start of a "quoted-string".
+                        * Copy it in its entirety.
+                        */
+                       while ((c = *cp) != '\0') {
+                               cp++;
+                               if (c == '"')
+                                       break;
+                               if (c != '\\')
+                                       *cp2++ = c;
+                               else if ((c = *cp) != '\0') {
+                                       *cp2++ = c;
+                                       cp++;
+                               }
+                       }
+                       lastsp = 0;
+                       break;
+
+               case ' ':
+                       if (cp[0] == 'a' && cp[1] == 't' && cp[2] == ' ')
+                               cp += 3, *cp2++ = '@';
+                       else
+                       if (cp[0] == '@' && cp[1] == ' ')
+                               cp += 2, *cp2++ = '@';
+                       else
+                               lastsp = 1;
+                       break;
+
+               case '<':
+                       cp2 = bufend;
+                       gotlt++;
+                       lastsp = 0;
+                       break;
+
+               case '>':
+                       if (gotlt) {
+                               gotlt = 0;
+                               while ((c = *cp) != '\0' && c != ',') {
+                                       cp++;
+                                       if (c == '(')
+                                               cp = skip_comment(cp);
+                                       else if (c == '"')
+                                               while ((c = *cp) != '\0') {
+                                                       cp++;
+                                                       if (c == '"')
+                                                               break;
+                                                       if (c == '\\' && *cp != '\0')
+                                                               cp++;
+                                               }
+                               }
+                               lastsp = 0;
+                               break;
+                       }
+                       /* FALLTHROUGH */
+
+               default:
+                       if (lastsp) {
+                               lastsp = 0;
+                               *cp2++ = ' ';
+                       }
+                       *cp2++ = c;
+                       if (c == ',' && *cp == ' ' && !gotlt) {
+                               *cp2++ = ' ';
+                               while (*++cp == ' ')
+                                       ;
+                               lastsp = 0;
+                               bufend = cp2;
+                       }
+               }
+       }
+       *cp2 = '\0';
+
+       nbuf = (char *)myrealloc(nbuf, strlen(nbuf) + 1);
+       return (nbuf);
+}
+
+
 struct email_container *find_email_adr(const char *str,
                struct email_container *retstruct)
 {
-       size_t len;
-       char *index_atsign;
-       char *tempstr = mystrdup(str);
-       char *c, *first_char = NULL, *last_char = NULL;
-       
-       index_atsign = strchr(tempstr, '@');
-       while(index_atsign) {
-               c = index_atsign;
-               retstruct->emailcount++;
-               while(c >= tempstr && *c != '<' && *c != ' ' && *c != ','
-                               && *c != ';' && *c != '(' && *c != '[' &&
-                               *c >= 32 && *c != '{') {
-                       c--;
+       char *p;
+       char *s;
+
+       s = (char *)mymalloc(strlen(str) + 1);
+       strcpy(s, str);
+
+       p = s;
+       while(p) {
+               char *adr;
+               char *cur;
+
+               cur = p;
+               p = strchr(p, ',');
+               if (p) {
+                       /* If there's a comma, replace it with a NUL, so
+                        * cur will only have one address in it. */
+                       *p = '\0';
+                       p += 1;
+               }
+
+               while(cur && ((' ' == *cur) ||
+                           ('\t' == *cur) ||
+                           ('\r' == *cur) ||
+                           ('\n' == *cur))) {
+                       cur += 1;
                }
-               first_char = ++c;
-               c = index_atsign;
-               while(*c != '>' && *c != ' ' && *c != ',' && *c != ';'
-                               && *c != ')' && *c != ']' && *c >= 32
-                               && *c != '}' && *c != 0) {
-                       c++;
+               if ('\0' == *cur) {
+                       continue;
+               }
+
+               adr = skin(cur);
+               if (adr) {
+                       retstruct->emailcount++;
+                       retstruct->emaillist = (char **)myrealloc(retstruct->emaillist,
+                                         sizeof(char *) * retstruct->emailcount);
+                       retstruct->emaillist[retstruct->emailcount-1] = adr;
                }
-               last_char = --c;
-
-               len = last_char - first_char + 2;
-               
-               retstruct->emaillist = (char **)realloc(retstruct->emaillist,
-                               sizeof(char *) * retstruct->emailcount);
-               retstruct->emaillist[retstruct->emailcount-1] =
-                               (char *)mymalloc(len + 1);
-               snprintf(retstruct->emaillist[retstruct->emailcount-1], len,
-                        "%s", first_char);
-#if 0
-               log_error(LOG_ARGS, "find_email_adr POST, [%s]\n",
-                               retstruct->emaillist[retstruct->emailcount-1]);
-#endif
-               *index_atsign = 'A'; /* Clear it so we don't find it again */
-               index_atsign = strchr(tempstr, '@');
        }
-       myfree(tempstr);
+
+       myfree(s);
+
        return retstruct;
 }
index ff5db5a83b98c3b349f29b05b791d07822d0a6bc..bc0a7c6add009af1c34018acfd6ac2bbe59f6515 100644 (file)
@@ -619,7 +619,7 @@ int main(int argc, char **argv)
                for(i = 0; i < toemails.emailcount; i++) {
                        for(j = 0; j < alternates->count; j++) {
                                chomp(alternates->strs[j]);
-                               if(strcmp(alternates->strs[j],
+                               if(strcasecmp(alternates->strs[j],
                                        toemails.emaillist[i]) == 0)
                                        intocc = 1;
                        }
@@ -627,7 +627,7 @@ int main(int argc, char **argv)
                for(i = 0; i < ccemails.emailcount; i++) {
                        for(j = 0; j < alternates->count; j++) {
                                chomp(alternates->strs[j]);
-                               if(strcmp(alternates->strs[j],
+                               if(strcasecmp(alternates->strs[j],
                                        ccemails.emaillist[i]) == 0)
                                        intocc = 1;
                        }