]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
876ecc1236f636862e3b205c1ec66a9b859df047
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.
12 #include "context_find.h"
14 #include "h/addrsbr.h"
19 /* High level parsing of addresses:
21 The routines in sbr/mf.c parse the syntactic representations of
22 addresses. The routines in sbr/addrsbr.c associate semantics with those
25 The comments below are left in for historical purposes; DUMB and
26 REALLYDUMB are now the default in the code.
28 If #ifdef DUMB is in effect, a full 822-style parser is called
29 for syntax recognition. This breaks each address into its components.
30 Note however that no semantics are assumed about the parts or their
31 totality. This means that implicit hostnames aren't made explicit,
32 and explicit hostnames aren't expanded to their "official" representations.
34 If DUMB is not in effect, then this module does some
35 high-level thinking about what the addresses are.
39 string%<uucp>@<local> -> string
41 2. for non-MMDF systems:
43 string@host.<uucp> -> host!string
45 3. for any system, an address interpreted relative to the local host:
47 string@<uucp> -> string
49 For cases (1) and (3) above, the leftmost host is extracted. If it's not
50 present, the local host is used. If the tests above fail, the address is
51 considered to be a real 822-style address.
53 If an explicit host is not present, then MH checks for a bang to indicate
54 an explicit UUCP-style address. If so, this is noted. If not, the host is
55 defaulted, typically to the local host. The lack of an explicit host is
58 If an explicit 822-style host is present, then MH checks to see if it
59 can expand this to the official name for the host. If the hostname is
60 unknown, the address is so typed.
62 To summarize, when we're all done, here's what MH knows about the address:
64 DUMB - type: local, uucp, or network
65 host: not locally defaulted, not explicitly expanded
68 other - type: local, uucp, network, unknown
74 static char *pers
= NULL
;
75 static char *mbox
= NULL
;
76 static char *host
= NULL
;
77 static char *route
= NULL
;
78 static char *grp
= NULL
;
79 static char *note
= NULL
;
80 static char err
[BUFSIZ
];
81 static char adr
[BUFSIZ
];
92 getname (const char *addrs
)
95 pers
= mbox
= host
= route
= grp
= note
= NULL
;
98 if ((ap
= getadrx (FENDNULL(addrs
), eai
)) == NULL
) {
102 strncpy (adr
, ap
->text
, sizeof(adr
));
110 if (ap
->err
&& *ap
->err
)
111 strncpy (err
, ap
->err
, sizeof(err
));
118 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
125 strncpy (eresult
, err
, eresultsize
);
126 eresult
[eresultsize
- 1] = '\0';
131 && mbox
== NULL
&& host
== NULL
&& route
== NULL
134 strncpy (eresult
, "null address", eresultsize
);
135 eresult
[eresultsize
- 1] = '\0';
139 if (mbox
== NULL
&& grp
== NULL
) {
141 strncpy (eresult
, "no mailbox in address", eresultsize
);
142 eresult
[eresultsize
- 1] = '\0';
147 if (dfhost
== NULL
) {
148 dfhost
= LocalName (0);
154 mp
->m_text
= getcpy (str
);
156 mp
->m_pers
= mh_xstrdup(pers
);
159 mp
->m_type
= BADHOST
;
162 mp
->m_gname
= getcpy (grp
);
164 mp
->m_note
= mh_xstrdup(note
);
169 mp
->m_mbox
= getcpy (mbox
);
170 mp
->m_host
= mh_xstrdup(host
);
172 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
174 if ((pp
= strchr(mbox
, '!'))) {
176 mp
->m_mbox
= mh_xstrdup(pp
);
177 mp
->m_host
= getcpy (mbox
);
178 mp
->m_type
= UUCPHOST
;
181 mp
->m_mbox
= getcpy (mbox
);
182 if (route
== NULL
&& dftype
== LOCALHOST
) {
186 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
187 mp
->m_type
= route
? NETHOST
: dftype
;
192 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
193 to support wild-card matching. */
196 mp
->m_path
= mh_xstrdup(route
);
199 mp
->m_gname
= mh_xstrdup(grp
);
201 mp
->m_note
= mh_xstrdup(note
);
208 mnfree (struct mailname
*mp
)
226 auxformat (struct mailname
*mp
, int extras
)
228 static char addr
[BUFSIZ
];
229 static char buffer
[BUFSIZ
];
232 strncpy (addr
, FENDNULL(mp
->m_mbox
), sizeof(addr
));
233 else if (mp
->m_type
!= UUCPHOST
) {
235 snprintf (addr
, sizeof(addr
), "%s%s@%s", FENDNULL(mp
->m_path
),
236 FENDNULL(mp
->m_mbox
), mp
->m_host
);
237 else snprintf (addr
, sizeof(addr
), "%s%s", FENDNULL(mp
->m_path
),
238 FENDNULL(mp
->m_mbox
));
240 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
245 if (mp
->m_pers
|| mp
->m_path
) {
247 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
248 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
251 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
252 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
254 } else if (mp
->m_note
)
255 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
257 strncpy (buffer
, addr
, sizeof(buffer
));
264 #define W_MBEG 0x0001
265 #define W_MEND 0x0002
266 #define W_MBOX (W_MBEG | W_MEND)
267 #define W_HBEG 0x0004
268 #define W_HEND 0x0008
269 #define W_HOST (W_HBEG | W_HEND)
270 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
273 * Check if this is my address
277 ismymbox (struct mailname
*np
)
285 static char *am
= NULL
;
286 static struct mailname mq
;
287 static bool localmailbox
;
290 * If this is the first call, initialize
291 * list of alternate mailboxes.
295 mq
.m_mbox
= getusername ();
297 if ((am
= context_find ("local-mailbox"))) {
301 if ((cp
= getname(am
)) == NULL
) {
302 inform("Unable to find address in local-mailbox, continuing...");
306 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
307 inform("invalid entry in local-mailbox: %s, continuing...", cp
);
311 /* Sigh, it turns out that the address parser gets messed up
312 * if you don't call getname() until it returns NULL. */
313 while (getname(am
) != NULL
)
317 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
320 mp
= mq
.m_next
? mq
.m_next
: &mq
;
322 while ((cp
= getname (am
))) {
323 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
324 inform("illegal address: %s, continuing...", cp
);
329 if (*mp
->m_mbox
== '*') {
330 mp
->m_type
|= W_MBEG
;
333 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
334 mp
->m_type
|= W_MEND
;
338 if (*mp
->m_host
== '*') {
339 mp
->m_type
|= W_HBEG
;
342 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
343 mp
->m_type
|= W_HEND
;
350 inform("please fix the %s: entry in your %s file",
351 "alternate-mailboxes", mh_profile
);
354 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
355 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
356 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
357 "mbox=\"%s\" host=\"%s\" %s\n",
358 FENDNULL(mp
->m_text
), mp
->m_mbox
,
359 FENDNULL(mp
->m_host
),
360 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
366 if (np
== NULL
) /* XXX */
370 * Don't perform this "local" test if we have a Local-Mailbox set
374 switch (np
->m_type
) {
376 len
= strlen (cp
= LocalName (0));
377 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
382 if (strcasecmp (np
->m_host
, SystemName()))
387 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
396 * Now scan through list of alternate
397 * mailboxes, and check for a match.
399 for (mp
= &mq
; mp
->m_next
;) {
403 if ((len
= strlen (cp
= np
->m_mbox
))
404 < (i
= strlen (pp
= mp
->m_mbox
)))
406 switch (mp
->m_type
& W_MBOX
) {
408 if (strcasecmp (cp
, pp
))
412 if (strcasecmp (cp
+ len
- i
, pp
))
419 case W_MBEG
| W_MEND
:
420 if (stringdex (pp
, cp
) < 0)
427 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
429 if ((len
= strlen (cp
= np
->m_host
))
430 < (i
= strlen (pp
= mp
->m_host
)))
432 switch (mp
->m_type
& W_HOST
) {
434 if (strcasecmp (cp
, pp
))
438 if (strcasecmp (cp
+ len
- i
, pp
))
445 case W_HBEG
| W_HEND
:
446 if (stringdex (pp
, cp
) < 0)