sdk: const correctness
[sdk] / ecere / src / sys / System.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <stdarg.h>
4 #include <string.h>
5
6 #define UNICODE
7
8 #if (defined(__unix__) || defined(__APPLE__)) && !defined(__dos__)
9 #define DIR_SEP   '/'
10 #define DIR_SEPS  "/"
11 #else
12 #define DIR_SEP   '\\'
13 #define DIR_SEPS  "\\"
14 #endif
15
16 // Maximum length for a vsprintf string
17 #define MAX_F_STRING 1025
18
19 #if defined(__WIN32__)
20
21 #define WIN32_LEAN_AND_MEAN
22 #include <windows.h>
23 #include <io.h>
24 #include <direct.h>
25 #include <shellapi.h>
26
27 #else
28
29 #include <unistd.h>
30 #include <sys/stat.h>
31
32 #endif
33
34 typedef int bool;
35 typedef unsigned int FileAttribs;
36 typedef unsigned char byte;
37 typedef unsigned int FileSize;
38 typedef unsigned short uint16;
39 typedef unsigned int uint;
40 typedef unsigned long long uint64;
41 typedef uint64 FileSize64;
42
43 #define false 0
44 #define true 1
45
46 #define null ((void *)0)
47
48 #define isDirectory  0x0040
49
50 #define MAX_LOCATION 797
51 #define MAX_FILENAME 274
52
53 void __ecereNameSpace__ecere__com__eSystem_Delete(void * memory);
54 void * __ecereNameSpace__ecere__com__eSystem_New(unsigned int size);
55 void * __ecereNameSpace__ecere__com__eSystem_New0(unsigned int size);
56 void * __ecereNameSpace__ecere__com__eSystem_Renew(void * memory, unsigned int size);
57 void * __ecereNameSpace__ecere__com__eSystem_Renew0(void * memory, unsigned int size);
58
59 unsigned short * __ecereNameSpace__ecere__sys__UTF8toUTF16(const char * source, int * wordCount);
60 unsigned short * __ecereNameSpace__ecere__sys__UTF8toUTF16Buffer(const char * source, uint16 * dest, int max);
61 char * __ecereNameSpace__ecere__sys__UTF16toUTF8(const uint16 * source);
62 char * __ecereNameSpace__ecere__sys__UTF16toUTF8Buffer(const uint16 * source, char * dest, int max);
63
64 char * __ecereNameSpace__ecere__sys__StripLastDirectory(const char * string, char * output);
65
66 char * __ecereNameSpace__ecere__sys__GetEnvironment(const char * envName, char * envValue, int max);
67 char * __ecereNameSpace__ecere__sys__SearchString(const char * buffer, int start, const char * subStr, bool matchCase, bool matchWord);
68
69 FileAttribs FILE_FileExists(const char * fileName);
70
71 bool System_MoveFile(const char * source, const char * dest)
72 {
73 #ifdef __WIN32__
74    bool result;
75    uint16 * _wsource = __ecereNameSpace__ecere__sys__UTF8toUTF16(source, null);
76    uint16 * _wdest = __ecereNameSpace__ecere__sys__UTF8toUTF16(dest, null);
77    result = MoveFileEx(_wsource, _wdest, MOVEFILE_COPY_ALLOWED) != 0;
78    __ecereNameSpace__ecere__com__eSystem_Delete(_wsource);
79    __ecereNameSpace__ecere__com__eSystem_Delete(_wdest);
80    return result;
81 #else
82    return rename(source, dest) == 0;
83 #endif
84 }
85
86 bool System_RenameFile(const char * oldName, const char * newName)
87 {
88 #if defined(__WIN32__)
89    bool result;
90    uint16 * _woldName = __ecereNameSpace__ecere__sys__UTF8toUTF16(oldName, null);
91    uint16 * _wnewName = __ecereNameSpace__ecere__sys__UTF8toUTF16(newName, null);
92    result = _wrename(_woldName, _wnewName) == 0;
93    __ecereNameSpace__ecere__com__eSystem_Delete(_woldName);
94    __ecereNameSpace__ecere__com__eSystem_Delete(_wnewName);
95    return result;
96
97 #else
98    return rename(oldName, newName) == 0;
99 #endif
100 }
101
102 bool System_DeleteFile(const char * fileName)
103 {
104    bool result = true;
105 #if defined(__WIN32__)
106    uint16 * _wfileName = __ecereNameSpace__ecere__sys__UTF8toUTF16(fileName, null);
107    if(_wunlink(_wfileName))
108       result = false;
109       //if(errno == 13/*EACCES*/) printf("delete file access error\n");
110       //else if(errno == 2/*ENOENT*/) printf("delete file file does not exist error\n");
111    __ecereNameSpace__ecere__com__eSystem_Delete(_wfileName);
112 #else
113    unlink(fileName);
114 #endif
115    return result;
116 }
117
118 bool System_MakeDir(const char * path)
119 {
120    bool result = false;
121    char location[MAX_LOCATION] = "";
122    int locationLen = 0;
123    int c = 0;
124 #ifdef __WIN32__
125    if(path[0] && path[1] == ':')
126       c = 2;
127    else if(path[0] == '\\' && path[1] == '\\')
128       c = 2;
129    else
130 #endif
131    if(path[0] == '/' || path[0] == '\\')
132       c = 1;
133
134    strncpy(location, path, c);
135    location[c] = '\0';
136    locationLen = c;
137
138    for(; path[c]; )
139    {
140       char directory[MAX_FILENAME];
141       int len = 0;
142       char ch;
143       for(;(ch = path[c]) && (ch == '/' || ch == '\\'); c++);
144       for(;(ch = path[c]) && (ch != '/' && ch != '\\'); c++)
145       {
146          if(len < MAX_FILENAME)
147             directory[len++] = ch;
148       }
149       directory[len] = '\0';
150       if(locationLen > 0 &&
151          (location[locationLen-1] != '\\' && location[locationLen-1] != '/'))
152          strcat(location, DIR_SEPS);
153       strcat(location, directory);
154       locationLen = strlen(location);
155
156       if(FILE_FileExists(location) != isDirectory)
157       {
158 #if defined(__unix__) || defined(__APPLE__)
159          result = !mkdir(location, 0755);
160 #else
161          uint16 _wlocation[MAX_LOCATION];
162          __ecereNameSpace__ecere__sys__UTF8toUTF16Buffer(location, _wlocation, MAX_LOCATION);
163          result = !_wmkdir(_wlocation);
164 #endif
165       }
166    }
167    return result;
168 }
169
170 bool System_RemoveDir(const char * path)
171 {
172    bool result = false;
173    char location[MAX_LOCATION] = "";
174    int locationLen = 0;
175    int c = 0;
176 #ifdef __WIN32__
177    if(path[0] && path[1] == ':')
178       c = 2;
179    else if(path[0] == '\\' && path[1] == '\\')
180       c = 2;
181    else
182 #endif
183    if(path[0] == '/' || path[0] == '\\')
184       c = 1;
185
186    strncpy(location, path, c);
187    location[c] = '\0';
188    locationLen = c;
189
190    for(; path[c]; )
191    {
192       char directory[MAX_FILENAME];
193       int len = 0;
194       char ch;
195       for(;(ch = path[c]) && (ch == '/' || ch == '\\'); c++);
196       for(;(ch = path[c]) && (ch != '/' && ch != '\\'); c++)
197       {
198          if(len < MAX_FILENAME)
199             directory[len++] = ch;
200       }
201       directory[len] = '\0';
202       if(locationLen > 0 &&
203          (location[locationLen-1] != '\\' && location[locationLen-1] != '/'))
204          strcat(location, DIR_SEPS);
205       strcat(location, directory);
206       locationLen = strlen(location);
207
208       if(FILE_FileExists(location) == isDirectory)
209       {
210 #if defined(__unix__) || defined(__APPLE__)
211          rmdir(location);
212 #else
213          uint16 _wlocation[MAX_LOCATION];
214          __ecereNameSpace__ecere__sys__UTF8toUTF16Buffer(location, _wlocation, MAX_LOCATION);
215          _wrmdir(_wlocation);
216 #endif
217          result = true;
218       }
219    }
220    return result;
221 }
222
223 char * System_GetWorkingDir(char * buf, int size)
224 {
225 #if defined(__WIN32__)
226    uint16 * _wbuf = __ecereNameSpace__ecere__com__eSystem_New(sizeof(uint16) * size);
227    _wgetcwd(_wbuf, size);
228    __ecereNameSpace__ecere__sys__UTF16toUTF8Buffer(_wbuf, buf, size);
229    __ecereNameSpace__ecere__com__eSystem_Delete(_wbuf);
230    return buf;
231 #else
232    return getcwd(buf, size);
233 #endif
234 }
235
236 bool System_ChangeWorkingDir(const char * buf)
237 {
238 #if defined(__WIN32__)
239    bool result;
240    uint16 * _wbuf = __ecereNameSpace__ecere__sys__UTF8toUTF16(buf, null);
241    result = !chdir(buf);
242    __ecereNameSpace__ecere__com__eSystem_Delete(_wbuf);
243    return result;
244 #else
245    return !chdir(buf);
246 #endif
247 }
248
249 const char * System_GetEnvironment(const char * envName, char * envValue, int max)
250 {
251 #if defined(__WIN32__)
252    uint16 * _wenvName = __ecereNameSpace__ecere__sys__UTF8toUTF16(envName, null);
253    //uint16 * result;
254    uint16 result[2048];
255    int success;
256
257    success = GetEnvironmentVariable(_wenvName, result, sizeof(result) / sizeof(uint16));
258    //result = _wgetenv(_wenvName);
259    //if(result)
260    if(success && success < sizeof(result) / sizeof(uint16))
261       __ecereNameSpace__ecere__sys__UTF16toUTF8Buffer(result, envValue, max);
262    else
263       envValue[0] = 0;
264
265    __ecereNameSpace__ecere__com__eSystem_Delete(_wenvName);
266    // Distinguish empty vs. unexisting environment variables with GetLastError()
267    return (success || !GetLastError()) ? envValue : null;
268 #else
269    char * result = getenv(envName);
270    if(result)
271       strncpy(envValue, result, max);
272    else
273       envValue[0] = 0;
274    return result ? envValue : null;
275 #endif
276 }
277
278 void System_SetEnvironment(const char * envName, const char * envValue)
279 {
280 #if defined(__WIN32__)
281    uint16 * _wenvName = __ecereNameSpace__ecere__sys__UTF8toUTF16(envName, null);
282    uint16 * _wenvValue = __ecereNameSpace__ecere__sys__UTF8toUTF16(envValue, null);
283    SetEnvironmentVariable(_wenvName, _wenvValue);
284    __ecereNameSpace__ecere__com__eSystem_Delete(_wenvName);
285    __ecereNameSpace__ecere__com__eSystem_Delete(_wenvValue);
286 #else
287    setenv(envName, envValue, 1);
288 #endif
289 }
290
291 void System_UnsetEnvironment(const char * envName)
292 {
293 #if defined(__WIN32__)
294    uint16 * _wenvName = __ecereNameSpace__ecere__sys__UTF8toUTF16(envName, null);
295    SetEnvironmentVariable(_wenvName, null);
296    __ecereNameSpace__ecere__com__eSystem_Delete(_wenvName);
297 #else
298    unsetenv(envName);
299 #endif
300 }
301
302 bool System_Execute(const char * env, const char * command, va_list args, bool wait)
303 {
304    bool result = false;
305    char commandLine[MAX_F_STRING*4];
306    vsnprintf(commandLine, sizeof(commandLine)-1, command, args);
307    commandLine[sizeof(commandLine)-1] = 0;
308
309 #ifndef __WIN32__
310    {
311       if(!wait) strcat(commandLine, "&");
312       system(commandLine);
313    }
314 #else
315    {
316       PROCESS_INFORMATION pi;
317       STARTUPINFO si = { 0 };
318       uint16 * _wcommandLine = __ecereNameSpace__ecere__sys__UTF8toUTF16(commandLine, null);
319
320       // Set up the start up info struct.
321       si.cb = sizeof(STARTUPINFO);
322       // if(CreateProcess(null, _wcommandLine, null, null, TRUE, 0, env, null, &si, &pi))
323       if(CreateProcess(null, _wcommandLine, null, null, TRUE, CREATE_NEW_CONSOLE, (void *)env, null, &si, &pi))
324       {
325          if(wait)
326             WaitForSingleObject(pi.hProcess, INFINITE);
327
328          CloseHandle(pi.hProcess);
329          CloseHandle(pi.hThread);
330          result = true;
331       }
332       __ecereNameSpace__ecere__com__eSystem_Delete(_wcommandLine);
333    }
334 #endif
335    return result;
336 }
337
338 bool System_ShellOpen(const char * fileName, va_list args)
339 {
340    bool result = false;
341    char filePath[MAX_F_STRING*4];
342    int len;
343 #if defined(__WIN32__)
344    filePath[0] = '"';
345    vsnprintf(filePath+1, sizeof(filePath)-2,fileName, args);
346 #else
347    vsnprintf(filePath, sizeof(filePath), fileName, args);
348 #endif
349    filePath[sizeof(filePath)-1] = 0;
350
351    len = strlen(filePath);
352 #if defined(__WIN32__)
353    filePath[len] = '"';
354    filePath[len+1] = '\0';
355 #else
356    filePath[len] = '\0';
357 #endif
358
359 #if !defined(__WIN32__)
360    {
361       char command[MAX_LOCATION] = "";
362       char desktop[MAX_F_STRING];
363       __ecereNameSpace__ecere__sys__GetEnvironment("ECERE_DESKTOP", desktop, sizeof(desktop));
364       if(__ecereNameSpace__ecere__sys__SearchString(desktop, 0, "ecere", false, false))
365          sprintf(command, "ede-open \"%s\" &", filePath);
366       else
367       {
368          __ecereNameSpace__ecere__sys__GetEnvironment("DESKTOP_SESSION", desktop, sizeof(desktop));
369          if(__ecereNameSpace__ecere__sys__SearchString(desktop, 0, "gnome", false, false))
370             sprintf(command, "gnome-open \"%s\" &", filePath);
371          else if(__ecereNameSpace__ecere__sys__SearchString(desktop, 0, "kde", false, false))
372             sprintf(command, "kde-open \"%s\" &", filePath);
373          else
374             sprintf(command, "xdg-open \"%s\" &", filePath);
375       }
376
377       if(command[0] && system(command) != -1)
378          result = true;
379    }
380 #elif defined(ECERE_VANILLA)
381    {
382       uint16 * _wfilePath = __ecereNameSpace__ecere__sys__UTF8toUTF16(filePath, null);
383       if(_wsystem(_wfilePath) != -1)
384          result = true;
385       __ecereNameSpace__ecere__com__eSystem_Delete(_wfilePath);
386    }
387 #else
388    {
389       uint16 * _wfilePath = __ecereNameSpace__ecere__sys__UTF8toUTF16(filePath, null);
390       char curDir[MAX_LOCATION];
391       uint16 * _wcurDir;
392       __ecereNameSpace__ecere__sys__StripLastDirectory(filePath, curDir);
393       _wcurDir = __ecereNameSpace__ecere__sys__UTF8toUTF16(curDir, null);
394       //if(ShellExecute(null, "open", _wfilePath, null, curDir, SW_SHOWNORMAL) > 32)
395       if((void *)ShellExecute(null, null, _wfilePath, null, _wcurDir, SW_SHOWNORMAL) > (void *)32)
396          result = true;
397       __ecereNameSpace__ecere__com__eSystem_Delete(_wfilePath);
398       __ecereNameSpace__ecere__com__eSystem_Delete(_wcurDir);
399    }
400 #endif
401    return result;
402 }
403
404 void System_GetFreeSpace(const char * path, FileSize64 * size)
405 {
406    uint64 freeSize = 0;
407 #ifdef __WIN32__
408    uint16 * _wpath = __ecereNameSpace__ecere__sys__UTF8toUTF16(path, null);
409    GetDiskFreeSpaceEx(_wpath, (PULARGE_INTEGER)&freeSize, null, null);
410    __ecereNameSpace__ecere__com__eSystem_Delete(_wpath);
411 #endif
412    *size = (FileSize64)freeSize;
413 }