Added -nocontentid (and -contentid, for symmetry) switch to mhbuild. This allows...
[mmh] / sbr / path.c
1
2 /*
3  * path.c -- return a pathname
4  *
5  * $Id$
6  *
7  * This code is Copyright (c) 2002, by the authors of nmh.  See the
8  * COPYRIGHT file in the root directory of the nmh distribution for
9  * complete copyright information.
10  */
11
12 #include <h/mh.h>
13
14 #define CWD     "./"
15 #define NCWD    (sizeof(CWD) - 1)
16 #define DOT     "."
17 #define DOTDOT  ".."
18 #define PWD     "../"
19 #define NPWD    (sizeof(PWD) - 1)
20
21 static char *pwds;
22
23 /*
24  * static prototypes
25  */
26 static char *expath(char *,int);
27 static void compath(char *);
28
29
30 char *
31 path(char *name, int flag)
32 {
33     register 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     register 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 = getcpy (name + strlen (buffer));
58             free (cp);
59         }
60         flag = TFOLDER;
61     }
62
63     if (*name == '/'
64             || (flag == TFOLDER
65                 && (strncmp (name, CWD, NCWD)
66                     && strcmp (name, DOT)
67                     && strcmp (name, DOTDOT)
68                     && strncmp (name, PWD, NPWD))))
69         return getcpy (name);
70
71     if (pwds == NULL)
72         pwds = pwd ();
73
74     if (strcmp (name, DOT) == 0 || strcmp (name, CWD) == 0)
75         return getcpy (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 (strncmp (name, CWD, NCWD) == 0)
85         name += NCWD;
86
87     if (strcmp (name, DOTDOT) == 0 || strcmp (name, PWD) == 0) {
88         snprintf (buffer, sizeof(buffer), "%.*s", cp - pwds, pwds);
89         return getcpy (buffer);
90     }
91
92     if (strncmp (name, PWD, NPWD) == 0)
93         name += NPWD;
94     else
95         cp = ep;
96
97     snprintf (buffer, sizeof(buffer), "%.*s/%s", cp - pwds, pwds, name);
98     return getcpy (buffer);
99 }
100
101
102 static void
103 compath (char *f)
104 {
105     register char *cp, *dp;
106
107     if (*f != '/')
108         return;
109
110     for (cp = f; *cp;)
111         if (*cp == '/') {
112             switch (*++cp) {
113                 case 0: 
114                     if (--cp > f)
115                         *cp = '\0';
116                     break;
117
118                 case '/': 
119                     for (dp = cp; *dp == '/'; dp++)
120                         continue;
121                     strcpy (cp--, dp);
122                     continue;
123
124                 case '.': 
125                     if (strcmp (cp, DOT) == 0) {
126                         if (cp > f + 1)
127                             cp--;
128                         *cp = '\0';
129                         break;
130                     }
131                     if (strcmp (cp, DOTDOT) == 0) {
132                         for (cp -= 2; cp > f; cp--)
133                             if (*cp == '/')
134                                 break;
135                         if (cp <= f)
136                             cp = f + 1;
137                         *cp = '\0';
138                         break;
139                     }
140                     if (strncmp (cp, PWD, NPWD) == 0) {
141                         for (dp = cp - 2; dp > f; dp--)
142                             if (*dp == '/')
143                                 break;
144                         if (dp <= f)
145                             dp = f;
146                         strcpy (dp, cp + NPWD - 1);
147                         cp = dp;
148                         continue;
149                     }
150                     if (strncmp (cp, CWD, NCWD) == 0) {
151                         strcpy (cp - 1, cp + NCWD - 1);
152                         cp--;
153                         continue;
154                     }
155                     continue;
156
157                 default: 
158                     cp++;
159                     continue;
160             }
161             break;
162         }
163         else
164             cp++;
165 }