diff options
author | Sébastien Helleu <flashcode@flashtux.org> | 2018-11-17 10:36:58 +0100 |
---|---|---|
committer | Sébastien Helleu <flashcode@flashtux.org> | 2018-11-17 10:36:58 +0100 |
commit | 85d7c9b6c5155db0156cd36c7b3127eb516399ff (patch) | |
tree | 3cea302ac0e9d60e004a2dfecccfb501bbe61250 /src/core | |
parent | b480c7e7c06873c900bbac4a8112c86ddc66e073 (diff) | |
download | weechat-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.c | 8 | ||||
-rw-r--r-- | src/core/wee-util.c | 93 | ||||
-rw-r--r-- | src/core/wee-util.h | 15 | ||||
-rw-r--r-- | src/core/weechat.c | 80 | ||||
-rw-r--r-- | src/core/weechat.h | 1 |
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; |