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