]>
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 explict 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
];
82 getname (const char *addrs
)
86 pers
= mbox
= host
= route
= grp
= note
= NULL
;
89 if ((ap
= getadrx (addrs
? addrs
: "")) == NULL
)
92 strncpy (adr
, ap
->text
, sizeof(adr
));
100 if (ap
->err
&& *ap
->err
)
101 strncpy (err
, ap
->err
, sizeof(err
));
108 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
115 strncpy (eresult
, err
, eresultsize
);
116 eresult
[eresultsize
- 1] = '\0';
121 && mbox
== NULL
&& host
== NULL
&& route
== NULL
124 strncpy (eresult
, "null address", eresultsize
);
125 eresult
[eresultsize
- 1] = '\0';
129 if (mbox
== NULL
&& grp
== NULL
) {
131 strncpy (eresult
, "no mailbox in address", eresultsize
);
132 eresult
[eresultsize
- 1] = '\0';
137 if (dfhost
== NULL
) {
138 dfhost
= LocalName (0);
142 mp
= (struct mailname
*) mh_xcalloc ((size_t) 1, sizeof(*mp
));
145 strncpy (eresult
, "insufficient memory to represent address",
147 eresult
[eresultsize
- 1] = '\0';
153 mp
->m_text
= getcpy (str
);
155 mp
->m_pers
= getcpy (pers
);
158 mp
->m_type
= BADHOST
;
161 mp
->m_gname
= getcpy (grp
);
163 mp
->m_note
= getcpy (note
);
168 mp
->m_mbox
= getcpy (mbox
);
169 mp
->m_host
= getcpy (host
);
171 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
173 if ((pp
= strchr(mbox
, '!'))) {
175 mp
->m_mbox
= getcpy (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
= getcpy (route
);
198 mp
->m_gname
= getcpy (grp
);
200 mp
->m_note
= getcpy (note
);
207 mnfree (struct mailname
*mp
)
231 #define empty(s) ((s) ? (s) : "")
234 auxformat (struct mailname
*mp
, int extras
)
236 static char addr
[BUFSIZ
];
237 static char buffer
[BUFSIZ
];
240 strncpy (addr
, mp
->m_mbox
? mp
->m_mbox
: "", sizeof(addr
));
243 if (mp
->m_type
!= UUCPHOST
) {
245 snprintf (addr
, sizeof(addr
), "%s%s@%s", empty(mp
->m_path
),
246 empty(mp
->m_mbox
), mp
->m_host
);
247 else snprintf (addr
, sizeof(addr
), "%s%s", empty(mp
->m_path
),
250 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
255 if (mp
->m_pers
|| mp
->m_path
) {
257 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
258 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
261 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
262 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
267 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
269 strncpy (buffer
, addr
, sizeof(buffer
));
276 #define W_MBEG 0x0001
277 #define W_MEND 0x0002
278 #define W_MBOX (W_MBEG | W_MEND)
279 #define W_HBEG 0x0004
280 #define W_HEND 0x0008
281 #define W_HOST (W_HBEG | W_HEND)
282 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
285 * Check if this is my address
289 ismymbox (struct mailname
*np
)
297 static char *am
= NULL
;
298 static struct mailname mq
;
299 static int localmailbox
= 0;
302 * If this is the first call, initialize
303 * list of alternate mailboxes.
307 mq
.m_mbox
= getusername ();
309 if ((am
= context_find ("local-mailbox"))) {
313 if ((cp
= getname(am
)) == NULL
) {
314 admonish (NULL
, "Unable to find address in local-mailbox");
318 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
319 admonish (NULL
, "invalid entry in local-mailbox: %s", cp
);
324 * Sigh, it turns out that the address parser gets messed up
325 * if you don't call getname() until it returns NULL.
328 while ((cp
= getname(am
)) != NULL
)
332 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
335 mp
= mq
.m_next
? mq
.m_next
: &mq
;
337 while ((cp
= getname (am
))) {
338 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
339 admonish (NULL
, "illegal address: %s", cp
);
344 if (*mp
->m_mbox
== '*') {
345 mp
->m_type
|= W_MBEG
;
348 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
349 mp
->m_type
|= W_MEND
;
353 if (*mp
->m_host
== '*') {
354 mp
->m_type
|= W_HBEG
;
357 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
358 mp
->m_type
|= W_HEND
;
365 advise (NULL
, "please fix the %s: entry in your %s file",
366 "alternate-mailboxes", mh_profile
);
369 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
370 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
371 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
372 "mbox=\"%s\" host=\"%s\" %s\n",
373 mp
->m_text
? mp
->m_text
: "", mp
->m_mbox
,
374 mp
->m_host
? mp
->m_host
: "",
375 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
381 if (np
== NULL
) /* XXX */
385 * Don't perform this "local" test if we have a Local-Mailbox set
389 switch (np
->m_type
) {
391 len
= strlen (cp
= LocalName (0));
392 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
397 if (strcasecmp (np
->m_host
, SystemName()))
401 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
410 * Now scan through list of alternate
411 * mailboxes, and check for a match.
413 for (mp
= &mq
; mp
->m_next
;) {
416 continue; if ((len
= strlen (cp
= np
->m_mbox
))
417 < (i
= strlen (pp
= mp
->m_mbox
)))
419 switch (mp
->m_type
& W_MBOX
) {
421 if (strcasecmp (cp
, pp
))
425 if (strcasecmp (cp
+ len
- i
, pp
))
432 case W_MBEG
| W_MEND
:
433 if (stringdex (pp
, cp
) < 0)
440 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
442 if ((len
= strlen (cp
= np
->m_host
))
443 < (i
= strlen (pp
= mp
->m_host
)))
445 switch (mp
->m_type
& W_HOST
) {
447 if (strcasecmp (cp
, pp
))
451 if (strcasecmp (cp
+ len
- i
, pp
))
458 case W_HBEG
| W_HEND
:
459 if (stringdex (pp
, cp
) < 0)