diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 6ce695d..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/JFreegman/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-groupchats"
- 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 392b257..1de0582 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 b8ead14..fa8c703 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.im)-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 2f4cc04..b33aa0a 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 f33a4be..1fc579b 100644
--- a/cfg/systems/Darwin.mk
+++ b/cfg/systems/Darwin.mk
@@ -6,5 +6,5 @@ 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
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/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 f4c0d9d..063551f 100644
--- a/misc/toxic.conf.example
+++ b/misc/toxic.conf.example
@@ -69,7 +69,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 7d17d0d..b5fb4f9 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 28
+#define AC_NUM_CHAT_COMMANDS 29
#else
-#define AC_NUM_CHAT_COMMANDS 21
+#define AC_NUM_CHAT_COMMANDS 22
#endif /* AUDIO */
/* Array of chat command names used for tab completion. */
@@ -87,6 +87,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 9595fcc..a658066 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -56,6 +56,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 be5a191..be6510f 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 */
- 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);
}
}
@@ -448,9 +448,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;
@@ -552,6 +552,15 @@ void cmd_note(WINDOW *window, ToxWindow *self, Tox *m, int argc, char (*argv)[MA
prompt_update_statusmessage(prompt, m, argv[1]);
}
+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 4615087..30c3ea3 100644
--- a/src/global_commands.h
+++ b/src/global_commands.h
@@ -38,6 +38,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 d32c802..08f28c5 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 40
+#define AC_NUM_GROUP_COMMANDS 41
#else
-#define AC_NUM_GROUP_COMMANDS 36
+#define AC_NUM_GROUP_COMMANDS 37
#endif /* AUDIO */
/* groupchat command names used for tab completion. */
@@ -99,6 +99,7 @@ static const char group_cmd_list[AC_NUM_GROUP_COMMANDS][MAX_CMDNAME_SIZE] = {
{ "/nick" },
{ "/note" },
{ "/passwd" },
+ { "/nospam" },
{ "/peerlimit" },
{ "/privacy" },
{ "/quit" },
diff --git a/src/help.c b/src/help.c
index 00f092d..11b6e68 100644
--- a/src/help.c
+++ b/src/help.c
@@ -153,6 +153,7 @@ static void help_draw_global(ToxWindow *self)
wprintw(win, " /group : Create a group chat\n");
wprintw(win, " /join : Join a group chat with optional password\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, " /myid : Print your Tox ID\n");
wprintw(win, " /clear : Clear window history\n");
diff --git a/src/name_lookup.c b/src/name_lookup.c
new file mode 100644
index 0000000..4f259e2
--- /dev/null
+++ b/src/name_lookup.c
@@ -0,0 +1,422 @@
+/* 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;
+}
+
+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);
+
+ 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, "");
+ 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 (arg_opts.proxy_type != TOX_PROXY_TYPE_NONE && arg_opts.force_tcp) {
+ 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 e080058..864dd7d 100644
--- a/src/prompt.c
+++ b/src/prompt.c
@@ -51,9 +51,9 @@ extern FriendsList Friends;
FriendRequests FrndRequests;
#ifdef AUDIO
-#define AC_NUM_GLOB_COMMANDS 19
+#define AC_NUM_GLOB_COMMANDS 20
#else
-#define AC_NUM_GLOB_COMMANDS 17
+#define AC_NUM_GLOB_COMMANDS 18
#endif /* AUDIO */
/* Array of global command names used for tab completion. */
@@ -72,6 +72,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 893c298..4ac41e1 100644
--- a/src/toxic.c
+++ b/src/toxic.c
@@ -59,6 +59,7 @@
#include "message_queue.h"
#include "execute.h"
#include "term_mplex.h"
+#include "name_lookup.h"
#ifdef X11
#include "xtra.h"
@@ -156,6 +157,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
@@ -925,7 +927,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");
@@ -953,7 +955,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'},
@@ -1065,10 +1067,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;
@@ -1098,7 +1100,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.
@@ -1245,7 +1246,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)
@@ -1294,9 +1306,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 ffe253d..2cbc413 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];