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