1
4
5# include <stdio.h>
6# include <sys/stat.h>
7
8# include "auxfile.h"
9# include "auxmemory.h"
10
11# ifdef _WIN32
12
13 # include <windows.h>
14 # include <ctype.h>
15 # include <io.h>
16 # include <shellapi.h>
17 # include <fileapi.h>
18
19 LPWSTR aux_utf8_to_wide(const char *utf8str) {
20 if (utf8str) {
21 int length = MultiByteToWideChar(CP_UTF8, 0, utf8str, -1, NULL, 0);
22 LPWSTR wide = (LPWSTR) lmt_memory_malloc(sizeof(WCHAR) * length);
23 MultiByteToWideChar(CP_UTF8, 0, utf8str, -1, wide, length);
24 return wide;
25 } else {
26 return NULL;
27 }
28 }
29
30 char *aux_utf8_from_wide(LPWSTR widestr) {
31 if (widestr) {
32 int length = WideCharToMultiByte(CP_UTF8, 0, widestr, -1, NULL, 0, NULL, NULL);
33 char * utf8str = (char *) lmt_memory_malloc(sizeof(char) * length);
34 WideCharToMultiByte(CP_UTF8, 0, widestr, -1, utf8str, length, NULL, NULL);
35 return (char *) utf8str;
36 } else {
37 return NULL;
38 }
39 }
40
41 FILE *aux_utf8_fopen(const char *path, const char *mode) {
42 if (path && mode) {
43 LPWSTR wpath = aux_utf8_to_wide(path);
44 LPWSTR wmode = aux_utf8_to_wide(mode);
45 FILE *f = _wfopen(wpath,wmode);
46 lmt_memory_free(wpath);
47 lmt_memory_free(wmode);
48 return f;
49 } else {
50 return NULL;
51 }
52 }
53
54 FILE *aux_utf8_popen(const char *path, const char *mode) {
55 if (path && mode) {
56 LPWSTR wpath = aux_utf8_to_wide(path);
57 LPWSTR wmode = aux_utf8_to_wide(mode);
58 FILE *f = _wpopen(wpath,wmode);
59 lmt_memory_free(wpath);
60 lmt_memory_free(wmode);
61 return f;
62 } else {
63 return NULL;
64 }
65 }
66
67 int aux_utf8_system(const char *cmd)
68 {
69 LPWSTR wcmd = aux_utf8_to_wide(cmd);
70 int result = _wsystem(wcmd);
71 lmt_memory_free(wcmd);
72 return result;
73 }
74
75 int aux_utf8_remove(const char *name)
76 {
77 LPWSTR wname = aux_utf8_to_wide(name);
78 int result = _wremove(wname);
79 lmt_memory_free(wname);
80 return result;
81 }
82
83 int aux_utf8_rename(const char *oldname, const char *newname)
84 {
85 LPWSTR woldname = aux_utf8_to_wide(oldname);
86 LPWSTR wnewname = aux_utf8_to_wide(newname);
87 int result = _wrename(woldname, wnewname);
88 lmt_memory_free(woldname);
89 lmt_memory_free(wnewname);
90 return result;
91 }
92
93 int aux_utf8_setargv(char * **av, char **argv, int argc)
94 {
95 if (argv) {
96 int c = 0;
97 LPWSTR *l = CommandLineToArgvW(GetCommandLineW(), &c);
98 if (l != NULL) {
99 char **v = lmt_memory_malloc(sizeof(char *) * c);
100 for (int i = 0; i < c; i++) {
101 v[i] = aux_utf8_from_wide(l[i]);
102 }
103 *av = v;
104
105 if (c > 1) {
106 if ((strlen(v[c-1]) > 2) && isalpha(v[c-1][0]) && (v[c-1][1] == ':') && (v[c-1][2] == '\\')) {
107 for (char *p = v[c-1]+2; *p; p++) {
108 if (*p == '\\') {
109 *p = '/';
110 }
111 }
112 }
113 }
114 }
115 return c;
116 } else {
117 *av = NULL;
118 return argc;
119 }
120 }
121
122 char *aux_utf8_getownpath(const char *file)
123 {
124 if (file) {
125 char *path = NULL;
126 char buffer[MAX_PATH];
127 GetModuleFileName(NULL, buffer, sizeof(buffer));
128 path = lmt_memory_strdup(buffer);
129 if (strlen(path) > 0) {
130 for (size_t i = 0; i < strlen(path); i++) {
131 if (path[i] == '\\') {
132 path[i] = '/';
133 }
134 }
135 return path;
136 }
137 }
138 return lmt_memory_strdup(".");
139 }
140
141
142
143
144
145
146
147 char *aux_utf8_readlink(const char *file)
148 {
149 LPWSTR wide = aux_utf8_to_wide(file);
150 HANDLE handle = CreateFileW(wide, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
151 char *link = NULL;
152 if (handle == INVALID_HANDLE_VALUE) {
153 LPWSTR path = (LPWSTR) lmt_memory_malloc((MAX_PATH+1) * sizeof(WCHAR));
154 DWORD size = GetFinalPathNameByHandleW(handle, path, MAX_PATH, VOLUME_NAME_NT);
155 if (size > 0 && size < MAX_PATH) {
156 path[size] = '\0';
157 link = aux_utf8_from_wide(path);
158 }
159 lmt_memory_free(path);
160 }
161 CloseHandle(handle);
162 lmt_memory_free(wide);
163 return link ? link : lmt_memory_strdup(file);
164 }
165
166# else
167
168 # include <string.h>
169 # include <stdlib.h>
170 # include <unistd.h>
171
172 int aux_utf8_setargv(char * **av, char **argv, int argc)
173 {
174 *av = argv;
175 return argc;
176 }
177
178 char *aux_utf8_getownpath(const char *file)
179 {
180 if (strchr(file, '/')) {
181 return lmt_memory_strdup(file);
182 } else {
183 const char *esp;
184 size_t prefixlen = 0;
185 size_t totallen = 0;
186 size_t filelen = strlen(file);
187 char *path = NULL;
188 char *searchpath = lmt_memory_strdup(getenv("PATH"));
189 const char *index = searchpath;
190 if (index) {
191 do {
192 esp = strchr(index, ':');
193 if (esp) {
194 prefixlen = (size_t) (esp - index);
195 } else {
196 prefixlen = strlen(index);
197 }
198 if (prefixlen == 0 || index[prefixlen - 1] == '/') {
199 totallen = prefixlen + filelen;
200# ifdef PATH_MAX
201 if (totallen >= PATH_MAX) {
202 continue;
203 }
204# endif
205 path = lmt_memory_malloc(totallen + 1);
206 memcpy(path, index, prefixlen);
207 memcpy(path + prefixlen, file, filelen);
208 } else {
209 totallen = prefixlen + filelen + 1;
210# ifdef PATH_MAX
211 if (totallen >= PATH_MAX) {
212 continue;
213 }
214# endif
215 path = lmt_memory_malloc(totallen + 1);
216 memcpy(path, index, prefixlen);
217 path[prefixlen] = '/';
218 memcpy(path + prefixlen + 1, file, filelen);
219 }
220 path[totallen] = '\0';
221 if (access(path, X_OK) >= 0) {
222 break;
223 }
224 lmt_memory_free(path);
225 path = NULL;
226 index = esp + 1;
227 } while (esp);
228 }
229 lmt_memory_free(searchpath);
230 if (path) {
231 return path;
232 } else {
233 return lmt_memory_strdup(".");
234 }
235 }
236 }
237
238
239
240 char *aux_utf8_readlink(const char *file)
241 {
242 int size = 256;
243 while (1) {
244 char *target = lmt_memory_malloc(size);
245 if (! target) {
246 break;
247 } else {
248 int tsize = readlink(file, target, size);
249 if (tsize <= 0) {
250 lmt_memory_free(target);
251 break;
252 } else if (tsize < size) {
253 target[tsize] = '\0';
254 return target;
255 } else {
256 size *= 2;
257 }
258 }
259 }
260 return lmt_memory_strdup(file);
261 }
262
263# endif
264
265# ifndef S_ISREG
266 # define S_ISREG(mode) (mode & _S_IFREG)
267# endif
268
269# ifdef _WIN32
270
271 char *aux_basename(const char *name) {
272 char base[256+1];
273 char suff[256+1];
274 _splitpath(name,NULL,NULL,base,suff);
275 {
276 size_t b = strlen((const char*)base);
277 size_t s = strlen((const char*)suff);
278 char *result = (char *) lmt_memory_malloc(sizeof(char) * (b+s+1));
279 if (result) {
280 memcpy(&result[0], &base[0], b);
281 memcpy(&result[b], &suff[0], s);
282 result[b + s] = '\0';
283 }
284 return result;
285 }
286 }
287
288 char *aux_dirname(const char *name) {
289 char driv[256 + 1];
290 char path[256 + 1];
291 _splitpath(name,driv,path,NULL,NULL);
292 {
293 size_t d = strlen((const char*)driv);
294 size_t p = strlen((const char*)path);
295 char *result = (char *) lmt_memory_malloc(sizeof(char) * (d+p+1));
296 if (result) {
297 if (path[p - 1] == '/' || path[p - 1] == '\\') {
298 --p;
299 }
300 memcpy(&result[0], &driv[0], d);
301 memcpy(&result[d], &path[0], p);
302 result[d + p] = '\0';
303 }
304 return result;
305 }
306 }
307
308 int aux_is_readable(const char *filename)
309 {
310 struct _stati64 info;
311 LPWSTR w = aux_utf8_to_wide(filename);
312 int r = _wstati64(w, &info);
313 FILE *f;
314 lmt_memory_free(w);
315 return (r == 0)
316 && (S_ISREG(info.st_mode))
317 && ((f = aux_utf8_fopen(filename, "r")) != NULL)
318 && ! fclose(f);
319 }
320
321# else
322
323 # include <libgen.h>
324
325 int aux_is_readable(const char *filename)
326 {
327 struct stat finfo;
328 FILE *f;
329 return (stat(filename, &finfo) == 0)
330 && S_ISREG(finfo.st_mode)
331 && ((f = fopen(filename, "r")) != NULL)
332 && ! fclose(f);
333 }
334
335# endif
336 |