Import ezmlm-idx 0.40
[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