diff --git a/include/fs.h b/include/fs.h index bc2ed6c..c17df20 100644 --- a/include/fs.h +++ b/include/fs.h @@ -100,6 +100,9 @@ off_t lseek(int fildes, off_t offset, int whence); int mkdir (const char *pathname, mode_t mode); + +/* Create a directory and its parents */ +int make_directory(const char *pathname); int rmdir (const char *pathname); const char *getcwd(void); diff --git a/lib/Makefile b/lib/Makefile index 2ee3d20..423e49a 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -14,6 +14,7 @@ obj-y += libbb.o obj-y += libgen.o obj-y += recursive_action.o +obj-y += make_directory.o obj-$(CONFIG_BZLIB) += bzlib.o bzlib_crctable.o bzlib_decompress.o bzlib_huffman.o bzlib_randtable.o obj-$(CONFIG_ZLIB) += zlib.o gunzip.o obj-$(CONFIG_CRC32) += crc32.o diff --git a/lib/make_directory.c b/lib/make_directory.c new file mode 100644 index 0000000..cf02e0b --- /dev/null +++ b/lib/make_directory.c @@ -0,0 +1,54 @@ + +#include +#include +#ifdef __U_BOOT__ +#include +#include +#endif + +int make_directory(const char *dir) +{ + char *s = strdup(dir); + char *path = s; + char c; + + do { + c = 0; + + /* Bypass leading non-'/'s and then subsequent '/'s. */ + while (*s) { + if (*s == '/') { + do { + ++s; + } while (*s == '/'); + c = *s; /* Save the current char */ + *s = 0; /* and replace it with nul. */ + break; + } + ++s; + } + + if (mkdir(path, 0777) < 0) { + + /* If we failed for any other reason than the directory + * already exists, output a diagnostic and return -1.*/ +#ifdef __U_BOOT__ + if (errno != -EEXIST) +#else + if (errno != EEXIST) +#endif + break; + } + if (!c) + goto out; + + /* Remove any inserted nul from the path (recursive mode). */ + *s = c; + + } while (1); + +out: + free(path); + return errno; +} +