1 /*
2  * files.c
3  * vim: expandtab:ts=4:sts=4:sw=4
4  *
5  * Copyright (C) 2012 - 2019 James Booth <boothj5@gmail.com>
6  * Copyright (C) 2020 Michael Vetter <jubalh@idoru.org>
7  *
8  * This file is part of Profanity.
9  *
10  * Profanity is free software: you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation, either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * Profanity is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with Profanity.  If not, see <https://www.gnu.org/licenses/>.
22  *
23  * In addition, as a special exception, the copyright holders give permission to
24  * link the code of portions of this program with the OpenSSL library under
25  * certain conditions as described in each individual source file, and
26  * distribute linked combinations including the two.
27  *
28  * You must obey the GNU General Public License in all respects for all of the
29  * code used other than OpenSSL. If you modify file(s) with this exception, you
30  * may extend this exception to your version of the file(s), but you are not
31  * obligated to do so. If you do not wish to do so, delete this exception
32  * statement from your version. If you delete this exception statement from all
33  * source files in the program, then also delete it here.
34  *
35  */
36 #include "config.h"
37 
38 #include <stdlib.h>
39 #include <string.h>
40 #include <unistd.h>
41 #include <glib.h>
42 
43 #include "common.h"
44 #include "log.h"
45 #include "config/files.h"
46 #include "config/preferences.h"
47 
48 static char* _files_get_xdg_config_home(void);
49 static char* _files_get_xdg_data_home(void);
50 
51 void
files_create_directories(void)52 files_create_directories(void)
53 {
54     gchar* xdg_config = _files_get_xdg_config_home();
55     gchar* xdg_data = _files_get_xdg_data_home();
56 
57     GString* themes_dir = g_string_new(xdg_config);
58     g_string_append(themes_dir, "/profanity/themes");
59     GString* icons_dir = g_string_new(xdg_config);
60     g_string_append(icons_dir, "/profanity/icons");
61     GString* chatlogs_dir = g_string_new(xdg_data);
62     g_string_append(chatlogs_dir, "/profanity/chatlogs");
63     GString* logs_dir = g_string_new(xdg_data);
64     g_string_append(logs_dir, "/profanity/logs");
65     GString* plugins_dir = g_string_new(xdg_data);
66     g_string_append(plugins_dir, "/profanity/plugins");
67 
68     if (!mkdir_recursive(themes_dir->str)) {
69         log_error("Error while creating directory %s", themes_dir->str);
70     }
71     if (!mkdir_recursive(icons_dir->str)) {
72         log_error("Error while creating directory %s", icons_dir->str);
73     }
74     if (!mkdir_recursive(chatlogs_dir->str)) {
75         log_error("Error while creating directory %s", chatlogs_dir->str);
76     }
77     if (!mkdir_recursive(logs_dir->str)) {
78         log_error("Error while creating directory %s", logs_dir->str);
79     }
80     if (!mkdir_recursive(plugins_dir->str)) {
81         log_error("Error while creating directory %s", plugins_dir->str);
82     }
83 
84     g_string_free(themes_dir, TRUE);
85     g_string_free(icons_dir, TRUE);
86     g_string_free(chatlogs_dir, TRUE);
87     g_string_free(logs_dir, TRUE);
88     g_string_free(plugins_dir, TRUE);
89 
90     g_free(xdg_config);
91     g_free(xdg_data);
92 }
93 
94 gchar*
files_get_inputrc_file(void)95 files_get_inputrc_file(void)
96 {
97     gchar* xdg_config = _files_get_xdg_config_home();
98     GString* inputrc_file = g_string_new(xdg_config);
99     g_free(xdg_config);
100 
101     g_string_append(inputrc_file, "/profanity/inputrc");
102 
103     if (g_file_test(inputrc_file->str, G_FILE_TEST_IS_REGULAR)) {
104         gchar* result = g_strdup(inputrc_file->str);
105         g_string_free(inputrc_file, TRUE);
106 
107         return result;
108     }
109 
110     g_string_free(inputrc_file, TRUE);
111 
112     return NULL;
113 }
114 
115 char*
files_get_log_file(const char * const log_file)116 files_get_log_file(const char* const log_file)
117 {
118     gchar* xdg_data = _files_get_xdg_data_home();
119     GString* logfile;
120 
121     if (log_file) {
122         gchar *log_path = g_path_get_dirname(log_file);
123         if (!mkdir_recursive(log_path)) {
124             log_error("Error while creating directory %s", log_path);
125         }
126         g_free(log_path);
127 
128         logfile = g_string_new(log_file);
129     } else {
130         logfile = g_string_new(xdg_data);
131         g_string_append(logfile, "/profanity/logs/profanity");
132 
133         if (!prefs_get_boolean(PREF_LOG_SHARED)) {
134             g_string_append_printf(logfile, "%d", getpid());
135         }
136 
137         g_string_append(logfile, ".log");
138     }
139 
140     char* result = g_strdup(logfile->str);
141 
142     free(xdg_data);
143     g_string_free(logfile, TRUE);
144 
145     return result;
146 }
147 
148 gchar*
files_get_config_path(const char * const config_base)149 files_get_config_path(const char* const config_base)
150 {
151     gchar* xdg_config = _files_get_xdg_config_home();
152     GString* file_str = g_string_new(xdg_config);
153     g_string_append(file_str, "/profanity/");
154     g_string_append(file_str, config_base);
155     gchar* result = g_strdup(file_str->str);
156     g_free(xdg_config);
157     g_string_free(file_str, TRUE);
158 
159     return result;
160 }
161 
162 gchar*
files_get_data_path(const char * const data_base)163 files_get_data_path(const char* const data_base)
164 {
165     gchar* xdg_data = _files_get_xdg_data_home();
166     GString* file_str = g_string_new(xdg_data);
167     g_string_append(file_str, "/profanity/");
168     g_string_append(file_str, data_base);
169     gchar* result = g_strdup(file_str->str);
170     g_free(xdg_data);
171     g_string_free(file_str, TRUE);
172 
173     return result;
174 }
175 
176 gchar*
files_get_account_data_path(const char * const specific_dir,const char * const jid)177 files_get_account_data_path(const char* const specific_dir, const char* const jid)
178 {
179     gchar* data_dir = files_get_data_path(specific_dir);
180     GString* result_dir = g_string_new(data_dir);
181     g_free(data_dir);
182 
183     gchar* account_dir = str_replace(jid, "@", "_at_");
184     g_string_append(result_dir, "/");
185     g_string_append(result_dir, account_dir);
186     g_free(account_dir);
187 
188     gchar* result = g_strdup(result_dir->str);
189     g_string_free(result_dir, TRUE);
190 
191     return result;
192 }
193 
194 static char*
_files_get_xdg_config_home(void)195 _files_get_xdg_config_home(void)
196 {
197     gchar* xdg_config_home_env = getenv("XDG_CONFIG_HOME");
198     gchar* xdg_config_home = NULL;
199 
200     if (xdg_config_home_env) {
201         xdg_config_home = strdup(xdg_config_home_env);
202         g_strstrip(xdg_config_home);
203     }
204 
205     if (xdg_config_home && (strcmp(xdg_config_home, "") != 0)) {
206         return xdg_config_home;
207     } else {
208         GString* default_path = g_string_new(getenv("HOME"));
209         g_string_append(default_path, "/.config");
210         char* result = strdup(default_path->str);
211         g_string_free(default_path, TRUE);
212 
213         return result;
214     }
215 }
216 
217 static char*
_files_get_xdg_data_home(void)218 _files_get_xdg_data_home(void)
219 {
220     gchar* xdg_data_home_env = getenv("XDG_DATA_HOME");
221     gchar* xdg_data_home = NULL;
222 
223     if (xdg_data_home_env) {
224         xdg_data_home = strdup(xdg_data_home_env);
225         g_strstrip(xdg_data_home);
226     }
227 
228     if (xdg_data_home && (strcmp(xdg_data_home, "") != 0)) {
229         return xdg_data_home;
230     } else {
231         GString* default_path = g_string_new(getenv("HOME"));
232         g_string_append(default_path, "/.local/share");
233         gchar* result = strdup(default_path->str);
234         g_string_free(default_path, TRUE);
235 
236         return result;
237     }
238 }
239