1 /* Lua scripting hooks */
13 #include "cache/cache.h"
14 #include "main/event.h"
15 #include "protocol/uri.h"
16 #include "scripting/lua/core.h"
17 #include "scripting/lua/hooks.h"
18 #include "session/location.h"
19 #include "session/session.h"
20 #include "util/string.h"
23 /* The events that will trigger the functions below and what they are expected
24 * to do is explained in doc/events.txt */
26 static enum evhook_status
27 script_hook_goto_url(va_list ap
, void *data
)
29 lua_State
*L
= lua_state
;
30 unsigned char **url
= va_arg(ap
, unsigned char **);
31 struct session
*ses
= va_arg(ap
, struct session
*);
34 if (*url
== NULL
) return EVENT_HOOK_STATUS_NEXT
;
36 lua_getglobal(L
, "goto_url_hook");
37 if (lua_isnil(L
, -1)) {
38 /* The function is not defined */
40 return EVENT_HOOK_STATUS_NEXT
;
43 lua_pushstring(L
, *url
);
45 if (!ses
|| !have_location(ses
)) {
48 lua_pushstring(L
, struri(cur_loc(ses
)->vs
.uri
));
51 if (prepare_lua(ses
)) return EVENT_HOOK_STATUS_NEXT
;
53 err
= lua_pcall(L
, 2, 1, 0);
55 if (err
) return EVENT_HOOK_STATUS_NEXT
;
57 if (lua_isstring(L
, -1)) {
58 unsigned char *new_url
;
60 new_url
= stracpy((unsigned char *) lua_tostring(L
, -1));
62 mem_free_set(url
, new_url
);
64 } else if (lua_isnil(L
, -1)) {
67 alert_lua_error("goto_url_hook must return a string or nil");
72 return EVENT_HOOK_STATUS_NEXT
;
75 static enum evhook_status
76 script_hook_follow_url(va_list ap
, void *data
)
78 lua_State
*L
= lua_state
;
79 unsigned char **url
= va_arg(ap
, unsigned char **);
80 struct session
*ses
= va_arg(ap
, struct session
*);
83 if (*url
== NULL
) return EVENT_HOOK_STATUS_NEXT
;
85 lua_getglobal(L
, "follow_url_hook");
86 if (lua_isnil(L
, -1)) {
87 /* The function is not defined */
89 return EVENT_HOOK_STATUS_NEXT
;
92 lua_pushstring(L
, *url
);
94 if (prepare_lua(ses
)) return EVENT_HOOK_STATUS_NEXT
;
96 err
= lua_pcall(L
, 1, 1, 0);
98 if (err
) return EVENT_HOOK_STATUS_NEXT
;
100 if (lua_isstring(L
, -1)) {
101 unsigned char *new_url
;
103 new_url
= stracpy((unsigned char *) lua_tostring(L
, -1));
105 mem_free_set(url
, new_url
);
107 } else if (lua_isnil(L
, -1)) {
110 alert_lua_error("follow_url_hook must return a string or nil");
115 return EVENT_HOOK_STATUS_NEXT
;
118 static enum evhook_status
119 script_hook_pre_format_html(va_list ap
, void *data
)
121 lua_State
*L
= lua_state
;
122 struct session
*ses
= va_arg(ap
, struct session
*);
123 struct cache_entry
*cached
= va_arg(ap
, struct cache_entry
*);
124 struct fragment
*fragment
= get_cache_fragment(cached
);
125 unsigned char *url
= struri(cached
->uri
);
128 if (!cached
->length
|| !*fragment
->data
) return EVENT_HOOK_STATUS_NEXT
;
130 lua_getglobal(L
, "pre_format_html_hook");
131 if (lua_isnil(L
, -1)) {
132 /* The function is not defined */
134 return EVENT_HOOK_STATUS_NEXT
;
137 lua_pushstring(L
, url
);
138 lua_pushlstring(L
, fragment
->data
, fragment
->length
);
140 if (prepare_lua(ses
)) return EVENT_HOOK_STATUS_NEXT
;
142 err
= lua_pcall(L
, 2, 1, 0);
144 if (err
) return EVENT_HOOK_STATUS_NEXT
;
146 if (lua_isstring(L
, -1)) {
147 int len
= lua_strlen(L
, -1);
149 add_fragment(cached
, 0, (unsigned char *) lua_tostring(L
, -1), len
);
150 normalize_cache_entry(cached
, len
);
151 } else if (!lua_isnil(L
, -1)) {
152 alert_lua_error("pre_format_html_hook must return a string or nil");
157 return EVENT_HOOK_STATUS_NEXT
;
160 /* The Lua function can return:
161 * - "PROXY:PORT" to use the specified proxy
162 * - "" to not use any proxy
163 * - nil to use the default proxies */
164 static enum evhook_status
165 script_hook_get_proxy(va_list ap
, void *data
)
167 lua_State
*L
= lua_state
;
168 unsigned char **new_proxy_url
= va_arg(ap
, unsigned char **);
169 unsigned char *url
= va_arg(ap
, unsigned char *);
172 if (!new_proxy_url
|| !url
)
173 return EVENT_HOOK_STATUS_NEXT
;
175 lua_getglobal(L
, "proxy_for_hook");
176 if (lua_isnil(L
, -1)) {
177 /* The function is not defined */
179 return EVENT_HOOK_STATUS_NEXT
;
182 lua_pushstring(L
, url
);
183 if (prepare_lua(NULL
)) return EVENT_HOOK_STATUS_NEXT
;
185 err
= lua_pcall(L
, 1, 1, 0);
187 if (err
) return EVENT_HOOK_STATUS_NEXT
;
189 if (lua_isstring(L
, -1)) {
190 mem_free_set(new_proxy_url
,
191 stracpy((unsigned char *) lua_tostring(L
, -1)));
192 } else if (lua_isnil(L
, -1)) {
193 mem_free_set(new_proxy_url
, NULL
);
195 alert_lua_error("proxy_hook must return a string or nil");
200 return EVENT_HOOK_STATUS_NEXT
;
203 static enum evhook_status
204 script_hook_quit(va_list ap
, void *data
)
206 if (!prepare_lua(NULL
)) {
207 (void)luaL_dostring(lua_state
, "if quit_hook then quit_hook() end");
211 return EVENT_HOOK_STATUS_NEXT
;
214 struct event_hook_info lua_scripting_hooks
[] = {
215 { "goto-url", 0, script_hook_goto_url
, NULL
},
216 { "follow-url", 0, script_hook_follow_url
, NULL
},
217 { "pre-format-html", 0, script_hook_pre_format_html
, NULL
},
218 { "get-proxy", 0, script_hook_get_proxy
, NULL
},
219 { "quit", 0, script_hook_quit
, NULL
},
220 { "dialog-lua-console", 0, dialog_lua_console
, NULL
},
221 { "free-history", 0, free_lua_console_history
, NULL
},
222 NULL_EVENT_HOOK_INFO
,