Commit | Line | Data |
---|---|---|
f8beb284 MW |
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 |