]>
diplodocus.org Git - nmh/blob - sbr/mts.c
151a4d0fc755f6c8643d9ad137145ccb26ea9727
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.
12 #define nmhetcdir(file) NMHETCDIR#file
16 #include <sys/socket.h>
22 static char *tailor_value (char *);
23 static void getuserinfo (void);
24 static const char *get_mtsconf_pathname(void);
25 static const char *get_mtsuserconf_pathname(void);
26 static void mts_read_conf_file (FILE *fp
);
29 * *mmdfldir and *uucpldir are the maildrop directories. If maildrops
30 * are kept in the user's home directory, then these should be empty
31 * strings. In this case, the appropriate ...lfil array should contain
32 * the name of the file in the user's home directory. Usually, this is
33 * something like ".mail".
37 * nmh mail transport interface customization file
39 static char *mtsconf
= nmhetcdir(/mts
.conf
);
41 static char *localname
= "";
42 static char *localdomain
= "";
43 static char *systemname
= "";
45 char *mmdfldir
= MAILSPOOL
;
47 char *uucpldir
= "/usr/spool/mail";
50 char *spoollocking
= DEFAULT_LOCKING
;
52 /* Cache the username, fullname, and mailbox of the user */
53 static char username
[BUFSIZ
];
54 static char fullname
[BUFSIZ
];
55 static char localmbox
[BUFSIZ
];
58 * MTS specific variables
60 static char *mts_method
= "smtp";
61 int sm_mts
= MTS_SMTP
;
62 char *sendmail
= SENDMAILPATH
;
67 char *clientname
= NULL
;
68 char *servers
= "localhost";
72 * Global MailDelivery file
74 char *maildelivery
= nmhetcdir(/maildelivery
);
78 * Customize the MTS settings for nmh by adjusting
79 * the file mts.conf in the nmh etc directory.
87 static struct bind binds
[] = {
88 { "localname", &localname
},
89 { "localdomain", &localdomain
},
90 { "systemname", &systemname
},
91 { "mmdfldir", &mmdfldir
},
92 { "mmdflfil", &mmdflfil
},
93 { "spoollocking", &spoollocking
},
94 { "uucpldir", &uucpldir
},
95 { "uucplfil", &uucplfil
},
96 { "mts", &mts_method
},
97 { "sendmail", &sendmail
},
98 { "clientname", &clientname
},
99 { "servers", &servers
},
100 { "pophost", &pophost
},
102 { "maildelivery", &maildelivery
},
107 /* Convert name of mts method to integer value and store it. */
109 save_mts_method (const char *value
)
111 if (! strcasecmp (value
, "smtp")) {
114 } else if (! strcasecmp (value
, "sendmail/smtp") ||
115 ! strcasecmp (value
, "sendmail")) {
116 mts_method
= "sendmail/smtp";
117 sm_mts
= MTS_SENDMAIL_SMTP
;
118 } else if (! strcasecmp (value
, "sendmail/pipe")) {
119 mts_method
= "sendmail/pipe";
120 sm_mts
= MTS_SENDMAIL_PIPE
;
122 die("unsupported mts selection \"%s\"", value
);
128 * Read the configuration file for the nmh interface
129 * to the mail transport system (MTS).
137 static int inited
= 0;
139 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
141 mts_read_conf_file(fp
);
144 cp
= get_mtsuserconf_pathname();
146 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
147 mts_read_conf_file(fp
);
151 save_mts_method (mts_method
);
158 * Convert escaped values, malloc some new space,
159 * and copy string to malloc'ed memory.
163 tailor_value (char *s
)
169 for (bp
= buffer
; *s
; bp
++, s
++) {
174 case 'b': *bp
= '\b'; break;
175 case 'f': *bp
= '\f'; break;
176 case 'n': *bp
= '\n'; break;
177 case 't': *bp
= '\t'; break;
186 if (!isdigit ((unsigned char) *s
)) {
190 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
191 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
192 i
*= r
+ ((unsigned char) *s
) - '0';
201 return mh_xstrdup(buffer
);
205 * Get the fully qualified name of the local host.
207 * If flag is 0, then use anything out of mts.conf (like localname).
208 * If flag is 1, then only use the "proper" local hostname.
214 static char buffer0
[BUFSIZ
] = "";
215 static char buffer1
[BUFSIZ
] = "";
216 static char *buffer
[] = { buffer0
, buffer1
};
218 struct addrinfo hints
, *res
;
220 if (flag
< 0 || flag
> 1)
225 /* check if we have cached the local name */
231 /* check if the mts.conf file specifies a "localname" */
232 if (*localname
&& flag
== 0) {
233 strncpy (buf
, localname
, sizeof(buffer0
));
235 memset(buf
, 0, sizeof(buffer0
));
236 /* first get our local name */
237 gethostname (buf
, sizeof(buffer0
) - 1);
238 /* now fully qualify our name */
241 hints
.ai_flags
= AI_CANONNAME
;
242 hints
.ai_family
= PF_UNSPEC
;
243 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
244 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
250 * If the mts.conf file specifies a "localdomain",
251 * we append that now. This should rarely be needed.
255 strcat (buf
, localdomain
);
263 * This is only for UUCP mail. It gets the hostname
264 * as part of the UUCP "domain".
270 static char buffer
[BUFSIZ
] = "";
272 /* check if we have cached the system name */
278 /* check if mts.conf file specifies a "systemname" */
280 strncpy (buffer
, systemname
, sizeof(buffer
));
284 gethostname (buffer
, sizeof(buffer
));
291 * Get the username of current user
297 if (username
[0] == '\0')
305 * Get full name of current user (typically from GECOS
306 * field of password file).
312 if (username
[0] == '\0')
320 * Get the full local mailbox name. This is in the form:
322 * User Name <user@name.com>
328 if (username
[0] == '\0')
335 * Find the user's username and full name, and cache them.
344 if ((pw
= getpwuid (getuid ())) == NULL
345 || pw
->pw_name
== NULL
346 || *pw
->pw_name
== '\0') {
347 strncpy (username
, "unknown", sizeof(username
));
348 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
355 /* If there's a Local-Mailbox profile component, try to extract
356 the username from it. But don't try very hard, this assumes
357 the very simple User Name <user@name.com> form.
358 Note that post(8) and whom(1) use context_foil (), so they
359 won't see the profile component. */
360 if ((np
= context_find("Local-Mailbox")) != NULL
) {
361 char *left_angle_bracket
= strchr (np
, '<');
362 char *at_sign
= strchr (np
, '@');
363 char *right_angle_bracket
= strchr (np
, '>');
365 strncpy(localmbox
, np
, sizeof(localmbox
));
367 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
368 if (at_sign
> left_angle_bracket
&&
369 at_sign
- left_angle_bracket
< BUFSIZ
) {
370 strncpy(username
, left_angle_bracket
+ 1,
371 at_sign
- left_angle_bracket
- 1);
376 if (username
[0] == '\0') {
377 strncpy (username
, pw
->pw_name
, sizeof(username
));
380 username
[sizeof(username
) - 1] = '\0';
382 escape_local_part(username
, sizeof(username
));
388 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
389 which some OSes use to separate other 'finger' information in the GECOS
390 field, like phone number. */
391 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
395 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
396 your real name. If SIGNATURE isn't set, use the Signature profile
397 setting if it exists.
398 Note that post(8) and whom(1) use context_foil (), so they
399 won't see the profile component. */
400 if ((cp
= getenv ("SIGNATURE")) && *cp
)
401 strncpy (fullname
, cp
, sizeof(fullname
));
402 else if ((cp
= context_find("Signature")))
403 strncpy (fullname
, cp
, sizeof(fullname
));
405 fullname
[sizeof(fullname
) - 1] = '\0';
407 escape_display_name(fullname
, sizeof(fullname
));
410 /* localmbox, if not using Local-Mailbox */
411 if (localmbox
[0] == '\0') {
412 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
413 username
, LocalName(0));
416 localmbox
[sizeof(localmbox
) - 1] = '\0';
420 get_mtsconf_pathname (void)
422 const char *cp
= getenv ( "MHMTSCONF" );
423 if (cp
!= NULL
&& *cp
!= '\0') {
430 get_mtsuserconf_pathname (void)
432 const char *cp
= getenv ( "MHMTSUSERCONF" );
433 if (cp
!= NULL
&& *cp
!= '\0') {
440 mts_read_conf_file (FILE *fp
)
442 char *bp
, *cp
, buffer
[BUFSIZ
];
445 while (fgets (buffer
, sizeof(buffer
), fp
)) {
446 if (!(cp
= strchr(buffer
, '\n')))
449 if (*buffer
== '#' || *buffer
== '\0')
451 if (!(bp
= strchr(buffer
, ':')))
454 while (isspace ((unsigned char) *bp
))
457 for (b
= binds
; b
->keyword
; b
++)
458 if (!strcmp (buffer
, b
->keyword
))
460 if (b
->keyword
&& (cp
= tailor_value (bp
)))