]>
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() */
14 #define nmhetcdir(file) NMHETCDIR#file
20 #include <sys/socket.h>
26 static char *tailor_value (char *);
27 static void getuserinfo (void);
28 static const char *get_mtsconf_pathname(void);
29 static const char *get_mtsuserconf_pathname(void);
30 static void mts_read_conf_file (FILE *fp
);
33 * *mmdfldir and *uucpldir are the maildrop directories. If maildrops
34 * are kept in the user's home directory, then these should be empty
35 * strings. In this case, the appropriate ...lfil array should contain
36 * the name of the file in the user's home directory. Usually, this is
37 * something like ".mail".
41 * nmh mail transport interface customization file
43 static char *mtsconf
= nmhetcdir(/mts
.conf
);
45 static char *localname
= "";
46 static char *localdomain
= "";
47 static char *systemname
= "";
49 char *mmdfldir
= MAILSPOOL
;
51 char *uucpldir
= "/usr/spool/mail";
54 char *mmdlm1
= "\001\001\001\001\n";
55 char *mmdlm2
= "\001\001\001\001\n";
57 char *spoollocking
= DEFAULT_LOCKING
;
59 /* Cache the username, fullname, and mailbox of the user */
60 static char username
[BUFSIZ
];
61 static char fullname
[BUFSIZ
];
62 static char localmbox
[BUFSIZ
];
65 * MTS specific variables
67 static char *mts_method
= "smtp";
68 int sm_mts
= MTS_SENDMAIL_SMTP
;
69 char *sendmail
= SENDMAILPATH
;
74 char *clientname
= NULL
;
75 char *servers
= "localhost";
79 * Global MailDelivery file
81 char *maildelivery
= nmhetcdir(/maildelivery
);
85 * Aliasing Facility (doesn't belong here)
88 static char *everyone
= "-1";
92 * Customize the MTS settings for nmh by adjusting
93 * the file mts.conf in the nmh etc directory.
101 static struct bind binds
[] = {
102 { "localname", &localname
},
103 { "localdomain", &localdomain
},
104 { "systemname", &systemname
},
105 { "mmdfldir", &mmdfldir
},
106 { "mmdflfil", &mmdflfil
},
107 { "spoollocking", &spoollocking
},
108 { "uucpldir", &uucpldir
},
109 { "uucplfil", &uucplfil
},
110 { "mmdelim1", &mmdlm1
},
111 { "mmdelim2", &mmdlm2
},
112 { "mts", &mts_method
},
113 { "sendmail", &sendmail
},
114 { "clientname", &clientname
},
115 { "servers", &servers
},
116 { "pophost", &pophost
},
118 { "maildelivery", &maildelivery
},
119 { "everyone", &everyone
},
120 { "noshell", &NoShell
},
125 /* Convert name of mts method to integer value and store it. */
127 save_mts_method (const char *value
) {
128 if (! strcasecmp (value
, "smtp")) {
131 } else if (! strcasecmp (value
, "sendmail/smtp") ||
132 ! strcasecmp (value
, "sendmail")) {
133 mts_method
= "sendmail/smtp";
134 sm_mts
= MTS_SENDMAIL_SMTP
;
135 } else if (! strcasecmp (value
, "sendmail/pipe")) {
136 mts_method
= "sendmail/pipe";
137 sm_mts
= MTS_SENDMAIL_PIPE
;
139 adios (NULL
, "unsupported mts selection \"%s\"", value
);
145 * Read the configuration file for the nmh interface
146 * to the mail transport system (MTS).
150 mts_init (char *name
)
154 static int inited
= 0;
157 if (inited
++ || (fp
= fopen (get_mtsconf_pathname(), "r")) == NULL
)
159 mts_read_conf_file(fp
);
162 cp
= get_mtsuserconf_pathname();
164 ((fp
= fopen (get_mtsuserconf_pathname(), "r")) != NULL
)) {
165 mts_read_conf_file(fp
);
169 Everyone
= atoi (everyone
);
171 save_mts_method (mts_method
);
178 * Convert escaped values, malloc some new space,
179 * and copy string to malloc'ed memory.
183 tailor_value (char *s
)
190 for (bp
= buffer
; *s
; bp
++, s
++) {
195 case 'b': *bp
= '\b'; break;
196 case 'f': *bp
= '\f'; break;
197 case 'n': *bp
= '\n'; break;
198 case 't': *bp
= '\t'; break;
206 if (!isdigit ((unsigned char) *s
)) {
210 r
= ((unsigned char) *s
) != '0' ? 10 : 8;
211 for (i
= 0; isdigit ((unsigned char) *s
); s
++)
212 i
= i
* r
+ ((unsigned char) *s
) - '0';
221 len
= strlen (buffer
) + 1;
222 bp
= mh_xmalloc (len
);
223 memcpy (bp
, buffer
, len
);
229 * Get the fully qualified name of the local host.
231 * If flag is 0, then use anything out of mts.conf (like localname).
232 * If flag is 1, then only use the "proper" local hostname.
238 static char buffer0
[BUFSIZ
] = "";
239 static char buffer1
[BUFSIZ
] = "";
240 static char *buffer
[] = { buffer0
, buffer1
};
242 struct addrinfo hints
, *res
;
244 if (flag
< 0 || flag
> 1)
249 /* check if we have cached the local name */
255 /* check if the mts.conf file specifies a "localname" */
256 if (*localname
&& flag
== 0) {
257 strncpy (buf
, localname
, sizeof(buffer0
));
259 memset(buf
, 0, sizeof(buffer0
));
260 /* first get our local name */
261 gethostname (buf
, sizeof(buffer0
) - 1);
262 /* now fully qualify our name */
264 memset(&hints
, 0, sizeof(hints
));
265 hints
.ai_flags
= AI_CANONNAME
;
266 hints
.ai_family
= PF_UNSPEC
;
267 if (getaddrinfo(buf
, NULL
, &hints
, &res
) == 0) {
268 strncpy(buf
, res
->ai_canonname
, sizeof(buffer0
) - 1);
274 * If the mts.conf file specifies a "localdomain",
275 * we append that now. This should rarely be needed.
279 strcat (buf
, localdomain
);
287 * This is only for UUCP mail. It gets the hostname
288 * as part of the UUCP "domain".
294 static char buffer
[BUFSIZ
] = "";
296 /* check if we have cached the system name */
302 /* check if mts.conf file specifies a "systemname" */
304 strncpy (buffer
, systemname
, sizeof(buffer
));
308 gethostname (buffer
, sizeof(buffer
));
315 * Get the username of current user
321 if (username
[0] == '\0')
329 * Get full name of current user (typically from GECOS
330 * field of password file).
336 if (username
[0] == '\0')
344 * Get the full local mailbox name. This is in the form:
346 * User Name <user@name.com>
352 if (username
[0] == '\0')
359 * Find the user's username and full name, and cache them.
368 if ((pw
= getpwuid (getuid ())) == NULL
369 || pw
->pw_name
== NULL
370 || *pw
->pw_name
== '\0') {
371 strncpy (username
, "unknown", sizeof(username
));
372 snprintf (fullname
, sizeof(fullname
), "The Unknown User-ID (%d)",
379 /* If there's a Local-Mailbox profile component, try to extract
380 the username from it. But don't try very hard, this assumes
381 the very simple User Name <user@name.com> form.
382 Note that post(8) and whom(1) use context_foil (), so they
383 won't see the profile component. */
384 if ((np
= context_find("Local-Mailbox")) != NULL
) {
385 char *left_angle_bracket
= strchr (np
, '<');
386 char *at_sign
= strchr (np
, '@');
387 char *right_angle_bracket
= strchr (np
, '>');
389 strncpy(localmbox
, np
, sizeof(localmbox
));
391 if (left_angle_bracket
&& at_sign
&& right_angle_bracket
) {
392 if (at_sign
> left_angle_bracket
&&
393 at_sign
- left_angle_bracket
< BUFSIZ
) {
394 strncpy(username
, left_angle_bracket
+ 1,
395 at_sign
- left_angle_bracket
- 1);
400 if (username
[0] == '\0') {
401 strncpy (username
, pw
->pw_name
, sizeof(username
));
404 username
[sizeof(username
) - 1] = '\0';
406 escape_local_part(username
, sizeof(username
));
412 /* Get the user's real name from the GECOS field. Stop once we hit a ',',
413 which some OSes use to separate other 'finger' information in the GECOS
414 field, like phone number. */
415 for (cp
= fullname
; *np
!= '\0' && *np
!= ','; *cp
++ = *np
++)
419 /* The $SIGNATURE environment variable overrides the GECOS field's idea of
420 your real name. If SIGNATURE isn't set, use the Signature profile
421 setting if it exists.
422 Note that post(8) and whom(1) use context_foil (), so they
423 won't see the profile component. */
424 if ((cp
= getenv ("SIGNATURE")) && *cp
)
425 strncpy (fullname
, cp
, sizeof(fullname
));
426 else if ((cp
= context_find("Signature")))
427 strncpy (fullname
, cp
, sizeof(fullname
));
429 fullname
[sizeof(fullname
) - 1] = '\0';
431 escape_display_name(fullname
, sizeof(fullname
));
434 /* localmbox, if not using Local-Mailbox */
435 if (localmbox
[0] == '\0') {
436 snprintf(localmbox
, sizeof(localmbox
), "%s <%s@%s>", fullname
,
437 username
, LocalName(0));
440 localmbox
[sizeof(localmbox
) - 1] = '\0';
444 get_mtsconf_pathname (void)
446 const char *cp
= getenv ( "MHMTSCONF" );
447 if (cp
!= NULL
&& *cp
!= '\0') {
454 get_mtsuserconf_pathname (void)
456 const char *cp
= getenv ( "MHMTSUSERCONF" );
457 if (cp
!= NULL
&& *cp
!= '\0') {
464 mts_read_conf_file (FILE *fp
)
466 char *bp
, *cp
, buffer
[BUFSIZ
];
469 while (fgets (buffer
, sizeof(buffer
), fp
)) {
470 if (!(cp
= strchr(buffer
, '\n')))
473 if (*buffer
== '#' || *buffer
== '\0')
475 if (!(bp
= strchr(buffer
, ':')))
478 while (isspace ((unsigned char) *bp
))
481 for (b
= binds
; b
->keyword
; b
++)
482 if (!strcmp (buffer
, b
->keyword
))
484 if (b
->keyword
&& (cp
= tailor_value (bp
)))