summaryrefslogtreecommitdiff
path: root/mkdir_r.c
diff options
context:
space:
mode:
Diffstat (limited to 'mkdir_r.c')
-rw-r--r--mkdir_r.c81
1 files changed, 81 insertions, 0 deletions
diff --git a/mkdir_r.c b/mkdir_r.c
new file mode 100644
index 0000000..d71c47c
--- /dev/null
+++ b/mkdir_r.c
@@ -0,0 +1,81 @@
+/*
+ Copyright 2020 Xavier Del Campo Romero
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+*/
+#include "mkdir_r.h"
+#include <string.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <dirent.h>
+#include <errno.h>
+#include <stdio.h>
+
+int mkdir_r(const char *const path, int level)
+{
+ int ret = -1;
+ char *dir = NULL;
+ DIR *d = NULL;
+
+ if (!strlen(path))
+ goto exit;
+
+ const char *c = path;
+ int cur_level = 0;
+
+ while (cur_level <= level)
+ {
+ for (; *c && *c != '\\' && *c != '/'; c++)
+ ;
+
+ if (*c)
+ c++;
+
+ cur_level++;
+ }
+
+ const size_t sz = c - path + 1;
+
+ dir = malloc(sz);
+
+ if (!dir)
+ goto exit;
+
+ memcpy(dir, path, sz - 1);
+ dir[sz - 1] = '\0';
+
+ d = opendir(dir);
+
+ if (!d && mkdir(dir, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH))
+ {
+ perror("mkdir");
+ goto exit;
+ }
+
+ if (*c)
+ mkdir_r(path, cur_level);
+
+ /* No more levels left. */
+ ret = 0;
+
+exit:
+ if (dir)
+ free(dir);
+
+ if (d)
+ closedir(d);
+
+ return ret;
+}