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