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