2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or (at
5 * your option) any later version.
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
10 * General Public License for more details.
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 * Copyright © 2007 Pierre Habouzit
20 #include <lib-lib/lib-lib.h>
22 #include <sys/types.h>
25 #include "lib-lua_priv.h"
29 /* {{{ madmutt functions */
31 static int madmutt_pwd(lua_State *L)
33 char path[_POSIX_PATH_MAX];
34 getcwd(path, sizeof(path));
35 lua_pushstring(L, path);
39 static int madmutt_folder_path(lua_State *L)
41 lua_pushstring(L, CurrentFolder ?: "");
45 static int madmutt_folder_name(lua_State *L)
49 if (!m_strisempty(Maildir)
50 && m_strstart(CurrentFolder, Maildir, &p) && *p) {
55 p = strchr(CurrentFolder ?: "", '/');
56 lua_pushstring(L, p ? p + 1 : (CurrentFolder ?: ""));
61 static quadopt_t quadopt_parse(const char *s)
63 if (!m_strcasecmp("yes", s))
65 if (!m_strcasecmp("no", s))
67 if (!m_strcasecmp("ask-yes", s))
69 if (!m_strcasecmp("ask-no", s))
74 static int madmutt_assign(lua_State *L)
76 const char *idx = luaL_checkstring(L, 2);
77 const char *val = luaL_checkstring(L, 3);
80 switch ((tk = lua_which_token(idx, -1))) {
88 _mutt_expand_path(buf, sizeof(buf), val, 0);
92 mlua_regsets(tk, val);
96 i = quadopt_parse(val);
98 return luaL_error(L, "invalid quad option value: '%s'", val);
107 return luaL_error(L, "read-only or inexistant property '%s'", idx, tk);
110 static int madmutt_get(lua_State *L)
112 const char *idx = luaL_checkstring(L, 2);
113 enum lua_token tk = lua_which_token(idx, -1);
120 lua_pushstring(L, mlua_reggets(tk));
124 switch (mlua_reggeti(tk)) {
126 lua_pushstring(L, "yes");
129 lua_pushstring(L, "no");
132 lua_pushstring(L, "ask-no");
135 lua_pushstring(L, "ask-yes");
146 lua_getmetatable(L, 1);
152 static const struct luaL_Reg madmutt_module_funcs[] = {
153 { "pwd", madmutt_pwd },
156 ** \fIThis is a read-only system property and, at runtime,
157 ** specifies the current working directory of the madmutt
160 { "folder_path", madmutt_folder_path },
163 ** \fIThis is a read-only system property and, at runtime,
164 ** specifies the full path or URI of the folder currently
167 { "folder_name", madmutt_folder_name },
170 ** \fIThis is a read-only system property and, at runtime,
171 ** specifies the actual name of the folder as far as it could
174 ** For detection, $$$folder is first taken into account
175 ** and simply stripped to form the result when a match is found. For
176 ** example, with $$$folder being \fTimap://host\fP and the folder is
177 ** \fTimap://host/INBOX/foo\fP, $$$madmutt_folder_name will be just
180 ** Second, if the initial portion of a name is not $$$folder,
181 ** the result will be everything after the last ``/''.
183 ** Third and last, the result will be just the name if neither
184 ** $$$folder nor a ``/'' were found in the name.
187 { "__newindex", madmutt_assign },
188 { "__index", madmutt_get },
194 /* {{{ read-only properties */
196 static const struct {
199 } madmutt_module_vars[] = {
200 { "version", VERSION },
203 ** \fIThis is a read-only system property and specifies madmutt's
204 ** version string.\fP
206 { "sysconfdir", SYSCONFDIR },
209 ** \fIThis is a read-only system property and specifies madmutt's
210 ** subversion revision string.\fP
212 { "bindir", BINDIR },
215 ** \fIThis is a read-only system property and specifies the
216 ** directory containing the madmutt binary.\fP
218 { "docdir", PKGDOCDIR },
221 ** \fIThis is a read-only system property and specifies the
222 ** directory containing the madmutt documentation.\fP
225 #if defined(HAVE_QDBM)
226 { "hcache_backend", "qdbm" },
227 #elif defined(HAVE_GDBM)
228 { "hcache_backend", "gdbm" },
229 #elif defined(HAVE_DB4)
230 { "hcache_backend", "db4" },
232 { "hcache_backend", "unknown" },
236 ** \fIThis is a read-only system property and specifies the
237 ** header chaching's database backend.\fP
244 /* {{{ madmutt magic properties */
246 static void madmutt_init_editor(char *buf, ssize_t len)
248 m_strcpy(buf, len, getenv("VISUAL") ?: getenv("EDITOR") ?: "vi");
251 static void madmutt_init_shell(char *buf, ssize_t len)
253 struct passwd *pw = getpwuid(getuid());
256 m_strcpy(buf, len, pw->pw_shell);
257 _mutt_expand_path(buf, len, pw->pw_shell, 0);
259 m_strcpy(buf, len, getenv("SHELL") ?: "/bin/sh");
263 static const struct {
265 void (*fun)(char *buf, ssize_t len);
267 } madmutt_module_vars2[] = {
268 { "dotlock", NULL, BINDIR "/mutt_dotlock" },
271 ** Contains the path of the \fTmadmutt_dotlock(1)\fP binary to be used by
274 { "editor", madmutt_init_editor, NULL },
277 ** This variable specifies which editor is used by Madmutt.
278 ** It defaults to the value of the \fT$$$VISUAL\fP, or \fT$$$EDITOR\fP, environment
279 ** variable, or to the string "\fTvi\fP" if neither of those are set.
281 { "sendmail", NULL, SENDMAIL " -oem -oi" },
284 ** Specifies the program and arguments used to deliver mail sent by Madmutt.
285 ** Madmutt expects that the specified program interprets additional
286 ** arguments as recipient addresses.
288 { "shell", madmutt_init_shell, NULL },
291 ** Command to use when spawning a subshell. By default, the user's login
292 ** shell from \fT/etc/passwd\fP is used.
294 { "quit", NULL, "yes" },
297 ** This variable controls whether ``quit'' and ``exit'' actually quit
298 ** from Madmutt. If it set to \fIyes\fP, they do quit, if it is set to \fIno\fP, they
299 ** have no effect, and if it is set to \fIask-yes\fP or \fIask-no\fP, you are
300 ** prompted for confirmation when you try to quit.
306 int luaopen_madmutt(lua_State *L)
310 lua_newuserdata(L, sizeof(void*));
311 luaL_newmetatable(L, "madmutt.core");
313 luaL_openlib(L, NULL, madmutt_module_funcs, 0);
315 for (i = 0; i < countof(madmutt_module_vars); i++) {
316 lua_pushstring(L, madmutt_module_vars[i].value);
317 lua_setfield(L, -2, madmutt_module_vars[i].key);
320 lua_setmetatable(L, -2);
322 for (i = 0; i < countof(madmutt_module_vars2); i++) {
323 if (madmutt_module_vars2[i].fun) {
325 (madmutt_module_vars2[i].fun)(buf, sizeof(buf));
326 lua_pushstring(L, buf);
328 lua_pushstring(L, madmutt_module_vars2[i].val);
330 lua_setfield(L, -2, madmutt_module_vars2[i].key);
333 lua_setglobal(L, "madmutt");