diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index fb0f5e9..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,52 +0,0 @@
-language: c
-compiler:
- - gcc
- - clang
-
-before_script:
- # Installing yasm (needed for compiling vpx) and openal
- - sudo apt-get -yq install yasm libopenal-dev libconfig-dev libalut-dev libnotify-dev clang llvm-dev
- # Installing libsodium, needed for toxcore
- - git clone https://github.com/jedisct1/libsodium.git libsodium
- - cd libsodium
- - git checkout tags/1.0.3 > /dev/null
- - ./autogen.sh > /dev/null
- - ./configure > /dev/null
- - make check -j2 || make check || exit 1 > /dev/null
- - sudo make install > /dev/null
- - cd ..
- # Installing libopus, needed for audio encoding/decoding
- - wget http://downloads.xiph.org/releases/opus/opus-1.1.tar.gz
- - tar xzf opus-1.1.tar.gz > /dev/null
- - cd opus-1.1
- - ./configure > /dev/null
- - make -j2 || make || exit 1 > /dev/null
- - sudo make install > /dev/null
- - cd ..
- # Installing vpx
- - git clone https://chromium.googlesource.com/webm/libvpx libvpx
- - cd libvpx
- - ./configure --enable-shared > /dev/null
- - make -j2 || make || exit 1 > /dev/null
- - sudo make install > /dev/null
- - cd ..
- # Creating libraries links and updating cache
- - sudo ldconfig > /dev/null
- # Installing toxcore
- - git clone https://github.com/irungentoo/toxcore.git toxcore
- - cd toxcore
- - autoreconf -i
- - ./configure --disable-tests --disable-ntox --disable-daemon --enable-av
- - make -j2 || make || exit 1
- - sudo make install
- - cd ..
-script:
- - make -j2 || make || exit 1
-notifications:
- email: false
-
- irc:
- channels:
- - "chat.freenode.net#tox-dev"
- on_success: always
- on_failure: always
diff --git a/INSTALL.md b/INSTALL.md
index 4e96a30..12d9749 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -9,17 +9,18 @@
## Dependencies
-| Name | Needed by | Debian package |
-|------------------------------------------------------|----------------------------|------------------|
-| [Tox Core](https://github.com/irungentoo/toxcore) | BASE | *None* |
-| [NCurses](https://www.gnu.org/software/ncurses) | BASE | libncursesw5-dev |
-| [LibConfig](http://www.hyperrealm.com/libconfig) | BASE | libconfig-dev |
-| [GNUmake](https://www.gnu.org/software/make) | BASE | make |
-| [Tox Core AV](https://github.com/irungentoo/toxcore) | AUDIO | *None* |
-| [OpenAL](http://openal.org) | AUDIO, SOUND NOTIFICATIONS | libopenal-dev |
-| [OpenALUT](http://openal.org) | SOUND NOTIFICATIONS | libalut-dev |
-| [LibNotify](https://developer.gnome.org/libnotify) | DESKTOP NOTIFICATIONS | libnotify-dev |
-| [AsciiDoc](http://asciidoc.org/index.html) | DOCUMENTATION1 | asciidoc |
+| Name | Needed by | Debian package |
+|------------------------------------------------------|----------------------------|---------------------|
+| [Tox Core](https://github.com/irungentoo/toxcore) | BASE | *None* |
+| [NCurses](https://www.gnu.org/software/ncurses) | BASE | libncursesw5-dev |
+| [LibConfig](http://www.hyperrealm.com/libconfig) | BASE | libconfig-dev |
+| [GNUmake](https://www.gnu.org/software/make) | BASE | make |
+| [libcurl](http://curl.haxx.se/) | BASE | libcurl4-openssl-dev|
+| [Tox Core AV](https://github.com/irungentoo/toxcore) | AUDIO | *None* |
+| [OpenAL](http://openal.org) | AUDIO, SOUND NOTIFICATIONS | libopenal-dev |
+| [OpenALUT](http://openal.org) | SOUND NOTIFICATIONS | libalut-dev |
+| [LibNotify](https://developer.gnome.org/libnotify) | DESKTOP NOTIFICATIONS | libnotify-dev |
+| [AsciiDoc](http://asciidoc.org/index.html) | DOCUMENTATION1 | asciidoc |
1: see [Documentation](#docs)
@@ -31,7 +32,7 @@ brew install https://raw.githubusercontent.com/Tox/homebrew-tox/master/Formula/l
brew install https://raw.githubusercontent.com/Homebrew/homebrew-x11/master/libnotify.rb
```
-You can omit `libnotify` if you intend to build without desktop notifications enabled.
+You can omit `libnotify` if you intend to build without desktop notifications enabled.
## Compiling
diff --git a/Makefile b/Makefile
index b567ad5..3f73cdb 100644
--- a/Makefile
+++ b/Makefile
@@ -11,10 +11,10 @@ CFLAGS += '-DPACKAGE_DATADIR="$(abspath $(DATADIR))"'
CFLAGS += $(USER_CFLAGS)
LDFLAGS = $(USER_LDFLAGS)
-OBJ = chat.o chat_commands.o configdir.o dns.o execute.o file_transfers.o notify.o
+OBJ = chat.o chat_commands.o configdir.o execute.o file_transfers.o notify.o
OBJ += friendlist.o global_commands.o groupchat.o line_info.o input.o help.o autocomplete.o
OBJ += log.o misc_tools.o prompt.o settings.o toxic.o toxic_strings.o windows.o message_queue.o
-OBJ += group_commands.o term_mplex.o avatars.o
+OBJ += group_commands.o term_mplex.o avatars.o name_lookup.o
# Check on wich system we are running
UNAME_S = $(shell uname -s)
diff --git a/README.md b/README.md
index f4bbaee..da5d8b5 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,3 @@
-# Toxic [![Build Status](https://travis-ci.org/Tox/toxic.png?branch=master)](https://travis-ci.org/Tox/toxic)
Toxic is a [Tox](https://tox.chat)-based instant messenging client which formerly resided in the [Tox core repository](https://github.com/irungentoo/toxcore), and is now available as a standalone application.
[![Toxic Screenshot](https://i.imgur.com/san99Z2.png "Home Screen")](https://i.imgur.com/san99Z2.png)
diff --git a/cfg/global_vars.mk b/cfg/global_vars.mk
index a62d277..de60c24 100644
--- a/cfg/global_vars.mk
+++ b/cfg/global_vars.mk
@@ -16,7 +16,7 @@ MISC_DIR = $(BASE_DIR)/misc
# Project files
MANFILES = toxic.1 toxic.conf.5
-DATAFILES = DHTnodes DNSservers toxic.conf.example
+DATAFILES = DHTnodes nameservers toxic.conf.example
DESKFILE = toxic.desktop
SNDFILES = ToxicContactOnline.wav ToxicContactOffline.wav ToxicError.wav
SNDFILES += ToxicRecvMessage.wav ToxicOutgoingCall.wav ToxicIncomingCall.wav
diff --git a/cfg/systems/Darwin.mk b/cfg/systems/Darwin.mk
index d228b6a..2ddd9c5 100644
--- a/cfg/systems/Darwin.mk
+++ b/cfg/systems/Darwin.mk
@@ -6,7 +6,7 @@ PKG_CONFIG_PATH = $(shell export PKG_CONFIG_PATH=/usr/lib/pkgconfig:/usr/local/o
LIBS := $(filter-out ncursesw, $(LIBS))
# OS X ships a usable, recent version of ncurses, but calls it ncurses not ncursesw.
-LDFLAGS += -lncurses -lalut -ltoxav -ltoxcore -ltoxdns -lresolv -lconfig -ltoxencryptsave -g
+LDFLAGS += -lncurses -lalut -ltoxav -ltoxcore -lcurl -lconfig -ltoxencryptsave -g
CFLAGS += -I/usr/local/opt/freealut/include/AL -I/usr/local/opt/glib/include/glib-2.0 -g
OSX_LIBRARIES = -lobjc -lresolv
@@ -15,4 +15,4 @@ OSX_FRAMEWORKS = -framework Foundation -framework CoreFoundation -framework AVFo
OSX_VIDEO = osx_video.m
LDFLAGS += $(OSX_LIBRARIES) $(OSX_FRAMEWORKS)
-OBJ += osx_video.o
\ No newline at end of file
+OBJ += osx_video.o
diff --git a/cfg/systems/Linux.mk b/cfg/systems/Linux.mk
index 9a67614..6bd4075 100644
--- a/cfg/systems/Linux.mk
+++ b/cfg/systems/Linux.mk
@@ -1,4 +1,4 @@
# Specials options for linux systems
CFLAGS +=
-LDFLAGS += -ldl -lresolv -lrt
+LDFLAGS += -ldl -lrt -lcurl
MANDIR = $(PREFIX)/share/man
diff --git a/doc/toxic.1 b/doc/toxic.1
index af74931..79d06a5 100644
--- a/doc/toxic.1
+++ b/doc/toxic.1
@@ -2,12 +2,12 @@
.\" Title: toxic
.\" Author: [see the "AUTHORS" section]
.\" Generator: DocBook XSL Stylesheets v1.78.1
-.\" Date: 2015-03-28
+.\" Date: 2015-07-08
.\" Manual: Toxic Manual
.\" Source: toxic __VERSION__
.\" Language: English
.\"
-.TH "TOXIC" "1" "2015\-03\-28" "toxic __VERSION__" "Toxic Manual"
+.TH "TOXIC" "1" "2015\-07\-08" "toxic __VERSION__" "Toxic Manual"
.\" -----------------------------------------------------------------
.\" * Define some portability stuff
.\" -----------------------------------------------------------------
@@ -101,9 +101,9 @@ Use a SOCKS5 proxy: Requires [IP] [port]
Use a HTTP proxy: Requires [IP] [port]
.RE
.PP
-\-r, \-\-dnslist
+\-r, \-\-namelist
.RS 4
-Use specified DNSservers file
+Use specified nameservers list
.RE
.PP
\-t, \-\-force\-tcp
diff --git a/doc/toxic.1.asc b/doc/toxic.1.asc
index 4950c6b..8384091 100644
--- a/doc/toxic.1.asc
+++ b/doc/toxic.1.asc
@@ -53,8 +53,8 @@ OPTIONS
-P, --HTTP-proxy::
Use a HTTP proxy: Requires [IP] [port]
--r, --dnslist::
- Use specified DNSservers file
+-r, --namelist::
+ Use specified nameservers list
-t, --force-tcp::
Force TCP connection (use this with proxies)
diff --git a/misc/DHTnodes b/misc/DHTnodes
index 705f56a..aa6a4ec 100644
--- a/misc/DHTnodes
+++ b/misc/DHTnodes
@@ -1,25 +1,17 @@
-192.254.75.102 33445 951C88B7E75C867418ACDB5D273821372BB5BD652740BCDF623A4FA293E75D2F
144.76.60.215 33445 04119E835DF3E78BACF0F84235B300546AF8B936F035185E2A8E9E0A67C8924F
23.226.230.47 33445 A09162D68618E742FFBCA1C2C70385E6679604B2D80EA6E84AD0996A1AC8A074
-178.62.125.224 33445 10B20C49ACBD968D7C80F2E8438F92EA51F189F4E70CFBBB2C2C8C799E97F03E
178.21.112.187 33445 4B2C19E924972CB9B57732FB172F8A8604DE13EEDA2A6234E348983344B23057
195.154.119.113 33445 E398A69646B8CEACA9F0B84F553726C1C49270558C57DF5F3C368F05A7D71354
192.210.149.121 33445 F404ABAA1C99A9D37D61AB54898F56793E1DEF8BD46B1038B9D822E8460FAB67
-76.191.23.96 33445 93574A3FAB7D612FEA29FD8D67D3DD10DFD07A075A5D62E8AF3DD9F5D0932E11
46.38.239.179 33445 F5A1A38EFB6BD3C2C8AF8B10D85F0F89E931704D349F1D0720C3C4059AF2440A
178.62.250.138 33445 788236D34978D1D5BD822F0A5BEBD2C53C64CC31CD3149350EE27D4D9A2F9B6B
-78.225.128.39 33445 7A2306BFBA665E5480AE59B31E116BE9C04DCEFE04D9FE25082316FA34B4DA0C
130.133.110.14 33445 461FA3776EF0FA655F1A05477DF1B3B614F7D6B124F7DB1DD4FE3C08B03B640F
104.167.101.29 33445 5918AC3C06955962A75AD7DF4F80A5D7C34F7DB9E1498D2E0495DE35B3FE8A57
-195.154.109.148 33445 391C96CB67AE893D4782B8E4495EB9D89CF1031F48460C06075AA8CE76D50A21
-192.3.173.88 33445 3E1FFDEB667BFF549F619EC6737834762124F50A89C8D0DBF1DDF64A2DD6CD1B
205.185.116.116 33445 A179B09749AC826FF01F37A9613F6B57118AE014D4196A0E1105A98F93A54702
198.98.51.198 33445 1D5A5F2F5D6233058BF0259B09622FB40B482E4FA0931EB8FD3AB8E7BF7DAF6F
80.232.246.79 33445 A7A060D553B017D9D8F038E265C7AFB6C70BAAC55070197F9C007432D0038E0F
108.61.165.198 33445 8E7D0B859922EF569298B4D261A8CCB5FEA14FB91ED412A7603A585A25698832
212.71.252.109 33445 C4CEB8C7AC607C6B374E2E782B3C00EA3A63B80D4910B8649CCACDD19F260819
194.249.212.109 33445 3CEE1F054081E7A011234883BC4FC39F661A55B73637A5AC293DDF1251D9432B
-194.249.212.109 443 3CEE1F054081E7A011234883BC4FC39F661A55B73637A5AC293DDF1251D9432B
-103.38.216.87 33445 601AEE6FC8C17E8CD8F8F1FFC4D4AD84E59A73BE451F037194E7A404E3795320
185.25.116.107 33445 DA4E4ED4B697F2E9B000EEFE3A34B554ACD3F45F5C96EAEA2516DD7FF9AF7B43
192.99.168.140 33445 6A4D0607A296838434A6A7DDF99F50EF9D60A2C510BBF31FE538A25CB6B4652F
diff --git a/misc/DNSservers b/misc/nameservers
similarity index 50%
rename from misc/DNSservers
rename to misc/nameservers
index 379637d..94f6aab 100644
--- a/misc/DNSservers
+++ b/misc/nameservers
@@ -1,3 +1,2 @@
-utox.org d3154f65d28a5b41a05d4ac7e4b39c6b1c233cc857fb365c56e8392737462a12
toxme.io 1A39E7A5D5FA9CF155C751570A32E625698A60A55F6D88028F949F66144F4F25
diff --git a/misc/toxic.conf.example b/misc/toxic.conf.example
index a4bf7fd..070796a 100644
--- a/misc/toxic.conf.example
+++ b/misc/toxic.conf.example
@@ -66,7 +66,7 @@ tox = {
// Path for downloaded files
// download_path="/home/USERNAME/Downloads/";
- // Path for your avatar (file must be a .png and cannot exceed 16.3 KiB)
+ // Path for your avatar (file must be a .png and cannot exceed 64 KiB)
// avatar_path="/home/USERNAME/Pictures/youravatar.png";
// Path for chatlogs
diff --git a/src/chat.c b/src/chat.c
index ac6835c..1872dbd 100644
--- a/src/chat.c
+++ b/src/chat.c
@@ -63,9 +63,9 @@ static void kill_infobox(ToxWindow *self);
#endif /* AUDIO */
#ifdef AUDIO
-#define AC_NUM_CHAT_COMMANDS 27
+#define AC_NUM_CHAT_COMMANDS 28
#else
-#define AC_NUM_CHAT_COMMANDS 20
+#define AC_NUM_CHAT_COMMANDS 21
#endif /* AUDIO */
/* Array of chat command names used for tab completion. */
@@ -86,6 +86,7 @@ static const char chat_cmd_list[AC_NUM_CHAT_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/myid" },
{ "/nick" },
{ "/note" },
+ { "/nospam" },
{ "/quit" },
{ "/savefile" },
{ "/sendfile" },
diff --git a/src/dns.c b/src/dns.c
deleted file mode 100644
index c5457a7..0000000
--- a/src/dns.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/* dns.c
- *
- *
- * Copyright (C) 2014 Toxic All Rights Reserved.
- *
- * This file is part of Toxic.
- *
- * Toxic 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.
- *
- * Toxic 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 Toxic. If not, see .
- *
- */
-
-#include
-#include
-#include /* for u_char */
-#include
-#include
-
-#ifdef __APPLE__
- #include
-#else
- #include
-#endif /* ifdef __APPLE__ */
-
-#include
-
-#include "toxic.h"
-#include "windows.h"
-#include "line_info.h"
-#include "dns.h"
-#include "global_commands.h"
-#include "misc_tools.h"
-#include "configdir.h"
-
-#define DNS3_KEY_SIZE 32
-#define MAX_DNS_REQST_SIZE 255
-#define TOX_DNS3_TXT_PREFIX "v=tox3;id="
-
-extern struct Winthread Winthread;
-extern struct dns3_servers dns3_servers;
-extern struct arg_opts arg_opts;
-
-static struct thread_data {
- ToxWindow *self;
- char id_bin[TOX_ADDRESS_SIZE];
- char addr[MAX_STR_SIZE];
- char msg[MAX_STR_SIZE];
- uint8_t busy;
- Tox *m;
-} t_data;
-
-static struct dns_thread {
- pthread_t tid;
- pthread_attr_t attr;
-} dns_thread;
-
-
-#define MAX_DNS_SERVERS 50
-#define MAX_DOMAIN_SIZE 32
-#define MAX_DNS_LINE MAX_DOMAIN_SIZE + (DNS3_KEY_SIZE * 2) + 3
-
-struct dns3_servers {
- bool loaded;
- int lines;
- char names[MAX_DNS_SERVERS][MAX_DOMAIN_SIZE];
- char keys[MAX_DNS_SERVERS][DNS3_KEY_SIZE];
-} dns3_servers;
-
-static int load_dns_domainlist(const char *path)
-{
- FILE *fp = fopen(path, "r");
-
- if (fp == NULL)
- return -1;
-
- char line[MAX_DNS_LINE];
-
- while (fgets(line, sizeof(line), fp) && dns3_servers.lines < MAX_DNS_SERVERS) {
- int linelen = strlen(line);
-
- if (linelen < DNS3_KEY_SIZE * 2 + 5)
- continue;
-
- if (line[linelen - 1] == '\n')
- line[--linelen] = '\0';
-
- const char *name = strtok(line, " ");
- const char *keystr = strtok(NULL, " ");
-
- if (name == NULL || keystr == NULL)
- continue;
-
- if (strlen(keystr) != DNS3_KEY_SIZE * 2)
- continue;
-
- snprintf(dns3_servers.names[dns3_servers.lines], sizeof(dns3_servers.names[dns3_servers.lines]), "%s", name);
- int res = hex_string_to_bytes(dns3_servers.keys[dns3_servers.lines], DNS3_KEY_SIZE, keystr);
-
- if (res == -1)
- continue;
-
- ++dns3_servers.lines;
- }
-
- fclose(fp);
-
- if (dns3_servers.lines < 1)
- return -2;
-
- return 0;
-}
-
-static int dns_error(ToxWindow *self, const char *errmsg)
-{
- pthread_mutex_lock(&Winthread.lock);
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "User lookup failed: %s", errmsg);
- pthread_mutex_unlock(&Winthread.lock);
-
- return -1;
-}
-
-static void killdns_thread(void *dns_obj)
-{
- if (dns_obj)
- tox_dns3_kill(dns_obj);
-
- memset(&t_data, 0, sizeof(struct thread_data));
- pthread_attr_destroy(&dns_thread.attr);
- pthread_exit(NULL);
-}
-
-/* puts TXT from dns response in buf. Returns length of TXT on success, -1 on fail.*/
-static int parse_dns_response(ToxWindow *self, u_char *answer, int ans_len, char *buf)
-{
- uint8_t *ans_pt = answer + sizeof(HEADER);
- uint8_t *ans_end = answer + ans_len;
- char exp_ans[PACKETSZ];
-
- int len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
-
- if (len == -1)
- return dns_error(self, "dn_expand failed.");
-
- ans_pt += len;
-
- if (ans_pt > ans_end - 4)
- return dns_error(self, "DNS reply was too short.");
-
- int type;
- GETSHORT(type, ans_pt);
-
- if (type != T_TXT)
- return dns_error(self, "Broken DNS reply.");
-
-
- ans_pt += INT16SZ; /* class */
- uint32_t size = 0;
-
- /* recurse through CNAME rr's */
- do {
- ans_pt += size;
- len = dn_expand(answer, ans_end, ans_pt, exp_ans, sizeof(exp_ans));
-
- if (len == -1)
- return dns_error(self, "Second dn_expand failed.");
-
- ans_pt += len;
-
- if (ans_pt > ans_end - 10)
- return dns_error(self, "DNS reply was too short.");
-
- GETSHORT(type, ans_pt);
- ans_pt += INT16SZ;
- ans_pt += 4;
- GETSHORT(size, ans_pt);
-
- if (ans_pt + size < answer || ans_pt + size > ans_end)
- return dns_error(self, "RR overflow.");
-
- } while (type == T_CNAME);
-
- if (type != T_TXT)
- return dns_error(self, "DNS response failed.");
-
- uint32_t txt_len = *ans_pt;
-
- if (!size || txt_len >= size || !txt_len)
- return dns_error(self, "No record found.");
-
- if (txt_len > MAX_DNS_REQST_SIZE)
- return dns_error(self, "Invalid DNS response.");
-
- ans_pt++;
- ans_pt[txt_len] = '\0';
- memcpy(buf, ans_pt, txt_len + 1);
-
- return txt_len;
-}
-
-/* Takes address addr in the form "username@domain", puts the username in namebuf,
- and the domain in dombuf.
-
- return length of username on success, -1 on failure */
-static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char *dombuf, size_t dombuf_sz)
-{
- if (strlen(addr) >= MAX_STR_SIZE)
- return -1;
-
- char tmpaddr[MAX_STR_SIZE];
- char *tmpname = NULL;
- char *tmpdom = NULL;
-
- snprintf(tmpaddr, sizeof(tmpaddr), "%s", addr);
- tmpname = strtok(tmpaddr, "@");
- tmpdom = strtok(NULL, "");
-
- if (tmpname == NULL || tmpdom == NULL)
- return -1;
-
- str_to_lower(tmpdom);
- snprintf(namebuf, namebuf_sz, "%s", tmpname);
- snprintf(dombuf, dombuf_sz, "%s", tmpdom);
-
- return strlen(namebuf);
-}
-
-/* matches input domain name with domains in list and obtains key. Return 0 on success, -1 on failure */
-static int get_domain_match(char *pubkey, char *domain, const char *inputdomain)
-{
- int i;
-
- for (i = 0; i < dns3_servers.lines; ++i) {
- if (strcmp(dns3_servers.names[i], inputdomain) == 0) {
- memcpy(pubkey, dns3_servers.keys[i], DNS3_KEY_SIZE);
- snprintf(domain, MAX_DOMAIN_SIZE, "%s", dns3_servers.names[i]);
- return 0;
- }
- }
-
- return -1;
-}
-
-/* Does DNS lookup for addr and puts resulting tox id in id_bin. */
-void *dns3_lookup_thread(void *data)
-{
- ToxWindow *self = t_data.self;
-
- char inputdomain[MAX_STR_SIZE];
- char name[MAX_STR_SIZE];
-
- int namelen = parse_addr(t_data.addr, name, sizeof(name), inputdomain, sizeof(inputdomain));
-
- if (namelen == -1) {
- dns_error(self, "Must be a Tox ID or an address in the form username@domain");
- killdns_thread(NULL);
- }
-
- char DNS_pubkey[DNS3_KEY_SIZE];
- char domain[MAX_DOMAIN_SIZE];
-
- int match = get_domain_match(DNS_pubkey, domain, inputdomain);
-
- if (match == -1) {
- dns_error(self, "Domain not found.");
- killdns_thread(NULL);
- }
-
- void *dns_obj = tox_dns3_new((uint8_t *) DNS_pubkey);
-
- if (dns_obj == NULL) {
- dns_error(self, "Core failed to create DNS object.");
- killdns_thread(NULL);
- }
-
- char string[MAX_DNS_REQST_SIZE + 1];
- uint32_t request_id;
-
- int str_len = tox_generate_dns3_string(dns_obj, (uint8_t *) string, sizeof(string), &request_id,
- (uint8_t *) name, namelen);
-
- if (str_len == -1) {
- dns_error(self, "Core failed to generate DNS3 string.");
- killdns_thread(dns_obj);
- }
-
- string[str_len] = '\0';
-
- u_char answer[PACKETSZ];
- char d_string[MAX_DOMAIN_SIZE + MAX_DNS_REQST_SIZE + 10];
-
- /* format string and create dns query */
- snprintf(d_string, sizeof(d_string), "_%s._tox.%s", string, domain);
- int ans_len = res_query(d_string, C_IN, T_TXT, answer, sizeof(answer));
-
- if (ans_len <= 0) {
- dns_error(self, "DNS query failed.");
- killdns_thread(dns_obj);
- }
-
- char ans_id[MAX_DNS_REQST_SIZE + 1];
-
- /* extract TXT from DNS response */
- if (parse_dns_response(self, answer, ans_len, ans_id) == -1)
- killdns_thread(dns_obj);
-
- char encrypted_id[MAX_DNS_REQST_SIZE + 1];
- int prfx_len = strlen(TOX_DNS3_TXT_PREFIX);
-
- /* extract the encrypted ID from TXT response */
- if (strncmp(ans_id, TOX_DNS3_TXT_PREFIX, prfx_len) != 0) {
- dns_error(self, "Bad DNS3 TXT response.");
- killdns_thread(dns_obj);
- }
-
- memcpy(encrypted_id, ans_id + prfx_len, ans_len - prfx_len);
-
- if (tox_decrypt_dns3_TXT(dns_obj, (uint8_t *) t_data.id_bin, (uint8_t *) encrypted_id,
- strlen(encrypted_id), request_id) == -1) {
- dns_error(self, "Core failed to decrypt DNS response.");
- killdns_thread(dns_obj);
- }
-
- pthread_mutex_lock(&Winthread.lock);
- cmd_add_helper(self, t_data.m, t_data.id_bin, t_data.msg);
- pthread_mutex_unlock(&Winthread.lock);
-
- killdns_thread(dns_obj);
- return 0;
-}
-
-/* creates new thread for dns3 lookup. Only allows one lookup at a time. */
-void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg)
-{
- if (arg_opts.proxy_type != TOX_PROXY_TYPE_NONE && arg_opts.force_tcp) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "DNS lookups are disabled.");
- return;
- }
-
- if (t_data.busy) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous user lookup to finish.");
- return;
- }
-
- if (!dns3_servers.loaded) {
- const char *path = arg_opts.dns_path[0] ? arg_opts.dns_path : PACKAGE_DATADIR "/DNSservers";
- dns3_servers.loaded = true;
- int ret = load_dns_domainlist(path);
-
- if (ret < 0) {
- const char *errmsg = "DNS server list failed to load with error code %d. Falling back to hard-coded list.";
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, errmsg, ret);
- }
- }
-
- snprintf(t_data.id_bin, sizeof(t_data.id_bin), "%s", id_bin);
- snprintf(t_data.addr, sizeof(t_data.addr), "%s", addr);
- snprintf(t_data.msg, sizeof(t_data.msg), "%s", msg);
- t_data.self = self;
- t_data.m = m;
- t_data.busy = 1;
-
- if (pthread_attr_init(&dns_thread.attr) != 0) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to init");
- memset(&t_data, 0, sizeof(struct thread_data));
- return;
- }
-
- if (pthread_attr_setdetachstate(&dns_thread.attr, PTHREAD_CREATE_DETACHED) != 0) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread attr failed to set");
- pthread_attr_destroy(&dns_thread.attr);
- memset(&t_data, 0, sizeof(struct thread_data));
- return;
- }
-
- if (pthread_create(&dns_thread.tid, &dns_thread.attr, dns3_lookup_thread, NULL) != 0) {
- line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: DNS thread failed to init");
- pthread_attr_destroy(&dns_thread.attr);
- memset(&t_data, 0, sizeof(struct thread_data));
- return;
- }
-}
diff --git a/src/execute.c b/src/execute.c
index c4c53f6..2683b5b 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -53,6 +53,7 @@ static struct cmd_func global_commands[] = {
{ "/myid", cmd_myid },
{ "/nick", cmd_nick },
{ "/note", cmd_note },
+ { "/nospam", cmd_nospam },
{ "/q", cmd_quit },
{ "/quit", cmd_quit },
{ "/requests", cmd_requests },
diff --git a/src/global_commands.c b/src/global_commands.c
index 619224c..5166a7c 100644
--- a/src/global_commands.c
+++ b/src/global_commands.c
@@ -30,12 +30,12 @@
#include "friendlist.h"
#include "log.h"
#include "line_info.h"
-#include "dns.h"
#include "groupchat.h"
#include "prompt.h"
#include "help.h"
#include "term_mplex.h"
#include "avatars.h"
+#include "name_lookup.h"
extern char *DATA_FILE;
extern ToxWindow *prompt;
@@ -192,8 +192,8 @@ void cmd_add(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
}
cmd_add_helper(self, m, id_bin, msg);
- } else { /* assume id is a username@domain address and do DNS lookup */
- dns3_lookup(self, m, id_bin, id, msg);
+ } else { /* assume id is a username@domain address and do http name server lookup */
+ name_lookup(self, m, id_bin, id, msg);
}
}
@@ -370,9 +370,9 @@ void cmd_log(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX
if (argc == 0) {
if (log->log_on)
- msg = "Logging for this window is ON. Type \"/log off\" to disable.";
+ msg = "Logging for this window is ON; type \"/log off\" to disable. (Logs are not encrypted)";
else
- msg = "Logging for this window is OFF. Type \"/log on\" to enable.";
+ msg = "Logging for this window is OFF; type \"/log on\" to enable.";
line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, msg);
return;
@@ -484,6 +484,15 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
prompt_update_statusmessage(prompt, m, msg);
}
+void cmd_nospam(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
+{
+ uint32_t nospam = rand(); /* should be random enough */
+ tox_self_set_nospam(m, nospam);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Your Tox ID has been changed to:");
+ cmd_myid(window, self, m, 0, NULL);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Any services that relied on your old ID will need to be updated manually.");
+}
+
void cmd_prompt_help(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE])
{
help_init_menu(self);
diff --git a/src/global_commands.h b/src/global_commands.h
index 7749c45..72c573b 100644
--- a/src/global_commands.h
+++ b/src/global_commands.h
@@ -37,6 +37,7 @@ void cmd_log(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE])
void cmd_myid(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_nick(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_note(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
+void cmd_nospam(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_prompt_help(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_quit(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
void cmd_requests(WINDOW *, ToxWindow *, Tox *, int argc, char (*argv)[MAX_STR_SIZE]);
diff --git a/src/groupchat.c b/src/groupchat.c
index 04e6235..8aad7d4 100644
--- a/src/groupchat.c
+++ b/src/groupchat.c
@@ -70,9 +70,9 @@ extern struct user_settings *user_settings;
extern struct Winthread Winthread;
#ifdef AUDIO
-#define AC_NUM_GROUP_COMMANDS 22
+#define AC_NUM_GROUP_COMMANDS 23
#else
-#define AC_NUM_GROUP_COMMANDS 18
+#define AC_NUM_GROUP_COMMANDS 19
#endif /* AUDIO */
/* Array of groupchat command names used for tab completion. */
@@ -91,6 +91,7 @@ static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/myid" },
{ "/nick" },
{ "/note" },
+ { "/nospam" },
{ "/quit" },
{ "/requests" },
{ "/status" },
diff --git a/src/help.c b/src/help.c
index 1f6ff66..3eaf4e9 100644
--- a/src/help.c
+++ b/src/help.c
@@ -151,6 +151,7 @@ static void help_draw_global(ToxWindow *self)
wprintw(win, " /status : Set status with optional note\n");
wprintw(win, " /note : Set a personal note\n");
wprintw(win, " /nick : Set your nickname\n");
+ wprintw(win, " /nospam : Change part of your Tox ID to stop spam\n");
wprintw(win, " /log or : Enable/disable logging\n");
wprintw(win, " /group : Create a group chat where type: text | audio\n");
wprintw(win, " /myid : Print your Tox ID\n");
@@ -310,11 +311,10 @@ void help_onKey(ToxWindow *self, wint_t key)
case 'g':
#ifdef VIDEO
- help_init_window(self, 28, 80);
+ help_init_window(self, 29, 80);
#elif AUDIO
- help_init_window(self, 24, 80);
#else
- help_init_window(self, 20, 80);
+ help_init_window(self, 21, 80);
#endif
self->help->type = HELP_GLOBAL;
break;
diff --git a/src/name_lookup.c b/src/name_lookup.c
new file mode 100644
index 0000000..464e206
--- /dev/null
+++ b/src/name_lookup.c
@@ -0,0 +1,461 @@
+/* name_lookup.c
+ *
+ *
+ * Copyright (C) 2015 Toxic All Rights Reserved.
+ *
+ * This file is part of Toxic.
+ *
+ * Toxic 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.
+ *
+ * Toxic 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 Toxic. If not, see .
+ *
+ */
+
+#include
+#include
+#include /* for u_char */
+#include
+
+#include "toxic.h"
+#include "windows.h"
+#include "line_info.h"
+#include "global_commands.h"
+#include "misc_tools.h"
+#include "configdir.h"
+
+extern struct arg_opts arg_opts;
+extern struct Winthread Winthread;;
+
+#define NAMESERVER_API_PATH "api"
+#define SERVER_KEY_SIZE 32
+#define MAX_SERVERS 50
+#define MAX_DOMAIN_SIZE 32
+#define MAX_SERVER_LINE MAX_DOMAIN_SIZE + (SERVER_KEY_SIZE * 2) + 3
+
+/* List based on Mozilla's recommended configurations for modern browsers */
+#define TLS_CIPHER_SUITE_LIST "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!3DES:!MD5:!PSK"
+
+struct Nameservers {
+ int lines;
+ char names[MAX_SERVERS][MAX_DOMAIN_SIZE];
+ char keys[MAX_SERVERS][SERVER_KEY_SIZE];
+} Nameservers;
+
+static struct thread_data {
+ Tox *m;
+ ToxWindow *self;
+ char id_bin[TOX_ADDRESS_SIZE];
+ char addr[MAX_STR_SIZE];
+ char msg[MAX_STR_SIZE];
+ bool busy;
+ bool disabled;
+} t_data;
+
+static struct lookup_thread {
+ pthread_t tid;
+ pthread_attr_t attr;
+} lookup_thread;
+
+static int lookup_error(ToxWindow *self, const char *errmsg, ...)
+{
+ char frmt_msg[MAX_STR_SIZE];
+
+ va_list args;
+ va_start(args, errmsg);
+ vsnprintf(frmt_msg, sizeof(frmt_msg), errmsg, args);
+ va_end(args);
+
+ pthread_mutex_lock(&Winthread.lock);
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "name lookup failed: %s", frmt_msg);
+ pthread_mutex_unlock(&Winthread.lock);
+
+ return -1;
+}
+
+static void kill_lookup_thread(void)
+{
+ memset(&t_data, 0, sizeof(struct thread_data));
+ pthread_attr_destroy(&lookup_thread.attr);
+ pthread_exit(NULL);
+}
+
+/* Attempts to load the nameserver list pointed at by path into the Nameservers structure.
+ *
+ * Returns 0 on success.
+ * -1 is reserved.
+ * Returns -2 if the supplied path does not exist.
+ * Returns -3 if the list does not contain any valid entries.
+ */
+static int load_nameserver_list(const char *path)
+{
+ FILE *fp = fopen(path, "r");
+
+ if (fp == NULL)
+ return -2;
+
+ char line[MAX_SERVER_LINE];
+
+ while (fgets(line, sizeof(line), fp) && Nameservers.lines < MAX_SERVERS) {
+ int linelen = strlen(line);
+
+ if (linelen < SERVER_KEY_SIZE * 2 + 5)
+ continue;
+
+ if (line[linelen - 1] == '\n')
+ line[--linelen] = '\0';
+
+ const char *name = strtok(line, " ");
+ const char *keystr = strtok(NULL, " ");
+
+ if (name == NULL || keystr == NULL)
+ continue;
+
+ if (strlen(keystr) != SERVER_KEY_SIZE * 2)
+ continue;
+
+ snprintf(Nameservers.names[Nameservers.lines], sizeof(Nameservers.names[Nameservers.lines]), "%s", name);
+ int res = hex_string_to_bytes(Nameservers.keys[Nameservers.lines], SERVER_KEY_SIZE, keystr);
+
+ if (res == -1)
+ continue;
+
+ ++Nameservers.lines;
+ }
+
+ fclose(fp);
+
+ if (Nameservers.lines < 1)
+ return -3;
+
+ return 0;
+}
+
+/* Takes address addr in the form "username@domain", puts the username in namebuf,
+ * and the domain in dombuf.
+ *
+ * Returns 0 on success.
+ * Returns -1 on failure
+ */
+static int parse_addr(const char *addr, char *namebuf, size_t namebuf_sz, char *dombuf, size_t dombuf_sz)
+{
+ if (strlen(addr) >= (MAX_STR_SIZE - strlen(NAMESERVER_API_PATH)))
+ return -1;
+
+ char tmpaddr[MAX_STR_SIZE];
+ char *tmpname = NULL;
+ char *tmpdom = NULL;
+
+ snprintf(tmpaddr, sizeof(tmpaddr), "%s", addr);
+ tmpname = strtok(tmpaddr, "@");
+ tmpdom = strtok(NULL, "");
+
+ if (tmpname == NULL || tmpdom == NULL)
+ return -1;
+
+ str_to_lower(tmpdom);
+ snprintf(namebuf, namebuf_sz, "%s", tmpname);
+ snprintf(dombuf, dombuf_sz, "%s", tmpdom);
+
+ return 0;
+}
+
+/* matches input domain name with domains in list and obtains key.
+ * Turns out_domain into the full domain we need to make a POST request.
+ *
+ * Return true on match.
+ * Returns false on no match.
+ */
+static bool get_domain_match(char *pubkey, char *out_domain, size_t out_domain_size, const char *inputdomain)
+{
+ int i;
+
+ for (i = 0; i < Nameservers.lines; ++i) {
+ if (strcmp(Nameservers.names[i], inputdomain) == 0) {
+ memcpy(pubkey, Nameservers.keys[i], SERVER_KEY_SIZE);
+ snprintf(out_domain, out_domain_size, "https://%s/%s", Nameservers.names[i], NAMESERVER_API_PATH);
+ return true;
+ }
+ }
+
+ return false;
+}
+
+#define MAX_RECV_LOOKUP_DATA_SIZE 1024
+
+/* Holds raw data received from name server */
+struct Recv_Data {
+ char data[MAX_RECV_LOOKUP_DATA_SIZE];
+ size_t size;
+};
+
+size_t write_lookup_data(void *data, size_t size, size_t nmemb, void *user_pointer)
+{
+ struct Recv_Data *recv_data = (struct Recv_Data *) user_pointer;
+ size_t real_size = size * nmemb;
+
+ if (real_size > MAX_RECV_LOOKUP_DATA_SIZE)
+ return 0;
+
+ memcpy(&recv_data->data, data, real_size);
+ recv_data->size = real_size;
+ recv_data->data[real_size] = 0;
+
+ return real_size;
+}
+
+/* Converts Tox ID string contained in recv_data to binary format and puts it in thread's ID buffer.
+ *
+ * Returns 0 on success.
+ * Returns -1 on failure.
+ */
+#define ID_PREFIX "\"tox_id\": \""
+static int process_response(struct Recv_Data *recv_data)
+{
+ size_t prefix_size = strlen(ID_PREFIX);
+
+ if (recv_data->size < TOX_ADDRESS_SIZE * 2 + prefix_size)
+ return -1;
+
+ const char *IDstart = strstr(recv_data->data, ID_PREFIX);
+
+ if (IDstart == NULL)
+ return -1;
+
+ if (strlen(IDstart) < TOX_ADDRESS_SIZE * 2 + prefix_size)
+ return -1;
+
+ char ID_string[TOX_ADDRESS_SIZE * 2 + 1];
+ memcpy(ID_string, IDstart + prefix_size, TOX_ADDRESS_SIZE * 2);
+ ID_string[TOX_ADDRESS_SIZE * 2] = 0;
+
+ if (hex_string_to_bin(ID_string, strlen(ID_string), t_data.id_bin, sizeof(t_data.id_bin)) == -1)
+ return -1;
+
+ return 0;
+}
+
+/* Sets proxy info for given CURL handler.
+ *
+ * Returns 0 on success or if no proxy is set by the client.
+ * Returns -1 on failure.
+ */
+static int set_lookup_proxy(ToxWindow *self, CURL *c_handle, const char *proxy_address, uint16_t port, uint8_t proxy_type)
+{
+ if (proxy_type == TOX_PROXY_TYPE_NONE)
+ return 0;
+
+ if (proxy_address == NULL || port == 0) {
+ lookup_error(self, "Unknown proxy error");
+ return -1;
+ }
+
+ int ret = curl_easy_setopt(c_handle, CURLOPT_PROXYPORT, (long) port);
+
+ if (ret != CURLE_OK) {
+ lookup_error(self, "Failed to set proxy port (libcurl error %d)", ret);
+ return -1;
+ }
+
+ long int type = proxy_type == TOX_PROXY_TYPE_SOCKS5 ? CURLPROXY_SOCKS5_HOSTNAME : CURLPROXY_HTTP;
+
+ ret = curl_easy_setopt(c_handle, CURLOPT_PROXYTYPE, type);
+
+ if (ret != CURLE_OK) {
+ lookup_error(self, "Failed to set proxy type (libcurl error %d)", ret);
+ return -1;
+ }
+
+ ret = curl_easy_setopt(c_handle, CURLOPT_PROXY, proxy_address);
+
+ if (ret != CURLE_OK) {
+ lookup_error(self, "Failed to set proxy (libcurl error %d)", ret);
+ return -1;
+ }
+
+ return 0;
+}
+
+void *lookup_thread_func(void *data)
+{
+ ToxWindow *self = t_data.self;
+
+ char input_domain[MAX_STR_SIZE];
+ char name[MAX_STR_SIZE];
+
+ if (parse_addr(t_data.addr, name, sizeof(name), input_domain, sizeof(input_domain)) == -1) {
+ lookup_error(self, "Input must be a 76 character Tox ID or an address in the form: username@domain");
+ kill_lookup_thread();
+ }
+
+ char nameserver_key[SERVER_KEY_SIZE];
+ char real_domain[MAX_DOMAIN_SIZE];
+
+ if (!get_domain_match(nameserver_key, real_domain, sizeof(real_domain), input_domain)) {
+ if (!strcasecmp(input_domain, "utox.org"))
+ lookup_error(self, "utox.org uses deprecated DNS-based lookups and is no longer supported by Toxic");
+ else
+ lookup_error(self, "Name server domain not found.");
+
+ kill_lookup_thread();
+ }
+
+ CURL *c_handle = curl_easy_init();
+
+ if (!c_handle) {
+ lookup_error(self, "curl handler error");
+ kill_lookup_thread();
+ }
+
+ struct Recv_Data recv_data;
+ memset(&recv_data, 0, sizeof(struct Recv_Data));
+
+ char post_data[MAX_STR_SIZE];
+ snprintf(post_data, sizeof(post_data), "{\"action\": 3, \"name\": \"%s\"}", name);
+
+ struct curl_slist *headers = NULL;
+
+ headers = curl_slist_append(headers, "Content-Type: application/json");
+ headers = curl_slist_append(headers, "charsets: utf-8");
+
+ curl_easy_setopt(c_handle, CURLOPT_HTTPHEADER, headers);
+ curl_easy_setopt(c_handle, CURLOPT_URL, real_domain);
+ curl_easy_setopt(c_handle, CURLOPT_WRITEFUNCTION, write_lookup_data);
+ curl_easy_setopt(c_handle, CURLOPT_WRITEDATA, (void *) &recv_data);
+ curl_easy_setopt(c_handle, CURLOPT_USERAGENT, "libcurl-agent/1.0");
+ curl_easy_setopt(c_handle, CURLOPT_POSTFIELDS, post_data);
+
+ if (set_lookup_proxy(self, c_handle, arg_opts.proxy_address, arg_opts.proxy_port, arg_opts.proxy_type) == -1)
+ goto on_exit;
+
+ int ret = curl_easy_setopt(c_handle, CURLOPT_USE_SSL, CURLUSESSL_ALL);
+
+ if (ret != CURLE_OK) {
+ lookup_error(self, "TLS could not be enabled (libcurl error %d)", ret);
+ goto on_exit;
+ }
+
+ ret = curl_easy_setopt(c_handle, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
+
+ if (ret != CURLE_OK) {
+ lookup_error(self, "TLSv1.2 could not be set (libcurl error %d)", ret);
+ goto on_exit;
+ }
+
+ ret = curl_easy_setopt(c_handle, CURLOPT_SSL_CIPHER_LIST, TLS_CIPHER_SUITE_LIST);
+
+ if (ret != CURLE_OK) {
+ lookup_error(self, "Failed to set TLS cipher list (libcurl error %d)", ret);
+ goto on_exit;
+ }
+
+ ret = curl_easy_perform(c_handle);
+
+ if (ret != CURLE_OK) {
+ /* If system doesn't support any of the specified ciphers suites, fall back to default */
+ if (ret == CURLE_SSL_CIPHER) {
+ curl_easy_setopt(c_handle, CURLOPT_SSL_CIPHER_LIST, NULL);
+ ret = curl_easy_perform(c_handle);
+ }
+
+ if (ret != CURLE_OK) {
+ lookup_error(self, "HTTPS lookup error (libcurl error %d)", ret);
+ goto on_exit;
+ }
+ }
+
+ if (process_response(&recv_data) == -1) {
+ lookup_error(self, "Bad response.");
+ goto on_exit;
+ }
+
+ pthread_mutex_lock(&Winthread.lock);
+ cmd_add_helper(self, t_data.m, t_data.id_bin, t_data.msg);
+ pthread_mutex_unlock(&Winthread.lock);
+
+on_exit:
+ curl_slist_free_all(headers);
+ curl_easy_cleanup(c_handle);
+ kill_lookup_thread();
+
+ return 0;
+}
+
+void name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message)
+{
+ if (t_data.disabled) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "name lookups are disabled.");
+ return;
+ }
+
+ if (t_data.busy) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, 0, "Please wait for previous name lookup to finish.");
+ return;
+ }
+
+ snprintf(t_data.id_bin, sizeof(t_data.id_bin), "%s", id_bin);
+ snprintf(t_data.addr, sizeof(t_data.addr), "%s", addr);
+ snprintf(t_data.msg, sizeof(t_data.msg), "%s", message);
+ t_data.self = self;
+ t_data.m = m;
+ t_data.busy = true;
+
+ if (pthread_attr_init(&lookup_thread.attr) != 0) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to init");
+ memset(&t_data, 0, sizeof(struct thread_data));
+ return;
+ }
+
+ if (pthread_attr_setdetachstate(&lookup_thread.attr, PTHREAD_CREATE_DETACHED) != 0) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread attr failed to set");
+ pthread_attr_destroy(&lookup_thread.attr);
+ memset(&t_data, 0, sizeof(struct thread_data));
+ return;
+ }
+
+ if (pthread_create(&lookup_thread.tid, &lookup_thread.attr, lookup_thread_func, NULL) != 0) {
+ line_info_add(self, NULL, NULL, NULL, SYS_MSG, 0, RED, "Error: lookup thread failed to init");
+ pthread_attr_destroy(&lookup_thread.attr);
+ memset(&t_data, 0, sizeof(struct thread_data));
+ return;
+ }
+}
+
+/* Initializes http based name lookups. Note: This function must be called only once before additional
+ * threads are spawned.
+ *
+ * Returns 0 on success.
+ * Returns -1 if curl failed to init.
+ * Returns -2 if the nameserver list cannot be found.
+ * Returns -3 if the nameserver list does not contain any valid entries.
+ */
+int name_lookup_init(void)
+{
+ if (curl_global_init(CURL_GLOBAL_ALL) != 0) {
+ t_data.disabled = true;
+ return -1;
+ }
+
+ const char *path = arg_opts.nameserver_path[0] ? arg_opts.nameserver_path : PACKAGE_DATADIR "/nameservers";
+ int ret = load_nameserver_list(path);
+
+ if (ret != 0) {
+ t_data.disabled = true;
+ return ret;
+ }
+
+ return 0;
+}
+
+void name_lookup_cleanup(void)
+{
+ curl_global_cleanup();
+}
diff --git a/src/dns.h b/src/name_lookup.h
similarity index 59%
rename from src/dns.h
rename to src/name_lookup.h
index 9e6852e..c1419d8 100644
--- a/src/dns.h
+++ b/src/name_lookup.h
@@ -1,7 +1,7 @@
-/* dns.c
+/* name_lookup.h
*
*
- * Copyright (C) 2014 Toxic All Rights Reserved.
+ * Copyright (C) 2015 Toxic All Rights Reserved.
*
* This file is part of Toxic.
*
@@ -20,13 +20,18 @@
*
*/
-/* Does DNS lookup for addr and puts resulting tox id in id_bin.
- Return 0 on success, -1 on failure. */
+#ifndef NAME_LOOKUP
+#define NAME_LOOKUP
-#ifndef DNS_H
-#define DNS_H
+/* Initializes http based name lookups. Note: This function must be called only once before additional
+ * threads are spawned.
+ *
+ * Returns 0 on success.
+ * Returns -1 on failure.
+ */
+int name_lookup_init(void);
+void name_lookup_cleanup(void);
-/* creates new thread for dns3 lookup. Only allows one lookup at a time. */
-void dns3_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *msg);
+int name_lookup(ToxWindow *self, Tox *m, const char *id_bin, const char *addr, const char *message);
-#endif /* #define DNS_H */
+#endif /* NAME_LOOKUP */
diff --git a/src/prompt.c b/src/prompt.c
index f0cb6c3..a103675 100644
--- a/src/prompt.c
+++ b/src/prompt.c
@@ -50,11 +50,10 @@ extern struct Winthread Winthread;
extern FriendsList Friends;
FriendRequests FrndRequests;
#ifdef VIDEO
-#define AC_NUM_GLOB_COMMANDS 20
+#define AC_NUM_GLOB_COMMANDS 21
#elif AUDIO
-#define AC_NUM_GLOB_COMMANDS 18
#else
-#define AC_NUM_GLOB_COMMANDS 16
+#define AC_NUM_GLOB_COMMANDS 17
#endif
/* Array of global command names used for tab completion. */
@@ -72,6 +71,7 @@ static const char glob_cmd_list[AC_NUM_GLOB_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/myid" },
{ "/nick" },
{ "/note" },
+ { "/nospam" },
{ "/quit" },
{ "/requests" },
{ "/status" },
diff --git a/src/toxic.c b/src/toxic.c
index 0d49557..ba41f5a 100644
--- a/src/toxic.c
+++ b/src/toxic.c
@@ -58,6 +58,7 @@
#include "message_queue.h"
#include "execute.h"
#include "term_mplex.h"
+#include "name_lookup.h"
#ifdef X11
#include "xtra.h"
@@ -163,6 +164,7 @@ void exit_toxic_success(Tox *m)
free_global_data();
tox_kill(m);
endwin();
+ name_lookup_cleanup();
#ifdef X11
/* We have to terminate xtra last coz reasons
@@ -912,7 +914,7 @@ static void print_usage(void)
fprintf(stderr, " -o, --noconnect Do not connect to the DHT network\n");
fprintf(stderr, " -p, --SOCKS5-proxy Use SOCKS5 proxy: Requires [IP] [port]\n");
fprintf(stderr, " -P, --HTTP-proxy Use HTTP proxy: Requires [IP] [port]\n");
- fprintf(stderr, " -r, --dnslist Use specified DNSservers file\n");
+ fprintf(stderr, " -r, --namelist Use specified name lookup server list\n");
fprintf(stderr, " -t, --force-tcp Force toxic to use a TCP connection (use with proxies)\n");
fprintf(stderr, " -T, --tcp-server Act as a TCP relay server: Requires [port]\n");
fprintf(stderr, " -u, --unencrypt-data Unencrypt an encrypted data file\n");
@@ -940,7 +942,7 @@ static void parse_args(int argc, char *argv[])
{"nodes", required_argument, 0, 'n'},
{"help", no_argument, 0, 'h'},
{"noconnect", no_argument, 0, 'o'},
- {"dnslist", required_argument, 0, 'r'},
+ {"namelist", required_argument, 0, 'r'},
{"force-tcp", no_argument, 0, 't'},
{"tcp-server", required_argument, 0, 'T'},
{"SOCKS5-proxy", required_argument, 0, 'p'},
@@ -1052,10 +1054,10 @@ static void parse_args(int argc, char *argv[])
break;
case 'r':
- snprintf(arg_opts.dns_path, sizeof(arg_opts.dns_path), "%s", optarg);
+ snprintf(arg_opts.nameserver_path, sizeof(arg_opts.nameserver_path), "%s", optarg);
- if (!file_exists(arg_opts.dns_path))
- queue_init_message("DNSservers file not found");
+ if (!file_exists(arg_opts.nameserver_path))
+ queue_init_message("nameserver list not found");
break;
@@ -1085,7 +1087,6 @@ static void parse_args(int argc, char *argv[])
}
/* Looks for an old default profile data file and blocklist, and renames them to the new default names.
- * Saves the old data files under the names "toxic_data.old" and "toxic_data_blocklist.old".
*
* Returns 0 on success.
* Returns -1 on failure.
@@ -1231,7 +1232,18 @@ int main(int argc, char **argv)
exit_toxic_err("failed in main", FATALERR_MEMORY);
const char *p = arg_opts.config_path[0] ? arg_opts.config_path : NULL;
- int settings_err = settings_load(user_settings, p);
+
+ if (settings_load(user_settings, p) == -1)
+ queue_init_message("Failed to load user settings");
+
+ int nameserver_ret = name_lookup_init();
+
+ if (nameserver_ret == -1)
+ queue_init_message("curl failed to initialize; name lookup service is disabled.");
+ else if (nameserver_ret == -2)
+ queue_init_message("Name lookup server list could not be found.");
+ else if (nameserver_ret == -3)
+ queue_init_message("Name lookup server list does not contain any valid entries.");
#ifdef X11
if (init_xtra(DnD_callback) == -1)
@@ -1285,9 +1297,6 @@ int main(int argc, char **argv)
init_notify(60, 3000);
- if (settings_err == -1)
- queue_init_message("Failed to load user settings");
-
/* screen/tmux auto-away timer */
if (init_mplex_away_timer(m) == -1)
queue_init_message("Failed to init mplex auto-away.");
diff --git a/src/windows.h b/src/windows.h
index c27b433..acef667 100644
--- a/src/windows.h
+++ b/src/windows.h
@@ -90,7 +90,7 @@ struct arg_opts {
bool encrypt_data;
bool unencrypt_data;
- char dns_path[MAX_STR_SIZE];
+ char nameserver_path[MAX_STR_SIZE];
char config_path[MAX_STR_SIZE];
char nodes_path[MAX_STR_SIZE];