Added ephemeral mode #562.
authorDaniel Carl <danielcarl@gmx.de>
Mon, 3 Jun 2019 23:43:35 +0000 (01:43 +0200)
committerDaniel Carl <danielcarl@gmx.de>
Tue, 4 Jun 2019 00:00:25 +0000 (02:00 +0200)
If vimb is started with --ephemeral option no files are created by
default and no persistent cookie manager is used.

src/bookmark.c
src/ex.c
src/file-storage.c
src/file-storage.h
src/history.c
src/main.c
src/main.h
src/setting.c
src/util.c
src/util.h
tests/test-file-storage.c

index 72c76a8..2a0a3cf 100644 (file)
@@ -236,7 +236,12 @@ gboolean bookmark_queue_clear(void)
 
 static GList *load(const char *file)
 {
-    return util_file_to_unique_list(file, (Util_Content_Func)line_to_bookmark, 0);
+    char **lines;
+    GList *list;
+    lines = util_get_lines(file);
+    list  = util_strv_to_unique_list(lines, (Util_Content_Func)line_to_bookmark, 0);
+    g_strfreev(lines);
+    return list;
 }
 
 /**
index 708020d..d67c05a 100644 (file)
--- a/src/ex.c
+++ b/src/ex.c
@@ -956,7 +956,7 @@ static VbCmdResult ex_queue(Client *c, const ExArg *arg)
 
     return command_queue(c, &a)
         ? CMD_SUCCESS | CMD_KEEPINPUT
-        : CMD_ERROR | CMD_KEEPINPUT;
+        : CMD_ERROR;
 }
 #endif
 
index a924482..98b7f99 100644 (file)
@@ -23,7 +23,6 @@
 #include <glib/gstdio.h>
 
 #include "file-storage.h"
-#include "util.h"
 
 struct filestorage {
     char        *file_path;
@@ -44,26 +43,19 @@ struct filestorage {
  *              creating it. If 0 the file is not created and the storage is
  *              used in read only mode - no data written to the file.
  */
-FileStorage *file_storage_new(const char *dir, const char *filename, int mode)
+FileStorage *file_storage_new(const char *dir, const char *filename, gboolean readonly)
 {
-    char *fullpath;
     FileStorage *storage;
 
-    storage           = g_slice_new(FileStorage);
-    storage->readonly = (mode == 0);
-
-    /* Built the full path out of dir and given file name. */
-    fullpath = g_build_filename(dir, filename, NULL);
-    if (!g_file_test(fullpath, G_FILE_TEST_IS_REGULAR) && mode) {
-        /* If create option was given - create the file. */
-        fclose(fopen(fullpath, "a"));
-        g_chmod(fullpath, mode);
-    }
-    storage->file_path = fullpath;
+    storage            = g_slice_new(FileStorage);
+    storage->readonly  = readonly;
+    storage->file_path = g_build_filename(dir, filename, NULL);
 
     /* Use gstring as storage in case when the file is used read only. */
     if (storage->readonly) {
         storage->str = g_string_new(NULL);
+    } else {
+        storage->str = NULL;
     }
 
     return storage;
@@ -147,3 +139,13 @@ char **file_storage_get_lines(FileStorage *storage)
 
     return lines;
 }
+
+const char *file_storage_get_path(FileStorage *storage)
+{
+    return storage->file_path;
+}
+
+gboolean file_storage_is_readonly(FileStorage *storage)
+{
+    return storage->readonly;
+}
index 3beecce..4a26a8f 100644 (file)
@@ -27,5 +27,7 @@ FileStorage *file_storage_new(const char *dir, const char *filename, int mode);
 void file_storage_free(FileStorage *storage);
 gboolean file_storage_append(FileStorage *storage, const char *format, ...);
 char **file_storage_get_lines(FileStorage *storage);
+const char *file_storage_get_path(FileStorage *storage);
+gboolean file_storage_is_readonly(FileStorage *storage);
 
 #endif /* end of include guard: _FILE_STORAGE_H */
index 9124605..250333b 100644 (file)
@@ -27,8 +27,9 @@
 #include "history.h"
 #include "main.h"
 #include "util.h"
+#include "file-storage.h"
 
-#define HIST_FILE(t) (vb.files[file_map[t]])
+#define HIST_STORAGE(t) (vb.storage[storage_map[t]])
 typedef struct {
     char *first;
     char *second;
@@ -37,14 +38,14 @@ typedef struct {
 static gboolean history_item_contains_all_tags(History *item, char **query, guint qlen);
 static void free_history(History *item);
 static History *line_to_history(const char *uri, const char *title);
-static GList *load(const char *file);
+static GList *load(FileStorage *s);
 static void write_to_file(GList *list, const char *file);
 
 /* map history types to files */
-static const int file_map[HISTORY_LAST] = {
-    FILES_COMMAND,
-    FILES_SEARCH,
-    FILES_HISTORY
+static const int storage_map[HISTORY_LAST] = {
+    STORAGE_COMMAND,
+    STORAGE_SEARCH,
+    STORAGE_HISTORY
 };
 extern struct Vimb vb;
 
@@ -53,18 +54,18 @@ extern struct Vimb vb;
  */
 void history_add(Client *c, HistoryType type, const char *value, const char *additional)
 {
-    const char *file;
+    FileStorage *s;
 
     /* Don't write a history entry if the history max size is set to 0. */
     if (!vb.config.history_max) {
         return;
     }
 
-    file = HIST_FILE(type);
+    s = HIST_STORAGE(type);
     if (additional) {
-        util_file_append(file, "%s\t%s\n", value, additional);
+        file_storage_append(s, "%s\t%s\n", value, additional);
     } else {
-        util_file_append(file, "%s\n", value);
+        file_storage_append(s, "%s\n", value);
     }
 }
 
@@ -74,7 +75,7 @@ void history_add(Client *c, HistoryType type, const char *value, const char *add
  */
 void history_cleanup(void)
 {
-    const char *file;
+    FileStorage *s;
     GList *list;
 
     /* don't cleanup the history file if history max size is 0 */
@@ -83,10 +84,12 @@ void history_cleanup(void)
     }
 
     for (HistoryType i = HISTORY_FIRST; i < HISTORY_LAST; i++) {
-        file = HIST_FILE(i);
-        list = load(file);
-        write_to_file(list, file);
-        g_list_free_full(list, (GDestroyNotify)free_history);
+        s = HIST_STORAGE(i);
+        if (!file_storage_is_readonly(s)) {
+            list = load(s);
+            write_to_file(list, file_storage_get_path(s));
+            g_list_free_full(list, (GDestroyNotify)free_history);
+        }
     }
 }
 
@@ -99,7 +102,7 @@ gboolean history_fill_completion(GtkListStore *store, HistoryType type, const ch
     GtkTreeIter iter;
     History *item;
 
-    src = load(HIST_FILE(type));
+    src = load(HIST_STORAGE(type));
     src = g_list_reverse(src);
     if (!input || !*input) {
         /* without any tags return all items */
@@ -168,12 +171,12 @@ GList *history_get_list(VbInputType type, const char *query)
 
     switch (type) {
         case INPUT_COMMAND:
-            src = load(HIST_FILE(HISTORY_COMMAND));
+            src = load(HIST_STORAGE(HISTORY_COMMAND));
             break;
 
         case INPUT_SEARCH_FORWARD:
         case INPUT_SEARCH_BACKWARD:
-            src = load(HIST_FILE(HISTORY_SEARCH));
+            src = load(HIST_STORAGE(HISTORY_SEARCH));
             break;
 
         default:
@@ -241,10 +244,12 @@ static History *line_to_history(const char *uri, const char *title)
  *
  * Returned list must be freed with (GDestroyNotify)free_history.
  */
-static GList *load(const char *file)
+static GList *load(FileStorage *s)
 {
-    return util_file_to_unique_list(
-        file, (Util_Content_Func)line_to_history, vb.config.history_max
+    return util_strv_to_unique_list(
+        file_storage_get_lines(s),
+        (Util_Content_Func)line_to_history,
+        vb.config.history_max
     );
 }
 
index 6a228a1..00d12cf 100644 (file)
@@ -46,6 +46,7 @@
 #include "shortcut.h"
 #include "util.h"
 #include "autocmd.h"
+#include "file-storage.h"
 
 static void client_destroy(Client *c);
 static Client *client_new(WebKitWebView *webview);
@@ -1768,6 +1769,9 @@ static void vimb_cleanup(void)
     /* free memory of other components */
     util_cleanup();
 
+    for (i = 0; i < STORAGE_LAST; i++) {
+        file_storage_free(vb.storage[i]);
+    }
     for (i = 0; i < FILES_LAST; i++) {
         if (vb.files[i]) {
             g_free(vb.files[i]);
@@ -1794,19 +1798,22 @@ static void vimb_setup(void)
         vb.files[FILES_CONFIG] = g_strdup(rp);
         free(rp);
     } else {
-        vb.files[FILES_CONFIG] = util_get_filepath(path, "config", FALSE, 0600);
+        vb.files[FILES_CONFIG] = g_build_filename(path, "config", NULL);
     }
 
     /* Setup those files that are use multiple time during runtime */
-    vb.files[FILES_CLOSED]     = util_get_filepath(path, "closed", TRUE, 0600);
-    vb.files[FILES_COOKIE]     = util_get_filepath(path, "cookies.db", TRUE, 0600);
-    vb.files[FILES_USER_STYLE] = util_get_filepath(path, "style.css", FALSE, 0600);
-    vb.files[FILES_SCRIPT]     = util_get_filepath(path, "scripts.js", FALSE, 0600);
-    vb.files[FILES_HISTORY]    = util_get_filepath(path, "history", TRUE, 0600);
-    vb.files[FILES_COMMAND]    = util_get_filepath(path, "command", TRUE, 0600);
-    vb.files[FILES_BOOKMARK]   = util_get_filepath(path, "bookmark", TRUE, 0600);
-    vb.files[FILES_QUEUE]      = util_get_filepath(path, "queue", TRUE, 0600);
-    vb.files[FILES_SEARCH]     = util_get_filepath(path, "search", TRUE, 0600);
+    if (!vb.ephemeral) {
+        vb.files[FILES_CLOSED] = g_build_filename(path, "closed", NULL);
+        vb.files[FILES_COOKIE] = g_build_filename(path, "cookies.db", NULL);
+    }
+    vb.files[FILES_BOOKMARK]   = g_build_filename(path, "bookmark", NULL);
+    vb.files[FILES_QUEUE]      = g_build_filename(path, "queue", NULL);
+    vb.files[FILES_SCRIPT]     = g_build_filename(path, "scripts.js", NULL);
+    vb.files[FILES_USER_STYLE] = g_build_filename(path, "style.css", NULL);
+
+    vb.storage[STORAGE_HISTORY]  = file_storage_new(path, "history", vb.ephemeral);
+    vb.storage[STORAGE_COMMAND]  = file_storage_new(path, "command", vb.ephemeral);
+    vb.storage[STORAGE_SEARCH]   = file_storage_new(path, "search", vb.ephemeral);
     g_free(path);
 
     /* Use seperate rendering processed for the webview of the clients in the
@@ -2066,6 +2073,7 @@ int main(int argc, char* argv[])
 
     GOptionEntry opts[] = {
         {"config", 'c', 0, G_OPTION_ARG_FILENAME, &vb.configfile, "Custom configuration file", NULL},
+        {"ephemeral", 'E', 0, G_OPTION_ARG_NONE, &vb.ephemeral, "Run in ephemeral mode", NULL},
         {"embed", 'e', 0, G_OPTION_ARG_STRING, &winid, "Reparents to window specified by xid", NULL},
         {"profile", 'p', 0, G_OPTION_ARG_CALLBACK, (GOptionArgFunc*)profileOptionArgFunc, "Profile name", NULL},
         {"version", 'v', 0, G_OPTION_ARG_NONE, &ver, "Print version", NULL},
index 9e922c6..616d39c 100644 (file)
@@ -26,6 +26,7 @@
 #include <webkit2/webkit2.h>
 #include "shortcut.h"
 #include "handler.h"
+#include "file-storage.h"
 
 #include "config.h"
 
@@ -105,17 +106,23 @@ typedef enum {
 enum {
     FILES_BOOKMARK,
     FILES_CLOSED,
-    FILES_COMMAND,
     FILES_CONFIG,
     FILES_COOKIE,
-    FILES_HISTORY,
     FILES_QUEUE,
     FILES_SCRIPT,
-    FILES_SEARCH,
     FILES_USER_STYLE,
     FILES_LAST
 };
 
+enum {
+    STORAGE_CLOSED,
+    STORAGE_COMMAND,
+    STORAGE_CONFIG,
+    STORAGE_HISTORY,
+    STORAGE_SEARCH,
+    STORAGE_LAST
+};
+
 typedef enum {
     LINK_TYPE_NONE,
     LINK_TYPE_LINK,
@@ -268,6 +275,7 @@ struct Vimb {
     GHashTable  *modes;             /* all available browser main modes */
     char        *configfile;        /* config file given as option on startup */
     char        *files[FILES_LAST];
+    FileStorage *storage[STORAGE_LAST];
     char        *profile;           /* profile name */
     struct {
         guint   history_max;
@@ -275,6 +283,7 @@ struct Vimb {
     } config;
     GtkCssProvider *style_provider;
     gboolean    no_maximize;
+    gboolean    ephemeral;
 };
 
 gboolean vb_download_set_destination(Client *c, WebKitDownload *download,
index 07218ba..b73bc18 100644 (file)
@@ -674,7 +674,7 @@ static int user_style(Client *c, const char *name, DataType type, void *value, v
 
     ucm = webkit_web_view_get_user_content_manager(c->webview);
 
-    if (enabled && vb.files[FILES_USER_STYLE]) {
+    if (enabled) {
         if (g_file_get_contents(vb.files[FILES_USER_STYLE], &source, NULL, NULL)) {
             style = webkit_user_style_sheet_new(
                 source, WEBKIT_USER_CONTENT_INJECT_ALL_FRAMES,
@@ -685,7 +685,7 @@ static int user_style(Client *c, const char *name, DataType type, void *value, v
             webkit_user_style_sheet_unref(style);
             g_free(source);
         } else {
-            g_warning("Could not reed style file: %s", vb.files[FILES_USER_STYLE]);
+            g_message("Could not reed style file: %s", vb.files[FILES_USER_STYLE]);
         }
     } else {
         webkit_user_content_manager_remove_all_style_sheets(ucm);
index 4cc50a0..94c9800 100644 (file)
@@ -429,41 +429,6 @@ out:
     return retval;
 }
 
-/**
- * Buil the path from given directory and filename and checks if the file
- * exists. If the file does not exists and the create option is not set, this
- * function returns NULL.
- * If the file exists or the create option was given the full generated path
- * is returned as newly allocated string.
- *
- * The return value must be freed with g_free.
- *
- * @dir:        Directory in which the file is searched.
- * @filename:   Filename to built the absolute path with.
- * @create:     If TRUE, the file is created if it does not already exist.
- * @mode:       Mode (file permission as chmod(2)) used for the file when creating it.
- */
-char *util_get_filepath(const char *dir, const char *filename, gboolean create, int mode)
-{
-    char *fullpath;
-
-    /* Built the full path out of config dir and given file name. */
-    fullpath = g_build_filename(dir, filename, NULL);
-
-    if (g_file_test(fullpath, G_FILE_TEST_IS_REGULAR)) {
-        return fullpath;
-    } else if (create) {
-        /* If create option was given - create the file. */
-        fclose(fopen(fullpath, "a"));
-        g_chmod(fullpath, mode);
-        return fullpath;
-    }
-
-    g_free(fullpath);
-    return NULL;
-}
-
-
 /**
  * Retrieves the file content as lines.
  *
@@ -478,7 +443,7 @@ char **util_get_lines(const char *filename)
         return NULL;
     }
 
-    if ((content = util_get_file_contents(filename, NULL))) {
+    if (g_file_get_contents(filename, &content, NULL, NULL)) {
         /* split the file content into lines */
         lines = g_strsplit(content, "\n", -1);
         g_free(content);
@@ -491,20 +456,18 @@ char **util_get_lines(const char *filename)
  * based on the lines comparing all chars until the next <tab> char or end of
  * line.
  *
- * @filename:    file to read items from
  * @func:        Function to parse a single line to item.
  * @max_items:   maximum number of items that are returned, use 0 for
  *               unlimited items
  */
-GList *util_file_to_unique_list(const char *filename, Util_Content_Func func,
+GList *util_strv_to_unique_list(char **lines, Util_Content_Func func,
         guint max_items)
 {
-    char *line, **lines;
+    char *line;
     int i, len;
     GList *gl = NULL;
     GHashTable *ht;
 
-    lines = util_get_lines(filename);
     if (!lines) {
         return NULL;
     }
@@ -556,7 +519,6 @@ GList *util_file_to_unique_list(const char *filename, Util_Content_Func func,
         }
     }
 
-    g_strfreev(lines);
     g_hash_table_destroy(ht);
 
     return gl;
index 62b7574..7edea55 100644 (file)
@@ -43,9 +43,8 @@ char *util_file_pop_line(const char *file, int *item_count);
 char *util_get_config_dir(void);
 char *util_get_file_contents(const char *filename, gsize *length);
 gboolean util_file_set_content(const char *file, const char *contents);
-char *util_get_filepath(const char *dir, const char *filename, gboolean create, int mode);
 char **util_get_lines(const char *filename);
-GList *util_file_to_unique_list(const char *filename, Util_Content_Func func,
+GList *util_strv_to_unique_list(char **lines, Util_Content_Func func,
         guint max_items);
 gboolean util_fill_completion(GtkListStore *store, const char *input, GList *src);
 gboolean util_filename_fill_completion(State state, GtkListStore *store, const char *input);
index 9cea872..387905b 100644 (file)
@@ -36,8 +36,10 @@ static void test_ephemeral_no_file(void)
 
     /* make sure the file does not exist */
     remove(file_path);
-    s = file_storage_new(pwd, none_existing_file, 0);
+    s = file_storage_new(pwd, none_existing_file, TRUE);
     g_assert_nonnull(s);
+    g_assert_cmpstr(file_path, ==, file_storage_get_path(s));
+    g_assert_true(file_storage_is_readonly(s));
 
     /* empty file storage */
     lines = file_storage_get_lines(s);
@@ -68,7 +70,13 @@ static void test_file_created(void)
     remove(file_path);
 
     g_assert_false(g_file_test(file_path, G_FILE_TEST_IS_REGULAR));
-    s = file_storage_new(pwd, created_file, 0640);
+    s = file_storage_new(pwd, created_file, FALSE);
+    g_assert_false(file_storage_is_readonly(s));
+    g_assert_cmpstr(file_path, ==, file_storage_get_path(s));
+
+    /* check that file is created only on first write */
+    g_assert_false(g_file_test(file_path, G_FILE_TEST_IS_REGULAR));
+    file_storage_append(s, "");
     g_assert_true(g_file_test(file_path, G_FILE_TEST_IS_REGULAR));
 
     file_storage_free(s);
@@ -85,8 +93,10 @@ static void test_ephemeral_with_file(void)
 
     file_path = g_build_filename(pwd, existing_file, NULL);
 
-    s = file_storage_new(pwd, existing_file, 0);
+    s = file_storage_new(pwd, existing_file, TRUE);
     g_assert_nonnull(s);
+    g_assert_true(file_storage_is_readonly(s));
+    g_assert_cmpstr(file_path, ==, file_storage_get_path(s));
 
     /* file does not exists yet */
     lines = file_storage_get_lines(s);