+/******************************************************************************/
+
+/*
+ * These functions manipulate paths in PATH_T structures.
+ *
+ * They eliminate multiple slashes in paths when they notice them,
+ * and keep the path non-slash terminated.
+ *
+ * Both path_set() and path_append() return 0 if the requested name
+ * would be too long.
+ */
+
+
+static void path_init(void)
+{
+ from.p_end = from.p_path; from.p_path[0] = '\0';
+ to.p_end = to.p_path; to.p_path[0] = '\0';
+}
+
+static void strip_trailing_slash(PATH_T *p)
+{
+ char *beg = p->p_path;
+ char *end = p->p_end;
+ if ((beg + 2) < end && (*beg & 0x38) == '0' && *(beg+1) == ':')
+ beg += 2;
+ if (beg < end && *beg == '/')
+ ++beg;
+ while (end > beg && end[-1] == '/')
+ *--end = '\0';
+
+ p->p_end =end;
+}
+
+/*
+ * Move specified string into path. Convert "" to "." to handle BSD
+ * semantics for a null path. Strip trailing slashes.
+ */
+int
+path_set(PATH_T *p, char *string)
+{
+ if (strlen(string) > MAX_PATHLEN) {
+ err(PSTR("set: '%s': name too long"), string);
+ return 0;
+ }
+
+ (void)strcpy(p->p_path, string);
+ p->p_end = p->p_path + strlen(p->p_path);
+
+ if (p->p_path == p->p_end) {
+ *p->p_end++ = '.';
+ *p->p_end = 0;
+ }
+
+ strip_trailing_slash(p);
+ return 1;
+}
+
+/*
+ * Append specified string to path, inserting '/' if necessary. Return a
+ * pointer to the old end of path for restoration.
+ */
+char *
+path_append(PATH_T *p, char *name)
+{
+ char *old = p->p_end;
+ int len = strlen(name);
+
+ /* The "+ 1" accounts for the '/' between old path and name. */
+ if ((len + p->p_end - p->p_path + 1) > MAX_PATHLEN) {
+ err(PSTR("append: '%s/%s': name too long"), p->p_path, name);
+ return(0);
+ }
+
+ /*
+ * This code should always be executed, since paths shouldn't
+ * end in '/'.
+ */
+ if (p->p_end[-1] != '/') {
+ *p->p_end++ = '/';
+ *p->p_end = '\0';
+ }
+
+ (void)strncat(p->p_end, name, len);
+ p->p_end += len;
+ *p->p_end = '\0';
+
+ strip_trailing_slash(p);
+ return old;
+}
+
+/*
+ * Restore path to previous value. (As returned by path_append.)
+ */
+void
+path_restore(PATH_T *p, char *old)
+{
+ p->p_end = old;
+ *p->p_end = '\0';
+}
+
+/*
+ * Return basename of path.
+ */
+char *path_basename(PATH_T *p)
+{
+ char *basename = strrchr(p->p_path, '/');
+
+ if (basename) {
+ ++basename;
+ } else {
+ basename = p->p_path;
+ if ((basename[0] & 0x38) == '0' && basename[1] == ':')
+ basename += 2;
+ }
+
+ return basename;
+}
+