]>
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>
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 explict 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
];
81 getname (const char *addrs
)
85 pers
= mbox
= host
= route
= grp
= note
= NULL
;
88 if ((ap
= getadrx (addrs
? addrs
: "")) == NULL
)
91 strncpy (adr
, ap
->text
, sizeof(adr
));
99 if (ap
->err
&& *ap
->err
)
100 strncpy (err
, ap
->err
, sizeof(err
));
107 getm (char *str
, char *dfhost
, int dftype
, int wanthost
, char *eresult
)
114 strcpy (eresult
, err
);
116 if (wanthost
== AD_HOST
)
117 admonish (NULL
, "bad address '%s' - %s", str
, err
);
121 && mbox
== NULL
&& host
== NULL
&& route
== NULL
124 strcpy (eresult
, "null address");
126 if (wanthost
== AD_HOST
)
127 admonish (NULL
, "null address '%s'", str
);
130 if (mbox
== NULL
&& grp
== NULL
) {
132 strcpy (eresult
, "no mailbox in address");
134 if (wanthost
== AD_HOST
)
135 admonish (NULL
, "no mailbox in address '%s'", str
);
139 if (dfhost
== NULL
) {
140 dfhost
= LocalName (0);
144 mp
= (struct mailname
*) calloc ((size_t) 1, sizeof(*mp
));
147 strcpy (eresult
, "insufficient memory to represent address");
149 if (wanthost
== AD_HOST
)
150 adios (NULL
, "insufficient memory to represent address");
155 mp
->m_text
= getcpy (str
);
157 mp
->m_pers
= getcpy (pers
);
160 mp
->m_type
= BADHOST
;
163 mp
->m_gname
= getcpy (grp
);
165 mp
->m_note
= getcpy (note
);
170 mp
->m_mbox
= getcpy (mbox
);
171 mp
->m_host
= getcpy (host
);
173 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
175 if ((pp
= strchr(mbox
, '!'))) {
177 mp
->m_mbox
= getcpy (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
= getcpy (route
);
200 mp
->m_gname
= getcpy (grp
);
202 mp
->m_note
= getcpy (note
);
209 mnfree (struct mailname
*mp
)
233 #define empty(s) ((s) ? (s) : "")
236 auxformat (struct mailname
*mp
, int extras
)
238 static char addr
[BUFSIZ
];
239 static char buffer
[BUFSIZ
];
242 strncpy (addr
, mp
->m_mbox
? mp
->m_mbox
: "", sizeof(addr
));
245 if (mp
->m_type
!= UUCPHOST
) {
247 snprintf (addr
, sizeof(addr
), "%s%s@%s", empty(mp
->m_path
),
248 empty(mp
->m_mbox
), mp
->m_host
);
249 else snprintf (addr
, sizeof(addr
), "%s%s", empty(mp
->m_path
),
252 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
257 if (mp
->m_pers
|| mp
->m_path
) {
259 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
260 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
263 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
264 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
269 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
271 strncpy (buffer
, addr
, sizeof(buffer
));
278 #define W_MBEG 0x0001
279 #define W_MEND 0x0002
280 #define W_MBOX (W_MBEG | W_MEND)
281 #define W_HBEG 0x0004
282 #define W_HEND 0x0008
283 #define W_HOST (W_HBEG | W_HEND)
284 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
287 * Check if this is my address
291 ismymbox (struct mailname
*np
)
299 static char *am
= NULL
;
300 static struct mailname mq
;
301 static int localmailbox
= 0;
304 * If this is the first call, initialize
305 * list of alternate mailboxes.
309 mq
.m_mbox
= getusername ();
311 if ((am
= context_find ("local-mailbox"))) {
315 if ((cp
= getname(am
)) == NULL
) {
316 admonish (NULL
, "Unable to find address in local-mailbox");
320 if ((mq
.m_next
= getm (cp
, NULL
, 0, AD_NAME
, NULL
)) == NULL
) {
321 admonish (NULL
, "invalid entry in local-mailbox: %s", cp
);
326 * Sigh, it turns out that the address parser gets messed up
327 * if you don't call getname() until it returns NULL.
330 while ((cp
= getname(am
)) != NULL
)
334 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
337 mp
= mq
.m_next
? mq
.m_next
: &mq
;
339 while ((cp
= getname (am
))) {
340 if ((mp
->m_next
= getm (cp
, NULL
, 0, AD_NAME
, NULL
)) == NULL
) {
341 admonish (NULL
, "illegal address: %s", cp
);
346 if (*mp
->m_mbox
== '*') {
347 mp
->m_type
|= W_MBEG
;
350 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
351 mp
->m_type
|= W_MEND
;
355 if (*mp
->m_host
== '*') {
356 mp
->m_type
|= W_HBEG
;
359 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
360 mp
->m_type
|= W_HEND
;
367 advise (NULL
, "please fix the %s: entry in your %s file",
368 "alternate-mailboxes", mh_profile
);
371 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
372 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
373 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
374 "mbox=\"%s\" host=\"%s\" %s\n",
375 mp
->m_text
? mp
->m_text
: "", mp
->m_mbox
,
376 mp
->m_host
? mp
->m_host
: "",
377 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
383 if (np
== NULL
) /* XXX */
387 * Don't perform this "local" test if we have a Local-Mailbox set
391 switch (np
->m_type
) {
393 len
= strlen (cp
= LocalName (0));
394 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
399 if (strcasecmp (np
->m_host
, SystemName()))
403 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
412 * Now scan through list of alternate
413 * mailboxes, and check for a match.
415 for (mp
= &mq
; mp
->m_next
;) {
418 continue; if ((len
= strlen (cp
= np
->m_mbox
))
419 < (i
= strlen (pp
= mp
->m_mbox
)))
421 switch (mp
->m_type
& W_MBOX
) {
423 if (strcasecmp (cp
, pp
))
427 if (strcasecmp (cp
+ len
- i
, pp
))
434 case W_MBEG
| W_MEND
:
435 if (stringdex (pp
, cp
) < 0)
442 if (np
->m_host
== NULL
)
444 if ((len
= strlen (cp
= np
->m_host
))
445 < (i
= strlen (pp
= mp
->m_host
)))
447 switch (mp
->m_type
& W_HOST
) {
449 if (strcasecmp (cp
, pp
))
453 if (strcasecmp (cp
+ len
- i
, pp
))
460 case W_HBEG
| W_HEND
:
461 if (stringdex (pp
, cp
) < 0)