aboutsummaryrefslogtreecommitdiffstats
path: root/samsung-ipc/path_utils.c
diff options
context:
space:
mode:
Diffstat (limited to 'samsung-ipc/path_utils.c')
-rw-r--r--samsung-ipc/path_utils.c163
1 files changed, 163 insertions, 0 deletions
diff --git a/samsung-ipc/path_utils.c b/samsung-ipc/path_utils.c
new file mode 100644
index 0000000..9cfc640
--- /dev/null
+++ b/samsung-ipc/path_utils.c
@@ -0,0 +1,163 @@
+/*
+ * This file is part of libsamsung-ipc.
+ *
+ * Copyright (C) 2013-2014 Paul Kocialkowski <contact@paulk.fr>
+ *
+ * libsamsung-ipc 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libsamsung-ipc 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 libsamsung-ipc. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <sys/stat.h>
+
+#include <samsung-ipc.h>
+
+#include "path_utils.h"
+
+int rmdir_p(struct ipc_client *client,
+ const char * const path, struct dir_infos *infos)
+{
+#if 0
+ char *_path;
+ char *startp;
+ char *endp;
+ uint64_t created_dirs = 0;
+ uint64_t dirs_depth = 0;
+ int rc;
+
+ /* We want to be able to modify the path string to replace '/'
+ * with '\0' to avoid having to copy again and again string
+ * parts */
+ _path = malloc(strlen(path) + 1);
+ if (_path == NULL) {
+ rc = errno;
+ ipc_client_log(client,
+ "%s: malloc _path failed with error %d: %s",
+ __func__, rc, strerror(rc));
+ errno = rc;
+ return -1;
+ }
+
+ memcpy(_path, path, strlen(path) + 1);
+
+ startp = _path;
+ while (true) {
+ endp = strchr(startp + 1, '/');
+ if (endp != NULL)
+ *endp = '\0';
+
+ //rc = mkdir(_path, mode);
+ if (rc == -1) {
+ rc = errno;
+ if (rc == EEXIST) {
+ dirs_depth++;
+ } else {
+ ipc_client_log(client,
+ "%s: mkdir %s failed with error %d: %s",
+ __func__, _path, rc, strerror(rc));
+ rc = rmdir_p(client, _path, dirs_depth, created_dirs);
+ if (rc == -1) {
+ ipc_client_log(client,
+ "%s: rmdir_p %s failed",
+ __func__, _path);
+ }
+ return -1;
+ }
+ } else {
+ created_dirs |= (DIR_CREATED << dirs_depth);
+ dirs_depth++;
+ }
+
+ if (endp == NULL)
+ break;
+
+ startp = endp;
+ *endp = '/';
+ }
+#endif
+ return 0;
+}
+
+int mkdir_p(struct ipc_client *client,
+ const char * const path, mode_t mode, struct dir_infos *infos)
+{
+ char *_path;
+ char *startp;
+ char *endp;
+ /* In case of errors we want to be able to remove (only) the
+ * directories we created, so we need to store what was
+ * already there and what we created. */
+ uint64_t created_dirs = 0;
+ uint64_t dirs_depth = 0;
+ int rc;
+
+ /* We want to be able to modify the path string to replace '/'
+ * with '\0' to avoid having to copy again and again string
+ * parts */
+ _path = malloc(strlen(path) + 1);
+ if (_path == NULL) {
+ rc = errno;
+ ipc_client_log(client,
+ "%s: malloc _path failed with error %d: %s",
+ __func__, rc, strerror(rc));
+ errno = rc;
+ return -1;
+ }
+
+ memcpy(_path, path, strlen(path) + 1);
+
+ startp = _path;
+ while (true) {
+ endp = strchr(startp + 1, '/');
+ if (endp != NULL)
+ *endp = '\0';
+
+ rc = mkdir(_path, mode);
+ if (rc == -1) {
+ rc = errno;
+ if (rc == EEXIST) {
+ dirs_depth++;
+ } else {
+ ipc_client_log(client,
+ "%s: mkdir %s failed with error %d: %s",
+ __func__, _path, rc, strerror(rc));
+ rc = rmdir_p(client, _path, infos);
+ if (rc == -1) {
+ ipc_client_log(client,
+ "%s: rmdir_p %s failed",
+ __func__, _path);
+ }
+ free(_path);
+ return -1;
+ }
+ } else {
+ created_dirs |= (DIR_CREATED << dirs_depth);
+ dirs_depth++;
+ }
+
+ if (endp == NULL)
+ break;
+
+ startp = endp;
+ *endp = '/';
+ }
+
+ free(_path);
+ return 0;
+}