]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
b752797657b76253772f6edcfaee0c1c86a1d4d9
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.
13 #include "context_find.h"
15 #include "h/addrsbr.h"
20 /* High level parsing of addresses:
22 The routines in sbr/mf.c parse the syntactic representations of
23 addresses. The routines in sbr/addrsbr.c associate semantics with those
26 The comments below are left in for historical purposes; DUMB and
27 REALLYDUMB are now the default in the code.
29 If #ifdef DUMB is in effect, a full 822-style parser is called
30 for syntax recognition. This breaks each address into its components.
31 Note however that no semantics are assumed about the parts or their
32 totality. This means that implicit hostnames aren't made explicit,
33 and explicit hostnames aren't expanded to their "official" representations.
35 If DUMB is not in effect, then this module does some
36 high-level thinking about what the addresses are.
40 string%<uucp>@<local> -> string
42 2. for non-MMDF systems:
44 string@host.<uucp> -> host!string
46 3. for any system, an address interpreted relative to the local host:
48 string@<uucp> -> string
50 For cases (1) and (3) above, the leftmost host is extracted. If it's not
51 present, the local host is used. If the tests above fail, the address is
52 considered to be a real 822-style address.
54 If an explicit host is not present, then MH checks for a bang to indicate
55 an explicit UUCP-style address. If so, this is noted. If not, the host is
56 defaulted, typically to the local host. The lack of an explicit host is
59 If an explicit 822-style host is present, then MH checks to see if it
60 can expand this to the official name for the host. If the hostname is
61 unknown, the address is so typed.
63 To summarize, when we're all done, here's what MH knows about the address:
65 DUMB - type: local, uucp, or network
66 host: not locally defaulted, not explicitly expanded
69 other - type: local, uucp, network, unknown
75 static char *pers
= NULL
;
76 static char *mbox
= NULL
;
77 static char *host
= NULL
;
78 static char *route
= NULL
;
79 static char *grp
= NULL
;
80 static char *note
= NULL
;
81 static char err
[BUFSIZ
];
82 static char adr
[BUFSIZ
];
93 getname (const char *addrs
)
96 pers
= mbox
= host
= route
= grp
= note
= NULL
;
99 if ((ap
= getadrx (FENDNULL(addrs
), eai
)) == NULL
) {
103 strncpy (adr
, ap
->text
, sizeof(adr
));
111 if (ap
->err
&& *ap
->err
)
112 strncpy (err
, ap
->err
, sizeof(err
));
119 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
126 strncpy (eresult
, err
, eresultsize
);
127 eresult
[eresultsize
- 1] = '\0';
132 && mbox
== NULL
&& host
== NULL
&& route
== NULL
135 strncpy (eresult
, "null address", eresultsize
);
136 eresult
[eresultsize
- 1] = '\0';
140 if (mbox
== NULL
&& grp
== NULL
) {
142 strncpy (eresult
, "no mailbox in address", eresultsize
);
143 eresult
[eresultsize
- 1] = '\0';
148 if (dfhost
== NULL
) {
149 dfhost
= LocalName (0);
155 mp
->m_text
= getcpy (str
);
157 mp
->m_pers
= mh_xstrdup(pers
);
160 mp
->m_type
= BADHOST
;
163 mp
->m_gname
= getcpy (grp
);
165 mp
->m_note
= mh_xstrdup(note
);
170 mp
->m_mbox
= getcpy (mbox
);
171 mp
->m_host
= mh_xstrdup(host
);
173 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
175 if ((pp
= strchr(mbox
, '!'))) {
177 mp
->m_mbox
= mh_xstrdup(pp
);
178 mp
->m_host
= getcpy (mbox
);
179 mp
->m_type
= UUCPHOST
;
182 mp
->m_mbox
= getcpy (mbox
);
183 if (route
== NULL
&& dftype
== LOCALHOST
) {
187 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
188 mp
->m_type
= route
? NETHOST
: dftype
;
193 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
194 to support wild-card matching. */
197 mp
->m_path
= mh_xstrdup(route
);
200 mp
->m_gname
= mh_xstrdup(grp
);
202 mp
->m_note
= mh_xstrdup(note
);
209 mnfree (struct mailname
*mp
)
227 auxformat (struct mailname
*mp
, int extras
)
229 static char addr
[BUFSIZ
-4];
230 static char buffer
[BUFSIZ
];
233 strncpy (addr
, FENDNULL(mp
->m_mbox
), sizeof(addr
));
234 else if (mp
->m_type
!= UUCPHOST
) {
236 snprintf (addr
, sizeof(addr
), "%s%s@%s", FENDNULL(mp
->m_path
),
237 FENDNULL(mp
->m_mbox
), mp
->m_host
);
238 else snprintf (addr
, sizeof(addr
), "%s%s", FENDNULL(mp
->m_path
),
239 FENDNULL(mp
->m_mbox
));
241 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
246 if (mp
->m_pers
|| mp
->m_path
) {
248 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
249 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
252 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
253 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
255 } else if (mp
->m_note
)
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 bool localmailbox
;
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 FENDNULL(mp
->m_text
), mp
->m_mbox
,
360 FENDNULL(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)