]>
diplodocus.org Git - nmh/blob - sbr/mts.c
639310b43338004c55e09cc1616a33580536651e
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 "context_find.h"
13 #define nmhetcdir(file) NMHETCDIR#file
17 #include <sys/socket.h>
23 static char *tailor_value (char *);
24 static void getuserinfo (void);
25 static const char *get_mtsconf_pathname(void);
26 static const char *get_mtsuserconf_pathname(void);
27 static void mts_read_conf_file (FILE *fp
);
30 * *mmdfldir and *uucpldir are the maildrop directories. If maildrops
31 * are kept in the user's home directory, then these should be empty
32 * strings. In this case, the appropriate ...lfil array should contain
33 * the name of the file in the user's home directory. Usually, this is
34 * something like ".mail".
38 * nmh mail transport interface customization file
40 static char *mtsconf
= nmhetcdir(/mts
.conf
);
42 static char *localname
= "";
43 static char *localdomain
= "";
44 static char *systemname
= "";
46 char *mmdfldir
= MAILSPOOL
;
48 char *uucpldir
= "/usr/spool/mail";
51 char *spoollocking
= DEFAULT_LOCKING
;
53 /* Cache the username, fullname, and mailbox of the user */
54 static char username
[BUFSIZ
];
55 static char fullname
[BUFSIZ
];
56 static char localmbox
[BUFSIZ
];
59 * MTS specific variables
61 static char *mts_method
= "smtp";
62 int sm_mts
= MTS_SMTP
;
63 char *sendmail
= SENDMAILPATH
;
68 char *clientname
= NULL
;
69 char *servers
= "localhost";
73 * Global MailDelivery file
75 char *maildelivery
= nmhetcdir(/maildelivery
);
79 * Customize the MTS settings for nmh by adjusting
80 * the file mts.conf in the nmh etc directory.
88 static struct bind binds
[] = {
89 { "localname", &localname
},
90 { "localdomain", &localdomain
},
91 { "systemname", &systemname
},
92 { "mmdfldir", &mmdfldir
},
93 { "mmdflfil", &mmdflfil
},
94 { "spoollocking", &spoollocking
},
95 { "uucpldir", &uucpldir
},
96 { "uucplfil", &uucplfil
},
97 { "mts", &mts_method
},
98 { "sendmail", &sendmail
},
99 { "clientname", &clientname
},
100 { "servers", &servers
},
101 { "pophost", &pophost
},
103 { "maildelivery", &maildelivery
},
108 /* Convert name of mts method to integer value and store it. */
110 save_mts_method (const char *value
)
112 if (! strcasecmp (value
, "smtp")) {
115 } else if (! strcasecmp (value
, "sendmail/smtp") ||
116 ! strcasecmp (value
, "sendmail")) {
117 mts_method
= "sendmail/smtp";
118 sm_mts
= MTS_SENDMAIL_SMTP
;
119 } else if (! strcasecmp (value
, "sendmail/pipe")) {
120 mts_method
= "sendmail/pipe";
121 sm_mts
= MTS_SENDMAIL_PIPE
;
123 die("unsupported mts selection \"%s\"", value
);
129 * Read the configuration file for the nmh interface
130 * to the mail transport system (MTS).
138 static int inited
= 0;
140 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
142 mts_read_conf_file(fp
);
145 cp
= get_mtsuserconf_pathname();
147 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
148 mts_read_conf_file(fp
);
152 save_mts_method (mts_method
);
159 * Convert escaped values, malloc some new space,
160 * and copy string to malloc'ed memory.
164 tailor_value (char *s
)
170 for (bp
= buffer
; *s
; bp
++, s
++) {
175 case 'b': *bp
= '\b'; break;
176 case 'f': *bp
= '\f'; break;
177 case 'n': *bp
= '\n'; break;
178 case 't': *bp
= '\t'; break;
187 if (!isdigit ((unsigned char) *s
)) {
191 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
192 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
193 i
*= r
+ ((unsigned char) *s
) - '0';
202 return mh_xstrdup(buffer
);
206 * Get the fully qualified name of the local host.
208 * If flag is 0, then use anything out of mts.conf (like localname).
209 * If flag is 1, then only use the "proper" local hostname.
215 static char buffer0
[BUFSIZ
] = "";
216 static char buffer1
[BUFSIZ
] = "";
217 static char *buffer
[] = { buffer0
, buffer1
};
219 struct addrinfo hints
, *res
;
221 if (flag
< 0 || flag
> 1)
226 /* check if we have cached the local name */
232 /* check if the mts.conf file specifies a "localname" */
233 if (*localname
&& flag
== 0) {
234 strncpy (buf
, localname
, sizeof(buffer0
));
236 memset(buf
, 0, sizeof(buffer0
));
237 /* first get our local name */
238 gethostname (buf
, sizeof(buffer0
) - 1);
239 /* now fully qualify our name */
242 hints
.ai_flags
= AI_CANONNAME
;
243 hints
.ai_family
= PF_UNSPEC
;
244 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
245 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
251 * If the mts.conf file specifies a "localdomain",
252 * we append that now. This should rarely be needed.
256 strcat (buf
, localdomain
);
264 * This is only for UUCP mail. It gets the hostname
265 * as part of the UUCP "domain".
271 static char buffer
[BUFSIZ
] = "";
273 /* check if we have cached the system name */
279 /* check if mts.conf file specifies a "systemname" */
281 strncpy (buffer
, systemname
, sizeof(buffer
));
285 gethostname (buffer
, sizeof(buffer
));
292 * Get the username of current user
298 if (username
[0] == '\0')
306 * Get full name of current user (typically from GECOS
307 * field of password file).
313 if (username
[0] == '\0')
321 * Get the full local mailbox name. This is in the form:
323 * User Name <user@name.com>
329 if (username
[0] == '\0')
336 * Find the user's username and full name, and cache them.
345 if ((pw
= getpwuid (getuid ())) == NULL
346 || pw
->pw_name
== NULL
347 || *pw
->pw_name
== '\0') {
348 strncpy (username
, "unknown", sizeof(username
));
349 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
356 /* If there's a Local-Mailbox profile component, try to extract
357 the username from it. But don't try very hard, this assumes
358 the very simple User Name <user@name.com> form.
359 Note that post(8) and whom(1) use context_foil (), so they
360 won't see the profile component. */
361 if ((np
= context_find("Local-Mailbox")) != NULL
) {
362 char *left_angle_bracket
= strchr (np
, '<');
363 char *at_sign
= strchr (np
, '@');
364 char *right_angle_bracket
= strchr (np
, '>');
366 strncpy(localmbox
, np
, sizeof(localmbox
));
368 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
369 if (at_sign
> left_angle_bracket
&&
370 at_sign
- left_angle_bracket
< BUFSIZ
) {
371 strncpy(username
, left_angle_bracket
+ 1,
372 at_sign
- left_angle_bracket
- 1);
377 if (username
[0] == '\0') {
378 strncpy (username
, pw
->pw_name
, sizeof(username
));
381 username
[sizeof(username
) - 1] = '\0';
383 escape_local_part(username
, sizeof(username
));
389 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
390 which some OSes use to separate other 'finger' information in the GECOS
391 field, like phone number. */
392 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
396 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
397 your real name. If SIGNATURE isn't set, use the Signature profile
398 setting if it exists.
399 Note that post(8) and whom(1) use context_foil (), so they
400 won't see the profile component. */
401 if ((cp
= getenv ("SIGNATURE")) && *cp
)
402 strncpy (fullname
, cp
, sizeof(fullname
));
403 else if ((cp
= context_find("Signature")))
404 strncpy (fullname
, cp
, sizeof(fullname
));
406 fullname
[sizeof(fullname
) - 1] = '\0';
408 escape_display_name(fullname
, sizeof(fullname
));
411 /* localmbox, if not using Local-Mailbox */
412 if (localmbox
[0] == '\0') {
413 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
414 username
, LocalName(0));
417 localmbox
[sizeof(localmbox
) - 1] = '\0';
421 get_mtsconf_pathname (void)
423 const char *cp
= getenv ( "MHMTSCONF" );
424 if (cp
!= NULL
&& *cp
!= '\0') {
431 get_mtsuserconf_pathname (void)
433 const char *cp
= getenv ( "MHMTSUSERCONF" );
434 if (cp
!= NULL
&& *cp
!= '\0') {
441 mts_read_conf_file (FILE *fp
)
443 char *bp
, *cp
, buffer
[BUFSIZ
];
446 while (fgets (buffer
, sizeof(buffer
), fp
)) {
447 if (!(cp
= strchr(buffer
, '\n')))
450 if (*buffer
== '#' || *buffer
== '\0')
452 if (!(bp
= strchr(buffer
, ':')))
455 while (isspace ((unsigned char) *bp
))
458 for (b
= binds
; b
->keyword
; b
++)
459 if (!strcmp (buffer
, b
->keyword
))
461 if (b
->keyword
&& (cp
= tailor_value (bp
)))