]>
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);
148 mp
= (struct mailname
*) mh_xcalloc ((size_t) 1, sizeof(*mp
));
151 strncpy (eresult
, "insufficient memory to represent address",
153 eresult
[eresultsize
- 1] = '\0';
159 mp
->m_text
= getcpy (str
);
161 mp
->m_pers
= getcpy (pers
);
164 mp
->m_type
= BADHOST
;
167 mp
->m_gname
= getcpy (grp
);
169 mp
->m_note
= getcpy (note
);
174 mp
->m_mbox
= getcpy (mbox
);
175 mp
->m_host
= getcpy (host
);
177 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
179 if ((pp
= strchr(mbox
, '!'))) {
181 mp
->m_mbox
= getcpy (pp
);
182 mp
->m_host
= getcpy (mbox
);
183 mp
->m_type
= UUCPHOST
;
186 mp
->m_mbox
= getcpy (mbox
);
187 if (route
== NULL
&& dftype
== LOCALHOST
) {
191 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
192 mp
->m_type
= route
? NETHOST
: dftype
;
197 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
198 to support wild-card matching. */
201 mp
->m_path
= getcpy (route
);
204 mp
->m_gname
= getcpy (grp
);
206 mp
->m_note
= getcpy (note
);
213 mnfree (struct mailname
*mp
)
237 #define empty(s) ((s) ? (s) : "")
240 auxformat (struct mailname
*mp
, int extras
)
242 static char addr
[BUFSIZ
];
243 static char buffer
[BUFSIZ
];
246 strncpy (addr
, mp
->m_mbox
? mp
->m_mbox
: "", sizeof(addr
));
249 if (mp
->m_type
!= UUCPHOST
) {
251 snprintf (addr
, sizeof(addr
), "%s%s@%s", empty(mp
->m_path
),
252 empty(mp
->m_mbox
), mp
->m_host
);
253 else snprintf (addr
, sizeof(addr
), "%s%s", empty(mp
->m_path
),
256 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
261 if (mp
->m_pers
|| mp
->m_path
) {
263 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
264 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
267 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
268 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
273 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
275 strncpy (buffer
, addr
, sizeof(buffer
));
282 #define W_MBEG 0x0001
283 #define W_MEND 0x0002
284 #define W_MBOX (W_MBEG | W_MEND)
285 #define W_HBEG 0x0004
286 #define W_HEND 0x0008
287 #define W_HOST (W_HBEG | W_HEND)
288 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
291 * Check if this is my address
295 ismymbox (struct mailname
*np
)
303 static char *am
= NULL
;
304 static struct mailname mq
;
305 static int localmailbox
= 0;
308 * If this is the first call, initialize
309 * list of alternate mailboxes.
313 mq
.m_mbox
= getusername ();
315 if ((am
= context_find ("local-mailbox"))) {
319 if ((cp
= getname(am
)) == NULL
) {
320 admonish (NULL
, "Unable to find address in local-mailbox");
324 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
325 admonish (NULL
, "invalid entry in local-mailbox: %s", cp
);
330 * Sigh, it turns out that the address parser gets messed up
331 * if you don't call getname() until it returns NULL.
334 while ((cp
= getname(am
)) != NULL
)
338 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
341 mp
= mq
.m_next
? mq
.m_next
: &mq
;
343 while ((cp
= getname (am
))) {
344 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
345 admonish (NULL
, "illegal address: %s", cp
);
350 if (*mp
->m_mbox
== '*') {
351 mp
->m_type
|= W_MBEG
;
354 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
355 mp
->m_type
|= W_MEND
;
359 if (*mp
->m_host
== '*') {
360 mp
->m_type
|= W_HBEG
;
363 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
364 mp
->m_type
|= W_HEND
;
371 advise (NULL
, "please fix the %s: entry in your %s file",
372 "alternate-mailboxes", mh_profile
);
375 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
376 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
377 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
378 "mbox=\"%s\" host=\"%s\" %s\n",
379 mp
->m_text
? mp
->m_text
: "", mp
->m_mbox
,
380 mp
->m_host
? mp
->m_host
: "",
381 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
387 if (np
== NULL
) /* XXX */
391 * Don't perform this "local" test if we have a Local-Mailbox set
395 switch (np
->m_type
) {
397 len
= strlen (cp
= LocalName (0));
398 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
403 if (strcasecmp (np
->m_host
, SystemName()))
407 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
416 * Now scan through list of alternate
417 * mailboxes, and check for a match.
419 for (mp
= &mq
; mp
->m_next
;) {
423 if ((len
= strlen (cp
= np
->m_mbox
))
424 < (i
= strlen (pp
= mp
->m_mbox
)))
426 switch (mp
->m_type
& W_MBOX
) {
428 if (strcasecmp (cp
, pp
))
432 if (strcasecmp (cp
+ len
- i
, pp
))
439 case W_MBEG
| W_MEND
:
440 if (stringdex (pp
, cp
) < 0)
447 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
449 if ((len
= strlen (cp
= np
->m_host
))
450 < (i
= strlen (pp
= mp
->m_host
)))
452 switch (mp
->m_type
& W_HOST
) {
454 if (strcasecmp (cp
, pp
))
458 if (strcasecmp (cp
+ len
- i
, pp
))
465 case W_HBEG
| W_HEND
:
466 if (stringdex (pp
, cp
) < 0)