This source file includes following definitions.
- examine_cd
- handle_cdpath
- cd_to
- cd_error_message
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/strutil.h"
40 #include "lib/util.h"
41 #include "lib/widget.h"
42
43 #include "filemanager.h"
44 #include "tree.h"
45
46 #include "cd.h"
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
74
75
76 static GString *
77 examine_cd (const char *_path)
78 {
79 typedef enum
80 {
81 copy_sym,
82 subst_var
83 } state_t;
84
85 state_t state = copy_sym;
86 GString *q;
87 char *path_tilde, *path;
88 char *p;
89
90
91 path = str_shell_unescape (_path);
92 path_tilde = tilde_expand (path);
93 g_free (path);
94
95 q = g_string_sized_new (32);
96
97
98 for (p = path_tilde; *p != '\0';)
99 {
100 switch (state)
101 {
102 case copy_sym:
103 if (p[0] == '\\' && p[1] == '$')
104 {
105 g_string_append_c (q, '$');
106 p += 2;
107 }
108 else if (p[0] != '$' || p[1] == '[' || p[1] == '(')
109 {
110 g_string_append_c (q, *p);
111 p++;
112 }
113 else
114 state = subst_var;
115 break;
116
117 case subst_var:
118 {
119 char *s = NULL;
120 char c;
121 const char *t = NULL;
122
123
124 p++;
125
126 if (p[0] == '{')
127 {
128 p++;
129 s = strchr (p, '}');
130 }
131 if (s == NULL)
132 s = strchr (p, PATH_SEP);
133 if (s == NULL)
134 s = strchr (p, '\0');
135 c = *s;
136 *s = '\0';
137 t = getenv (p);
138 *s = c;
139 if (t == NULL)
140 {
141 g_string_append_c (q, '$');
142 if (p[-1] != '$')
143 g_string_append_c (q, '{');
144 }
145 else
146 {
147 g_string_append (q, t);
148 p = s;
149 if (*s == '}')
150 p++;
151 }
152
153 state = copy_sym;
154 break;
155 }
156
157 default:
158 break;
159 }
160 }
161
162 g_free (path_tilde);
163
164 return q;
165 }
166
167
168
169
170 static gboolean
171 handle_cdpath (const char *path)
172 {
173 gboolean result = FALSE;
174
175
176 if (!IS_PATH_SEP (*path))
177 {
178 char *cdpath, *p;
179 char c;
180
181 cdpath = g_strdup (getenv ("CDPATH"));
182 p = cdpath;
183 c = (p == NULL) ? '\0' : ':';
184
185 while (!result && c == ':')
186 {
187 char *s;
188
189 s = strchr (p, ':');
190 if (s == NULL)
191 s = strchr (p, '\0');
192 c = *s;
193 *s = '\0';
194 if (*p != '\0')
195 {
196 vfs_path_t *r_vpath;
197
198 r_vpath = vfs_path_build_filename (p, path, (char *) NULL);
199 result = panel_cd (current_panel, r_vpath, cd_parse_command);
200 vfs_path_free (r_vpath, TRUE);
201 }
202 *s = c;
203 p = s + 1;
204 }
205 g_free (cdpath);
206 }
207
208 return result;
209 }
210
211
212
213
214
215
216
217
218
219
220 void
221 cd_to (const char *path)
222 {
223 char *p;
224
225
226
227
228
229
230
231 p = g_strstrip (g_strdup (path));
232
233 if (get_current_type () == view_tree)
234 {
235 vfs_path_t *new_vpath = NULL;
236
237 if (p[0] == '\0')
238 {
239 new_vpath = vfs_path_from_str (mc_config_get_home_dir ());
240 sync_tree (new_vpath);
241 }
242 else if (DIR_IS_DOTDOT (p))
243 {
244 if (vfs_path_elements_count (current_panel->cwd_vpath) != 1
245 || strlen (vfs_path_get_by_index (current_panel->cwd_vpath, 0)->path) > 1)
246 {
247 vfs_path_t *tmp_vpath = current_panel->cwd_vpath;
248
249 current_panel->cwd_vpath =
250 vfs_path_vtokens_get (tmp_vpath, 0, vfs_path_tokens_count (tmp_vpath) - 1);
251 vfs_path_free (tmp_vpath, TRUE);
252 }
253 sync_tree (current_panel->cwd_vpath);
254 }
255 else
256 {
257 if (IS_PATH_SEP (*p))
258 new_vpath = vfs_path_from_str (p);
259 else
260 new_vpath = vfs_path_append_new (current_panel->cwd_vpath, p, (char *) NULL);
261
262 sync_tree (new_vpath);
263 }
264
265 vfs_path_free (new_vpath, TRUE);
266 }
267 else
268 {
269 GString *s_path;
270 vfs_path_t *q_vpath;
271 gboolean ok;
272
273 s_path = examine_cd (p);
274
275 if (s_path->len == 0)
276 q_vpath = vfs_path_from_str (mc_config_get_home_dir ());
277 else
278 q_vpath = vfs_path_from_str_flags (s_path->str, VPF_NO_CANON);
279
280 ok = panel_cd (current_panel, q_vpath, cd_parse_command);
281 if (!ok)
282 ok = handle_cdpath (s_path->str);
283 if (!ok)
284 {
285 char *d;
286
287 d = vfs_path_to_str_flags (q_vpath, 0, VPF_STRIP_PASSWORD);
288 cd_error_message (d);
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
300
301 void
302 cd_error_message (const char *path)
303 {
304 message (D_ERROR, MSG_ERROR, _ ("Cannot change directory to\n%s\n%s"), path,
305 unix_error_string (errno));
306 }
307
308