aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/filepath.c28
-rw-r--r--src/filepath.h1
-rw-r--r--src/redo.c17
3 files changed, 31 insertions, 15 deletions
diff --git a/src/filepath.c b/src/filepath.c
index b8b217a..fd6f953 100644
--- a/src/filepath.c
+++ b/src/filepath.c
@@ -9,7 +9,7 @@
#include "dbg.h"
-/* Check if the given path is absolute */
+/* Check if the given path is absolute. */
bool is_absolute(const char* path) {
return path[0] == '/';
}
@@ -35,7 +35,7 @@ char *remove_ext(const char *str) {
return ret;
}
-/* Returns the extension of the target or the empty string if none was found */
+/* Returns the extension of the target or the empty string if none was found. */
char *take_extension(const char *target) {
assert(target);
char *temp = strrchr(target, '.');
@@ -46,7 +46,7 @@ char *take_extension(const char *target) {
}
/* Make one path relative to another i.e. some/path to some/path/a/b/c would
- yield a/b/c as result. Prints '.' if the 2 paths match */
+ yield a/b/c as result. Prints '.' if the 2 paths match. */
// TODO: nameing, requires absolute paths, doesn't MALLOC
const char *make_relative(const char *target, const char *to) {
int i;
@@ -68,7 +68,7 @@ const char *make_relative(const char *target, const char *to) {
return &to[i];
}
-/* Transforms target into a safe filename, replacing all '/' with '!' */
+/* Transforms target into a safe filename, replacing all '/' with '!'. */
char *transform_path(const char *target) {
char *ptr = (char*) target;
size_t escape = 0, i = 0;
@@ -90,7 +90,7 @@ char *transform_path(const char *target) {
return ptr;
}
-/* Sane and portable basename implementation */
+/* Sane and portable basename implementation. */
char *xbasename(const char *path) {
assert(path);
char *ptr = strrchr(path, '/');
@@ -119,3 +119,21 @@ off_t fsize(const char *fn) {
return st.st_size;
}
+
+/* Create the directory dir, while removing other 'files' with the same name. */
+void mkdirp(const char *dir) {
+ struct stat st;
+ if (stat(dir, &st)) {
+ if (errno != ENOENT)
+ fatal(ERRM_STAT, dir);
+ if (mkdir(dir, 0755))
+ fatal(ERRM_MKDIR, dir);
+ } else {
+ if (!S_ISDIR(st.st_mode)) {
+ if (remove(dir))
+ fatal(ERRM_REMOVE, dir);
+ if (mkdir(dir, 0755))
+ fatal(ERRM_MKDIR, dir);
+ }
+ }
+}
diff --git a/src/filepath.h b/src/filepath.h
index 91f4623..f7d6da9 100644
--- a/src/filepath.h
+++ b/src/filepath.h
@@ -11,5 +11,6 @@ extern char *transform_path(const char *target);
extern char *xbasename(const char *path);
extern bool fexists(const char *target);
extern off_t fsize(const char *fn);
+extern void mkdirp(const char *dir);
#endif
diff --git a/src/redo.c b/src/redo.c
index 40946dc..6cf68c3 100644
--- a/src/redo.c
+++ b/src/redo.c
@@ -11,6 +11,7 @@
#include "build.h"
#include "util.h"
#include "dbg.h"
+#include "filepath.h"
/* Returns the amount of digits a number n has in decimal. */
@@ -19,26 +20,22 @@ static inline int digits(unsigned n) {
}
int main(int argc, char *argv[]) {
- /* create .redo directory */
- if (mkdir(".redo/deps", 0744))
- if (errno != EEXIST) /* TODO: unsafe, dir could be a file or broken symlink */
- fatal(ERRM_MKDIR, ".redo/deps");
+ /* create the dependency store if it doesn't already exist */
+ mkdirp(".redo");
+ mkdirp(".redo/deps");
/* set REDO_ROOT */
char *cwd = getcwd(NULL, 0);
if (!cwd)
fatal("redo: failed to obtain cwd");
-
if (setenv("REDO_ROOT", cwd, 0))
fatal("redo: failed to setenv %s to %s", "REDO_ROOT", cwd);
-
free(cwd);
- srand(time(NULL)); /* TODO: error checking */
- unsigned magic = rand();
-
+ /* set REDO_MAGIC */
+ srand(time(NULL));
char magic_str[digits(UINT_MAX) + 1];
- sprintf(magic_str, "%u", magic);
+ sprintf(magic_str, "%u", rand());
debug("magic number: %s\n", magic_str);