]>
diplodocus.org Git - nmh/blob - sbr/mts.c
b7e6571aec18b89e5c541ae852cc36744b527be2
1 /* mts.c -- definitions for the mail transport system
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 "escape_addresses.h"
10 #include "context_find.h"
14 #define nmhetcdir(file) NMHETCDIR#file
18 #include <sys/socket.h>
24 static char *tailor_value (char *);
25 static void getuserinfo (void);
26 static const char *get_mtsconf_pathname(void);
27 static const char *get_mtsuserconf_pathname(void);
28 static void mts_read_conf_file (FILE *fp
);
31 * *mmdfldir and *uucpldir are the maildrop directories. If maildrops
32 * are kept in the user's home directory, then these should be empty
33 * strings. In this case, the appropriate ...lfil array should contain
34 * the name of the file in the user's home directory. Usually, this is
35 * something like ".mail".
39 * nmh mail transport interface customization file
41 static char *mtsconf
= nmhetcdir(/mts
.conf
);
43 static char *localname
= "";
44 static char *localdomain
= "";
45 static char *systemname
= "";
47 char *mmdfldir
= MAILSPOOL
;
49 char *uucpldir
= "/usr/spool/mail";
52 char *spoollocking
= DEFAULT_LOCKING
;
54 /* Cache the username, fullname, mailbox name, and mailbox of the user */
55 static char username
[BUFSIZ
];
56 static char fullname
[BUFSIZ
];
57 /* mboxname comes from a Local-Mailbox profile component, or if that
58 doesn't exist, the username. */
59 static char mboxname
[BUFSIZ
];
60 static char localmbox
[2*BUFSIZ
+3];
63 * MTS specific variables
65 static char *mts_method
= "smtp";
66 int sm_mts
= MTS_SMTP
;
67 char *sendmail
= SENDMAILPATH
;
72 char *clientname
= NULL
;
73 char *servers
= "localhost";
77 * Global MailDelivery file
79 char *maildelivery
= nmhetcdir(/maildelivery
);
83 * Customize the MTS settings for nmh by adjusting
84 * the file mts.conf in the nmh etc directory.
92 static struct bind binds
[] = {
93 { "localname", &localname
},
94 { "localdomain", &localdomain
},
95 { "systemname", &systemname
},
96 { "mmdfldir", &mmdfldir
},
97 { "mmdflfil", &mmdflfil
},
98 { "spoollocking", &spoollocking
},
99 { "uucpldir", &uucpldir
},
100 { "uucplfil", &uucplfil
},
101 { "mts", &mts_method
},
102 { "sendmail", &sendmail
},
103 { "clientname", &clientname
},
104 { "servers", &servers
},
105 { "pophost", &pophost
},
107 { "maildelivery", &maildelivery
},
112 /* Convert name of mts method to integer value and store it. */
114 save_mts_method (const char *value
)
116 if (! strcasecmp (value
, "smtp")) {
119 } else if (! strcasecmp (value
, "sendmail/smtp") ||
120 ! strcasecmp (value
, "sendmail")) {
121 mts_method
= "sendmail/smtp";
122 sm_mts
= MTS_SENDMAIL_SMTP
;
123 } else if (! strcasecmp (value
, "sendmail/pipe")) {
124 mts_method
= "sendmail/pipe";
125 sm_mts
= MTS_SENDMAIL_PIPE
;
127 die("unsupported mts selection \"%s\"", value
);
133 * Read the configuration file for the nmh interface
134 * to the mail transport system (MTS).
142 static int inited
= 0;
144 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
146 mts_read_conf_file(fp
);
149 cp
= get_mtsuserconf_pathname();
151 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
152 mts_read_conf_file(fp
);
156 save_mts_method (mts_method
);
163 * Convert escaped values, malloc some new space,
164 * and copy string to malloc'ed memory.
168 tailor_value (char *s
)
174 for (bp
= buffer
; *s
; bp
++, s
++) {
179 case 'b': *bp
= '\b'; break;
180 case 'f': *bp
= '\f'; break;
181 case 'n': *bp
= '\n'; break;
182 case 't': *bp
= '\t'; break;
191 if (!isdigit ((unsigned char) *s
)) {
195 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
196 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
197 i
*= r
+ ((unsigned char) *s
) - '0';
206 return mh_xstrdup(buffer
);
210 * Get the fully qualified name of the local host.
212 * If flag is 0, then use anything out of mts.conf (like localname).
213 * If flag is 1, then only use the "proper" local hostname.
219 static char buffer0
[BUFSIZ
] = "";
220 static char buffer1
[BUFSIZ
] = "";
221 static char *buffer
[] = { buffer0
, buffer1
};
223 struct addrinfo hints
, *res
;
225 if (flag
< 0 || flag
> 1)
230 /* check if we have cached the local name */
236 /* check if the mts.conf file specifies a "localname" */
237 if (*localname
&& flag
== 0) {
238 strncpy (buf
, localname
, sizeof(buffer0
));
240 memset(buf
, 0, sizeof(buffer0
));
241 /* first get our local name */
242 gethostname (buf
, sizeof(buffer0
) - 1);
243 /* now fully qualify our name */
246 hints
.ai_flags
= AI_CANONNAME
;
247 hints
.ai_family
= PF_UNSPEC
;
248 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
249 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
255 * If the mts.conf file specifies a "localdomain",
256 * we append that now. This should rarely be needed.
260 strcat (buf
, localdomain
);
268 * This is only for UUCP mail. It gets the hostname
269 * as part of the UUCP "domain".
275 static char buffer
[BUFSIZ
] = "";
277 /* check if we have cached the system name */
283 /* check if mts.conf file specifies a "systemname" */
285 strncpy (buffer
, systemname
, sizeof(buffer
));
289 gethostname (buffer
, sizeof(buffer
));
296 * Get the username of current user
298 * If flag is 0, then attempt to extract username from Local-Mailbox profile
299 * component, if present.
300 * If flag is 1, then only use the "proper" local hostname.
304 getusername (int flag
)
306 if (username
[0] == '\0')
309 return flag
== 0 ? mboxname
: username
;
314 * Get full name of current user (typically from GECOS
315 * field of password file).
321 if (username
[0] == '\0')
329 * Get the full local mailbox name. This is in the form:
331 * User Name <user@name.com>
337 if (username
[0] == '\0')
344 * Find and cache the user's username, full name, and local mbox.
353 if ((pw
= getpwuid (getuid ())) == NULL
354 || pw
->pw_name
== NULL
355 || *pw
->pw_name
== '\0') {
356 strncpy (username
, "unknown", sizeof(username
));
357 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
363 if (username
[0] == '\0') {
364 strncpy (username
, pw
->pw_name
, sizeof(username
));
366 username
[sizeof(username
) - 1] = '\0';
368 /* localmbox and mboxname */
369 /* If there's a Local-Mailbox profile component, try to extract
370 the username from it. But don't try very hard, this assumes
371 the very simple User Name <user@name.com> form.
372 Note that post(8) uses context_foil(), so it won't see the profile
374 if ((np
= context_find("Local-Mailbox")) != NULL
) {
375 char *left_angle_bracket
= strchr (np
, '<');
376 char *at_sign
= strchr (np
, '@');
377 char *right_angle_bracket
= strchr (np
, '>');
379 strncpy(localmbox
, np
, sizeof(localmbox
));
381 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
382 if (at_sign
> left_angle_bracket
&&
383 at_sign
- left_angle_bracket
< BUFSIZ
) {
384 strncpy(mboxname
, left_angle_bracket
+ 1,
385 at_sign
- left_angle_bracket
- 1);
389 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
390 username
, LocalName(0));
392 localmbox
[sizeof(localmbox
) - 1] = '\0';
393 if (mboxname
[0] == '\0') {
394 strncpy (mboxname
, username
, sizeof(mboxname
));
396 mboxname
[sizeof(mboxname
) - 1] = '\0';
397 escape_local_part(mboxname
, sizeof(mboxname
));
402 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
403 which some OSes use to separate other 'finger' information in the GECOS
404 field, like phone number. */
405 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
409 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
410 your real name. If SIGNATURE isn't set, use the Signature profile
411 setting if it exists.
412 Note that post(8) uses context_foil(), so it won't see the profile
414 if ((cp
= getenv ("SIGNATURE")) && *cp
)
415 strncpy (fullname
, cp
, sizeof(fullname
));
416 else if ((cp
= context_find("Signature")))
417 strncpy (fullname
, cp
, sizeof(fullname
));
418 fullname
[sizeof(fullname
) - 1] = '\0';
419 escape_display_name(fullname
, sizeof(fullname
));
423 get_mtsconf_pathname (void)
425 const char *cp
= getenv ( "MHMTSCONF" );
426 if (cp
!= NULL
&& *cp
!= '\0') {
433 get_mtsuserconf_pathname (void)
435 const char *cp
= getenv ( "MHMTSUSERCONF" );
436 if (cp
!= NULL
&& *cp
!= '\0') {
443 mts_read_conf_file (FILE *fp
)
445 char *bp
, *cp
, buffer
[BUFSIZ
];
448 while (fgets (buffer
, sizeof(buffer
), fp
)) {
449 if (!(cp
= strchr(buffer
, '\n')))
452 if (*buffer
== '#' || *buffer
== '\0')
454 if (!(bp
= strchr(buffer
, ':')))
457 while (isspace ((unsigned char) *bp
))
460 for (b
= binds
; b
->keyword
; b
++)
461 if (!strcmp (buffer
, b
->keyword
))
463 if (b
->keyword
&& (cp
= tailor_value (bp
)))