X-Git-Url: http://git.marmaro.de/?p=mmh;a=blobdiff_plain;f=sbr%2Fpath.c;h=41328964660c8e3504803d710351b33f8688640c;hp=3dd552c146a2115b3ffe0a2d48392ed88a908b34;hb=d39e2c447b0d163a5a63f480b23d06edb7a73aa0;hpb=6e8aba3714fe8ffc21dbb75ea9efdc41ab87b07f diff --git a/sbr/path.c b/sbr/path.c index 3dd552c..4132896 100644 --- a/sbr/path.c +++ b/sbr/path.c @@ -1,5 +1,5 @@ /* -** path.c -- return a pathname +** path.c -- return or convert paths ** ** This code is Copyright (c) 2002, by the authors of nmh. See the ** COPYRIGHT file in the root directory of the nmh distribution for @@ -8,13 +8,13 @@ #include -static char *pwds; - /* -** Compactify an absolute path name by removing unneccessary parts. -** Removes trailing slashes, but not if it would empty the string then. -** Modifies f. +** Compactify a path name by removing unneccessary parts. +** Removes trailing slashes. Cares to never remove all characters. +** Modifies f (never enlarges it). +** +** FIXME: Cannot use strcpy() as the areas overlap! */ static void packpath(char *f) @@ -90,111 +90,147 @@ packpath(char *f) } + + /* -** +** Get the default folder +** Return the Inbox profile entry or, as fallback, the compile time default +** Returns a pointer to the abs folpath */ -static char * -expath(char *name, int type) +char * +getdeffol(void) { - char *cp, *ep; - char buffer[BUFSIZ]; - - if (type == TSUBCWF) { - /* convert TSUBCWF to TFOLDER */ - snprintf(buffer, sizeof(buffer), "%s/%s", - getfolder(FCUR), name); - name = m_mailpath(buffer); - packpath(name); - snprintf(buffer, sizeof(buffer), "%s/", m_maildir("")); - if (isprefix(buffer, name)) { - cp = name; - name = getcpy(name + strlen(buffer)); - free(cp); - } - type = TFOLDER; - } + char *folder = context_find(inbox); - if (*name == '/') { - return getcpy(name); + if (!folder || !*folder) { + folder = defaultfolder; /* the compile time default */ } - - if (type == TFOLDER && - (strncmp(name, "./", 2) && strcmp(name, ".") && - strcmp(name, "..") && strncmp(name, "../", 3))) { - /* - ** FIXME: Seems as if this check does not catch names like: - ** ``foo/../../..''. - */ - return getcpy(name); + if (*folder == '+') { + folder++; } + return folder; +} - if (pwds == NULL) { - pwds = pwd(); - } - if (strcmp(name, ".") == 0 || strcmp(name, "./") == 0) { - return getcpy(pwds); - } +/* +** Get the current folder +** Return the Current-Folder context entry or, as fallback, the default folder +** Returns a pointer to the abs folpath +** +** Equivalent to: expandfol("@") +*/ +char * +getcurfol(void) +{ + char *folder = context_find(pfolder); - ep = pwds + strlen(pwds); - if ((cp = strrchr(pwds, '/')) == NULL) { - cp = ep; - } else if (cp == pwds) { - cp++; + if (!folder || !*folder) { + folder = getdeffol(); } + return folder; +} - if (strncmp(name, "./", 2) == 0) { - name += 2; - } - if (strcmp(name, "..") == 0 || strcmp(name, "../") == 0) { - snprintf(buffer, sizeof(buffer), "%.*s", - (int)(cp - pwds), pwds); - return getcpy(buffer); - } +/* +** Expand folder path +** Convert rel folpaths (@) into abs folpaths +** dir paths are simply passed through +** Returns the abs folpath (without prefix), in static mem +** +** TODO: Always copy into the static buffer, or just return the pointer? +*/ +char * +expandfol(char *f) +{ + static char buf[BUFSIZ]; + + if (*f == '@') { + /* f = concat(getcurfol(), "/", f+1, NULL); */ + snprintf(buf, sizeof buf, "%s/%s", getcurfol(), f+1); + + } else if (*f == '+') { + strcpy(buf, f+1); - if (strncmp(name, "../", 3) == 0) { - name += 3; } else { - cp = ep; + strcpy(buf, f); } - - snprintf(buffer, sizeof(buffer), "%.*s/%s", - (int)(cp - pwds), pwds, name); - return getcpy(buffer); + packpath(buf); + return buf; } /* -** Return a path name +** Expand directory path +** Convert rel dirpath into abs dirpath +** The argument is assumed to be a dir path relative to the cwd, +** except when beginning with '/' (then it will be passed through). +** Returns the abs dirpath, in static mem +** +** TODO: Always copy into the static buffer, or just return the pointer? */ char * -path(char *name, int type) +expanddir(char *d) { - char *cp, *ep; + static char buf[BUFSIZ]; - if ((cp = expath(name, type)) && - (ep = cp+strlen(cp)-1) > cp && - *ep == '/') { - *ep = '\0'; + if (*d == '/') { + strcpy(buf, d); + } else { + getcwd(buf, sizeof buf); + int len = strlen(buf); + snprintf(buf+len, sizeof buf - len, "/%s", d); } - - return cp; + packpath(buf); + return buf; } /* -** Call path() appropriately for ``+folder'' or ``@folder'' +** Anypath to absolute directory path +** Convert any kind of path into an abs dirpath +** A path without distinguishing prefix is assumed to be an abs folpath +** Abs dirpaths are passed unchanged +** Rel dirpaths ('.') get prefixed with the (abs) cwd +** Return pointer to static memory +** +** To get the dir path of the mail storage root, call: toabsdir("+") +** +** TODO: check lengths for copies */ char * -pluspath(char *name) +toabsdir(char *path) { - switch (*name) { - case '+': - return path(name+1, TFOLDER); - case '@': - return path(name+1, TSUBCWF); - default: - return path(name, TFILE); + static char buf[BUFSIZ]; + + if (*path == '/') { + /* nothing to do */ + strncpy(buf, path, sizeof buf); + packpath(buf); + return buf; + + } else if (*path == '.') { + /* rel dir path */ + strncpy(buf, expanddir(path), sizeof buf); + return buf; + + } else { + /* folder path */ + char *cp=buf, *pp; + + if (!(pp = context_find("path")) || !*pp) { + adios(NULL, "Non-empty profile entry `Path' required"); + } + if (*pp != '/') { + /* Path is relative to $HOME */ + snprintf(buf, sizeof buf, "%s/", mypath); + cp += strlen(buf); + } + strcpy(cp, pp); + packpath(buf); + /* append the mail folder */ + cp = buf + strlen(buf); + *cp++ = '/'; + strcpy(cp, expandfol(path)); + return buf; } }