]> git.deb.at Git - pkg/abook.git/blob - getname.c
Upload 0.6.1-2 to unstable
[pkg/abook.git] / getname.c
1
2 /*
3  * This code was taken from hypermail http://www.hypermail.org/
4  *
5  * license: GNU GENERAL PUBLIC LICENSE, Version 2
6  *
7  * modified by Jaakko Heinonen <jheinonen@users.sourceforge.net>
8  */
9
10 #include <stdio.h>
11 #include <string.h>
12 #include <ctype.h>
13 /*#include "hypermail.h"*/
14 #include "getname.h"
15 /*#include "setup.h"*/
16
17 /*extern char *set_domainaddr;*/
18 const char *set_domainaddr = "";
19 const int use_domainaddr = 0;
20
21 #define NAMESTRLEN   80
22 #define MAILSTRLEN   80
23
24 #define NONAME      "(no name)"
25 #define NOEMAIL     "(no email)"
26
27 #ifndef FALSE
28 #       define FALSE    0
29 #endif
30
31 #ifndef TRUE
32 #       define TRUE     1
33 #endif
34
35 #define hm_strchr(X, XX) strchr(X, XX)
36 #define strsav(X) ((X == NULL) ? strdup("") : strdup(X))
37
38 /*const int set_iso2022jp = 0;*/
39
40 void
41 strcpymax(char *dest, const char *src, int n)
42 {
43         int i;
44
45         if (n) {
46                 n--;            /* decrease one to allow for the termination byte */
47                 for (i = 0; *src && (i < n); i++)
48                         *dest++ = *src++;
49         }
50         *dest = 0;
51 }
52
53 static int
54 blankstring(char *str)
55 {
56         register char *cp;
57         for (cp = str; *cp; cp++) {
58                 if (*cp != ' ' && *cp != '\t' && *cp != '\r'
59                     && *cp != '\n')
60                         return (0);
61         }
62         return (1);
63 }
64
65 #if 0
66 char *
67 spamify(char *input)
68 {
69         /* we should replace the @-letter in the email
70            address */
71         int newlen = strlen(input) + 4;
72         char *atptr = strchr(input, '@');
73         if (atptr) {
74                 char *newbuf = malloc(newlen);
75                 int index = atptr - input;
76                 /* copy the part before the @ */
77                 memcpy(newbuf, input, index);
78                 /* append _at_ */
79                 memcpy(newbuf + index, "_at_", 4);
80                 /* append the part after the @ */
81                 strcpy(newbuf + index + 4, input + index + 1);
82                 /* correct the pointer and free the old */
83                 free(input);
84                 return newbuf;
85         }
86         /* weird email, bail out */
87         return input;
88 }
89 #endif
90
91 /*
92 ** Grabs the name and email address from a From: header.
93 ** This could get tricky; I've tried to keep it simple.
94 ** Should be able to handle all the addresses below:
95 **
96 **   From: user                   [no @]
97 **   From: kent (Kent Landfield)  [no @ - with comment]
98 **   From: <user@node.domain>     [no text name, use email as text name]
99 **   From: Kent Landfield <kent>  [text name but no @]
100 **   From: (kent)                 [comment - no email address]
101 **   From: "" <kent>              [email address but null comment]
102 **   From:                        [blank From: line]
103 **   From: uu.net!kent            [uucp addresses - no comment]
104 **   From: uu.net!kent (kent)     [uucp addresses - with comment]
105 **   From: "(Joe Bloggs)" <joe@anorg.com>
106 **   From: "Roy T. Fielding" <fielding@kiwi.ics.uci.edu>
107 **   From: kent@localhost
108 **   From: kent@uu.net (Kent Landfield)
109 **   From: (George Burgyan) <gburgyan@cybercon.com>
110 **   From: <gburgyan@cybercon.com> (George Burgyan)
111 **   From:              Kent B. Landfield <kent@landfield.com>
112 **   From:      IN%"fekete+reply@c2.net" 26-JAN-1997 13:28:55.36
113 **   From:      IN%"vicric@panix.com"  "Vicki Richman" 13-AUG-1996 10:54:33.38
114 **   From:      US2RMC::"lwv26@cas.org" "Larry W. Virden, x2487" 22-OCT-1994 09:44:21.44
115 **   From:          Mail Delivery Subsystem <postmaster@igc.apc.org>
116 **   From:          Self <ehasbrouck>
117 **   From:         adam@eden.apana.org.au (Adam Frey)
118 **   From:        faqserv@penguin-lust.mit.edu
119 **   From:    nc0548@freebsd.netcom.com (Mark Hittinger)
120 **   From: "- Pam Greene, one of the *.answers moderators" <pgreene@MIT.EDU>
121 **   From: "Felan shena Thoron'edras" <felan@netcom.com>
122 **   From: David Muir Sharnoff <muir@idiom.com>
123 **   From: A.J.Doherty@reading.ac.uk (Andy Doherty)
124 **   From: Jordan Hubbard                        <jkh@vector.eikon.e-technik.tu-muenchen.de>
125 **   From: ZXPAN%SLACVM.BITNET@MITVMA.MIT.EDU
126 **   From: afs!piz!alf@uu5.psi.com (Alf the Poet)
127 **   From: answers@cp.tn.tudelft.nl ("Moderator *.answers")
128 **   From: mdw%merengue@merengue.oit.unc.edu (Matt Welsh)
129 **   From: bgoffe@whale.st.usm.edu (William L. Goffe)
130 **
131 ** This is an interesting new one (1998-11-26):
132 ** From: <name.hidden@era.ericsson.se>\9bName.Hidden@era.ericsson.se\9c
133 */
134
135 void
136 getname(char *line, char **namep, char **emailp)
137 {
138         int i;
139         int len;
140         char *c;
141         int comment_fnd;
142
143         char email[MAILSTRLEN];
144         char name[NAMESTRLEN];
145
146         len = MAILSTRLEN - 1;
147         comment_fnd = 0;
148
149         /*
150          * Zero out data storage.
151          */
152         memset(email, 0, MAILSTRLEN);
153         memset(name, 0, NAMESTRLEN);
154
155         *namep = NULL;
156         *emailp = NULL;
157
158         /* EMail Processing First:
159            ** First, is there an '@' sign we can use as an anchor ?
160          */
161         if ((c = hm_strchr(line, '@')) == NULL) {
162                 /*
163                    ** No '@' sign here so ...
164                  */
165                 if (strchr(line, '(')) {        /* From: bob (The Big Guy) */
166                         c = strchr(line, ':') + 1;
167                         while (*c == ' ' || *c == '\t')
168                                 c++;
169                         for (i = 0; *c && *c != '(' && *c != ' ' &&
170                              *c != '\t' && *c != '\n' && i < len; c++)
171                                 email[i++] = *c;
172                         email[i] = '\0';
173                 } else if ((c = strchr(line, '<'))) {   /* From: <kent> */
174                         c++;
175                         for (i = 0; *c && *c != '>' && *c != ' ' &&
176                              *c != '\t' && *c != '\n' && i < len; c++)
177                                 email[i++] = *c;
178                         email[i] = '\0';
179                 } else {
180                         /*
181                          *    - check to see if the From: line is blank, (taken care of)
182                          *    - check if From: uu.net!kent formatted line
183                          *    - check if "From: kent" formatted line
184                          */
185                         c = strchr(line, ':') + 1;
186                         while (*c == ' ' || *c == '\t')
187                                 c++;
188                         for (i = 0; *c && *c != ' ' && *c != '\t' &&
189                              *c != '\n' && *c != ',' && i < len; c++)
190                                 email[i++] = *c;
191                         email[i] = '\0';
192
193                 }
194
195                 if (email[0] == '\0')   /* Was it a junk From line ? */
196                         strcpymax(email, NOEMAIL, MAILSTRLEN);
197
198                 else if (use_domainaddr) {
199                         /*
200                          * check if site domainizes addresses
201                          * but don't modify uucp addresses
202                          */
203                         if ((c = strchr(email, '!')) == NULL) {
204                                 strcat(email, "@");
205                                 strcat(email, set_domainaddr);
206                         }
207                 }
208         } else {
209                 while (*c != ' ' && *c != '\t' && *c != '<' && *c != '"' &&
210                        *c != ':')
211                         c--;
212                 c++;
213                 for (i = 0; *c && *c != '>' && *c != ' ' && *c != '\t' &&
214                      *c != '"' && *c != '\n' && *c != ']' && *c != ',' &&
215                      i < len; c++)
216                         email[i++] = *c;
217                 email[i] = '\0';
218         }
219
220         /*
221          * NAME Processing - Boy are there a bunch of funky formats here.
222          *                   No promises... I'll do my best. Let me know
223          *                   what I missed...
224          */
225
226         if (strchr(line, '<')) {
227                 c = strchr(line, ':') + 1;
228                 while (*c == ' ' || *c == '\t')
229                         c++;
230
231                 /* if a comment then just look for the end point */
232
233                 if (*c == '\"') {
234                         int rmparen = 0;
235
236                         ++c;
237                         if (*c == '(') {
238                                 ++c;
239                                 rmparen = 1;
240                         }
241                         for (i = 0, len = NAMESTRLEN - 1;
242                              *c && *c != '\"' && *c != '\n' && i < len;
243                              c++)
244                                 name[i++] = *c;
245
246                         if (rmparen && name[(i - 1)] == ')')
247                                 --i;    /* get rid of "(name-comment)" parens */
248
249                         comment_fnd = 1;
250                 } else if (hm_strchr(line, '(')) {
251                         c = hm_strchr(line, '(') + 1;
252                         if (*c == '"')  /* is there a comment in the comment ? */
253                                 c++;
254                 } else if (*c == '<') { /* Comment may be on the end */
255                         /* From: <bill@celestial.com> Bill Campbell */
256                         c = strchr(line, '>') + 1;
257                         for (i = 0, len = NAMESTRLEN - 1;
258                              *c && *c != '\n' && i < len; c++)
259                                 name[i++] = *c;
260
261                         comment_fnd = 1;
262                 }
263         } else if (strchr(line, '(')) {
264                 c = strchr(line, '(');
265                 c++;
266                 if (*c == '"')  /* is there a comment in the comment ? */
267                         c++;
268                 while (*c == ' ' || *c == '\t')
269                         c++;
270         } else if (strchr(line, '[')) {
271                 c = strchr(line, ':') + 1;
272                 while (*c == ' ' || *c == '\t')
273                         c++;
274
275                 for (i = 0, len = NAMESTRLEN - 1;
276                      *c && *c != '\"' && *c != '[' && *c != '\n'
277                      && i < len; c++)
278                         name[i++] = *c;
279
280                 name[--i] = '\0';
281                 comment_fnd = 1;
282         } else {
283                 /*
284                  * Is there an email address available
285                  * that we can use for the name ?
286                  */
287                 if (!strcmp(email, NOEMAIL))    /* No */
288                         strcpymax(name, NONAME, NAMESTRLEN);
289                 else {
290                         c = email + strlen(email) - 1;
291                         while (isspace((unsigned char) *c))
292                                 *c-- = '\0';
293                         strcpymax(name, email, NAMESTRLEN);     /* Yes */
294                 }
295                 *namep = strsav(name);
296                 *emailp = strsav(email);
297                 return;
298         }
299
300         if (!comment_fnd) {
301                 /*int in_ascii = TRUE, esclen = 0; */
302                 for (i = 0, len = NAMESTRLEN - 1;
303                      *c && *c != '<' && *c != '\"' && *c != ')'
304                      && *c != '(' && *c != '\n' && i < len; c++) {
305                         /*if (set_iso2022jp) {
306                            iso2022_state(c, &in_ascii, &esclen);
307                            if (esclen) {
308                            for (; esclen; esclen--, c++) name[i++] = *c;
309                            for (; in_ascii == FALSE && i < len;
310                            c++, iso2022_state(c, &in_ascii, &esclen)) {
311                            name[i++] = *c;
312                            }
313                            c--;
314                            } else {
315                            name[i++] = *c;
316                            }
317                            } else { */
318                         name[i++] = *c;
319                         /*} */
320                 }
321         }
322
323         if (i > 0 && name[i - 1] == ' ' && (*c == '<' || *c == '('))
324                 name[--i] = '\0';
325         else
326                 name[i] = '\0';
327
328         /*
329          * Is the name string blank ? If so then
330          * force it to get filled with something.
331          */
332         if (blankstring(name))
333                 name[0] = '\0';
334
335         /* Bailing and taking the easy way out... */
336
337         if (name[0] == '\0') {
338                 if (email[0] == '\0')
339                         strcpymax(name, NONAME, NAMESTRLEN);
340                 else
341                         strcpymax(name, email, NAMESTRLEN);
342         }
343
344         /*
345          * need to strip spaces off the end of
346          * the email and name strings
347          */
348
349         c = email + (strlen(email) - 1);
350         while (c > email && isspace((unsigned char) *c))
351                 *c-- = '\0';
352
353         *namep = strsav(name);
354         *emailp = strsav(email);
355 }