chiark / gitweb /
Debianization and various other fixes.
[ezmlm] / author.c
1 /*$Id: author.c,v 1.3 1999/09/29 03:11:44 lindberg Exp $*/
2 /*$Name:*/
3
4 unsigned int author_name(char **sout,char *s,unsigned int l)
5 /* s is a string that contains a from: line argument\n. We parse */
6 /* s as follows: If there is an unquoted '<' we eliminate everything after */
7 /* it else if there is a unquoted ';' we eliminate everything after it.    */
8 /* Then, we eliminate LWSP and '"' from the beginning and end. Note that   */
9 /* this is not strict rfc822, but all we need is a display handle that     */
10 /* doesn't show the address. If in the remaining text there is a '@' we put*/
11 /* in a '.' instead. Also, there are some non-rfc822 from lines out there  */
12 /* and we still want to maximize the chance of getting a handle, even if it*/
13 /* costs a little extra work.*/
14 {
15   int squote = 0;
16   int dquote = 0;
17   int level = 0;
18   int flagdone;
19   unsigned int len;
20   char ch;
21   char *cpfirst,*cp;
22   char *cpcomlast = 0;
23   char *cpquotlast = 0;
24   char *cpquot = 0;
25   char *cpcom = 0;
26   char *cplt = 0;
27
28   if (!s || !l) {       /* Yuck - pass the buck */
29     *sout = s;
30     return 0;
31   }
32   cp = s; len = l;
33
34   while (len--) {
35     ch = *(cp++);
36     if (squote) {
37       squote = 0;
38       continue;
39     }
40     if (ch == '\\') {
41       squote = 1;
42       continue;
43     }
44     if (ch == '"') {            /* "name" <address@host> */
45       if (dquote) {
46         cpquotlast = cp - 2;
47         break;
48       } else {
49         cpquot = cp;
50         dquote = 1;
51       }
52       continue;
53     } else if (dquote) continue;
54     if (ch == '(') {
55         if (!level) cpcom = cp;
56         level++;
57     } else if (ch == ')') {
58         level--;
59         if (!level)
60           cpcomlast = cp - 2;   /* address@host (name) */
61     } else if (!level) {
62       if (ch == '<') {          /* name <address@host> */
63         cplt = cp - 2;
64         break;
65       } else if (ch == ';') break;      /* address@host ;garbage */
66     }
67   }
68   if (cplt) {                   /* non-comment '<' */
69     cp = cplt;
70     cpfirst = s;
71   } else if (cpquot && cpquotlast >= cpquot) {
72     cpfirst = cpquot;
73     cp = cpquotlast;
74   } else if (cpcom && cpcomlast >= cpcom) {
75     cpfirst = cpcom;
76     cp = cpcomlast;
77   } else {
78     cp = s + l - 1;
79     cpfirst = s;
80   }
81   flagdone = 0;
82   for (;;) {            /* e.g. LWSP <user@host> */
83     while (cpfirst <= cp &&
84         (*cpfirst == ' ' || *cpfirst == '\t' || *cpfirst == '<')) cpfirst++;
85     while (cp >= cpfirst &&
86         (*cp == ' ' || *cp == '\t' || *cp == '\n' || *cp == '>')) cp--;
87     if (cp >= cpfirst || flagdone)
88       break;
89     cp = s + l - 1;
90     cpfirst = s;
91     flagdone = 1;
92   }
93
94   *sout = cpfirst;
95   len = cp - cpfirst + 1;
96   while (cpfirst <= cp) {
97     if (*cpfirst == '@')
98       *cpfirst = '.';
99     cpfirst++;
100   }
101   return len;
102 }
103