]> diplodocus.org Git - nmh/blob - sbr/path.c
mhbuildsbr.c: Flip logic, moving goto to then-block; no need for else.
[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 <h/utils.h>
10 #include "m_maildir.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 if (cp == pwds)
82 cp++;
83
84 if (has_prefix(name, CWD))
85 name += LEN(CWD);
86
87 if (strcmp (name, DOTDOT) == 0 || strcmp (name, PWD) == 0) {
88 snprintf (buffer, sizeof(buffer), "%.*s", (int)(cp - pwds), pwds);
89 return mh_xstrdup(buffer);
90 }
91
92 if (has_prefix(name, PWD))
93 name += LEN(PWD);
94 else
95 cp = ep;
96
97 snprintf (buffer, sizeof(buffer), "%.*s/%s", (int)(cp - pwds), pwds, name);
98 return mh_xstrdup(buffer);
99 }
100
101
102 static void
103 compath (char *f)
104 {
105 char *cp, *dp;
106
107 if (*f != '/')
108 return;
109
110 for (cp = f; *cp;) {
111 if (*cp != '/') {
112 cp++;
113 continue;
114 }
115
116 switch (*++cp) {
117 case 0:
118 if (--cp > f)
119 *cp = '\0';
120 return;
121
122 case '/':
123 for (dp = cp; *dp == '/'; dp++)
124 continue;
125 strcpy (cp--, dp);
126 continue;
127
128 case '.':
129 if (strcmp (cp, DOT) == 0) {
130 if (cp > f + 1)
131 cp--;
132 *cp = '\0';
133 return;
134 }
135 if (strcmp (cp, DOTDOT) == 0) {
136 for (cp -= 2; cp > f; cp--)
137 if (*cp == '/')
138 break;
139 if (cp <= f)
140 cp = f + 1;
141 *cp = '\0';
142 return;
143 }
144 if (has_prefix(cp, PWD)) {
145 for (dp = cp - 2; dp > f; dp--)
146 if (*dp == '/')
147 break;
148 if (dp <= f)
149 dp = f;
150 strcpy (dp, cp + LEN(PWD) - 1);
151 cp = dp;
152 continue;
153 }
154 if (has_prefix(cp, CWD)) {
155 strcpy (cp - 1, cp + LEN(CWD) - 1);
156 cp--;
157 continue;
158 }
159 continue;
160
161 default:
162 cp++;
163 continue;
164 }
165 }
166 }