1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
|
/**
* vimb - a webkit based vim like browser.
*
* Copyright (C) 2012-2019 Daniel Carl
*
* This program 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.
*
* This program 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 this program. If not, see http://www.gnu.org/licenses/.
*/
#include <glib.h>
#include <stdio.h>
#include <sys/file.h>
#include <glib/gstdio.h>
#include "file-storage.h"
struct filestorage {
char *file_path;
gboolean readonly;
GString *str;
};
/**
* Create new file storage instance for given directory and filename. If the
* file does not exists in the directory and give mode is not 0 the file is
* created with the given mode.
*
* The returned FileStorage must be freed by file_storage_free().
*
* @dir: Directory in which the file is searched.
* @filename: Filename to built the absolute path with.
* @mode: Mode (file permission as chmod(2)) used for the file when
* 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, gboolean readonly)
{
FileStorage *storage;
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;
}
/**
* Free memory for given file storage.
*/
void file_storage_free(FileStorage *storage)
{
if (storage) {
g_free(storage->file_path);
if (storage->str) {
g_string_free(storage->str, TRUE);
}
g_slice_free(FileStorage, storage);
}
}
/**
* Append new data to file.
*
* @fileStorage: FileStorage to append the data to
* @format: Format string used to process va_list
*/
gboolean file_storage_append(FileStorage *storage, const char *format, ...)
{
FILE *f;
va_list args;
g_assert(storage);
/* Write data to in memory list in case the file storage is read only. */
if (storage->readonly) {
va_start(args, format);
g_string_append_vprintf(storage->str, format, args);
va_end(args);
return TRUE;
}
if ((f = fopen(storage->file_path, "a+"))) {
flock(fileno(f), LOCK_EX);
va_start(args, format);
vfprintf(f, format, args);
va_end(args);
flock(fileno(f), LOCK_UN);
fclose(f);
return TRUE;
}
return FALSE;
}
/**
* Retrieves all the lines from file storage.
*
* The result have to be freed by g_strfreev().
*/
char **file_storage_get_lines(FileStorage *storage)
{
char *fullcontent = NULL;
char *content = NULL;
char **lines = NULL;
g_file_get_contents(storage->file_path, &content, NULL, NULL);
if (storage->str && storage->str->len) {
if (content) {
fullcontent = g_strconcat(content, storage->str->str, NULL);
lines = g_strsplit(fullcontent, "\n", -1);
g_free(fullcontent);
} else {
lines = g_strsplit(storage->str->str, "\n", -1);
}
} else {
lines = g_strsplit(content ? content : "", "\n", -1);
}
if (content) {
g_free(content);
}
return lines;
}
const char *file_storage_get_path(FileStorage *storage)
{
return storage->file_path;
}
gboolean file_storage_is_readonly(FileStorage *storage)
{
return storage->readonly;
}
|