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