about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Makefile.am3
-rw-r--r--src/chat_log.c9
-rw-r--r--src/files.c155
-rw-r--r--src/files.h35
-rw-r--r--src/log.c34
-rw-r--r--src/preferences.c15
-rw-r--r--src/profanity.c16
-rw-r--r--src/theme.c13
-rw-r--r--src/xdg_base.c62
-rw-r--r--src/xdg_base.h31
10 files changed, 322 insertions, 51 deletions
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 <boothj5@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <errno.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#include "xdg_base.h"
+
+#include <glib.h>
+
+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 <boothj5@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#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 <stdlib.h>
 #include <string.h>
 
@@ -34,10 +31,13 @@
 #include <ncurses/ncurses.h>
 #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 <ncurses/ncurses.h>
 #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 <boothj5@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+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 <boothj5@gmail.com>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ *
+ */
+
+#ifndef XDG_BASE_H
+#define XDG_BASE_H
+
+#include <glib.h>
+
+gchar* xdg_get_config_home(void);
+gchar* xdg_get_data_home(void);
+
+#endif