[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

[PATCH] new helper function ensure_parent_directory(path), which will be used by



From: Sean Finney <seanius@seanius.net>

---
 src/help.c |   52 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/main.h |    1 +
 2 files changed, 53 insertions(+), 0 deletions(-)

diff --git a/src/help.c b/src/help.c
index ad85800..6038836 100644
--- a/src/help.c
+++ b/src/help.c
@@ -583,6 +583,58 @@ char* quote_filename(char *buf, int size, char *s)
   return r;
 }
 
+/*
+ * ensure that all the leading components of path exist such that path
+ * could be created directly by some other means.
+ */
+void ensure_parent_directory(const char* pathname){
+  char *p=strdup(pathname);
+  struct stat stab;
+  size_t plen, plen_orig=strlen(p);
+  plen=plen_orig;
+
+  /* check for corner cases that shouldn't happen, but... */
+  if(!p) {
+    ohshite("Ñ?trdup(%s) failed", pathname);
+  }
+  if(!plen || p[plen-1] == '/') {
+    ohshit("invalid path '%s' provided", p);
+  }
+  /* strip away parts of path until a component is found that exists */
+  while(plen > 0){
+    if(stat(p, &stab) != 0){
+      if(errno==ENOTDIR) {
+        ohshite("can not leading component %s", p);
+        break;
+      } else if (errno!=ENOENT) {
+        ohshite("stat(%s) returned something funny", p);
+        break;
+      }
+    } else {
+      break;
+    }
+    while(plen > 0 && p[--plen] != '/');
+    p[plen]='\0';
+  }
+  /* create all components between p and dirname(pathname) */
+  while(plen < plen_orig){
+    p[plen]='/';
+    plen=strlen(p);
+    /* if the length is still less than the original, then we have a
+     * directory component to create. 
+     */
+    if(plen < plen_orig) {
+      printf("reconstructing %s\n", p);
+      if(mkdir(p, S_IRWXU)){
+        ohshite("mkdir(%s) failed", p);
+        break;
+      }
+    }
+  }
+  free(p);
+  return;
+}
+
 void log_action(const char *action, struct pkginfo *pkg) {
   log_message("%s %s %s %s", action, pkg->name,
 	      versiondescribe(&pkg->installed.version, vdew_nonambig),
diff --git a/src/main.h b/src/main.h
index 4322da4..5f18e1d 100644
--- a/src/main.h
+++ b/src/main.h
@@ -190,6 +190,7 @@ void ensure_package_clientdata(struct pkginfo *pkg);
 const char *pkgadminfile(struct pkginfo *pkg, const char *whichfile);
 void oldconffsetflags(const struct conffile *searchconff);
 void ensure_pathname_nonexisting(const char *pathname);
+void ensure_parent_directory(const char* pathname);
 char *quote_filename(char *buf, int size, char *s);
 int chmodsafe_unlink(const char *pathname, const char **failed);
 int chmodsafe_unlink_statted(const char *pathname, const struct stat *stab,
-- 
1.5.4.3


Reply to: