]>
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
];
87 getname (const char *addrs
)
90 pers
= mbox
= host
= route
= grp
= note
= NULL
;
93 if ((ap
= getadrx (FENDNULL(addrs
), eai
)) == NULL
) {
97 strncpy (adr
, ap
->text
, sizeof(adr
));
105 if (ap
->err
&& *ap
->err
)
106 strncpy (err
, ap
->err
, sizeof(err
));
113 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
120 strncpy (eresult
, err
, eresultsize
);
121 eresult
[eresultsize
- 1] = '\0';
126 && mbox
== NULL
&& host
== NULL
&& route
== NULL
129 strncpy (eresult
, "null address", eresultsize
);
130 eresult
[eresultsize
- 1] = '\0';
134 if (mbox
== NULL
&& grp
== NULL
) {
136 strncpy (eresult
, "no mailbox in address", eresultsize
);
137 eresult
[eresultsize
- 1] = '\0';
142 if (dfhost
== NULL
) {
143 dfhost
= LocalName (0);
149 mp
->m_text
= getcpy (str
);
151 mp
->m_pers
= mh_xstrdup(pers
);
154 mp
->m_type
= BADHOST
;
157 mp
->m_gname
= getcpy (grp
);
159 mp
->m_note
= mh_xstrdup(note
);
164 mp
->m_mbox
= getcpy (mbox
);
165 mp
->m_host
= mh_xstrdup(host
);
167 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
169 if ((pp
= strchr(mbox
, '!'))) {
171 mp
->m_mbox
= mh_xstrdup(pp
);
172 mp
->m_host
= getcpy (mbox
);
173 mp
->m_type
= UUCPHOST
;
176 mp
->m_mbox
= getcpy (mbox
);
177 if (route
== NULL
&& dftype
== LOCALHOST
) {
181 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
182 mp
->m_type
= route
? NETHOST
: dftype
;
187 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
188 to support wild-card matching. */
191 mp
->m_path
= mh_xstrdup(route
);
194 mp
->m_gname
= mh_xstrdup(grp
);
196 mp
->m_note
= mh_xstrdup(note
);
203 mnfree (struct mailname
*mp
)
221 auxformat (struct mailname
*mp
, int extras
)
223 static char addr
[BUFSIZ
];
224 static char buffer
[BUFSIZ
];
227 strncpy (addr
, FENDNULL(mp
->m_mbox
), sizeof(addr
));
228 else if (mp
->m_type
!= UUCPHOST
) {
230 snprintf (addr
, sizeof(addr
), "%s%s@%s", FENDNULL(mp
->m_path
),
231 FENDNULL(mp
->m_mbox
), mp
->m_host
);
232 else snprintf (addr
, sizeof(addr
), "%s%s", FENDNULL(mp
->m_path
),
233 FENDNULL(mp
->m_mbox
));
235 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
240 if (mp
->m_pers
|| mp
->m_path
) {
242 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
243 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
246 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
247 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
249 } else if (mp
->m_note
)
250 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
252 strncpy (buffer
, addr
, sizeof(buffer
));
259 #define W_MBEG 0x0001
260 #define W_MEND 0x0002
261 #define W_MBOX (W_MBEG | W_MEND)
262 #define W_HBEG 0x0004
263 #define W_HEND 0x0008
264 #define W_HOST (W_HBEG | W_HEND)
265 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
268 * Check if this is my address
272 ismymbox (struct mailname
*np
)
280 static char *am
= NULL
;
281 static struct mailname mq
;
282 static bool localmailbox
;
285 * If this is the first call, initialize
286 * list of alternate mailboxes.
290 mq
.m_mbox
= getusername ();
292 if ((am
= context_find ("local-mailbox"))) {
296 if ((cp
= getname(am
)) == NULL
) {
297 inform("Unable to find address in local-mailbox, continuing...");
301 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
302 inform("invalid entry in local-mailbox: %s, continuing...", cp
);
306 /* Sigh, it turns out that the address parser gets messed up
307 * if you don't call getname() until it returns NULL. */
308 while (getname(am
) != NULL
)
312 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
315 mp
= mq
.m_next
? mq
.m_next
: &mq
;
317 while ((cp
= getname (am
))) {
318 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
319 inform("illegal address: %s, continuing...", cp
);
324 if (*mp
->m_mbox
== '*') {
325 mp
->m_type
|= W_MBEG
;
328 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
329 mp
->m_type
|= W_MEND
;
333 if (*mp
->m_host
== '*') {
334 mp
->m_type
|= W_HBEG
;
337 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
338 mp
->m_type
|= W_HEND
;
345 inform("please fix the %s: entry in your %s file",
346 "alternate-mailboxes", mh_profile
);
349 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
350 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
351 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
352 "mbox=\"%s\" host=\"%s\" %s\n",
353 FENDNULL(mp
->m_text
), mp
->m_mbox
,
354 FENDNULL(mp
->m_host
),
355 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
361 if (np
== NULL
) /* XXX */
365 * Don't perform this "local" test if we have a Local-Mailbox set
369 switch (np
->m_type
) {
371 len
= strlen (cp
= LocalName (0));
372 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
377 if (strcasecmp (np
->m_host
, SystemName()))
382 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
391 * Now scan through list of alternate
392 * mailboxes, and check for a match.
394 for (mp
= &mq
; mp
->m_next
;) {
398 if ((len
= strlen (cp
= np
->m_mbox
))
399 < (i
= strlen (pp
= mp
->m_mbox
)))
401 switch (mp
->m_type
& W_MBOX
) {
403 if (strcasecmp (cp
, pp
))
407 if (strcasecmp (cp
+ len
- i
, pp
))
414 case W_MBEG
| W_MEND
:
415 if (stringdex (pp
, cp
) < 0)
422 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
424 if ((len
= strlen (cp
= np
->m_host
))
425 < (i
= strlen (pp
= mp
->m_host
)))
427 switch (mp
->m_type
& W_HOST
) {
429 if (strcasecmp (cp
, pp
))
433 if (strcasecmp (cp
+ len
- i
, pp
))
440 case W_HBEG
| W_HEND
:
441 if (stringdex (pp
, cp
) < 0)