]>
diplodocus.org Git - nmh/blob - sbr/mts.c
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.
8 #include <h/mh.h> /* for snprintf() */
11 #define nmhetcdir(file) NMHETCDIR#file
15 #include <sys/socket.h>
21 static char *tailor_value (char *);
22 static void getuserinfo (void);
23 static const char *get_mtsconf_pathname(void);
24 static const char *get_mtsuserconf_pathname(void);
25 static void mts_read_conf_file (FILE *fp
);
28 * *mmdfldir and *uucpldir are the maildrop directories. If maildrops
29 * are kept in the user's home directory, then these should be empty
30 * strings. In this case, the appropriate ...lfil array should contain
31 * the name of the file in the user's home directory. Usually, this is
32 * something like ".mail".
36 * nmh mail transport interface customization file
38 static char *mtsconf
= nmhetcdir(/mts
.conf
);
40 static char *localname
= "";
41 static char *localdomain
= "";
42 static char *systemname
= "";
44 char *mmdfldir
= MAILSPOOL
;
46 char *uucpldir
= "/usr/spool/mail";
49 char *spoollocking
= DEFAULT_LOCKING
;
51 /* Cache the username, fullname, and mailbox of the user */
52 static char username
[BUFSIZ
];
53 static char fullname
[BUFSIZ
];
54 static char localmbox
[BUFSIZ
];
57 * MTS specific variables
59 static char *mts_method
= "smtp";
60 int sm_mts
= MTS_SMTP
;
61 char *sendmail
= SENDMAILPATH
;
66 char *clientname
= NULL
;
67 char *servers
= "localhost";
71 * Global MailDelivery file
73 char *maildelivery
= nmhetcdir(/maildelivery
);
77 * Customize the MTS settings for nmh by adjusting
78 * the file mts.conf in the nmh etc directory.
86 static struct bind binds
[] = {
87 { "localname", &localname
},
88 { "localdomain", &localdomain
},
89 { "systemname", &systemname
},
90 { "mmdfldir", &mmdfldir
},
91 { "mmdflfil", &mmdflfil
},
92 { "spoollocking", &spoollocking
},
93 { "uucpldir", &uucpldir
},
94 { "uucplfil", &uucplfil
},
95 { "mts", &mts_method
},
96 { "sendmail", &sendmail
},
97 { "clientname", &clientname
},
98 { "servers", &servers
},
99 { "pophost", &pophost
},
101 { "maildelivery", &maildelivery
},
106 /* Convert name of mts method to integer value and store it. */
108 save_mts_method (const char *value
) {
109 if (! strcasecmp (value
, "smtp")) {
112 } else if (! strcasecmp (value
, "sendmail/smtp") ||
113 ! strcasecmp (value
, "sendmail")) {
114 mts_method
= "sendmail/smtp";
115 sm_mts
= MTS_SENDMAIL_SMTP
;
116 } else if (! strcasecmp (value
, "sendmail/pipe")) {
117 mts_method
= "sendmail/pipe";
118 sm_mts
= MTS_SENDMAIL_PIPE
;
120 adios (NULL
, "unsupported mts selection \"%s\"", value
);
126 * Read the configuration file for the nmh interface
127 * to the mail transport system (MTS).
135 static int inited
= 0;
137 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
139 mts_read_conf_file(fp
);
142 cp
= get_mtsuserconf_pathname();
144 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
145 mts_read_conf_file(fp
);
149 save_mts_method (mts_method
);
156 * Convert escaped values, malloc some new space,
157 * and copy string to malloc'ed memory.
161 tailor_value (char *s
)
167 for (bp
= buffer
; *s
; bp
++, s
++) {
172 case 'b': *bp
= '\b'; break;
173 case 'f': *bp
= '\f'; break;
174 case 'n': *bp
= '\n'; break;
175 case 't': *bp
= '\t'; break;
184 if (!isdigit ((unsigned char) *s
)) {
188 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
189 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
190 i
*= r
+ ((unsigned char) *s
) - '0';
199 return mh_xstrdup(buffer
);
203 * Get the fully qualified name of the local host.
205 * If flag is 0, then use anything out of mts.conf (like localname).
206 * If flag is 1, then only use the "proper" local hostname.
212 static char buffer0
[BUFSIZ
] = "";
213 static char buffer1
[BUFSIZ
] = "";
214 static char *buffer
[] = { buffer0
, buffer1
};
216 struct addrinfo hints
, *res
;
218 if (flag
< 0 || flag
> 1)
223 /* check if we have cached the local name */
229 /* check if the mts.conf file specifies a "localname" */
230 if (*localname
&& flag
== 0) {
231 strncpy (buf
, localname
, sizeof(buffer0
));
233 memset(buf
, 0, sizeof(buffer0
));
234 /* first get our local name */
235 gethostname (buf
, sizeof(buffer0
) - 1);
236 /* now fully qualify our name */
239 hints
.ai_flags
= AI_CANONNAME
;
240 hints
.ai_family
= PF_UNSPEC
;
241 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
242 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
248 * If the mts.conf file specifies a "localdomain",
249 * we append that now. This should rarely be needed.
253 strcat (buf
, localdomain
);
261 * This is only for UUCP mail. It gets the hostname
262 * as part of the UUCP "domain".
268 static char buffer
[BUFSIZ
] = "";
270 /* check if we have cached the system name */
276 /* check if mts.conf file specifies a "systemname" */
278 strncpy (buffer
, systemname
, sizeof(buffer
));
282 gethostname (buffer
, sizeof(buffer
));
289 * Get the username of current user
295 if (username
[0] == '\0')
303 * Get full name of current user (typically from GECOS
304 * field of password file).
310 if (username
[0] == '\0')
318 * Get the full local mailbox name. This is in the form:
320 * User Name <user@name.com>
326 if (username
[0] == '\0')
333 * Find the user's username and full name, and cache them.
342 if ((pw
= getpwuid (getuid ())) == NULL
343 || pw
->pw_name
== NULL
344 || *pw
->pw_name
== '\0') {
345 strncpy (username
, "unknown", sizeof(username
));
346 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
353 /* If there's a Local-Mailbox profile component, try to extract
354 the username from it. But don't try very hard, this assumes
355 the very simple User Name <user@name.com> form.
356 Note that post(8) and whom(1) use context_foil (), so they
357 won't see the profile component. */
358 if ((np
= context_find("Local-Mailbox")) != NULL
) {
359 char *left_angle_bracket
= strchr (np
, '<');
360 char *at_sign
= strchr (np
, '@');
361 char *right_angle_bracket
= strchr (np
, '>');
363 strncpy(localmbox
, np
, sizeof(localmbox
));
365 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
366 if (at_sign
> left_angle_bracket
&&
367 at_sign
- left_angle_bracket
< BUFSIZ
) {
368 strncpy(username
, left_angle_bracket
+ 1,
369 at_sign
- left_angle_bracket
- 1);
374 if (username
[0] == '\0') {
375 strncpy (username
, pw
->pw_name
, sizeof(username
));
378 username
[sizeof(username
) - 1] = '\0';
380 escape_local_part(username
, sizeof(username
));
386 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
387 which some OSes use to separate other 'finger' information in the GECOS
388 field, like phone number. */
389 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
393 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
394 your real name. If SIGNATURE isn't set, use the Signature profile
395 setting if it exists.
396 Note that post(8) and whom(1) use context_foil (), so they
397 won't see the profile component. */
398 if ((cp
= getenv ("SIGNATURE")) && *cp
)
399 strncpy (fullname
, cp
, sizeof(fullname
));
400 else if ((cp
= context_find("Signature")))
401 strncpy (fullname
, cp
, sizeof(fullname
));
403 fullname
[sizeof(fullname
) - 1] = '\0';
405 escape_display_name(fullname
, sizeof(fullname
));
408 /* localmbox, if not using Local-Mailbox */
409 if (localmbox
[0] == '\0') {
410 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
411 username
, LocalName(0));
414 localmbox
[sizeof(localmbox
) - 1] = '\0';
418 get_mtsconf_pathname (void)
420 const char *cp
= getenv ( "MHMTSCONF" );
421 if (cp
!= NULL
&& *cp
!= '\0') {
428 get_mtsuserconf_pathname (void)
430 const char *cp
= getenv ( "MHMTSUSERCONF" );
431 if (cp
!= NULL
&& *cp
!= '\0') {
438 mts_read_conf_file (FILE *fp
)
440 char *bp
, *cp
, buffer
[BUFSIZ
];
443 while (fgets (buffer
, sizeof(buffer
), fp
)) {
444 if (!(cp
= strchr(buffer
, '\n')))
447 if (*buffer
== '#' || *buffer
== '\0')
449 if (!(bp
= strchr(buffer
, ':')))
452 while (isspace ((unsigned char) *bp
))
455 for (b
= binds
; b
->keyword
; b
++)
456 if (!strcmp (buffer
, b
->keyword
))
458 if (b
->keyword
&& (cp
= tailor_value (bp
)))