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];