comparison src/mule-mcpath.c @ 412:697ef44129c6 r21-2-14

Import from CVS: tag r21-2-14
author cvs
date Mon, 13 Aug 2007 11:20:41 +0200
parents
children 8de8e3f6228a
comparison
equal deleted inserted replaced
411:12e008d41344 412:697ef44129c6
1 /* Support for Non-ASCII Path Name
2 Copyright (C) 1985, 1986, 1992, 1993, 1995 Free Software Foundation, Inc.
3 Copyright (C) 1995 Sun Microsystems, Inc.
4
5 This file is part of XEmacs.
6
7 XEmacs is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by the
9 Free Software Foundation; either version 2, or (at your option) any
10 later version.
11
12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with XEmacs; see the file COPYING. If not, write to
19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
21
22 /* Synched up with: Mule 2.3. Not in FSF. */
23
24 /* mcpath.h should be included in config.h */
25 #include <config.h>
26 #include "lisp.h"
27
28 #include "sysfile.h"
29 #include "buffer.h"
30 #include "mule.h"
31
32 Lisp_Object Qpathname_coding_system = 0;
33
34 static void
35 mcpath_encode_code (struct Lisp_Coding_System *cp)
36 {
37 Lisp_Object coding_system;
38
39 coding_system = Fsymbol_value (Qpathname_coding_system);
40
41 mule_encode_code (coding_system, cp);
42 CODE_CNTL (cp) |= CC_END;
43 }
44
45 static int
46 mule_encode_path_1 (unsigned char *src, unsigned int srcsize,
47 unsigned char *dst, unsigned int dstsize)
48 {
49 struct Lisp_Coding_System code;
50
51 mcpath_encode_code (&code);
52 if (CODE_TYPE (&code) > MULE_AUTOCONV)
53 {
54 unsigned char *buf;
55
56 /* get_conversion_buffer () is not */
57 /* re-entrant. */
58 buf = (unsigned char *) alloca (MULE_ENCODE_BUF_SIZE (srcsize, &code));
59 if (buf)
60 {
61 int len;
62 Lisp_Object dummy = Qnil;
63
64 len = mule_encode (&code, src, buf, srcsize, &dummy);
65 if (!CODE_CHAR (&code) && len <= dstsize)
66 {
67 memcpy (dst, buf, len);
68 return len;
69 }
70 }
71 }
72 return -1; /* use original */
73 }
74
75 static unsigned char *
76 mule_decode_path_1 (unsigned char *src, unsigned char *dst,
77 unsigned int dstsize)
78 {
79 struct Lisp_Coding_System code;
80
81 mcpath_encode_code (&code);
82 if (CODE_TYPE (&code) > MULE_AUTOCONV)
83 {
84 int len;
85 unsigned char *buf;
86
87 len = strlen (src) + 1; /* + 1 for '\0' */
88
89 /* get_conversion_buffer () is not */
90 /* re-entrant. */
91 buf = (unsigned char *) alloca (MULE_DECODE_BUF_SIZE (len, &code));
92 if (buf)
93 {
94 CODE_CNTL (&code) |= CC_END;
95 len = mule_decode (&code, src, buf, len);
96 if (!CODE_CHAR (&code) && len <= dstsize)
97 {
98 memcpy (dst, buf, len); /* len should include '\0' */
99 return dst;
100 }
101 }
102 }
103 return src;
104 }
105
106 static unsigned char *
107 mule_decode_path (unsigned char *path, unsigned char ext_path[MC_MAXPATHLEN])
108 {
109 return
110 (Qpathname_coding_system
111 ? mule_decode_path_1 (path, ext_path, MC_MAXPATHLEN)
112 : path); /* in case of before initialization */
113 }
114
115 static unsigned char *
116 mule_encode_path (unsigned char *path, unsigned char *encode_buffer,
117 unsigned int size)
118 {
119 int len;
120
121 len = mule_encode_path_1 (path, strlen (path), encode_buffer, size);
122 if (len > 0)
123 path = encode_buffer;
124 #ifdef MSDOS
125 /* convert the MSDOS style path delimiter to the UNIX style. Note
126 that now the code is *internal*, so we can simply compare each
127 character with '\\'. And this operation will alter the contents
128 of Lisp Object, PATH. */
129 {
130 unsigned char *p = path;
131
132 while (*p)
133 {
134 if (*p == '\\')
135 *p = '/';
136 p++;
137 }
138 }
139 #endif /* MSDOS */
140 return path;
141 }
142
143 #if 0 /* example of how they do it (similar junk deleted) ... */
144
145 int
146 mc_creat (unsigned char *path, int mode)
147 {
148 unsigned char buffer[MC_MAXPATHLEN];
149 return creat (mule_decode_path (path, buffer), mode);
150 }
151
152 int
153 mc_readlink (unsigned char *path, unsigned char *buf, int size)
154 {
155 unsigned char buffer[MC_MAXPATHLEN], buffer2[MAXPATHLEN];
156 int nread;
157
158 nread = readlink (mule_decode_path (path, buffer), buffer2, MAXPATHLEN);
159 if (nread > 0)
160 {
161 int len;
162 unsigned char *p;
163
164 len = mule_encode_path_1 (buffer2, nread, buffer, sizeof (buffer));
165 if (0 <= len && len <= size)
166 {
167 memcpy (buf, buffer, len);
168 return len;
169 }
170 }
171 return -1;
172 }
173
174 int
175 mc_chdir (unsigned char *path)
176 {
177 unsigned char buffer[MC_MAXPATHLEN];
178
179 path = mule_decode_path (path, buffer);
180
181 #ifdef MSDOS
182 if ((path[0] != 0) && (path[1] == ':'))
183 {
184 int drive = (tolower (path[0]) - 'a');
185 if (getdisk () != drive)
186 setdisk (drive);
187 }
188
189 /* If path != "/" and path != "a:/" and path ends with slash, remove
190 it. */
191 {
192 int len = strlen (path);
193
194 if (strcmp (path + 1, ":/") && (len > 1) && (path[len - 1] == '/'))
195 {
196 if (path != buffer) /* It is not good to modify original path. */
197 {
198 memcpy (buffer, path, len - 1); /* no need to copy last /. */
199 path = buffer;
200 }
201 path[len - 1] = 0;
202 }
203 }
204 #endif /* MSDOS */
205
206 return chdir (path);
207 }
208
209 #ifdef MSDOS
210 #ifndef HAVE_GETWD
211 unsigned char *
212 mc_getcwd (unsigned char *null, size_t size)
213 {
214 unsigned char buffer[MAXPATHLEN];
215 unsigned char *path;
216
217 path = (unsigned char *) getcwd ((char *)buffer, MAXPATHLEN);
218 if (path)
219 {
220 /* here, should be (path == buffer). */
221 path = (unsigned char *) xmalloc (MC_MAXPATHLEN); /* MSDOS */
222 if (path)
223 {
224 int len;
225 int buffer_length = strlen (buffer) + 1;
226
227 len = mule_encode_path_1 (buffer, buffer_length, path, MC_MAXPATHLEN);
228 if (len < 0)
229 {
230 /* conversion failed. use value that is returned from system. */
231 memcpy (path, buffer, buffer_length);
232 }
233 }
234 }
235 return path;
236 }
237 #else /* HAVE_GETWD */
238 unsigned char *
239 mc_getwd (unsigned char path[])
240 {
241 unsigned char *p;
242
243 p = getwd (path);
244 if (p)
245 {
246 unsigned char buffer[MC_MAXPATHLEN];
247 int len;
248
249 len = mule_encode_path_1 (path, strlen (path) + 1, buffer, sizeof buffer);
250 if (len > 0)
251 {
252 memcpy (path, buffer, len);
253 }
254 }
255 return p;
256 }
257 #endif /* HAVE_GETWD */
258 #endif /* MSDOS */
259
260 /* In callproc.c, execvp() is called like this:
261 * execvp (new_argv[0], new_argv);
262 * following implement depends this.
263 */
264 #ifndef NO_MC_EXECVP
265 void
266 mc_execvp (unsigned char *path, unsigned char *argv[])
267 {
268 unsigned char buffer[MC_MAXPATHLEN];
269 argv[0] = path = mule_decode_path (path, buffer);
270 execvp (path, argv);
271 }
272 #endif /* !NO_MC_EXECVP */
273
274 static DIRENTRY mcpath_directory_entry;
275 DIRENTRY *
276 mc_readdir (DIR *d)
277 {
278 SYSTEM_DIRENTRY *sp;
279 DIRENTRY *dp = &mcpath_directory_entry;
280
281 sp = readdir (d);
282 if (!sp) return 0;
283
284 #ifndef MSDOS
285 dp->d_ino = sp->d_ino;
286 #endif /* MSDOS */
287 { /* copy d_name with conversion. */
288 int len;
289
290 len = mule_encode_path_1 (sp->d_name, NAMLEN (sp),
291 dp->d_name, sizeof (dp->d_name) - 1);
292 if (len < 0)
293 {
294 len = NAMLEN (sp);
295 #ifdef MCPATH_ASSERT
296 assert (len < sizeof (dp->d_name));
297 #endif
298 memcpy (dp->d_name, sp->d_name, len);
299 }
300 dp->d_name[len] = 0;
301 }
302 return dp;
303 }
304
305 #endif /* 0 */
306