Mercurial > hg > xemacs-beta
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 |