From 66b2c35aa2466aaba421f8cd13502eeddd3bce1a Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 12:42:16 +0100
Subject: [PATCH 01/15] bee-dep: add regular_file_exists() helper function

regular_file_exists(filename)

 returns:
   1 : file exists and is a regular file
   0 : file is not a regular file or does not exist
       check errno for
          EEXIST : file exists but is not a regular file
          ENOENT : file does not exist
   -1 : error; check errno see(stat(2))
---
 src/bee-dep.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 65f53a0..2a95f09 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -41,6 +41,9 @@
 
 #define CACHENAME "index.db"
 
+#define likely(x)       __builtin_expect(!!(x), 1)
+#define unlikely(x)     __builtin_expect(!!(x), 0)
+
 static void usage(void)
 {
      printf("bee-dep v%s 2011\n"
@@ -192,6 +195,39 @@ int mkdirp(char *path, mode_t mode)
   return 0;
 }
 
+/*
+ * checks if given filename is a regular file
+ * returns:
+ *
+ *   1 : file exists and is a regular file
+ *   0 : file is not a regular file or does not exist
+ *       check errno for
+ *          EEXIST : file exists but is not a regular file
+ *          ENOENT : file does not exist
+ *  -1 : error; check errno see(stat(2))
+ */
+int regular_file_exists(char *fname)
+{
+    struct stat st;
+    int ret;
+
+    ret = stat(fname, &st);
+
+    if(likely(ret == 0)) {
+        if(likely(S_ISREG(st.st_mode)))
+            return 1;
+
+        /* set errno for file exists but is not a regular file */
+        errno = EEXIST;
+        return 0;
+    }
+
+    if (likely(errno == ENOENT))
+        return 0;
+
+    return -1;
+}
+
 int main(int argc, char *argv[])
 {
     int c, help, rebuild, update, remove, print, options;

From 83f6eedf68d6a7a1baff248a79e6991c2e7a53b4 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 13:30:19 +0100
Subject: [PATCH 02/15] bee-dep: use regular_file_exists() to check for
 cachefile

---
 src/bee-dep.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 2a95f09..ff13b38 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -231,6 +231,7 @@ int regular_file_exists(char *fname)
 int main(int argc, char *argv[])
 {
     int c, help, rebuild, update, remove, print, options;
+    int ret;
     char found;
     char cachefile[PATH_MAX + 1], path[PATH_MAX + 1], tmp[PATH_MAX + 1];
     char *bee_metadir, *bee_cachedir, *pkgname;
@@ -313,8 +314,6 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    found = (stat(cachefile, &st) != -1 && S_ISREG(st.st_mode));
-
     graph = hash_new();
 
     if (rebuild) {
@@ -331,7 +330,12 @@ int main(int argc, char *argv[])
         cleanup_and_exit(graph, cache, EXIT_SUCCESS);
     }
 
-    if (found) {
+    ret = regular_file_exists(cachefile);
+
+    if (ret == -1 || (ret == 0 && errno != ENOENT)) {
+        perror("bee-dep: regular_file_exists(cachefile)");
+        cleanup_and_exit(graph, cache, EXIT_FAILURE);
+    } else if (ret) {
         cache = open_and_lock(cachefile, "r");
 
         if (load_cache(graph, cache) == EXIT_FAILURE)

From 410539462af77f8aa2c3678ac6f96cf03f7c0cad Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 14:20:57 +0100
Subject: [PATCH 03/15] bee-dep: do not exit in hash_new()

---
 src/bee-dep.c | 5 ++++-
 src/hash.c    | 6 ++----
 2 files changed, 6 insertions(+), 5 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index ff13b38..dfb4955 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -314,7 +314,10 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    graph = hash_new();
+    if(!(graph = hash_new())) {
+        perror("bee-dep: hash_new");
+        exit(EXIT_FAILURE);
+    }
 
     if (rebuild) {
         if (init_cache(graph, bee_metadir, tmp) == EXIT_FAILURE)
diff --git a/src/hash.c b/src/hash.c
index f3b137e..54101cd 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -34,10 +34,8 @@ struct hash *hash_new(void)
     struct hash *h;
     unsigned long i;
 
-    if ((h = calloc(1, sizeof(struct hash))) == NULL) {
-        perror("bee-dep: hash_new: calloc");
-        exit(EXIT_FAILURE);
-    }
+    if (!(h = calloc(1, sizeof(struct hash))))
+        return NULL;
 
     for (i = 0; i < TBLSIZE; i++)
         h->tbl[i] = tree_new();

From 59f8e57d01f15502567e03834a27a69f08525935 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 14:45:51 +0100
Subject: [PATCH 04/15] bee-dep: use asprintf in main()

---
 src/bee-dep.c | 116 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 92 insertions(+), 24 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index dfb4955..5c5e8c7 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -24,6 +24,8 @@
 ** along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
+#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <sys/stat.h>
@@ -232,8 +234,10 @@ int main(int argc, char *argv[])
 {
     int c, help, rebuild, update, remove, print, options;
     int ret;
+    char *cachefile = NULL;
+    char *tmpfile   = NULL;
+    char *depfile   = NULL;
     char found;
-    char cachefile[PATH_MAX + 1], path[PATH_MAX + 1], tmp[PATH_MAX + 1];
     char *bee_metadir, *bee_cachedir, *pkgname;
     struct hash *graph;
     struct stat st;
@@ -303,12 +307,6 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    if (sprintf(cachefile, "%s/%s", bee_cachedir, CACHENAME) < 0
-        || sprintf(tmp, "%s/index.tmp", bee_cachedir) < 0) {
-        perror("bee-dep: sprintf");
-        exit(EXIT_FAILURE);
-    }
-
     if (mkdirp(bee_cachedir, 0755) == -1) {
         perror("bee-dep: mkdirp");
         exit(EXIT_FAILURE);
@@ -319,17 +317,35 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
+    if(asprintf(&cachefile, "%s/%s", bee_cachedir, CACHENAME) == -1) {
+        perror("bee-dep: asprintf");
+        exit(EXIT_FAILURE);
+    }
+
+    if(asprintf(&tmpfile, "%s/index.tmp", bee_cachedir) == -1) {
+        perror("bee-dep: asprintf");
+        free(cachefile);
+        exit(EXIT_FAILURE);
+    }
+
     if (rebuild) {
-        if (init_cache(graph, bee_metadir, tmp) == EXIT_FAILURE)
+        if (init_cache(graph, bee_metadir, tmpfile) == EXIT_FAILURE) {
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, NULL, EXIT_FAILURE);
+        }
 
         cache = open_and_lock(cachefile, "w");
 
-        if (rename(tmp, cachefile) == -1) {
+        if (rename(tmpfile, cachefile) == -1) {
             perror("bee-dep: rename");
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
+        free(cachefile);
+        free(tmpfile);
         cleanup_and_exit(graph, cache, EXIT_SUCCESS);
     }
 
@@ -337,20 +353,30 @@ int main(int argc, char *argv[])
 
     if (ret == -1 || (ret == 0 && errno != ENOENT)) {
         perror("bee-dep: regular_file_exists(cachefile)");
+        free(cachefile);
+        free(tmpfile);
         cleanup_and_exit(graph, cache, EXIT_FAILURE);
     } else if (ret) {
         cache = open_and_lock(cachefile, "r");
 
-        if (load_cache(graph, cache) == EXIT_FAILURE)
+        if (load_cache(graph, cache) == EXIT_FAILURE) {
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
+        }
     } else {
-        if (init_cache(graph, bee_metadir, tmp) == EXIT_FAILURE)
+        if (init_cache(graph, bee_metadir, tmpfile) == EXIT_FAILURE) {
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, NULL, EXIT_FAILURE);
+        }
 
         cache = open_and_lock(cachefile, "w");
 
-        if (rename(tmp, cachefile) == -1) {
+        if (rename(tmpfile, cachefile) == -1) {
             perror("bee-dep: rename");
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
     }
@@ -358,71 +384,113 @@ int main(int argc, char *argv[])
     if (update) {
         found = !!hash_search(graph, pkgname);
 
-        if (sprintf(path, "%s/%s/DEPENDENCIES",
-                    bee_metadir, pkgname) < 0) {
-            perror("bee-dep: sprintf");
+        if (asprintf(&depfile, "%s/%s/DEPENDENCIES",
+                    bee_metadir, pkgname) == -1) {
+            perror("bee-dep: asprintf");
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
-        if (stat(path, &st) != -1) {
+        if (stat(depfile, &st) != -1) {
             if (found) {
                 fprintf(stderr, "bee-dep: package '%s' is "
                         "already in the cache\n", pkgname);
+                free(cachefile);
+                free(tmpfile);
+                free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_SUCCESS);
             }
 
-            if (graph_insert_nodes(graph, path) == EXIT_FAILURE)
+            if (graph_insert_nodes(graph, depfile) == EXIT_FAILURE) {
+                free(cachefile);
+                free(tmpfile);
+                free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
+            }
         } else {
             if (!found) {
                 fprintf(stderr,
                         "bee-dep: unknown package '%s'\n", pkgname);
+                free(cachefile);
+                free(tmpfile);
+                free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
             }
 
             if ((h = hash_search(graph, pkgname)) == NULL || !IS_PKG(h)) {
                 fprintf(stderr, "bee-dep: unknown package '%s'\n", pkgname);
+                free(cachefile);
+                free(tmpfile);
+                free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
             }
 
             if (remove_package(graph, pkgname) == EXIT_FAILURE)
+                free(cachefile);
+                free(tmpfile);
+                free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
-        if (save_cache(graph, tmp) == EXIT_FAILURE)
+        if (save_cache(graph, tmpfile) == EXIT_FAILURE) {
+            free(cachefile);
+            free(tmpfile);
+            free(depfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
-
-        if (rename(tmp, cachefile) == -1) {
+        }
+        if (rename(tmpfile, cachefile) == -1) {
             perror("bee-dep: rename");
+            free(cachefile);
+            free(tmpfile);
+            free(depfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
+        free(cachefile);
+        free(tmpfile);
+        free(depfile);
         cleanup_and_exit(graph, cache, EXIT_SUCCESS);
     }
 
     if ((h = hash_search(graph, pkgname)) == NULL || !IS_PKG(h)) {
         fprintf(stderr, "bee-dep: unknown package '%s'\n", pkgname);
+        free(cachefile);
+        free(tmpfile);
         cleanup_and_exit(graph, cache, EXIT_FAILURE);
     }
 
     if (print) {
-        if (print_removable(graph, pkgname) == EXIT_FAILURE)
+        if (print_removable(graph, pkgname) == EXIT_FAILURE) {
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
+        }
     }
 
     if (remove) {
-        if (remove_package(graph, pkgname) == EXIT_FAILURE)
+        if (remove_package(graph, pkgname) == EXIT_FAILURE) {
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
+        }
 
-        if (save_cache(graph, tmp) == EXIT_FAILURE)
+        if (save_cache(graph, tmpfile) == EXIT_FAILURE) {
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
+        }
 
-        if (rename(tmp, cachefile) == -1) {
+        if (rename(tmpfile, cachefile) == -1) {
             perror("bee-dep: rename");
+            free(cachefile);
+            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
     }
 
+    free(cachefile);
+    free(tmpfile);
     cleanup_and_exit(graph, cache, EXIT_SUCCESS);
 
     return EXIT_FAILURE;

From 7a1c800b3b3d53dc880decd40b12413556025dfc Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 14:52:08 +0100
Subject: [PATCH 05/15] bee-dep: save_cache(), init_cache() return 1 on success
 and 0 on failure

---
 src/bee-dep.c | 16 ++++++++--------
 src/graph.c   |  8 ++++----
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 5c5e8c7..c172e62 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -72,7 +72,7 @@ int init_cache(struct hash *graph, char *bee_metadir, char *filename)
 
     if ((pkg_cnt = scandir(bee_metadir, &package, 0, alphasort)) < 0) {
         perror("bee-dep: create_cache: scandir");
-        return EXIT_FAILURE;
+        return 0;
     }
 
     /* skip . and .. */
@@ -84,7 +84,7 @@ int init_cache(struct hash *graph, char *bee_metadir, char *filename)
 
         if (stat(path, &st) == -1) {
             perror("bee-dep: create_cache: stat");
-            return EXIT_FAILURE;
+            return 0;
         }
 
         if (S_ISDIR(st.st_mode)) {
@@ -95,11 +95,11 @@ int init_cache(struct hash *graph, char *bee_metadir, char *filename)
                         "bee-dep: create_cache: missing "
                         "DEPENDENCIES file for package '%s'\n",
                         package[i]->d_name);
-                return EXIT_FAILURE;
+                return 0;
             }
 
             if (graph_insert_nodes(graph, path) == EXIT_FAILURE)
-                return EXIT_FAILURE;
+                return 0;
         }
 
         free(package[i]);
@@ -329,7 +329,7 @@ int main(int argc, char *argv[])
     }
 
     if (rebuild) {
-        if (init_cache(graph, bee_metadir, tmpfile) == EXIT_FAILURE) {
+        if (!init_cache(graph, bee_metadir, tmpfile)) {
             free(cachefile);
             free(tmpfile);
             cleanup_and_exit(graph, NULL, EXIT_FAILURE);
@@ -365,7 +365,7 @@ int main(int argc, char *argv[])
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
     } else {
-        if (init_cache(graph, bee_metadir, tmpfile) == EXIT_FAILURE) {
+        if (!init_cache(graph, bee_metadir, tmpfile)) {
             free(cachefile);
             free(tmpfile);
             cleanup_and_exit(graph, NULL, EXIT_FAILURE);
@@ -433,7 +433,7 @@ int main(int argc, char *argv[])
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
-        if (save_cache(graph, tmpfile) == EXIT_FAILURE) {
+        if (!save_cache(graph, tmpfile)) {
             free(cachefile);
             free(tmpfile);
             free(depfile);
@@ -475,7 +475,7 @@ int main(int argc, char *argv[])
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
-        if (save_cache(graph, tmpfile) == EXIT_FAILURE) {
+        if (!save_cache(graph, tmpfile)) {
             free(cachefile);
             free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
diff --git a/src/graph.c b/src/graph.c
index 0643d26..82e40f1 100644
--- a/src/graph.c
+++ b/src/graph.c
@@ -504,13 +504,13 @@ int save_cache(struct hash *hash, char *path)
 
     if ((file = fopen(path, "w")) == NULL) {
         perror("bee-dep: save_cache: fopen");
-        return EXIT_FAILURE;
+        return 0;
     }
 
     index = 0;
 
     if (hash->cnt == 0)
-        return EXIT_SUCCESS;
+        return 1;
 
     for (i = 0; i < TBLSIZE; i++) {
         if (hash->tbl[i]->root) {
@@ -555,10 +555,10 @@ int save_cache(struct hash *hash, char *path)
 
     if (fclose(file) == EOF) {
         perror("bee-dep: save_cache: fclose");
-        return EXIT_FAILURE;
+        return 0;
     }
 
-    return EXIT_SUCCESS;
+    return 1;
 }
 
 int load_cache(struct hash *hash, FILE *file)

From f3880fb6b2a112d1a039785514bec84dd668d15f Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 14:54:21 +0100
Subject: [PATCH 06/15] bee-dep: rebuild: don't lock file which gets renamed in
 next step

---
 src/bee-dep.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index c172e62..0cbf967 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -241,7 +241,7 @@ int main(int argc, char *argv[])
     char *bee_metadir, *bee_cachedir, *pkgname;
     struct hash *graph;
     struct stat st;
-    FILE *cache;
+    FILE *cache = NULL;
     struct node *h;
 
     struct option long_options[] = {
@@ -335,8 +335,6 @@ int main(int argc, char *argv[])
             cleanup_and_exit(graph, NULL, EXIT_FAILURE);
         }
 
-        cache = open_and_lock(cachefile, "w");
-
         if (rename(tmpfile, cachefile) == -1) {
             perror("bee-dep: rename");
             free(cachefile);

From de403ee5f9f86cee62341389c1a53a977901ccf9 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 15:39:00 +0100
Subject: [PATCH 07/15] bee-dep: cleanup rebuild: move tmpfile logic to
 save_cache()

init_cache() now save_cache()s the cachefile under a temporary name and renames it.
---
 src/bee-dep.c | 75 +++++++++------------------------------------------
 src/graph.c   | 36 ++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 64 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 0cbf967..47a6ac1 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -70,6 +70,8 @@ int init_cache(struct hash *graph, char *bee_metadir, char *filename)
     char path[PATH_MAX + 1];
     struct stat st;
 
+    /* TODO: need to handle all kinds of race conditions here 8) */
+
     if ((pkg_cnt = scandir(bee_metadir, &package, 0, alphasort)) < 0) {
         perror("bee-dep: create_cache: scandir");
         return 0;
@@ -235,7 +237,6 @@ int main(int argc, char *argv[])
     int c, help, rebuild, update, remove, print, options;
     int ret;
     char *cachefile = NULL;
-    char *tmpfile   = NULL;
     char *depfile   = NULL;
     char found;
     char *bee_metadir, *bee_cachedir, *pkgname;
@@ -322,29 +323,15 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    if(asprintf(&tmpfile, "%s/index.tmp", bee_cachedir) == -1) {
-        perror("bee-dep: asprintf");
-        free(cachefile);
-        exit(EXIT_FAILURE);
-    }
-
     if (rebuild) {
-        if (!init_cache(graph, bee_metadir, tmpfile)) {
-            free(cachefile);
-            free(tmpfile);
-            cleanup_and_exit(graph, NULL, EXIT_FAILURE);
-        }
+        int ret = EXIT_SUCCESS;
 
-        if (rename(tmpfile, cachefile) == -1) {
-            perror("bee-dep: rename");
-            free(cachefile);
-            free(tmpfile);
-            cleanup_and_exit(graph, cache, EXIT_FAILURE);
-        }
+        if (!init_cache(graph, bee_metadir, cachefile))
+            ret = EXIT_FAILURE;
 
         free(cachefile);
-        free(tmpfile);
-        cleanup_and_exit(graph, cache, EXIT_SUCCESS);
+        hash_free(graph);
+        return ret;
     }
 
     ret = regular_file_exists(cachefile);
@@ -352,30 +339,19 @@ int main(int argc, char *argv[])
     if (ret == -1 || (ret == 0 && errno != ENOENT)) {
         perror("bee-dep: regular_file_exists(cachefile)");
         free(cachefile);
-        free(tmpfile);
         cleanup_and_exit(graph, cache, EXIT_FAILURE);
     } else if (ret) {
         cache = open_and_lock(cachefile, "r");
 
         if (load_cache(graph, cache) == EXIT_FAILURE) {
             free(cachefile);
-            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
     } else {
-        if (!init_cache(graph, bee_metadir, tmpfile)) {
+        if (!init_cache(graph, bee_metadir, cachefile)) {
             free(cachefile);
-            free(tmpfile);
-            cleanup_and_exit(graph, NULL, EXIT_FAILURE);
-        }
-
-        cache = open_and_lock(cachefile, "w");
-
-        if (rename(tmpfile, cachefile) == -1) {
-            perror("bee-dep: rename");
-            free(cachefile);
-            free(tmpfile);
-            cleanup_and_exit(graph, cache, EXIT_FAILURE);
+            hash_free(graph);
+            return EXIT_FAILURE;
         }
     }
 
@@ -386,7 +362,6 @@ int main(int argc, char *argv[])
                     bee_metadir, pkgname) == -1) {
             perror("bee-dep: asprintf");
             free(cachefile);
-            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
@@ -395,14 +370,12 @@ int main(int argc, char *argv[])
                 fprintf(stderr, "bee-dep: package '%s' is "
                         "already in the cache\n", pkgname);
                 free(cachefile);
-                free(tmpfile);
                 free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_SUCCESS);
             }
 
             if (graph_insert_nodes(graph, depfile) == EXIT_FAILURE) {
                 free(cachefile);
-                free(tmpfile);
                 free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
             }
@@ -411,7 +384,6 @@ int main(int argc, char *argv[])
                 fprintf(stderr,
                         "bee-dep: unknown package '%s'\n", pkgname);
                 free(cachefile);
-                free(tmpfile);
                 free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
             }
@@ -419,34 +391,23 @@ int main(int argc, char *argv[])
             if ((h = hash_search(graph, pkgname)) == NULL || !IS_PKG(h)) {
                 fprintf(stderr, "bee-dep: unknown package '%s'\n", pkgname);
                 free(cachefile);
-                free(tmpfile);
                 free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
             }
 
             if (remove_package(graph, pkgname) == EXIT_FAILURE)
                 free(cachefile);
-                free(tmpfile);
                 free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
-        if (!save_cache(graph, tmpfile)) {
-            free(cachefile);
-            free(tmpfile);
-            free(depfile);
-            cleanup_and_exit(graph, cache, EXIT_FAILURE);
-        }
-        if (rename(tmpfile, cachefile) == -1) {
-            perror("bee-dep: rename");
+        if (!save_cache(graph, cachefile)) {
             free(cachefile);
-            free(tmpfile);
             free(depfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
         free(cachefile);
-        free(tmpfile);
         free(depfile);
         cleanup_and_exit(graph, cache, EXIT_SUCCESS);
     }
@@ -454,14 +415,12 @@ int main(int argc, char *argv[])
     if ((h = hash_search(graph, pkgname)) == NULL || !IS_PKG(h)) {
         fprintf(stderr, "bee-dep: unknown package '%s'\n", pkgname);
         free(cachefile);
-        free(tmpfile);
         cleanup_and_exit(graph, cache, EXIT_FAILURE);
     }
 
     if (print) {
         if (print_removable(graph, pkgname) == EXIT_FAILURE) {
             free(cachefile);
-            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
     }
@@ -469,26 +428,16 @@ int main(int argc, char *argv[])
     if (remove) {
         if (remove_package(graph, pkgname) == EXIT_FAILURE) {
             free(cachefile);
-            free(tmpfile);
-            cleanup_and_exit(graph, cache, EXIT_FAILURE);
-        }
-
-        if (!save_cache(graph, tmpfile)) {
-            free(cachefile);
-            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
 
-        if (rename(tmpfile, cachefile) == -1) {
-            perror("bee-dep: rename");
+        if (!save_cache(graph, cachefile)) {
             free(cachefile);
-            free(tmpfile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
     }
 
     free(cachefile);
-    free(tmpfile);
     cleanup_and_exit(graph, cache, EXIT_SUCCESS);
 
     return EXIT_FAILURE;
diff --git a/src/graph.c b/src/graph.c
index 82e40f1..500c1d2 100644
--- a/src/graph.c
+++ b/src/graph.c
@@ -24,11 +24,14 @@
 ** along with this program; if not, see <http://www.gnu.org/licenses/>.
 */
 
+#define _GNU_SOURCE
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <limits.h>
 #include <string.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
 #include "graph.h"
 
@@ -495,13 +498,15 @@ int print_removable(struct hash *hash, char *remove)
     return EXIT_SUCCESS;
 }
 
-int save_cache(struct hash *hash, char *path)
+static int save_cache_to_file(struct hash *hash, char *path)
 {
     int i;
     unsigned long index;
     struct tree_node *s, *t;
     FILE *file;
 
+    /* TODO: need to handle all kinds of race conditions here 8) */
+
     if ((file = fopen(path, "w")) == NULL) {
         perror("bee-dep: save_cache: fopen");
         return 0;
@@ -561,6 +566,35 @@ int save_cache(struct hash *hash, char *path)
     return 1;
 }
 
+int save_cache(struct hash *hash, char *fname)
+{
+    char *tmpname;
+    int ret = 1;
+
+    /* TODO: need to handle all kinds of race conditions here 8) */
+
+    if(asprintf(&tmpname, "%s.tmp", fname) == -1) {
+        perror("bee-dep: save_cache: asprintf");
+        return 0;
+    }
+
+    if(save_cache_to_file(hash, tmpname)) {
+        if(rename(tmpname, fname) == -1) {
+            perror("bee-dep: save_cache: rename");
+            if(unlink(tmpname) == -1) {
+                perror("bee-dep: save_cache: unlink");
+            }
+            ret = 0;
+        }
+    } else {
+        ret = 0;
+    }
+
+    free(tmpname);
+
+    return ret;
+}
+
 int load_cache(struct hash *hash, FILE *file)
 {
     char line[LINE_MAX],

From f6368458db7787ae73e7fae5d14d816505cff5b8 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 15:52:02 +0100
Subject: [PATCH 08/15] bee-dep: load_cache() return 1 on success and 0 on
 failure

---
 src/bee-dep.c |  2 +-
 src/graph.c   | 10 +++++-----
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 47a6ac1..5b4932c 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -343,7 +343,7 @@ int main(int argc, char *argv[])
     } else if (ret) {
         cache = open_and_lock(cachefile, "r");
 
-        if (load_cache(graph, cache) == EXIT_FAILURE) {
+        if (!load_cache(graph, cache)) {
             free(cachefile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
diff --git a/src/graph.c b/src/graph.c
index 500c1d2..30b04ff 100644
--- a/src/graph.c
+++ b/src/graph.c
@@ -616,7 +616,7 @@ int load_cache(struct hash *hash, FILE *file)
         if (sscanf(line, "%s %s", a, b) == EOF) {
             fprintf(stderr, "beedep: load_cache: "
                             "cache file is broken (line %d)\n", line_cnt);
-            return EXIT_FAILURE;
+            return 0;
         }
 
         hash_insert(hash, node_new(a, b));
@@ -628,7 +628,7 @@ int load_cache(struct hash *hash, FILE *file)
         if (sscanf(line, "%s %s %c", a, b, &c) == EOF) {
             fprintf(stderr, "beedep: load_cache: "
                             "cache file is broken (line %d)\n", line_cnt);
-            return EXIT_FAILURE;
+            return 0;
         }
 
         k = hash_search(hash, a);
@@ -637,7 +637,7 @@ int load_cache(struct hash *hash, FILE *file)
         if (!k || !l) {
             fprintf(stderr, "beedep: load_cache: "
                             "cache file is broken (line %d)\n", line_cnt);
-            return EXIT_FAILURE;
+            return 0;
         }
 
         if (c == 'n') {
@@ -649,11 +649,11 @@ int load_cache(struct hash *hash, FILE *file)
         } else {
             fprintf(stderr, "beedep: load_cache: "
                             "cache file is broken (line %d)\n", line_cnt);
-            return EXIT_FAILURE;
+            return 0;
         }
     }
 
-    return EXIT_SUCCESS;
+    return 1;
 }
 
 unsigned long count_providedby(struct hash *hash, char *count)

From 9f926c7b13deb5ca98ca49c6323485ddcd0ca667 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 16:00:45 +0100
Subject: [PATCH 09/15] bee-dep: new ENV handling

---
 src/bee-dep.c | 66 ++++++++++++++++++++++++++++++++-------------------
 1 file changed, 42 insertions(+), 24 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 5b4932c..59e4a65 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -46,6 +46,39 @@
 #define likely(x)       __builtin_expect(!!(x), 1)
 #define unlikely(x)     __builtin_expect(!!(x), 0)
 
+#define BEE_METADIR  env_bee_metadir()
+#define BEE_CACHEDIR env_bee_cachedir()
+
+static char *env_bee_metadir(void)
+{
+    static char *value = NULL;
+
+    if(value)
+        return value;
+
+    value = getenv("BEE_METADIR");
+
+    if(!value)
+        value = "";
+
+    return value;
+}
+
+static char *env_bee_cachedir(void)
+{
+    static char *value = NULL;
+
+    if(value)
+        return value;
+
+    value = getenv("BEE_CACHEDIR");
+
+    if(!value)
+        value = "";
+
+    return value;
+}
+
 static void usage(void)
 {
      printf("bee-dep v%s 2011\n"
@@ -63,7 +96,7 @@ static void usage(void)
             getenv("BEE_VERSION"));
 }
 
-int init_cache(struct hash *graph, char *bee_metadir, char *filename)
+int init_cache(struct hash *graph, char *filename)
 {
     struct dirent **package;
     int i, pkg_cnt;
@@ -72,7 +105,7 @@ int init_cache(struct hash *graph, char *bee_metadir, char *filename)
 
     /* TODO: need to handle all kinds of race conditions here 8) */
 
-    if ((pkg_cnt = scandir(bee_metadir, &package, 0, alphasort)) < 0) {
+    if ((pkg_cnt = scandir(BEE_METADIR, &package, 0, alphasort)) < 0) {
         perror("bee-dep: create_cache: scandir");
         return 0;
     }
@@ -82,7 +115,7 @@ int init_cache(struct hash *graph, char *bee_metadir, char *filename)
     free(package[1]);
 
     for (i = 2; i < pkg_cnt; i++) {
-        sprintf(path, "%s/%s", bee_metadir, package[i]->d_name);
+        sprintf(path, "%s/%s", BEE_METADIR, package[i]->d_name);
 
         if (stat(path, &st) == -1) {
             perror("bee-dep: create_cache: stat");
@@ -136,19 +169,6 @@ void cleanup_and_exit(struct hash *h, FILE *f, int r)
     exit(r);
 }
 
-void get_bee_variables(char **bee_cachedir, char **bee_metadir)
-{
-    if (!(*bee_cachedir = getenv("BEE_CACHEDIR"))) {
-        fprintf(stderr, "BEE-ERROR: BEE_CACHEDIR not set\n");
-        exit(EXIT_FAILURE);
-    }
-
-    if (!(*bee_metadir = getenv("BEE_METADIR"))) {
-        fprintf(stderr, "BEE-ERROR: BEE_METADIR not set\n");
-        exit(EXIT_FAILURE);
-    }
-}
-
 static FILE *open_and_lock(char *filename, char *mode)
 {
     FILE *f;
@@ -239,7 +259,7 @@ int main(int argc, char *argv[])
     char *cachefile = NULL;
     char *depfile   = NULL;
     char found;
-    char *bee_metadir, *bee_cachedir, *pkgname;
+    char *pkgname;
     struct hash *graph;
     struct stat st;
     FILE *cache = NULL;
@@ -259,8 +279,6 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    get_bee_variables(&bee_cachedir, &bee_metadir);
-
     if (argc == 1) {
         usage();
         exit(EXIT_FAILURE);
@@ -308,7 +326,7 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    if (mkdirp(bee_cachedir, 0755) == -1) {
+    if (mkdirp(BEE_CACHEDIR, 0755) == -1) {
         perror("bee-dep: mkdirp");
         exit(EXIT_FAILURE);
     }
@@ -318,7 +336,7 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    if(asprintf(&cachefile, "%s/%s", bee_cachedir, CACHENAME) == -1) {
+    if(asprintf(&cachefile, "%s/%s", BEE_CACHEDIR, CACHENAME) == -1) {
         perror("bee-dep: asprintf");
         exit(EXIT_FAILURE);
     }
@@ -326,7 +344,7 @@ int main(int argc, char *argv[])
     if (rebuild) {
         int ret = EXIT_SUCCESS;
 
-        if (!init_cache(graph, bee_metadir, cachefile))
+        if (!init_cache(graph, cachefile))
             ret = EXIT_FAILURE;
 
         free(cachefile);
@@ -348,7 +366,7 @@ int main(int argc, char *argv[])
             cleanup_and_exit(graph, cache, EXIT_FAILURE);
         }
     } else {
-        if (!init_cache(graph, bee_metadir, cachefile)) {
+        if (!init_cache(graph, cachefile)) {
             free(cachefile);
             hash_free(graph);
             return EXIT_FAILURE;
@@ -359,7 +377,7 @@ int main(int argc, char *argv[])
         found = !!hash_search(graph, pkgname);
 
         if (asprintf(&depfile, "%s/%s/DEPENDENCIES",
-                    bee_metadir, pkgname) == -1) {
+                    BEE_METADIR, pkgname) == -1) {
             perror("bee-dep: asprintf");
             free(cachefile);
             cleanup_and_exit(graph, cache, EXIT_FAILURE);

From 22bc2852edb527ba602320da0863e9f94e39d9d8 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 16:21:09 +0100
Subject: [PATCH 10/15] bee-dep: graph_insert_nodes() return 1 on success and 0
 on failure

---
 src/bee-dep.c |  4 ++--
 src/graph.c   | 21 +++++++++------------
 2 files changed, 11 insertions(+), 14 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 59e4a65..34c5902 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -133,7 +133,7 @@ int init_cache(struct hash *graph, char *filename)
                 return 0;
             }
 
-            if (graph_insert_nodes(graph, path) == EXIT_FAILURE)
+            if (!graph_insert_nodes(graph, path))
                 return 0;
         }
 
@@ -392,7 +392,7 @@ int main(int argc, char *argv[])
                 cleanup_and_exit(graph, cache, EXIT_SUCCESS);
             }
 
-            if (graph_insert_nodes(graph, depfile) == EXIT_FAILURE) {
+            if (!graph_insert_nodes(graph, depfile)) {
                 free(cachefile);
                 free(depfile);
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
diff --git a/src/graph.c b/src/graph.c
index 30b04ff..ca8472e 100644
--- a/src/graph.c
+++ b/src/graph.c
@@ -100,7 +100,7 @@ int graph_insert_nodes(struct hash *hash, char *filename)
 
     if ((file = fopen(filename, "r")) == NULL) {
         perror("bee-dep: graph_insert_nodes: fopen");
-        return EXIT_FAILURE;
+        return 0;
     }
 
     line_cnt = type_flag = u = 0;
@@ -137,7 +137,7 @@ int graph_insert_nodes(struct hash *hash, char *filename)
                 fprintf(stderr,
                         "bee-dep: %s: error at line %d: missing bracket\n",
                         filename, line_cnt);
-                return EXIT_FAILURE;
+                return 0;
             }
 
             *p = '\0';
@@ -146,7 +146,7 @@ int graph_insert_nodes(struct hash *hash, char *filename)
                 fprintf(stderr,
                         "bee-dep: %s: error at line %d: empty node name\n",
                         filename, line_cnt);
-                return EXIT_FAILURE;
+                return 0;
             }
 
             if (IS_FILE(s)) {
@@ -155,7 +155,7 @@ int graph_insert_nodes(struct hash *hash, char *filename)
                             "bee-dep: %s: error at line %d: "
                             "dont know to which package"
                             "\"%s\" belongs to\n", filename, line_cnt, s);
-                    return EXIT_FAILURE;
+                    return 0;
                 }
 
                 sprintf(nodename, "%s%s", pkgname, s);
@@ -192,7 +192,7 @@ int graph_insert_nodes(struct hash *hash, char *filename)
             fprintf(stderr,
                     "bee-dep: %s: error at line %d: missing value "
                     "for property \"%s\"\n", filename, line_cnt, prop);
-            return EXIT_FAILURE;
+            return 0;
         }
 
         memset(value, '\0', LINE_MAX);
@@ -204,7 +204,7 @@ int graph_insert_nodes(struct hash *hash, char *filename)
                         "bee-dep: %s: error at line %d: "
                         "ambiguous type \"%s\"\n",
                         filename, line_cnt, value);
-                return EXIT_FAILURE;
+                return 0;
             }
 
             node_set_type(n, value);
@@ -248,18 +248,15 @@ int graph_insert_nodes(struct hash *hash, char *filename)
 
     if (fclose(file) == EOF) {
         perror("bee-dep: graph_insert_nodes: fclose");
-        return EXIT_FAILURE;
+        return 0;
     }
 
     if(line_cnt == 0) {
        fprintf(stderr, "bee-dep: error: file '%s' is empty\n", filename);
-       /* WTF: why can't we return 0 here for errors ??? */
-       return EXIT_FAILURE;
+       return 0;
     }
 
-    /* we dont't want to exit on success ??? or do we? i don't get it! */
-    /* but works for me now.. 8) */
-    return EXIT_SUCCESS;
+    return 1;
 }
 
 void search_dependencies(struct hash *hash, struct node *n, struct tree *d)

From ecffb716985e32d87cefec38ca52ca8c388d26a6 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 16:32:14 +0100
Subject: [PATCH 11/15] bee-dep: fix a minor memory leak

---
 src/bee-dep.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 34c5902..2b126f6 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -338,6 +338,7 @@ int main(int argc, char *argv[])
 
     if(asprintf(&cachefile, "%s/%s", BEE_CACHEDIR, CACHENAME) == -1) {
         perror("bee-dep: asprintf");
+        hash_free(graph);
         exit(EXIT_FAILURE);
     }
 

From feb20abf8a88a269bb9c0cb4a91b63764cc4f6ef Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 16:39:09 +0100
Subject: [PATCH 12/15] bee-dep: init_cache() cleanup

---
 src/bee-dep.c | 41 +++++++++++++++++------------------------
 1 file changed, 17 insertions(+), 24 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 2b126f6..d145eef 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -96,12 +96,26 @@ static void usage(void)
             getenv("BEE_VERSION"));
 }
 
+int pkg_to_graph(struct hash *graph, char *pkgname)
+{
+    int ret = 1;
+    char *fname;
+
+    if(asprintf(&fname, "%s/%s/DEPENDENCIES", BEE_METADIR, pkgname) == -1) {
+        perror("bee-dep: pkg_to_graph: asprintf");
+        return -1;
+    }
+
+    ret = graph_insert_nodes(graph, fname);
+
+    free(fname);
+    return ret;
+}
+
 int init_cache(struct hash *graph, char *filename)
 {
     struct dirent **package;
     int i, pkg_cnt;
-    char path[PATH_MAX + 1];
-    struct stat st;
 
     /* TODO: need to handle all kinds of race conditions here 8) */
 
@@ -115,28 +129,7 @@ int init_cache(struct hash *graph, char *filename)
     free(package[1]);
 
     for (i = 2; i < pkg_cnt; i++) {
-        sprintf(path, "%s/%s", BEE_METADIR, package[i]->d_name);
-
-        if (stat(path, &st) == -1) {
-            perror("bee-dep: create_cache: stat");
-            return 0;
-        }
-
-        if (S_ISDIR(st.st_mode)) {
-            strcat(path, "/DEPENDENCIES");
-
-            if (stat(path, &st) == -1) {
-                fprintf(stderr,
-                        "bee-dep: create_cache: missing "
-                        "DEPENDENCIES file for package '%s'\n",
-                        package[i]->d_name);
-                return 0;
-            }
-
-            if (!graph_insert_nodes(graph, path))
-                return 0;
-        }
-
+        pkg_to_graph(graph, package[i]->d_name);
         free(package[i]);
     }
 

From c92df330eac84ccff24617f39503679ab6872b8b Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 16:57:55 +0100
Subject: [PATCH 13/15] bee-dep: search pkg only once in cachedb

---
 src/bee-dep.c | 13 +++++++------
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index d145eef..5ad0f28 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -256,7 +256,7 @@ int main(int argc, char *argv[])
     struct hash *graph;
     struct stat st;
     FILE *cache = NULL;
-    struct node *h;
+    struct node *hnode;
 
     struct option long_options[] = {
         {"help",            0, &help,    1},
@@ -367,9 +367,10 @@ int main(int argc, char *argv[])
         }
     }
 
-    if (update) {
-        found = !!hash_search(graph, pkgname);
+    hnode = hash_search(graph, pkgname);
+    found = hnode && IS_PKG(hnode);
 
+    if (update) {
         if (asprintf(&depfile, "%s/%s/DEPENDENCIES",
                     BEE_METADIR, pkgname) == -1) {
             perror("bee-dep: asprintf");
@@ -378,7 +379,7 @@ int main(int argc, char *argv[])
         }
 
         if (stat(depfile, &st) != -1) {
-            if (found) {
+            if (hnode) {
                 fprintf(stderr, "bee-dep: package '%s' is "
                         "already in the cache\n", pkgname);
                 free(cachefile);
@@ -400,7 +401,7 @@ int main(int argc, char *argv[])
                 cleanup_and_exit(graph, cache, EXIT_FAILURE);
             }
 
-            if ((h = hash_search(graph, pkgname)) == NULL || !IS_PKG(h)) {
+            if (!hnode || !IS_PKG(hnode)) {
                 fprintf(stderr, "bee-dep: unknown package '%s'\n", pkgname);
                 free(cachefile);
                 free(depfile);
@@ -424,7 +425,7 @@ int main(int argc, char *argv[])
         cleanup_and_exit(graph, cache, EXIT_SUCCESS);
     }
 
-    if ((h = hash_search(graph, pkgname)) == NULL || !IS_PKG(h)) {
+    if (!hnode || !IS_PKG(hnode)) {
         fprintf(stderr, "bee-dep: unknown package '%s'\n", pkgname);
         free(cachefile);
         cleanup_and_exit(graph, cache, EXIT_FAILURE);

From 7e6bc60170461e63c9a1590d614584d835d6f292 Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 17:03:37 +0100
Subject: [PATCH 14/15] bee-dep: get_cachefilename() added to create cache
 filename

---
 src/bee-dep.c | 14 ++++++++++++--
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 5ad0f28..7ffaf7b 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -245,6 +245,17 @@ int regular_file_exists(char *fname)
     return -1;
 }
 
+char *get_cachefilename(void)
+{
+    char *cfname;
+
+    if(asprintf(&cfname, "%s/%s", BEE_CACHEDIR, CACHENAME) == -1) {
+        perror("bee-dep: get_cachefilename");
+        return NULL;
+    }
+    return cfname;
+}
+
 int main(int argc, char *argv[])
 {
     int c, help, rebuild, update, remove, print, options;
@@ -329,8 +340,7 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    if(asprintf(&cachefile, "%s/%s", BEE_CACHEDIR, CACHENAME) == -1) {
-        perror("bee-dep: asprintf");
+    if(!(cachefile = get_cachefilename())) {
         hash_free(graph);
         exit(EXIT_FAILURE);
     }

From 8a20f41cee1872831e67129d0e9add0083184d2a Mon Sep 17 00:00:00 2001
From: Marius Tolzmann <tolzmann@molgen.mpg.de>
Date: Mon, 19 Dec 2011 17:14:38 +0100
Subject: [PATCH 15/15] bee-dep: rebuild logic now 100% in do_rebuild_cachedb()

---
 src/bee-dep.c | 42 ++++++++++++++++++++++++++++++++----------
 1 file changed, 32 insertions(+), 10 deletions(-)

diff --git a/src/bee-dep.c b/src/bee-dep.c
index 7ffaf7b..54d77cf 100644
--- a/src/bee-dep.c
+++ b/src/bee-dep.c
@@ -256,6 +256,32 @@ char *get_cachefilename(void)
     return cfname;
 }
 
+int do_rebuild_cachedb(void)
+{
+    char *cfname;
+    struct hash *graph;
+    int ret;
+
+    cfname = get_cachefilename();
+
+    if (!cfname)
+        return 0;
+
+    graph = hash_new();
+
+    if (!graph) {
+        free(cfname);
+        return 0;
+    }
+
+    ret = init_cache(graph, cfname);
+
+    free(cfname);
+    hash_free(graph);
+
+    return ret;
+}
+
 int main(int argc, char *argv[])
 {
     int c, help, rebuild, update, remove, print, options;
@@ -335,6 +361,12 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
+    if (rebuild) {
+        if(!do_rebuild_cachedb())
+            return EXIT_FAILURE;
+        return EXIT_SUCCESS;
+    }
+
     if(!(graph = hash_new())) {
         perror("bee-dep: hash_new");
         exit(EXIT_FAILURE);
@@ -345,16 +377,6 @@ int main(int argc, char *argv[])
         exit(EXIT_FAILURE);
     }
 
-    if (rebuild) {
-        int ret = EXIT_SUCCESS;
-
-        if (!init_cache(graph, cachefile))
-            ret = EXIT_FAILURE;
-
-        free(cachefile);
-        hash_free(graph);
-        return ret;
-    }
 
     ret = regular_file_exists(cachefile);