]> diplodocus.org Git - nmh/blob - sbr/path.c
5505451e9e381cc7d884ee18e345e276099f3299
[nmh] / sbr / path.c
1 /* path.c -- return a pathname
2 *
3 * This code is Copyright (c) 2002, by the authors of nmh. See the
4 * COPYRIGHT file in the root directory of the nmh distribution for
5 * complete copyright information.
6 */
7
8 #include "h/mh.h"
9 #include "getfolder.h"
10 #include "path.h"
11 #include "h/utils.h"
12 #include "m_maildir.h"
13
14 #define CWD "./"
15 #define DOT "."
16 #define DOTDOT ".."
17 #define PWD "../"
18
19 static char *pwds;
20
21 /*
22 * static prototypes
23 */
24 static char *expath(char *,int);
25 static void compath(char *);
26
27
28 /* Return value must be free(3)'d. */
29 char *
30 pluspath(char *name)
31 {
32 return path(name + 1, *name == '+' ? TFOLDER : TSUBCWF);
33 }
34
35
36 /* Return value must be free(3)'d. */
37 char *
38 path(char *name, int flag)
39 {
40 char *p, *last;
41
42 p = expath(name, flag);
43 last = p + strlen(p) - 1;
44 if (last > p && *last == '/')
45 *last = '\0';
46
47 return p;
48 }
49
50
51 /* Return value must be free(3)'d. */
52 static char *
53 expath (char *name, int flag)
54 {
55 char *cp, *ep;
56 char buffer[BUFSIZ];
57
58 if (flag == TSUBCWF) {
59 snprintf (buffer, sizeof(buffer), "%s/%s", getfolder (1), name);
60 name = m_mailpath (buffer);
61 compath (name);
62 snprintf (buffer, sizeof(buffer), "%s/", m_maildir (""));
63 if (ssequal (buffer, name)) {
64 cp = name;
65 name = mh_xstrdup(name + strlen(buffer));
66 free (cp);
67 }
68 flag = TFOLDER;
69 }
70
71 if (*name == '/'
72 || (flag == TFOLDER
73 && (!has_prefix(name, CWD)
74 && strcmp (name, DOT)
75 && strcmp (name, DOTDOT)
76 && !has_prefix(name, PWD))))
77 return mh_xstrdup(name);
78
79 if (pwds == NULL)
80 pwds = pwd ();
81
82 if (strcmp (name, DOT) == 0 || strcmp (name, CWD) == 0)
83 return mh_xstrdup(pwds);
84
85 ep = pwds + strlen (pwds);
86 if ((cp = strrchr(pwds, '/')) == NULL)
87 cp = ep;
88 else if (cp == pwds)
89 cp++;
90
91 if (has_prefix(name, CWD))
92 name += LEN(CWD);
93
94 if (strcmp (name, DOTDOT) == 0 || strcmp (name, PWD) == 0) {
95 snprintf (buffer, sizeof(buffer), "%.*s", (int)(cp - pwds), pwds);
96 return mh_xstrdup(buffer);
97 }
98
99 if (has_prefix(name, PWD))
100 name += LEN(PWD);
101 else
102 cp = ep;
103
104 snprintf (buffer, sizeof(buffer), "%.*s/%s", (int)(cp - pwds), pwds, name);
105 return mh_xstrdup(buffer);
106 }
107
108
109 static void
110 compath (char *f)
111 {
112 char *cp, *dp;
113
114 if (*f != '/')
115 return;
116
117 for (cp = f; *cp;) {
118 if (*cp != '/') {
119 cp++;
120 continue;
121 }
122
123 switch (*++cp) {
124 case 0:
125 if (--cp > f)
126 *cp = '\0';
127 return;
128
129 case '/':
130 for (dp = cp; *dp == '/'; dp++)
131 continue;
132 strcpy (cp--, dp);
133 continue;
134
135 case '.':
136 if (strcmp (cp, DOT) == 0) {
137 if (cp > f + 1)
138 cp--;
139 *cp = '\0';
140 return;
141 }
142 if (strcmp (cp, DOTDOT) == 0) {
143 for (cp -= 2; cp > f; cp--)
144 if (*cp == '/')
145 break;
146 if (cp <= f)
147 cp = f + 1;
148 *cp = '\0';
149 return;
150 }
151 if (has_prefix(cp, PWD)) {
152 for (dp = cp - 2; dp > f; dp--)
153 if (*dp == '/')
154 break;
155 if (dp <= f)
156 dp = f;
157 strcpy (dp, cp + LEN(PWD) - 1);
158 cp = dp;
159 continue;
160 }
161 if (has_prefix(cp, CWD)) {
162 strcpy (cp - 1, cp + LEN(CWD) - 1);
163 cp--;
164 continue;
165 }
166 continue;
167
168 default:
169 cp++;
170 continue;
171 }
172 }
173 }