*/
#include <lib-lib/lib-lib.h>
+
+#include <sys/types.h>
+#include <pwd.h>
+
#include "lib-lua_priv.h"
#include "../mutt.h"
+/* {{{ madmutt functions */
+
static int madmutt_pwd(lua_State *L)
{
char path[_POSIX_PATH_MAX];
return 1;
}
+static quadopt_t quadopt_parse(const char *s)
+{
+ if (!m_strcasecmp("yes", s))
+ return M_YES;
+ if (!m_strcasecmp("no", s))
+ return M_NO;
+ if (!m_strcasecmp("ask-yes", s))
+ return M_ASKYES;
+ if (!m_strcasecmp("ask-no", s))
+ return M_ASKNO;
+ return -1;
+}
+
+static int madmutt_assign(lua_State *L)
+{
+ const char *idx = luaL_checkstring(L, 2);
+ const char *val = luaL_checkstring(L, 3);
+ int tk;
+
+ switch ((tk = lua_which_token(idx, -1))) {
+ char buf[STRING];
+ int i;
+
+ default:
+ return luaL_error(L, "read-only or inexistant property '%s'", idx, tk);
+
+ case LTK_DOTLOCK:
+ case LTK_SENDMAIL:
+ case LTK_SHELL:
+ case LTK_EDITOR:
+ _mutt_expand_path(buf, sizeof(buf), val, 0);
+ val = buf;
+ /* FALLTHROUGH */
+
+ mlua_regsets(tk, val);
+ return 0;
+
+ case LTK_QUIT:
+ i = quadopt_parse(val);
+ if (i < 0)
+ return luaL_error(L, "invalid quad option value: '%s'", val);
+ mlua_regsetq(tk, i);
+ return 0;
+ }
+}
+
+static int madmutt_get(lua_State *L)
+{
+ const char *idx = luaL_checkstring(L, 2);
+ int tk;
+
+ switch ((tk = lua_which_token(idx, -1))) {
+ default:
+ lua_getmetatable(L, 1);
+ lua_replace(L, 1);
+ lua_rawget(L, 1);
+ return 1;
+
+ case LTK_DOTLOCK:
+ case LTK_SENDMAIL:
+ case LTK_SHELL:
+ lua_pushstring(L, mlua_reggets(tk));
+ break;
+ }
+
+ return 1;
+}
+
static const struct luaL_Reg madmutt_module_funcs[] = {
- {"pwd", madmutt_pwd},
+ { "pwd", madmutt_pwd },
/*
** .pp
** \fIThis is a read-only system property and, at runtime,
** specifies the current working directory of the madmutt
** binary.\fP
*/
- {"folder_path", madmutt_folder_path},
+ { "folder_path", madmutt_folder_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
*/
- {"folder_name", madmutt_folder_name},
+ { "folder_name", madmutt_folder_name },
/*
** .pp
** \fIThis is a read-only system property and, at runtime,
** Third and last, the result will be just the name if neither
** $$$folder nor a ``/'' were found in the name.
*/
- {NULL, NULL}
+
+ { "__newindex", madmutt_assign },
+ { "__index", madmutt_get },
+ { NULL, NULL }
};
+/* }}} */
+
+/* {{{ read-only properties */
+
static const struct {
const char *key;
const char *value;
*/
#ifdef USE_HCACHE
#if defined(HAVE_QDBM)
- {"hcache_backend", "qdbm" },
+ { "hcache_backend", "qdbm" },
#elif defined(HAVE_GDBM)
- {"hcache_backend", "gdbm" },
+ { "hcache_backend", "gdbm" },
#elif defined(HAVE_DB4)
- {"hcache_backend", "db4" },
+ { "hcache_backend", "db4" },
#else
- {"hcache_backend", "unknown" },
+ { "hcache_backend", "unknown" },
#endif
/*
** .pp
#endif
};
+/* }}} */
+
+/* {{{ madmutt magic properties */
+
+static void madmutt_init_editor(char *buf, ssize_t len)
+{
+ m_strcpy(buf, len, getenv("VISUAL") ?: getenv("EDITOR") ?: "vi");
+}
+
+static void madmutt_init_shell(char *buf, ssize_t len)
+{
+ struct passwd *pw = getpwuid(getuid());
+
+ if (pw) {
+ m_strcpy(buf, len, pw->pw_shell);
+ _mutt_expand_path(buf, len, pw->pw_shell, 0);
+ } else {
+ m_strcpy(buf, len, getenv("SHELL") ?: "/bin/sh");
+ }
+}
+
+static const struct {
+ const char *key;
+ void (*fun)(char *buf, ssize_t len);
+ const char *val;
+} madmutt_module_vars2[] = {
+ { "dotlock", NULL, BINDIR "/mutt_dotlock" },
+ /*
+ ** .pp
+ ** Contains the path of the \fTmadmutt_dotlock(1)\fP binary to be used by
+ ** Madmutt.
+ */
+ {"editor", madmutt_init_editor, NULL },
+ /*
+ ** .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.
+ */
+ { "sendmail", NULL, SENDMAIL " -oem -oi" },
+ /*
+ ** .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.
+ */
+ { "shell", madmutt_init_shell, NULL },
+ /*
+ ** .pp
+ ** Command to use when spawning a subshell. By default, the user's login
+ ** shell from \fT/etc/passwd\fP is used.
+ */
+ {"quit", NULL, "yes" }
+ /*
+ ** .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.
+ */
+};
+
+/* }}} */
+
int luaopen_madmutt(lua_State *L)
{
int i;
- luaL_register(L, LUA_MADMUTT, madmutt_module_funcs);
+
+ lua_newuserdata(L, sizeof(void*));
+ luaL_newmetatable(L, "madmutt.core");
+
+ luaL_openlib(L, NULL, madmutt_module_funcs, 0);
for (i = 0; i < countof(madmutt_module_vars); i++) {
lua_pushstring(L, madmutt_module_vars[i].value);
lua_setfield(L, -2, madmutt_module_vars[i].key);
}
+
+ lua_setmetatable(L, -2);
+
+ for (i = 0; i < countof(madmutt_module_vars2); i++) {
+ if (madmutt_module_vars2[i].fun) {
+ char buf[STRING];
+ (madmutt_module_vars2[i].fun)(buf, sizeof(buf));
+ lua_pushstring(L, buf);
+ } else {
+ lua_pushstring(L, madmutt_module_vars2[i].val);
+ }
+ lua_setfield(L, -2, madmutt_module_vars2[i].key);
+ }
+
+ lua_setglobal(L, "madmutt");
return 1;
}