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