]>
diplodocus.org Git - nmh/blob - sbr/mts.c
3 * mts.c -- definitions for the mail transport system
5 * This code is Copyright (c) 2002, by the authors of nmh. See the
6 * COPYRIGHT file in the root directory of the nmh distribution for
7 * complete copyright information.
10 #include <h/mh.h> /* for snprintf() */
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 *mmdlm1
= "\001\001\001\001\n";
52 char *mmdlm2
= "\001\001\001\001\n";
54 char *spoollocking
= DEFAULT_LOCKING
;
56 /* Cache the username, fullname, and mailbox of the user */
57 static char username
[BUFSIZ
];
58 static char fullname
[BUFSIZ
];
59 static char localmbox
[BUFSIZ
];
62 * MTS specific variables
64 static char *mts_method
= "smtp";
65 int sm_mts
= MTS_SENDMAIL_SMTP
;
66 char *sendmail
= SENDMAILPATH
;
71 char *clientname
= NULL
;
72 char *servers
= "localhost";
76 * Global MailDelivery file
78 char *maildelivery
= nmhetcdir(/maildelivery
);
82 * Aliasing Facility (doesn't belong here)
85 static char *everyone
= "-1";
89 * Customize the MTS settings for nmh by adjusting
90 * the file mts.conf in the nmh etc directory.
98 static struct bind binds
[] = {
99 { "localname", &localname
},
100 { "localdomain", &localdomain
},
101 { "systemname", &systemname
},
102 { "mmdfldir", &mmdfldir
},
103 { "mmdflfil", &mmdflfil
},
104 { "spoollocking", &spoollocking
},
105 { "uucpldir", &uucpldir
},
106 { "uucplfil", &uucplfil
},
107 { "mmdelim1", &mmdlm1
},
108 { "mmdelim2", &mmdlm2
},
109 { "mts", &mts_method
},
110 { "sendmail", &sendmail
},
111 { "clientname", &clientname
},
112 { "servers", &servers
},
113 { "pophost", &pophost
},
115 { "maildelivery", &maildelivery
},
116 { "everyone", &everyone
},
117 { "noshell", &NoShell
},
122 /* Convert name of mts method to integer value and store it. */
124 save_mts_method (const char *value
) {
125 if (! strcasecmp (value
, "smtp")) {
128 } else if (! strcasecmp (value
, "sendmail/smtp") ||
129 ! strcasecmp (value
, "sendmail")) {
130 mts_method
= "sendmail/smtp";
131 sm_mts
= MTS_SENDMAIL_SMTP
;
132 } else if (! strcasecmp (value
, "sendmail/pipe")) {
133 mts_method
= "sendmail/pipe";
134 sm_mts
= MTS_SENDMAIL_PIPE
;
136 adios (NULL
, "unsupported mts selection \"%s\"", value
);
142 * Read the configuration file for the nmh interface
143 * to the mail transport system (MTS).
147 mts_init (char *name
)
151 static int inited
= 0;
154 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
156 mts_read_conf_file(fp
);
159 cp
= get_mtsuserconf_pathname();
161 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
162 mts_read_conf_file(fp
);
166 Everyone
= atoi (everyone
);
168 save_mts_method (mts_method
);
175 * Convert escaped values, malloc some new space,
176 * and copy string to malloc'ed memory.
180 tailor_value (char *s
)
187 for (bp
= buffer
; *s
; bp
++, s
++) {
192 case 'b': *bp
= '\b'; break;
193 case 'f': *bp
= '\f'; break;
194 case 'n': *bp
= '\n'; break;
195 case 't': *bp
= '\t'; break;
203 if (!isdigit ((unsigned char) *s
)) {
207 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
208 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
209 i
= i
* r
+ ((unsigned char) *s
) - '0';
218 len
= strlen (buffer
) + 1;
219 bp
= mh_xmalloc (len
);
220 memcpy (bp
, buffer
, len
);
226 * Get the fully qualified name of the local host.
228 * If flag is 0, then use anything out of mts.conf (like localname).
229 * If flag is 1, then only use the "proper" local hostname.
235 static char buffer0
[BUFSIZ
] = "";
236 static char buffer1
[BUFSIZ
] = "";
237 static char *buffer
[] = { buffer0
, buffer1
};
239 struct addrinfo hints
, *res
;
241 if (flag
< 0 || flag
> 1)
246 /* check if we have cached the local name */
252 /* check if the mts.conf file specifies a "localname" */
253 if (*localname
&& flag
== 0) {
254 strncpy (buf
, localname
, sizeof(buffer0
));
256 memset(buf
, 0, sizeof(buffer0
));
257 /* first get our local name */
258 gethostname (buf
, sizeof(buffer0
) - 1);
259 /* now fully qualify our name */
261 memset(&hints
, 0, sizeof(hints
));
262 hints
.ai_flags
= AI_CANONNAME
;
263 hints
.ai_family
= PF_UNSPEC
;
264 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
265 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
271 * If the mts.conf file specifies a "localdomain",
272 * we append that now. This should rarely be needed.
276 strcat (buf
, localdomain
);
284 * This is only for UUCP mail. It gets the hostname
285 * as part of the UUCP "domain".
291 static char buffer
[BUFSIZ
] = "";
293 /* check if we have cached the system name */
299 /* check if mts.conf file specifies a "systemname" */
301 strncpy (buffer
, systemname
, sizeof(buffer
));
305 gethostname (buffer
, sizeof(buffer
));
312 * Get the username of current user
318 if (username
[0] == '\0')
326 * Get full name of current user (typically from GECOS
327 * field of password file).
333 if (username
[0] == '\0')
341 * Get the full local mailbox name. This is in the form:
343 * User Name <user@name.com>
349 if (username
[0] == '\0')
356 * Find the user's username and full name, and cache them.
365 if ((pw
= getpwuid (getuid ())) == NULL
366 || pw
->pw_name
== NULL
367 || *pw
->pw_name
== '\0') {
368 strncpy (username
, "unknown", sizeof(username
));
369 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
376 /* If there's a Local-Mailbox profile component, try to extract
377 the username from it. But don't try very hard, this assumes
378 the very simple User Name <user@name.com> form.
379 Note that post(8) and whom(1) use context_foil (), so they
380 won't see the profile component. */
381 if ((np
= context_find("Local-Mailbox")) != NULL
) {
382 char *left_angle_bracket
= strchr (np
, '<');
383 char *at_sign
= strchr (np
, '@');
384 char *right_angle_bracket
= strchr (np
, '>');
386 strncpy(localmbox
, np
, sizeof(localmbox
));
388 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
389 if (at_sign
> left_angle_bracket
&&
390 at_sign
- left_angle_bracket
< BUFSIZ
) {
391 strncpy(username
, left_angle_bracket
+ 1,
392 at_sign
- left_angle_bracket
- 1);
397 if (username
[0] == '\0') {
398 strncpy (username
, pw
->pw_name
, sizeof(username
));
401 username
[sizeof(username
) - 1] = '\0';
403 escape_local_part(username
, sizeof(username
));
409 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
410 which some OSes use to separate other 'finger' information in the GECOS
411 field, like phone number. */
412 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
416 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
417 your real name. If SIGNATURE isn't set, use the Signature profile
418 setting if it exists.
419 Note that post(8) and whom(1) use context_foil (), so they
420 won't see the profile component. */
421 if ((cp
= getenv ("SIGNATURE")) && *cp
)
422 strncpy (fullname
, cp
, sizeof(fullname
));
423 else if ((cp
= context_find("Signature")))
424 strncpy (fullname
, cp
, sizeof(fullname
));
426 fullname
[sizeof(fullname
) - 1] = '\0';
428 escape_display_name(fullname
, sizeof(fullname
));
431 /* localmbox, if not using Local-Mailbox */
432 if (localmbox
[0] == '\0') {
433 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
434 username
, LocalName(0));
437 localmbox
[sizeof(localmbox
) - 1] = '\0';
441 get_mtsconf_pathname (void)
443 const char *cp
= getenv ( "MHMTSCONF" );
444 if (cp
!= NULL
&& *cp
!= '\0') {
451 get_mtsuserconf_pathname (void)
453 const char *cp
= getenv ( "MHMTSUSERCONF" );
454 if (cp
!= NULL
&& *cp
!= '\0') {
461 mts_read_conf_file (FILE *fp
)
463 char *bp
, *cp
, buffer
[BUFSIZ
];
466 while (fgets (buffer
, sizeof(buffer
), fp
)) {
467 if (!(cp
= strchr(buffer
, '\n')))
470 if (*buffer
== '#' || *buffer
== '\0')
472 if (!(bp
= strchr(buffer
, ':')))
475 while (isspace ((unsigned char) *bp
))
478 for (b
= binds
; b
->keyword
; b
++)
479 if (!strcmp (buffer
, b
->keyword
))
481 if (b
->keyword
&& (cp
= tailor_value (bp
)))