]>
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 * Customize the MTS settings for nmh by adjusting
83 * the file mts.conf in the nmh etc directory.
91 static struct bind binds
[] = {
92 { "localname", &localname
},
93 { "localdomain", &localdomain
},
94 { "systemname", &systemname
},
95 { "mmdfldir", &mmdfldir
},
96 { "mmdflfil", &mmdflfil
},
97 { "spoollocking", &spoollocking
},
98 { "uucpldir", &uucpldir
},
99 { "uucplfil", &uucplfil
},
100 { "mmdelim1", &mmdlm1
},
101 { "mmdelim2", &mmdlm2
},
102 { "mts", &mts_method
},
103 { "sendmail", &sendmail
},
104 { "clientname", &clientname
},
105 { "servers", &servers
},
106 { "pophost", &pophost
},
108 { "maildelivery", &maildelivery
},
113 /* Convert name of mts method to integer value and store it. */
115 save_mts_method (const char *value
) {
116 if (! strcasecmp (value
, "smtp")) {
119 } else if (! strcasecmp (value
, "sendmail/smtp") ||
120 ! strcasecmp (value
, "sendmail")) {
121 mts_method
= "sendmail/smtp";
122 sm_mts
= MTS_SENDMAIL_SMTP
;
123 } else if (! strcasecmp (value
, "sendmail/pipe")) {
124 mts_method
= "sendmail/pipe";
125 sm_mts
= MTS_SENDMAIL_PIPE
;
127 adios (NULL
, "unsupported mts selection \"%s\"", value
);
133 * Read the configuration file for the nmh interface
134 * to the mail transport system (MTS).
138 mts_init (char *name
)
142 static int inited
= 0;
145 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
147 mts_read_conf_file(fp
);
150 cp
= get_mtsuserconf_pathname();
152 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
153 mts_read_conf_file(fp
);
157 save_mts_method (mts_method
);
164 * Convert escaped values, malloc some new space,
165 * and copy string to malloc'ed memory.
169 tailor_value (char *s
)
176 for (bp
= buffer
; *s
; bp
++, s
++) {
181 case 'b': *bp
= '\b'; break;
182 case 'f': *bp
= '\f'; break;
183 case 'n': *bp
= '\n'; break;
184 case 't': *bp
= '\t'; break;
192 if (!isdigit ((unsigned char) *s
)) {
196 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
197 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
198 i
= i
* r
+ ((unsigned char) *s
) - '0';
207 len
= strlen (buffer
) + 1;
208 bp
= mh_xmalloc (len
);
209 memcpy (bp
, buffer
, len
);
215 * Get the fully qualified name of the local host.
217 * If flag is 0, then use anything out of mts.conf (like localname).
218 * If flag is 1, then only use the "proper" local hostname.
224 static char buffer0
[BUFSIZ
] = "";
225 static char buffer1
[BUFSIZ
] = "";
226 static char *buffer
[] = { buffer0
, buffer1
};
228 struct addrinfo hints
, *res
;
230 if (flag
< 0 || flag
> 1)
235 /* check if we have cached the local name */
241 /* check if the mts.conf file specifies a "localname" */
242 if (*localname
&& flag
== 0) {
243 strncpy (buf
, localname
, sizeof(buffer0
));
245 memset(buf
, 0, sizeof(buffer0
));
246 /* first get our local name */
247 gethostname (buf
, sizeof(buffer0
) - 1);
248 /* now fully qualify our name */
250 memset(&hints
, 0, sizeof(hints
));
251 hints
.ai_flags
= AI_CANONNAME
;
252 hints
.ai_family
= PF_UNSPEC
;
253 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
254 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
260 * If the mts.conf file specifies a "localdomain",
261 * we append that now. This should rarely be needed.
265 strcat (buf
, localdomain
);
273 * This is only for UUCP mail. It gets the hostname
274 * as part of the UUCP "domain".
280 static char buffer
[BUFSIZ
] = "";
282 /* check if we have cached the system name */
288 /* check if mts.conf file specifies a "systemname" */
290 strncpy (buffer
, systemname
, sizeof(buffer
));
294 gethostname (buffer
, sizeof(buffer
));
301 * Get the username of current user
307 if (username
[0] == '\0')
315 * Get full name of current user (typically from GECOS
316 * field of password file).
322 if (username
[0] == '\0')
330 * Get the full local mailbox name. This is in the form:
332 * User Name <user@name.com>
338 if (username
[0] == '\0')
345 * Find the user's username and full name, and cache them.
354 if ((pw
= getpwuid (getuid ())) == NULL
355 || pw
->pw_name
== NULL
356 || *pw
->pw_name
== '\0') {
357 strncpy (username
, "unknown", sizeof(username
));
358 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
365 /* If there's a Local-Mailbox profile component, try to extract
366 the username from it. But don't try very hard, this assumes
367 the very simple User Name <user@name.com> form.
368 Note that post(8) and whom(1) use context_foil (), so they
369 won't see the profile component. */
370 if ((np
= context_find("Local-Mailbox")) != NULL
) {
371 char *left_angle_bracket
= strchr (np
, '<');
372 char *at_sign
= strchr (np
, '@');
373 char *right_angle_bracket
= strchr (np
, '>');
375 strncpy(localmbox
, np
, sizeof(localmbox
));
377 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
378 if (at_sign
> left_angle_bracket
&&
379 at_sign
- left_angle_bracket
< BUFSIZ
) {
380 strncpy(username
, left_angle_bracket
+ 1,
381 at_sign
- left_angle_bracket
- 1);
386 if (username
[0] == '\0') {
387 strncpy (username
, pw
->pw_name
, sizeof(username
));
390 username
[sizeof(username
) - 1] = '\0';
392 escape_local_part(username
, sizeof(username
));
398 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
399 which some OSes use to separate other 'finger' information in the GECOS
400 field, like phone number. */
401 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
405 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
406 your real name. If SIGNATURE isn't set, use the Signature profile
407 setting if it exists.
408 Note that post(8) and whom(1) use context_foil (), so they
409 won't see the profile component. */
410 if ((cp
= getenv ("SIGNATURE")) && *cp
)
411 strncpy (fullname
, cp
, sizeof(fullname
));
412 else if ((cp
= context_find("Signature")))
413 strncpy (fullname
, cp
, sizeof(fullname
));
415 fullname
[sizeof(fullname
) - 1] = '\0';
417 escape_display_name(fullname
, sizeof(fullname
));
420 /* localmbox, if not using Local-Mailbox */
421 if (localmbox
[0] == '\0') {
422 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
423 username
, LocalName(0));
426 localmbox
[sizeof(localmbox
) - 1] = '\0';
430 get_mtsconf_pathname (void)
432 const char *cp
= getenv ( "MHMTSCONF" );
433 if (cp
!= NULL
&& *cp
!= '\0') {
440 get_mtsuserconf_pathname (void)
442 const char *cp
= getenv ( "MHMTSUSERCONF" );
443 if (cp
!= NULL
&& *cp
!= '\0') {
450 mts_read_conf_file (FILE *fp
)
452 char *bp
, *cp
, buffer
[BUFSIZ
];
455 while (fgets (buffer
, sizeof(buffer
), fp
)) {
456 if (!(cp
= strchr(buffer
, '\n')))
459 if (*buffer
== '#' || *buffer
== '\0')
461 if (!(bp
= strchr(buffer
, ':')))
464 while (isspace ((unsigned char) *bp
))
467 for (b
= binds
; b
->keyword
; b
++)
468 if (!strcmp (buffer
, b
->keyword
))
470 if (b
->keyword
&& (cp
= tailor_value (bp
)))