mirror of
https://github.com/weechat/weechat.git
synced 2026-07-02 15:53:12 +02:00
api: add function hook_url
This commit is contained in:
+1
-2
@@ -27,8 +27,7 @@ New features::
|
||||
* core: add options weechat.buffer.* to save buffer properties set by user, add option `setauto` in command `/buffer` (issue #352)
|
||||
* core: add parameters and key bindings to move to edges of current area with commands `/cursor go` and `/cursor move` (issue #1282)
|
||||
* core: add variables "_chat_focused_line_bol" and "_chat_focused_line_eol" in focus data (issue #1955)
|
||||
* core: add algorithms `sha512-224`, `sha512-256`, `sha3-*`, blake2b-*` and `blake2s-*` in option sec.crypt.hash_algo (issue #2008)
|
||||
* api: add algorithms `sha512-224`, `sha512-256`, blake2b-*` and `blake2s-*` in hash functions (issue #2008)
|
||||
* api: add function hook_url, add option `url` in command `/debug` (issue #1723)
|
||||
* api: add support of path to variable and hashtable comparison in function hdata_compare (issue #1066)
|
||||
* api: add infos "nick_color_ignore_case" and "nick_color_name_ignore_case" (issue #194)
|
||||
* api: add info "buffer" (issue #1962)
|
||||
|
||||
@@ -167,6 +167,7 @@ WeeChat "core" is located in following directories:
|
||||
| wee-hook-process.c | Hook "process".
|
||||
| wee-hook-signal.c | Hook "signal".
|
||||
| wee-hook-timer.c | Hook "timer".
|
||||
| wee-hook-url.c | Hook "url".
|
||||
| gui/ | Functions for buffers, windows, ... (used by all interfaces).
|
||||
| gui-bar-item.c | Bar items.
|
||||
| gui-bar-window.c | Bar windows.
|
||||
|
||||
@@ -169,6 +169,7 @@ Le cœur de WeeChat est situé dans les répertoires suivants :
|
||||
| wee-hook-process.c | Hook "process".
|
||||
| wee-hook-signal.c | Hook "signal".
|
||||
| wee-hook-timer.c | Hook "timer".
|
||||
| wee-hook-url.c | Hook "url".
|
||||
| gui/ | Fonctions pour les tampons, fenêtres, ... (utilisées par toutes les interfaces).
|
||||
| gui-bar-item.c | Objets de barre.
|
||||
| gui-bar-window.c | Fenêtres de barre.
|
||||
|
||||
@@ -180,6 +180,7 @@ WeeChat "core" は以下のディレクトリに配置されています:
|
||||
| wee-hook-process.c | "process" フック
|
||||
| wee-hook-signal.c | "signal" フック
|
||||
| wee-hook-timer.c | "timer" フック
|
||||
| wee-hook-url.c | "url" フック
|
||||
| gui/ | バッファ、ウィンドウなどの関数 (全てのインターフェースで利用)
|
||||
| gui-bar-item.c | バー要素
|
||||
| gui-bar-window.c | バーウィンドウ
|
||||
|
||||
@@ -169,6 +169,7 @@ WeeChat „језгро” се налази у следећим директо
|
||||
| wee-hook-process.c | Кука "process".
|
||||
| wee-hook-signal.c | Кука "signal".
|
||||
| wee-hook-timer.c | Кука "timer".
|
||||
| wee-hook-url.c | Кука "url".
|
||||
| gui/ | Функције за бафере, прозоре, ... (користе их сви интерфејси).
|
||||
| gui-bar-item.c | Ставке трака.
|
||||
| gui-bar-window.c | Прозори трака.
|
||||
|
||||
@@ -35,6 +35,8 @@ SET(WEECHAT_SOURCES
|
||||
./src/core/hook/wee-hook-signal.h
|
||||
./src/core/hook/wee-hook-timer.c
|
||||
./src/core/hook/wee-hook-timer.h
|
||||
./src/core/hook/wee-hook-url.c
|
||||
./src/core/hook/wee-hook-url.h
|
||||
./src/core/wee-arraylist.c
|
||||
./src/core/wee-arraylist.h
|
||||
./src/core/wee-backtrace.c
|
||||
|
||||
@@ -72,6 +72,7 @@ set(LIB_CORE_SRC
|
||||
hook/wee-hook-process.c hook/wee-hook-process.h
|
||||
hook/wee-hook-signal.c hook/wee-hook-signal.h
|
||||
hook/wee-hook-timer.c hook/wee-hook-timer.h
|
||||
hook/wee-hook-url.c hook/wee-hook-url.h
|
||||
)
|
||||
|
||||
# Check for flock support
|
||||
|
||||
@@ -278,7 +278,9 @@ hook_process_child (struct t_hook *hook_process)
|
||||
{
|
||||
ptr_url++;
|
||||
}
|
||||
rc = weeurl_download (ptr_url, HOOK_PROCESS(hook_process, options));
|
||||
rc = weeurl_download (ptr_url,
|
||||
HOOK_PROCESS(hook_process, options),
|
||||
NULL); /* output */
|
||||
}
|
||||
else if (strncmp (HOOK_PROCESS(hook_process, command), "func:", 5) == 0)
|
||||
{
|
||||
|
||||
@@ -0,0 +1,419 @@
|
||||
/*
|
||||
* wee-hook-url.c - WeeChat URL hook
|
||||
*
|
||||
* Copyright (C) 2023 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <poll.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "../weechat.h"
|
||||
#include "../wee-hashtable.h"
|
||||
#include "../wee-hook.h"
|
||||
#include "../wee-infolist.h"
|
||||
#include "../wee-log.h"
|
||||
#include "../wee-string.h"
|
||||
#include "../wee-url.h"
|
||||
#include "../../gui/gui-chat.h"
|
||||
#include "../../plugins/plugin.h"
|
||||
|
||||
|
||||
/*
|
||||
* Returns description of hook.
|
||||
*
|
||||
* Note: result must be freed after use.
|
||||
*/
|
||||
|
||||
char *
|
||||
hook_url_get_description (struct t_hook *hook)
|
||||
{
|
||||
char str_desc[1024];
|
||||
|
||||
snprintf (str_desc, sizeof (str_desc),
|
||||
"URL: \"%s\", thread id: %d",
|
||||
HOOK_URL(hook, url),
|
||||
0);
|
||||
|
||||
return strdup (str_desc);
|
||||
}
|
||||
|
||||
/*
|
||||
* Displays keys and values of a hashtable.
|
||||
*/
|
||||
|
||||
void
|
||||
hook_url_hashtable_map_cb (void *data, struct t_hashtable *hashtable,
|
||||
const void *key, const void *value)
|
||||
{
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) hashtable;
|
||||
|
||||
gui_chat_printf (NULL, " %s: \"%s\"",
|
||||
(const char *)key,
|
||||
(const char *)value);
|
||||
}
|
||||
|
||||
/*
|
||||
* Runs callback of url hook.
|
||||
*/
|
||||
|
||||
void
|
||||
hook_url_run_callback (struct t_hook *hook)
|
||||
{
|
||||
if (url_debug)
|
||||
{
|
||||
gui_chat_printf (NULL, "Running hook_url callback for URL \"%s\":",
|
||||
HOOK_URL(hook, url));
|
||||
gui_chat_printf (NULL, " options:");
|
||||
hashtable_map (HOOK_URL(hook, options), &hook_url_hashtable_map_cb, NULL);
|
||||
gui_chat_printf (NULL, " output:");
|
||||
hashtable_map (HOOK_URL(hook, output), &hook_url_hashtable_map_cb, NULL);
|
||||
}
|
||||
|
||||
(void) (HOOK_URL(hook, callback))
|
||||
(hook->callback_pointer,
|
||||
hook->callback_data,
|
||||
HOOK_URL(hook, url),
|
||||
HOOK_URL(hook, options),
|
||||
HOOK_URL(hook, output));
|
||||
}
|
||||
|
||||
/*
|
||||
* Thread cleanup function: mark thread as not running any more.
|
||||
*/
|
||||
|
||||
void
|
||||
hook_url_thread_cleanup (void *hook_pointer)
|
||||
{
|
||||
struct t_hook *hook;
|
||||
|
||||
hook = (struct t_hook *)hook_pointer;
|
||||
|
||||
HOOK_URL(hook, thread_running) = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* URL transfer (in a separate thread).
|
||||
*/
|
||||
|
||||
void *
|
||||
hook_url_transfer_thread (void *hook_pointer)
|
||||
{
|
||||
struct t_hook *hook;
|
||||
|
||||
hook = (struct t_hook *)hook_pointer;
|
||||
|
||||
pthread_cleanup_push (&hook_url_thread_cleanup, hook);
|
||||
|
||||
(void) weeurl_download (HOOK_URL(hook, url),
|
||||
HOOK_URL(hook, options),
|
||||
HOOK_URL(hook, output));
|
||||
|
||||
pthread_cleanup_pop (1);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if thread is still alive.
|
||||
*/
|
||||
|
||||
int
|
||||
hook_url_timer_cb (const void *pointer, void *data, int remaining_calls)
|
||||
{
|
||||
struct t_hook *hook;
|
||||
const char *ptr_error;
|
||||
|
||||
/* make C compiler happy */
|
||||
(void) data;
|
||||
(void) remaining_calls;
|
||||
|
||||
hook = (struct t_hook *)pointer;
|
||||
|
||||
if (hook->deleted)
|
||||
return WEECHAT_RC_OK;
|
||||
|
||||
if (!HOOK_URL(hook, thread_running))
|
||||
{
|
||||
hook_url_run_callback (hook);
|
||||
ptr_error = hashtable_get (HOOK_URL(hook, output), "error");
|
||||
if (ptr_error && ptr_error[0])
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("%sURL transfer error: %s (URL: \"%s\")"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
ptr_error,
|
||||
HOOK_URL(hook, url));
|
||||
}
|
||||
unhook (hook);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
if (remaining_calls == 0)
|
||||
{
|
||||
hook_url_run_callback (hook);
|
||||
if (weechat_debug_core >= 1)
|
||||
{
|
||||
gui_chat_printf (
|
||||
NULL,
|
||||
_("End of URL transfer '%s', timeout reached (%.1fs)"),
|
||||
HOOK_URL(hook, url),
|
||||
((float)HOOK_URL(hook, timeout)) / 1000);
|
||||
}
|
||||
pthread_cancel (HOOK_URL(hook, thread_id));
|
||||
usleep (1000);
|
||||
unhook (hook);
|
||||
}
|
||||
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Starts transfer for an URL hook.
|
||||
*/
|
||||
|
||||
void
|
||||
hook_url_transfer (struct t_hook *hook)
|
||||
{
|
||||
int rc, timeout, max_calls;
|
||||
long interval;
|
||||
|
||||
HOOK_URL(hook, thread_running) = 1;
|
||||
|
||||
/* create thread */
|
||||
rc = pthread_create (&(HOOK_URL(hook, thread_id)), NULL,
|
||||
&hook_url_transfer_thread, hook);
|
||||
if (rc != 0)
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sError running thread in hook_url: %s (URL: \"%s\")"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR],
|
||||
strerror (rc),
|
||||
HOOK_URL(hook, url));
|
||||
unhook (hook);
|
||||
return;
|
||||
}
|
||||
|
||||
/* main thread */
|
||||
timeout = HOOK_URL(hook, timeout);
|
||||
interval = 100;
|
||||
max_calls = 0;
|
||||
if (timeout > 0)
|
||||
{
|
||||
if (timeout <= 100)
|
||||
{
|
||||
interval = timeout;
|
||||
max_calls = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
interval = 100;
|
||||
max_calls = timeout / 100;
|
||||
if (timeout % 100 == 0)
|
||||
max_calls++;
|
||||
}
|
||||
}
|
||||
HOOK_URL(hook, hook_timer) = hook_timer (hook->plugin,
|
||||
interval, 0, max_calls,
|
||||
&hook_url_timer_cb,
|
||||
hook,
|
||||
NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Hooks a URL.
|
||||
*
|
||||
* Returns pointer to new hook, NULL if error.
|
||||
*/
|
||||
|
||||
struct t_hook *
|
||||
hook_url (struct t_weechat_plugin *plugin,
|
||||
const char *url,
|
||||
struct t_hashtable *options,
|
||||
int timeout,
|
||||
t_hook_callback_url *callback,
|
||||
const void *callback_pointer,
|
||||
void *callback_data)
|
||||
{
|
||||
struct t_hook *new_hook;
|
||||
struct t_hook_url *new_hook_url;
|
||||
|
||||
new_hook = NULL;
|
||||
new_hook_url = NULL;
|
||||
|
||||
if (!url || !url[0] || !callback)
|
||||
goto error;
|
||||
|
||||
new_hook = malloc (sizeof (*new_hook));
|
||||
if (!new_hook)
|
||||
goto error;
|
||||
|
||||
new_hook_url = malloc (sizeof (*new_hook_url));
|
||||
if (!new_hook_url)
|
||||
goto error;
|
||||
|
||||
hook_init_data (new_hook, plugin, HOOK_TYPE_URL, HOOK_PRIORITY_DEFAULT,
|
||||
callback_pointer, callback_data);
|
||||
|
||||
new_hook->hook_data = new_hook_url;
|
||||
new_hook_url->callback = callback;
|
||||
new_hook_url->url = strdup (url);
|
||||
new_hook_url->options = (options) ? hashtable_dup (options) : NULL;
|
||||
new_hook_url->timeout = timeout;
|
||||
new_hook_url->thread_id = 0;
|
||||
new_hook_url->thread_running = 0;
|
||||
new_hook_url->hook_timer = NULL;
|
||||
new_hook_url->output = hashtable_new (32,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
WEECHAT_HASHTABLE_STRING,
|
||||
NULL, NULL);
|
||||
hook_add_to_list (new_hook);
|
||||
|
||||
if (weechat_debug_core >= 1)
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
"debug: hook_url: url=\"%s\", "
|
||||
"options=\"%s\", timeout=%d",
|
||||
new_hook_url->url,
|
||||
hashtable_get_string (new_hook_url->options,
|
||||
"keys_values"),
|
||||
new_hook_url->timeout);
|
||||
}
|
||||
|
||||
hook_url_transfer (new_hook);
|
||||
|
||||
return new_hook;
|
||||
|
||||
error:
|
||||
if (new_hook)
|
||||
free (new_hook);
|
||||
if (new_hook_url)
|
||||
free (new_hook_url);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Frees data in a url hook.
|
||||
*/
|
||||
|
||||
void
|
||||
hook_url_free_data (struct t_hook *hook)
|
||||
{
|
||||
if (!hook || !hook->hook_data)
|
||||
return;
|
||||
|
||||
if (HOOK_URL(hook, url))
|
||||
{
|
||||
free (HOOK_URL(hook, url));
|
||||
HOOK_URL(hook, url) = NULL;
|
||||
}
|
||||
if (HOOK_URL(hook, options))
|
||||
{
|
||||
hashtable_free (HOOK_URL(hook, options));
|
||||
HOOK_URL(hook, options) = NULL;
|
||||
}
|
||||
if (HOOK_URL(hook, hook_timer))
|
||||
{
|
||||
unhook (HOOK_URL(hook, hook_timer));
|
||||
HOOK_URL(hook, hook_timer) = NULL;
|
||||
}
|
||||
if (HOOK_URL(hook, thread_running))
|
||||
{
|
||||
pthread_cancel (HOOK_URL(hook, thread_id));
|
||||
HOOK_URL(hook, thread_running) = 0;
|
||||
}
|
||||
if (HOOK_URL(hook, output))
|
||||
{
|
||||
hashtable_free (HOOK_URL(hook, output));
|
||||
HOOK_URL(hook, output) = NULL;
|
||||
}
|
||||
|
||||
free (hook->hook_data);
|
||||
hook->hook_data = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds url hook data in the infolist item.
|
||||
*
|
||||
* Returns:
|
||||
* 1: OK
|
||||
* 0: error
|
||||
*/
|
||||
|
||||
int
|
||||
hook_url_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_hook *hook)
|
||||
{
|
||||
if (!item || !hook || !hook->hook_data)
|
||||
return 0;
|
||||
|
||||
if (!infolist_new_var_pointer (item, "callback", HOOK_URL(hook, callback)))
|
||||
return 0;
|
||||
if (!infolist_new_var_string (item, "url", HOOK_URL(hook, url)))
|
||||
return 0;
|
||||
if (!infolist_new_var_string (item, "options", hashtable_get_string (HOOK_URL(hook, options), "keys_values")))
|
||||
return 0;
|
||||
if (!infolist_new_var_integer (item, "timeout", (int)(HOOK_URL(hook, timeout))))
|
||||
return 0;
|
||||
if (!infolist_new_var_integer (item, "thread_running", (int)(HOOK_URL(hook, thread_running))))
|
||||
return 0;
|
||||
if (!infolist_new_var_pointer (item, "hook_timer", HOOK_URL(hook, hook_timer)))
|
||||
return 0;
|
||||
if (!infolist_new_var_string (item, "output", hashtable_get_string (HOOK_URL(hook, output), "keys_values")))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Prints url hook data in WeeChat log file (usually for crash dump).
|
||||
*/
|
||||
|
||||
void
|
||||
hook_url_print_log (struct t_hook *hook)
|
||||
{
|
||||
if (!hook || !hook->hook_data)
|
||||
return;
|
||||
|
||||
log_printf (" url data:");
|
||||
log_printf (" callback. . . . . . . : 0x%lx", HOOK_URL(hook, callback));
|
||||
log_printf (" url . . . . . . . . . : '%s'", HOOK_URL(hook, url));
|
||||
log_printf (" options . . . . . . . : 0x%lx (hashtable: '%s')",
|
||||
HOOK_URL(hook, options),
|
||||
hashtable_get_string (HOOK_URL(hook, options),
|
||||
"keys_values"));
|
||||
log_printf (" timeout . . . . . . . : %ld", HOOK_URL(hook, timeout));
|
||||
log_printf (" thread_running. . . . : %d", (int)HOOK_URL(hook, thread_running));
|
||||
log_printf (" hook_timer. . . . . . : 0x%lx", HOOK_URL(hook, hook_timer));
|
||||
log_printf (" output. . . . . . . . : 0x%lx (hashtable: '%s')",
|
||||
HOOK_URL(hook, output),
|
||||
hashtable_get_string (HOOK_URL(hook, output),
|
||||
"keys_values"));
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (C) 2023 Sébastien Helleu <flashcode@flashtux.org>
|
||||
*
|
||||
* This file is part of WeeChat, the extensible chat client.
|
||||
*
|
||||
* WeeChat 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 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* WeeChat 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 WeeChat. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef WEECHAT_HOOK_URL_H
|
||||
#define WEECHAT_HOOK_URL_H
|
||||
|
||||
struct t_weechat_plugin;
|
||||
struct t_infolist_item;
|
||||
struct t_hashtable;
|
||||
|
||||
#define HOOK_URL(hook, var) (((struct t_hook_url *)hook->hook_data)->var)
|
||||
|
||||
typedef int (t_hook_callback_url)(const void *pointer, void *data,
|
||||
const char *url,
|
||||
struct t_hashtable *options,
|
||||
struct t_hashtable *output);
|
||||
|
||||
struct t_hook_url
|
||||
{
|
||||
t_hook_callback_url *callback; /* URL callback */
|
||||
char *url; /* URL */
|
||||
struct t_hashtable *options; /* URL options (see doc) */
|
||||
long timeout; /* timeout (ms) (0 = no timeout) */
|
||||
pthread_t thread_id; /* thread id */
|
||||
int thread_running; /* 1 if thread is running */
|
||||
struct t_hook *hook_timer; /* timer to check if thread has ended*/
|
||||
struct t_hashtable *output; /* URL transfer output data */
|
||||
};
|
||||
|
||||
extern char *hook_url_get_description (struct t_hook *hook);
|
||||
extern struct t_hook *hook_url (struct t_weechat_plugin *plugin,
|
||||
const char *url,
|
||||
struct t_hashtable *options,
|
||||
int timeout,
|
||||
t_hook_callback_url *callback,
|
||||
const void *callback_pointer,
|
||||
void *callback_data);
|
||||
extern void hook_url_free_data (struct t_hook *hook);
|
||||
extern int hook_url_add_to_infolist (struct t_infolist_item *item,
|
||||
struct t_hook *hook);
|
||||
extern void hook_url_print_log (struct t_hook *hook);
|
||||
|
||||
#endif /* WEECHAT_HOOK_URL_H */
|
||||
+20
-5
@@ -63,6 +63,7 @@
|
||||
#include "wee-string.h"
|
||||
#include "wee-sys.h"
|
||||
#include "wee-upgrade.h"
|
||||
#include "wee-url.h"
|
||||
#include "wee-utf8.h"
|
||||
#include "wee-util.h"
|
||||
#include "wee-version.h"
|
||||
@@ -2223,6 +2224,15 @@ COMMAND_CALLBACK(debug)
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
if (string_strcmp (argv[1], "url") == 0)
|
||||
{
|
||||
url_debug ^= 1;
|
||||
gui_chat_printf (NULL,
|
||||
_("Debug hook_url: %s"),
|
||||
(url_debug) ? _("enabled") : _("disabled"));
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
|
||||
if (string_strcmp (argv[1], "windows") == 0)
|
||||
{
|
||||
debug_windows_tree ();
|
||||
@@ -7056,14 +7066,17 @@ COMMAND_CALLBACK(upgrade)
|
||||
}
|
||||
|
||||
/*
|
||||
* it is forbidden to upgrade while there are some background process
|
||||
* (hook type "process" or "connect")
|
||||
* it is forbidden to upgrade while there are some background process or
|
||||
* thread (hook types: process, connect, url)
|
||||
*/
|
||||
if (weechat_hooks[HOOK_TYPE_PROCESS] || weechat_hooks[HOOK_TYPE_CONNECT])
|
||||
if (weechat_hooks[HOOK_TYPE_PROCESS]
|
||||
|| weechat_hooks[HOOK_TYPE_CONNECT]
|
||||
|| weechat_hooks[HOOK_TYPE_URL])
|
||||
{
|
||||
gui_chat_printf (NULL,
|
||||
_("%sCan't upgrade: there is one or more background "
|
||||
"process (hook type 'process' or 'connect')"),
|
||||
"process/thread running (hook type: process, "
|
||||
"connect or url)"),
|
||||
gui_chat_prefix[GUI_CHAT_PREFIX_ERROR]);
|
||||
return WEECHAT_RC_OK;
|
||||
}
|
||||
@@ -8189,7 +8202,7 @@ command_init ()
|
||||
" || set <plugin> <level>"
|
||||
" || dump|hooks [<plugin>]"
|
||||
" || buffer|certs|color|dirs|infolists|libs|memory|tags|"
|
||||
"term|windows"
|
||||
"term|url|windows"
|
||||
" || callbacks <duration>[<unit>]"
|
||||
" || mouse|cursor [verbose]"
|
||||
" || hdata [free]"
|
||||
@@ -8227,6 +8240,7 @@ command_init ()
|
||||
" mouse: toggle debug for mouse\n"
|
||||
" tags: display tags for lines\n"
|
||||
" term: display infos about terminal\n"
|
||||
" url: toggle debug for calls to hook_url (display output hashtable)\n"
|
||||
" windows: display windows tree\n"
|
||||
" time: measure time to execute a command or to send text to "
|
||||
"the current buffer\n"
|
||||
@@ -8256,6 +8270,7 @@ command_init ()
|
||||
" || mouse verbose"
|
||||
" || tags"
|
||||
" || term"
|
||||
" || url"
|
||||
" || windows"
|
||||
" || time %(commands:/)"
|
||||
" || unicode",
|
||||
|
||||
+87
-39
@@ -46,7 +46,7 @@
|
||||
char *hook_type_string[HOOK_NUM_TYPES] =
|
||||
{ "command", "command_run", "timer", "fd", "process", "connect", "line",
|
||||
"print", "signal", "hsignal", "config", "completion", "modifier",
|
||||
"info", "info_hashtable", "infolist", "hdata", "focus" };
|
||||
"info", "info_hashtable", "infolist", "hdata", "focus", "url" };
|
||||
struct t_hook *weechat_hooks[HOOK_NUM_TYPES]; /* list of hooks */
|
||||
struct t_hook *last_weechat_hook[HOOK_NUM_TYPES]; /* last hook */
|
||||
int hooks_count[HOOK_NUM_TYPES]; /* number of hooks */
|
||||
@@ -59,50 +59,98 @@ int hook_socketpair_ok = 0; /* 1 if socketpair() is OK */
|
||||
/* hook callbacks */
|
||||
t_callback_hook *hook_callback_add[HOOK_NUM_TYPES] =
|
||||
{ NULL, NULL, NULL, &hook_fd_add_cb, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
t_callback_hook *hook_callback_remove[HOOK_NUM_TYPES] =
|
||||
{ NULL, NULL, NULL, &hook_fd_remove_cb, NULL, NULL, NULL, NULL, NULL, NULL,
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL };
|
||||
t_callback_hook *hook_callback_free_data[HOOK_NUM_TYPES] =
|
||||
{ &hook_command_free_data, &hook_command_run_free_data,
|
||||
&hook_timer_free_data, &hook_fd_free_data,
|
||||
&hook_process_free_data, &hook_connect_free_data,
|
||||
&hook_line_free_data, &hook_print_free_data,
|
||||
&hook_signal_free_data, &hook_hsignal_free_data,
|
||||
&hook_config_free_data, &hook_completion_free_data,
|
||||
&hook_modifier_free_data, &hook_info_free_data,
|
||||
&hook_info_hashtable_free_data, &hook_infolist_free_data,
|
||||
&hook_hdata_free_data, &hook_focus_free_data };
|
||||
{
|
||||
&hook_command_free_data,
|
||||
&hook_command_run_free_data,
|
||||
&hook_timer_free_data,
|
||||
&hook_fd_free_data,
|
||||
&hook_process_free_data,
|
||||
&hook_connect_free_data,
|
||||
&hook_line_free_data,
|
||||
&hook_print_free_data,
|
||||
&hook_signal_free_data,
|
||||
&hook_hsignal_free_data,
|
||||
&hook_config_free_data,
|
||||
&hook_completion_free_data,
|
||||
&hook_modifier_free_data,
|
||||
&hook_info_free_data,
|
||||
&hook_info_hashtable_free_data,
|
||||
&hook_infolist_free_data,
|
||||
&hook_hdata_free_data,
|
||||
&hook_focus_free_data,
|
||||
&hook_url_free_data,
|
||||
};
|
||||
t_callback_hook_get_desc *hook_callback_get_desc[HOOK_NUM_TYPES] =
|
||||
{ &hook_command_get_description, &hook_command_run_get_description,
|
||||
&hook_timer_get_description, &hook_fd_get_description,
|
||||
&hook_process_get_description, &hook_connect_get_description,
|
||||
&hook_line_get_description, &hook_print_get_description,
|
||||
&hook_signal_get_description, &hook_hsignal_get_description,
|
||||
&hook_config_get_description, &hook_completion_get_description,
|
||||
&hook_modifier_get_description, &hook_info_get_description,
|
||||
&hook_info_hashtable_get_description, &hook_infolist_get_description,
|
||||
&hook_hdata_get_description, &hook_focus_get_description };
|
||||
{
|
||||
&hook_command_get_description,
|
||||
&hook_command_run_get_description,
|
||||
&hook_timer_get_description,
|
||||
&hook_fd_get_description,
|
||||
&hook_process_get_description,
|
||||
&hook_connect_get_description,
|
||||
&hook_line_get_description,
|
||||
&hook_print_get_description,
|
||||
&hook_signal_get_description,
|
||||
&hook_hsignal_get_description,
|
||||
&hook_config_get_description,
|
||||
&hook_completion_get_description,
|
||||
&hook_modifier_get_description,
|
||||
&hook_info_get_description,
|
||||
&hook_info_hashtable_get_description,
|
||||
&hook_infolist_get_description,
|
||||
&hook_hdata_get_description,
|
||||
&hook_focus_get_description,
|
||||
&hook_url_get_description,
|
||||
};
|
||||
t_callback_hook_infolist *hook_callback_add_to_infolist[HOOK_NUM_TYPES] =
|
||||
{ &hook_command_add_to_infolist, &hook_command_run_add_to_infolist,
|
||||
&hook_timer_add_to_infolist, &hook_fd_add_to_infolist,
|
||||
&hook_process_add_to_infolist, &hook_connect_add_to_infolist,
|
||||
&hook_line_add_to_infolist, &hook_print_add_to_infolist,
|
||||
&hook_signal_add_to_infolist, &hook_hsignal_add_to_infolist,
|
||||
&hook_config_add_to_infolist, &hook_completion_add_to_infolist,
|
||||
&hook_modifier_add_to_infolist, &hook_info_add_to_infolist,
|
||||
&hook_info_hashtable_add_to_infolist, &hook_infolist_add_to_infolist,
|
||||
&hook_hdata_add_to_infolist, &hook_focus_add_to_infolist };
|
||||
{
|
||||
&hook_command_add_to_infolist,
|
||||
&hook_command_run_add_to_infolist,
|
||||
&hook_timer_add_to_infolist,
|
||||
&hook_fd_add_to_infolist,
|
||||
&hook_process_add_to_infolist,
|
||||
&hook_connect_add_to_infolist,
|
||||
&hook_line_add_to_infolist,
|
||||
&hook_print_add_to_infolist,
|
||||
&hook_signal_add_to_infolist,
|
||||
&hook_hsignal_add_to_infolist,
|
||||
&hook_config_add_to_infolist,
|
||||
&hook_completion_add_to_infolist,
|
||||
&hook_modifier_add_to_infolist,
|
||||
&hook_info_add_to_infolist,
|
||||
&hook_info_hashtable_add_to_infolist,
|
||||
&hook_infolist_add_to_infolist,
|
||||
&hook_hdata_add_to_infolist,
|
||||
&hook_focus_add_to_infolist,
|
||||
&hook_url_add_to_infolist,
|
||||
};
|
||||
t_callback_hook *hook_callback_print_log[HOOK_NUM_TYPES] =
|
||||
{ &hook_command_print_log, &hook_command_run_print_log,
|
||||
&hook_timer_print_log, &hook_fd_print_log,
|
||||
&hook_process_print_log, &hook_connect_print_log,
|
||||
&hook_line_print_log, &hook_print_print_log,
|
||||
&hook_signal_print_log, &hook_hsignal_print_log,
|
||||
&hook_config_print_log, &hook_completion_print_log,
|
||||
&hook_modifier_print_log, &hook_info_print_log,
|
||||
&hook_info_hashtable_print_log, &hook_infolist_print_log,
|
||||
&hook_hdata_print_log, &hook_focus_print_log };
|
||||
{
|
||||
&hook_command_print_log,
|
||||
&hook_command_run_print_log,
|
||||
&hook_timer_print_log,
|
||||
&hook_fd_print_log,
|
||||
&hook_process_print_log,
|
||||
&hook_connect_print_log,
|
||||
&hook_line_print_log,
|
||||
&hook_print_print_log,
|
||||
&hook_signal_print_log,
|
||||
&hook_hsignal_print_log,
|
||||
&hook_config_print_log,
|
||||
&hook_completion_print_log,
|
||||
&hook_modifier_print_log,
|
||||
&hook_info_print_log,
|
||||
&hook_info_hashtable_print_log,
|
||||
&hook_infolist_print_log,
|
||||
&hook_hdata_print_log,
|
||||
&hook_focus_print_log,
|
||||
&hook_url_print_log,
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
|
||||
@@ -40,6 +40,7 @@ struct t_hook;
|
||||
#include "hook/wee-hook-process.h"
|
||||
#include "hook/wee-hook-signal.h"
|
||||
#include "hook/wee-hook-timer.h"
|
||||
#include "hook/wee-hook-url.h"
|
||||
|
||||
struct t_gui_bar;
|
||||
struct t_gui_buffer;
|
||||
@@ -73,6 +74,7 @@ enum t_hook_type
|
||||
HOOK_TYPE_INFOLIST, /* get some info as infolist */
|
||||
HOOK_TYPE_HDATA, /* get hdata pointer */
|
||||
HOOK_TYPE_FOCUS, /* focus event (mouse/key) */
|
||||
HOOK_TYPE_URL, /* URL transfer */
|
||||
/* number of hook types */
|
||||
HOOK_NUM_TYPES,
|
||||
};
|
||||
|
||||
+116
-11
@@ -44,6 +44,7 @@
|
||||
{ #__name, CURLOPT_##__name, URL_TYPE_##__type, __constants }
|
||||
|
||||
|
||||
int url_debug = 0;
|
||||
char *url_type_string[] = { "string", "long", "long long", "mask", "list" };
|
||||
|
||||
/*
|
||||
@@ -1013,8 +1014,6 @@ struct t_url_option url_options[] =
|
||||
{ NULL, 0, 0, NULL },
|
||||
};
|
||||
|
||||
char url_error[CURL_ERROR_SIZE + 1];
|
||||
|
||||
|
||||
/*
|
||||
* Searches for a constant in array of constants.
|
||||
@@ -1116,7 +1115,7 @@ weeurl_search_option (const char *name)
|
||||
*/
|
||||
|
||||
size_t
|
||||
weeurl_read (void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
weeurl_read_stream (void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
return (stream) ? fread (buffer, size, nmemb, stream) : 0;
|
||||
}
|
||||
@@ -1126,11 +1125,26 @@ weeurl_read (void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
*/
|
||||
|
||||
size_t
|
||||
weeurl_write (void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
weeurl_write_stream (void *buffer, size_t size, size_t nmemb, void *stream)
|
||||
{
|
||||
return (stream) ? fwrite (buffer, size, nmemb, stream) : 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Adds data to a dynamic string (callback called to catch stdout).
|
||||
*/
|
||||
|
||||
size_t
|
||||
weeurl_write_string (void *buffer, size_t size, size_t nmemb, void *string)
|
||||
{
|
||||
if (!string)
|
||||
return 0;
|
||||
|
||||
string_dyn_concat ((char **)string, buffer, size * nmemb);
|
||||
|
||||
return size * nmemb;
|
||||
}
|
||||
|
||||
/*
|
||||
* Sets option in CURL easy handle (callback called for each option in hashtable
|
||||
* "options").
|
||||
@@ -1303,6 +1317,17 @@ weeurl_set_proxy (CURL *curl, struct t_proxy *proxy)
|
||||
/*
|
||||
* Downloads URL using options.
|
||||
*
|
||||
* If output is not NULL, it must be a hashtable with keys and values of type
|
||||
* "string". The following keys may be added in the hashtable,
|
||||
* depending on the success or error of the URL transfer:
|
||||
*
|
||||
* key | description
|
||||
* --------------|--------------------------------------------------------
|
||||
* response_code | HTTP response code (as string)
|
||||
* headers | HTTP headers in response
|
||||
* output | stdout (set only if "file_out" was not set in options)
|
||||
* error | error message (set only in case of error)
|
||||
*
|
||||
* Returns:
|
||||
* 0: OK
|
||||
* 1: invalid URL
|
||||
@@ -1312,20 +1337,28 @@ weeurl_set_proxy (CURL *curl, struct t_proxy *proxy)
|
||||
*/
|
||||
|
||||
int
|
||||
weeurl_download (const char *url, struct t_hashtable *options)
|
||||
weeurl_download (const char *url, struct t_hashtable *options,
|
||||
struct t_hashtable *output)
|
||||
{
|
||||
CURL *curl;
|
||||
struct t_url_file url_file[2];
|
||||
char *url_file_option[2] = { "file_in", "file_out" };
|
||||
char *url_file_mode[2] = { "rb", "wb" };
|
||||
char url_error[CURL_ERROR_SIZE + 1], **string_headers, **string_output;
|
||||
char str_response_code[32];
|
||||
CURLoption url_file_opt_func[2] = { CURLOPT_READFUNCTION, CURLOPT_WRITEFUNCTION };
|
||||
CURLoption url_file_opt_data[2] = { CURLOPT_READDATA, CURLOPT_WRITEDATA };
|
||||
void *url_file_opt_cb[2] = { &weeurl_read, &weeurl_write };
|
||||
void *url_file_opt_cb[2] = { &weeurl_read_stream, &weeurl_write_stream };
|
||||
struct t_proxy *ptr_proxy;
|
||||
int rc, curl_rc, i;
|
||||
int rc, curl_rc, i, output_to_file;
|
||||
long response_code;
|
||||
|
||||
rc = 0;
|
||||
|
||||
string_headers = NULL;
|
||||
string_output = NULL;
|
||||
url_error[0] = '\0';
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
url_file[i].filename = NULL;
|
||||
@@ -1334,6 +1367,7 @@ weeurl_download (const char *url, struct t_hashtable *options)
|
||||
|
||||
if (!url || !url[0])
|
||||
{
|
||||
snprintf (url_error, sizeof (url_error), "%s", _("invalid URL"));
|
||||
rc = 1;
|
||||
goto end;
|
||||
}
|
||||
@@ -1341,6 +1375,7 @@ weeurl_download (const char *url, struct t_hashtable *options)
|
||||
curl = curl_easy_init ();
|
||||
if (!curl)
|
||||
{
|
||||
snprintf (url_error, sizeof (url_error), "%s", _("not enough memory"));
|
||||
rc = 3;
|
||||
goto end;
|
||||
}
|
||||
@@ -1358,7 +1393,19 @@ weeurl_download (const char *url, struct t_hashtable *options)
|
||||
weeurl_set_proxy (curl, ptr_proxy);
|
||||
}
|
||||
|
||||
/* set callback to retrieve HTTP headers */
|
||||
if (output)
|
||||
{
|
||||
string_headers = string_dyn_alloc (1024);
|
||||
if (string_headers)
|
||||
{
|
||||
curl_easy_setopt (curl, CURLOPT_HEADERFUNCTION, &weeurl_write_string);
|
||||
curl_easy_setopt (curl, CURLOPT_HEADERDATA, string_headers);
|
||||
}
|
||||
}
|
||||
|
||||
/* set file in/out from options in hashtable */
|
||||
output_to_file = 0;
|
||||
if (options)
|
||||
{
|
||||
for (i = 0; i < 2; i++)
|
||||
@@ -1369,15 +1416,33 @@ weeurl_download (const char *url, struct t_hashtable *options)
|
||||
url_file[i].stream = fopen (url_file[i].filename, url_file_mode[i]);
|
||||
if (!url_file[i].stream)
|
||||
{
|
||||
snprintf (url_error, sizeof (url_error),
|
||||
(i == 0) ?
|
||||
_("file \"%s\" not found") :
|
||||
_("can not write file \"%s\""),
|
||||
url_file[i].filename);
|
||||
rc = 4;
|
||||
goto end;
|
||||
}
|
||||
curl_easy_setopt (curl, url_file_opt_func[i], url_file_opt_cb[i]);
|
||||
curl_easy_setopt (curl, url_file_opt_data[i], url_file[i].stream);
|
||||
if (i == 1)
|
||||
output_to_file = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* redirect stdout if no filename was given (via key "file_out") */
|
||||
if (output && !output_to_file)
|
||||
{
|
||||
string_output = string_dyn_alloc (1024);
|
||||
if (string_output)
|
||||
{
|
||||
curl_easy_setopt (curl, CURLOPT_WRITEFUNCTION, &weeurl_write_string);
|
||||
curl_easy_setopt (curl, CURLOPT_WRITEDATA, string_output);
|
||||
}
|
||||
}
|
||||
|
||||
/* set other options in hashtable */
|
||||
hashtable_map (options, &weeurl_option_map_cb, curl);
|
||||
|
||||
@@ -1386,11 +1451,36 @@ weeurl_download (const char *url, struct t_hashtable *options)
|
||||
|
||||
/* perform action! */
|
||||
curl_rc = curl_easy_perform (curl);
|
||||
if (curl_rc != CURLE_OK)
|
||||
if (curl_rc == CURLE_OK)
|
||||
{
|
||||
fprintf (stderr,
|
||||
_("curl error %d (%s) (URL: \"%s\")\n"),
|
||||
curl_rc, url_error, url);
|
||||
if (output)
|
||||
{
|
||||
curl_easy_getinfo (curl, CURLINFO_RESPONSE_CODE, &response_code);
|
||||
snprintf (str_response_code, sizeof (str_response_code),
|
||||
"%ld", response_code);
|
||||
hashtable_set (output, "response_code", str_response_code);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (output)
|
||||
{
|
||||
if (!url_error[0])
|
||||
{
|
||||
snprintf (url_error, sizeof (url_error),
|
||||
"%s", _("transfer error"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/*
|
||||
* URL transfer done in a forked process: display error on stderr,
|
||||
* which will be sent to the hook_process callback
|
||||
*/
|
||||
fprintf (stderr,
|
||||
_("curl error %d (%s) (URL: \"%s\")\n"),
|
||||
curl_rc, url_error, url);
|
||||
}
|
||||
rc = 2;
|
||||
}
|
||||
|
||||
@@ -1403,6 +1493,21 @@ end:
|
||||
if (url_file[i].stream)
|
||||
fclose (url_file[i].stream);
|
||||
}
|
||||
if (output)
|
||||
{
|
||||
if (string_headers)
|
||||
{
|
||||
hashtable_set (output, "headers", *string_headers);
|
||||
string_dyn_free (string_headers, 1);
|
||||
}
|
||||
if (string_output)
|
||||
{
|
||||
hashtable_set (output, "output", *string_output);
|
||||
string_dyn_free (string_output, 1);
|
||||
}
|
||||
if (url_error[0])
|
||||
hashtable_set (output, "error", url_error);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -54,10 +54,12 @@ struct t_url_file
|
||||
FILE *stream; /* file stream */
|
||||
};
|
||||
|
||||
extern int url_debug;
|
||||
extern char *url_type_string[];
|
||||
extern struct t_url_option url_options[];
|
||||
|
||||
extern int weeurl_download (const char *url, struct t_hashtable *options);
|
||||
extern int weeurl_download (const char *url, struct t_hashtable *options,
|
||||
struct t_hashtable *output);
|
||||
extern int weeurl_option_add_to_infolist (struct t_infolist *infolist,
|
||||
struct t_url_option *option);
|
||||
|
||||
|
||||
@@ -798,6 +798,7 @@ plugin_load (const char *filename, int init_plugin, int argc, char **argv)
|
||||
new_plugin->hook_fd = &hook_fd;
|
||||
new_plugin->hook_process = &hook_process;
|
||||
new_plugin->hook_process_hashtable = &hook_process_hashtable;
|
||||
new_plugin->hook_url = &hook_url;
|
||||
new_plugin->hook_connect = &hook_connect;
|
||||
new_plugin->hook_line = &hook_line;
|
||||
new_plugin->hook_print = &hook_print;
|
||||
|
||||
@@ -68,7 +68,7 @@ struct timeval;
|
||||
* please change the date with current one; for a second change at same
|
||||
* date, increment the 01, otherwise please keep 01.
|
||||
*/
|
||||
#define WEECHAT_PLUGIN_API_VERSION "20230706-01"
|
||||
#define WEECHAT_PLUGIN_API_VERSION "20230908-01"
|
||||
|
||||
/* macros for defining plugin infos */
|
||||
#define WEECHAT_PLUGIN_NAME(__name) \
|
||||
@@ -748,6 +748,17 @@ struct t_weechat_plugin
|
||||
const char *err),
|
||||
const void *callback_pointer,
|
||||
void *callback_data);
|
||||
struct t_hook *(*hook_url) (struct t_weechat_plugin *plugin,
|
||||
const char *url,
|
||||
struct t_hashtable *options,
|
||||
int timeout,
|
||||
int (*callback)(const void *pointer,
|
||||
void *data,
|
||||
const char *url,
|
||||
struct t_hashtable *options,
|
||||
struct t_hashtable *output),
|
||||
const void *callback_pointer,
|
||||
void *callback_data);
|
||||
struct t_hook *(*hook_connect) (struct t_weechat_plugin *plugin,
|
||||
const char *proxy,
|
||||
const char *address,
|
||||
@@ -1810,6 +1821,12 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
|
||||
__callback, \
|
||||
__callback_pointer, \
|
||||
__callback_data)
|
||||
#define weechat_hook_url(__command, __options, __timeout, \
|
||||
__callback, __callback_pointer, \
|
||||
__callback_data) \
|
||||
(weechat_plugin->hook_url)(weechat_plugin, __command, __options, \
|
||||
__timeout, __callback, \
|
||||
__callback_pointer, __callback_data)
|
||||
#define weechat_hook_connect(__proxy, __address, __port, __ipv6, \
|
||||
__retry, __gnutls_sess, __gnutls_cb, \
|
||||
__gnutls_dhkey_size, __gnutls_priorities, \
|
||||
|
||||
@@ -139,6 +139,10 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Haiku")
|
||||
list(APPEND EXTRA_LIBS "pthread")
|
||||
endif()
|
||||
|
||||
# binary to run tests
|
||||
set(WEECHAT_TESTS_SRC
|
||||
tests.cpp tests.h
|
||||
|
||||
Reference in New Issue
Block a user