]>
diplodocus.org Git - nmh/blob - sbr/addrsbr.c
7f961c48f522adf52e48b7760c9ef057353b86e7
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.
9 #include "context_find.h"
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 recognition. 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" representations.
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 explicit 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
];
89 getname (const char *addrs
)
92 pers
= mbox
= host
= route
= grp
= note
= NULL
;
95 if ((ap
= getadrx (FENDNULL(addrs
), eai
)) == NULL
) {
99 strncpy (adr
, ap
->text
, sizeof(adr
));
107 if (ap
->err
&& *ap
->err
)
108 strncpy (err
, ap
->err
, sizeof(err
));
115 getm (char *str
, char *dfhost
, int dftype
, char *eresult
, size_t eresultsize
)
122 strncpy (eresult
, err
, eresultsize
);
123 eresult
[eresultsize
- 1] = '\0';
128 && mbox
== NULL
&& host
== NULL
&& route
== NULL
131 strncpy (eresult
, "null address", eresultsize
);
132 eresult
[eresultsize
- 1] = '\0';
136 if (mbox
== NULL
&& grp
== NULL
) {
138 strncpy (eresult
, "no mailbox in address", eresultsize
);
139 eresult
[eresultsize
- 1] = '\0';
144 if (dfhost
== NULL
) {
145 dfhost
= LocalName (0);
151 mp
->m_text
= getcpy (str
);
153 mp
->m_pers
= mh_xstrdup(pers
);
156 mp
->m_type
= BADHOST
;
159 mp
->m_gname
= getcpy (grp
);
161 mp
->m_note
= mh_xstrdup(note
);
166 mp
->m_mbox
= getcpy (mbox
);
167 mp
->m_host
= mh_xstrdup(host
);
169 strcasecmp (LocalName(0), mp
->m_host
) ? NETHOST
: LOCALHOST
;
171 if ((pp
= strchr(mbox
, '!'))) {
173 mp
->m_mbox
= mh_xstrdup(pp
);
174 mp
->m_host
= getcpy (mbox
);
175 mp
->m_type
= UUCPHOST
;
178 mp
->m_mbox
= getcpy (mbox
);
179 if (route
== NULL
&& dftype
== LOCALHOST
) {
183 mp
->m_host
= route
? NULL
: getcpy (dfhost
);
184 mp
->m_type
= route
? NETHOST
: dftype
;
189 /* For alternate mailboxes, m_type gets overwritten in ismymbox ()
190 to support wild-card matching. */
193 mp
->m_path
= mh_xstrdup(route
);
196 mp
->m_gname
= mh_xstrdup(grp
);
198 mp
->m_note
= mh_xstrdup(note
);
205 mnfree (struct mailname
*mp
)
223 auxformat (struct mailname
*mp
, int extras
)
225 static char addr
[BUFSIZ
];
226 static char buffer
[BUFSIZ
];
229 strncpy (addr
, FENDNULL(mp
->m_mbox
), sizeof(addr
));
230 else if (mp
->m_type
!= UUCPHOST
) {
232 snprintf (addr
, sizeof(addr
), "%s%s@%s", FENDNULL(mp
->m_path
),
233 FENDNULL(mp
->m_mbox
), mp
->m_host
);
234 else snprintf (addr
, sizeof(addr
), "%s%s", FENDNULL(mp
->m_path
),
235 FENDNULL(mp
->m_mbox
));
237 snprintf (addr
, sizeof(addr
), "%s!%s", mp
->m_host
, mp
->m_mbox
);
242 if (mp
->m_pers
|| mp
->m_path
) {
244 snprintf (buffer
, sizeof(buffer
), "%s %s <%s>",
245 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
248 snprintf (buffer
, sizeof(buffer
), "%s <%s>",
249 legal_person (mp
->m_pers
? mp
->m_pers
: mp
->m_mbox
),
251 } else if (mp
->m_note
)
252 snprintf (buffer
, sizeof(buffer
), "%s %s", addr
, mp
->m_note
);
254 strncpy (buffer
, addr
, sizeof(buffer
));
261 #define W_MBEG 0x0001
262 #define W_MEND 0x0002
263 #define W_MBOX (W_MBEG | W_MEND)
264 #define W_HBEG 0x0004
265 #define W_HEND 0x0008
266 #define W_HOST (W_HBEG | W_HEND)
267 #define WBITS "\020\01MBEG\02MEND\03HBEG\04HEND"
270 * Check if this is my address
274 ismymbox (struct mailname
*np
)
282 static char *am
= NULL
;
283 static struct mailname mq
;
284 static bool localmailbox
;
287 * If this is the first call, initialize
288 * list of alternate mailboxes.
292 mq
.m_mbox
= getusername ();
294 if ((am
= context_find ("local-mailbox"))) {
298 if ((cp
= getname(am
)) == NULL
) {
299 inform("Unable to find address in local-mailbox, continuing...");
303 if ((mq
.m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
304 inform("invalid entry in local-mailbox: %s, continuing...", cp
);
308 /* Sigh, it turns out that the address parser gets messed up
309 * if you don't call getname() until it returns NULL. */
310 while (getname(am
) != NULL
)
314 if ((am
= context_find ("alternate-mailboxes")) == NULL
)
317 mp
= mq
.m_next
? mq
.m_next
: &mq
;
319 while ((cp
= getname (am
))) {
320 if ((mp
->m_next
= getm (cp
, NULL
, 0, NULL
, 0)) == NULL
) {
321 inform("illegal address: %s, continuing...", cp
);
326 if (*mp
->m_mbox
== '*') {
327 mp
->m_type
|= W_MBEG
;
330 if (*(cp
= mp
->m_mbox
+ strlen (mp
->m_mbox
) - 1) == '*') {
331 mp
->m_type
|= W_MEND
;
335 if (*mp
->m_host
== '*') {
336 mp
->m_type
|= W_HBEG
;
339 if (*(cp
= mp
->m_host
+ strlen (mp
->m_host
) - 1) == '*') {
340 mp
->m_type
|= W_HEND
;
347 inform("please fix the %s: entry in your %s file",
348 "alternate-mailboxes", mh_profile
);
351 if ((cp
= getenv ("MHWDEBUG")) && *cp
) {
352 for (mp
= &mq
; mp
; mp
= mp
->m_next
) {
353 fprintf (stderr
, "Local- or Alternate-Mailbox: text=\"%s\" "
354 "mbox=\"%s\" host=\"%s\" %s\n",
355 FENDNULL(mp
->m_text
), mp
->m_mbox
,
356 FENDNULL(mp
->m_host
),
357 snprintb (buffer
, sizeof(buffer
), (unsigned) mp
->m_type
,
363 if (np
== NULL
) /* XXX */
367 * Don't perform this "local" test if we have a Local-Mailbox set
371 switch (np
->m_type
) {
373 len
= strlen (cp
= LocalName (0));
374 if (!uprf (np
->m_host
, cp
) || np
->m_host
[len
] != '.')
379 if (strcasecmp (np
->m_host
, SystemName()))
384 if (!strcasecmp (np
->m_mbox
, mq
.m_mbox
))
393 * Now scan through list of alternate
394 * mailboxes, and check for a match.
396 for (mp
= &mq
; mp
->m_next
;) {
400 if ((len
= strlen (cp
= np
->m_mbox
))
401 < (i
= strlen (pp
= mp
->m_mbox
)))
403 switch (mp
->m_type
& W_MBOX
) {
405 if (strcasecmp (cp
, pp
))
409 if (strcasecmp (cp
+ len
- i
, pp
))
416 case W_MBEG
| W_MEND
:
417 if (stringdex (pp
, cp
) < 0)
424 if (np
->m_host
== NULL
|| mp
->m_host
== NULL
)
426 if ((len
= strlen (cp
= np
->m_host
))
427 < (i
= strlen (pp
= mp
->m_host
)))
429 switch (mp
->m_type
& W_HOST
) {
431 if (strcasecmp (cp
, pp
))
435 if (strcasecmp (cp
+ len
- i
, pp
))
442 case W_HBEG
| W_HEND
:
443 if (stringdex (pp
, cp
) < 0)