1 /* Lua scripting hooks */
9 #include "cache/cache.h"
10 #include "main/event.h"
11 #include "protocol/uri.h"
12 #include "scripting/lua/core.h"
13 #include "scripting/lua/hooks.h"
14 #include "session/location.h"
15 #include "session/session.h"
16 #include "util/string.h"
19 /* The events that will trigger the functions below and what they are expected
20 * to do is explained in doc/events.txt */
22 static enum evhook_status
23 script_hook_goto_url(va_list ap
, void *data
)
25 lua_State
*L
= lua_state
;
26 unsigned char **url
= va_arg(ap
, unsigned char **);
27 struct session
*ses
= va_arg(ap
, struct session
*);
30 if (*url
== NULL
) return EVENT_HOOK_STATUS_NEXT
;
32 lua_getglobal(L
, "goto_url_hook");
33 if (lua_isnil(L
, -1)) {
34 /* The function is not defined */
36 return EVENT_HOOK_STATUS_NEXT
;
39 lua_pushstring(L
, *url
);
41 if (!ses
|| !have_location(ses
)) {
44 lua_pushstring(L
, struri(cur_loc(ses
)->vs
.uri
));
47 if (prepare_lua(ses
)) return EVENT_HOOK_STATUS_NEXT
;
49 err
= lua_pcall(L
, 2, 1, 0);
51 if (err
) return EVENT_HOOK_STATUS_NEXT
;
53 if (lua_isstring(L
, -1)) {
54 unsigned char *new_url
;
56 new_url
= stracpy((unsigned char *) lua_tostring(L
, -1));
58 mem_free_set(url
, new_url
);
60 } else if (lua_isnil(L
, -1)) {
63 alert_lua_error("goto_url_hook must return a string or nil");
68 return EVENT_HOOK_STATUS_NEXT
;
71 static enum evhook_status
72 script_hook_follow_url(va_list ap
, void *data
)
74 lua_State
*L
= lua_state
;
75 unsigned char **url
= va_arg(ap
, unsigned char **);
76 struct session
*ses
= va_arg(ap
, struct session
*);
79 if (*url
== NULL
) return EVENT_HOOK_STATUS_NEXT
;
81 lua_getglobal(L
, "follow_url_hook");
82 if (lua_isnil(L
, -1)) {
83 /* The function is not defined */
85 return EVENT_HOOK_STATUS_NEXT
;
88 lua_pushstring(L
, *url
);
90 if (prepare_lua(ses
)) return EVENT_HOOK_STATUS_NEXT
;
92 err
= lua_pcall(L
, 1, 1, 0);
94 if (err
) return EVENT_HOOK_STATUS_NEXT
;
96 if (lua_isstring(L
, -1)) {
97 unsigned char *new_url
;
99 new_url
= stracpy((unsigned char *) lua_tostring(L
, -1));
101 mem_free_set(url
, new_url
);
103 } else if (lua_isnil(L
, -1)) {
106 alert_lua_error("follow_url_hook must return a string or nil");
111 return EVENT_HOOK_STATUS_NEXT
;
114 static enum evhook_status
115 script_hook_pre_format_html(va_list ap
, void *data
)
117 lua_State
*L
= lua_state
;
118 struct session
*ses
= va_arg(ap
, struct session
*);
119 struct cache_entry
*cached
= va_arg(ap
, struct cache_entry
*);
120 struct fragment
*fragment
= get_cache_fragment(cached
);
121 unsigned char *url
= struri(cached
->uri
);
124 if (!cached
->length
|| !*fragment
->data
) return EVENT_HOOK_STATUS_NEXT
;
126 lua_getglobal(L
, "pre_format_html_hook");
127 if (lua_isnil(L
, -1)) {
128 /* The function is not defined */
130 return EVENT_HOOK_STATUS_NEXT
;
133 lua_pushstring(L
, url
);
134 lua_pushlstring(L
, fragment
->data
, fragment
->length
);
136 if (prepare_lua(ses
)) return EVENT_HOOK_STATUS_NEXT
;
138 err
= lua_pcall(L
, 2, 1, 0);
140 if (err
) return EVENT_HOOK_STATUS_NEXT
;
142 if (lua_isstring(L
, -1)) {
143 int len
= lua_strlen(L
, -1);
145 add_fragment(cached
, 0, (unsigned char *) lua_tostring(L
, -1), len
);
146 normalize_cache_entry(cached
, len
);
147 } else if (!lua_isnil(L
, -1)) {
148 alert_lua_error("pre_format_html_hook must return a string or nil");
153 return EVENT_HOOK_STATUS_NEXT
;
156 /* The Lua function can return:
157 * - "PROXY:PORT" to use the specified proxy
158 * - "" to not use any proxy
159 * - nil to use the default proxies */
160 static enum evhook_status
161 script_hook_get_proxy(va_list ap
, void *data
)
163 lua_State
*L
= lua_state
;
164 unsigned char **new_proxy_url
= va_arg(ap
, unsigned char **);
165 unsigned char *url
= va_arg(ap
, unsigned char *);
168 if (!new_proxy_url
|| !url
)
169 return EVENT_HOOK_STATUS_NEXT
;
171 lua_getglobal(L
, "proxy_for_hook");
172 if (lua_isnil(L
, -1)) {
173 /* The function is not defined */
175 return EVENT_HOOK_STATUS_NEXT
;
178 lua_pushstring(L
, url
);
179 if (prepare_lua(NULL
)) return EVENT_HOOK_STATUS_NEXT
;
181 err
= lua_pcall(L
, 1, 1, 0);
183 if (err
) return EVENT_HOOK_STATUS_NEXT
;
185 if (lua_isstring(L
, -1)) {
186 mem_free_set(new_proxy_url
,
187 stracpy((unsigned char *) lua_tostring(L
, -1)));
188 } else if (lua_isnil(L
, -1)) {
189 mem_free_set(new_proxy_url
, NULL
);
191 alert_lua_error("proxy_hook must return a string or nil");
196 return EVENT_HOOK_STATUS_NEXT
;
199 static enum evhook_status
200 script_hook_quit(va_list ap
, void *data
)
202 if (!prepare_lua(NULL
)) {
203 lua_dostring(lua_state
, "if quit_hook then quit_hook() end");
207 return EVENT_HOOK_STATUS_NEXT
;
210 struct event_hook_info lua_scripting_hooks
[] = {
211 { "goto-url", 0, script_hook_goto_url
, NULL
},
212 { "follow-url", 0, script_hook_follow_url
, NULL
},
213 { "pre-format-html", 0, script_hook_pre_format_html
, NULL
},
214 { "get-proxy", 0, script_hook_get_proxy
, NULL
},
215 { "quit", 0, script_hook_quit
, NULL
},
216 { "dialog-lua-console", 0, dialog_lua_console
, NULL
},
217 { "free-history", 0, free_lua_console_history
, NULL
},
218 NULL_EVENT_HOOK_INFO
,