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