/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. * * Copyright © 2007 Pierre Habouzit */ #include #include #include #include #include #include #include #include "../mutt.h" @import "base.cpkg" static char *madmutt_init_shell(void) { struct passwd *pw = getpwuid(getuid()); return m_strdup(pw ? pw->pw_shell : (getenv("SHELL") ?: "/bin/sh")); } static char *madmutt_init_username(void) { struct passwd *pw = getpwuid(getuid()); return m_strdup(pw ? pw->pw_name : (getenv("USER") ?: "john_doe")); } static char *madmutt_init_homedir(void) { struct passwd *pw = getpwuid(getuid()); return m_strdup(pw ? pw->pw_dir : (getenv("HOME") ?: "/")); } static char *madmutt_init_shorthost(void) { struct utsname utsname; const char *p; /* some systems report the FQDN instead of just the hostname */ uname(&utsname); p = m_strchrnul(utsname.nodename, '.'); return p_dupstr(utsname.nodename, p - utsname.nodename); } static char *madmutt_init_os(void) { struct utsname un; return m_strdup(uname(&un) < 0 ? "Unix" : un.sysname); } static char *madmutt_init_hostname(void) { char buffer[STRING]; if (getdnsdomainname(buffer, sizeof(buffer)) < 0) return m_strdup("@"); if (*buffer != '@') { int len = m_strlen(buffer) + m_strlen(mod_core.shorthost) + 2; char *res = p_new(char, len); snprintf(res, len, "%s.%s", NONULL(mod_core.shorthost), buffer); return res; } return m_strdup(NONULL(mod_core.shorthost)); } static void madmutt_update_cachedir(const char *dir) { static char *cachedir = NULL; char path[_POSIX_PATH_MAX]; char buf[HUGE_STRING]; struct stat st; _mutt_expand_path(path, sizeof(path), dir, 0); if (lstat(path, &st) || !S_ISDIR(st.st_mode)) { snprintf(buf, sizeof(buf), _("Directory %s not exist. Create it?"), dir); if (mutt_yesorno(buf, M_YES) == M_YES) mkdir(path, 0750); } if (lstat(path, &st) || !S_ISDIR(st.st_mode)) { mutt_error(_("Cache directory not created!")); return; } if (st.st_mode & 0027) { snprintf(buf, sizeof(buf), _("Directory %s is unsafe, do you want to use it ?"), dir); if (mutt_yesorno(buf, M_YES) != M_YES) return; } m_strreplace(&cachedir, path); mod_core.cachedir = cachedir; } #if defined(HAVE_QDBM) # define HCACHE_BACKEND "qdbm" #elif defined(HAVE_GDBM) # define HCACHE_BACKEND "gdbm" #elif defined(HAVE_DB4) # define HCACHE_BACKEND "db4" #else # define HCACHE_BACKEND NULL #endif static void mod_core_init2(void) { madmutt_update_cachedir("~/.cache/madmutt"); } #define mod_core_init() do { (mod_core_init)(); mod_core_init2(); } while (0) @package mod_core { /* ** .pp ** \fIThis is a read-only system property and specifies madmutt's ** version string.\fP */ const string_t version = VERSION; /* ** .pp ** \fIThis is a read-only system property and specifies madmutt's ** subversion revision string.\fP */ const string_t sysconfdir = SYSCONFDIR; /* ** .pp ** \fIThis is a read-only system property and specifies the ** directory containing the madmutt binary.\fP */ const string_t bindir = BINDIR; /* ** .pp ** \fIThis is a read-only system property and specifies the ** directory containing the madmutt documentation.\fP */ const string_t docdir = PKGDOCDIR; /* ** .pp ** \fIThis is a read-only system property and specifies the ** header chaching's database backend.\fP */ const string_t hcache_backend = HCACHE_BACKEND; /* ** .pp ** This variable specifies which editor is used by Madmutt. ** It defaults to the value of the \fT$$$VISUAL\fP, or \fT$$$EDITOR\fP, environment ** variable, or to the string "\fTvi\fP" if neither of those are set. */ path_t editor = m_strdup(getenv("VISUAL") ?: getenv("EDITOR") ?: "vi"); /* ** .pp ** Command to use when spawning a subshell. By default, the user's login ** shell from \fT/etc/passwd\fP is used. */ path_t shell = madmutt_init_shell(); /* ** .pp ** This specifies the operating system name for the \fTUser-Agent:\fP header field. If ** this is \fIunset\fP, it will be set to the operating system name that \fTuname(2)\fP ** returns. If \fTuname(2)\fP fails, ``UNIX'' will be used. ** .pp ** It may, for example, look as: ``\fTMadmutt 1.5.9i (Linux)\fP''. */ string_t operating_system = madmutt_init_os(); path_t username = madmutt_init_username(); path_t homedir = madmutt_init_homedir(); /* ** .pp ** Specifies the hostname to use after the ``\fT@\fP'' in local e-mail ** addresses and during generation of \fTMessage-ID:\fP headers. ** .pp ** Please be sure to really know what you are doing when changing this variable ** to configure a custom domain part of Message-IDs. */ string_t shorthost = madmutt_init_shorthost(); string_t hostname = madmutt_init_hostname(); /* ** .pp ** This variable allows you to specify where Madmutt will place its ** temporary files needed for displaying and composing messages. If ** this variable is not set, the environment variable \fT$$$TMPDIR\fP is ** used. If \fT$$$TMPDIR\fP is not set then "\fT/tmp\fP" is used. */ path_t tmpdir = m_strdup(getenv("TMPDIR") ?: "/tmp"); /* ** .pp ** A regular expression used by Madmutt to parse the GECOS field of a password ** entry when expanding the alias. By default the regular expression is set ** to ``\fT^[^,]*\fP'' which will return the string up to the first ``\fT,\fP'' encountered. ** If the GECOS field contains a string like "lastname, firstname" then you ** should do: \fTset gecos_mask=".*"\fP. ** .pp ** This can be useful if you see the following behavior: you address a e-mail ** to user ID stevef whose full name is Steve Franklin. If Madmutt expands ** stevef to ``Franklin'' stevef@foo.bar then you should set the gecos_mask to ** a regular expression that will match the whole name so Madmutt will expand ** ``Franklin'' to ``Franklin, Steve''. */ rx_t gecos_mask = luaM_rxnew("^[^,]*"); /* ** .pp ** This variable controls whether ``quit'' and ``exit'' actually quit ** from Madmutt. If it set to \fIyes\fP, they do quit, if it is set to \fIno\fP, they ** have no effect, and if it is set to \fIask-yes\fP or \fIask-no\fP, you are ** prompted for confirmation when you try to quit. */ quadopt_t quit = M_YES; /* ** .pp ** When this variable is \fIset\fP, Madmutt will beep when an error occurs. */ bool beep = 1; /* ** .pp ** When this variable is \fIset\fP, Madmutt will beep whenever it prints a message ** notifying you of new mail. This is independent of the setting of the ** ``$$beep'' variable. */ bool beep_new = 0; /* ** .pp ** When \fIset\fP, Madmutt will qualify all local addresses (ones without the ** @host portion) with the value of ``$$hostname''. If \fIunset\fP, no ** addresses will be qualified. */ bool use_domain = 1; /* ** .pp ** \fIThis is a read-only system property and, at runtime, ** specifies the current working directory of the madmutt ** binary.\fP */ const string_t pwd(void) { char path[_POSIX_PATH_MAX]; getcwd(path, sizeof(path)); RETURN(path); }; /* ** .pp ** \fIThis is a read-only system property and, at runtime, ** specifies the full path or URI of the folder currently ** open (if any).\fP */ const string_t folder_path(void) { RETURN(CurrentFolder); }; /* ** .pp ** \fIThis is a read-only system property and, at runtime, ** specifies the actual name of the folder as far as it could ** be detected.\fP ** .pp ** For detection, $$$folder is first taken into account ** and simply stripped to form the result when a match is found. For ** example, with $$$folder being \fTimap://host\fP and the folder is ** \fTimap://host/INBOX/foo\fP, $$$madmutt_folder_name will be just ** \fTINBOX/foo\fP.) ** .pp ** Second, if the initial portion of a name is not $$$folder, ** the result will be everything after the last ``/''. ** .pp ** Third and last, the result will be just the name if neither ** $$$folder nor a ``/'' were found in the name. */ const string_t folder_name(void) { const char *p; if (!m_strisempty(Maildir) && m_strstart(CurrentFolder, Maildir, &p) && *p) { while (*p == '/') p++; RETURN(p); } else { p = strchr(CurrentFolder ?: "", '/'); RETURN(p ? p + 1 : (CurrentFolder ?: "")); } }; const string_t cachedir = NULL; void setcachedir(const string_t path) { madmutt_update_cachedir(path); RETURN(); }; }; @package MTransport { /* ** .pp ** Specifies the program and arguments used to deliver mail sent by Madmutt. ** Madmutt expects that the specified program interprets additional ** arguments as recipient addresses. */ path_t sendmail = m_strdup(SENDMAIL " -eom -oi"); /* ** .pp ** \fBNote:\fP you should not enable this unless you are using Sendmail ** 8.8.x or greater. ** .pp ** This variable sets the request for when notification is returned. The ** string consists of a comma separated list (no spaces!) of one or more ** of the following: \fInever\fP, to never request notification, ** \fIfailure\fP, to request notification on transmission failure, ** \fIdelay\fP, to be notified of message delays, \fIsuccess\fP, to be ** notified of successful transmission. ** .pp ** Example: \fTset dsn_notify="failure,delay"\fP */ /* TODO: check it's NULL, hdrs or full */ string_t dsn_notify = NULL; /* ** .pp ** \fBNote:\fP you should not enable this unless you are using Sendmail ** 8.8.x or greater. ** .pp ** This variable controls how much of your message is returned in DSN ** messages. It may be set to either \fIhdrs\fP to return just the ** message header, or \fIfull\fP to return the full message. ** .pp ** Example: \fTset dsn_return=hdrs\fP */ /* TODO: check it's never, delay, failure, success with ',' */ string_t dsn_return = NULL; /* ** .pp ** Specifies the number of seconds to wait for the ``$$sendmail'' process ** to finish before giving up and putting delivery in the background. ** .pp ** Madmutt interprets the value of this variable as follows: ** .dl ** .dt >0 .dd number of seconds to wait for sendmail to finish before continuing ** .dt 0 .dd wait forever for sendmail to finish ** .dt <0 .dd always put sendmail in the background without waiting ** .de ** .pp ** Note that if you specify a value other than 0, the output of the child ** process will be put in a temporary file. If there is some error, you ** will be informed as to where to find the output. */ int sendmail_wait = 0; /* ** .pp ** \fBWarning:\fP do not set this variable unless you are using a version ** of sendmail which supports the \fT-B8BITMIME\fP flag (such as sendmail ** 8.8.x). ** Otherwise you may not be able to send mail. ** .pp ** When \fIset\fP, Madmutt will either invoke ``$$sendmail'' with the \fT-B8BITMIME\fP ** flag when sending 8-bit messages to enable ESMTP negotiation. */ bool use_8bitmime = 0; /* ** .pp ** When \fIset\fP, Madmutt will use ``$$envelope_from_address'' as the ** \fIenvelope\fP sender if that is set, otherwise it will attempt to ** derive it from the "From:" header. ** ** .pp ** \fBNote:\fP This information is passed to sendmail command using the ** "-f" command line switch. */ bool use_envelope_from = 0; /* ** .pp ** Manually sets the \fIenvelope\fP sender for outgoing messages. ** This value is ignored if ``$$use_envelope_from'' is unset. */ address_t envelope_from_address = NULL; }; /* vim:set ft=c: */