summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/libalpm/util.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c
index 92e99914..65b6372a 100644
--- a/lib/libalpm/util.c
+++ b/lib/libalpm/util.c
@@ -185,34 +185,38 @@ int _alpm_makepath(const char *path)
/* does the same thing as 'mkdir -p' */
int _alpm_makepath_mode(const char *path, mode_t mode)
{
- char *orig, *str, *ptr;
- char full[PATH_MAX] = "";
- mode_t oldmask;
-
- oldmask = umask(0000);
+ /* A bit of pointer hell here. Descriptions:
+ * orig - a copy of path so we can safely butcher it with strsep
+ * str - the current position in the path string (after the delimiter)
+ * ptr - the original position of str after calling strsep
+ * incr - incrementally generated path for use in stat/mkdir call
+ */
+ char *orig, *str, *ptr, *incr;
+ mode_t oldmask = umask(0000);
+ int ret = 0;
orig = strdup(path);
+ incr = calloc(strlen(orig) + 1, sizeof(char));
str = orig;
while((ptr = strsep(&str, "/"))) {
if(strlen(ptr)) {
struct stat buf;
-
- strcat(full, "/");
- strcat(full, ptr);
- if(stat(full, &buf)) {
- if(mkdir(full, mode)) {
- FREE(orig);
- umask(oldmask);
- _alpm_log(PM_LOG_ERROR, _("failed to make path '%s' : %s\n"),
- path, strerror(errno));
- return(1);
+ /* we have another path component- append the newest component to
+ * existing string and create one more level of dir structure */
+ strcat(incr, "/");
+ strcat(incr, ptr);
+ if(stat(incr, &buf)) {
+ if(mkdir(incr, mode)) {
+ ret = 1;
+ break;
}
}
}
}
- FREE(orig);
+ free(orig);
+ free(incr);
umask(oldmask);
- return(0);
+ return(ret);
}
#define CPBUFSIZE 8 * 1024