This source file includes following definitions.
- examine_cd
- handle_cdpath
- cd_to
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #include <config.h>
32
33 #include <stdlib.h>
34 #include <errno.h>
35 #include <string.h>
36
37 #include "lib/global.h"
38 #include "lib/vfs/vfs.h"
39 #include "lib/strescape.h"
40 #include "lib/util.h"
41
42 #include "filemanager.h"
43 #include "tree.h"
44
45 #include "cd.h"
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73 static GString *
74 examine_cd (const char *_path)
75 {
76
77 typedef enum
78 {
79 copy_sym,
80 subst_var
81 } state_t;
82
83
84 state_t state = copy_sym;
85 GString *q;
86 char *path_tilde, *path;
87 char *p;
88
89
90 path = strutils_shell_unescape (_path);
91 path_tilde = tilde_expand (path);
92 g_free (path);
93
94 q = g_string_sized_new (32);
95
96
97 for (p = path_tilde; *p != '\0';)
98 {
99 switch (state)
100 {
101 case copy_sym:
102 if (p[0] == '\\' && p[1] == '$')
103 {
104 g_string_append_c (q, '$');
105 p += 2;
106 }
107 else if (p[0] != '$' || p[1] == '[' || p[1] == '(')
108 {
109 g_string_append_c (q, *p);
110 p++;
111 }
112 else
113 state = subst_var;
114 break;
115
116 case subst_var:
117 {
118 char *s = NULL;
119 char c;
120 const char *t = NULL;
121
122
123 p++;
124
125 if (p[0] == '{')
126 {
127 p++;
128 s = strchr (p, '}');
129 }
130 if (s == NULL)
131 s = strchr (p, PATH_SEP);
132 if (s == NULL)
133 s = strchr (p, '\0');
134 c = *s;
135 *s = '\0';
136 t = getenv (p);
137 *s = c;
138 if (t == NULL)
139 {
140 g_string_append_c (q, '$');
141 if (p[-1] != '$')
142 g_string_append_c (q, '{');
143 }
144 else
145 {
146 g_string_append (q, t);
147 p = s;
148 if (*s == '}')
149 p++;
150 }
151
152 state = copy_sym;
153 break;
154 }
155
156 default:
157 break;
158 }
159 }
160
161 g_free (path_tilde);
162
163 return q;
164 }
165
166
167
168
169 static gboolean
170 handle_cdpath (const char *path)
171 {
172 gboolean result = FALSE;
173
174
175 if (!IS_PATH_SEP (*path))
176 {
177 char *cdpath, *p;
178 char c;
179
180 cdpath = g_strdup (getenv ("CDPATH"));
181 p = cdpath;
182 c = (p == NULL) ? '\0' : ':';
183
184 while (!result && c == ':')
185 {
186 char *s;
187
188 s = strchr (p, ':');
189 if (s == NULL)
190 s = strchr (p, '\0');
191 c = *s;
192 *s = '\0';
193 if (*p != '\0')
194 {
195 vfs_path_t *r_vpath;
196
197 r_vpath = vfs_path_build_filename (p, path, (char *) NULL);
198 result = panel_cd (current_panel, r_vpath, cd_parse_command);
199 vfs_path_free (r_vpath, TRUE);
200 }
201 *s = c;
202 p = s + 1;
203 }
204 g_free (cdpath);
205 }
206
207 return result;
208 }
209
210
211
212
213
214
215
216
217
218
219 void
220 cd_to (const char *path)
221 {
222 char *p;
223
224
225
226
227
228
229
230 p = g_strstrip (g_strdup (path));
231
232 if (get_current_type () == view_tree)
233 {
234 vfs_path_t *new_vpath = NULL;
235
236 if (p[0] == '\0')
237 {
238 new_vpath = vfs_path_from_str (mc_config_get_home_dir ());
239 sync_tree (new_vpath);
240 }
241 else if (DIR_IS_DOTDOT (p))
242 {
243 if (vfs_path_elements_count (current_panel->cwd_vpath) != 1 ||
244 strlen (vfs_path_get_by_index (current_panel->cwd_vpath, 0)->path) > 1)
245 {
246 vfs_path_t *tmp_vpath = current_panel->cwd_vpath;
247
248 current_panel->cwd_vpath =
249 vfs_path_vtokens_get (tmp_vpath, 0, vfs_path_tokens_count (tmp_vpath) - 1);
250 vfs_path_free (tmp_vpath, TRUE);
251 }
252 sync_tree (current_panel->cwd_vpath);
253 }
254 else
255 {
256 if (IS_PATH_SEP (*p))
257 new_vpath = vfs_path_from_str (p);
258 else
259 new_vpath = vfs_path_append_new (current_panel->cwd_vpath, p, (char *) NULL);
260
261 sync_tree (new_vpath);
262 }
263
264 vfs_path_free (new_vpath, TRUE);
265 }
266 else
267 {
268 GString *s_path;
269 vfs_path_t *q_vpath;
270 gboolean ok;
271
272 s_path = examine_cd (p);
273
274 if (s_path->len == 0)
275 q_vpath = vfs_path_from_str (mc_config_get_home_dir ());
276 else
277 q_vpath = vfs_path_from_str_flags (s_path->str, VPF_NO_CANON);
278
279 ok = panel_cd (current_panel, q_vpath, cd_parse_command);
280 if (!ok)
281 ok = handle_cdpath (s_path->str);
282 if (!ok)
283 {
284 char *d;
285
286 d = vfs_path_to_str_flags (q_vpath, 0, VPF_STRIP_PASSWORD);
287 message (D_ERROR, MSG_ERROR, _("Cannot chdir to \"%s\"\n%s"), d,
288 unix_error_string (errno));
289 g_free (d);
290 }
291
292 vfs_path_free (q_vpath, TRUE);
293 g_string_free (s_path, TRUE);
294 }
295
296 g_free (p);
297 }
298
299