From e91bbc1ff7b132d8ac676c224062336ebf4ec3ba Mon Sep 17 00:00:00 2001 From: John Breaux Date: Wed, 23 Feb 2022 18:25:06 -0600 Subject: [PATCH] bscopy: Implement recursive mkdir (mkdir -p) --- bscopy.c | 42 ++++++++++++++++++++++++++++++++---------- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/bscopy.c b/bscopy.c index 27deb5e..b2b3625 100644 --- a/bscopy.c +++ b/bscopy.c @@ -28,7 +28,6 @@ size_t fcopy (size_t block, char* in_filename, char* out_filename); /* fcreate: create a new file at filename, if it doesn't exist. If file is attempted to be created in a nonexistent directory, recursively create directories until the error is resolved. - I have no time for grading mistakes due to user error. args: size: size of file in bytes filename: path to file @@ -36,6 +35,13 @@ size_t fcopy (size_t block, char* in_filename, char* out_filename); size_t: difference between number of bytes requested and actually created (should be zero) */ int fcreate(size_t size, char* filename); +/* dircreate: recursive mkdir (aka mkdir -p) + args: + path: path to directory + returns: + depth: number of directories created +*/ +int dircreate(char* path); int main (int argc, char** argv) { int block_size = 1; @@ -59,7 +65,7 @@ int main (int argc, char** argv) { exit (EXIT_FAILURE); } - +/* printf ("Copy %s to %s with blocksize of %d.\n", in, out, block_size); // start the clock clock_t time = clock(); @@ -69,6 +75,9 @@ int main (int argc, char** argv) { time = clock() - time; printf ("Copy of %.3f MBytes took %f seconds\n", (double)size / (1024*1024), (double) time / CLOCKS_PER_SEC); exit (EXIT_SUCCESS); +*/ + // Test dircreate + printf("dircreate returned %d\n",dircreate(out)); } size_t fcopy (size_t block, char *in_filename, char *out_filename) { @@ -107,25 +116,37 @@ int min(int a, int b) { } // Recursive mkdir -int dircreate(char* path) { +int dircreate_recurse(char* path, int depth) { + if (depth == 2) { + printf("If you see this message, you've asked to create an awful lot of directories.\n"); + } while (mkdir(path, 0700)) { switch (errno){ case EEXIST: - return 0; + // path exists. Success! + return depth; case ENOENT: { char subpath[0x1000] = {0}, *last_slash; size_t l = 0; + // get the length of the substring last_slash = strrchr(path, '/'); - l = path - (last_slash == NULL ? path : last_slash); - strncpy(subpath, path, min(l, 0x1000)); // construct the substring - dircreate(subpath); // recurse + l = (last_slash == NULL ? path : last_slash) - path; + strncpy(subpath, path, min(l, 0x1000)); // construct the substring + depth++; + // if at first you don't succeed, try and try again + depth = dircreate_recurse(subpath, depth); // recurse + break; } default: - printf("Could not create directory: %s\n", strerror(errno)); + printf("Could not create directory %s: Error %d (%s)\n", path, errno, strerror(errno)); return -1; } } - return 0; + return depth; +} +// wrap dircreate_recurse +int dircreate(char* path) { + return dircreate_recurse(path, 0); } int fcreate(size_t size, char* filename) { @@ -139,7 +160,7 @@ int fcreate(size_t size, char* filename) { // then, try to create a file in that directory uint8_t buffer[0x400] = {0}; // Assemble a buffer FILE *file = fopen(filename, "w"); // Open for writing - F_ERROR(file, -1); // abort if error + F_ERROR(file, -1); // abort if error // Copy 1024-byte chunks up until the desired filesize < 1024 bytes away while (size > 0x400) { size -= fwrite(buffer, 0x400, size/0x400, file); @@ -148,5 +169,6 @@ int fcreate(size_t size, char* filename) { if (size > 0) { size -= fwrite(buffer, size, 1, file); } + // Return the number of unwritten bytes, if any return size; }