]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
669572a59d33dccf56351eacedc1cdd593ae2914
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.
11 #include "context_find.h"
13 #include "h/addrsbr.h"
18 /* High level parsing of addresses:
20 The routines in sbr/mf.c parse the syntactic representations of
21 addresses. The routines in sbr/addrsbr.c associate semantics with those
24 The comments below are left in for historical purposes; DUMB and
25 REALLYDUMB are now the default in the code.
27 If #ifdef DUMB is in effect, a full 822-style parser is called
28 for syntax recognition. This breaks each address into its components.
29 Note however that no semantics are assumed about the parts or their
30 totality. This means that implicit hostnames aren't made explicit,
31 and explicit hostnames aren't expanded to their "official" representations.
33 If DUMB is not in effect, then this module does some
34 high-level thinking about what the addresses are.
38 string%<uucp>@<local> -> string
40 2. for non-MMDF systems:
42 string@host.<uucp> -> host!string
44 3. for any system, an address interpreted relative to the local host:
46 string@<uucp> -> string
48 For cases (1) and (3) above, the leftmost host is extracted. If it's not
49 present, the local host is used. If the tests above fail, the address is
50 considered to be a real 822-style address.
52 If an explicit host is not present, then MH checks for a bang to indicate
53 an explicit UUCP-style address. If so, this is noted. If not, the host is
54 defaulted, typically to the local host. The lack of an explicit host is
57 If an explicit 822-style host is present, then MH checks to see if it
58 can expand this to the official name for the host. If the hostname is
59 unknown, the address is so typed.
61 To summarize, when we're all done, here's what MH knows about the address:
63 DUMB - type: local, uucp, or network
64 host: not locally defaulted, not explicitly expanded
67 other - type: local, uucp, network, unknown
73 static char *pers
= NULL
;
74 static char *mbox
= NULL
;
75 static char *host
= NULL
;
76 static char *route
= NULL
;
77 static char *grp
= NULL
;
78 static char *note
= NULL
;
79 static char err
[BUFSIZ
];
80 static char adr
[BUFSIZ
];
91 getname (const char *addrs
)
94 pers
= mbox
= host
= route
= grp
= note
= NULL
;
97 if ((ap
= getadrx (FENDNULL(addrs
), eai
)) == NULL
) {
101 strncpy (adr
, ap
->text
, sizeof(adr
));
109 if (ap
->err
&& *ap
->err
)
110 strncpy (err
, ap
->err
, sizeof(err
));
117 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
124 strncpy (eresult
, err
, eresultsize
);
125 eresult
[eresultsize
- 1] = '\0';
130 && mbox
== NULL
&& host
== NULL
&& route
== NULL
133 strncpy (eresult
, "null address", eresultsize
);
134 eresult
[eresultsize
- 1] = '\0';
138 if (mbox
== NULL
&& grp
== NULL
) {
140 strncpy (eresult
, "no mailbox in address", eresultsize
);
141 eresult
[eresultsize
- 1] = '\0';
146 if (dfhost
== NULL
) {
147 dfhost
= LocalName (0);
153 mp
->m_text
= getcpy (str
);
155 mp
->m_pers
= mh_xstrdup(pers
);
158 mp
->m_type
= BADHOST
;
161 mp
->m_gname
= getcpy (grp
);
163 mp
->m_note
= mh_xstrdup(note
);
168 mp
->m_mbox
= getcpy (mbox
);
169 mp
->m_host
= mh_xstrdup(host
);
171 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
173 if ((pp
= strchr(mbox
, '!'))) {
175 mp
->m_mbox
= mh_xstrdup(pp
);
176 mp
->m_host
= getcpy (mbox
);
177 mp
->m_type
= UUCPHOST
;
180 mp
->m_mbox
= getcpy (mbox
);
181 if (route
== NULL
&& dftype
== LOCALHOST
) {
185 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
186 mp
->m_type
= route
? NETHOST
: dftype
;
191 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
192 to support wild-card matching. */
195 mp
->m_path
= mh_xstrdup(route
);
198 mp
->m_gname
= mh_xstrdup(grp
);
200 mp
->m_note
= mh_xstrdup(note
);
207 mnfree (struct mailname
*mp
)
225 auxformat (struct mailname
*mp
, int extras
)
227 static char addr
[BUFSIZ
];
228 static char buffer
[BUFSIZ
];
231 strncpy (addr
, FENDNULL(mp
->m_mbox
), sizeof(addr
));
232 else if (mp
->m_type
!= UUCPHOST
) {
234 snprintf (addr
, sizeof(addr
), "%s%s@%s", FENDNULL(mp
->m_path
),
235 FENDNULL(mp
->m_mbox
), mp
->m_host
);
236 else snprintf (addr
, sizeof(addr
), "%s%s", FENDNULL(mp
->m_path
),
237 FENDNULL(mp
->m_mbox
));
239 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
244 if (mp
->m_pers
|| mp
->m_path
) {
246 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
247 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
250 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
251 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
253 } else if (mp
->m_note
)
254 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
256 strncpy (buffer
, addr
, sizeof(buffer
));
263 #define W_MBEG 0x0001
264 #define W_MEND 0x0002
265 #define W_MBOX (W_MBEG | W_MEND)
266 #define W_HBEG 0x0004
267 #define W_HEND 0x0008
268 #define W_HOST (W_HBEG | W_HEND)
269 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
272 * Check if this is my address
276 ismymbox (struct mailname
*np
)
284 static char *am
= NULL
;
285 static struct mailname mq
;
286 static bool localmailbox
;
289 * If this is the first call, initialize
290 * list of alternate mailboxes.
294 mq
.m_mbox
= getusername ();
296 if ((am
= context_find ("local-mailbox"))) {
300 if ((cp
= getname(am
)) == NULL
) {
301 inform("Unable to find address in local-mailbox, continuing...");
305 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
306 inform("invalid entry in local-mailbox: %s, continuing...", cp
);
310 /* Sigh, it turns out that the address parser gets messed up
311 * if you don't call getname() until it returns NULL. */
312 while (getname(am
) != NULL
)
316 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
319 mp
= mq
.m_next
? mq
.m_next
: &mq
;
321 while ((cp
= getname (am
))) {
322 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
323 inform("illegal address: %s, continuing...", cp
);
328 if (*mp
->m_mbox
== '*') {
329 mp
->m_type
|= W_MBEG
;
332 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
333 mp
->m_type
|= W_MEND
;
337 if (*mp
->m_host
== '*') {
338 mp
->m_type
|= W_HBEG
;
341 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
342 mp
->m_type
|= W_HEND
;
349 inform("please fix the %s: entry in your %s file",
350 "alternate-mailboxes", mh_profile
);
353 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
354 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
355 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
356 "mbox=\"%s\" host=\"%s\" %s\n",
357 FENDNULL(mp
->m_text
), mp
->m_mbox
,
358 FENDNULL(mp
->m_host
),
359 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
365 if (np
== NULL
) /* XXX */
369 * Don't perform this "local" test if we have a Local-Mailbox set
373 switch (np
->m_type
) {
375 len
= strlen (cp
= LocalName (0));
376 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
381 if (strcasecmp (np
->m_host
, SystemName()))
386 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
395 * Now scan through list of alternate
396 * mailboxes, and check for a match.
398 for (mp
= &mq
; mp
->m_next
;) {
402 if ((len
= strlen (cp
= np
->m_mbox
))
403 < (i
= strlen (pp
= mp
->m_mbox
)))
405 switch (mp
->m_type
& W_MBOX
) {
407 if (strcasecmp (cp
, pp
))
411 if (strcasecmp (cp
+ len
- i
, pp
))
418 case W_MBEG
| W_MEND
:
419 if (stringdex (pp
, cp
) < 0)
426 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
428 if ((len
= strlen (cp
= np
->m_host
))
429 < (i
= strlen (pp
= mp
->m_host
)))
431 switch (mp
->m_type
& W_HOST
) {
433 if (strcasecmp (cp
, pp
))
437 if (strcasecmp (cp
+ len
- i
, pp
))
444 case W_HBEG
| W_HEND
:
445 if (stringdex (pp
, cp
) < 0)