core: add URL transfer (using libcurl), add function hook_process_hashtable in plugin API, add support of URL in hook_process/hook_process_hashtable (task #10247)

v2.8-utf8proc
Sebastien Helleu 2012-01-16 19:52:08 +01:00
parent ca07f58406
commit b91c231096
52 changed files with 2049 additions and 56 deletions

View File

@ -41,9 +41,10 @@ Version 0.3.7 (under dev!)
* core: fix compilation error with "pid_t" on Mac OS X (bug #34639)
* core: enable background process under Cygwin to connect to servers, fix
reconnection problem (bug #34626)
* api: add support of URL in hook_process/hook_process_hashtable (task #10247)
* api: add new functions strcasecmp_range, strncasecmp_range,
hashtable_map_string, hdata_check_pointer, hdata_char, hdata_hashtable and
nicklist_get_next_item
hashtable_map_string, hook_process_hashtable, hdata_check_pointer, hdata_char,
hdata_hashtable and nicklist_get_next_item
* alias: add default alias umode => /mode $nick
* irc: use low priority for MODE sent automatically by WeeChat (when joining
channel)

View File

@ -929,6 +929,21 @@ else
not_asked="$not_asked zlib"
fi
# ------------------------------------------------------------------------------
# curl
# ------------------------------------------------------------------------------
AC_PATH_PROG(CURL_CONFIG, curl-config)
if test "x$CURL_CONFIG" = "x" ; then
AC_MSG_ERROR([
*** "curl-config" couldn't be found on your system.
*** Try to install libcurl-dev with your software package manager.])
fi
CURL_CFLAGS=`$CURL_CONFIG --cflags`
CURL_LFLAGS=`$CURL_CONFIG --libs`
AC_SUBST(CURL_CFLAGS)
AC_SUBST(CURL_LFLAGS)
# ------------------------------------------------------------------------------
# documentation
# ------------------------------------------------------------------------------

2
debian/control vendored
View File

@ -6,7 +6,7 @@ Build-Depends-Indep: asciidoc (>= 8.5), source-highlight
Build-Depends: debhelper (>= 7.0.50), cmake, libncursesw5-dev,
ruby1.9.1, ruby1.9.1-dev, libperl-dev, python-dev, libaspell-dev, liblua5.1-0-dev,
tcl8.5-dev, guile-1.8-dev, libgcrypt11-dev, libgnutls-dev, zlib1g-dev,
dpkg-dev (>= 1.13.19), pkg-config
libcurl-dev, dpkg-dev (>= 1.13.19), pkg-config
Standards-Version: 3.9.2
Homepage: http://weechat.org/
Vcs-Git: git://git.debian.org/users/kolter/weechat.git

View File

@ -58,6 +58,8 @@
| weechat | plugin | Auflistung der Erweiterungen | Pointer der Erweiterung (optional) | Name einer Erweiterung (darf mit einem "*" als Platzhalter beginnen oder enden) (optional)
| weechat | url_options | options for URL | - | -
| weechat | window | Auflistung der Windows | Fenster Pointer (optional) | "current" für aktuelles Fenster oder die Nummer eines Fensters (optional)
| xfer | xfer | Transfer-Liste | Transfer-Pointer (optional) | -

View File

@ -0,0 +1,91 @@
[width="100%",cols="2,^1,7",options="header"]
|========================================
| Option | Type | Constants ^(1)^
| header | long |
| wildcardmatch | long |
| failonerror | long |
| protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| redir_protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| proxy | string |
| proxyport | long |
| proxytype | long | http, http_1_0, socks4, socks5, socks4a, socks5_hostname
| noproxy | string |
| httpproxytunnel | long |
| socks5_gssapi_service | string |
| socks5_gssapi_nec | long |
| interface | string |
| localport | long |
| localportrange | long |
| dns_cache_timeout | long |
| buffersize | long |
| port | long |
| tcp_nodelay | long |
| address_scope | long |
| netrc | long | ignored, optional, required
| netrc_file | string |
| userpwd | string |
| proxyuserpwd | string |
| username | string |
| password | string |
| proxyusername | string |
| proxypassword | string |
| httpauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| tlsauth_type | mask | none, srp
| tlsauth_username | string |
| tlsauth_password | string |
| proxyauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| autoreferer | long |
| accept_encoding | string |
| transfer_encoding | long |
| followlocation | long |
| unrestricted_auth | long |
| maxredirs | long |
| postredir | mask | post_301, post_302
| post | long |
| postfields | string |
| postfieldsize | long |
|========================================

View File

@ -90,6 +90,8 @@ welche Pakete optional genutzt werden können.
| Paket ^(1)^ | Version | benötigt | Funktion
| cmake | | *ja* | zum kompilieren (autotools ist möglich. cmake wird aber empfohlen)
| libncursesw5-dev ^(2)^ | | *ja* | ncurses Oberfläche
// TRANSLATION MISSING
| libcurl4-xxxxx-dev | | *ja* | URL transfer
| gettext | | | Internationalisierung (Übersetzung der Mitteilungen; Hauptsprache ist englisch)
| libgcrypt11-dev | | | SASL Authentifikation am IRC Server mittels DH-BLOWFISH Methode
| libgnutls-dev | ≥ 2.2.0 | | SSL Verbindung zu einem IRC Server

View File

@ -250,6 +250,18 @@ def get_completions():
weechat.infolist_free(infolist)
return completions
def get_url_options():
"""Get list of completions hooked by plugins in a dict with 3 indexes: plugin, item, xxx."""
url_options = []
infolist = weechat.infolist_get('url_options', '', '')
while weechat.infolist_next(infolist):
url_options.append({ 'name': weechat.infolist_string(infolist, 'name').lower(),
'option': weechat.infolist_integer(infolist, 'option'),
'type': weechat.infolist_string(infolist, 'type'),
'constants': weechat.infolist_string(infolist, 'constants').lower().replace(',', ', ') })
weechat.infolist_free(infolist)
return url_options
def update_file(oldfile, newfile, num_files, num_files_updated, obj):
"""Update a doc file."""
try:
@ -288,6 +300,7 @@ def docgen_cmd_cb(data, buffer, args):
infolists = get_infolists()
hdata = get_hdata()
completions = get_completions()
url_options = get_url_options()
# get path and replace ~ by home if needed
path = weechat.config_get_plugin('path')
@ -497,6 +510,24 @@ def docgen_cmd_cb(data, buffer, args):
f.close()
update_file(filename, tmpfilename, num_files, num_files_updated, 'completions')
# write url options
filename = '%s/plugin_api/url_options.txt' % directory
tmpfilename = '%s.tmp' % filename
f = open(tmpfilename, 'w')
f.write('[width="100%",cols="2,^1,7",options="header"]\n')
f.write('|========================================\n')
f.write('| %s | %s | %s\n\n' % (_('Option'), _('Type'), _('Constants') + ' ^(1)^'))
for option in url_options:
constants = option['constants']
if constants:
constants = ' ' + constants
f.write('| %s | %s |%s\n\n' % (escape(option['name']),
escape(option['type']),
escape(constants)))
f.write('|========================================\n')
f.close()
update_file(filename, tmpfilename, num_files, num_files_updated, 'url_options')
# write counters
weechat.prnt('',
'docgen: %s: %3d files (%2d cmd, %2d opt, %2d infos, '

View File

@ -58,6 +58,8 @@
| weechat | plugin | list of plugins | plugin pointer (optional) | plugin name (can start or end with "*" as wildcard) (optional)
| weechat | url_options | options for URL | - | -
| weechat | window | list of windows | window pointer (optional) | "current" for current window or a window number (optional)
| xfer | xfer | list of xfer | xfer pointer (optional) | -

View File

@ -0,0 +1,91 @@
[width="100%",cols="2,^1,7",options="header"]
|========================================
| Option | Type | Constants ^(1)^
| header | long |
| wildcardmatch | long |
| failonerror | long |
| protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| redir_protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| proxy | string |
| proxyport | long |
| proxytype | long | http, http_1_0, socks4, socks5, socks4a, socks5_hostname
| noproxy | string |
| httpproxytunnel | long |
| socks5_gssapi_service | string |
| socks5_gssapi_nec | long |
| interface | string |
| localport | long |
| localportrange | long |
| dns_cache_timeout | long |
| buffersize | long |
| port | long |
| tcp_nodelay | long |
| address_scope | long |
| netrc | long | ignored, optional, required
| netrc_file | string |
| userpwd | string |
| proxyuserpwd | string |
| username | string |
| password | string |
| proxyusername | string |
| proxypassword | string |
| httpauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| tlsauth_type | mask | none, srp
| tlsauth_username | string |
| tlsauth_password | string |
| proxyauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| autoreferer | long |
| accept_encoding | string |
| transfer_encoding | long |
| followlocation | long |
| unrestricted_auth | long |
| maxredirs | long |
| postredir | mask | post_301, post_302
| post | long |
| postfields | string |
| postfieldsize | long |
|========================================

View File

@ -6706,7 +6706,8 @@ struct t_hook *weechat_hook_process (const char *command,
Arguments:
* 'command': command to launch in child process
* 'command': command to launch in child process or URL (_new in version 0.3.7_),
see below
* 'timeout': timeout for command (in milliseconds): after this timeout, child
process is killed (0 means no timeout)
* 'callback': function called when data from child is available, or when child
@ -6731,6 +6732,10 @@ Return value:
When command has ended, or if timeout is reached, WeeChat will automatically
unhook (and kill process if it is still running).
The command can be an URL with format: "url:http://www.example.com", to download
content of URL (_new in version 0.3.7_). Options are possible for URL with
function <<_weechat_hook_process_hashtable,weechat_hook_process_hashtable>>.
[NOTE]
Buffer size for sending data to callback is 64KB (there are 2 buffers: one for
stdout and one for stderr).
@ -6801,6 +6806,127 @@ def my_process_cb(data, command, return_code, out, err):
hook = weechat.hook_process("ls", 5000, "my_process_cb", "")
----------------------------------------
weechat_hook_process_hashtable
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_New in version 0.3.7._
Hook a process (launched with fork) using options in a hashtable, and catch
output.
Prototype:
[source,C]
----------------------------------------
struct t_hook *weechat_hook_process_hashtable (const char *command,
struct t_hashtable *options,
int timeout,
int (*callback)(void *data,
const char *command,
int return_code,
const char *out,
const char *err),
void *callback_data);
----------------------------------------
Arguments are the same as function <<_weechat_hook_process,weechat_hook_process>>,
with an extra argument:
* 'options': options for command executed (see table below); the hashtable is
duplicated in function, so it's safe to free it after this call
For command "url:...", following options are available (see
`man curl_easy_setopt` for a description of each option):
include::autogen/plugin_api/url_options.txt[]
[NOTE]
^(1)^ When constants are available they must be used as value for option. For
options with type "mask", format is: "value1+value2+value3".
For URL, two extra options (strings) are allowed for input/output file:
* 'file_in': file to read and send with URLs (post file)
* 'file_out': write downloaded URL/file in this file (instead of standard
output)
Return value:
* pointer to new hook, NULL if error occurred
C example:
[source,C]
----------------------------------------
int
my_process_cb (void *data, const char *command, int return_code,
const char *out, const char *err)
{
if (return_code == WEECHAT_HOOK_PROCESS_ERROR)
{
weechat_printf (NULL, "Error with command '%s'", command);
return WEECHAT_RC_OK;
}
if (return_code >= 0)
{
weechat_printf (NULL, "return_code = %d", return_code);
}
if (out)
{
weechat_printf (NULL, "stdout: %s", out);
}
if (err)
{
weechat_printf (NULL, "stderr: %s", err);
}
return WEECHAT_RC_OK;
}
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (hashtable)
{
weechat_hashtable_set (options, "file_out", "/tmp/weechat.org.html");
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("url:http://www.weechat.org/",
options,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options);
}
----------------------------------------
Script (Python):
[source,python]
----------------------------------------
# prototype
hook = weechat.hook_process_hashtable(command, options, timeout, callback, callback_data)
# example
def my_process_cb(data, command, return_code, out, err):
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR:
weechat.prnt("", "Error with command '%s'" % command)
return weechat.WEECHAT_RC_OK
if return_code >= 0:
weechat.prnt("", "return_code = %d" % return_code)
if out != "":
weechat.prnt("", "stdout: %s" % out)
if err != "":
weechat.prnt("", "stderr: %s" % err)
return weechat.WEECHAT_RC_OK
hook = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
----------------------------------------
weechat_hook_connect
^^^^^^^^^^^^^^^^^^^^

View File

@ -90,6 +90,7 @@ compile WeeChat.
| Package ^(1)^ | Version | Required | Feature
| cmake | | *yes* | build (autotools still possible, but cmake is recommended)
| libncursesw5-dev ^(2)^ | | *yes* | ncurses interface
| libcurl4-xxxxx-dev | | *yes* | URL transfer
| gettext | | | internationalization (translation of messages; base language is english)
| libgcrypt11-dev | | | SASL authentication with IRC server using DH-BLOWFISH mechanism
| libgnutls-dev | ≥ 2.2.0 | | SSL connection to IRC server

View File

@ -58,6 +58,8 @@
| weechat | plugin | liste des extensions | pointeur vers l'extension (optionnel) | nom d'extension (peut démarrer ou se terminer par "*" comme joker) (optionnel)
| weechat | url_options | options pour l'URL | - | -
| weechat | window | liste des fenêtres | pointeur vers la fenêtre (optionnel) | "current" pour la fenêtre courante ou un numéro de fenêtre (optionnel)
| xfer | xfer | liste des xfer | pointeur vers le xfer (optionnel) | -

View File

@ -0,0 +1,91 @@
[width="100%",cols="2,^1,7",options="header"]
|========================================
| Option | Type | Constantes ^(1)^
| header | long |
| wildcardmatch | long |
| failonerror | long |
| protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| redir_protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| proxy | string |
| proxyport | long |
| proxytype | long | http, http_1_0, socks4, socks5, socks4a, socks5_hostname
| noproxy | string |
| httpproxytunnel | long |
| socks5_gssapi_service | string |
| socks5_gssapi_nec | long |
| interface | string |
| localport | long |
| localportrange | long |
| dns_cache_timeout | long |
| buffersize | long |
| port | long |
| tcp_nodelay | long |
| address_scope | long |
| netrc | long | ignored, optional, required
| netrc_file | string |
| userpwd | string |
| proxyuserpwd | string |
| username | string |
| password | string |
| proxyusername | string |
| proxypassword | string |
| httpauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| tlsauth_type | mask | none, srp
| tlsauth_username | string |
| tlsauth_password | string |
| proxyauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| autoreferer | long |
| accept_encoding | string |
| transfer_encoding | long |
| followlocation | long |
| unrestricted_auth | long |
| maxredirs | long |
| postredir | mask | post_301, post_302
| post | long |
| postfields | string |
| postfieldsize | long |
|========================================

View File

@ -6795,7 +6795,8 @@ struct t_hook *weechat_hook_process (const char *command,
Paramètres :
* 'command' : commande à lancer dans le processus fils
* 'command' : commande à lancer dans le processus fils ou URL
(_nouveau dans la version 0.3.7_), voir ci-dessous
* 'timeout' : timeout pour la commande (en millisecondes) : après ce délai, le
processus fils est tué (0 signifie pas de limite)
* 'callback' : function appelée quand des données du fils sont disponibles, or
@ -6823,6 +6824,11 @@ Lorsque la commande est terminée, ou si le timeout est atteint, WeeChat
supprimera automatiquement le "hook" (et tuera le processus s'il tourne
toujours).
La commande peut être une URL avec le format : "url:http://www.example.com",
pour télécharger le contenu de l'URL (_nouveau dans la version 0.3.7_).
Des options pour l'URL sont possibles avec la fonction
<<_weechat_hook_process_hashtable,weechat_hook_process_hashtable>>.
[NOTE]
La taille du tampon pour l'envoi des données au "callback" est de 64 Ko (il y a
2 tampons : un pour stdout et un pour stderr).
@ -6894,6 +6900,131 @@ def my_process_cb(data, command, return_code, out, err):
hook = weechat.hook_process("ls", 5000, "my_process_cb", "")
----------------------------------------
weechat_hook_process_hashtable
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_Nouveau dans la version 0.3.7._
Accroche un processus (lancé par un fork) en utilisant des options dans une
hashtable, et intercepter sa sortie.
Prototype :
[source,C]
----------------------------------------
struct t_hook *weechat_hook_process_hashtable (const char *command,
struct t_hashtable *options,
int timeout,
int (*callback)(void *data,
const char *command,
int return_code,
const char *out,
const char *err),
void *callback_data);
----------------------------------------
Les paramètres sont les mêmes que ceux de la fonction
<<_weechat_hook_process,weechat_hook_process>>, avec un paramètre
supplémentaire :
* 'options' : options pour la commande exécutée (voir le tableau ci-dessous);
la hashtable est dupliquée dans la fonction, donc il est possible de la
supprimer après cet appel
Pour la commande "url:...", les options suivantes sont disponibles (voir
`man curl_easy_setopt` pour une description de chaque option) :
include::autogen/plugin_api/url_options.txt[]
[NOTE]
^(1)^ Lorsque des constantes sont disponibles, elles doivent être utilisées
comme valeur pour l'option. Pour les options avec le type "mask", le format est :
"valeur1+valeur2+valeur3".
Pour l'URL, deux options supplémentaires (chaînes) sont autorisées, pour le
fichier en entrée/sortie :
* 'file_in' : fichier à lire pour envoyer avec l'URL (envoi de fichier "post")
* 'file_out' : écrire l'URL/fichier dans ce fichier (au lieu de la sortie
standard)
Valeur de retour :
* pointeur vers le nouveau "hook", NULL en cas d'erreur
Exemple en C :
[source,C]
----------------------------------------
int
my_process_cb (void *data, const char *command, int return_code,
const char *out, const char *err)
{
if (return_code == WEECHAT_HOOK_PROCESS_ERROR)
{
weechat_printf (NULL, "Erreur avec la commande '%s'", command);
return WEECHAT_RC_OK;
}
if (return_code >= 0)
{
weechat_printf (NULL, "return_code = %d", return_code);
}
if (out)
{
weechat_printf (NULL, "stdout : %s", out);
}
if (err)
{
weechat_printf (NULL, "stderr : %s", err);
}
return WEECHAT_RC_OK;
}
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (hashtable)
{
weechat_hashtable_set (options, "file_out", "/tmp/weechat.org.html");
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("url:http://www.weechat.org/",
options,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options);
}
----------------------------------------
Script (Python):
[source,python]
----------------------------------------
# prototype
hook = weechat.hook_process_hashtable(command, options, timeout, callback, callback_data)
# exemple
def my_process_cb(data, command, return_code, out, err):
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR:
weechat.prnt("", "Erreur avec la commande '%s'" % command)
return weechat.WEECHAT_RC_OK
if return_code >= 0:
weechat.prnt("", "return_code = %d" % return_code)
if out != "":
weechat.prnt("", "stdout: %s" % out)
if err != "":
weechat.prnt("", "stderr: %s" % err)
return weechat.WEECHAT_RC_OK
hook = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
----------------------------------------
weechat_hook_connect
^^^^^^^^^^^^^^^^^^^^
@ -13326,7 +13457,7 @@ Script (Python) :
# prototype
hashtable = weechat.hdata_hashtable(hdata, pointer, name)
# example
# exemple
hdata = weechat.hdata_get("buffer")
buffer = weechat.buffer_search_main()
hash = weechat.hdata_hashtable(hdata, buffer, "local_variables")

View File

@ -92,6 +92,7 @@ compiler WeeChat.
| Paquet ^(1)^ | Version | Requis | Fonctionnalité
| cmake | | *oui* | construction (autotools toujours possible, mais cmake est recommandé)
| libncursesw5-dev ^(2)^ | | *oui* | interface ncurses
| libcurl4-xxxxx-dev | | *oui* | transfert d'URL
| gettext | | | internationalisation (traduction des messages; la langue de base est l'anglais)
| libgcrypt11-dev | | | authentification SASL avec le serveur IRC, en utilisant le mécanisme DH-BLOWFISH
| libgnutls-dev | ≥ 2.2.0 | | connexion SSL au serveur IRC

View File

@ -58,6 +58,8 @@
| weechat | plugin | elenco dei plugin | puntatore al plugin (opzionale) | nome plugin (può iniziare o terminare con "*" come carattere jolly) (opzionale)
| weechat | url_options | options for URL | - | -
| weechat | window | elenco delle finestre | puntatore alla finestra (opzionale) | "current" per la finestra corrente o un numero della finestra (opzionale)
| xfer | xfer | lista di xfer | puntatore a xfer (opzionale) | -

View File

@ -0,0 +1,91 @@
[width="100%",cols="2,^1,7",options="header"]
|========================================
| Option | Type | Constants ^(1)^
| header | long |
| wildcardmatch | long |
| failonerror | long |
| protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| redir_protocols | mask | http, https, ftp, ftps, scp, sftp, telnet, ldap, ldaps, dict, file, tftp, imap, imaps, pop3, pop3s, smtp, smtps, rtsp, rtmp, rtmpt, rtmpe, rtmpte, rtmps, rtmpts, gopher, all
| proxy | string |
| proxyport | long |
| proxytype | long | http, http_1_0, socks4, socks5, socks4a, socks5_hostname
| noproxy | string |
| httpproxytunnel | long |
| socks5_gssapi_service | string |
| socks5_gssapi_nec | long |
| interface | string |
| localport | long |
| localportrange | long |
| dns_cache_timeout | long |
| buffersize | long |
| port | long |
| tcp_nodelay | long |
| address_scope | long |
| netrc | long | ignored, optional, required
| netrc_file | string |
| userpwd | string |
| proxyuserpwd | string |
| username | string |
| password | string |
| proxyusername | string |
| proxypassword | string |
| httpauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| tlsauth_type | mask | none, srp
| tlsauth_username | string |
| tlsauth_password | string |
| proxyauth | mask | none, basic, digest, gssnegotiate, ntlm, digest_ie, ntlm_wb, only, any, anysafe
| autoreferer | long |
| accept_encoding | string |
| transfer_encoding | long |
| followlocation | long |
| unrestricted_auth | long |
| maxredirs | long |
| postredir | mask | post_301, post_302
| post | long |
| postfields | string |
| postfieldsize | long |
|========================================

View File

@ -6731,7 +6731,9 @@ struct t_hook *weechat_hook_process (const char *command,
Argomenti:
* 'command': comando da avviare nel processo figlio
// TRANSLATION MISSING
* 'command': comando da avviare nel processo figlio or URL
(_novità nella versione 0.3.7_), see below
* 'timeout': timeout per il comando (in millisecondi): dopo questo timeout,
il processo figlio viene terminato (0 vuol dire nessun timeout)
* 'callback': funzione chiamata quando i dati dal processo figlio sono disponibili,
@ -6757,6 +6759,11 @@ Valore restituito:
Quando il comando ha terminato, o se viene raggiunto il timeout, WeeChat
effettua automaticamente l'unhook (e termina il processo se ancora in esecuzione).
// TRANSLATION MISSING
The command can be an URL with format: "url:http://www.example.com", to download
content of URL (_new in version 0.3.7_). Options are possible for URL with
function <<_weechat_hook_process_hashtable,weechat_hook_process_hashtable>>.
[NOTE]
La dimensione del buffer per l'invio dei dati alla callback è di 64KB (ci sono
2 buffer: uno per stdout ed uno per stderr).
@ -6828,6 +6835,131 @@ def my_process_cb(data, command, return_code, out, err):
hook = weechat.hook_process("ls", 5000, "my_process_cb", "")
----------------------------------------
weechat_hook_process_hashtable
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
_Novità nella versione 0.3.7._
// TRANSLATION MISSING
Hook a process (launched with fork) using options in a hashtable, and catch
output.
Prototipo:
[source,C]
----------------------------------------
struct t_hook *weechat_hook_process_hashtable (const char *command,
struct t_hashtable *options,
int timeout,
int (*callback)(void *data,
const char *command,
int return_code,
const char *out,
const char *err),
void *callback_data);
----------------------------------------
// TRANSLATION MISSING
Arguments are the same as function <<_weechat_hook_process,weechat_hook_process>>,
with an extra argument:
* 'options': options for command executed (see table below); the hashtable is
duplicated in function, so it's safe to free it after this call
// TRANSLATION MISSING
For command "url:...", following options are available (see
`man curl_easy_setopt` for a description of each option):
include::autogen/plugin_api/url_options.txt[]
// TRANSLATION MISSING
[NOTE]
^(1)^ When constants are available they must be used as value for option. For
options with type "mask", format is: "value1+value2+value3".
For URL, two extra options (strings) are allowed for input/output file:
* 'file_in': file to read and send with URLs (post file)
* 'file_out': write downloaded URL/file in this file (instead of standard
output)
Valore restituito:
* puntatore al nuovo hook, NULL in caso di errore
Esempio in C:
[source,C]
----------------------------------------
int
my_process_cb (void *data, const char *command, int return_code,
const char *out, const char *err)
{
if (return_code == WEECHAT_HOOK_PROCESS_ERROR)
{
weechat_printf (NULL, "Error with command '%s'", command);
return WEECHAT_RC_OK;
}
if (return_code >= 0)
{
weechat_printf (NULL, "return_code = %d", return_code);
}
if (out)
{
weechat_printf (NULL, "stdout: %s", out);
}
if (err)
{
weechat_printf (NULL, "stderr: %s", err);
}
return WEECHAT_RC_OK;
}
struct t_hashtable *options = weechat_hashtable_new (8,
WEECHAT_HASHTABLE_STRING,
WEECHAT_HASHTABLE_STRING,
NULL,
NULL);
if (hashtable)
{
weechat_hashtable_set (options, "file_out", "/tmp/weechat.org.html");
struct t_hook *my_process_hook = weechat_hook_process_hashtable ("url:http://www.weechat.org/",
options,
20000,
&my_process_cb, NULL);
weechat_hashtable_free (options);
}
----------------------------------------
Script (Python):
[source,python]
----------------------------------------
# prototipo
hook = weechat.hook_process_hashtable(command, options, timeout, callback, callback_data)
# esempio
def my_process_cb(data, command, return_code, out, err):
if return_code == weechat.WEECHAT_HOOK_PROCESS_ERROR:
weechat.prnt("", "Error with command '%s'" % command)
return weechat.WEECHAT_RC_OK
if return_code >= 0:
weechat.prnt("", "return_code = %d" % return_code)
if out != "":
weechat.prnt("", "stdout: %s" % out)
if err != "":
weechat.prnt("", "stderr: %s" % err)
return weechat.WEECHAT_RC_OK
hook = weechat.hook_process_hashtable("url:http://www.weechat.org/",
{ "file_out": "/tmp/weechat.org.html" },
20000, "my_process_cb", "")
----------------------------------------
weechat_hook_connect
^^^^^^^^^^^^^^^^^^^^

View File

@ -94,6 +94,8 @@ compilare WeeChat.
| Pacchetto ^(1)^ | Versione | Richiesto | Caratteristica
| cmake | | *sì* | compilazione (ancora possibile con autotools, ma si raccomanda cmake)
| libncursesw5-dev ^(2)^ | | *sì* | interfaccia ncurses
// TRANSLATION MISSING
| libcurl4-xxxxx-dev | | *sì* | URL transfer
| gettext | | | internazionalizzazione (traduzione dei messaggi; la lingua base è l'inglese)
| libgcrypt11-dev | | | autenticazione SASL per i server IRC che utilizzano il meccanismo DH-BLOWFISH
| libgnutls-dev | ≥ 2.2.0 | | connessione SSL al server IRC

View File

@ -32,6 +32,8 @@
./src/core/wee-upgrade.h
./src/core/wee-upgrade-file.c
./src/core/wee-upgrade-file.h
./src/core/wee-url.c
./src/core/wee-url.h
./src/core/wee-utf8.c
./src/core/wee-utf8.h
./src/core/wee-util.c

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"Last-Translator: Jiri Golembiovsky <golemj@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -6996,6 +6996,10 @@ msgstr ""
"jméno pluginu (může začínat nebo končit \"*\" jako zástupným znakem) "
"(volitelné)"
#, fuzzy
msgid "options for URL"
msgstr "volby pro pole"
msgid "list of windows"
msgstr "seznam oken"
@ -8197,3 +8201,13 @@ msgstr ""
msgid "Lists"
msgstr ""
#, fuzzy
msgid "Option"
msgstr "<volba>"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -22,7 +22,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"Last-Translator: Nils Görs <weechatter@arcor.de>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -7431,6 +7431,10 @@ msgstr ""
"Name einer Erweiterung (darf mit einem \"*\" als Platzhalter beginnen oder "
"enden) (optional)"
#, fuzzy
msgid "options for URL"
msgstr "Optionen für Infobars"
msgid "list of windows"
msgstr "Auflistung der Windows"
@ -8658,3 +8662,13 @@ msgstr "Variablen"
msgid "Lists"
msgstr "Listen"
#, fuzzy
msgid "Option"
msgstr "<option>"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"Last-Translator: Elián Hanisch <lambdae2@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -7201,6 +7201,10 @@ msgstr ""
"nombre del plugin (puede empezar o terminar con \"*\" como comodín) "
"(opcional)"
#, fuzzy
msgid "options for URL"
msgstr "opciones para barras"
msgid "list of windows"
msgstr "lista de ventanas"
@ -8412,3 +8416,13 @@ msgstr "Variables"
msgid "Lists"
msgstr "Listas"
#, fuzzy
msgid "Option"
msgstr "<opción>"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -21,8 +21,8 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2012-01-14 11:24+0100\n"
"Last-Translator: Sebastien Helleu <flashcode@flashtux.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
"Language: French\n"
@ -7260,6 +7260,9 @@ msgstr ""
"nom d'extension (peut démarrer ou se terminer par \"*\" comme joker) "
"(optionnel)"
msgid "options for URL"
msgstr "options pour l'URL"
msgid "list of windows"
msgstr "liste des fenêtres"
@ -8480,3 +8483,12 @@ msgstr "Variables"
msgid "Lists"
msgstr "Listes"
msgid "Option"
msgstr "Option"
msgid "Type"
msgstr "Type"
msgid "Constants"
msgstr "Constantes"

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"Last-Translator: Andras Voroskoi <voroskoi@frugalware.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -6529,6 +6529,10 @@ msgstr ""
msgid "plugin name (can start or end with \"*\" as wildcard) (optional)"
msgstr ""
#, fuzzy
msgid "options for URL"
msgstr "Aliaszok listája:\n"
#, fuzzy
msgid "list of windows"
msgstr "Mellőzések listája:\n"
@ -7725,3 +7729,13 @@ msgstr ""
msgid "Lists"
msgstr ""
#, fuzzy
msgid "Option"
msgstr "[parancs]"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -20,7 +20,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"Last-Translator: Marco Paolone <marcopaolone@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -7197,6 +7197,10 @@ msgstr ""
"nome plugin (può iniziare o terminare con \"*\" come carattere jolly) "
"(opzionale)"
#, fuzzy
msgid "options for URL"
msgstr "opzioni per le barre"
msgid "list of windows"
msgstr "elenco delle finestre"
@ -8395,3 +8399,13 @@ msgstr "Variabili"
msgid "Lists"
msgstr "Liste"
#, fuzzy
msgid "Option"
msgstr "<opzione>"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"Last-Translator: Krzysztof Korościk <soltys@szluug.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -7134,6 +7134,10 @@ msgstr "wskaźnik wtyczki (opcjonalne)"
msgid "plugin name (can start or end with \"*\" as wildcard) (optional)"
msgstr "nazwa wtyczki (może się zaczynać lub kończyć \"*\") (opcjonalne)"
#, fuzzy
msgid "options for URL"
msgstr "opcje pasków"
msgid "list of windows"
msgstr "lista okien"
@ -8320,3 +8324,13 @@ msgstr "Zmienne"
msgid "Lists"
msgstr "Listy"
#, fuzzy
msgid "Option"
msgstr "<opcja>"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2011-12-25 22:56+0100\n"
"Last-Translator: Sergio Durigan Junior <sergiosdj@gmail.com>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -6676,6 +6676,10 @@ msgstr ""
"nome do plugin (pode começar ou terminar com \"*\" como um coringa) "
"(opcional)"
#, fuzzy
msgid "options for URL"
msgstr "opções para barras"
msgid "list of windows"
msgstr "lista de janelas"
@ -7841,3 +7845,13 @@ msgstr "Variáveis"
msgid "Lists"
msgstr "Listas"
#, fuzzy
msgid "Option"
msgstr "<opção>"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -21,7 +21,7 @@ msgid ""
msgstr ""
"Project-Id-Version: WeeChat 0.3.7-dev\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: 2012-01-07 09:24+0100\n"
"Last-Translator: Aleksey V Zapparov AKA ixti <ixti@member.fsf.org>\n"
"Language-Team: weechat-dev <weechat-dev@nongnu.org>\n"
@ -6553,6 +6553,10 @@ msgstr ""
msgid "plugin name (can start or end with \"*\" as wildcard) (optional)"
msgstr ""
#, fuzzy
msgid "options for URL"
msgstr "Список сокращений:\n"
#, fuzzy
msgid "list of windows"
msgstr "Список игнорирования:\n"
@ -7743,3 +7747,13 @@ msgstr ""
msgid "Lists"
msgstr ""
#, fuzzy
msgid "Option"
msgstr "[команда]"
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -33,6 +33,8 @@ SET(WEECHAT_SOURCES
./src/core/wee-upgrade.h
./src/core/wee-upgrade-file.c
./src/core/wee-upgrade-file.h
./src/core/wee-url.c
./src/core/wee-url.h
./src/core/wee-utf8.c
./src/core/wee-utf8.h
./src/core/wee-util.c

View File

@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: flashcode@flashtux.org\n"
"POT-Creation-Date: 2012-01-08 12:03+0100\n"
"POT-Creation-Date: 2012-01-15 09:29+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@ -5713,6 +5713,9 @@ msgstr ""
msgid "plugin name (can start or end with \"*\" as wildcard) (optional)"
msgstr ""
msgid "options for URL"
msgstr ""
msgid "list of windows"
msgstr ""
@ -6783,3 +6786,12 @@ msgstr ""
msgid "Lists"
msgstr ""
msgid "Option"
msgstr ""
msgid "Type"
msgstr ""
msgid "Constants"
msgstr ""

View File

@ -124,6 +124,9 @@ IF(ICONV_FOUND)
ADD_DEFINITIONS( -DHAVE_ICONV )
ENDIF(ICONV_FOUND)
# Check for CURL
FIND_PACKAGE(CURL REQUIRED)
FIND_LIBRARY(DL_LIBRARY
NAMES dl
PATHS /lib /usr/lib /usr/libexec /usr/local/lib /usr/local/libexec

View File

@ -39,6 +39,7 @@ wee-proxy.c wee-proxy.h
wee-string.c wee-string.h
wee-upgrade.c wee-upgrade.h
wee-upgrade-file.c wee-upgrade-file.h
wee-url.c wee-url.h
wee-utf8.c wee-utf8.h
wee-util.c wee-util.h)
@ -59,5 +60,7 @@ IF(GNUTLS_FOUND)
INCLUDE_DIRECTORIES(${GNUTLS_INCLUDE_PATH})
ENDIF(GNUTLS_FOUND)
INCLUDE_DIRECTORIES(${CURL_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR})
ADD_LIBRARY(weechat_core STATIC ${LIB_CORE_SRC})

View File

@ -17,7 +17,7 @@
# along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
#
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(GCRYPT_CFLAGS) $(GNUTLS_CFLAGS)
INCLUDES = -DLOCALEDIR=\"$(datadir)/locale\" $(GCRYPT_CFLAGS) $(GNUTLS_CFLAGS) $(CURL_CFLAGS)
noinst_LIBRARIES = lib_weechat_core.a
@ -59,6 +59,8 @@ lib_weechat_core_a_SOURCES = weechat.c \
wee-upgrade.h \
wee-upgrade-file.c \
wee-upgrade-file.h \
wee-url.c \
wee-url.h \
wee-utf8.c \
wee-utf8.h \
wee-util.c \

View File

@ -46,6 +46,7 @@
#include "wee-log.h"
#include "wee-network.h"
#include "wee-string.h"
#include "wee-url.h"
#include "wee-utf8.h"
#include "wee-util.h"
#include "../gui/gui-chat.h"
@ -1293,13 +1294,14 @@ hook_fd_exec (fd_set *read_fds, fd_set *write_fds, fd_set *exception_fds)
}
/*
* hook_process: hook a process (using fork)
* hook_process_hashtable: hook a process (using fork) with options in hashtable
*/
struct t_hook *
hook_process (struct t_weechat_plugin *plugin,
const char *command, int timeout,
t_hook_callback_process *callback, void *callback_data)
hook_process_hashtable (struct t_weechat_plugin *plugin,
const char *command, struct t_hashtable *options,
int timeout,
t_hook_callback_process *callback, void *callback_data)
{
struct t_hook *new_hook;
struct t_hook_process *new_hook_process;
@ -1341,6 +1343,7 @@ hook_process (struct t_weechat_plugin *plugin,
new_hook->hook_data = new_hook_process;
new_hook_process->callback = callback;
new_hook_process->command = strdup (command);
new_hook_process->options = (options) ? hashtable_dup (options) : NULL;
new_hook_process->timeout = timeout;
new_hook_process->child_read[HOOK_PROCESS_STDOUT] = -1;
new_hook_process->child_read[HOOK_PROCESS_STDERR] = -1;
@ -1362,6 +1365,19 @@ hook_process (struct t_weechat_plugin *plugin,
return new_hook;
}
/*
* hook_process: hook a process (using fork)
*/
struct t_hook *
hook_process (struct t_weechat_plugin *plugin,
const char *command, int timeout,
t_hook_callback_process *callback, void *callback_data)
{
return hook_process_hashtable (plugin, command, NULL, timeout,
callback, callback_data);
}
/*
* hook_process_child: child process for hook process: execute function and
* return string result into pipe for WeeChat process
@ -1371,6 +1387,8 @@ void
hook_process_child (struct t_hook *hook_process)
{
char *exec_args[4] = { "sh", "-c", NULL, NULL };
const char *ptr_url;
int rc;
/*
* close stdin, so that process will fail to read stdin (process reading
@ -1392,14 +1410,36 @@ hook_process_child (struct t_hook *hook_process)
_exit (EXIT_FAILURE);
}
/* launch command */
exec_args[2] = HOOK_PROCESS(hook_process, command);
execvp (exec_args[0], exec_args);
rc = EXIT_SUCCESS;
/* should not be executed if execvp was ok */
fprintf (stderr, "Error with command '%s'\n",
HOOK_PROCESS(hook_process, command));
_exit (EXIT_FAILURE);
if (strncmp (HOOK_PROCESS(hook_process, command), "url:", 4) == 0)
{
/* get URL output (on stdout or file, depending on options) */
ptr_url = HOOK_PROCESS(hook_process, command) + 4;
while (ptr_url[0] == ' ')
{
ptr_url++;
}
rc = weeurl_download (ptr_url, HOOK_PROCESS(hook_process, options));
if (rc != 0)
fprintf (stderr, "Error with URL '%s'\n", ptr_url);
}
else
{
/* launch command */
exec_args[2] = HOOK_PROCESS(hook_process, command);
execvp (exec_args[0], exec_args);
/* should not be executed if execvp was ok */
fprintf (stderr, "Error with command '%s'\n",
HOOK_PROCESS(hook_process, command));
rc = EXIT_FAILURE;
}
fflush (stdout);
fflush (stderr);
_exit (rc);
}
/*
@ -3051,6 +3091,8 @@ unhook (struct t_hook *hook)
case HOOK_TYPE_PROCESS:
if (HOOK_PROCESS(hook, command))
free (HOOK_PROCESS(hook, command));
if (HOOK_PROCESS(hook, options))
hashtable_free (HOOK_PROCESS(hook, options));
if (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDOUT]))
unhook (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDOUT]));
if (HOOK_PROCESS(hook, hook_fd[HOOK_PROCESS_STDERR]))
@ -3378,6 +3420,8 @@ hook_add_to_infolist_type (struct t_infolist *infolist, int type,
return 0;
if (!infolist_new_var_string (ptr_item, "command", HOOK_PROCESS(ptr_hook, command)))
return 0;
if (!infolist_new_var_string (ptr_item, "options", hashtable_get_string (HOOK_PROCESS(ptr_hook, options), "keys_values")))
return 0;
if (!infolist_new_var_integer (ptr_item, "timeout", HOOK_PROCESS(ptr_hook, timeout)))
return 0;
if (!infolist_new_var_integer (ptr_item, "child_read_stdout", HOOK_PROCESS(ptr_hook, child_read[HOOK_PROCESS_STDOUT])))
@ -3792,6 +3836,10 @@ hook_print_log ()
log_printf (" process data:");
log_printf (" callback. . . . . . . : 0x%lx", HOOK_PROCESS(ptr_hook, callback));
log_printf (" command . . . . . . . : '%s'", HOOK_PROCESS(ptr_hook, command));
log_printf (" options . . . . . . . : 0x%lx (hashtable: '%s')",
HOOK_PROCESS(ptr_hook, options),
hashtable_get_string (HOOK_PROCESS(ptr_hook, options),
"keys_values"));
log_printf (" timeout . . . . . . . : %d", HOOK_PROCESS(ptr_hook, timeout));
log_printf (" child_read[stdout]. . : %d", HOOK_PROCESS(ptr_hook, child_read[HOOK_PROCESS_STDOUT]));
log_printf (" child_write[stdout] . : %d", HOOK_PROCESS(ptr_hook, child_write[HOOK_PROCESS_STDOUT]));

View File

@ -194,6 +194,7 @@ struct t_hook_process
{
t_hook_callback_process *callback; /* process callback (after child end)*/
char *command; /* command executed by child */
struct t_hashtable *options; /* options for process (see doc) */
long timeout; /* timeout (ms) (0 = no timeout) */
int child_read[2]; /* to read data in pipe from child */
int child_write[2]; /* to write data in pipe for child */
@ -443,6 +444,12 @@ extern struct t_hook *hook_process (struct t_weechat_plugin *plugin,
int timeout,
t_hook_callback_process *callback,
void *callback_data);
extern struct t_hook *hook_process_hashtable (struct t_weechat_plugin *plugin,
const char *command,
struct t_hashtable *options,
int timeout,
t_hook_callback_process *callback,
void *callback_data);
extern struct t_hook *hook_connect (struct t_weechat_plugin *plugin,
const char *proxy, const char *address,
int port, int sock, int ipv6,

628
src/core/wee-url.c Normal file
View File

@ -0,0 +1,628 @@
/*
* Copyright (C) 2012 Sebastien 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 <http://www.gnu.org/licenses/>.
*/
/*
* wee-url.c: URL transfer
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <curl/curl.h>
#include "weechat.h"
#include "wee-url.h"
#include "wee-hashtable.h"
#include "wee-infolist.h"
#include "wee-string.h"
#define URL_DEF_CONST(__prefix, __name) \
{ #__name, CURL##__prefix##_##__name }
#define URL_DEF_OPTION(__name, __type, __constants) \
{ #__name, CURLOPT_##__name, URL_TYPE_##__type, __constants }
char *url_type_string[] = { "string", "long", "mask" };
struct t_url_constant url_proxy_types[] =
{
#if LIBCURL_VERSION_NUM >= 0x070A00
/* libcurl >= 7.10 */
URL_DEF_CONST(PROXY, HTTP),
#endif
#if LIBCURL_VERSION_NUM >= 0x071304
/* libcurl >= 7.19.4 */
URL_DEF_CONST(PROXY, HTTP_1_0),
#endif
#if LIBCURL_VERSION_NUM >= 0x070A00
/* libcurl >= 7.10 */
URL_DEF_CONST(PROXY, SOCKS4),
URL_DEF_CONST(PROXY, SOCKS5),
#endif
#if LIBCURL_VERSION_NUM >= 0x071200
/* libcurl >= 7.18.0 */
URL_DEF_CONST(PROXY, SOCKS4A),
URL_DEF_CONST(PROXY, SOCKS5_HOSTNAME),
#endif
{ NULL, 0 },
};
struct t_url_constant url_protocols[] =
{
#if LIBCURL_VERSION_NUM >= 0x071304
/* libcurl >= 7.19.4 */
URL_DEF_CONST(PROTO, HTTP),
URL_DEF_CONST(PROTO, HTTPS),
URL_DEF_CONST(PROTO, FTP),
URL_DEF_CONST(PROTO, FTPS),
URL_DEF_CONST(PROTO, SCP),
URL_DEF_CONST(PROTO, SFTP),
URL_DEF_CONST(PROTO, TELNET),
URL_DEF_CONST(PROTO, LDAP),
URL_DEF_CONST(PROTO, LDAPS),
URL_DEF_CONST(PROTO, DICT),
URL_DEF_CONST(PROTO, FILE),
URL_DEF_CONST(PROTO, TFTP),
#endif
#if LIBCURL_VERSION_NUM >= 0x071400
/* libcurl >= 7.20.0 */
URL_DEF_CONST(PROTO, IMAP),
URL_DEF_CONST(PROTO, IMAPS),
URL_DEF_CONST(PROTO, POP3),
URL_DEF_CONST(PROTO, POP3S),
URL_DEF_CONST(PROTO, SMTP),
URL_DEF_CONST(PROTO, SMTPS),
URL_DEF_CONST(PROTO, RTSP),
#endif
#if LIBCURL_VERSION_NUM >= 0x071500
/* libcurl >= 7.21.0 */
URL_DEF_CONST(PROTO, RTMP),
URL_DEF_CONST(PROTO, RTMPT),
URL_DEF_CONST(PROTO, RTMPE),
URL_DEF_CONST(PROTO, RTMPTE),
URL_DEF_CONST(PROTO, RTMPS),
URL_DEF_CONST(PROTO, RTMPTS),
#endif
#if LIBCURL_VERSION_NUM >= 0x071502
/* libcurl >= 7.21.2 */
URL_DEF_CONST(PROTO, GOPHER),
#endif
#if LIBCURL_VERSION_NUM >= 0x071304
/* libcurl >= 7.19.4 */
URL_DEF_CONST(PROTO, ALL),
#endif
{ NULL, 0 },
};
struct t_url_constant url_netrc[] =
{
#if LIBCURL_VERSION_NUM >= 0x070908
/* libcurl >= 7.9.8 */
URL_DEF_CONST(_NETRC, IGNORED),
URL_DEF_CONST(_NETRC, OPTIONAL),
URL_DEF_CONST(_NETRC, REQUIRED),
#endif
{ NULL, 0 },
};
struct t_url_constant url_auth[] =
{
#if LIBCURL_VERSION_NUM >= 0x070A06
/* libcurl >= 7.10.6 */
URL_DEF_CONST(AUTH, NONE),
URL_DEF_CONST(AUTH, BASIC),
URL_DEF_CONST(AUTH, DIGEST),
URL_DEF_CONST(AUTH, GSSNEGOTIATE),
URL_DEF_CONST(AUTH, NTLM),
#endif
#if LIBCURL_VERSION_NUM >= 0x071303
/* libcurl >= 7.19.3 */
URL_DEF_CONST(AUTH, DIGEST_IE),
#endif
#if LIBCURL_VERSION_NUM >= 0x071600
/* libcurl >= 7.22.0 */
URL_DEF_CONST(AUTH, NTLM_WB),
#endif
#if LIBCURL_VERSION_NUM >= 0x071503
/* libcurl >= 7.21.3 */
URL_DEF_CONST(AUTH, ONLY),
#endif
#if LIBCURL_VERSION_NUM >= 0x070A06
/* libcurl >= 7.10.6 */
URL_DEF_CONST(AUTH, ANY),
URL_DEF_CONST(AUTH, ANYSAFE),
#endif
{ NULL, 0 },
};
struct t_url_constant url_authtype[] =
{
#if LIBCURL_VERSION_NUM >= 0x071504
/* libcurl >= 7.21.4 */
URL_DEF_CONST(_TLSAUTH, NONE),
URL_DEF_CONST(_TLSAUTH, SRP),
#endif
{ NULL, 0 },
};
struct t_url_constant url_postredir[] =
{
#if LIBCURL_VERSION_NUM >= 0x071301
/* libcurl >= 7.19.1 */
URL_DEF_CONST(_REDIR, POST_301),
URL_DEF_CONST(_REDIR, POST_302),
#endif
{ NULL, 0 },
};
struct t_url_option url_options[] =
{
/* behavior options */
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(HEADER, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x071501
/* libcurl >= 7.21 */
URL_DEF_OPTION(WILDCARDMATCH, LONG, NULL),
#endif
/* error options */
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(FAILONERROR, LONG, NULL),
#endif
/* network options */
#if LIBCURL_VERSION_NUM >= 0x071304
/* libcurl >= 7.19.4 */
URL_DEF_OPTION(PROTOCOLS, MASK, url_protocols),
URL_DEF_OPTION(REDIR_PROTOCOLS, MASK, url_protocols),
#endif
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(PROXY, STRING, NULL),
URL_DEF_OPTION(PROXYPORT, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070A00
/* libcurl >= 7.10 */
URL_DEF_OPTION(PROXYTYPE, LONG, url_proxy_types),
#endif
#if LIBCURL_VERSION_NUM >= 0x071304
/* libcurl >= 7.19.4 */
URL_DEF_OPTION(NOPROXY, STRING, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070300
/* libcurl >= 7.3 */
URL_DEF_OPTION(HTTPPROXYTUNNEL, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x071304
/* libcurl >= 7.19.4 */
URL_DEF_OPTION(SOCKS5_GSSAPI_SERVICE, STRING, NULL),
URL_DEF_OPTION(SOCKS5_GSSAPI_NEC, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070300
/* libcurl >= 7.3 */
URL_DEF_OPTION(INTERFACE, STRING, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070F02
/* libcurl >= 7.15.2 */
URL_DEF_OPTION(LOCALPORT, LONG, NULL),
URL_DEF_OPTION(LOCALPORTRANGE, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070903
/* libcurl >= 7.9.3 */
URL_DEF_OPTION(DNS_CACHE_TIMEOUT, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070A00
/* libcurl >= 7.10 */
URL_DEF_OPTION(BUFFERSIZE, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(PORT, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070B02
/* libcurl >= 7.11.2 */
URL_DEF_OPTION(TCP_NODELAY, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x071300
/* libcurl >= 7.19.0 */
URL_DEF_OPTION(ADDRESS_SCOPE, LONG, NULL),
#endif
/* name and password options (authentication) */
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(NETRC, LONG, url_netrc),
#endif
#if LIBCURL_VERSION_NUM >= 0x070B00
/* libcurl >= 7.11.0 */
URL_DEF_OPTION(NETRC_FILE, STRING, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(USERPWD, STRING, NULL),
URL_DEF_OPTION(PROXYUSERPWD, STRING, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x071301
/* libcurl >= 7.19.1 */
URL_DEF_OPTION(USERNAME, STRING, NULL),
URL_DEF_OPTION(PASSWORD, STRING, NULL),
URL_DEF_OPTION(PROXYUSERNAME, STRING, NULL),
URL_DEF_OPTION(PROXYPASSWORD, STRING, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070A06
/* libcurl >= 7.10.6 */
URL_DEF_OPTION(HTTPAUTH, MASK, url_auth),
#endif
#if LIBCURL_VERSION_NUM >= 0x071504
/* libcurl >= 7.21.4 */
URL_DEF_OPTION(TLSAUTH_TYPE, MASK, url_authtype),
URL_DEF_OPTION(TLSAUTH_USERNAME, STRING, NULL),
URL_DEF_OPTION(TLSAUTH_PASSWORD, STRING, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070A07
/* libcurl >= 7.10.7 */
URL_DEF_OPTION(PROXYAUTH, MASK, url_auth),
#endif
/* HTTP options */
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(AUTOREFERER, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x071506
/* libcurl >= 7.15.6 */
URL_DEF_OPTION(ACCEPT_ENCODING, STRING, NULL),
URL_DEF_OPTION(TRANSFER_ENCODING, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(FOLLOWLOCATION, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070A04
/* libcurl >= 7.10.4 */
URL_DEF_OPTION(UNRESTRICTED_AUTH, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070500
/* libcurl >= 7.5 */
URL_DEF_OPTION(MAXREDIRS, LONG, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x071301
/* libcurl >= 7.19.1 */
URL_DEF_OPTION(POSTREDIR, MASK, url_postredir),
#endif
#if LIBCURL_VERSION_NUM >= 0x070100
/* libcurl >= 7.1 */
URL_DEF_OPTION(POST, LONG, NULL),
URL_DEF_OPTION(POSTFIELDS, STRING, NULL),
#endif
#if LIBCURL_VERSION_NUM >= 0x070200
/* libcurl >= 7.2 */
URL_DEF_OPTION(POSTFIELDSIZE, LONG, NULL),
#endif
{ NULL, 0, 0, NULL },
};
/*
* weeurl_search_constant: search a constant in array of constants
*/
int
weeurl_search_constant (struct t_url_constant *constants, const char *name)
{
int i;
for (i = 0; constants[i].name; i++)
{
if (string_strcasecmp (constants[i].name, name) == 0)
{
return i;
}
}
/* constant not found */
return -1;
}
/*
* weeurl_get_mask_value: get value of mask using constants
* string_mask has format: "const1+const2+const3"
*/
long
weeurl_get_mask_value (struct t_url_constant *constants,
const char *string_mask)
{
char **items, *item;
int num_items, i, index;
long mask;
mask = 0;
items = string_split (string_mask, "+", 0, 0, &num_items);
if (items)
{
for (i = 0; i < num_items; i++)
{
item = string_remove_quotes(items[i], "'\"");
if (item)
{
index = weeurl_search_constant (constants, item);
if (index >= 0)
mask |= constants[index].value;
free (item);
}
}
string_free_split (items);
}
return mask;
}
/*
* weeurl_search_option: search an url option in table of options
*/
int
weeurl_search_option (const char *name)
{
int i;
for (i = 0; url_options[i].name; i++)
{
if (string_strcasecmp (url_options[i].name, name) == 0)
{
return i;
}
}
/* option not found */
return -1;
}
/*
* weeurl_read: read callback for curl, used to read data from a file
*/
size_t
weeurl_read (void *buffer, size_t size, size_t nmemb, void *stream)
{
return (stream) ? fread (buffer, size, nmemb, stream) : 0;
}
/*
* weeurl_write: write callback for curl, used to write data in a file
*/
size_t
weeurl_write (void *buffer, size_t size, size_t nmemb, void *stream)
{
return (stream) ? fwrite (buffer, size, nmemb, stream) : 0;
}
/*
* weeurl_set_options: callback called for each option in hashtable "options",
* it sets option in CURL easy handle
*/
void
weeurl_option_map_cb (void *data,
struct t_hashtable *hashtable,
const void *key, const void *value)
{
CURL *curl;
int index, index_constant, rc;
long long_value;
/* make C compiler happy */
(void) hashtable;
curl = (CURL *)data;
if (!curl)
return;
index = weeurl_search_option ((const char *)key);
if (index >= 0)
{
switch (url_options[index].type)
{
case URL_TYPE_STRING:
curl_easy_setopt (curl, url_options[index].option,
(const char *)value);
break;
case URL_TYPE_LONG:
if (url_options[index].constants)
{
index_constant = weeurl_search_constant (url_options[index].constants,
(const char *)value);
if (index_constant >= 0)
{
curl_easy_setopt (curl, url_options[index].option,
url_options[index].constants[index_constant].value);
}
}
else
{
rc = sscanf ((const char *)value, "%ld", &long_value);
if (rc != EOF)
{
curl_easy_setopt (curl, url_options[index].option,
long_value);
}
}
break;
case URL_TYPE_MASK:
if (url_options[index].constants)
{
long_value = weeurl_get_mask_value (url_options[index].constants,
(const char *)value);
curl_easy_setopt (curl, url_options[index].option,
long_value);
}
break;
}
}
return;
}
/*
* weeurl_download: download URL, using options
* return code:
* 0: ok
* 1: invalid url
* 2: error downloading url
* 3: memory error
* 4: file error
*/
int
weeurl_download (const char *url, struct t_hashtable *options)
{
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" };
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 };
int rc, i;
rc = 0;
for (i = 0; i < 2; i++)
{
url_file[i].filename = NULL;
url_file[i].stream = NULL;
}
if (!url || !url[0])
{
rc = 1;
goto end;
}
curl = curl_easy_init();
if (!curl)
{
rc = 3;
goto end;
}
/* set default options */
curl_easy_setopt (curl, CURLOPT_URL, url);
curl_easy_setopt (curl, CURLOPT_FOLLOWLOCATION, "1");
/* set file in/out from options in hashtable */
if (options)
{
for (i = 0; i < 2; i++)
{
url_file[i].filename = hashtable_get (options, url_file_option[i]);
if (url_file[i].filename)
{
url_file[i].stream = fopen (url_file[i].filename, url_file_mode[i]);
if (!url_file[i].stream)
{
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);
}
}
}
/* set other options in hashtable */
hashtable_map (options, &weeurl_option_map_cb, curl);
/* perform action! */
if (curl_easy_perform (curl) != CURLE_OK)
rc = 2;
/* cleanup */
curl_easy_cleanup (curl);
end:
for (i = 0; i < 2; i++)
{
if (url_file[i].stream)
fclose (url_file[i].stream);
}
return rc;
}
/*
* weeurl_option_add_to_infolist: add an url option in an infolist
* return 1 if ok, 0 if error
*/
int
weeurl_option_add_to_infolist (struct t_infolist *infolist,
struct t_url_option *option)
{
struct t_infolist_item *ptr_item;
char *constants;
int i, length;
if (!infolist || !option)
return 0;
ptr_item = infolist_new_item (infolist);
if (!ptr_item)
return 0;
if (!infolist_new_var_string (ptr_item, "name", option->name))
return 0;
if (!infolist_new_var_integer (ptr_item, "option", option->option))
return 0;
if (!infolist_new_var_string (ptr_item, "type", url_type_string[option->type]))
return 0;
if (option->constants)
{
length = 1;
for (i = 0; option->constants[i].name; i++)
{
length += strlen (option->constants[i].name) + 1;
}
constants = malloc (length);
if (constants)
{
constants[0] = '\0';
for (i = 0; option->constants[i].name; i++)
{
if (i > 0)
strcat (constants, ",");
strcat (constants, option->constants[i].name);
}
if (!infolist_new_var_string (ptr_item, "constants", constants))
{
free (constants);
return 0;
}
free (constants);
}
}
return 1;
}

59
src/core/wee-url.h Normal file
View File

@ -0,0 +1,59 @@
/*
* Copyright (C) 2012 Sebastien 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 <http://www.gnu.org/licenses/>.
*/
#ifndef __WEECHAT_URL_H
#define __WEECHAT_URL_H 1
struct t_hashtable;
struct t_infolist;
enum t_url_type
{
URL_TYPE_STRING = 0,
URL_TYPE_LONG,
URL_TYPE_MASK,
};
struct t_url_constant
{
char *name; /* string with name of constant */
long value; /* value of constant */
};
struct t_url_option
{
char *name; /* name of option */
int option; /* option (for curl_easy_setopt()) */
enum t_url_type type; /* type of argument expected */
struct t_url_constant *constants; /* constants allowed for this option */
};
struct t_url_file
{
char *filename; /* filename */
FILE *stream; /* file stream */
};
extern struct t_url_option url_options[];
extern int weeurl_download (const char *url, struct t_hashtable *options);
extern int weeurl_option_add_to_infolist (struct t_infolist *infolist,
struct t_url_option *option);
#endif /* __WEECHAT_URL_H */

View File

@ -71,6 +71,8 @@ ENDIF(LIBINTL_LIBRARY)
LIST(APPEND EXTRA_LIBS "m")
LIST(APPEND EXTRA_LIBS ${CURL_LIBRARIES})
ADD_EXECUTABLE(${EXECUTABLE} ${WEECHAT_CURSES_SRC})
INCLUDE_DIRECTORIES(.. ../../core ../../plugins)

View File

@ -31,6 +31,7 @@ weechat_curses_LDADD = ./../../core/lib_weechat_core.a \
$(NCURSES_LFLAGS) \
$(GCRYPT_LFLAGS) \
$(GNUTLS_LFLAGS) \
$(CURL_LFLAGS) \
-lm
weechat_curses_SOURCES = gui-curses-bar-window.c \

View File

@ -64,6 +64,8 @@ IF(LIBINTL_LIBRARY)
LIST(APPEND EXTRA_LIBS ${LIBINTL_LIBRARY})
ENDIF(LIBINTL_LIBRARY)
LIST(APPEND EXTRA_LIBS ${CURL_LIBRARIES})
ADD_EXECUTABLE(${EXECUTABLE} ${WEECHAT_GTK_SRC})
INCLUDE_DIRECTORIES(.. ../../core ../../plugins)

View File

@ -30,7 +30,8 @@ weechat_gtk_LDADD = ./../../core/lib_weechat_core.a \
$(PLUGINS_LFLAGS) \
$(GTK_LFLAGS) \
$(GCRYPT_LFLAGS) \
$(GNUTLS_LFLAGS)
$(GNUTLS_LFLAGS) \
$(CURL_LFLAGS)
weechat_gtk_SOURCES = gui-gtk-bar-window.c \
gui-gtk-chat.c \

View File

@ -42,6 +42,7 @@
#include "../core/wee-infolist.h"
#include "../core/wee-input.h"
#include "../core/wee-string.h"
#include "../core/wee-url.h"
#include "../core/wee-util.h"
#include "../gui/gui-bar.h"
#include "../gui/gui-bar-item.h"
@ -400,7 +401,7 @@ plugin_api_infolist_get_internal (void *data, const char *infolist_name,
struct t_gui_hotlist *ptr_hotlist;
struct t_gui_key *ptr_key;
struct t_weechat_plugin *ptr_plugin;
int context, number;
int context, number, i;
char *error;
/* make C compiler happy */
@ -770,6 +771,22 @@ plugin_api_infolist_get_internal (void *data, const char *infolist_name,
}
}
}
else if (string_strcasecmp (infolist_name, "url_options") == 0)
{
ptr_infolist = infolist_new ();
if (ptr_infolist)
{
for (i = 0; url_options[i].name; i++)
{
if (!weeurl_option_add_to_infolist (ptr_infolist, &url_options[i]))
{
infolist_free (ptr_infolist);
return NULL;
}
}
return ptr_infolist;
}
}
else if (string_strcasecmp (infolist_name, "window") == 0)
{
/* invalid window pointer ? */
@ -1080,6 +1097,10 @@ plugin_api_init ()
N_("plugin pointer (optional)"),
N_("plugin name (can start or end with \"*\" as wildcard) (optional)"),
&plugin_api_infolist_get_internal, NULL);
hook_infolist (NULL, "url_options", N_("options for URL"),
NULL,
NULL,
&plugin_api_infolist_get_internal, NULL);
hook_infolist (NULL, "window", N_("list of windows"),
N_("window pointer (optional)"),
N_("\"current\" for current window or a window number (optional)"),

View File

@ -634,6 +634,7 @@ plugin_load (const char *filename, int argc, char **argv)
new_plugin->hook_timer = &hook_timer;
new_plugin->hook_fd = &hook_fd;
new_plugin->hook_process = &hook_process;
new_plugin->hook_process_hashtable = &hook_process_hashtable;
new_plugin->hook_connect = &hook_connect;
new_plugin->hook_print = &hook_print;
new_plugin->hook_signal = &hook_signal;

View File

@ -2667,6 +2667,45 @@ weechat_lua_api_hook_process (lua_State *L)
API_RETURN_STRING_FREE(result);
}
/*
* weechat_lua_api_hook_process_hashtable: hook a process with options in
* a hashtable
*/
static int
weechat_lua_api_hook_process_hashtable (lua_State *L)
{
const char *command, *function, *data;
struct t_hashtable *options;
int timeout;
char *result;
API_FUNC(1, "hook_process_hashtable", API_RETURN_EMPTY);
if (lua_gettop (lua_current_interpreter) < 5)
API_WRONG_ARGS(API_RETURN_EMPTY);
command = lua_tostring (lua_current_interpreter, -5);
options = weechat_lua_tohashtable (lua_current_interpreter, -4,
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE);
timeout = lua_tonumber (lua_current_interpreter, -3);
function = lua_tostring (lua_current_interpreter, -2);
data = lua_tostring (lua_current_interpreter, -1);
result = script_ptr2str (script_api_hook_process_hashtable (weechat_lua_plugin,
lua_current_script,
command,
options,
timeout,
&weechat_lua_api_hook_process_cb,
function,
data));
if (options)
weechat_hashtable_free (options);
API_RETURN_STRING_FREE(result);
}
/*
* weechat_lua_api_hook_connect_cb: callback for connect hooked
*/
@ -6207,6 +6246,7 @@ const struct luaL_reg weechat_lua_api_funcs[] = {
API_DEF_FUNC(hook_timer),
API_DEF_FUNC(hook_fd),
API_DEF_FUNC(hook_process),
API_DEF_FUNC(hook_process_hashtable),
API_DEF_FUNC(hook_connect),
API_DEF_FUNC(hook_print),
API_DEF_FUNC(hook_signal),

View File

@ -2505,6 +2505,41 @@ XS (XS_weechat_api_hook_process)
API_RETURN_STRING_FREE(result);
}
/*
* weechat::hook_process_hashtable: hook a process with options in a hashtable
*/
XS (XS_weechat_api_hook_process_hashtable)
{
char *command, *function, *data, *result;
struct t_hashtable *options;
dXSARGS;
API_FUNC(1, "hook_process_hashtable", API_RETURN_EMPTY);
if (items < 5)
API_WRONG_ARGS(API_RETURN_EMPTY);
command = SvPV_nolen (ST (0));
options = weechat_perl_hash_to_hashtable (ST (1),
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE);
function = SvPV_nolen (ST (3));
data = SvPV_nolen (ST (4));
result = script_ptr2str (script_api_hook_process_hashtable (weechat_perl_plugin,
perl_current_script,
command,
options,
SvIV (ST (2)), /* timeout */
&weechat_perl_api_hook_process_cb,
function,
data));
if (options)
weechat_hashtable_free (options);
API_RETURN_STRING_FREE(result);
}
/*
* weechat_perl_api_hook_connect_cb: callback for connect hooked
*/
@ -5565,6 +5600,7 @@ weechat_perl_api_init (pTHX)
API_DEF_FUNC(hook_timer);
API_DEF_FUNC(hook_fd);
API_DEF_FUNC(hook_process);
API_DEF_FUNC(hook_process_hashtable);
API_DEF_FUNC(hook_connect);
API_DEF_FUNC(hook_print);
API_DEF_FUNC(hook_signal);

View File

@ -2608,6 +2608,46 @@ weechat_python_api_hook_process (PyObject *self, PyObject *args)
API_RETURN_STRING_FREE(result);
}
/*
* weechat_python_api_hook_process_hashtable: hook a process with options in
* a hashtable
*/
static PyObject *
weechat_python_api_hook_process_hashtable (PyObject *self, PyObject *args)
{
char *command, *function, *data, *result;
int timeout;
struct t_hashtable *options;
PyObject *dict, *return_value;
API_FUNC(1, "hook_process_hashtable", API_RETURN_EMPTY);
command = NULL;
options = NULL;
timeout = 0;
function = NULL;
data = NULL;
if (!PyArg_ParseTuple (args, "sOiss", &command, &dict, &timeout, &function,
&data))
API_WRONG_ARGS(API_RETURN_EMPTY);
options = weechat_python_dict_to_hashtable (dict,
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE);
result = script_ptr2str (script_api_hook_process_hashtable (weechat_python_plugin,
python_current_script,
command,
options,
timeout,
&weechat_python_api_hook_process_cb,
function,
data));
if (options)
weechat_hashtable_free (options);
API_RETURN_STRING_FREE(result);
}
/*
* weechat_python_api_hook_connect_cb: callback for connect hooked
*/
@ -5733,6 +5773,7 @@ PyMethodDef weechat_python_funcs[] =
API_DEF_FUNC(hook_timer),
API_DEF_FUNC(hook_fd),
API_DEF_FUNC(hook_process),
API_DEF_FUNC(hook_process_hashtable),
API_DEF_FUNC(hook_connect),
API_DEF_FUNC(hook_print),
API_DEF_FUNC(hook_signal),

View File

@ -2988,6 +2988,54 @@ weechat_ruby_api_hook_process (VALUE class, VALUE command, VALUE timeout,
API_RETURN_STRING_FREE(result);
}
/*
* weechat_ruby_api_hook_process_hashtable: hook a process with options in
* a hashtable
*/
static VALUE
weechat_ruby_api_hook_process_hashtable (VALUE class, VALUE command,
VALUE options, VALUE timeout,
VALUE function, VALUE data)
{
char *c_command, *c_function, *c_data, *result;
struct t_hashtable *c_options;
int c_timeout;
VALUE return_value;
API_FUNC(1, "hook_process_hashtable", API_RETURN_EMPTY);
if (NIL_P (command) || NIL_P (options) || NIL_P (timeout)
|| NIL_P (function) || NIL_P (data))
API_WRONG_ARGS(API_RETURN_EMPTY);
Check_Type (command, T_STRING);
Check_Type (options, T_HASH);
Check_Type (timeout, T_FIXNUM);
Check_Type (function, T_STRING);
Check_Type (data, T_STRING);
c_command = StringValuePtr (command);
c_options = weechat_ruby_hash_to_hashtable (options,
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE);
c_timeout = FIX2INT (timeout);
c_function = StringValuePtr (function);
c_data = StringValuePtr (data);
result = script_ptr2str (script_api_hook_process_hashtable (weechat_ruby_plugin,
ruby_current_script,
c_command,
c_options,
c_timeout,
&weechat_ruby_api_hook_process_cb,
c_function,
c_data));
if (c_options)
weechat_hashtable_free (c_options);
API_RETURN_STRING_FREE(result);
}
/*
* weechat_ruby_api_hook_connect_cb: callback for connect hooked
*/
@ -6638,6 +6686,7 @@ weechat_ruby_api_init (VALUE ruby_mWeechat)
API_DEF_FUNC(hook_timer, 5);
API_DEF_FUNC(hook_fd, 6);
API_DEF_FUNC(hook_process, 4);
API_DEF_FUNC(hook_process_hashtable, 5);
API_DEF_FUNC(hook_connect, 8);
API_DEF_FUNC(hook_print, 6);
API_DEF_FUNC(hook_signal, 3);

View File

@ -859,7 +859,50 @@ script_api_hook_fd (struct t_weechat_plugin *weechat_plugin,
}
/*
* script_api_hook_connect: hook a connection
* script_api_hook_process_hashtable: hook a process
* return new hook, NULL if error
*/
struct t_hook *
script_api_hook_process_hashtable (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
const char *command,
struct t_hashtable *options,
int timeout,
int (*callback)(void *data,
const char *command,
int return_code,
const char *out,
const char *err),
const char *function,
const char *data)
{
struct t_script_callback *new_script_callback;
struct t_hook *new_hook;
new_script_callback = script_callback_alloc ();
if (!new_script_callback)
return NULL;
script_callback_init (new_script_callback, script, function, data);
script_callback_add (script, new_script_callback);
new_hook = weechat_hook_process_hashtable (command, options, timeout,
callback, new_script_callback);
if (!new_hook)
{
script_callback_remove (script, new_script_callback);
return NULL;
}
new_script_callback->hook = new_hook;
return new_hook;
}
/*
* script_api_hook_process: hook a process
* return new hook, NULL if error
*/
@ -876,28 +919,9 @@ script_api_hook_process (struct t_weechat_plugin *weechat_plugin,
const char *function,
const char *data)
{
struct t_script_callback *new_script_callback;
struct t_hook *new_hook;
new_script_callback = script_callback_alloc ();
if (!new_script_callback)
return NULL;
script_callback_init (new_script_callback, script, function, data);
script_callback_add (script, new_script_callback);
new_hook = weechat_hook_process (command, timeout, callback,
new_script_callback);
if (!new_hook)
{
script_callback_remove (script, new_script_callback);
return NULL;
}
new_script_callback->hook = new_hook;
return new_hook;
return script_api_hook_process_hashtable (weechat_plugin, script, command,
NULL, timeout,
callback, function, data);
}
/*

View File

@ -152,6 +152,18 @@ extern struct t_hook *script_api_hook_fd (struct t_weechat_plugin *weechat_plugi
int (*callback)(void *data, int fd),
const char *function,
const char *data);
extern struct t_hook *script_api_hook_process_hashtable (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
const char *command,
struct t_hashtable *options,
int timeout,
int (*callback)(void *data,
const char *command,
int return_code,
const char *out,
const char *err),
const char *function,
const char *data);
extern struct t_hook *script_api_hook_process (struct t_weechat_plugin *weechat_plugin,
struct t_plugin_script *script,
const char *command,

View File

@ -2933,6 +2933,49 @@ weechat_tcl_api_hook_process (ClientData clientData, Tcl_Interp *interp,
API_RETURN_STRING_FREE(result);
}
/*
* weechat_tcl_api_hook_process_hashtable: hook a process with options in
* a hashtable
*/
static int
weechat_tcl_api_hook_process_hashtable (ClientData clientData,
Tcl_Interp *interp,
int objc, Tcl_Obj *CONST objv[])
{
Tcl_Obj *objp;
char *command, *function, *data, *result;
struct t_hashtable *options;
int i, timeout;
API_FUNC(1, "hook_process_hashtable", API_RETURN_EMPTY);
if (objc < 6)
API_WRONG_ARGS(API_RETURN_EMPTY);
if ((Tcl_GetIntFromObj (interp, objv[3], &timeout) != TCL_OK))
API_WRONG_ARGS(API_RETURN_EMPTY);
command = Tcl_GetStringFromObj (objv[1], &i);
options = weechat_tcl_dict_to_hashtable (interp, objv[2],
WEECHAT_SCRIPT_HASHTABLE_DEFAULT_SIZE);
function = Tcl_GetStringFromObj (objv[4], &i);
data = Tcl_GetStringFromObj (objv[5], &i);
result = script_ptr2str (script_api_hook_process_hashtable (weechat_tcl_plugin,
tcl_current_script,
command,
options,
timeout,
&weechat_tcl_api_hook_process_cb,
function,
data));
if (options)
weechat_hashtable_free (options);
API_RETURN_STRING_FREE(result);
}
/*
* weechat_tcl_api_hook_connect_cb: callback for connect hooked
*/
@ -6380,6 +6423,7 @@ void weechat_tcl_api_init (Tcl_Interp *interp)
API_DEF_FUNC(hook_timer);
API_DEF_FUNC(hook_fd);
API_DEF_FUNC(hook_process);
API_DEF_FUNC(hook_process_hashtable);
API_DEF_FUNC(hook_connect);
API_DEF_FUNC(hook_print);
API_DEF_FUNC(hook_signal);

View File

@ -46,7 +46,7 @@ struct timeval;
*/
/* API version (used to check that plugin has same API and can be loaded) */
#define WEECHAT_PLUGIN_API_VERSION "20111219-01"
#define WEECHAT_PLUGIN_API_VERSION "20120112-01"
/* macros for defining plugin infos */
#define WEECHAT_PLUGIN_NAME(__name) \
@ -516,6 +516,16 @@ struct t_weechat_plugin
const char *out,
const char *err),
void *callback_data);
struct t_hook *(*hook_process_hashtable) (struct t_weechat_plugin *plugin,
const char *command,
struct t_hashtable *options,
int timeout,
int (*callback)(void *data,
const char *command,
int return_code,
const char *out,
const char *err),
void *callback_data);
struct t_hook *(*hook_connect) (struct t_weechat_plugin *plugin,
const char *proxy,
const char *address,
@ -1281,6 +1291,11 @@ extern int weechat_plugin_end (struct t_weechat_plugin *plugin);
__callback_data) \
weechat_plugin->hook_process(weechat_plugin, __command, __timeout, \
__callback, __callback_data)
#define weechat_hook_process_hashtable(__command, __options, __timeout, \
__callback, __callback_data) \
weechat_plugin->hook_process_hashtable(weechat_plugin, __command, \
__options, __timeout, \
__callback, __callback_data)
#define weechat_hook_connect(__proxy, __address, __port, __sock, \
__ipv6, __gnutls_sess, __gnutls_cb, \
__gnutls_dhkey_size, __gnutls_priorities, \