| 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 | |