]>
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
)
110 if (! strcasecmp (value
, "smtp")) {
113 } else if (! strcasecmp (value
, "sendmail/smtp") ||
114 ! strcasecmp (value
, "sendmail")) {
115 mts_method
= "sendmail/smtp";
116 sm_mts
= MTS_SENDMAIL_SMTP
;
117 } else if (! strcasecmp (value
, "sendmail/pipe")) {
118 mts_method
= "sendmail/pipe";
119 sm_mts
= MTS_SENDMAIL_PIPE
;
121 die("unsupported mts selection \"%s\"", value
);
127 * Read the configuration file for the nmh interface
128 * to the mail transport system (MTS).
136 static int inited
= 0;
138 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
140 mts_read_conf_file(fp
);
143 cp
= get_mtsuserconf_pathname();
145 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
146 mts_read_conf_file(fp
);
150 save_mts_method (mts_method
);
157 * Convert escaped values, malloc some new space,
158 * and copy string to malloc'ed memory.
162 tailor_value (char *s
)
168 for (bp
= buffer
; *s
; bp
++, s
++) {
173 case 'b': *bp
= '\b'; break;
174 case 'f': *bp
= '\f'; break;
175 case 'n': *bp
= '\n'; break;
176 case 't': *bp
= '\t'; break;
185 if (!isdigit ((unsigned char) *s
)) {
189 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
190 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
191 i
*= r
+ ((unsigned char) *s
) - '0';
200 return mh_xstrdup(buffer
);
204 * Get the fully qualified name of the local host.
206 * If flag is 0, then use anything out of mts.conf (like localname).
207 * If flag is 1, then only use the "proper" local hostname.
213 static char buffer0
[BUFSIZ
] = "";
214 static char buffer1
[BUFSIZ
] = "";
215 static char *buffer
[] = { buffer0
, buffer1
};
217 struct addrinfo hints
, *res
;
219 if (flag
< 0 || flag
> 1)
224 /* check if we have cached the local name */
230 /* check if the mts.conf file specifies a "localname" */
231 if (*localname
&& flag
== 0) {
232 strncpy (buf
, localname
, sizeof(buffer0
));
234 memset(buf
, 0, sizeof(buffer0
));
235 /* first get our local name */
236 gethostname (buf
, sizeof(buffer0
) - 1);
237 /* now fully qualify our name */
240 hints
.ai_flags
= AI_CANONNAME
;
241 hints
.ai_family
= PF_UNSPEC
;
242 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
243 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
249 * If the mts.conf file specifies a "localdomain",
250 * we append that now. This should rarely be needed.
254 strcat (buf
, localdomain
);
262 * This is only for UUCP mail. It gets the hostname
263 * as part of the UUCP "domain".
269 static char buffer
[BUFSIZ
] = "";
271 /* check if we have cached the system name */
277 /* check if mts.conf file specifies a "systemname" */
279 strncpy (buffer
, systemname
, sizeof(buffer
));
283 gethostname (buffer
, sizeof(buffer
));
290 * Get the username of current user
296 if (username
[0] == '\0')
304 * Get full name of current user (typically from GECOS
305 * field of password file).
311 if (username
[0] == '\0')
319 * Get the full local mailbox name. This is in the form:
321 * User Name <user@name.com>
327 if (username
[0] == '\0')
334 * Find the user's username and full name, and cache them.
343 if ((pw
= getpwuid (getuid ())) == NULL
344 || pw
->pw_name
== NULL
345 || *pw
->pw_name
== '\0') {
346 strncpy (username
, "unknown", sizeof(username
));
347 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
354 /* If there's a Local-Mailbox profile component, try to extract
355 the username from it. But don't try very hard, this assumes
356 the very simple User Name <user@name.com> form.
357 Note that post(8) and whom(1) use context_foil (), so they
358 won't see the profile component. */
359 if ((np
= context_find("Local-Mailbox")) != NULL
) {
360 char *left_angle_bracket
= strchr (np
, '<');
361 char *at_sign
= strchr (np
, '@');
362 char *right_angle_bracket
= strchr (np
, '>');
364 strncpy(localmbox
, np
, sizeof(localmbox
));
366 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
367 if (at_sign
> left_angle_bracket
&&
368 at_sign
- left_angle_bracket
< BUFSIZ
) {
369 strncpy(username
, left_angle_bracket
+ 1,
370 at_sign
- left_angle_bracket
- 1);
375 if (username
[0] == '\0') {
376 strncpy (username
, pw
->pw_name
, sizeof(username
));
379 username
[sizeof(username
) - 1] = '\0';
381 escape_local_part(username
, sizeof(username
));
387 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
388 which some OSes use to separate other 'finger' information in the GECOS
389 field, like phone number. */
390 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
394 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
395 your real name. If SIGNATURE isn't set, use the Signature profile
396 setting if it exists.
397 Note that post(8) and whom(1) use context_foil (), so they
398 won't see the profile component. */
399 if ((cp
= getenv ("SIGNATURE")) && *cp
)
400 strncpy (fullname
, cp
, sizeof(fullname
));
401 else if ((cp
= context_find("Signature")))
402 strncpy (fullname
, cp
, sizeof(fullname
));
404 fullname
[sizeof(fullname
) - 1] = '\0';
406 escape_display_name(fullname
, sizeof(fullname
));
409 /* localmbox, if not using Local-Mailbox */
410 if (localmbox
[0] == '\0') {
411 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
412 username
, LocalName(0));
415 localmbox
[sizeof(localmbox
) - 1] = '\0';
419 get_mtsconf_pathname (void)
421 const char *cp
= getenv ( "MHMTSCONF" );
422 if (cp
!= NULL
&& *cp
!= '\0') {
429 get_mtsuserconf_pathname (void)
431 const char *cp
= getenv ( "MHMTSUSERCONF" );
432 if (cp
!= NULL
&& *cp
!= '\0') {
439 mts_read_conf_file (FILE *fp
)
441 char *bp
, *cp
, buffer
[BUFSIZ
];
444 while (fgets (buffer
, sizeof(buffer
), fp
)) {
445 if (!(cp
= strchr(buffer
, '\n')))
448 if (*buffer
== '#' || *buffer
== '\0')
450 if (!(bp
= strchr(buffer
, ':')))
453 while (isspace ((unsigned char) *bp
))
456 for (b
= binds
; b
->keyword
; b
++)
457 if (!strcmp (buffer
, b
->keyword
))
459 if (b
->keyword
&& (cp
= tailor_value (bp
)))