summaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorSébastien Helleu <flashcode@flashtux.org>2018-11-17 10:36:58 +0100
committerSébastien Helleu <flashcode@flashtux.org>2018-11-17 10:36:58 +0100
commit85d7c9b6c5155db0156cd36c7b3127eb516399ff (patch)
tree3cea302ac0e9d60e004a2dfecccfb501bbe61250 /src/core
parentb480c7e7c06873c900bbac4a8112c86ddc66e073 (diff)
downloadweechat-85d7c9b6c5155db0156cd36c7b3127eb516399ff.zip
core: add command line option "-t" (or "--temp-dir") to create a temporary WeeChat home (deleted on exit)
Diffstat (limited to 'src/core')
-rw-r--r--src/core/wee-debug.c8
-rw-r--r--src/core/wee-util.c93
-rw-r--r--src/core/wee-util.h15
-rw-r--r--src/core/weechat.c80
-rw-r--r--src/core/weechat.h1
5 files changed, 193 insertions, 4 deletions
diff --git a/src/core/wee-debug.c b/src/core/wee-debug.c
index 44d20e616..b21a7d98a 100644
--- a/src/core/wee-debug.c
+++ b/src/core/wee-debug.c
@@ -581,8 +581,12 @@ debug_directories ()
gui_chat_printf (NULL, "");
gui_chat_printf (NULL, _("Directories:"));
- gui_chat_printf (NULL, " home: %s (%s: %s)",
- weechat_home, _("default"), WEECHAT_HOME);
+ gui_chat_printf (NULL, " home: %s%s%s",
+ weechat_home,
+ (weechat_home_temp) ? " " : "",
+ (weechat_home_temp) ? _("(TEMPORARY, deleted on exit)") : "");
+ gui_chat_printf (NULL, _(" (default: %s)"),
+ WEECHAT_HOME);
gui_chat_printf (NULL, " lib: %s", WEECHAT_LIBDIR);
gui_chat_printf (NULL, " lib (extra): %s",
(extra_libdir && extra_libdir[0]) ? extra_libdir : "-");
diff --git a/src/core/wee-util.c b/src/core/wee-util.c
index 8760aacea..be2512d88 100644
--- a/src/core/wee-util.c
+++ b/src/core/wee-util.c
@@ -19,6 +19,14 @@
* along with WeeChat. If not, see <http://www.gnu.org/licenses/>.
*/
+/* for P_tmpdir in stdio.h */
+#ifndef __USE_XOPEN
+#define __USE_XOPEN
+#endif
+
+/* for nftw() */
+#define _XOPEN_SOURCE 700
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -39,6 +47,7 @@
#include <signal.h>
#include <ctype.h>
#include <time.h>
+#include <ftw.h>
#include "weechat.h"
#include "wee-util.h"
@@ -363,6 +372,49 @@ util_catch_signal (int signum, void (*handler)(int))
}
/*
+ * Returns the path to a temporary directory, the first valid directory in
+ * this list:
+ * - content of environment variable "TMPDIR"
+ * - P_tmpdir (from stdio.h)
+ * - content of environment variable "HOME" (user home directory)
+ * - "." (current directory)
+ */
+
+char *
+util_get_temp_dir()
+{
+ char *tmpdir;
+ struct stat buf;
+ int rc;
+
+ /* get directory from $TMPDIR */
+ tmpdir = getenv ("TMPDIR");
+ if (tmpdir && tmpdir[0])
+ {
+ rc = stat (tmpdir, &buf);
+ if ((rc == 0) && S_ISDIR(buf.st_mode))
+ return strdup (tmpdir);
+ }
+
+ /* get directory from P_tmpdir */
+ rc = stat (P_tmpdir, &buf);
+ if ((rc == 0) && S_ISDIR(buf.st_mode))
+ return strdup (P_tmpdir);
+
+ /* get directory from $HOME */
+ tmpdir = getenv ("HOME");
+ if (tmpdir && tmpdir[0])
+ {
+ rc = stat (tmpdir, &buf);
+ if ((rc == 0) && S_ISDIR(buf.st_mode))
+ return strdup (tmpdir);
+ }
+
+ /* fallback on current directory */
+ return strdup (".");
+}
+
+/*
* Creates a directory in WeeChat home.
*
* Returns:
@@ -483,6 +535,47 @@ util_mkdir_parents (const char *directory, int mode)
}
/*
+ * Unlinks a file or directory; callback called by function util_rmtree().
+ *
+ * Returns the return code of remove():
+ * 0: OK
+ * -1: error
+ */
+
+int
+util_unlink_cb (const char *fpath, const struct stat *sb, int typeflag,
+ struct FTW *ftwbuf)
+{
+ /* make C compiler happy */
+ (void) sb;
+ (void) typeflag;
+ (void) ftwbuf;
+
+ return remove (fpath);
+}
+
+/*
+ * Removes a directory and all files inside recursively.
+ *
+ * Returns:
+ * 1: OK
+ * 0: error
+ */
+
+int
+util_rmtree (const char *directory)
+{
+ int rc;
+
+ if (!directory)
+ return 0;
+
+ rc = nftw (directory, util_unlink_cb, 64, FTW_DEPTH | FTW_PHYS);
+
+ return (rc == 0) ? 1 : 0;
+}
+
+/*
* Finds files in a directory and executes a function on each file.
*/
diff --git a/src/core/wee-util.h b/src/core/wee-util.h
index 53ae47535..cd41fc083 100644
--- a/src/core/wee-util.h
+++ b/src/core/wee-util.h
@@ -36,16 +36,27 @@ struct t_util_signal
int signal; /* signal number */
};
+/* limits */
extern void util_setrlimit ();
+
+/* timeval */
extern int util_timeval_cmp (struct timeval *tv1, struct timeval *tv2);
extern long long util_timeval_diff (struct timeval *tv1, struct timeval *tv2);
extern void util_timeval_add (struct timeval *tv, long long interval);
+
+/* time */
extern const char *util_get_time_string (const time_t *date);
+
+/* signal */
extern int util_signal_search (const char *name);
extern void util_catch_signal (int signum, void (*handler)(int));
+
+/* files/directories */
+extern char *util_get_temp_dir();
extern int util_mkdir_home (const char *directory, int mode);
extern int util_mkdir (const char *directory, int mode);
extern int util_mkdir_parents (const char *directory, int mode);
+extern int util_rmtree (const char *directory);
extern void util_exec_on_files (const char *directory, int recurse_subdirs,
int hidden_files,
void (*callback)(void *data,
@@ -54,7 +65,11 @@ extern void util_exec_on_files (const char *directory, int recurse_subdirs,
extern char *util_search_full_lib_name (const char *filename,
const char *sys_directory);
extern char *util_file_get_content (const char *filename);
+
+/* version */
extern int util_version_number (const char *version);
+
+/* uptime */
extern void util_get_uptime (time_t *total_seconds, int *days,
int *hours, int *minutes, int *seconds);
diff --git a/src/core/weechat.c b/src/core/weechat.c
index dee813023..7ddc636ea 100644
--- a/src/core/weechat.c
+++ b/src/core/weechat.c
@@ -94,6 +94,8 @@ volatile sig_atomic_t weechat_quit = 0; /* = 1 if quit request from user */
volatile sig_atomic_t weechat_quit_signal = 0; /* signal received, */
/* WeeChat must quit */
char *weechat_home = NULL; /* home dir. (default: ~/.weechat) */
+int weechat_home_temp = 0; /* 1 if using a temporary home */
+int weechat_home_delete_on_exit = 0; /* 1 if home is deleted on exit */
int weechat_locale_ok = 0; /* is locale OK? */
char *weechat_local_charset = NULL; /* example: ISO-8859-1, UTF-8 */
int weechat_server_cmd_line = 0; /* at least 1 server on cmd line */
@@ -152,6 +154,9 @@ weechat_display_usage ()
"(default: ~/.weechat)\n"
" (environment variable WEECHAT_HOME is "
"read if this option is not given)\n"
+ " -t, --temp-dir create a temporary WeeChat home"
+ "directory and delete it on exit\n"
+ " (incompatible with option \"-d\")\n"
" -h, --help display this help\n"
" -l, --license display WeeChat license\n"
" -p, --no-plugin don't load any plugin at startup\n"
@@ -199,6 +204,8 @@ weechat_parse_args (int argc, char *argv[])
weechat_argv0 = (argv[0]) ? strdup (argv[0]) : NULL;
weechat_upgrading = 0;
weechat_home = NULL;
+ weechat_home_temp = 0;
+ weechat_home_delete_on_exit = 0;
weechat_server_cmd_line = 0;
weechat_force_plugin_autoload = NULL;
weechat_plugin_no_dlclose = 0;
@@ -212,8 +219,10 @@ weechat_parse_args (int argc, char *argv[])
weechat_shutdown (EXIT_SUCCESS, 0);
}
else if ((strcmp (argv[i], "-d") == 0)
- || (strcmp (argv[i], "--dir") == 0))
+ || (strcmp (argv[i], "--dir") == 0))
{
+ if (weechat_home_temp)
+ weechat_home_temp = 0;
if (i + 1 < argc)
{
if (weechat_home)
@@ -228,6 +237,16 @@ weechat_parse_args (int argc, char *argv[])
weechat_shutdown (EXIT_FAILURE, 0);
}
}
+ else if ((strcmp (argv[i], "-t") == 0)
+ || (strcmp (argv[i], "--temp-dir") == 0))
+ {
+ if (weechat_home)
+ {
+ free (weechat_home);
+ weechat_home = NULL;
+ }
+ weechat_home_temp = 1;
+ }
else if ((strcmp (argv[i], "-h") == 0)
|| (strcmp (argv[i], "--help") == 0))
{
@@ -383,9 +402,60 @@ weechat_set_home_path (char *home_path)
void
weechat_create_home_dir ()
{
- char *ptr_weechat_home, *config_weechat_home;
+ char *temp_dir, *temp_home_template, *ptr_weechat_home;
+ char *config_weechat_home;
+ int length, add_separator;
struct stat statinfo;
+ /* temporary WeeChat home */
+ if (weechat_home_temp)
+ {
+ temp_dir = util_get_temp_dir ();
+ if (!temp_dir || !temp_dir[0])
+ {
+ string_fprintf (stderr,
+ _("Error: not enough memory for home "
+ "directory\n"));
+ weechat_shutdown (EXIT_FAILURE, 0);
+ /* make C static analyzer happy (never executed) */
+ return;
+ }
+ length = strlen (temp_dir) + 32 + 1;
+ temp_home_template = malloc (length);
+ if (!temp_home_template)
+ {
+ free (temp_dir);
+ string_fprintf (stderr,
+ _("Error: not enough memory for home "
+ "directory\n"));
+ weechat_shutdown (EXIT_FAILURE, 0);
+ /* make C static analyzer happy (never executed) */
+ return;
+ }
+ add_separator = (temp_dir[strlen (temp_dir) - 1] != DIR_SEPARATOR_CHAR);
+ snprintf (temp_home_template, length,
+ "%s%sweechat_temp_XXXXXX",
+ temp_dir,
+ add_separator ? DIR_SEPARATOR : "");
+ free (temp_dir);
+ ptr_weechat_home = mkdtemp (temp_home_template);
+ if (!ptr_weechat_home)
+ {
+ string_fprintf (stderr,
+ _("Error: unable to create a temporary "
+ "home directory (using template: \"%s\")\n"),
+ temp_home_template);
+ free (temp_home_template);
+ weechat_shutdown (EXIT_FAILURE, 0);
+ /* make C static analyzer happy (never executed) */
+ return;
+ }
+ weechat_home = strdup (ptr_weechat_home);
+ free (temp_home_template);
+ weechat_home_delete_on_exit = 1;
+ return;
+ }
+
/*
* weechat_home is not set yet: look for environment variable
* "WEECHAT_HOME"
@@ -637,6 +707,12 @@ weechat_shutdown (int return_code, int crash)
network_end ();
debug_end ();
+ if (!crash && weechat_home_delete_on_exit)
+ {
+ /* remove temporary home (only if not crashing) */
+ util_rmtree (weechat_home);
+ }
+
if (weechat_argv0)
free (weechat_argv0);
if (weechat_home)
diff --git a/src/core/weechat.h b/src/core/weechat.h
index cbb565a03..9002de328 100644
--- a/src/core/weechat.h
+++ b/src/core/weechat.h
@@ -110,6 +110,7 @@ extern int weechat_upgrade_count;
extern volatile sig_atomic_t weechat_quit;
extern volatile sig_atomic_t weechat_quit_signal;
extern char *weechat_home;
+extern int weechat_home_temp;
extern char *weechat_local_charset;
extern int weechat_plugin_no_dlclose;
extern int weechat_no_gnutls;