df5d963b9e44f8c405aefed5e75c3707390227af
[mmh] / 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 }