]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
3 * addrsbr.c -- parse addresses 822-style
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
11 #include <h/addrsbr.h>
16 /* High level parsing of addresses:
18 The routines in sbr/mf.c parse the syntactic representations of
19 addresses. The routines in sbr/addrsbr.c associate semantics with those
22 The comments below are left in for historical purposes; DUMB and
23 REALLYDUMB are now the default in the code.
25 If #ifdef DUMB is in effect, a full 822-style parser is called
26 for syntax recongition. This breaks each address into its components.
27 Note however that no semantics are assumed about the parts or their
28 totality. This means that implicit hostnames aren't made explicit,
29 and explicit hostnames aren't expanded to their "official" represenations.
31 If DUMB is not in effect, then this module does some
32 high-level thinking about what the addresses are.
36 string%<uucp>@<local> -> string
38 2. for non-MMDF systems:
40 string@host.<uucp> -> host!string
42 3. for any system, an address interpreted relative to the local host:
44 string@<uucp> -> string
46 For cases (1) and (3) above, the leftmost host is extracted. If it's not
47 present, the local host is used. If the tests above fail, the address is
48 considered to be a real 822-style address.
50 If an explicit host is not present, then MH checks for a bang to indicate
51 an explicit UUCP-style address. If so, this is noted. If not, the host is
52 defaulted, typically to the local host. The lack of an explicit host is
55 If an explicit 822-style host is present, then MH checks to see if it
56 can expand this to the official name for the host. If the hostname is
57 unknown, the address is so typed.
59 To summarize, when we're all done, here's what MH knows about the address:
61 DUMB - type: local, uucp, or network
62 host: not locally defaulted, not explicitly expanded
65 other - type: local, uucp, network, unknown
71 static char *pers
= NULL
;
72 static char *mbox
= NULL
;
73 static char *host
= NULL
;
74 static char *route
= NULL
;
75 static char *grp
= NULL
;
76 static char *note
= NULL
;
77 static char err
[BUFSIZ
];
78 static char adr
[BUFSIZ
];
88 getname (const char *addrs
)
91 pers
= mbox
= host
= route
= grp
= note
= NULL
;
94 if ((ap
= getadrx (addrs
? addrs
: "", eai
)) == NULL
) {
98 strncpy (adr
, ap
->text
, sizeof(adr
));
106 if (ap
->err
&& *ap
->err
)
107 strncpy (err
, ap
->err
, sizeof(err
));
114 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
121 strncpy (eresult
, err
, eresultsize
);
122 eresult
[eresultsize
- 1] = '\0';
127 && mbox
== NULL
&& host
== NULL
&& route
== NULL
130 strncpy (eresult
, "null address", eresultsize
);
131 eresult
[eresultsize
- 1] = '\0';
135 if (mbox
== NULL
&& grp
== NULL
) {
137 strncpy (eresult
, "no mailbox in address", eresultsize
);
138 eresult
[eresultsize
- 1] = '\0';
143 if (dfhost
== NULL
) {
144 dfhost
= LocalName (0);
150 mp
->m_text
= getcpy (str
);
152 mp
->m_pers
= mh_xstrdup(pers
);
155 mp
->m_type
= BADHOST
;
158 mp
->m_gname
= getcpy (grp
);
160 mp
->m_note
= mh_xstrdup(note
);
165 mp
->m_mbox
= getcpy (mbox
);
166 mp
->m_host
= mh_xstrdup(host
);
168 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
170 if ((pp
= strchr(mbox
, '!'))) {
172 mp
->m_mbox
= mh_xstrdup(pp
);
173 mp
->m_host
= getcpy (mbox
);
174 mp
->m_type
= UUCPHOST
;
177 mp
->m_mbox
= getcpy (mbox
);
178 if (route
== NULL
&& dftype
== LOCALHOST
) {
182 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
183 mp
->m_type
= route
? NETHOST
: dftype
;
188 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
189 to support wild-card matching. */
192 mp
->m_path
= mh_xstrdup(route
);
195 mp
->m_gname
= mh_xstrdup(grp
);
197 mp
->m_note
= mh_xstrdup(note
);
204 mnfree (struct mailname
*mp
)
209 mh_xfree(mp
->m_text
);
210 mh_xfree(mp
->m_pers
);
211 mh_xfree(mp
->m_mbox
);
212 mh_xfree(mp
->m_host
);
213 mh_xfree(mp
->m_path
);
214 mh_xfree(mp
->m_gname
);
215 mh_xfree(mp
->m_note
);
221 #define empty(s) ((s) ? (s) : "")
224 auxformat (struct mailname
*mp
, int extras
)
226 static char addr
[BUFSIZ
];
227 static char buffer
[BUFSIZ
];
230 strncpy (addr
, mp
->m_mbox
? mp
->m_mbox
: "", sizeof(addr
));
233 if (mp
->m_type
!= UUCPHOST
) {
235 snprintf (addr
, sizeof(addr
), "%s%s@%s", empty(mp
->m_path
),
236 empty(mp
->m_mbox
), mp
->m_host
);
237 else snprintf (addr
, sizeof(addr
), "%s%s", empty(mp
->m_path
),
240 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
245 if (mp
->m_pers
|| mp
->m_path
) {
247 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
248 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
251 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
252 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
257 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
259 strncpy (buffer
, addr
, sizeof(buffer
));
266 #define W_MBEG 0x0001
267 #define W_MEND 0x0002
268 #define W_MBOX (W_MBEG | W_MEND)
269 #define W_HBEG 0x0004
270 #define W_HEND 0x0008
271 #define W_HOST (W_HBEG | W_HEND)
272 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
275 * Check if this is my address
279 ismymbox (struct mailname
*np
)
287 static char *am
= NULL
;
288 static struct mailname mq
;
289 static int localmailbox
= 0;
292 * If this is the first call, initialize
293 * list of alternate mailboxes.
297 mq
.m_mbox
= getusername ();
299 if ((am
= context_find ("local-mailbox"))) {
303 if ((cp
= getname(am
)) == NULL
) {
304 admonish (NULL
, "Unable to find address in local-mailbox");
308 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
309 admonish (NULL
, "invalid entry in local-mailbox: %s", cp
);
314 * Sigh, it turns out that the address parser gets messed up
315 * if you don't call getname() until it returns NULL.
318 while ((cp
= getname(am
)) != NULL
)
322 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
325 mp
= mq
.m_next
? mq
.m_next
: &mq
;
327 while ((cp
= getname (am
))) {
328 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
329 admonish (NULL
, "illegal address: %s", cp
);
334 if (*mp
->m_mbox
== '*') {
335 mp
->m_type
|= W_MBEG
;
338 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
339 mp
->m_type
|= W_MEND
;
343 if (*mp
->m_host
== '*') {
344 mp
->m_type
|= W_HBEG
;
347 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
348 mp
->m_type
|= W_HEND
;
355 advise (NULL
, "please fix the %s: entry in your %s file",
356 "alternate-mailboxes", mh_profile
);
359 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
360 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
361 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
362 "mbox=\"%s\" host=\"%s\" %s\n",
363 mp
->m_text
? mp
->m_text
: "", mp
->m_mbox
,
364 mp
->m_host
? mp
->m_host
: "",
365 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
371 if (np
== NULL
) /* XXX */
375 * Don't perform this "local" test if we have a Local-Mailbox set
379 switch (np
->m_type
) {
381 len
= strlen (cp
= LocalName (0));
382 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
387 if (strcasecmp (np
->m_host
, SystemName()))
392 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
401 * Now scan through list of alternate
402 * mailboxes, and check for a match.
404 for (mp
= &mq
; mp
->m_next
;) {
408 if ((len
= strlen (cp
= np
->m_mbox
))
409 < (i
= strlen (pp
= mp
->m_mbox
)))
411 switch (mp
->m_type
& W_MBOX
) {
413 if (strcasecmp (cp
, pp
))
417 if (strcasecmp (cp
+ len
- i
, pp
))
424 case W_MBEG
| W_MEND
:
425 if (stringdex (pp
, cp
) < 0)
432 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
434 if ((len
= strlen (cp
= np
->m_host
))
435 < (i
= strlen (pp
= mp
->m_host
)))
437 switch (mp
->m_type
& W_HOST
) {
439 if (strcasecmp (cp
, pp
))
443 if (strcasecmp (cp
+ len
- i
, pp
))
450 case W_HBEG
| W_HEND
:
451 if (stringdex (pp
, cp
) < 0)