2 ** path.c -- return or convert paths
4 ** This code is Copyright (c) 2002, by the authors of nmh. See the
5 ** COPYRIGHT file in the root directory of the nmh distribution for
6 ** complete copyright information.
13 ** Compactify a path name by removing unneccessary parts.
14 ** Removes trailing slashes. Cares to never remove all characters.
15 ** Modifies f (never enlarges it).
17 ** FIXME: Cannot use strcpy() as the areas overlap!
28 abspath = (*f == '/');
32 /* Skip. Interesting places are only after slashes. */
33 /* We don't care about "./" beginnings */
38 /* Let's see what follows the slash ... */
42 continue; /* ... and thus exit the loop */
45 /* reduce subsequent slashes to one */
46 for (dp = cp; *dp == '/'; dp++) {
51 continue; /* ... at the slash */
54 if (cp[1] == '/' || cp[1] == '\0') {
59 } else if ((strncmp(cp, "../", 3) == 0) ||
60 (strcmp(cp, "..") == 0)) {
62 /* crop out previous path element */
63 for (dp=cp-2; dp>f && *dp!='/'; dp--) {
67 /* path starts with "/.." */
74 /* a normal hidden file */
87 /* We have removed everything, but need something. */
88 strcpy(f, abspath ? "/" : ".");
96 ** Get the default folder
97 ** Return the Inbox profile entry or, as fallback, the compile time default
98 ** Returns a pointer to the abs folpath
103 char *folder = context_find(inbox);
105 if (!folder || !*folder) {
106 folder = defaultfolder; /* the compile time default */
108 if (*folder == '+') {
116 ** Get the current folder
117 ** Return the Current-Folder context entry or, as fallback, the default folder
118 ** Returns a pointer to the abs folpath
120 ** Equivalent to: expandfol("@")
125 char *folder = context_find(curfolder);
127 if (!folder || !*folder) {
128 folder = getdeffol();
135 ** Expand folder path
136 ** Convert rel folpaths (@) into abs folpaths
137 ** dir paths are simply passed through
138 ** Returns the abs folpath (without prefix), in static mem
140 ** TODO: Always copy into the static buffer, or just return the pointer?
145 static char buf[BUFSIZ];
148 /* f = concat(getcurfol(), "/", f+1, NULL); */
149 snprintf(buf, sizeof buf, "%s/%s", getcurfol(), f+1);
151 } else if (*f == '+') {
163 ** Expand directory path
164 ** Convert rel dirpath into abs dirpath
165 ** The argument is assumed to be a dir path relative to the cwd,
166 ** except when beginning with '/' (then it will be passed through).
167 ** Returns the abs dirpath, in static mem
169 ** TODO: Always copy into the static buffer, or just return the pointer?
174 static char buf[BUFSIZ];
179 getcwd(buf, sizeof buf);
180 int len = strlen(buf);
181 snprintf(buf+len, sizeof buf - len, "/%s", d);
189 ** Anypath to absolute directory path
190 ** Convert any kind of path into an abs dirpath
191 ** A path without distinguishing prefix is assumed to be an abs folpath
192 ** Abs dirpaths are passed unchanged
193 ** Rel dirpaths ('.') get prefixed with the (abs) cwd
194 ** Return pointer to static memory
196 ** To get the dir path of the mail storage root, call: toabsdir("+")
198 ** TODO: check lengths for copies
203 static char buf[BUFSIZ];
207 strncpy(buf, path, sizeof buf);
211 } else if (*path == '.') {
213 strncpy(buf, expanddir(path), sizeof buf);
220 if (!(pp = context_find("path")) || !*pp) {
221 adios(NULL, "Non-empty profile entry `Path' required");
224 /* Path is relative to $HOME */
225 snprintf(buf, sizeof buf, "%s/", mypath);
230 /* append the mail folder */
231 cp = buf + strlen(buf);
233 strcpy(cp, expandfol(path));