]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
d3c423e42e88298bab04c1d04d86d6f1b6dd3244
2 * addrsbr.c -- parse addresses 822-style
4 * This code is Copyright (c) 2002, by the authors of nmh. See the
5 * COPYRIGHT file in the root directory of the nmh distribution for
6 * complete copyright information.
10 #include <h/addrsbr.h>
15 /* High level parsing of addresses:
17 The routines in sbr/mf.c parse the syntactic representations of
18 addresses. The routines in sbr/addrsbr.c associate semantics with those
21 The comments below are left in for historical purposes; DUMB and
22 REALLYDUMB are now the default in the code.
24 If #ifdef DUMB is in effect, a full 822-style parser is called
25 for syntax recongition. This breaks each address into its components.
26 Note however that no semantics are assumed about the parts or their
27 totality. This means that implicit hostnames aren't made explicit,
28 and explicit hostnames aren't expanded to their "official" represenations.
30 If DUMB is not in effect, then this module does some
31 high-level thinking about what the addresses are.
35 string%<uucp>@<local> -> string
37 2. for non-MMDF systems:
39 string@host.<uucp> -> host!string
41 3. for any system, an address interpreted relative to the local host:
43 string@<uucp> -> string
45 For cases (1) and (3) above, the leftmost host is extracted. If it's not
46 present, the local host is used. If the tests above fail, the address is
47 considered to be a real 822-style address.
49 If an explicit host is not present, then MH checks for a bang to indicate
50 an explicit UUCP-style address. If so, this is noted. If not, the host is
51 defaulted, typically to the local host. The lack of an explicit host is
54 If an explicit 822-style host is present, then MH checks to see if it
55 can expand this to the official name for the host. If the hostname is
56 unknown, the address is so typed.
58 To summarize, when we're all done, here's what MH knows about the address:
60 DUMB - type: local, uucp, or network
61 host: not locally defaulted, not explicitly expanded
64 other - type: local, uucp, network, unknown
70 static char *pers
= NULL
;
71 static char *mbox
= NULL
;
72 static char *host
= NULL
;
73 static char *route
= NULL
;
74 static char *grp
= NULL
;
75 static char *note
= NULL
;
76 static char err
[BUFSIZ
];
77 static char adr
[BUFSIZ
];
87 getname (const char *addrs
)
90 pers
= mbox
= host
= route
= grp
= note
= NULL
;
93 if ((ap
= getadrx (addrs
? addrs
: "", eai
)) == NULL
) {
97 strncpy (adr
, ap
->text
, sizeof(adr
));
105 if (ap
->err
&& *ap
->err
)
106 strncpy (err
, ap
->err
, sizeof(err
));
113 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
120 strncpy (eresult
, err
, eresultsize
);
121 eresult
[eresultsize
- 1] = '\0';
126 && mbox
== NULL
&& host
== NULL
&& route
== NULL
129 strncpy (eresult
, "null address", eresultsize
);
130 eresult
[eresultsize
- 1] = '\0';
134 if (mbox
== NULL
&& grp
== NULL
) {
136 strncpy (eresult
, "no mailbox in address", eresultsize
);
137 eresult
[eresultsize
- 1] = '\0';
142 if (dfhost
== NULL
) {
143 dfhost
= LocalName (0);
149 mp
->m_text
= getcpy (str
);
151 mp
->m_pers
= mh_xstrdup(pers
);
154 mp
->m_type
= BADHOST
;
157 mp
->m_gname
= getcpy (grp
);
159 mp
->m_note
= mh_xstrdup(note
);
164 mp
->m_mbox
= getcpy (mbox
);
165 mp
->m_host
= mh_xstrdup(host
);
167 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
169 if ((pp
= strchr(mbox
, '!'))) {
171 mp
->m_mbox
= mh_xstrdup(pp
);
172 mp
->m_host
= getcpy (mbox
);
173 mp
->m_type
= UUCPHOST
;
176 mp
->m_mbox
= getcpy (mbox
);
177 if (route
== NULL
&& dftype
== LOCALHOST
) {
181 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
182 mp
->m_type
= route
? NETHOST
: dftype
;
187 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
188 to support wild-card matching. */
191 mp
->m_path
= mh_xstrdup(route
);
194 mp
->m_gname
= mh_xstrdup(grp
);
196 mp
->m_note
= mh_xstrdup(note
);
203 mnfree (struct mailname
*mp
)
208 mh_xfree(mp
->m_text
);
209 mh_xfree(mp
->m_pers
);
210 mh_xfree(mp
->m_mbox
);
211 mh_xfree(mp
->m_host
);
212 mh_xfree(mp
->m_path
);
213 mh_xfree(mp
->m_gname
);
214 mh_xfree(mp
->m_note
);
220 #define empty(s) ((s) ? (s) : "")
223 auxformat (struct mailname
*mp
, int extras
)
225 static char addr
[BUFSIZ
];
226 static char buffer
[BUFSIZ
];
229 strncpy (addr
, mp
->m_mbox
? mp
->m_mbox
: "", sizeof(addr
));
232 if (mp
->m_type
!= UUCPHOST
) {
234 snprintf (addr
, sizeof(addr
), "%s%s@%s", empty(mp
->m_path
),
235 empty(mp
->m_mbox
), mp
->m_host
);
236 else snprintf (addr
, sizeof(addr
), "%s%s", empty(mp
->m_path
),
239 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
244 if (mp
->m_pers
|| mp
->m_path
) {
246 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
247 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
250 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
251 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
256 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
258 strncpy (buffer
, addr
, sizeof(buffer
));
265 #define W_MBEG 0x0001
266 #define W_MEND 0x0002
267 #define W_MBOX (W_MBEG | W_MEND)
268 #define W_HBEG 0x0004
269 #define W_HEND 0x0008
270 #define W_HOST (W_HBEG | W_HEND)
271 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
274 * Check if this is my address
278 ismymbox (struct mailname
*np
)
286 static char *am
= NULL
;
287 static struct mailname mq
;
288 static int localmailbox
= 0;
291 * If this is the first call, initialize
292 * list of alternate mailboxes.
296 mq
.m_mbox
= getusername ();
298 if ((am
= context_find ("local-mailbox"))) {
302 if ((cp
= getname(am
)) == NULL
) {
303 inform("Unable to find address in local-mailbox, continuing...");
307 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
308 inform("invalid entry in local-mailbox: %s, continuing...", cp
);
312 /* Sigh, it turns out that the address parser gets messed up
313 * if you don't call getname() until it returns NULL. */
314 while (getname(am
) != NULL
)
318 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
321 mp
= mq
.m_next
? mq
.m_next
: &mq
;
323 while ((cp
= getname (am
))) {
324 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
325 inform("illegal address: %s, continuing...", cp
);
330 if (*mp
->m_mbox
== '*') {
331 mp
->m_type
|= W_MBEG
;
334 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
335 mp
->m_type
|= W_MEND
;
339 if (*mp
->m_host
== '*') {
340 mp
->m_type
|= W_HBEG
;
343 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
344 mp
->m_type
|= W_HEND
;
351 inform("please fix the %s: entry in your %s file",
352 "alternate-mailboxes", mh_profile
);
355 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
356 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
357 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
358 "mbox=\"%s\" host=\"%s\" %s\n",
359 mp
->m_text
? mp
->m_text
: "", mp
->m_mbox
,
360 mp
->m_host
? mp
->m_host
: "",
361 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
367 if (np
== NULL
) /* XXX */
371 * Don't perform this "local" test if we have a Local-Mailbox set
375 switch (np
->m_type
) {
377 len
= strlen (cp
= LocalName (0));
378 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
383 if (strcasecmp (np
->m_host
, SystemName()))
388 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
397 * Now scan through list of alternate
398 * mailboxes, and check for a match.
400 for (mp
= &mq
; mp
->m_next
;) {
404 if ((len
= strlen (cp
= np
->m_mbox
))
405 < (i
= strlen (pp
= mp
->m_mbox
)))
407 switch (mp
->m_type
& W_MBOX
) {
409 if (strcasecmp (cp
, pp
))
413 if (strcasecmp (cp
+ len
- i
, pp
))
420 case W_MBEG
| W_MEND
:
421 if (stringdex (pp
, cp
) < 0)
428 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
430 if ((len
= strlen (cp
= np
->m_host
))
431 < (i
= strlen (pp
= mp
->m_host
)))
433 switch (mp
->m_type
& W_HOST
) {
435 if (strcasecmp (cp
, pp
))
439 if (strcasecmp (cp
+ len
- i
, pp
))
446 case W_HBEG
| W_HEND
:
447 if (stringdex (pp
, cp
) < 0)