From 4b73f3d7f92e3af6e7ebf3a9551477820024d9d3 Mon Sep 17 00:00:00 2001 From: James Booth Date: Sun, 25 Nov 2012 21:40:49 +0000 Subject: [PATCH] Profanity files now use %XDG_CONFIG_HOME and %XDG_DATA_HOME --- Makefile.am | 3 +- src/chat_log.c | 9 ++- src/files.c | 155 ++++++++++++++++++++++++++++++++++++++++++++++ src/files.h | 35 +++++++++++ src/log.c | 34 ++++------ src/preferences.c | 15 +++-- src/profanity.c | 16 ++--- src/theme.c | 13 ++-- src/xdg_base.c | 62 +++++++++++++++++++ src/xdg_base.h | 31 ++++++++++ 10 files changed, 322 insertions(+), 51 deletions(-) create mode 100644 src/files.c create mode 100644 src/files.h create mode 100644 src/xdg_base.c create mode 100644 src/xdg_base.h diff --git a/Makefile.am b/Makefile.am index 181ffcb2..f3701677 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,7 +9,8 @@ profanity_SOURCES = src/command.c src/contact.c src/history.c src/jabber.h \ src/chat_log.h src/tinyurl.c src/tinyurl.h src/chat_session.c \ src/chat_session.h src/release.c src/release.h src/room_chat.c \ src/room_chat.h src/stanza.c src/stanza.h src/parser.c src/parser.h \ - src/theme.c src/theme.h src/window.c src/window.h + src/theme.c src/theme.h src/window.c src/window.h src/xdg_base.c \ + src/xdg_base.h src/files.c src/files.h TESTS = tests/testsuite check_PROGRAMS = tests/testsuite diff --git a/src/chat_log.c b/src/chat_log.c index e1aa6865..4d7f50b6 100644 --- a/src/chat_log.c +++ b/src/chat_log.c @@ -29,6 +29,7 @@ #include "chat_log.h" #include "common.h" +#include "files.h" #include "log.h" #include "ui.h" @@ -223,11 +224,9 @@ static char * _get_log_filename(const char * const other, const char * const login, GDateTime *dt, gboolean create) { - GString *log_file = g_string_new(getenv("HOME")); - g_string_append(log_file, "/.profanity/log"); - if (create) { - create_dir(log_file->str); - } + gchar *chatlogs_dir = files_get_chatlog_dir(); + GString *log_file = g_string_new(chatlogs_dir); + g_free(chatlogs_dir); gchar *login_dir = str_replace(login, "@", "_at_"); g_string_append_printf(log_file, "/%s", login_dir); diff --git a/src/files.c b/src/files.c new file mode 100644 index 00000000..ef60cbfb --- /dev/null +++ b/src/files.c @@ -0,0 +1,155 @@ +/* + * files.c + * + * Copyright (C) 2012 James Booth + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see . + * + */ + +#include +#include +#include +#include + +#include "xdg_base.h" + +#include + +static void _create_dir(char *name); +static void _mkdir_recursive(const char *dir); + +void +files_create_config_directory(void) +{ + gchar *xdg_config = xdg_get_config_home(); + GString *prof_conf_dir = g_string_new(xdg_config); + g_string_append(prof_conf_dir, "/profanity"); + _mkdir_recursive(prof_conf_dir->str); + g_free(xdg_config); + g_string_free(prof_conf_dir, TRUE); +} + +void +files_create_data_directory(void) +{ + gchar *xdg_data = xdg_get_data_home(); + GString *prof_data_dir = g_string_new(xdg_data); + g_string_append(prof_data_dir, "/profanity"); + _mkdir_recursive(prof_data_dir->str); + g_free(xdg_data); + g_string_free(prof_data_dir, TRUE); +} + +void +files_create_chatlog_directory(void) +{ + gchar *xdg_data = xdg_get_data_home(); + GString *chatlogs_dir = g_string_new(xdg_data); + g_string_append(chatlogs_dir, "/profanity/chatlogs"); + _mkdir_recursive(chatlogs_dir->str); + g_free(xdg_data); + g_string_free(chatlogs_dir, TRUE); +} + +void +files_create_themes_directory(void) +{ + gchar *xdg_config = xdg_get_config_home(); + GString *themes_dir = g_string_new(xdg_config); + g_string_append(themes_dir, "/profanity/themes"); + _mkdir_recursive(themes_dir->str); + g_free(xdg_config); + g_string_free(themes_dir, TRUE); +} + +gchar * +files_get_chatlog_dir(void) +{ + gchar *xdg_data = xdg_get_data_home(); + GString *chatlogs_dir = g_string_new(xdg_data); + g_string_append(chatlogs_dir, "/profanity/chatlogs"); + gchar *result = strdup(chatlogs_dir->str); + g_free(xdg_data); + g_string_free(chatlogs_dir, TRUE); + + return result; +} + +gchar * +files_get_preferences_file(void) +{ + gchar *xdg_config = xdg_get_config_home(); + GString *prefs_file = g_string_new(xdg_config); + g_string_append(prefs_file, "/profanity/profrc"); + gchar *result = strdup(prefs_file->str); + g_free(xdg_config); + g_string_free(prefs_file, TRUE); + + return result; +} + +gchar * +files_get_log_file(void) +{ + gchar *xdg_data = xdg_get_data_home(); + GString *logfile = g_string_new(xdg_data); + g_string_append(logfile, "/profanity/profanity.log"); + gchar *result = strdup(logfile->str); + g_free(xdg_data); + g_string_free(logfile, TRUE); + + return result; +} + +gchar * +files_get_themes_dir(void) +{ + gchar *xdg_config = xdg_get_config_home(); + GString *themes_dir = g_string_new(xdg_config); + g_string_append(themes_dir, "/profanity/themes"); + gchar *result = strdup(themes_dir->str); + g_free(xdg_config); + g_string_free(themes_dir, TRUE); + + return result; +} + +static void +_create_dir(char *name) +{ + int e; + struct stat sb; + + e = stat(name, &sb); + if (e != 0) + if (errno == ENOENT) + e = mkdir(name, S_IRWXU); +} + +static void +_mkdir_recursive(const char *dir) +{ + int i; + for (i = 1; i <= strlen(dir); i++) { + if (dir[i] == '/' || dir[i] == '\0') { + gchar *next_dir = g_strndup(dir, i); + _create_dir(next_dir); + g_free(next_dir); + } + } +} + diff --git a/src/files.h b/src/files.h new file mode 100644 index 00000000..694ec0e1 --- /dev/null +++ b/src/files.h @@ -0,0 +1,35 @@ +/* + * files.h + * + * Copyright (C) 2012 James Booth + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see . + * + */ + +#ifndef FILES_H +#define FILES_H + +void files_create_config_directory(void); +void files_create_data_directory(void); +void files_create_chatlog_directory(void); +void files_create_themes_directory(void); +gchar* files_get_chatlog_dir(void); +gchar* files_get_preferences_file(void); +gchar* files_get_log_file(void); +gchar* files_get_themes_dir(void); + +#endif diff --git a/src/log.c b/src/log.c index e1cbddb7..63149143 100644 --- a/src/log.c +++ b/src/log.c @@ -29,6 +29,7 @@ #include "glib.h" #include "common.h" +#include "files.h" #include "log.h" #include "preferences.h" @@ -45,7 +46,6 @@ static GTimeZone *tz; static GDateTime *dt; static log_level_t level_filter; -static GString *_get_log_file(void); static void _rotate_log_file(void); void @@ -101,9 +101,9 @@ log_init(log_level_t filter) { level_filter = filter; tz = g_time_zone_new_local(); - GString *log_file = _get_log_file(); - logp = fopen(log_file->str, "a"); - g_string_free(log_file, TRUE); + gchar *log_file = files_get_log_file(); + logp = fopen(log_file, "a"); + g_free(log_file); } log_level_t @@ -125,7 +125,7 @@ log_msg(log_level_t level, const char * const area, const char * const msg) if (level >= level_filter) { struct stat st; int result; - GString *log_file = _get_log_file(); + gchar *log_file = files_get_log_file(); dt = g_date_time_new_now(tz); gchar *date_fmt = g_date_time_format(dt, "%d/%m/%Y %H:%M:%S"); @@ -135,42 +135,32 @@ log_msg(log_level_t level, const char * const area, const char * const msg) fflush(logp); g_free(date_fmt); - result = stat(log_file->str, &st); + result = stat(log_file, &st); if (result == 0 && st.st_size >= prefs_get_max_log_size()) { _rotate_log_file(); } - g_string_free(log_file, TRUE); + g_free(log_file); } } -static GString * -_get_log_file(void) -{ - GString *log_file = g_string_new(getenv("HOME")); - g_string_append(log_file, "/.profanity/log"); - create_dir(log_file->str); - g_string_append(log_file, "/profanity.log"); - - return log_file; -} static void _rotate_log_file(void) { - GString *log_file = _get_log_file(); - size_t len = strlen(log_file->str); + gchar *log_file = files_get_log_file(); + size_t len = strlen(log_file); char *log_file_new = malloc(len + 3); - strncpy(log_file_new, log_file->str, len); + strncpy(log_file_new, log_file, len); log_file_new[len] = '.'; log_file_new[len+1] = '1'; log_file_new[len+2] = 0; log_close(); - rename(log_file->str, log_file_new); + rename(log_file, log_file_new); log_init(log_get_filter()); free(log_file_new); - g_string_free(log_file, TRUE); + g_free(log_file); log_info("Log has been rotated"); } diff --git a/src/preferences.c b/src/preferences.c index b2db3123..5fbce0ef 100644 --- a/src/preferences.c +++ b/src/preferences.c @@ -20,9 +20,6 @@ * */ -#include "config.h" -#include "preferences.h" - #include #include @@ -34,10 +31,13 @@ #include #endif +#include "config.h" +#include "files.h" #include "log.h" +#include "preferences.h" #include "prof_autocomplete.h" -static GString *prefs_loc; +static gchar *prefs_loc; static GKeyFile *prefs; gint log_maxsize = 0; @@ -53,11 +53,10 @@ prefs_load(void) log_info("Loading preferences"); login_ac = p_autocomplete_new(); - prefs_loc = g_string_new(getenv("HOME")); - g_string_append(prefs_loc, "/.profanity/config"); + prefs_loc = files_get_preferences_file(); prefs = g_key_file_new(); - g_key_file_load_from_file(prefs, prefs_loc->str, G_KEY_FILE_KEEP_COMMENTS, + g_key_file_load_from_file(prefs, prefs_loc, G_KEY_FILE_KEEP_COMMENTS, NULL); // create the logins searchable list for autocompletion @@ -378,5 +377,5 @@ _save_prefs(void) { gsize g_data_size; char *g_prefs_data = g_key_file_to_data(prefs, &g_data_size, NULL); - g_file_set_contents(prefs_loc->str, g_prefs_data, g_data_size, NULL); + g_file_set_contents(prefs_loc, g_prefs_data, g_data_size, NULL); } diff --git a/src/profanity.c b/src/profanity.c index e98443eb..8af64643 100644 --- a/src/profanity.c +++ b/src/profanity.c @@ -34,6 +34,7 @@ #include "common.h" #include "contact.h" #include "contact_list.h" +#include "files.h" #include "history.h" #include "log.h" #include "preferences.h" @@ -45,7 +46,6 @@ static log_level_t _get_log_level(char *log_level); static gboolean _process_input(char *inp); -static void _create_config_directory(); static void _init(const int disable_tls, char *log_level); static void _shutdown(void); @@ -374,15 +374,6 @@ prof_handle_activity(void) } } -static void -_create_config_directory(void) -{ - GString *dir = g_string_new(getenv("HOME")); - g_string_append(dir, "/.profanity"); - create_dir(dir->str); - g_string_free(dir, TRUE); -} - static log_level_t _get_log_level(char *log_level) { @@ -441,7 +432,10 @@ _init(const int disable_tls, char *log_level) { // ignore SIGPIPE signal(SIGPIPE, SIG_IGN); - _create_config_directory(); + files_create_config_directory(); + files_create_data_directory(); + files_create_chatlog_directory(); + files_create_themes_directory(); log_level_t prof_log_level = _get_log_level(log_level); log_init(prof_log_level); log_info("Starting Profanity (%s)...", PACKAGE_VERSION); diff --git a/src/theme.c b/src/theme.c index aafbd859..6274b647 100644 --- a/src/theme.c +++ b/src/theme.c @@ -33,6 +33,7 @@ #include #endif +#include "files.h" #include "log.h" #include "theme.h" @@ -99,8 +100,10 @@ theme_load(const char * const theme_name) theme = g_key_file_new(); if (theme_name != NULL) { - theme_loc = g_string_new(getenv("HOME")); - g_string_append(theme_loc, "/.profanity/themes/"); + gchar *themes_dir = files_get_themes_dir(); + theme_loc = g_string_new(themes_dir); + g_free(themes_dir); + g_string_append(theme_loc, "/"); g_string_append(theme_loc, theme_name); g_key_file_load_from_file(theme, theme_loc->str, G_KEY_FILE_KEEP_COMMENTS, NULL); @@ -119,8 +122,10 @@ theme_change(const char * const theme_name) _load_colours(); return TRUE; } else { - GString *new_theme_file = g_string_new(getenv("HOME")); - g_string_append(new_theme_file, "/.profanity/themes/"); + gchar *themes_dir = files_get_themes_dir(); + GString *new_theme_file = g_string_new(themes_dir); + g_free(themes_dir); + g_string_append(new_theme_file, "/"); g_string_append(new_theme_file, theme_name); // no theme file found diff --git a/src/xdg_base.c b/src/xdg_base.c new file mode 100644 index 00000000..7b8cf28f --- /dev/null +++ b/src/xdg_base.c @@ -0,0 +1,62 @@ +/* + * xdg_base.c + * + * Copyright (C) 2012 James Booth + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see . + * + */ + +#include +#include + +#include + +gchar * +xdg_get_config_home(void) +{ + gchar *xdg_config_home = getenv("XDG_CONFIG_HOME"); + g_strstrip(xdg_config_home); + + if ((xdg_config_home != NULL) && (strcmp(xdg_config_home, "") != 0)) { + return strdup(xdg_config_home); + } else { + GString *default_path = g_string_new(getenv("HOME")); + g_string_append(default_path, "/.config"); + gchar *result = strdup(default_path->str); + g_string_free(default_path, TRUE); + + return result; + } +} + +gchar * +xdg_get_data_home(void) +{ + gchar *xdg_data_home = getenv("XDG_DATA_HOME"); + g_strstrip(xdg_data_home); + + if ((xdg_data_home != NULL) && (strcmp(xdg_data_home, "") != 0)) { + return strdup(xdg_data_home); + } else { + GString *default_path = g_string_new(getenv("HOME")); + g_string_append(default_path, "/.local/share"); + gchar *result = strdup(default_path->str); + g_string_free(default_path, TRUE); + + return result; + } +} diff --git a/src/xdg_base.h b/src/xdg_base.h new file mode 100644 index 00000000..80c8f409 --- /dev/null +++ b/src/xdg_base.h @@ -0,0 +1,31 @@ +/* + * xdg_base.h + * + * Copyright (C) 2012 James Booth + * + * This file is part of Profanity. + * + * Profanity 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. + * + * Profanity 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 Profanity. If not, see . + * + */ + +#ifndef XDG_BASE_H +#define XDG_BASE_H + +#include + +gchar* xdg_get_config_home(void); +gchar* xdg_get_data_home(void); + +#endif