aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/lib.c29
-rw-r--r--lib/lib.h1
2 files changed, 30 insertions, 0 deletions
diff --git a/lib/lib.c b/lib/lib.c
index 03c1db69..3bfee2ef 100644
--- a/lib/lib.c
+++ b/lib/lib.c
@@ -216,6 +216,7 @@ int mkpath(char *dir)
}
// Split a path into linked list of components, tracking head and tail of list.
+// Assigns head of list to *list, returns address of ->next entry to extend list
// Filters out // entries with no contents.
struct string_list **splitpath(char *path, struct string_list **list)
{
@@ -1028,6 +1029,34 @@ char *fileunderdir(char *file, char *dir)
return rc ? s2 : 0;
}
+// return (malloced) relative path to get from "from" to "to"
+char *relative_path(char *from, char *to)
+{
+ char *s, *ret = 0;
+ int i, j, k;
+
+ if (!(from = xabspath(from, -1))) return 0;
+ if (!(to = xabspath(to, -1))) goto error;
+
+ // skip common directories from root
+ for (i = j = 0; from[i] && from[i] == to[i]; i++) if (to[i] == '/') j = i+1;
+
+ // count remaining destination directories
+ for (i = j, k = 0; from[i]; i++) if (from[i] == '/') k++;
+
+ if (!k) ret = xstrdup(to+j);
+ else {
+ s = ret = xmprintf("%*c%s", 3*k, ' ', to+j);
+ while (k--) memcpy(s+3*k, "../", 3);
+ }
+
+error:
+ free(from);
+ free(to);
+
+ return ret;
+}
+
// Execute a callback for each PID that matches a process name from a list.
void names_to_pid(char **names, int (*callback)(pid_t pid, char *name),
int scripts)
diff --git a/lib/lib.h b/lib/lib.h
index b48d320e..f3eacb9d 100644
--- a/lib/lib.h
+++ b/lib/lib.h
@@ -402,6 +402,7 @@ mode_t string_to_mode(char *mode_str, mode_t base);
void mode_to_string(mode_t mode, char *buf);
char *getbasename(char *name);
char *fileunderdir(char *file, char *dir);
+char *relative_path(char *from, char *to);
void names_to_pid(char **names, int (*callback)(pid_t pid, char *name),
int scripts);