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