X-Git-Url: https://mattmccutchen.net/rsync/rsync.git/blobdiff_plain/fe8c0a9824bf990ae3ff692d25105dd2c9f0ebf4..b72f24c7190fde1c15662d52c8d62789bd2086ad:/util.c diff --git a/util.c b/util.c index 6470bf97..11e4a9d9 100644 --- a/util.c +++ b/util.c @@ -559,3 +559,97 @@ void *Realloc(void *p, int size) if (!p) return (void *)malloc(size); return (void *)realloc(p, size); } + + +void clean_fname(char *name) +{ + char *p; + int l; + int modified = 1; + + if (!name) return; + + while (modified) { + modified = 0; + + if ((p=strstr(name,"/./"))) { + modified = 1; + while (*p) { + p[0] = p[2]; + p++; + } + } + + if ((p=strstr(name,"//"))) { + modified = 1; + while (*p) { + p[0] = p[1]; + p++; + } + } + + if (strncmp(p=name,"./",2) == 0) { + modified = 1; + do { + p[0] = p[2]; + } while (*p++); + } + + l = strlen(p=name); + if (l > 1 && p[l-1] == '/') { + modified = 1; + p[l-1] = 0; + } + } +} + + +static char curr_dir[MAXPATHLEN]; + +/* like chdir() but can be reversed with pop_dir() if save is set. It + is also much faster as it remembers where we have been */ +char *push_dir(char *dir, int save) +{ + char *ret = curr_dir; + static int initialised; + + if (!initialised) { + initialised = 1; + getcwd(curr_dir, sizeof(curr_dir)-1); + } + + if (chdir(dir)) return NULL; + + if (save) { + ret = strdup(curr_dir); + } + + if (*dir == '/') { + strlcpy(curr_dir, dir, sizeof(curr_dir)-1); + } else { + strlcat(curr_dir,"/", sizeof(curr_dir)-1); + strlcat(curr_dir,dir, sizeof(curr_dir)-1); + } + + clean_fname(curr_dir); + + return ret; +} + +/* reverse a push_dir call */ +int pop_dir(char *dir) +{ + int ret; + + ret = chdir(dir); + if (ret) { + free(dir); + return ret; + } + + strlcpy(curr_dir, dir, sizeof(curr_dir)-1); + + free(dir); + + return 0; +}