diff options
Diffstat (limited to 'lib/libalpm')
| -rw-r--r-- | lib/libalpm/util.c | 38 | 
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 | 
