[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: