]> diplodocus.org Git - nmh/blob - sbr/path.c
h/prototypes.h: Remove scan_reset_m_getfld_state() prototype.
[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
11 #define CWD "./"
12 #define DOT "."
13 #define DOTDOT ".."
14 #define PWD "../"
15
16 static char *pwds;
17
18 /*
19 * static prototypes
20 */
21 static char *expath(char *,int);
22 static void compath(char *);
23
24 char *
25 pluspath(char *name)
26 {
27 return path(name + 1, *name == '+' ? TFOLDER : TSUBCWF);
28 }
29
30 char *
31 path(char *name, int flag)
32 {
33 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 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 = mh_xstrdup(name + strlen(buffer));
58 free (cp);
59 }
60 flag = TFOLDER;
61 }
62
63 if (*name == '/'
64 || (flag == TFOLDER
65 && (!has_prefix(name, CWD)
66 && strcmp (name, DOT)
67 && strcmp (name, DOTDOT)
68 && !has_prefix(name, PWD))))
69 return mh_xstrdup(name);
70
71 if (pwds == NULL)
72 pwds = pwd ();
73
74 if (strcmp (name, DOT) == 0 || strcmp (name, CWD) == 0)
75 return mh_xstrdup(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 (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 }