1
0
mirror of https://github.com/Tha14/toxic.git synced 2024-12-23 07:13:25 +01:00

Refactor a few complex functions

Also moved some single use functions from misc_tools to their
respective files
This commit is contained in:
jfreegman 2020-11-01 15:55:07 -05:00
parent 7560bc9547
commit e7a0c32a68
No known key found for this signature in database
GPG Key ID: 3627F3144076AE63
6 changed files with 136 additions and 145 deletions

View File

@ -56,7 +56,7 @@ static void print_ac_matches(ToxWindow *self, Tox *m, char **list, size_t n_matc
*
* Returns the length of the match.
*/
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, char **matches, size_t n_items,
static size_t get_str_match(ToxWindow *self, char *match, size_t match_sz, const char **matches, size_t n_items,
size_t max_size)
{
UNUSED_VAR(self);
@ -181,7 +181,7 @@ static int complete_line_helper(ToxWindow *self, const char **list, const size_t
}
char match[MAX_STR_SIZE];
size_t match_len = get_str_match(self, match, sizeof(match), matches, n_matches, MAX_STR_SIZE);
size_t match_len = get_str_match(self, match, sizeof(match), (const char **) matches, n_matches, MAX_STR_SIZE);
free_ptr_array((void **) matches);
@ -298,6 +298,18 @@ static void complete_home_dir(ToxWindow *self, char *path, int pathsize, const c
ctx->len = ctx->pos;
}
/*
* Return true if the first `p_len` chars in `s` are equal to `p` and `s` is a valid directory name.
*/
static bool is_partial_match(const char *s, const char *p, size_t p_len)
{
if (s == NULL || p == NULL) {
return false;
}
return strncmp(s, p, p_len) == 0 && strcmp(".", s) != 0 && strcmp("..", s) != 0;
}
/* Attempts to match /command "<incomplete-dir>" line to matching directories.
* If there is only one match the line is auto-completed.
*
@ -336,7 +348,7 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
snprintf(b_name, sizeof(b_name), "%s", &b_path[si + 1]);
b_path[si + 1] = '\0';
int b_name_len = strlen(b_name);
size_t b_name_len = strlen(b_name);
DIR *dp = opendir(b_path);
if (dp == NULL) {
@ -355,8 +367,7 @@ int dir_match(ToxWindow *self, Tox *m, const wchar_t *line, const wchar_t *cmd)
int dircount = 0;
while ((entry = readdir(dp)) && dircount < MAX_DIRS) {
if (strncmp(entry->d_name, b_name, b_name_len) == 0
&& strcmp(".", entry->d_name) && strcmp("..", entry->d_name)) {
if (is_partial_match(entry->d_name, b_name, b_name_len)) {
snprintf(dirnames[dircount], NAME_MAX + 1, "%s", entry->d_name);
++dircount;
}

View File

@ -39,6 +39,37 @@ static struct Avatar {
off_t size;
} Avatar;
/* Compares the first size bytes of fp to signature.
*
* Returns 0 if they are the same
* Returns 1 if they differ
* Returns -1 on error.
*
* On success this function will seek back to the beginning of fp.
*/
static int check_file_signature(const unsigned char *signature, size_t size, FILE *fp)
{
char *buf = malloc(size);
if (buf == NULL) {
return -1;
}
if (fread(buf, size, 1, fp) != 1) {
free(buf);
return -1;
}
int ret = memcmp(signature, buf, size);
free(buf);
if (fseek(fp, 0L, SEEK_SET) == -1) {
return -1;
}
return ret == 0 ? 0 : 1;
}
static void avatar_clear(void)
{

View File

@ -24,6 +24,9 @@
#include <string.h>
#include <stdbool.h>
#include <limits.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <curl/curl.h>
#include <tox/tox.h>
@ -105,6 +108,37 @@ static struct DHT_Nodes {
time_t last_updated;
} Nodes;
/* Return true if address appears to be a valid ipv4 address. */
static bool is_ip4_address(const char *address)
{
struct sockaddr_in s_addr;
return inet_pton(AF_INET, address, &(s_addr.sin_addr)) != 0;
}
/* Return true if address roughly appears to be a valid ipv6 address.
*
* TODO: Improve this function (inet_pton behaves strangely with ipv6).
* for now the only guarantee is that it won't return true if the
* address is a domain or ipv4 address, and should only be used if you're
* reasonably sure that the address is one of the three (ipv4, ipv6 or a domain).
*/
static bool is_ip6_address(const char *address)
{
size_t num_colons = 0;
char ch = 0;
for (size_t i = 0; (ch = address[i]); ++i) {
if (ch == '.') {
return false;
}
if (ch == ':') {
++num_colons;
}
}
return num_colons > 1 && num_colons < 8;
}
/* Determine if a node is offline by comparing the age of the nodeslist
* to the last time the node was successfully pinged.

View File

@ -25,10 +25,6 @@
#include <string.h>
#include <time.h>
#include <limits.h>
#include <dirent.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <sys/stat.h>
#include "toxic.h"
@ -59,7 +55,6 @@ void hst_to_net(uint8_t *num, uint16_t numbytes)
}
memcpy(num, buff, numbytes);
free(buff);
#endif
}
@ -146,11 +141,10 @@ int hex_string_to_bytes(char *buf, int size, const char *keystr)
return -1;
}
int i, res;
const char *pos = keystr;
for (i = 0; i < size; ++i) {
res = sscanf(pos, "%2hhx", (unsigned char *)&buf[i]);
for (size_t i = 0; i < size; ++i) {
int res = sscanf(pos, "%2hhx", (unsigned char *)&buf[i]);
pos += 2;
if (res == EOF || res < 1) {
@ -172,9 +166,7 @@ int bin_id_to_string(const char *bin_id, size_t bin_id_size, char *output, size_
return -1;
}
size_t i;
for (i = 0; i < TOX_ADDRESS_SIZE; ++i) {
for (size_t i = 0; i < TOX_ADDRESS_SIZE; ++i) {
snprintf(&output[i * 2], output_size - (i * 2), "%02X", bin_id[i] & 0xff);
}
@ -245,43 +237,59 @@ int qsort_ptr_char_array_helper(const void *str1, const void *str2)
return strcasecmp(*(char **)str1, *(char **)str2);
}
/* Returns 1 if nick is valid, 0 if not. A valid toxic nick:
- cannot be empty
- cannot start with a space
- must not contain a forward slash (for logfile naming purposes)
- must not contain contiguous spaces
- must not contain a newline or tab seqeunce */
int valid_nick(const char *nick)
static const char invalid_chars[] = {'/', '\n', '\t', '\v', '\r', '\0'};
/*
* Helper function for `valid_nick()`.
*
* Returns true if `ch` is not in the `invalid_chars` array.
*/
static bool is_valid_char(char ch)
{
if (!nick[0] || nick[0] == ' ') {
return 0;
}
char tmp;
int i;
for (i = 0; nick[i]; ++i) {
if ((nick[i] == ' ' && nick[i + 1] == ' ')
|| nick[i] == '/'
|| nick[i] == '\n'
|| nick[i] == '\t'
|| nick[i] == '\v'
|| nick[i] == '\r')
{
return 0;
for (size_t i = 0; (tmp = invalid_chars[i]); ++i) {
if (tmp == ch) {
return false;
}
}
return 1;
return true;
}
/* Returns true if nick is valid.
*
* A valid toxic nick:
* - cannot be empty
* - cannot start with a space
* - must not contain a forward slash (for logfile naming purposes)
* - must not contain contiguous spaces
* - must not contain a newline or tab seqeunce
*/
bool valid_nick(const char *nick)
{
if (!nick[0] || nick[0] == ' ') {
return false;
}
for (size_t i = 0; nick[i]; ++i) {
char ch = nick[i];
if ((ch == ' ' && nick[i + 1] == ' ') || !is_valid_char(ch)) {
return false;
}
}
return true;
}
/* Converts all newline/tab chars to spaces (use for strings that should be contained to a single line) */
void filter_str(char *str, size_t len)
{
size_t i;
for (size_t i = 0; i < len; ++i) {
char ch = str[i];
for (i = 0; i < len; ++i) {
if (str[i] == '\n' || str[i] == '\r' || str[i] == '\t' || str[i] == '\v' || str[i] == '\0') {
if (!is_valid_char(ch) || str[i] == '\0') {
str[i] = ' ';
}
}
@ -535,38 +543,6 @@ off_t file_size(const char *path)
return st.st_size;
}
/* Compares the first size bytes of fp to signature.
*
* Returns 0 if they are the same
* Returns 1 if they differ
* Returns -1 on error.
*
* On success this function will seek back to the beginning of fp.
*/
int check_file_signature(const unsigned char *signature, size_t size, FILE *fp)
{
char *buf = malloc(size);
if (buf == NULL) {
return -1;
}
if (fread(buf, size, 1, fp) != 1) {
free(buf);
return -1;
}
int ret = memcmp(signature, buf, size);
free(buf);
if (fseek(fp, 0L, SEEK_SET) == -1) {
return -1;
}
return ret == 0 ? 0 : 1;
}
/* sets window title in tab bar. */
void set_window_title(ToxWindow *self, const char *title, int len)
{
@ -590,39 +566,6 @@ void set_window_title(ToxWindow *self, const char *title, int len)
snprintf(self->name, sizeof(self->name), "%s", cpy);
}
/* Return true if address appears to be a valid ipv4 address. */
bool is_ip4_address(const char *address)
{
struct sockaddr_in s_addr;
return inet_pton(AF_INET, address, &(s_addr.sin_addr)) != 0;
}
/* Return true if address roughly appears to be a valid ipv6 address.
*
* TODO: Improve this function (inet_pton behaves strangely with ipv6).
* for now the only guarantee is that it won't return true if the
* address is a domain or ipv4 address, and should only be used if you're
* reasonably sure that the address is one of the three (ipv4, ipv6 or a domain).
*/
bool is_ip6_address(const char *address)
{
size_t i;
size_t num_colons = 0;
char ch = 0;
for (i = 0; (ch = address[i]); ++i) {
if (ch == '.') {
return false;
}
if (ch == ':') {
++num_colons;
}
}
return num_colons > 1 && num_colons < 8;
}
/*
* Frees all members of a pointer array plus `arr`.
*/

View File

@ -110,13 +110,16 @@ int qsort_strcasecmp_hlpr(const void *str1, const void *str2);
/* case-insensitive string compare function for use with qsort */
int qsort_ptr_char_array_helper(const void *str1, const void *str2);
/* Returns 1 if nick is valid, 0 if not. A valid toxic nick:
- cannot be empty
- cannot start with a space
- must not contain a forward slash (for logfile naming purposes)
- must not contain contiguous spaces
- must not contain a newline or tab seqeunce */
int valid_nick(const char *nick);
/* Returns true if nick is valid.
*
* A valid toxic nick:
* - cannot be empty
* - cannot start with a space
* - must not contain a forward slash (for logfile naming purposes)
* - must not contain contiguous spaces
* - must not contain a newline or tab seqeunce
*/
bool valid_nick(const char *nick);
/* Converts all newline/tab chars to spaces (use for strings that should be contained to a single line) */
void filter_str(char *str, size_t len);
@ -172,32 +175,9 @@ File_Type file_type(const char *path);
/* returns file size. If file doesn't exist returns 0. */
off_t file_size(const char *path);
/* Compares the first size bytes of fp to signature.
*
* Returns 0 if they are the same
* Returns 1 if they differ
* Returns -1 on error.
*
* On success this function will seek back to the beginning of fp.
*/
int check_file_signature(const unsigned char *signature, size_t size, FILE *fp);
/* sets window title in tab bar. */
void set_window_title(ToxWindow *self, const char *title, int len);
/* Return true if address appears to be a valid ipv4 address. */
bool is_ip4_address(const char *address);
/* Return true if address roughly appears to be a valid ipv6 address.
*
* TODO: Improve this function (inet_pton behaves strangely with ipv6).
* for now the only guarantee is that it won't return true if the
* address is a domain or ipv4 address, and should only be used if you're
* reasonably sure that the address is one of the three (ipv4, ipv6 or a domain).
*/
bool is_ip6_address(const char *address);
/*
* Frees all members of a pointer array plus `arr`.
*/

View File

@ -742,7 +742,6 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
if (len == 0) {
fclose(fp);
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
return NULL;
}
char *data = malloc(len);
@ -750,14 +749,12 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
if (data == NULL) {
fclose(fp);
exit_toxic_err("failed in load_tox", FATALERR_MEMORY);
return NULL;
}
if (fread(data, len, 1, fp) != 1) {
fclose(fp);
free(data);
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
return NULL;
}
bool is_encrypted = tox_is_data_encrypted((uint8_t *) data);
@ -767,7 +764,6 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
fclose(fp);
free(data);
exit_toxic_err("failed in load_tox", FATALERR_ENCRYPT);
return NULL;
}
if (arg_opts.unencrypt_data && is_encrypted) {
@ -796,7 +792,6 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
fclose(fp);
free(data);
exit_toxic_err("failed in load_tox", FATALERR_MEMORY);
return NULL;
}
while (true) {
@ -853,7 +848,6 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
free(data);
free(plain);
exit_toxic_err("tox_pass_decrypt() failed", pwerr);
return NULL;
}
}
@ -876,7 +870,6 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
} else { /* Data file does not/should not exist */
if (file_exists(data_path)) {
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
return NULL;
}
tox_options_set_savedata_type(tox_opts, TOX_SAVEDATA_TYPE_NONE);
@ -889,7 +882,6 @@ static Tox *load_tox(char *data_path, struct Tox_Options *tox_opts, Tox_Err_New
if (store_data(m, data_path) == -1) {
exit_toxic_err("failed in load_tox", FATALERR_FILEOP);
return NULL;
}
}