From d7e2cca854cbc3d0f2418fd95f7033d6b352b587 Mon Sep 17 00:00:00 2001 From: Simon Levermann Date: Thu, 8 Aug 2013 10:15:07 +0200 Subject: [PATCH 1/3] Attempt to get and create a proper directory for config storage. --- testing/toxic/configdir.c | 91 +++++++++++++++++++++++++++++++++++++++ testing/toxic/configdir.h | 27 ++++++++++++ testing/toxic/main.c | 20 ++++++++- 3 files changed, 137 insertions(+), 1 deletion(-) create mode 100644 testing/toxic/configdir.c create mode 100644 testing/toxic/configdir.h diff --git a/testing/toxic/configdir.c b/testing/toxic/configdir.c new file mode 100644 index 00000000..c9f7de85 --- /dev/null +++ b/testing/toxic/configdir.c @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2013 Tox project All Rights Reserved. + * + * This file is part of Tox. + * + * Tox 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. + * + * Tox 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 Tox. If not, see . + * + */ + +#include +#include +#include + +#ifdef _win32 +#include +#endif + +#ifdef __APPLE__ +#include +#include +#include +#endif + +char *get_user_config_dir(void) +{ + char *user_config_dir; + + #ifdef _win32 + + char appdata[MAX_PATH]; + HRESULT result = SHGetFolderPath( + NULL, + CSIDL_APPDATA, // TODO: Maybe use CSIDL_LOCAL_APPDATA instead? Not sure. + NULL, + SHGFP_TYPE_CURRENT, + appdata + ) + if (!result) return NULL; + + user_config_dir = malloc(strlen(appdata) + strlen(CONFIGDIR) + 1); + if (user_config_dir) { + strcpy(user_config_dir, appdata); + strcat(user_config_dir, CONFIGDIR); + } + return user_config_dir; + + #elif defined __APPLE__ + + struct passwd *pass = getpwuid(getuid()); + if (!pass) return NULL; + char *home = pass->pw_dir; + user_config_dir = malloc(strlen(home) + strlen("/Library/Application Support") + strlen(CONFIGDIR) + 1); + + if(user_config_dir) { + strcpy(user_config_dir, home); + strcat(user_config_dir, "/Library/Application Support"); + strcat(user_config_dir, CONFIGDIR); + } + return user_config_dir; + + #else + + if (getenv("XDG_CONFIG_HOME")) { + user_config_dir = malloc(strlen(getenv("XDG_CONFIG_HOME")) + strlen(CONFIGDIR) + 1); + if (user_config_dir) { + strcpy(user_config_dir, getenv("XDG_CONFIG_HOME")); + strcat(user_config_dir, CONFIGDIR); + } + } else { + user_config_dir = malloc(strlen(getenv("HOME")) + strlen("/.config") + strlen(CONFIGDIR) + 1); + if (user_config_dir) { + strcpy(user_config_dir, getenv("HOME")); + strcat(user_config_dir, "/.config"); + strcat(user_config_dir, CONFIGDIR); + } + } + return user_config_dir; + + #endif +} \ No newline at end of file diff --git a/testing/toxic/configdir.h b/testing/toxic/configdir.h new file mode 100644 index 00000000..441ffdab --- /dev/null +++ b/testing/toxic/configdir.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 Tox project All Rights Reserved. + * + * This file is part of Tox. + * + * Tox 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. + * + * Tox 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 Tox. If not, see . + * + */ + +#ifdef _win32 +#define CONFIGDIR "\\toxic\\" +#else +#define CONFIGDIR "/toxic/" +#endif + +char *get_user_config_dir(void); \ No newline at end of file diff --git a/testing/toxic/main.c b/testing/toxic/main.c index b2310c80..ec439c84 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -11,6 +11,7 @@ #include "../../core/Messenger.h" #include "../../core/network.h" +#include "configdir.h" #include "windows.h" extern ToxWindow new_prompt(); @@ -331,7 +332,24 @@ int main(int argc, char *argv[]) { int ch; int f_flag = 0; - char *filename = "data"; + char *configdir = get_user_config_dir(); + char *default_file = "data"; + int mkdir_err + #ifdef _win32 + mkdir_err = _mkdir(configdir); + #else + mkdir_err = mkdir(configdir, 0700); + #endif + + char *filename; + if(mkdir_err == -1) { + filename = default_file; + } else { + filename = malloc(strlen(configdir) + strlen(default_file) + 1); + strcpy(filename, configdir); + strcat(filename, default_file); + } + ToxWindow* a; int i = 0; From 97e178db3aa9485ab49c646071305164cb5a7681 Mon Sep 17 00:00:00 2001 From: Simon Levermann Date: Thu, 8 Aug 2013 16:00:12 +0200 Subject: [PATCH 2/3] Implement proper config directories. --- testing/toxic/CMakeLists.txt | 3 +- testing/toxic/configdir.c | 151 ++++++++++++++++++++++++----------- testing/toxic/configdir.h | 8 +- testing/toxic/main.c | 38 +++++---- 4 files changed, 135 insertions(+), 65 deletions(-) diff --git a/testing/toxic/CMakeLists.txt b/testing/toxic/CMakeLists.txt index f30d8e9e..bfcf04bf 100644 --- a/testing/toxic/CMakeLists.txt +++ b/testing/toxic/CMakeLists.txt @@ -7,7 +7,8 @@ add_executable(${exe_name} main.c prompt.c friendlist.c - chat.c) + chat.c + configdir.c) target_link_libraries(${exe_name} curses) diff --git a/testing/toxic/configdir.c b/testing/toxic/configdir.c index c9f7de85..7d11d020 100644 --- a/testing/toxic/configdir.c +++ b/testing/toxic/configdir.c @@ -21,71 +21,126 @@ #include #include #include +#include +#include +#include -#ifdef _win32 +#ifdef WIN32 #include +#include #endif #ifdef __APPLE__ -#include #include #include #endif +#include "configdir.h" + +/* + * Retrieves a correct configuration directory, depending on the OS used, with a trailing slash + */ char *get_user_config_dir(void) { - char *user_config_dir; + char *user_config_dir; - #ifdef _win32 + #ifdef WIN32 - char appdata[MAX_PATH]; - HRESULT result = SHGetFolderPath( - NULL, - CSIDL_APPDATA, // TODO: Maybe use CSIDL_LOCAL_APPDATA instead? Not sure. - NULL, - SHGFP_TYPE_CURRENT, - appdata - ) - if (!result) return NULL; + char appdata[MAX_PATH]; + HRESULT result = SHGetFolderPath( + NULL, + CSIDL_APPDATA, + NULL, + SHGFP_TYPE_CURRENT, + appdata + ) + if (!result) return NULL; - user_config_dir = malloc(strlen(appdata) + strlen(CONFIGDIR) + 1); - if (user_config_dir) { - strcpy(user_config_dir, appdata); - strcat(user_config_dir, CONFIGDIR); - } - return user_config_dir; + user_config_dir = malloc(strlen(appdata) + 1); + if (user_config_dir) { + strcpy(user_config_dir, appdata); + } + return user_config_dir; - #elif defined __APPLE__ + #elif defined __APPLE__ - struct passwd *pass = getpwuid(getuid()); - if (!pass) return NULL; - char *home = pass->pw_dir; - user_config_dir = malloc(strlen(home) + strlen("/Library/Application Support") + strlen(CONFIGDIR) + 1); - - if(user_config_dir) { - strcpy(user_config_dir, home); - strcat(user_config_dir, "/Library/Application Support"); - strcat(user_config_dir, CONFIGDIR); - } - return user_config_dir; + struct passwd *pass = getpwuid(getuid()); + if (!pass) return NULL; + char *home = pass->pw_dir; + user_config_dir = malloc(strlen(home) + strlen("/Library/Application Support") + 1); + + if(user_config_dir) { + strcpy(user_config_dir, home); + strcat(user_config_dir, "/Library/Application Support"); + } + return user_config_dir; - #else + #else - if (getenv("XDG_CONFIG_HOME")) { - user_config_dir = malloc(strlen(getenv("XDG_CONFIG_HOME")) + strlen(CONFIGDIR) + 1); - if (user_config_dir) { - strcpy(user_config_dir, getenv("XDG_CONFIG_HOME")); - strcat(user_config_dir, CONFIGDIR); - } - } else { - user_config_dir = malloc(strlen(getenv("HOME")) + strlen("/.config") + strlen(CONFIGDIR) + 1); - if (user_config_dir) { - strcpy(user_config_dir, getenv("HOME")); - strcat(user_config_dir, "/.config"); - strcat(user_config_dir, CONFIGDIR); - } - } - return user_config_dir; + if (getenv("XDG_CONFIG_HOME")) { + user_config_dir = malloc(strlen(getenv("XDG_CONFIG_HOME")) + 1); + if (user_config_dir) { + strcpy(user_config_dir, getenv("XDG_CONFIG_HOME")); + } + } else { + user_config_dir = malloc(strlen(getenv("HOME")) + strlen("/.config") + 1); + if (user_config_dir) { + strcpy(user_config_dir, getenv("HOME")); + strcat(user_config_dir, "/.config"); + } + } + return user_config_dir; - #endif + #endif +} + +/* + * Creates the config directory. + */ +int create_user_config_dir(char *path) +{ + + int mkdir_err; + + #ifdef WIN32 + + char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1); + strcpy(fullpath, path); + strcat(fullpath, CONFIGDIR); + + mkdir_err = _mkdir(fullpath); + + if (mkdir_err) { + if(errno != EEXIST) return -1; + struct _stat buf; + if(_wstat64(fullpath, &buf)) return -1; + if(!S_ISDIR(buf.st_mode)) return -1; + } + + #else + + mkdir_err = mkdir(path, 0700); + struct stat buf; + + if(mkdir_err) { + if(errno != EEXIST) return -1; + if(stat(path, &buf)) return -1; + if(!S_ISDIR(buf.st_mode)) return -1; + } + + char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1); + strcpy(fullpath, path); + strcat(fullpath, CONFIGDIR); + + mkdir_err = mkdir(fullpath, 0700); + + if(mkdir_err) { + if(errno != EEXIST) return -1; + if(stat(fullpath, &buf)) return -1; + if(!S_ISDIR(buf.st_mode)) return -1; + } + + #endif + + return 0; } \ No newline at end of file diff --git a/testing/toxic/configdir.h b/testing/toxic/configdir.h index 441ffdab..d9837d77 100644 --- a/testing/toxic/configdir.h +++ b/testing/toxic/configdir.h @@ -23,5 +23,11 @@ #else #define CONFIGDIR "/toxic/" #endif + +#ifndef S_ISDIR +#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) +#endif -char *get_user_config_dir(void); \ No newline at end of file +char *get_user_config_dir(void); + +int create_user_config_dir(char *path); \ No newline at end of file diff --git a/testing/toxic/main.c b/testing/toxic/main.c index ec439c84..cb0d9e19 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -3,11 +3,19 @@ */ #include +#include #include #include #include #include +#ifdef _win32 +#include +#else +#include +#include +#endif + #include "../../core/Messenger.h" #include "../../core/network.h" @@ -332,26 +340,19 @@ int main(int argc, char *argv[]) { int ch; int f_flag = 0; - char *configdir = get_user_config_dir(); - char *default_file = "data"; - int mkdir_err - #ifdef _win32 - mkdir_err = _mkdir(configdir); - #else - mkdir_err = mkdir(configdir, 0700); - #endif - + char *user_config_dir = get_user_config_dir(); char *filename; - if(mkdir_err == -1) { - filename = default_file; + int config_err = create_user_config_dir(user_config_dir); + if(config_err) { + filename = "data"; } else { - filename = malloc(strlen(configdir) + strlen(default_file) + 1); - strcpy(filename, configdir); - strcat(filename, default_file); + filename = malloc(strlen(user_config_dir) + strlen(CONFIGDIR) + strlen("data") + 1); + strcpy(filename, user_config_dir); + strcat(filename, CONFIGDIR); + strcat(filename, "data"); } ToxWindow* a; - int i = 0; for (i = 0; i < argc; ++i) { if (argv[i] == NULL) @@ -378,6 +379,13 @@ int main(int argc, char *argv[]) "defaulting to 'data' for a keyfile...\n"); attroff(COLOR_PAIR(3) | A_BOLD); } + + if(config_err) { + attron(COLOR_PAIR(3) | A_BOLD); + wprintw(prompt->window, "Unable to determine configuration directory!\n" + "defaulting to 'data' for a keyfile...\n"); + attroff(COLOR_PAIR(3) | A_BOLD); + } while(true) { /* Update tox */ From b5f5b1a111d9e08b2b001b5d4d76629019462f39 Mon Sep 17 00:00:00 2001 From: Simon Levermann Date: Thu, 8 Aug 2013 16:36:16 +0200 Subject: [PATCH 3/3] Cleanup and Error fixes Add several frees that were missing to prevent memory leaks Replace strcpy with strdup where appropriate Replace _stat with __stat64 for building on Windows --- testing/toxic/configdir.c | 36 +++++++++++++----------------------- testing/toxic/configdir.h | 2 +- testing/toxic/main.c | 1 + 3 files changed, 15 insertions(+), 24 deletions(-) diff --git a/testing/toxic/configdir.c b/testing/toxic/configdir.c index 7d11d020..d91d0804 100644 --- a/testing/toxic/configdir.c +++ b/testing/toxic/configdir.c @@ -56,10 +56,8 @@ char *get_user_config_dir(void) ) if (!result) return NULL; - user_config_dir = malloc(strlen(appdata) + 1); - if (user_config_dir) { - strcpy(user_config_dir, appdata); - } + user_config_dir = strdup(appdata); + return user_config_dir; #elif defined __APPLE__ @@ -78,10 +76,7 @@ char *get_user_config_dir(void) #else if (getenv("XDG_CONFIG_HOME")) { - user_config_dir = malloc(strlen(getenv("XDG_CONFIG_HOME")) + 1); - if (user_config_dir) { - strcpy(user_config_dir, getenv("XDG_CONFIG_HOME")); - } + user_config_dir = strdup(getenv("XDG_CONFIG_HOME")); } else { user_config_dir = malloc(strlen(getenv("HOME")) + strlen("/.config") + 1); if (user_config_dir) { @@ -109,12 +104,10 @@ int create_user_config_dir(char *path) strcat(fullpath, CONFIGDIR); mkdir_err = _mkdir(fullpath); - - if (mkdir_err) { - if(errno != EEXIST) return -1; - struct _stat buf; - if(_wstat64(fullpath, &buf)) return -1; - if(!S_ISDIR(buf.st_mode)) return -1; + struct __stat64 buf; + if (mkdir_err && (errno != EEXIST || _wstat64(fullpath, &buf) || !S_ISDIR(buf.st_mode))) { + free(fullpath); + return -1; } #else @@ -122,10 +115,8 @@ int create_user_config_dir(char *path) mkdir_err = mkdir(path, 0700); struct stat buf; - if(mkdir_err) { - if(errno != EEXIST) return -1; - if(stat(path, &buf)) return -1; - if(!S_ISDIR(buf.st_mode)) return -1; + if(mkdir_err && (errno != EEXIST || stat(path, &buf) || !S_ISDIR(buf.st_mode))) { + return -1; } char *fullpath = malloc(strlen(path) + strlen(CONFIGDIR) + 1); @@ -134,13 +125,12 @@ int create_user_config_dir(char *path) mkdir_err = mkdir(fullpath, 0700); - if(mkdir_err) { - if(errno != EEXIST) return -1; - if(stat(fullpath, &buf)) return -1; - if(!S_ISDIR(buf.st_mode)) return -1; + if(mkdir_err && (errno != EEXIST || stat(fullpath, &buf) || !S_ISDIR(buf.st_mode))) { + free(fullpath); + return -1; } #endif return 0; -} \ No newline at end of file +} diff --git a/testing/toxic/configdir.h b/testing/toxic/configdir.h index d9837d77..fad949cf 100644 --- a/testing/toxic/configdir.h +++ b/testing/toxic/configdir.h @@ -30,4 +30,4 @@ char *get_user_config_dir(void); -int create_user_config_dir(char *path); \ No newline at end of file +int create_user_config_dir(char *path); diff --git a/testing/toxic/main.c b/testing/toxic/main.c index cb0d9e19..13577cc7 100644 --- a/testing/toxic/main.c +++ b/testing/toxic/main.c @@ -370,6 +370,7 @@ int main(int argc, char *argv[]) init_term(); init_tox(); load_data(filename); + free(filename); init_windows(); init_window_status();