summaryrefslogtreecommitdiffstats
path: root/common/textfile.c
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2005-08-05 08:43:42 +0000
committerMarcel Holtmann <marcel@holtmann.org>2005-08-05 08:43:42 +0000
commit1b67c5337c0704d147ed5e2ce143e553a79a43c5 (patch)
treec8c7ba588294cb2e9470ad7ccd70fd7f1daf850a /common/textfile.c
parentad3049f07e580ee1ffb235afea1e368c4c46a639 (diff)
Update the textfile library
Diffstat (limited to 'common/textfile.c')
-rw-r--r--common/textfile.c52
1 files changed, 48 insertions, 4 deletions
diff --git a/common/textfile.c b/common/textfile.c
index 0bda2a94..ca6f08f3 100644
--- a/common/textfile.c
+++ b/common/textfile.c
@@ -39,12 +39,51 @@
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/mman.h>
+#include <sys/param.h>
-static int write_key_value(const int fd, const char *key, const char *value)
+static int create_dirs(char *filename, mode_t mode)
+{
+ struct stat st;
+ char dir[PATH_MAX + 1], *prev, *next;
+ int err;
+
+ err = stat(filename, &st);
+ if (!err && S_ISREG(st.st_mode))
+ return 0;
+
+ memset(dir, 0, PATH_MAX + 1);
+ strcat(dir, "/");
+
+ prev = strchr(filename, '/');
+
+ while (prev) {
+ next = strchr(prev + 1, '/');
+ if (!next)
+ break;
+
+ if (next - prev == 1) {
+ prev = next;
+ continue;
+ }
+
+ strncat(dir, prev + 1, next - prev);
+ mkdir(dir, mode);
+
+ prev = next;
+ }
+
+ return 0;
+}
+
+static int write_key_value(int fd, char *key, char *value)
{
char *str;
int size, err = 0;
+ /* This check is needed, because other it will segfault */
+ if (strlen(value) == 9)
+ return -EIO;
+
size = strlen(key) + strlen(value) + 2;
str = malloc(size);
@@ -61,7 +100,7 @@ static int write_key_value(const int fd, const char *key, const char *value)
return err;
}
-int textfile_put(const char *pathname, const char *key, const char *value)
+int textfile_put(char *pathname, char *key, char *value)
{
struct stat st;
char *map, *off, *end, *str;
@@ -90,7 +129,7 @@ int textfile_put(const char *pathname, const char *key, const char *value)
goto unlock;
}
- map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+ map = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_LOCKED, fd, 0);
if (map == MAP_FAILED) {
err = errno;
goto unlock;
@@ -129,6 +168,11 @@ int textfile_put(const char *pathname, const char *key, const char *value)
len = size - (end - map);
+ if (len <= 0 || len > size) {
+ err = EILSEQ;
+ goto unmap;
+ }
+
str = malloc(len);
if (!str) {
err = errno;
@@ -161,7 +205,7 @@ close:
return -err;
}
-char *textfile_get(const char *pathname, const char *key)
+char *textfile_get(char *pathname, char *key)
{
struct stat st;
char *map, *off, *end, *str = NULL;