diff options
author | Andrzej Zaborowski <andrew.zaborowski@intel.com> | 2009-09-05 03:12:19 +0200 |
---|---|---|
committer | Denis Kenzior <denkenz@gmail.com> | 2009-09-08 13:34:07 -0500 |
commit | 17cb0ce3c4a936ed38109d1455178eb14f18ea07 (patch) | |
tree | 6ba0ac915fe7eff22d90f998fce329999fa116f2 /src/storage.c | |
parent | 36d0c8451fdd5ae6516e1d787336456cfb5f5ab7 (diff) | |
download | ofono-17cb0ce3c4a936ed38109d1455178eb14f18ea07.tar.bz2 |
Move create_dirs to storage.c, add file read/write utilities
Diffstat (limited to 'src/storage.c')
-rw-r--r-- | src/storage.c | 125 |
1 files changed, 125 insertions, 0 deletions
diff --git a/src/storage.c b/src/storage.c new file mode 100644 index 00000000..d66f20f4 --- /dev/null +++ b/src/storage.c @@ -0,0 +1,125 @@ +/* + * + * oFono - Open Source Telephony + * + * Copyright (C) 2008-2009 Intel Corporation. All rights reserved. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * 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, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#define _GNU_SOURCE +#include <string.h> +#include <stdarg.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> +#include <errno.h> + +#include <glib.h> + +#include <ofono/types.h> +#include "storage.h" + +int create_dirs(const char *filename, const mode_t mode) +{ + struct stat st; + char *dir; + const char *prev, *next; + int err; + + err = stat(filename, &st); + if (!err && S_ISREG(st.st_mode)) + return 0; + + dir = g_malloc(strlen(filename) + 1); + strcpy(dir, "/"); + + for (prev = filename; (next = strchr(prev + 1, '/')); prev = next) + if (next > prev + 1) { + strncat(dir, prev + 1, next - prev); + + if (mkdir(dir, mode) && errno != EEXIST) { + g_free(dir); + return -1; + } + } + + g_free(dir); + return 0; +} + +ssize_t read_file(unsigned char *buffer, size_t len, + const char *path_fmt, ...) { + va_list ap; + char *path; + ssize_t r; + int fd; + + va_start(ap, path_fmt); + path = g_strdup_vprintf(path_fmt, ap); + va_end(ap); + + fd = TFR(open(path, O_RDONLY)); + + g_free(path); + + if (fd == -1) + return -1; + + r = TFR(read(fd, buffer, len)); + + TFR(close(fd)); + + return r; +} + +ssize_t write_file(const unsigned char *buffer, size_t len, mode_t mode, + const char *path_fmt, ...) { + va_list ap; + char *path; + ssize_t r; + int fd; + + va_start(ap, path_fmt); + path = g_strdup_vprintf(path_fmt, ap); + va_end(ap); + + if (create_dirs(path, mode | S_IXUSR) != 0) { + g_free(path); + return -1; + } + + fd = TFR(open(path, O_WRONLY | O_CREAT | O_TRUNC, mode)); + if (fd == -1) { + g_free(path); + return -1; + } + + r = TFR(write(fd, buffer, len)); + + TFR(close(fd)); + + if (r != (ssize_t) len) { + unlink(path); + r = -1; + } + + g_free(path); + return r; +} |