]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
62abfb99cd448cfcb91ce2d96d02eca35584a26e
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.
10 #include "context_find.h"
12 #include "h/addrsbr.h"
17 /* High level parsing of addresses:
19 The routines in sbr/mf.c parse the syntactic representations of
20 addresses. The routines in sbr/addrsbr.c associate semantics with those
23 The comments below are left in for historical purposes; DUMB and
24 REALLYDUMB are now the default in the code.
26 If #ifdef DUMB is in effect, a full 822-style parser is called
27 for syntax recognition. This breaks each address into its components.
28 Note however that no semantics are assumed about the parts or their
29 totality. This means that implicit hostnames aren't made explicit,
30 and explicit hostnames aren't expanded to their "official" representations.
32 If DUMB is not in effect, then this module does some
33 high-level thinking about what the addresses are.
37 string%<uucp>@<local> -> string
39 2. for non-MMDF systems:
41 string@host.<uucp> -> host!string
43 3. for any system, an address interpreted relative to the local host:
45 string@<uucp> -> string
47 For cases (1) and (3) above, the leftmost host is extracted. If it's not
48 present, the local host is used. If the tests above fail, the address is
49 considered to be a real 822-style address.
51 If an explicit host is not present, then MH checks for a bang to indicate
52 an explicit UUCP-style address. If so, this is noted. If not, the host is
53 defaulted, typically to the local host. The lack of an explicit host is
56 If an explicit 822-style host is present, then MH checks to see if it
57 can expand this to the official name for the host. If the hostname is
58 unknown, the address is so typed.
60 To summarize, when we're all done, here's what MH knows about the address:
62 DUMB - type: local, uucp, or network
63 host: not locally defaulted, not explicitly expanded
66 other - type: local, uucp, network, unknown
72 static char *pers
= NULL
;
73 static char *mbox
= NULL
;
74 static char *host
= NULL
;
75 static char *route
= NULL
;
76 static char *grp
= NULL
;
77 static char *note
= NULL
;
78 static char err
[BUFSIZ
];
79 static char adr
[BUFSIZ
];
90 getname (const char *addrs
)
93 pers
= mbox
= host
= route
= grp
= note
= NULL
;
96 if ((ap
= getadrx (FENDNULL(addrs
), eai
)) == NULL
) {
100 strncpy (adr
, ap
->text
, sizeof(adr
));
108 if (ap
->err
&& *ap
->err
)
109 strncpy (err
, ap
->err
, sizeof(err
));
116 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
123 strncpy (eresult
, err
, eresultsize
);
124 eresult
[eresultsize
- 1] = '\0';
129 && mbox
== NULL
&& host
== NULL
&& route
== NULL
132 strncpy (eresult
, "null address", eresultsize
);
133 eresult
[eresultsize
- 1] = '\0';
137 if (mbox
== NULL
&& grp
== NULL
) {
139 strncpy (eresult
, "no mailbox in address", eresultsize
);
140 eresult
[eresultsize
- 1] = '\0';
145 if (dfhost
== NULL
) {
146 dfhost
= LocalName (0);
152 mp
->m_text
= getcpy (str
);
154 mp
->m_pers
= mh_xstrdup(pers
);
157 mp
->m_type
= BADHOST
;
160 mp
->m_gname
= getcpy (grp
);
162 mp
->m_note
= mh_xstrdup(note
);
167 mp
->m_mbox
= getcpy (mbox
);
168 mp
->m_host
= mh_xstrdup(host
);
170 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
172 if ((pp
= strchr(mbox
, '!'))) {
174 mp
->m_mbox
= mh_xstrdup(pp
);
175 mp
->m_host
= getcpy (mbox
);
176 mp
->m_type
= UUCPHOST
;
179 mp
->m_mbox
= getcpy (mbox
);
180 if (route
== NULL
&& dftype
== LOCALHOST
) {
184 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
185 mp
->m_type
= route
? NETHOST
: dftype
;
190 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
191 to support wild-card matching. */
194 mp
->m_path
= mh_xstrdup(route
);
197 mp
->m_gname
= mh_xstrdup(grp
);
199 mp
->m_note
= mh_xstrdup(note
);
206 mnfree (struct mailname
*mp
)
224 auxformat (struct mailname
*mp
, int extras
)
226 static char addr
[BUFSIZ
];
227 static char buffer
[BUFSIZ
];
230 strncpy (addr
, FENDNULL(mp
->m_mbox
), sizeof(addr
));
231 else if (mp
->m_type
!= UUCPHOST
) {
233 snprintf (addr
, sizeof(addr
), "%s%s@%s", FENDNULL(mp
->m_path
),
234 FENDNULL(mp
->m_mbox
), mp
->m_host
);
235 else snprintf (addr
, sizeof(addr
), "%s%s", FENDNULL(mp
->m_path
),
236 FENDNULL(mp
->m_mbox
));
238 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
243 if (mp
->m_pers
|| mp
->m_path
) {
245 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
246 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
249 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
250 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
252 } else if (mp
->m_note
)
253 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
255 strncpy (buffer
, addr
, sizeof(buffer
));
262 #define W_MBEG 0x0001
263 #define W_MEND 0x0002
264 #define W_MBOX (W_MBEG | W_MEND)
265 #define W_HBEG 0x0004
266 #define W_HEND 0x0008
267 #define W_HOST (W_HBEG | W_HEND)
268 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
271 * Check if this is my address
275 ismymbox (struct mailname
*np
)
283 static char *am
= NULL
;
284 static struct mailname mq
;
285 static bool localmailbox
;
288 * If this is the first call, initialize
289 * list of alternate mailboxes.
293 mq
.m_mbox
= getusername ();
295 if ((am
= context_find ("local-mailbox"))) {
299 if ((cp
= getname(am
)) == NULL
) {
300 inform("Unable to find address in local-mailbox, continuing...");
304 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
305 inform("invalid entry in local-mailbox: %s, continuing...", cp
);
309 /* Sigh, it turns out that the address parser gets messed up
310 * if you don't call getname() until it returns NULL. */
311 while (getname(am
) != NULL
)
315 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
318 mp
= mq
.m_next
? mq
.m_next
: &mq
;
320 while ((cp
= getname (am
))) {
321 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
322 inform("illegal address: %s, continuing...", cp
);
327 if (*mp
->m_mbox
== '*') {
328 mp
->m_type
|= W_MBEG
;
331 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
332 mp
->m_type
|= W_MEND
;
336 if (*mp
->m_host
== '*') {
337 mp
->m_type
|= W_HBEG
;
340 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
341 mp
->m_type
|= W_HEND
;
348 inform("please fix the %s: entry in your %s file",
349 "alternate-mailboxes", mh_profile
);
352 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
353 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
354 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
355 "mbox=\"%s\" host=\"%s\" %s\n",
356 FENDNULL(mp
->m_text
), mp
->m_mbox
,
357 FENDNULL(mp
->m_host
),
358 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
364 if (np
== NULL
) /* XXX */
368 * Don't perform this "local" test if we have a Local-Mailbox set
372 switch (np
->m_type
) {
374 len
= strlen (cp
= LocalName (0));
375 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
380 if (strcasecmp (np
->m_host
, SystemName()))
385 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
394 * Now scan through list of alternate
395 * mailboxes, and check for a match.
397 for (mp
= &mq
; mp
->m_next
;) {
401 if ((len
= strlen (cp
= np
->m_mbox
))
402 < (i
= strlen (pp
= mp
->m_mbox
)))
404 switch (mp
->m_type
& W_MBOX
) {
406 if (strcasecmp (cp
, pp
))
410 if (strcasecmp (cp
+ len
- i
, pp
))
417 case W_MBEG
| W_MEND
:
418 if (stringdex (pp
, cp
) < 0)
425 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
427 if ((len
= strlen (cp
= np
->m_host
))
428 < (i
= strlen (pp
= mp
->m_host
)))
430 switch (mp
->m_type
& W_HOST
) {
432 if (strcasecmp (cp
, pp
))
436 if (strcasecmp (cp
+ len
- i
, pp
))
443 case W_HBEG
| W_HEND
:
444 if (stringdex (pp
, cp
) < 0)