]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
1 /* addrsbr.c -- parse addresses 822-style
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
14 /* High level parsing of addresses:
16 The routines in sbr/mf.c parse the syntactic representations of
17 addresses. The routines in sbr/addrsbr.c associate semantics with those
20 The comments below are left in for historical purposes; DUMB and
21 REALLYDUMB are now the default in the code.
23 If #ifdef DUMB is in effect, a full 822-style parser is called
24 for syntax recognition. This breaks each address into its components.
25 Note however that no semantics are assumed about the parts or their
26 totality. This means that implicit hostnames aren't made explicit,
27 and explicit hostnames aren't expanded to their "official" representations.
29 If DUMB is not in effect, then this module does some
30 high-level thinking about what the addresses are.
34 string%<uucp>@<local> -> string
36 2. for non-MMDF systems:
38 string@host.<uucp> -> host!string
40 3. for any system, an address interpreted relative to the local host:
42 string@<uucp> -> string
44 For cases (1) and (3) above, the leftmost host is extracted. If it's not
45 present, the local host is used. If the tests above fail, the address is
46 considered to be a real 822-style address.
48 If an explicit host is not present, then MH checks for a bang to indicate
49 an explicit UUCP-style address. If so, this is noted. If not, the host is
50 defaulted, typically to the local host. The lack of an explicit host is
53 If an explicit 822-style host is present, then MH checks to see if it
54 can expand this to the official name for the host. If the hostname is
55 unknown, the address is so typed.
57 To summarize, when we're all done, here's what MH knows about the address:
59 DUMB - type: local, uucp, or network
60 host: not locally defaulted, not explicitly expanded
63 other - type: local, uucp, network, unknown
69 static char *pers
= NULL
;
70 static char *mbox
= NULL
;
71 static char *host
= NULL
;
72 static char *route
= NULL
;
73 static char *grp
= NULL
;
74 static char *note
= NULL
;
75 static char err
[BUFSIZ
];
76 static char adr
[BUFSIZ
];
86 getname (const char *addrs
)
89 pers
= mbox
= host
= route
= grp
= note
= NULL
;
92 if ((ap
= getadrx (FENDNULL(addrs
), eai
)) == NULL
) {
96 strncpy (adr
, ap
->text
, sizeof(adr
));
104 if (ap
->err
&& *ap
->err
)
105 strncpy (err
, ap
->err
, sizeof(err
));
112 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
119 strncpy (eresult
, err
, eresultsize
);
120 eresult
[eresultsize
- 1] = '\0';
125 && mbox
== NULL
&& host
== NULL
&& route
== NULL
128 strncpy (eresult
, "null address", eresultsize
);
129 eresult
[eresultsize
- 1] = '\0';
133 if (mbox
== NULL
&& grp
== NULL
) {
135 strncpy (eresult
, "no mailbox in address", eresultsize
);
136 eresult
[eresultsize
- 1] = '\0';
141 if (dfhost
== NULL
) {
142 dfhost
= LocalName (0);
148 mp
->m_text
= getcpy (str
);
150 mp
->m_pers
= mh_xstrdup(pers
);
153 mp
->m_type
= BADHOST
;
156 mp
->m_gname
= getcpy (grp
);
158 mp
->m_note
= mh_xstrdup(note
);
163 mp
->m_mbox
= getcpy (mbox
);
164 mp
->m_host
= mh_xstrdup(host
);
166 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
168 if ((pp
= strchr(mbox
, '!'))) {
170 mp
->m_mbox
= mh_xstrdup(pp
);
171 mp
->m_host
= getcpy (mbox
);
172 mp
->m_type
= UUCPHOST
;
175 mp
->m_mbox
= getcpy (mbox
);
176 if (route
== NULL
&& dftype
== LOCALHOST
) {
180 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
181 mp
->m_type
= route
? NETHOST
: dftype
;
186 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
187 to support wild-card matching. */
190 mp
->m_path
= mh_xstrdup(route
);
193 mp
->m_gname
= mh_xstrdup(grp
);
195 mp
->m_note
= mh_xstrdup(note
);
202 mnfree (struct mailname
*mp
)
220 auxformat (struct mailname
*mp
, int extras
)
222 static char addr
[BUFSIZ
];
223 static char buffer
[BUFSIZ
];
226 strncpy (addr
, FENDNULL(mp
->m_mbox
), sizeof(addr
));
227 else if (mp
->m_type
!= UUCPHOST
) {
229 snprintf (addr
, sizeof(addr
), "%s%s@%s", FENDNULL(mp
->m_path
),
230 FENDNULL(mp
->m_mbox
), mp
->m_host
);
231 else snprintf (addr
, sizeof(addr
), "%s%s", FENDNULL(mp
->m_path
),
232 FENDNULL(mp
->m_mbox
));
234 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
239 if (mp
->m_pers
|| mp
->m_path
) {
241 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
242 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
245 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
246 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
248 } else if (mp
->m_note
)
249 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
251 strncpy (buffer
, addr
, sizeof(buffer
));
258 #define W_MBEG 0x0001
259 #define W_MEND 0x0002
260 #define W_MBOX (W_MBEG | W_MEND)
261 #define W_HBEG 0x0004
262 #define W_HEND 0x0008
263 #define W_HOST (W_HBEG | W_HEND)
264 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
267 * Check if this is my address
271 ismymbox (struct mailname
*np
)
279 static char *am
= NULL
;
280 static struct mailname mq
;
281 static int localmailbox
= 0;
284 * If this is the first call, initialize
285 * list of alternate mailboxes.
289 mq
.m_mbox
= getusername ();
291 if ((am
= context_find ("local-mailbox"))) {
295 if ((cp
= getname(am
)) == NULL
) {
296 inform("Unable to find address in local-mailbox, continuing...");
300 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
301 inform("invalid entry in local-mailbox: %s, continuing...", cp
);
305 /* Sigh, it turns out that the address parser gets messed up
306 * if you don't call getname() until it returns NULL. */
307 while (getname(am
) != NULL
)
311 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
314 mp
= mq
.m_next
? mq
.m_next
: &mq
;
316 while ((cp
= getname (am
))) {
317 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
318 inform("illegal address: %s, continuing...", cp
);
323 if (*mp
->m_mbox
== '*') {
324 mp
->m_type
|= W_MBEG
;
327 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
328 mp
->m_type
|= W_MEND
;
332 if (*mp
->m_host
== '*') {
333 mp
->m_type
|= W_HBEG
;
336 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
337 mp
->m_type
|= W_HEND
;
344 inform("please fix the %s: entry in your %s file",
345 "alternate-mailboxes", mh_profile
);
348 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
349 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
350 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
351 "mbox=\"%s\" host=\"%s\" %s\n",
352 FENDNULL(mp
->m_text
), mp
->m_mbox
,
353 FENDNULL(mp
->m_host
),
354 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
360 if (np
== NULL
) /* XXX */
364 * Don't perform this "local" test if we have a Local-Mailbox set
368 switch (np
->m_type
) {
370 len
= strlen (cp
= LocalName (0));
371 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
376 if (strcasecmp (np
->m_host
, SystemName()))
381 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
390 * Now scan through list of alternate
391 * mailboxes, and check for a match.
393 for (mp
= &mq
; mp
->m_next
;) {
397 if ((len
= strlen (cp
= np
->m_mbox
))
398 < (i
= strlen (pp
= mp
->m_mbox
)))
400 switch (mp
->m_type
& W_MBOX
) {
402 if (strcasecmp (cp
, pp
))
406 if (strcasecmp (cp
+ len
- i
, pp
))
413 case W_MBEG
| W_MEND
:
414 if (stringdex (pp
, cp
) < 0)
421 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
423 if ((len
= strlen (cp
= np
->m_host
))
424 < (i
= strlen (pp
= mp
->m_host
)))
426 switch (mp
->m_type
& W_HOST
) {
428 if (strcasecmp (cp
, pp
))
432 if (strcasecmp (cp
+ len
- i
, pp
))
439 case W_HBEG
| W_HEND
:
440 if (stringdex (pp
, cp
) < 0)