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